1 /*
2 * Copyright (C) 2004-2016 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 1999-2003 Internet Software Consortium.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15 * PERFORMANCE OF THIS SOFTWARE.
16 */
17
18 /*! \file */
19
20 #include <config.h>
21 #include <errno.h>
22
23 #include <isc/file.h>
24 #include <isc/hex.h>
25 #include <isc/mutex.h>
26 #include <isc/pool.h>
27 #include <isc/print.h>
28 #include <isc/random.h>
29 #include <isc/ratelimiter.h>
30 #include <isc/refcount.h>
31 #include <isc/rwlock.h>
32 #include <isc/serial.h>
33 #include <isc/stats.h>
34 #include <isc/stdtime.h>
35 #include <isc/strerror.h>
36 #include <isc/string.h>
37 #include <isc/taskpool.h>
38 #include <isc/thread.h>
39 #include <isc/timer.h>
40 #include <isc/util.h>
41
42 #include <dns/acache.h>
43 #include <dns/acl.h>
44 #include <dns/adb.h>
45 #include <dns/callbacks.h>
46 #include <dns/db.h>
47 #include <dns/dbiterator.h>
48 #include <dns/dnssec.h>
49 #include <dns/ds.h>
50 #include <dns/events.h>
51 #include <dns/journal.h>
52 #include <dns/keydata.h>
53 #include <dns/keytable.h>
54 #include <dns/keyvalues.h>
55 #include <dns/log.h>
56 #include <dns/master.h>
57 #include <dns/masterdump.h>
58 #include <dns/message.h>
59 #include <dns/name.h>
60 #include <dns/nsec.h>
61 #include <dns/nsec3.h>
62 #include <dns/peer.h>
63 #include <dns/private.h>
64 #include <dns/rbt.h>
65 #include <dns/rcode.h>
66 #include <dns/rdata.h>
67 #include <dns/rdataclass.h>
68 #include <dns/rdatalist.h>
69 #include <dns/rdataset.h>
70 #include <dns/rdatasetiter.h>
71 #include <dns/rdatastruct.h>
72 #include <dns/rdatatype.h>
73 #include <dns/request.h>
74 #include <dns/resolver.h>
75 #include <dns/result.h>
76 #include <dns/rriterator.h>
77 #include <dns/soa.h>
78 #include <dns/ssu.h>
79 #include <dns/stats.h>
80 #include <dns/time.h>
81 #include <dns/tsig.h>
82 #include <dns/update.h>
83 #include <dns/xfrin.h>
84 #include <dns/zone.h>
85 #include <dns/zt.h>
86
87 #include <dst/dst.h>
88
89 #define ZONE_MAGIC ISC_MAGIC('Z', 'O', 'N', 'E')
90 #define DNS_ZONE_VALID(zone) ISC_MAGIC_VALID(zone, ZONE_MAGIC)
91
92 #define NOTIFY_MAGIC ISC_MAGIC('N', 't', 'f', 'y')
93 #define DNS_NOTIFY_VALID(notify) ISC_MAGIC_VALID(notify, NOTIFY_MAGIC)
94
95 #define STUB_MAGIC ISC_MAGIC('S', 't', 'u', 'b')
96 #define DNS_STUB_VALID(stub) ISC_MAGIC_VALID(stub, STUB_MAGIC)
97
98 #define ZONEMGR_MAGIC ISC_MAGIC('Z', 'm', 'g', 'r')
99 #define DNS_ZONEMGR_VALID(stub) ISC_MAGIC_VALID(stub, ZONEMGR_MAGIC)
100
101 #define LOAD_MAGIC ISC_MAGIC('L', 'o', 'a', 'd')
102 #define DNS_LOAD_VALID(load) ISC_MAGIC_VALID(load, LOAD_MAGIC)
103
104 #define FORWARD_MAGIC ISC_MAGIC('F', 'o', 'r', 'w')
105 #define DNS_FORWARD_VALID(load) ISC_MAGIC_VALID(load, FORWARD_MAGIC)
106
107 #define IO_MAGIC ISC_MAGIC('Z', 'm', 'I', 'O')
108 #define DNS_IO_VALID(load) ISC_MAGIC_VALID(load, IO_MAGIC)
109
110 /*%
111 * Ensure 'a' is at least 'min' but not more than 'max'.
112 */
113 #define RANGE(a, min, max) \
114 (((a) < (min)) ? (min) : ((a) < (max) ? (a) : (max)))
115
116 #define NSEC3REMOVE(x) (((x) & DNS_NSEC3FLAG_REMOVE) != 0)
117
118 /*%
119 * Key flags
120 */
121 #define REVOKE(x) ((dst_key_flags(x) & DNS_KEYFLAG_REVOKE) != 0)
122 #define KSK(x) ((dst_key_flags(x) & DNS_KEYFLAG_KSK) != 0)
123 #define ALG(x) dst_key_alg(x)
124
125 /*
126 * Default values.
127 */
128 #define DNS_DEFAULT_IDLEIN 3600 /*%< 1 hour */
129 #define DNS_DEFAULT_IDLEOUT 3600 /*%< 1 hour */
130 #define MAX_XFER_TIME (2*3600) /*%< Documented default is 2 hours */
131 #define RESIGN_DELAY 3600 /*%< 1 hour */
132
133 #ifndef DNS_MAX_EXPIRE
134 #define DNS_MAX_EXPIRE 14515200 /*%< 24 weeks */
135 #endif
136
137 #ifndef DNS_DUMP_DELAY
138 #define DNS_DUMP_DELAY 900 /*%< 15 minutes */
139 #endif
140
141 typedef struct dns_notify dns_notify_t;
142 typedef struct dns_stub dns_stub_t;
143 typedef struct dns_load dns_load_t;
144 typedef struct dns_forward dns_forward_t;
145 typedef ISC_LIST(dns_forward_t) dns_forwardlist_t;
146 typedef struct dns_io dns_io_t;
147 typedef ISC_LIST(dns_io_t) dns_iolist_t;
148 typedef struct dns_signing dns_signing_t;
149 typedef ISC_LIST(dns_signing_t) dns_signinglist_t;
150 typedef struct dns_nsec3chain dns_nsec3chain_t;
151 typedef ISC_LIST(dns_nsec3chain_t) dns_nsec3chainlist_t;
152 typedef struct dns_keyfetch dns_keyfetch_t;
153 typedef struct dns_asyncload dns_asyncload_t;
154
155 #define DNS_ZONE_CHECKLOCK
156 #ifdef DNS_ZONE_CHECKLOCK
157 #define LOCK_ZONE(z) \
158 do { LOCK(&(z)->lock); \
159 INSIST((z)->locked == ISC_FALSE); \
160 (z)->locked = ISC_TRUE; \
161 } while (0)
162 #define UNLOCK_ZONE(z) \
163 do { (z)->locked = ISC_FALSE; UNLOCK(&(z)->lock); } while (0)
164 #define LOCKED_ZONE(z) ((z)->locked)
165 #define TRYLOCK_ZONE(result, z) \
166 do { \
167 result = isc_mutex_trylock(&(z)->lock); \
168 if (result == ISC_R_SUCCESS) { \
169 INSIST((z)->locked == ISC_FALSE); \
170 (z)->locked = ISC_TRUE; \
171 } \
172 } while (0)
173 #else
174 #define LOCK_ZONE(z) LOCK(&(z)->lock)
175 #define UNLOCK_ZONE(z) UNLOCK(&(z)->lock)
176 #define LOCKED_ZONE(z) ISC_TRUE
177 #define TRYLOCK_ZONE(result, z) \
178 do { result = isc_mutex_trylock(&(z)->lock); } while (0)
179 #endif
180
181 #ifdef ISC_RWLOCK_USEATOMIC
182 #define ZONEDB_INITLOCK(l) isc_rwlock_init((l), 0, 0)
183 #define ZONEDB_DESTROYLOCK(l) isc_rwlock_destroy(l)
184 #define ZONEDB_LOCK(l, t) RWLOCK((l), (t))
185 #define ZONEDB_UNLOCK(l, t) RWUNLOCK((l), (t))
186 #else
187 #define ZONEDB_INITLOCK(l) isc_mutex_init(l)
188 #define ZONEDB_DESTROYLOCK(l) DESTROYLOCK(l)
189 #define ZONEDB_LOCK(l, t) LOCK(l)
190 #define ZONEDB_UNLOCK(l, t) UNLOCK(l)
191 #endif
192
193 struct dns_zone {
194 /* Unlocked */
195 unsigned int magic;
196 isc_mutex_t lock;
197 #ifdef DNS_ZONE_CHECKLOCK
198 isc_boolean_t locked;
199 #endif
200 isc_mem_t *mctx;
201 isc_refcount_t erefs;
202
203 #ifdef ISC_RWLOCK_USEATOMIC
204 isc_rwlock_t dblock;
205 #else
206 isc_mutex_t dblock;
207 #endif
208 dns_db_t *db; /* Locked by dblock */
209
210 /* Locked */
211 dns_zonemgr_t *zmgr;
212 ISC_LINK(dns_zone_t) link; /* Used by zmgr. */
213 isc_timer_t *timer;
214 unsigned int irefs;
215 dns_name_t origin;
216 char *masterfile;
217 dns_masterformat_t masterformat;
218 char *journal;
219 isc_int32_t journalsize;
220 dns_rdataclass_t rdclass;
221 dns_zonetype_t type;
222 unsigned int flags;
223 unsigned int options;
224 unsigned int db_argc;
225 char **db_argv;
226 isc_time_t expiretime;
227 isc_time_t refreshtime;
228 isc_time_t dumptime;
229 isc_time_t loadtime;
230 isc_time_t notifytime;
231 isc_time_t resigntime;
232 isc_time_t keywarntime;
233 isc_time_t signingtime;
234 isc_time_t nsec3chaintime;
235 isc_time_t refreshkeytime;
236 isc_uint32_t refreshkeyinterval;
237 isc_uint32_t refreshkeycount;
238 isc_uint32_t refresh;
239 isc_uint32_t retry;
240 isc_uint32_t expire;
241 isc_uint32_t minimum;
242 isc_stdtime_t key_expiry;
243 isc_stdtime_t log_key_expired_timer;
244 char *keydirectory;
245
246 isc_uint32_t maxrefresh;
247 isc_uint32_t minrefresh;
248 isc_uint32_t maxretry;
249 isc_uint32_t minretry;
250
251 isc_sockaddr_t *masters;
252 dns_name_t **masterkeynames;
253 isc_boolean_t *mastersok;
254 unsigned int masterscnt;
255 unsigned int curmaster;
256 isc_sockaddr_t masteraddr;
257 dns_notifytype_t notifytype;
258 isc_sockaddr_t *notify;
259 dns_name_t **notifykeynames;
260 unsigned int notifycnt;
261 isc_sockaddr_t notifyfrom;
262 isc_task_t *task;
263 isc_task_t *loadtask;
264 isc_sockaddr_t notifysrc4;
265 isc_sockaddr_t notifysrc6;
266 isc_sockaddr_t xfrsource4;
267 isc_sockaddr_t xfrsource6;
268 isc_sockaddr_t altxfrsource4;
269 isc_sockaddr_t altxfrsource6;
270 isc_sockaddr_t sourceaddr;
271 dns_xfrin_ctx_t *xfr; /* task locked */
272 dns_tsigkey_t *tsigkey; /* key used for xfr */
273 /* Access Control Lists */
274 dns_acl_t *update_acl;
275 dns_acl_t *forward_acl;
276 dns_acl_t *notify_acl;
277 dns_acl_t *query_acl;
278 dns_acl_t *queryon_acl;
279 dns_acl_t *xfr_acl;
280 isc_boolean_t update_disabled;
281 isc_boolean_t zero_no_soa_ttl;
282 dns_severity_t check_names;
283 ISC_LIST(dns_notify_t) notifies;
284 dns_request_t *request;
285 dns_loadctx_t *lctx;
286 dns_io_t *readio;
287 dns_dumpctx_t *dctx;
288 dns_io_t *writeio;
289 isc_uint32_t maxxfrin;
290 isc_uint32_t maxxfrout;
291 isc_uint32_t idlein;
292 isc_uint32_t idleout;
293 isc_event_t ctlevent;
294 dns_ssutable_t *ssutable;
295 isc_uint32_t sigvalidityinterval;
296 isc_uint32_t sigresigninginterval;
297 dns_view_t *view;
298 dns_acache_t *acache;
299 dns_checkmxfunc_t checkmx;
300 dns_checksrvfunc_t checksrv;
301 dns_checknsfunc_t checkns;
302 /*%
303 * Zones in certain states such as "waiting for zone transfer"
304 * or "zone transfer in progress" are kept on per-state linked lists
305 * in the zone manager using the 'statelink' field. The 'statelist'
306 * field points at the list the zone is currently on. It the zone
307 * is not on any such list, statelist is NULL.
308 */
309 ISC_LINK(dns_zone_t) statelink;
310 dns_zonelist_t *statelist;
311 /*%
312 * Statistics counters about zone management.
313 */
314 isc_stats_t *stats;
315 /*%
316 * Optional per-zone statistics counters. Counted outside of this
317 * module.
318 */
319 dns_zonestat_level_t statlevel;
320 isc_boolean_t requeststats_on;
321 isc_stats_t *requeststats;
322 dns_stats_t *rcvquerystats;
323 isc_uint32_t notifydelay;
324 dns_isselffunc_t isself;
325 void *isselfarg;
326
327 char * strnamerd;
328 char * strname;
329 char * strrdclass;
330 char * strviewname;
331
332 /*%
333 * Serial number for deferred journal compaction.
334 */
335 isc_uint32_t compact_serial;
336 /*%
337 * Keys that are signing the zone for the first time.
338 */
339 dns_signinglist_t signing;
340 dns_nsec3chainlist_t nsec3chain;
341 /*%
342 * Signing / re-signing quantum stopping parameters.
343 */
344 isc_uint32_t signatures;
345 isc_uint32_t nodes;
346 dns_rdatatype_t privatetype;
347
348 /*%
349 * Autosigning/key-maintenance options
350 */
351 isc_uint32_t keyopts;
352
353 /*%
354 * True if added by "rndc addzone"
355 */
356 isc_boolean_t added;
357
358 /*%
359 * whether this is a response policy zone
360 */
361 isc_boolean_t is_rpz;
362
363 /*%
364 * Serial number update method.
365 */
366 dns_updatemethod_t updatemethod;
367
368 /*%
369 * whether ixfr is requested
370 */
371 isc_boolean_t requestixfr;
372
373 /*%
374 * Outstanding forwarded UPDATE requests.
375 */
376 dns_forwardlist_t forwards;
377
378 dns_zone_t *raw;
379 dns_zone_t *secure;
380
381 isc_boolean_t sourceserialset;
382 isc_uint32_t sourceserial;
383
384 /*%
385 * maximum zone ttl
386 */
387 dns_ttl_t maxttl;
388
389 /*
390 * Inline zone signing state.
391 */
392 dns_diff_t rss_diff;
393 isc_eventlist_t rss_events;
394 dns_dbversion_t *rss_newver;
395 dns_dbversion_t *rss_oldver;
396 dns_db_t *rss_db;
397 dns_zone_t *rss_raw;
398 isc_event_t *rss_event;
399 dns_update_state_t *rss_state;
400 };
401
402 typedef struct {
403 dns_diff_t *diff;
404 isc_boolean_t offline;
405 } zonediff_t;
406
407 #define zonediff_init(z, d) \
408 do { \
409 zonediff_t *_z = (z); \
410 (_z)->diff = (d); \
411 (_z)->offline = ISC_FALSE; \
412 } while (0)
413
414 #define DNS_ZONE_FLAG(z,f) (ISC_TF(((z)->flags & (f)) != 0))
415 #define DNS_ZONE_SETFLAG(z,f) do { \
416 INSIST(LOCKED_ZONE(z)); \
417 (z)->flags |= (f); \
418 } while (0)
419 #define DNS_ZONE_CLRFLAG(z,f) do { \
420 INSIST(LOCKED_ZONE(z)); \
421 (z)->flags &= ~(f); \
422 } while (0)
423 /* XXX MPA these may need to go back into zone.h */
424 #define DNS_ZONEFLG_REFRESH 0x00000001U /*%< refresh check in progress */
425 #define DNS_ZONEFLG_NEEDDUMP 0x00000002U /*%< zone need consolidation */
426 #define DNS_ZONEFLG_USEVC 0x00000004U /*%< use tcp for refresh query */
427 #define DNS_ZONEFLG_DUMPING 0x00000008U /*%< a dump is in progress */
428 #define DNS_ZONEFLG_HASINCLUDE 0x00000010U /*%< $INCLUDE in zone file */
429 #define DNS_ZONEFLG_LOADED 0x00000020U /*%< database has loaded */
430 #define DNS_ZONEFLG_EXITING 0x00000040U /*%< zone is being destroyed */
431 #define DNS_ZONEFLG_EXPIRED 0x00000080U /*%< zone has expired */
432 #define DNS_ZONEFLG_NEEDREFRESH 0x00000100U /*%< refresh check needed */
433 #define DNS_ZONEFLG_UPTODATE 0x00000200U /*%< zone contents are
434 * uptodate */
435 #define DNS_ZONEFLG_NEEDNOTIFY 0x00000400U /*%< need to send out notify
436 * messages */
437 #define DNS_ZONEFLG_DIFFONRELOAD 0x00000800U /*%< generate a journal diff on
438 * reload */
439 #define DNS_ZONEFLG_NOMASTERS 0x00001000U /*%< an attempt to refresh a
440 * zone with no masters
441 * occurred */
442 #define DNS_ZONEFLG_LOADING 0x00002000U /*%< load from disk in progress*/
443 #define DNS_ZONEFLG_HAVETIMERS 0x00004000U /*%< timer values have been set
444 * from SOA (if not set, we
445 * are still using
446 * default timer values) */
447 #define DNS_ZONEFLG_FORCEXFER 0x00008000U /*%< Force a zone xfer */
448 #define DNS_ZONEFLG_NOREFRESH 0x00010000U
449 #define DNS_ZONEFLG_DIALNOTIFY 0x00020000U
450 #define DNS_ZONEFLG_DIALREFRESH 0x00040000U
451 #define DNS_ZONEFLG_SHUTDOWN 0x00080000U
452 #define DNS_ZONEFLAG_NOIXFR 0x00100000U /*%< IXFR failed, force AXFR */
453 #define DNS_ZONEFLG_FLUSH 0x00200000U
454 #define DNS_ZONEFLG_NOEDNS 0x00400000U
455 #define DNS_ZONEFLG_USEALTXFRSRC 0x00800000U
456 #define DNS_ZONEFLG_SOABEFOREAXFR 0x01000000U
457 #define DNS_ZONEFLG_NEEDCOMPACT 0x02000000U
458 #define DNS_ZONEFLG_REFRESHING 0x04000000U /*%< Refreshing keydata */
459 #define DNS_ZONEFLG_THAW 0x08000000U
460 #define DNS_ZONEFLG_LOADPENDING 0x10000000U /*%< Loading scheduled */
461 #define DNS_ZONEFLG_NODELAY 0x20000000U
462 #define DNS_ZONEFLG_SENDSECURE 0x40000000U
463 #define DNS_ZONEFLG_NEEDSTARTUPNOTIFY 0x80000000U /*%< need to send out notify
464 * due to the zone just
465 * being loaded for the
466 * first time. */
467
468 #define DNS_ZONE_OPTION(z,o) (((z)->options & (o)) != 0)
469 #define DNS_ZONEKEY_OPTION(z,o) (((z)->keyopts & (o)) != 0)
470
471 /* Flags for zone_load() */
472 #define DNS_ZONELOADFLAG_NOSTAT 0x00000001U /* Do not stat() master files */
473 #define DNS_ZONELOADFLAG_THAW 0x00000002U /* Thaw the zone on successful
474 load. */
475
476 #define UNREACH_CHACHE_SIZE 10U
477 #define UNREACH_HOLD_TIME 600 /* 10 minutes */
478
479 #define CHECK(op) \
480 do { result = (op); \
481 if (result != ISC_R_SUCCESS) goto failure; \
482 } while (0)
483
484 struct dns_unreachable {
485 isc_sockaddr_t remote;
486 isc_sockaddr_t local;
487 isc_uint32_t expire;
488 isc_uint32_t last;
489 isc_uint32_t count;
490 };
491
492 struct dns_zonemgr {
493 unsigned int magic;
494 isc_mem_t * mctx;
495 int refs; /* Locked by rwlock */
496 isc_taskmgr_t * taskmgr;
497 isc_timermgr_t * timermgr;
498 isc_socketmgr_t * socketmgr;
499 isc_taskpool_t * zonetasks;
500 isc_taskpool_t * loadtasks;
501 isc_task_t * task;
502 isc_pool_t * mctxpool;
503 isc_ratelimiter_t * notifyrl;
504 isc_ratelimiter_t * refreshrl;
505 isc_ratelimiter_t * startupnotifyrl;
506 isc_ratelimiter_t * startuprefreshrl;
507 isc_rwlock_t rwlock;
508 isc_mutex_t iolock;
509 isc_rwlock_t urlock;
510
511 /* Locked by rwlock. */
512 dns_zonelist_t zones;
513 dns_zonelist_t waiting_for_xfrin;
514 dns_zonelist_t xfrin_in_progress;
515
516 /* Configuration data. */
517 isc_uint32_t transfersin;
518 isc_uint32_t transfersperns;
519 unsigned int notifyrate;
520 unsigned int startupnotifyrate;
521 unsigned int serialqueryrate;
522 unsigned int startupserialqueryrate;
523
524 /* Locked by iolock */
525 isc_uint32_t iolimit;
526 isc_uint32_t ioactive;
527 dns_iolist_t high;
528 dns_iolist_t low;
529
530 /* Locked by urlock. */
531 /* LRU cache */
532 struct dns_unreachable unreachable[UNREACH_CHACHE_SIZE];
533 };
534
535 /*%
536 * Hold notify state.
537 */
538 struct dns_notify {
539 unsigned int magic;
540 unsigned int flags;
541 isc_mem_t *mctx;
542 dns_zone_t *zone;
543 dns_adbfind_t *find;
544 dns_request_t *request;
545 dns_name_t ns;
546 isc_sockaddr_t dst;
547 dns_tsigkey_t *key;
548 ISC_LINK(dns_notify_t) link;
549 isc_event_t *event;
550 };
551
552 #define DNS_NOTIFY_NOSOA 0x0001U
553 #define DNS_NOTIFY_STARTUP 0x0002U
554
555 /*%
556 * dns_stub holds state while performing a 'stub' transfer.
557 * 'db' is the zone's 'db' or a new one if this is the initial
558 * transfer.
559 */
560
561 struct dns_stub {
562 unsigned int magic;
563 isc_mem_t *mctx;
564 dns_zone_t *zone;
565 dns_db_t *db;
566 dns_dbversion_t *version;
567 };
568
569 /*%
570 * Hold load state.
571 */
572 struct dns_load {
573 unsigned int magic;
574 isc_mem_t *mctx;
575 dns_zone_t *zone;
576 dns_db_t *db;
577 isc_time_t loadtime;
578 dns_rdatacallbacks_t callbacks;
579 };
580
581 /*%
582 * Hold forward state.
583 */
584 struct dns_forward {
585 unsigned int magic;
586 isc_mem_t *mctx;
587 dns_zone_t *zone;
588 isc_buffer_t *msgbuf;
589 dns_request_t *request;
590 isc_uint32_t which;
591 isc_sockaddr_t addr;
592 dns_updatecallback_t callback;
593 void *callback_arg;
594 unsigned int options;
595 ISC_LINK(dns_forward_t) link;
596 };
597
598 /*%
599 * Hold IO request state.
600 */
601 struct dns_io {
602 unsigned int magic;
603 dns_zonemgr_t *zmgr;
604 isc_boolean_t high;
605 isc_task_t *task;
606 ISC_LINK(dns_io_t) link;
607 isc_event_t *event;
608 };
609
610 /*%
611 * Hold state for when we are signing a zone with a new
612 * DNSKEY as result of an update.
613 */
614 struct dns_signing {
615 unsigned int magic;
616 dns_db_t *db;
617 dns_dbiterator_t *dbiterator;
618 dns_secalg_t algorithm;
619 isc_uint16_t keyid;
620 isc_boolean_t delete;
621 isc_boolean_t done;
622 ISC_LINK(dns_signing_t) link;
623 };
624
625 struct dns_nsec3chain {
626 unsigned int magic;
627 dns_db_t *db;
628 dns_dbiterator_t *dbiterator;
629 dns_rdata_nsec3param_t nsec3param;
630 unsigned char salt[255];
631 isc_boolean_t done;
632 isc_boolean_t seen_nsec;
633 isc_boolean_t delete_nsec;
634 isc_boolean_t save_delete_nsec;
635 ISC_LINK(dns_nsec3chain_t) link;
636 };
637 /*%<
638 * 'dbiterator' contains a iterator for the database. If we are creating
639 * a NSEC3 chain only the non-NSEC3 nodes will be iterated. If we are
640 * removing a NSEC3 chain then both NSEC3 and non-NSEC3 nodes will be
641 * iterated.
642 *
643 * 'nsec3param' contains the parameters of the NSEC3 chain being created
644 * or removed.
645 *
646 * 'salt' is buffer space and is referenced via 'nsec3param.salt'.
647 *
648 * 'seen_nsec' will be set to true if, while iterating the zone to create a
649 * NSEC3 chain, a NSEC record is seen.
650 *
651 * 'delete_nsec' will be set to true if, at the completion of the creation
652 * of a NSEC3 chain, 'seen_nsec' is true. If 'delete_nsec' is true then we
653 * are in the process of deleting the NSEC chain.
654 *
655 * 'save_delete_nsec' is used to store the initial state of 'delete_nsec'
656 * so it can be recovered in the event of a error.
657 */
658
659 struct dns_keyfetch {
660 dns_fixedname_t name;
661 dns_rdataset_t keydataset;
662 dns_rdataset_t dnskeyset;
663 dns_rdataset_t dnskeysigset;
664 dns_zone_t *zone;
665 dns_db_t *db;
666 dns_fetch_t *fetch;
667 };
668
669 /*%
670 * Hold state for an asynchronous load
671 */
672 struct dns_asyncload {
673 dns_zone_t *zone;
674 dns_zt_zoneloaded_t loaded;
675 void *loaded_arg;
676 };
677
678 #define HOUR 3600
679 #define DAY (24*HOUR)
680 #define MONTH (30*DAY)
681
682 /*
683 * These can be overridden by the -T mkeytimers option on the command
684 * line, so that we can test with shorter periods than specified in
685 * RFC 5011.
686 */
687 unsigned int dns_zone_mkey_hour = HOUR;
688 unsigned int dns_zone_mkey_day = DAY;
689 unsigned int dns_zone_mkey_month = MONTH;
690
691 #define SEND_BUFFER_SIZE 2048
692
693 static void zone_settimer(dns_zone_t *, isc_time_t *);
694 static void cancel_refresh(dns_zone_t *);
695 static void zone_debuglog(dns_zone_t *zone, const char *, int debuglevel,
696 const char *msg, ...) ISC_FORMAT_PRINTF(4, 5);
697 static void notify_log(dns_zone_t *zone, int level, const char *fmt, ...)
698 ISC_FORMAT_PRINTF(3, 4);
699 static void queue_xfrin(dns_zone_t *zone);
700 static isc_result_t update_one_rr(dns_db_t *db, dns_dbversion_t *ver,
701 dns_diff_t *diff, dns_diffop_t op,
702 dns_name_t *name, dns_ttl_t ttl,
703 dns_rdata_t *rdata);
704 static void zone_unload(dns_zone_t *zone);
705 static void zone_expire(dns_zone_t *zone);
706 static void zone_iattach(dns_zone_t *source, dns_zone_t **target);
707 static void zone_idetach(dns_zone_t **zonep);
708 static isc_result_t zone_replacedb(dns_zone_t *zone, dns_db_t *db,
709 isc_boolean_t dump);
710 static inline void zone_attachdb(dns_zone_t *zone, dns_db_t *db);
711 static inline void zone_detachdb(dns_zone_t *zone);
712 static isc_result_t default_journal(dns_zone_t *zone);
713 static void zone_xfrdone(dns_zone_t *zone, isc_result_t result);
714 static isc_result_t zone_postload(dns_zone_t *zone, dns_db_t *db,
715 isc_time_t loadtime, isc_result_t result);
716 static void zone_needdump(dns_zone_t *zone, unsigned int delay);
717 static void zone_shutdown(isc_task_t *, isc_event_t *);
718 static void zone_loaddone(void *arg, isc_result_t result);
719 static isc_result_t zone_startload(dns_db_t *db, dns_zone_t *zone,
720 isc_time_t loadtime);
721 static void zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length);
722 static void zone_name_tostr(dns_zone_t *zone, char *buf, size_t length);
723 static void zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length);
724 static void zone_viewname_tostr(dns_zone_t *zone, char *buf, size_t length);
725 static isc_result_t zone_send_secureserial(dns_zone_t *zone,
726 isc_uint32_t serial);
727
728 #if 0
729 /* ondestroy example */
730 static void dns_zonemgr_dbdestroyed(isc_task_t *task, isc_event_t *event);
731 #endif
732
733 static void refresh_callback(isc_task_t *, isc_event_t *);
734 static void stub_callback(isc_task_t *, isc_event_t *);
735 static void queue_soa_query(dns_zone_t *zone);
736 static void soa_query(isc_task_t *, isc_event_t *);
737 static void ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset,
738 dns_stub_t *stub);
739 static int message_count(dns_message_t *msg, dns_section_t section,
740 dns_rdatatype_t type);
741 static void notify_cancel(dns_zone_t *zone);
742 static void notify_find_address(dns_notify_t *notify);
743 static void notify_send(dns_notify_t *notify);
744 static isc_result_t notify_createmessage(dns_zone_t *zone,
745 unsigned int flags,
746 dns_message_t **messagep);
747 static void notify_done(isc_task_t *task, isc_event_t *event);
748 static void notify_send_toaddr(isc_task_t *task, isc_event_t *event);
749 static isc_result_t zone_dump(dns_zone_t *, isc_boolean_t);
750 static void got_transfer_quota(isc_task_t *task, isc_event_t *event);
751 static isc_result_t zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr,
752 dns_zone_t *zone);
753 static void zmgr_resume_xfrs(dns_zonemgr_t *zmgr, isc_boolean_t multi);
754 static void zonemgr_free(dns_zonemgr_t *zmgr);
755 static isc_result_t zonemgr_getio(dns_zonemgr_t *zmgr, isc_boolean_t high,
756 isc_task_t *task, isc_taskaction_t action,
757 void *arg, dns_io_t **iop);
758 static void zonemgr_putio(dns_io_t **iop);
759 static void zonemgr_cancelio(dns_io_t *io);
760
761 static isc_result_t
762 zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount,
763 unsigned int *soacount, isc_uint32_t *serial,
764 isc_uint32_t *refresh, isc_uint32_t *retry,
765 isc_uint32_t *expire, isc_uint32_t *minimum,
766 unsigned int *errors);
767
768 static void zone_freedbargs(dns_zone_t *zone);
769 static void forward_callback(isc_task_t *task, isc_event_t *event);
770 static void zone_saveunique(dns_zone_t *zone, const char *path,
771 const char *templat);
772 static void zone_maintenance(dns_zone_t *zone);
773 static void zone_notify(dns_zone_t *zone, isc_time_t *now);
774 static void dump_done(void *arg, isc_result_t result);
775 static isc_result_t zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm,
776 isc_uint16_t keyid, isc_boolean_t delete);
777 static isc_result_t delete_nsec(dns_db_t *db, dns_dbversion_t *ver,
778 dns_dbnode_t *node, dns_name_t *name,
779 dns_diff_t *diff);
780 static void zone_rekey(dns_zone_t *zone);
781 static isc_result_t zone_send_securedb(dns_zone_t *zone, dns_db_t *db);
782 static void setrl(isc_ratelimiter_t *rl, unsigned int *rate,
783 unsigned int value);
784
785 #define ENTER zone_debuglog(zone, me, 1, "enter")
786
787 static const unsigned int dbargc_default = 1;
788 static const char *dbargv_default[] = { "rbt" };
789
790 #define DNS_ZONE_JITTER_ADD(a, b, c) \
791 do { \
792 isc_interval_t _i; \
793 isc_uint32_t _j; \
794 _j = isc_random_jitter((b), (b)/4); \
795 isc_interval_set(&_i, _j, 0); \
796 if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \
797 dns_zone_log(zone, ISC_LOG_WARNING, \
798 "epoch approaching: upgrade required: " \
799 "now + %s failed", #b); \
800 isc_interval_set(&_i, _j/2, 0); \
801 (void)isc_time_add((a), &_i, (c)); \
802 } \
803 } while (0)
804
805 #define DNS_ZONE_TIME_ADD(a, b, c) \
806 do { \
807 isc_interval_t _i; \
808 isc_interval_set(&_i, (b), 0); \
809 if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \
810 dns_zone_log(zone, ISC_LOG_WARNING, \
811 "epoch approaching: upgrade required: " \
812 "now + %s failed", #b); \
813 isc_interval_set(&_i, (b)/2, 0); \
814 (void)isc_time_add((a), &_i, (c)); \
815 } \
816 } while (0)
817
818 typedef struct nsec3param nsec3param_t;
819 struct nsec3param {
820 unsigned char data[DNS_NSEC3PARAM_BUFFERSIZE + 1];
821 unsigned int length;
822 isc_boolean_t nsec;
823 isc_boolean_t replace;
824 ISC_LINK(nsec3param_t) link;
825 };
826 typedef ISC_LIST(nsec3param_t) nsec3paramlist_t;
827 struct np3event {
828 isc_event_t event;
829 nsec3param_t params;
830 };
831
832 /*%
833 * Increment resolver-related statistics counters. Zone must be locked.
834 */
835 static inline void
inc_stats(dns_zone_t * zone,isc_statscounter_t counter)836 inc_stats(dns_zone_t *zone, isc_statscounter_t counter) {
837 if (zone->stats != NULL)
838 isc_stats_increment(zone->stats, counter);
839 }
840
841 /***
842 *** Public functions.
843 ***/
844
845 isc_result_t
dns_zone_create(dns_zone_t ** zonep,isc_mem_t * mctx)846 dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
847 isc_result_t result;
848 dns_zone_t *zone;
849 isc_time_t now;
850
851 REQUIRE(zonep != NULL && *zonep == NULL);
852 REQUIRE(mctx != NULL);
853
854 TIME_NOW(&now);
855 zone = isc_mem_get(mctx, sizeof(*zone));
856 if (zone == NULL)
857 return (ISC_R_NOMEMORY);
858
859 zone->mctx = NULL;
860 isc_mem_attach(mctx, &zone->mctx);
861
862 result = isc_mutex_init(&zone->lock);
863 if (result != ISC_R_SUCCESS)
864 goto free_zone;
865
866 result = ZONEDB_INITLOCK(&zone->dblock);
867 if (result != ISC_R_SUCCESS)
868 goto free_mutex;
869
870 /* XXX MPA check that all elements are initialised */
871 #ifdef DNS_ZONE_CHECKLOCK
872 zone->locked = ISC_FALSE;
873 #endif
874 zone->db = NULL;
875 zone->zmgr = NULL;
876 ISC_LINK_INIT(zone, link);
877 result = isc_refcount_init(&zone->erefs, 1); /* Implicit attach. */
878 if (result != ISC_R_SUCCESS)
879 goto free_dblock;
880 zone->irefs = 0;
881 dns_name_init(&zone->origin, NULL);
882 zone->strnamerd = NULL;
883 zone->strname = NULL;
884 zone->strrdclass = NULL;
885 zone->strviewname = NULL;
886 zone->masterfile = NULL;
887 zone->masterformat = dns_masterformat_none;
888 zone->keydirectory = NULL;
889 zone->journalsize = -1;
890 zone->journal = NULL;
891 zone->rdclass = dns_rdataclass_none;
892 zone->type = dns_zone_none;
893 zone->flags = 0;
894 zone->options = 0;
895 zone->keyopts = 0;
896 zone->db_argc = 0;
897 zone->db_argv = NULL;
898 isc_time_settoepoch(&zone->expiretime);
899 isc_time_settoepoch(&zone->refreshtime);
900 isc_time_settoepoch(&zone->dumptime);
901 isc_time_settoepoch(&zone->loadtime);
902 zone->notifytime = now;
903 isc_time_settoepoch(&zone->resigntime);
904 isc_time_settoepoch(&zone->keywarntime);
905 isc_time_settoepoch(&zone->signingtime);
906 isc_time_settoepoch(&zone->nsec3chaintime);
907 isc_time_settoepoch(&zone->refreshkeytime);
908 zone->refreshkeyinterval = 0;
909 zone->refreshkeycount = 0;
910 zone->refresh = DNS_ZONE_DEFAULTREFRESH;
911 zone->retry = DNS_ZONE_DEFAULTRETRY;
912 zone->expire = 0;
913 zone->minimum = 0;
914 zone->maxrefresh = DNS_ZONE_MAXREFRESH;
915 zone->minrefresh = DNS_ZONE_MINREFRESH;
916 zone->maxretry = DNS_ZONE_MAXRETRY;
917 zone->minretry = DNS_ZONE_MINRETRY;
918 zone->masters = NULL;
919 zone->masterkeynames = NULL;
920 zone->mastersok = NULL;
921 zone->masterscnt = 0;
922 zone->curmaster = 0;
923 zone->notify = NULL;
924 zone->notifykeynames = NULL;
925 zone->notifytype = dns_notifytype_yes;
926 zone->notifycnt = 0;
927 zone->task = NULL;
928 zone->loadtask = NULL;
929 zone->update_acl = NULL;
930 zone->forward_acl = NULL;
931 zone->notify_acl = NULL;
932 zone->query_acl = NULL;
933 zone->queryon_acl = NULL;
934 zone->xfr_acl = NULL;
935 zone->update_disabled = ISC_FALSE;
936 zone->zero_no_soa_ttl = ISC_TRUE;
937 zone->check_names = dns_severity_ignore;
938 zone->request = NULL;
939 zone->lctx = NULL;
940 zone->readio = NULL;
941 zone->dctx = NULL;
942 zone->writeio = NULL;
943 zone->timer = NULL;
944 zone->idlein = DNS_DEFAULT_IDLEIN;
945 zone->idleout = DNS_DEFAULT_IDLEOUT;
946 zone->log_key_expired_timer = 0;
947 ISC_LIST_INIT(zone->notifies);
948 isc_sockaddr_any(&zone->notifysrc4);
949 isc_sockaddr_any6(&zone->notifysrc6);
950 isc_sockaddr_any(&zone->xfrsource4);
951 isc_sockaddr_any6(&zone->xfrsource6);
952 isc_sockaddr_any(&zone->altxfrsource4);
953 isc_sockaddr_any6(&zone->altxfrsource6);
954 zone->xfr = NULL;
955 zone->tsigkey = NULL;
956 zone->maxxfrin = MAX_XFER_TIME;
957 zone->maxxfrout = MAX_XFER_TIME;
958 zone->ssutable = NULL;
959 zone->sigvalidityinterval = 30 * 24 * 3600;
960 zone->sigresigninginterval = 7 * 24 * 3600;
961 zone->view = NULL;
962 zone->acache = NULL;
963 zone->checkmx = NULL;
964 zone->checksrv = NULL;
965 zone->checkns = NULL;
966 ISC_LINK_INIT(zone, statelink);
967 zone->statelist = NULL;
968 zone->stats = NULL;
969 zone->requeststats_on = ISC_FALSE;
970 zone->statlevel = dns_zonestat_none;
971 zone->requeststats = NULL;
972 zone->rcvquerystats = NULL;
973 zone->notifydelay = 5;
974 zone->isself = NULL;
975 zone->isselfarg = NULL;
976 ISC_LIST_INIT(zone->signing);
977 ISC_LIST_INIT(zone->nsec3chain);
978 zone->signatures = 10;
979 zone->nodes = 100;
980 zone->privatetype = (dns_rdatatype_t)0xffffU;
981 zone->added = ISC_FALSE;
982 zone->is_rpz = ISC_FALSE;
983 ISC_LIST_INIT(zone->forwards);
984 zone->raw = NULL;
985 zone->secure = NULL;
986 zone->sourceserial = 0;
987 zone->sourceserialset = ISC_FALSE;
988 ISC_LIST_INIT(zone->rss_events);
989 zone->rss_db = NULL;
990 zone->rss_raw = NULL;
991 zone->rss_newver = NULL;
992 zone->rss_oldver = NULL;
993 zone->rss_event = NULL;
994 zone->rss_state = NULL;
995 zone->updatemethod = dns_updatemethod_increment;
996
997 zone->magic = ZONE_MAGIC;
998
999 /* Must be after magic is set. */
1000 result = dns_zone_setdbtype(zone, dbargc_default, dbargv_default);
1001 if (result != ISC_R_SUCCESS)
1002 goto free_erefs;
1003
1004 ISC_EVENT_INIT(&zone->ctlevent, sizeof(zone->ctlevent), 0, NULL,
1005 DNS_EVENT_ZONECONTROL, zone_shutdown, zone, zone,
1006 NULL, NULL);
1007 *zonep = zone;
1008 return (ISC_R_SUCCESS);
1009
1010 free_erefs:
1011 isc_refcount_decrement(&zone->erefs, NULL);
1012 isc_refcount_destroy(&zone->erefs);
1013
1014 free_dblock:
1015 ZONEDB_DESTROYLOCK(&zone->dblock);
1016
1017 free_mutex:
1018 DESTROYLOCK(&zone->lock);
1019
1020 free_zone:
1021 isc_mem_putanddetach(&zone->mctx, zone, sizeof(*zone));
1022 return (result);
1023 }
1024
1025 /*
1026 * Free a zone. Because we require that there be no more
1027 * outstanding events or references, no locking is necessary.
1028 */
1029 static void
zone_free(dns_zone_t * zone)1030 zone_free(dns_zone_t *zone) {
1031 isc_mem_t *mctx = NULL;
1032 dns_signing_t *signing;
1033 dns_nsec3chain_t *nsec3chain;
1034
1035 REQUIRE(DNS_ZONE_VALID(zone));
1036 REQUIRE(isc_refcount_current(&zone->erefs) == 0);
1037 REQUIRE(zone->irefs == 0);
1038 REQUIRE(!LOCKED_ZONE(zone));
1039 REQUIRE(zone->timer == NULL);
1040 REQUIRE(zone->zmgr == NULL);
1041
1042 /*
1043 * Managed objects. Order is important.
1044 */
1045 if (zone->request != NULL)
1046 dns_request_destroy(&zone->request); /* XXXMPA */
1047 INSIST(zone->readio == NULL);
1048 INSIST(zone->statelist == NULL);
1049 INSIST(zone->writeio == NULL);
1050
1051 if (zone->task != NULL)
1052 isc_task_detach(&zone->task);
1053 if (zone->loadtask != NULL)
1054 isc_task_detach(&zone->loadtask);
1055 if (zone->view != NULL)
1056 dns_view_weakdetach(&zone->view);
1057
1058 /* Unmanaged objects */
1059 for (signing = ISC_LIST_HEAD(zone->signing);
1060 signing != NULL;
1061 signing = ISC_LIST_HEAD(zone->signing)) {
1062 ISC_LIST_UNLINK(zone->signing, signing, link);
1063 dns_db_detach(&signing->db);
1064 dns_dbiterator_destroy(&signing->dbiterator);
1065 isc_mem_put(zone->mctx, signing, sizeof *signing);
1066 }
1067 for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
1068 nsec3chain != NULL;
1069 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain)) {
1070 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link);
1071 dns_db_detach(&nsec3chain->db);
1072 dns_dbiterator_destroy(&nsec3chain->dbiterator);
1073 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
1074 }
1075 if (zone->masterfile != NULL)
1076 isc_mem_free(zone->mctx, zone->masterfile);
1077 zone->masterfile = NULL;
1078 if (zone->keydirectory != NULL)
1079 isc_mem_free(zone->mctx, zone->keydirectory);
1080 zone->keydirectory = NULL;
1081 zone->journalsize = -1;
1082 if (zone->journal != NULL)
1083 isc_mem_free(zone->mctx, zone->journal);
1084 zone->journal = NULL;
1085 if (zone->stats != NULL)
1086 isc_stats_detach(&zone->stats);
1087 if (zone->requeststats != NULL)
1088 isc_stats_detach(&zone->requeststats);
1089 if(zone->rcvquerystats != NULL )
1090 dns_stats_detach(&zone->rcvquerystats);
1091 if (zone->db != NULL)
1092 zone_detachdb(zone);
1093 if (zone->acache != NULL)
1094 dns_acache_detach(&zone->acache);
1095 zone_freedbargs(zone);
1096 RUNTIME_CHECK(dns_zone_setmasterswithkeys(zone, NULL, NULL, 0)
1097 == ISC_R_SUCCESS);
1098 RUNTIME_CHECK(dns_zone_setalsonotify(zone, NULL, 0)
1099 == ISC_R_SUCCESS);
1100 zone->check_names = dns_severity_ignore;
1101 if (zone->update_acl != NULL)
1102 dns_acl_detach(&zone->update_acl);
1103 if (zone->forward_acl != NULL)
1104 dns_acl_detach(&zone->forward_acl);
1105 if (zone->notify_acl != NULL)
1106 dns_acl_detach(&zone->notify_acl);
1107 if (zone->query_acl != NULL)
1108 dns_acl_detach(&zone->query_acl);
1109 if (zone->queryon_acl != NULL)
1110 dns_acl_detach(&zone->queryon_acl);
1111 if (zone->xfr_acl != NULL)
1112 dns_acl_detach(&zone->xfr_acl);
1113 if (dns_name_dynamic(&zone->origin))
1114 dns_name_free(&zone->origin, zone->mctx);
1115 if (zone->strnamerd != NULL)
1116 isc_mem_free(zone->mctx, zone->strnamerd);
1117 if (zone->strname != NULL)
1118 isc_mem_free(zone->mctx, zone->strname);
1119 if (zone->strrdclass != NULL)
1120 isc_mem_free(zone->mctx, zone->strrdclass);
1121 if (zone->strviewname != NULL)
1122 isc_mem_free(zone->mctx, zone->strviewname);
1123 if (zone->ssutable != NULL)
1124 dns_ssutable_detach(&zone->ssutable);
1125
1126 /* last stuff */
1127 ZONEDB_DESTROYLOCK(&zone->dblock);
1128 DESTROYLOCK(&zone->lock);
1129 isc_refcount_destroy(&zone->erefs);
1130 zone->magic = 0;
1131 mctx = zone->mctx;
1132 isc_mem_put(mctx, zone, sizeof(*zone));
1133 isc_mem_detach(&mctx);
1134 }
1135
1136 /*
1137 * Returns ISC_TRUE iff this the signed side of an inline-signing zone.
1138 * Caller should hold zone lock.
1139 */
1140 static inline isc_boolean_t
inline_secure(dns_zone_t * zone)1141 inline_secure(dns_zone_t *zone) {
1142 REQUIRE(DNS_ZONE_VALID(zone));
1143 if (zone->raw != NULL)
1144 return (ISC_TRUE);
1145 return (ISC_FALSE);
1146 }
1147
1148 /*
1149 * Returns ISC_TRUE iff this the unsigned side of an inline-signing zone
1150 * Caller should hold zone lock.
1151 */
1152 static inline isc_boolean_t
inline_raw(dns_zone_t * zone)1153 inline_raw(dns_zone_t *zone) {
1154 REQUIRE(DNS_ZONE_VALID(zone));
1155 if (zone->secure != NULL)
1156 return (ISC_TRUE);
1157 return (ISC_FALSE);
1158 }
1159
1160 /*
1161 * Single shot.
1162 */
1163 void
dns_zone_setclass(dns_zone_t * zone,dns_rdataclass_t rdclass)1164 dns_zone_setclass(dns_zone_t *zone, dns_rdataclass_t rdclass) {
1165 char namebuf[1024];
1166
1167 REQUIRE(DNS_ZONE_VALID(zone));
1168 REQUIRE(rdclass != dns_rdataclass_none);
1169
1170 /*
1171 * Test and set.
1172 */
1173 LOCK_ZONE(zone);
1174 REQUIRE(zone->rdclass == dns_rdataclass_none ||
1175 zone->rdclass == rdclass);
1176 zone->rdclass = rdclass;
1177
1178 if (zone->strnamerd != NULL)
1179 isc_mem_free(zone->mctx, zone->strnamerd);
1180 if (zone->strrdclass != NULL)
1181 isc_mem_free(zone->mctx, zone->strrdclass);
1182
1183 zone_namerd_tostr(zone, namebuf, sizeof namebuf);
1184 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
1185 zone_rdclass_tostr(zone, namebuf, sizeof namebuf);
1186 zone->strrdclass = isc_mem_strdup(zone->mctx, namebuf);
1187
1188 if (inline_secure(zone))
1189 dns_zone_setclass(zone->raw, rdclass);
1190 UNLOCK_ZONE(zone);
1191 }
1192
1193 dns_rdataclass_t
dns_zone_getclass(dns_zone_t * zone)1194 dns_zone_getclass(dns_zone_t *zone) {
1195 REQUIRE(DNS_ZONE_VALID(zone));
1196
1197 return (zone->rdclass);
1198 }
1199
1200 void
dns_zone_setnotifytype(dns_zone_t * zone,dns_notifytype_t notifytype)1201 dns_zone_setnotifytype(dns_zone_t *zone, dns_notifytype_t notifytype) {
1202 REQUIRE(DNS_ZONE_VALID(zone));
1203
1204 LOCK_ZONE(zone);
1205 zone->notifytype = notifytype;
1206 UNLOCK_ZONE(zone);
1207 }
1208
1209 isc_result_t
dns_zone_getserial2(dns_zone_t * zone,isc_uint32_t * serialp)1210 dns_zone_getserial2(dns_zone_t *zone, isc_uint32_t *serialp) {
1211 isc_result_t result;
1212 unsigned int soacount;
1213
1214 REQUIRE(DNS_ZONE_VALID(zone));
1215 REQUIRE(serialp != NULL);
1216
1217 LOCK_ZONE(zone);
1218 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
1219 if (zone->db != NULL) {
1220 result = zone_get_from_db(zone, zone->db, NULL, &soacount,
1221 serialp, NULL, NULL, NULL, NULL,
1222 NULL);
1223 if (result == ISC_R_SUCCESS && soacount == 0)
1224 result = ISC_R_FAILURE;
1225 } else
1226 result = DNS_R_NOTLOADED;
1227 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
1228 UNLOCK_ZONE(zone);
1229
1230 return (result);
1231 }
1232
1233 isc_uint32_t
dns_zone_getserial(dns_zone_t * zone)1234 dns_zone_getserial(dns_zone_t *zone) {
1235 isc_result_t result;
1236 isc_uint32_t serial;
1237
1238 result = dns_zone_getserial2(zone, &serial);
1239 if (result != ISC_R_SUCCESS)
1240 serial = 0; /* XXX: not really correct, but no other choice */
1241
1242 return (serial);
1243 }
1244
1245 /*
1246 * Single shot.
1247 */
1248 void
dns_zone_settype(dns_zone_t * zone,dns_zonetype_t type)1249 dns_zone_settype(dns_zone_t *zone, dns_zonetype_t type) {
1250 char namebuf[1024];
1251
1252 REQUIRE(DNS_ZONE_VALID(zone));
1253 REQUIRE(type != dns_zone_none);
1254
1255 /*
1256 * Test and set.
1257 */
1258 LOCK_ZONE(zone);
1259 REQUIRE(zone->type == dns_zone_none || zone->type == type);
1260 zone->type = type;
1261
1262 if (zone->strnamerd != NULL)
1263 isc_mem_free(zone->mctx, zone->strnamerd);
1264
1265 zone_namerd_tostr(zone, namebuf, sizeof namebuf);
1266 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
1267 UNLOCK_ZONE(zone);
1268 }
1269
1270 static void
zone_freedbargs(dns_zone_t * zone)1271 zone_freedbargs(dns_zone_t *zone) {
1272 unsigned int i;
1273
1274 /* Free the old database argument list. */
1275 if (zone->db_argv != NULL) {
1276 for (i = 0; i < zone->db_argc; i++)
1277 isc_mem_free(zone->mctx, zone->db_argv[i]);
1278 isc_mem_put(zone->mctx, zone->db_argv,
1279 zone->db_argc * sizeof(*zone->db_argv));
1280 }
1281 zone->db_argc = 0;
1282 zone->db_argv = NULL;
1283 }
1284
1285 isc_result_t
dns_zone_getdbtype(dns_zone_t * zone,char *** argv,isc_mem_t * mctx)1286 dns_zone_getdbtype(dns_zone_t *zone, char ***argv, isc_mem_t *mctx) {
1287 size_t size = 0;
1288 unsigned int i;
1289 isc_result_t result = ISC_R_SUCCESS;
1290 void *mem;
1291 char **tmp, *tmp2;
1292
1293 REQUIRE(DNS_ZONE_VALID(zone));
1294 REQUIRE(argv != NULL && *argv == NULL);
1295
1296 LOCK_ZONE(zone);
1297 size = (zone->db_argc + 1) * sizeof(char *);
1298 for (i = 0; i < zone->db_argc; i++)
1299 size += strlen(zone->db_argv[i]) + 1;
1300 mem = isc_mem_allocate(mctx, size);
1301 if (mem != NULL) {
1302 tmp = mem;
1303 tmp2 = mem;
1304 tmp2 += (zone->db_argc + 1) * sizeof(char *);
1305 for (i = 0; i < zone->db_argc; i++) {
1306 *tmp++ = tmp2;
1307 strcpy(tmp2, zone->db_argv[i]);
1308 tmp2 += strlen(tmp2) + 1;
1309 }
1310 *tmp = NULL;
1311 } else
1312 result = ISC_R_NOMEMORY;
1313 UNLOCK_ZONE(zone);
1314 *argv = mem;
1315 return (result);
1316 }
1317
1318 isc_result_t
dns_zone_setdbtype(dns_zone_t * zone,unsigned int dbargc,const char * const * dbargv)1319 dns_zone_setdbtype(dns_zone_t *zone,
1320 unsigned int dbargc, const char * const *dbargv) {
1321 isc_result_t result = ISC_R_SUCCESS;
1322 char **new = NULL;
1323 unsigned int i;
1324
1325 REQUIRE(DNS_ZONE_VALID(zone));
1326 REQUIRE(dbargc >= 1);
1327 REQUIRE(dbargv != NULL);
1328
1329 LOCK_ZONE(zone);
1330
1331 /* Set up a new database argument list. */
1332 new = isc_mem_get(zone->mctx, dbargc * sizeof(*new));
1333 if (new == NULL)
1334 goto nomem;
1335 for (i = 0; i < dbargc; i++)
1336 new[i] = NULL;
1337 for (i = 0; i < dbargc; i++) {
1338 new[i] = isc_mem_strdup(zone->mctx, dbargv[i]);
1339 if (new[i] == NULL)
1340 goto nomem;
1341 }
1342
1343 /* Free the old list. */
1344 zone_freedbargs(zone);
1345
1346 zone->db_argc = dbargc;
1347 zone->db_argv = new;
1348 result = ISC_R_SUCCESS;
1349 goto unlock;
1350
1351 nomem:
1352 if (new != NULL) {
1353 for (i = 0; i < dbargc; i++)
1354 if (new[i] != NULL)
1355 isc_mem_free(zone->mctx, new[i]);
1356 isc_mem_put(zone->mctx, new, dbargc * sizeof(*new));
1357 }
1358 result = ISC_R_NOMEMORY;
1359
1360 unlock:
1361 UNLOCK_ZONE(zone);
1362 return (result);
1363 }
1364
1365 void
dns_zone_setview(dns_zone_t * zone,dns_view_t * view)1366 dns_zone_setview(dns_zone_t *zone, dns_view_t *view) {
1367 char namebuf[1024];
1368 REQUIRE(DNS_ZONE_VALID(zone));
1369
1370 LOCK_ZONE(zone);
1371 if (zone->view != NULL)
1372 dns_view_weakdetach(&zone->view);
1373 dns_view_weakattach(view, &zone->view);
1374
1375 if (zone->strviewname != NULL)
1376 isc_mem_free(zone->mctx, zone->strviewname);
1377 if (zone->strnamerd != NULL)
1378 isc_mem_free(zone->mctx, zone->strnamerd);
1379
1380 zone_namerd_tostr(zone, namebuf, sizeof namebuf);
1381 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
1382 zone_viewname_tostr(zone, namebuf, sizeof namebuf);
1383 zone->strviewname = isc_mem_strdup(zone->mctx, namebuf);
1384
1385 if (inline_secure(zone))
1386 dns_zone_setview(zone->raw, view);
1387
1388 UNLOCK_ZONE(zone);
1389 }
1390
1391 dns_view_t *
dns_zone_getview(dns_zone_t * zone)1392 dns_zone_getview(dns_zone_t *zone) {
1393 REQUIRE(DNS_ZONE_VALID(zone));
1394
1395 return (zone->view);
1396 }
1397
1398
1399 isc_result_t
dns_zone_setorigin(dns_zone_t * zone,const dns_name_t * origin)1400 dns_zone_setorigin(dns_zone_t *zone, const dns_name_t *origin) {
1401 isc_result_t result;
1402 char namebuf[1024];
1403
1404 REQUIRE(DNS_ZONE_VALID(zone));
1405 REQUIRE(origin != NULL);
1406
1407 LOCK_ZONE(zone);
1408 if (dns_name_dynamic(&zone->origin)) {
1409 dns_name_free(&zone->origin, zone->mctx);
1410 dns_name_init(&zone->origin, NULL);
1411 }
1412 result = dns_name_dup(origin, zone->mctx, &zone->origin);
1413
1414 if (zone->strnamerd != NULL)
1415 isc_mem_free(zone->mctx, zone->strnamerd);
1416 if (zone->strname != NULL)
1417 isc_mem_free(zone->mctx, zone->strname);
1418
1419 zone_namerd_tostr(zone, namebuf, sizeof namebuf);
1420 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
1421 zone_name_tostr(zone, namebuf, sizeof namebuf);
1422 zone->strname = isc_mem_strdup(zone->mctx, namebuf);
1423
1424 if (result == ISC_R_SUCCESS && inline_secure(zone))
1425 result = dns_zone_setorigin(zone->raw, origin);
1426 UNLOCK_ZONE(zone);
1427 return (result);
1428 }
1429
1430 void
dns_zone_setacache(dns_zone_t * zone,dns_acache_t * acache)1431 dns_zone_setacache(dns_zone_t *zone, dns_acache_t *acache) {
1432 REQUIRE(DNS_ZONE_VALID(zone));
1433 REQUIRE(acache != NULL);
1434
1435 LOCK_ZONE(zone);
1436 if (zone->acache != NULL)
1437 dns_acache_detach(&zone->acache);
1438 dns_acache_attach(acache, &zone->acache);
1439 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
1440 if (zone->db != NULL) {
1441 isc_result_t result;
1442
1443 /*
1444 * If the zone reuses an existing DB, the DB needs to be
1445 * set in the acache explicitly. We can safely ignore the
1446 * case where the DB is already set. If other error happens,
1447 * the acache will not work effectively.
1448 */
1449 result = dns_acache_setdb(acache, zone->db);
1450 if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) {
1451 UNEXPECTED_ERROR(__FILE__, __LINE__,
1452 "dns_acache_setdb() failed: %s",
1453 isc_result_totext(result));
1454 }
1455 }
1456 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
1457 UNLOCK_ZONE(zone);
1458 }
1459
1460 static isc_result_t
dns_zone_setstring(dns_zone_t * zone,char ** field,const char * value)1461 dns_zone_setstring(dns_zone_t *zone, char **field, const char *value) {
1462 char *copy;
1463
1464 if (value != NULL) {
1465 copy = isc_mem_strdup(zone->mctx, value);
1466 if (copy == NULL)
1467 return (ISC_R_NOMEMORY);
1468 } else {
1469 copy = NULL;
1470 }
1471
1472 if (*field != NULL)
1473 isc_mem_free(zone->mctx, *field);
1474
1475 *field = copy;
1476 return (ISC_R_SUCCESS);
1477 }
1478
1479 isc_result_t
dns_zone_setfile(dns_zone_t * zone,const char * file)1480 dns_zone_setfile(dns_zone_t *zone, const char *file) {
1481 return (dns_zone_setfile2(zone, file, dns_masterformat_text));
1482 }
1483
1484 isc_result_t
dns_zone_setfile2(dns_zone_t * zone,const char * file,dns_masterformat_t format)1485 dns_zone_setfile2(dns_zone_t *zone, const char *file,
1486 dns_masterformat_t format) {
1487 isc_result_t result = ISC_R_SUCCESS;
1488
1489 REQUIRE(DNS_ZONE_VALID(zone));
1490
1491 LOCK_ZONE(zone);
1492 result = dns_zone_setstring(zone, &zone->masterfile, file);
1493 if (result == ISC_R_SUCCESS) {
1494 zone->masterformat = format;
1495 result = default_journal(zone);
1496 }
1497 UNLOCK_ZONE(zone);
1498
1499 return (result);
1500 }
1501
1502 const char *
dns_zone_getfile(dns_zone_t * zone)1503 dns_zone_getfile(dns_zone_t *zone) {
1504 REQUIRE(DNS_ZONE_VALID(zone));
1505
1506 return (zone->masterfile);
1507 }
1508
1509 static isc_result_t
default_journal(dns_zone_t * zone)1510 default_journal(dns_zone_t *zone) {
1511 isc_result_t result;
1512 char *journal;
1513
1514 REQUIRE(DNS_ZONE_VALID(zone));
1515 REQUIRE(LOCKED_ZONE(zone));
1516
1517 if (zone->masterfile != NULL) {
1518 /* Calculate string length including '\0'. */
1519 int len = strlen(zone->masterfile) + sizeof(".jnl");
1520 journal = isc_mem_allocate(zone->mctx, len);
1521 if (journal == NULL)
1522 return (ISC_R_NOMEMORY);
1523 strcpy(journal, zone->masterfile);
1524 strcat(journal, ".jnl");
1525 } else {
1526 journal = NULL;
1527 }
1528 result = dns_zone_setstring(zone, &zone->journal, journal);
1529 if (journal != NULL)
1530 isc_mem_free(zone->mctx, journal);
1531 return (result);
1532 }
1533
1534 isc_result_t
dns_zone_setjournal(dns_zone_t * zone,const char * journal)1535 dns_zone_setjournal(dns_zone_t *zone, const char *journal) {
1536 isc_result_t result = ISC_R_SUCCESS;
1537
1538 REQUIRE(DNS_ZONE_VALID(zone));
1539
1540 LOCK_ZONE(zone);
1541 result = dns_zone_setstring(zone, &zone->journal, journal);
1542 UNLOCK_ZONE(zone);
1543
1544 return (result);
1545 }
1546
1547 char *
dns_zone_getjournal(dns_zone_t * zone)1548 dns_zone_getjournal(dns_zone_t *zone) {
1549 REQUIRE(DNS_ZONE_VALID(zone));
1550
1551 return (zone->journal);
1552 }
1553
1554 /*
1555 * Return true iff the zone is "dynamic", in the sense that the zone's
1556 * master file (if any) is written by the server, rather than being
1557 * updated manually and read by the server.
1558 *
1559 * This is true for slave zones, stub zones, key zones, and zones that
1560 * allow dynamic updates either by having an update policy ("ssutable")
1561 * or an "allow-update" ACL with a value other than exactly "{ none; }".
1562 */
1563 isc_boolean_t
dns_zone_isdynamic(dns_zone_t * zone,isc_boolean_t ignore_freeze)1564 dns_zone_isdynamic(dns_zone_t *zone, isc_boolean_t ignore_freeze) {
1565 REQUIRE(DNS_ZONE_VALID(zone));
1566
1567 if (zone->type == dns_zone_slave || zone->type == dns_zone_stub ||
1568 zone->type == dns_zone_key ||
1569 (zone->type == dns_zone_redirect && zone->masters != NULL))
1570 return (ISC_TRUE);
1571
1572 /* If !ignore_freeze, we need check whether updates are disabled. */
1573 if (zone->type == dns_zone_master &&
1574 (!zone->update_disabled || ignore_freeze) &&
1575 ((zone->ssutable != NULL) ||
1576 (zone->update_acl != NULL && !dns_acl_isnone(zone->update_acl))))
1577 return (ISC_TRUE);
1578
1579 return (ISC_FALSE);
1580
1581 }
1582
1583 /*
1584 * Set the response policy index and information for a zone.
1585 */
1586 isc_result_t
dns_zone_rpz_enable(dns_zone_t * zone)1587 dns_zone_rpz_enable(dns_zone_t *zone) {
1588 /*
1589 * Only RBTDB zones can be used for response policy zones,
1590 * because only they have the code to load the create the summary data.
1591 * Only zones that are loaded instead of mmap()ed create the
1592 * summary data and so can be policy zones.
1593 */
1594 if (strcmp(zone->db_argv[0], "rbt") != 0 &&
1595 strcmp(zone->db_argv[0], "rbt64") != 0)
1596 return (ISC_R_NOTIMPLEMENTED);
1597
1598 zone->is_rpz = ISC_TRUE;
1599
1600 return (ISC_R_SUCCESS);
1601 }
1602
1603 isc_boolean_t
dns_zone_get_rpz(dns_zone_t * zone)1604 dns_zone_get_rpz(dns_zone_t *zone) {
1605 return (zone->is_rpz);
1606 }
1607
1608 /*
1609 * If a zone is a response policy zone, mark its new database.
1610 */
1611 isc_result_t
dns_zone_rpz_enable_db(dns_zone_t * zone,dns_db_t * db)1612 dns_zone_rpz_enable_db(dns_zone_t *zone, dns_db_t *db) {
1613 #ifdef BIND9
1614 if (zone->is_rpz)
1615 return (dns_db_rpz_enabled(db, NULL));
1616 #endif
1617 return (ISC_R_SUCCESS);
1618 }
1619
1620 static isc_result_t
zone_load(dns_zone_t * zone,unsigned int flags,isc_boolean_t locked)1621 zone_load(dns_zone_t *zone, unsigned int flags, isc_boolean_t locked) {
1622 isc_result_t result;
1623 isc_time_t now;
1624 isc_time_t loadtime, filetime;
1625 dns_db_t *db = NULL;
1626 isc_boolean_t rbt, hasraw;
1627
1628 REQUIRE(DNS_ZONE_VALID(zone));
1629
1630 if (!locked)
1631 LOCK_ZONE(zone);
1632 hasraw = inline_secure(zone);
1633 if (hasraw) {
1634 result = zone_load(zone->raw, flags, ISC_FALSE);
1635 if (result != ISC_R_SUCCESS) {
1636 if (!locked)
1637 UNLOCK_ZONE(zone);
1638 return(result);
1639 }
1640 LOCK_ZONE(zone->raw);
1641 }
1642
1643 TIME_NOW(&now);
1644
1645 INSIST(zone->type != dns_zone_none);
1646
1647 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING)) {
1648 if ((flags & DNS_ZONELOADFLAG_THAW) != 0)
1649 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW);
1650 result = DNS_R_CONTINUE;
1651 goto cleanup;
1652 }
1653
1654 INSIST(zone->db_argc >= 1);
1655
1656 rbt = strcmp(zone->db_argv[0], "rbt") == 0 ||
1657 strcmp(zone->db_argv[0], "rbt64") == 0;
1658
1659 if (zone->db != NULL && zone->masterfile == NULL && rbt) {
1660 /*
1661 * The zone has no master file configured.
1662 */
1663 result = ISC_R_SUCCESS;
1664 goto cleanup;
1665 }
1666
1667 if (zone->db != NULL && dns_zone_isdynamic(zone, ISC_FALSE)) {
1668 /*
1669 * This is a slave, stub, or dynamically updated
1670 * zone being reloaded. Do nothing - the database
1671 * we already have is guaranteed to be up-to-date.
1672 */
1673 if (zone->type == dns_zone_master)
1674 result = DNS_R_DYNAMIC;
1675 else
1676 result = ISC_R_SUCCESS;
1677 goto cleanup;
1678 }
1679
1680 /*
1681 * Store the current time before the zone is loaded, so that if the
1682 * file changes between the time of the load and the time that
1683 * zone->loadtime is set, then the file will still be reloaded
1684 * the next time dns_zone_load is called.
1685 */
1686 TIME_NOW(&loadtime);
1687
1688 /*
1689 * Don't do the load if the file that stores the zone is older
1690 * than the last time the zone was loaded. If the zone has not
1691 * been loaded yet, zone->loadtime will be the epoch.
1692 */
1693 if (zone->masterfile != NULL) {
1694 /*
1695 * The file is already loaded. If we are just doing a
1696 * "rndc reconfig", we are done.
1697 */
1698 if (!isc_time_isepoch(&zone->loadtime) &&
1699 (flags & DNS_ZONELOADFLAG_NOSTAT) != 0) {
1700 result = ISC_R_SUCCESS;
1701 goto cleanup;
1702 }
1703
1704 result = isc_file_getmodtime(zone->masterfile, &filetime);
1705 if (result == ISC_R_SUCCESS) {
1706 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
1707 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE) &&
1708 isc_time_compare(&filetime, &zone->loadtime) <= 0) {
1709 dns_zone_log(zone, ISC_LOG_DEBUG(1),
1710 "skipping load: master file "
1711 "older than last load");
1712 result = DNS_R_UPTODATE;
1713 goto cleanup;
1714 }
1715 loadtime = filetime;
1716 }
1717 }
1718
1719 /*
1720 * Built in zones (with the exception of empty zones) don't need
1721 * to be reloaded.
1722 */
1723 if (zone->type == dns_zone_master &&
1724 strcmp(zone->db_argv[0], "_builtin") == 0 &&
1725 (zone->db_argc < 2 || strcmp(zone->db_argv[1], "empty") != 0) &&
1726 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
1727 result = ISC_R_SUCCESS;
1728 goto cleanup;
1729 }
1730
1731 if ((zone->type == dns_zone_slave || zone->type == dns_zone_stub ||
1732 (zone->type == dns_zone_redirect && zone->masters != NULL)) &&
1733 rbt) {
1734 if (zone->masterfile == NULL ||
1735 !isc_file_exists(zone->masterfile)) {
1736 if (zone->masterfile != NULL) {
1737 dns_zone_log(zone, ISC_LOG_DEBUG(1),
1738 "no master file");
1739 }
1740 zone->refreshtime = now;
1741 if (zone->task != NULL)
1742 zone_settimer(zone, &now);
1743 result = ISC_R_SUCCESS;
1744 goto cleanup;
1745 }
1746 }
1747
1748 dns_zone_log(zone, ISC_LOG_DEBUG(1), "starting load");
1749
1750 result = dns_db_create(zone->mctx, zone->db_argv[0],
1751 &zone->origin, (zone->type == dns_zone_stub) ?
1752 dns_dbtype_stub : dns_dbtype_zone,
1753 zone->rdclass,
1754 zone->db_argc - 1, zone->db_argv + 1,
1755 &db);
1756
1757 if (result != ISC_R_SUCCESS) {
1758 dns_zone_log(zone, ISC_LOG_ERROR,
1759 "loading zone: creating database: %s",
1760 isc_result_totext(result));
1761 goto cleanup;
1762 }
1763 dns_db_settask(db, zone->task);
1764
1765 if (! dns_db_ispersistent(db)) {
1766 if (zone->masterfile != NULL) {
1767 result = zone_startload(db, zone, loadtime);
1768 } else {
1769 result = DNS_R_NOMASTERFILE;
1770 if (zone->type == dns_zone_master ||
1771 (zone->type == dns_zone_redirect &&
1772 zone->masters == NULL)) {
1773 dns_zone_log(zone, ISC_LOG_ERROR,
1774 "loading zone: "
1775 "no master file configured");
1776 goto cleanup;
1777 }
1778 dns_zone_log(zone, ISC_LOG_INFO, "loading zone: "
1779 "no master file configured: continuing");
1780 }
1781 }
1782
1783 if (result == DNS_R_CONTINUE) {
1784 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADING);
1785 if ((flags & DNS_ZONELOADFLAG_THAW) != 0)
1786 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW);
1787 goto cleanup;
1788 }
1789
1790 result = zone_postload(zone, db, loadtime, result);
1791
1792 cleanup:
1793 if (hasraw)
1794 UNLOCK_ZONE(zone->raw);
1795 if (!locked)
1796 UNLOCK_ZONE(zone);
1797 if (db != NULL)
1798 dns_db_detach(&db);
1799 return (result);
1800 }
1801
1802 isc_result_t
dns_zone_load(dns_zone_t * zone)1803 dns_zone_load(dns_zone_t *zone) {
1804 return (zone_load(zone, 0, ISC_FALSE));
1805 }
1806
1807 isc_result_t
dns_zone_loadnew(dns_zone_t * zone)1808 dns_zone_loadnew(dns_zone_t *zone) {
1809 return (zone_load(zone, DNS_ZONELOADFLAG_NOSTAT, ISC_FALSE));
1810 }
1811
1812 static void
zone_asyncload(isc_task_t * task,isc_event_t * event)1813 zone_asyncload(isc_task_t *task, isc_event_t *event) {
1814 dns_asyncload_t *asl = event->ev_arg;
1815 dns_zone_t *zone = asl->zone;
1816 isc_result_t result = ISC_R_SUCCESS;
1817 isc_boolean_t load_pending;
1818
1819 UNUSED(task);
1820
1821 REQUIRE(DNS_ZONE_VALID(zone));
1822
1823 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0)
1824 result = ISC_R_CANCELED;
1825 isc_event_free(&event);
1826
1827 if (result == ISC_R_CANCELED)
1828 goto cleanup;
1829
1830 /* Make sure load is still pending */
1831 LOCK_ZONE(zone);
1832 load_pending = ISC_TF(DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING));
1833
1834 if (!load_pending) {
1835 UNLOCK_ZONE(zone);
1836 goto cleanup;
1837 }
1838
1839 zone_load(zone, 0, ISC_TRUE);
1840
1841 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADPENDING);
1842 UNLOCK_ZONE(zone);
1843
1844 /* Inform the zone table we've finished loading */
1845 if (asl->loaded != NULL)
1846 (asl->loaded)(asl->loaded_arg, zone, task);
1847
1848 cleanup:
1849 isc_mem_put(zone->mctx, asl, sizeof (*asl));
1850 dns_zone_idetach(&zone);
1851 }
1852
1853 isc_result_t
dns_zone_asyncload(dns_zone_t * zone,dns_zt_zoneloaded_t done,void * arg)1854 dns_zone_asyncload(dns_zone_t *zone, dns_zt_zoneloaded_t done, void *arg) {
1855 isc_event_t *e;
1856 dns_asyncload_t *asl = NULL;
1857 isc_result_t result = ISC_R_SUCCESS;
1858
1859 REQUIRE(DNS_ZONE_VALID(zone));
1860
1861 if (zone->zmgr == NULL)
1862 return (ISC_R_FAILURE);
1863
1864 /* If we already have a load pending, stop now */
1865 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING))
1866 return (ISC_R_ALREADYRUNNING);
1867
1868 asl = isc_mem_get(zone->mctx, sizeof (*asl));
1869 if (asl == NULL)
1870 CHECK(ISC_R_NOMEMORY);
1871
1872 asl->zone = NULL;
1873 asl->loaded = done;
1874 asl->loaded_arg = arg;
1875
1876 e = isc_event_allocate(zone->zmgr->mctx, zone->zmgr,
1877 DNS_EVENT_ZONELOAD,
1878 zone_asyncload, asl,
1879 sizeof(isc_event_t));
1880 if (e == NULL)
1881 CHECK(ISC_R_NOMEMORY);
1882
1883 LOCK_ZONE(zone);
1884 zone_iattach(zone, &asl->zone);
1885 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADPENDING);
1886 isc_task_send(zone->loadtask, &e);
1887 UNLOCK_ZONE(zone);
1888
1889 return (ISC_R_SUCCESS);
1890
1891 failure:
1892 if (asl != NULL)
1893 isc_mem_put(zone->mctx, asl, sizeof (*asl));
1894 return (result);
1895 }
1896
1897 isc_boolean_t
dns__zone_loadpending(dns_zone_t * zone)1898 dns__zone_loadpending(dns_zone_t *zone) {
1899 REQUIRE(DNS_ZONE_VALID(zone));
1900
1901 return (ISC_TF(DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING)));
1902 }
1903
1904 isc_result_t
dns_zone_loadandthaw(dns_zone_t * zone)1905 dns_zone_loadandthaw(dns_zone_t *zone) {
1906 isc_result_t result;
1907
1908 if (inline_raw(zone))
1909 result = zone_load(zone->secure, DNS_ZONELOADFLAG_THAW,
1910 ISC_FALSE);
1911 else
1912 result = zone_load(zone, DNS_ZONELOADFLAG_THAW, ISC_FALSE);
1913
1914 switch (result) {
1915 case DNS_R_CONTINUE:
1916 /* Deferred thaw. */
1917 break;
1918 case DNS_R_UPTODATE:
1919 case ISC_R_SUCCESS:
1920 case DNS_R_SEENINCLUDE:
1921 zone->update_disabled = ISC_FALSE;
1922 break;
1923 case DNS_R_NOMASTERFILE:
1924 zone->update_disabled = ISC_FALSE;
1925 break;
1926 default:
1927 /* Error, remain in disabled state. */
1928 break;
1929 }
1930 return (result);
1931 }
1932
1933 static unsigned int
get_master_options(dns_zone_t * zone)1934 get_master_options(dns_zone_t *zone) {
1935 unsigned int options;
1936
1937 options = DNS_MASTER_ZONE;
1938 if (zone->type == dns_zone_slave ||
1939 (zone->type == dns_zone_redirect && zone->masters == NULL))
1940 options |= DNS_MASTER_SLAVE;
1941 if (zone->type == dns_zone_key)
1942 options |= DNS_MASTER_KEY;
1943 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNS))
1944 options |= DNS_MASTER_CHECKNS;
1945 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_FATALNS))
1946 options |= DNS_MASTER_FATALNS;
1947 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES))
1948 options |= DNS_MASTER_CHECKNAMES;
1949 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL))
1950 options |= DNS_MASTER_CHECKNAMESFAIL;
1951 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMX))
1952 options |= DNS_MASTER_CHECKMX;
1953 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMXFAIL))
1954 options |= DNS_MASTER_CHECKMXFAIL;
1955 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKWILDCARD))
1956 options |= DNS_MASTER_CHECKWILDCARD;
1957 if (inline_secure(zone) || (zone->type == dns_zone_master &&
1958 ((zone->update_acl != NULL && !dns_acl_isnone(zone->update_acl)) ||
1959 zone->ssutable != NULL)))
1960 options |= DNS_MASTER_RESIGN;
1961 return (options);
1962 }
1963
1964 static void
zone_gotreadhandle(isc_task_t * task,isc_event_t * event)1965 zone_gotreadhandle(isc_task_t *task, isc_event_t *event) {
1966 dns_load_t *load = event->ev_arg;
1967 isc_result_t result = ISC_R_SUCCESS;
1968 unsigned int options;
1969
1970 REQUIRE(DNS_LOAD_VALID(load));
1971
1972 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0)
1973 result = ISC_R_CANCELED;
1974 isc_event_free(&event);
1975 if (result == ISC_R_CANCELED)
1976 goto fail;
1977
1978 options = get_master_options(load->zone);
1979
1980 result = dns_master_loadfileinc3(load->zone->masterfile,
1981 dns_db_origin(load->db),
1982 dns_db_origin(load->db),
1983 load->zone->rdclass, options, 0,
1984 &load->callbacks, task,
1985 zone_loaddone, load,
1986 &load->zone->lctx, load->zone->mctx,
1987 load->zone->masterformat);
1988 if (result != ISC_R_SUCCESS && result != DNS_R_CONTINUE &&
1989 result != DNS_R_SEENINCLUDE)
1990 goto fail;
1991 return;
1992
1993 fail:
1994 zone_loaddone(load, result);
1995 }
1996
1997 static void
get_raw_serial(dns_zone_t * raw,dns_masterrawheader_t * rawdata)1998 get_raw_serial(dns_zone_t *raw, dns_masterrawheader_t *rawdata) {
1999 isc_result_t result;
2000 unsigned int soacount;
2001
2002 LOCK(&raw->lock);
2003 if (raw->db != NULL) {
2004 result = zone_get_from_db(raw, raw->db, NULL, &soacount,
2005 &rawdata->sourceserial,
2006 NULL, NULL, NULL, NULL,
2007 NULL);
2008 if (result == ISC_R_SUCCESS && soacount > 0U)
2009 rawdata->flags |= DNS_MASTERRAW_SOURCESERIALSET;
2010 }
2011 UNLOCK(&raw->lock);
2012 }
2013
2014 static void
zone_gotwritehandle(isc_task_t * task,isc_event_t * event)2015 zone_gotwritehandle(isc_task_t *task, isc_event_t *event) {
2016 const char me[] = "zone_gotwritehandle";
2017 dns_zone_t *zone = event->ev_arg;
2018 isc_result_t result = ISC_R_SUCCESS;
2019 dns_dbversion_t *version = NULL;
2020 dns_masterrawheader_t rawdata;
2021
2022 REQUIRE(DNS_ZONE_VALID(zone));
2023 INSIST(task == zone->task);
2024 ENTER;
2025
2026 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0)
2027 result = ISC_R_CANCELED;
2028 isc_event_free(&event);
2029 if (result == ISC_R_CANCELED)
2030 goto fail;
2031
2032 LOCK_ZONE(zone);
2033 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
2034 if (zone->db != NULL) {
2035 const dns_master_style_t *output_style;
2036
2037 dns_db_currentversion(zone->db, &version);
2038 dns_master_initrawheader(&rawdata);
2039 if (inline_secure(zone))
2040 get_raw_serial(zone->raw, &rawdata);
2041 if (zone->type == dns_zone_key)
2042 output_style = &dns_master_style_keyzone;
2043 else
2044 output_style = &dns_master_style_default;
2045 result = dns_master_dumpinc3(zone->mctx, zone->db, version,
2046 output_style, zone->masterfile,
2047 zone->task, dump_done, zone, &zone->dctx, zone->masterformat,
2048 &rawdata);
2049 dns_db_closeversion(zone->db, &version, ISC_FALSE);
2050 } else
2051 result = ISC_R_CANCELED;
2052 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
2053 UNLOCK_ZONE(zone);
2054 if (result != DNS_R_CONTINUE)
2055 goto fail;
2056 return;
2057
2058 fail:
2059 dump_done(zone, result);
2060 }
2061
2062 /*
2063 * Save the raw serial number for inline-signing zones.
2064 * (XXX: Other information from the header will be used
2065 * for other purposes in the future, but for now this is
2066 * all we're interested in.)
2067 */
2068 static void
zone_setrawdata(dns_zone_t * zone,dns_masterrawheader_t * header)2069 zone_setrawdata(dns_zone_t *zone, dns_masterrawheader_t *header) {
2070 if ((header->flags & DNS_MASTERRAW_SOURCESERIALSET) == 0)
2071 return;
2072
2073 zone->sourceserial = header->sourceserial;
2074 zone->sourceserialset = ISC_TRUE;
2075 }
2076
2077 void
dns_zone_setrawdata(dns_zone_t * zone,dns_masterrawheader_t * header)2078 dns_zone_setrawdata(dns_zone_t *zone, dns_masterrawheader_t *header) {
2079 if (zone == NULL)
2080 return;
2081
2082 LOCK_ZONE(zone);
2083 zone_setrawdata(zone, header);
2084 UNLOCK_ZONE(zone);
2085 }
2086
2087 static isc_result_t
zone_startload(dns_db_t * db,dns_zone_t * zone,isc_time_t loadtime)2088 zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) {
2089 dns_load_t *load;
2090 isc_result_t result;
2091 isc_result_t tresult;
2092 unsigned int options;
2093
2094 result = dns_zone_rpz_enable_db(zone, db);
2095 if (result != ISC_R_SUCCESS)
2096 return (result);
2097 options = get_master_options(zone);
2098 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MANYERRORS))
2099 options |= DNS_MASTER_MANYERRORS;
2100
2101 if (zone->zmgr != NULL && zone->db != NULL && zone->loadtask != NULL) {
2102 load = isc_mem_get(zone->mctx, sizeof(*load));
2103 if (load == NULL)
2104 return (ISC_R_NOMEMORY);
2105
2106 load->mctx = NULL;
2107 load->zone = NULL;
2108 load->db = NULL;
2109 load->loadtime = loadtime;
2110 load->magic = LOAD_MAGIC;
2111
2112 isc_mem_attach(zone->mctx, &load->mctx);
2113 zone_iattach(zone, &load->zone);
2114 dns_db_attach(db, &load->db);
2115 dns_rdatacallbacks_init(&load->callbacks);
2116 load->callbacks.rawdata = zone_setrawdata;
2117 zone_iattach(zone, &load->callbacks.zone);
2118 result = dns_db_beginload(db, &load->callbacks.add,
2119 &load->callbacks.add_private);
2120 if (result != ISC_R_SUCCESS)
2121 goto cleanup;
2122 result = zonemgr_getio(zone->zmgr, ISC_TRUE, zone->loadtask,
2123 zone_gotreadhandle, load,
2124 &zone->readio);
2125 if (result != ISC_R_SUCCESS) {
2126 /*
2127 * We can't report multiple errors so ignore
2128 * the result of dns_db_endload().
2129 */
2130 (void)dns_db_endload(load->db,
2131 &load->callbacks.add_private);
2132 goto cleanup;
2133 } else
2134 result = DNS_R_CONTINUE;
2135 } else {
2136 dns_rdatacallbacks_t callbacks;
2137
2138 dns_rdatacallbacks_init(&callbacks);
2139 callbacks.rawdata = zone_setrawdata;
2140 zone_iattach(zone, &callbacks.zone);
2141 result = dns_db_beginload(db, &callbacks.add,
2142 &callbacks.add_private);
2143 if (result != ISC_R_SUCCESS) {
2144 zone_idetach(&callbacks.zone);
2145 return (result);
2146 }
2147 result = dns_master_loadfile3(zone->masterfile,
2148 &zone->origin, &zone->origin,
2149 zone->rdclass, options, 0,
2150 &callbacks, zone->mctx,
2151 zone->masterformat);
2152 tresult = dns_db_endload(db, &callbacks.add_private);
2153 if (result == ISC_R_SUCCESS)
2154 result = tresult;
2155 zone_idetach(&callbacks.zone);
2156 }
2157
2158 return (result);
2159
2160 cleanup:
2161 load->magic = 0;
2162 dns_db_detach(&load->db);
2163 zone_idetach(&load->zone);
2164 zone_idetach(&load->callbacks.zone);
2165 isc_mem_detach(&load->mctx);
2166 isc_mem_put(zone->mctx, load, sizeof(*load));
2167 return (result);
2168 }
2169
2170 static isc_boolean_t
zone_check_mx(dns_zone_t * zone,dns_db_t * db,dns_name_t * name,dns_name_t * owner)2171 zone_check_mx(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
2172 dns_name_t *owner)
2173 {
2174 isc_result_t result;
2175 char ownerbuf[DNS_NAME_FORMATSIZE];
2176 char namebuf[DNS_NAME_FORMATSIZE];
2177 char altbuf[DNS_NAME_FORMATSIZE];
2178 dns_fixedname_t fixed;
2179 dns_name_t *foundname;
2180 int level;
2181
2182 /*
2183 * "." means the services does not exist.
2184 */
2185 if (dns_name_equal(name, dns_rootname))
2186 return (ISC_TRUE);
2187
2188 /*
2189 * Outside of zone.
2190 */
2191 if (!dns_name_issubdomain(name, &zone->origin)) {
2192 if (zone->checkmx != NULL)
2193 return ((zone->checkmx)(zone, name, owner));
2194 return (ISC_TRUE);
2195 }
2196
2197 if (zone->type == dns_zone_master)
2198 level = ISC_LOG_ERROR;
2199 else
2200 level = ISC_LOG_WARNING;
2201
2202 dns_fixedname_init(&fixed);
2203 foundname = dns_fixedname_name(&fixed);
2204
2205 result = dns_db_find(db, name, NULL, dns_rdatatype_a,
2206 0, 0, NULL, foundname, NULL, NULL);
2207 if (result == ISC_R_SUCCESS)
2208 return (ISC_TRUE);
2209
2210 if (result == DNS_R_NXRRSET) {
2211 result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
2212 0, 0, NULL, foundname, NULL, NULL);
2213 if (result == ISC_R_SUCCESS)
2214 return (ISC_TRUE);
2215 }
2216
2217 dns_name_format(owner, ownerbuf, sizeof ownerbuf);
2218 dns_name_format(name, namebuf, sizeof namebuf);
2219 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
2220 result == DNS_R_EMPTYNAME) {
2221 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMXFAIL))
2222 level = ISC_LOG_WARNING;
2223 dns_zone_log(zone, level,
2224 "%s/MX '%s' has no address records (A or AAAA)",
2225 ownerbuf, namebuf);
2226 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
2227 }
2228
2229 if (result == DNS_R_CNAME) {
2230 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) ||
2231 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
2232 level = ISC_LOG_WARNING;
2233 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
2234 dns_zone_log(zone, level,
2235 "%s/MX '%s' is a CNAME (illegal)",
2236 ownerbuf, namebuf);
2237 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
2238 }
2239
2240 if (result == DNS_R_DNAME) {
2241 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) ||
2242 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
2243 level = ISC_LOG_WARNING;
2244 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) {
2245 dns_name_format(foundname, altbuf, sizeof altbuf);
2246 dns_zone_log(zone, level, "%s/MX '%s' is below a DNAME"
2247 " '%s' (illegal)", ownerbuf, namebuf,
2248 altbuf);
2249 }
2250 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
2251 }
2252
2253 if (zone->checkmx != NULL && result == DNS_R_DELEGATION)
2254 return ((zone->checkmx)(zone, name, owner));
2255
2256 return (ISC_TRUE);
2257 }
2258
2259 static isc_boolean_t
zone_check_srv(dns_zone_t * zone,dns_db_t * db,dns_name_t * name,dns_name_t * owner)2260 zone_check_srv(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
2261 dns_name_t *owner)
2262 {
2263 isc_result_t result;
2264 char ownerbuf[DNS_NAME_FORMATSIZE];
2265 char namebuf[DNS_NAME_FORMATSIZE];
2266 char altbuf[DNS_NAME_FORMATSIZE];
2267 dns_fixedname_t fixed;
2268 dns_name_t *foundname;
2269 int level;
2270
2271 /*
2272 * "." means the services does not exist.
2273 */
2274 if (dns_name_equal(name, dns_rootname))
2275 return (ISC_TRUE);
2276
2277 /*
2278 * Outside of zone.
2279 */
2280 if (!dns_name_issubdomain(name, &zone->origin)) {
2281 if (zone->checksrv != NULL)
2282 return ((zone->checksrv)(zone, name, owner));
2283 return (ISC_TRUE);
2284 }
2285
2286 if (zone->type == dns_zone_master)
2287 level = ISC_LOG_ERROR;
2288 else
2289 level = ISC_LOG_WARNING;
2290
2291 dns_fixedname_init(&fixed);
2292 foundname = dns_fixedname_name(&fixed);
2293
2294 result = dns_db_find(db, name, NULL, dns_rdatatype_a,
2295 0, 0, NULL, foundname, NULL, NULL);
2296 if (result == ISC_R_SUCCESS)
2297 return (ISC_TRUE);
2298
2299 if (result == DNS_R_NXRRSET) {
2300 result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
2301 0, 0, NULL, foundname, NULL, NULL);
2302 if (result == ISC_R_SUCCESS)
2303 return (ISC_TRUE);
2304 }
2305
2306 dns_name_format(owner, ownerbuf, sizeof ownerbuf);
2307 dns_name_format(name, namebuf, sizeof namebuf);
2308 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
2309 result == DNS_R_EMPTYNAME) {
2310 dns_zone_log(zone, level,
2311 "%s/SRV '%s' has no address records (A or AAAA)",
2312 ownerbuf, namebuf);
2313 /* XXX950 make fatal for 9.5.0. */
2314 return (ISC_TRUE);
2315 }
2316
2317 if (result == DNS_R_CNAME) {
2318 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) ||
2319 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
2320 level = ISC_LOG_WARNING;
2321 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
2322 dns_zone_log(zone, level,
2323 "%s/SRV '%s' is a CNAME (illegal)",
2324 ownerbuf, namebuf);
2325 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
2326 }
2327
2328 if (result == DNS_R_DNAME) {
2329 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) ||
2330 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
2331 level = ISC_LOG_WARNING;
2332 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) {
2333 dns_name_format(foundname, altbuf, sizeof altbuf);
2334 dns_zone_log(zone, level, "%s/SRV '%s' is below a "
2335 "DNAME '%s' (illegal)", ownerbuf, namebuf,
2336 altbuf);
2337 }
2338 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
2339 }
2340
2341 if (zone->checksrv != NULL && result == DNS_R_DELEGATION)
2342 return ((zone->checksrv)(zone, name, owner));
2343
2344 return (ISC_TRUE);
2345 }
2346
2347 static isc_boolean_t
zone_check_glue(dns_zone_t * zone,dns_db_t * db,dns_name_t * name,dns_name_t * owner)2348 zone_check_glue(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
2349 dns_name_t *owner)
2350 {
2351 isc_boolean_t answer = ISC_TRUE;
2352 isc_result_t result, tresult;
2353 char ownerbuf[DNS_NAME_FORMATSIZE];
2354 char namebuf[DNS_NAME_FORMATSIZE];
2355 char altbuf[DNS_NAME_FORMATSIZE];
2356 dns_fixedname_t fixed;
2357 dns_name_t *foundname;
2358 dns_rdataset_t a;
2359 dns_rdataset_t aaaa;
2360 int level;
2361
2362 /*
2363 * Outside of zone.
2364 */
2365 if (!dns_name_issubdomain(name, &zone->origin)) {
2366 if (zone->checkns != NULL)
2367 return ((zone->checkns)(zone, name, owner, NULL, NULL));
2368 return (ISC_TRUE);
2369 }
2370
2371 if (zone->type == dns_zone_master)
2372 level = ISC_LOG_ERROR;
2373 else
2374 level = ISC_LOG_WARNING;
2375
2376 dns_fixedname_init(&fixed);
2377 foundname = dns_fixedname_name(&fixed);
2378 dns_rdataset_init(&a);
2379 dns_rdataset_init(&aaaa);
2380
2381 result = dns_db_find(db, name, NULL, dns_rdatatype_a,
2382 DNS_DBFIND_GLUEOK, 0, NULL,
2383 foundname, &a, NULL);
2384
2385 if (result == ISC_R_SUCCESS) {
2386 dns_rdataset_disassociate(&a);
2387 return (ISC_TRUE);
2388 } else if (result == DNS_R_DELEGATION)
2389 dns_rdataset_disassociate(&a);
2390
2391 if (result == DNS_R_NXRRSET || result == DNS_R_DELEGATION ||
2392 result == DNS_R_GLUE) {
2393 tresult = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
2394 DNS_DBFIND_GLUEOK, 0, NULL,
2395 foundname, &aaaa, NULL);
2396 if (tresult == ISC_R_SUCCESS) {
2397 if (dns_rdataset_isassociated(&a))
2398 dns_rdataset_disassociate(&a);
2399 dns_rdataset_disassociate(&aaaa);
2400 return (ISC_TRUE);
2401 }
2402 if (tresult == DNS_R_DELEGATION)
2403 dns_rdataset_disassociate(&aaaa);
2404 if (result == DNS_R_GLUE || tresult == DNS_R_GLUE) {
2405 /*
2406 * Check glue against child zone.
2407 */
2408 if (zone->checkns != NULL)
2409 answer = (zone->checkns)(zone, name, owner,
2410 &a, &aaaa);
2411 if (dns_rdataset_isassociated(&a))
2412 dns_rdataset_disassociate(&a);
2413 if (dns_rdataset_isassociated(&aaaa))
2414 dns_rdataset_disassociate(&aaaa);
2415 return (answer);
2416 }
2417 }
2418
2419 dns_name_format(owner, ownerbuf, sizeof ownerbuf);
2420 dns_name_format(name, namebuf, sizeof namebuf);
2421 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
2422 result == DNS_R_EMPTYNAME || result == DNS_R_DELEGATION) {
2423 const char *what;
2424 isc_boolean_t required = ISC_FALSE;
2425 if (dns_name_issubdomain(name, owner)) {
2426 what = "REQUIRED GLUE ";
2427 required = ISC_TRUE;
2428 } else if (result == DNS_R_DELEGATION)
2429 what = "SIBLING GLUE ";
2430 else
2431 what = "";
2432
2433 if (result != DNS_R_DELEGATION || required ||
2434 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKSIBLING)) {
2435 dns_zone_log(zone, level, "%s/NS '%s' has no %s"
2436 "address records (A or AAAA)",
2437 ownerbuf, namebuf, what);
2438 /*
2439 * Log missing address record.
2440 */
2441 if (result == DNS_R_DELEGATION && zone->checkns != NULL)
2442 (void)(zone->checkns)(zone, name, owner,
2443 &a, &aaaa);
2444 /* XXX950 make fatal for 9.5.0. */
2445 /* answer = ISC_FALSE; */
2446 }
2447 } else if (result == DNS_R_CNAME) {
2448 dns_zone_log(zone, level, "%s/NS '%s' is a CNAME (illegal)",
2449 ownerbuf, namebuf);
2450 /* XXX950 make fatal for 9.5.0. */
2451 /* answer = ISC_FALSE; */
2452 } else if (result == DNS_R_DNAME) {
2453 dns_name_format(foundname, altbuf, sizeof altbuf);
2454 dns_zone_log(zone, level,
2455 "%s/NS '%s' is below a DNAME '%s' (illegal)",
2456 ownerbuf, namebuf, altbuf);
2457 /* XXX950 make fatal for 9.5.0. */
2458 /* answer = ISC_FALSE; */
2459 }
2460
2461 if (dns_rdataset_isassociated(&a))
2462 dns_rdataset_disassociate(&a);
2463 if (dns_rdataset_isassociated(&aaaa))
2464 dns_rdataset_disassociate(&aaaa);
2465 return (answer);
2466 }
2467
2468 static isc_boolean_t
zone_rrset_check_dup(dns_zone_t * zone,dns_name_t * owner,dns_rdataset_t * rdataset)2469 zone_rrset_check_dup(dns_zone_t *zone, dns_name_t *owner,
2470 dns_rdataset_t *rdataset)
2471 {
2472 dns_rdataset_t tmprdataset;
2473 isc_result_t result;
2474 isc_boolean_t answer = ISC_TRUE;
2475 isc_boolean_t format = ISC_TRUE;
2476 int level = ISC_LOG_WARNING;
2477 char ownerbuf[DNS_NAME_FORMATSIZE];
2478 char typebuf[DNS_RDATATYPE_FORMATSIZE];
2479 unsigned int count1 = 0;
2480
2481 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKDUPRRFAIL))
2482 level = ISC_LOG_ERROR;
2483
2484 dns_rdataset_init(&tmprdataset);
2485 for (result = dns_rdataset_first(rdataset);
2486 result == ISC_R_SUCCESS;
2487 result = dns_rdataset_next(rdataset)) {
2488 dns_rdata_t rdata1 = DNS_RDATA_INIT;
2489 unsigned int count2 = 0;
2490
2491 count1++;
2492 dns_rdataset_current(rdataset, &rdata1);
2493 dns_rdataset_clone(rdataset, &tmprdataset);
2494 for (result = dns_rdataset_first(&tmprdataset);
2495 result == ISC_R_SUCCESS;
2496 result = dns_rdataset_next(&tmprdataset)) {
2497 dns_rdata_t rdata2 = DNS_RDATA_INIT;
2498 count2++;
2499 if (count1 >= count2)
2500 continue;
2501 dns_rdataset_current(&tmprdataset, &rdata2);
2502 if (dns_rdata_casecompare(&rdata1, &rdata2) == 0) {
2503 if (format) {
2504 dns_name_format(owner, ownerbuf,
2505 sizeof ownerbuf);
2506 dns_rdatatype_format(rdata1.type,
2507 typebuf,
2508 sizeof(typebuf));
2509 format = ISC_FALSE;
2510 }
2511 dns_zone_log(zone, level, "%s/%s has "
2512 "semantically identical records",
2513 ownerbuf, typebuf);
2514 if (level == ISC_LOG_ERROR)
2515 answer = ISC_FALSE;
2516 break;
2517 }
2518 }
2519 dns_rdataset_disassociate(&tmprdataset);
2520 if (!format)
2521 break;
2522 }
2523 return (answer);
2524 }
2525
2526 static isc_boolean_t
zone_check_dup(dns_zone_t * zone,dns_db_t * db)2527 zone_check_dup(dns_zone_t *zone, dns_db_t *db) {
2528 dns_dbiterator_t *dbiterator = NULL;
2529 dns_dbnode_t *node = NULL;
2530 dns_fixedname_t fixed;
2531 dns_name_t *name;
2532 dns_rdataset_t rdataset;
2533 dns_rdatasetiter_t *rdsit = NULL;
2534 isc_boolean_t ok = ISC_TRUE;
2535 isc_result_t result;
2536
2537 dns_fixedname_init(&fixed);
2538 name = dns_fixedname_name(&fixed);
2539 dns_rdataset_init(&rdataset);
2540
2541 result = dns_db_createiterator(db, 0, &dbiterator);
2542 if (result != ISC_R_SUCCESS)
2543 return (ISC_TRUE);
2544
2545 for (result = dns_dbiterator_first(dbiterator);
2546 result == ISC_R_SUCCESS;
2547 result = dns_dbiterator_next(dbiterator)) {
2548 result = dns_dbiterator_current(dbiterator, &node, name);
2549 if (result != ISC_R_SUCCESS)
2550 continue;
2551
2552 result = dns_db_allrdatasets(db, node, NULL, 0, &rdsit);
2553 if (result != ISC_R_SUCCESS)
2554 continue;
2555
2556 for (result = dns_rdatasetiter_first(rdsit);
2557 result == ISC_R_SUCCESS;
2558 result = dns_rdatasetiter_next(rdsit)) {
2559 dns_rdatasetiter_current(rdsit, &rdataset);
2560 if (!zone_rrset_check_dup(zone, name, &rdataset))
2561 ok = ISC_FALSE;
2562 dns_rdataset_disassociate(&rdataset);
2563 }
2564 dns_rdatasetiter_destroy(&rdsit);
2565 dns_db_detachnode(db, &node);
2566 }
2567
2568 if (node != NULL)
2569 dns_db_detachnode(db, &node);
2570 dns_dbiterator_destroy(&dbiterator);
2571
2572 return (ok);
2573 }
2574
2575 static isc_boolean_t
isspf(const dns_rdata_t * rdata)2576 isspf(const dns_rdata_t *rdata) {
2577 char buf[1024];
2578 const unsigned char *data = rdata->data;
2579 unsigned int rdl = rdata->length, i = 0, tl, len;
2580
2581 while (rdl > 0U) {
2582 len = tl = *data;
2583 ++data;
2584 --rdl;
2585 INSIST(tl <= rdl);
2586 if (len > sizeof(buf) - i - 1)
2587 len = sizeof(buf) - i - 1;
2588 memmove(buf + i, data, len);
2589 i += len;
2590 data += tl;
2591 rdl -= tl;
2592 }
2593
2594 if (i < 6U)
2595 return(ISC_FALSE);
2596
2597 buf[i] = 0;
2598 if (strncmp(buf, "v=spf1", 6) == 0 && (buf[6] == 0 || buf[6] == ' '))
2599 return (ISC_TRUE);
2600 return (ISC_FALSE);
2601 }
2602
2603 static isc_boolean_t
integrity_checks(dns_zone_t * zone,dns_db_t * db)2604 integrity_checks(dns_zone_t *zone, dns_db_t *db) {
2605 dns_dbiterator_t *dbiterator = NULL;
2606 dns_dbnode_t *node = NULL;
2607 dns_rdataset_t rdataset;
2608 dns_fixedname_t fixed;
2609 dns_fixedname_t fixedbottom;
2610 dns_rdata_mx_t mx;
2611 dns_rdata_ns_t ns;
2612 dns_rdata_in_srv_t srv;
2613 dns_rdata_t rdata;
2614 dns_name_t *name;
2615 dns_name_t *bottom;
2616 isc_result_t result;
2617 isc_boolean_t ok = ISC_TRUE, have_spf, have_txt;
2618
2619 dns_fixedname_init(&fixed);
2620 name = dns_fixedname_name(&fixed);
2621 dns_fixedname_init(&fixedbottom);
2622 bottom = dns_fixedname_name(&fixedbottom);
2623 dns_rdataset_init(&rdataset);
2624 dns_rdata_init(&rdata);
2625
2626 result = dns_db_createiterator(db, 0, &dbiterator);
2627 if (result != ISC_R_SUCCESS)
2628 return (ISC_TRUE);
2629
2630 result = dns_dbiterator_first(dbiterator);
2631 while (result == ISC_R_SUCCESS) {
2632 result = dns_dbiterator_current(dbiterator, &node, name);
2633 if (result != ISC_R_SUCCESS)
2634 goto cleanup;
2635
2636 /*
2637 * Is this name visible in the zone?
2638 */
2639 if (!dns_name_issubdomain(name, &zone->origin) ||
2640 (dns_name_countlabels(bottom) > 0 &&
2641 dns_name_issubdomain(name, bottom)))
2642 goto next;
2643
2644 /*
2645 * Don't check the NS records at the origin.
2646 */
2647 if (dns_name_equal(name, &zone->origin))
2648 goto checkmx;
2649
2650 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_ns,
2651 0, 0, &rdataset, NULL);
2652 if (result != ISC_R_SUCCESS)
2653 goto checkmx;
2654 /*
2655 * Remember bottom of zone.
2656 */
2657 dns_name_copy(name, bottom, NULL);
2658
2659 result = dns_rdataset_first(&rdataset);
2660 while (result == ISC_R_SUCCESS) {
2661 dns_rdataset_current(&rdataset, &rdata);
2662 result = dns_rdata_tostruct(&rdata, &ns, NULL);
2663 RUNTIME_CHECK(result == ISC_R_SUCCESS);
2664 if (!zone_check_glue(zone, db, &ns.name, name))
2665 ok = ISC_FALSE;
2666 dns_rdata_reset(&rdata);
2667 result = dns_rdataset_next(&rdataset);
2668 }
2669 dns_rdataset_disassociate(&rdataset);
2670 goto next;
2671
2672 checkmx:
2673 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_mx,
2674 0, 0, &rdataset, NULL);
2675 if (result != ISC_R_SUCCESS)
2676 goto checksrv;
2677 result = dns_rdataset_first(&rdataset);
2678 while (result == ISC_R_SUCCESS) {
2679 dns_rdataset_current(&rdataset, &rdata);
2680 result = dns_rdata_tostruct(&rdata, &mx, NULL);
2681 RUNTIME_CHECK(result == ISC_R_SUCCESS);
2682 if (!zone_check_mx(zone, db, &mx.mx, name))
2683 ok = ISC_FALSE;
2684 dns_rdata_reset(&rdata);
2685 result = dns_rdataset_next(&rdataset);
2686 }
2687 dns_rdataset_disassociate(&rdataset);
2688
2689 checksrv:
2690 if (zone->rdclass != dns_rdataclass_in)
2691 goto next;
2692 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_srv,
2693 0, 0, &rdataset, NULL);
2694 if (result != ISC_R_SUCCESS)
2695 goto checkspf;
2696 result = dns_rdataset_first(&rdataset);
2697 while (result == ISC_R_SUCCESS) {
2698 dns_rdataset_current(&rdataset, &rdata);
2699 result = dns_rdata_tostruct(&rdata, &srv, NULL);
2700 RUNTIME_CHECK(result == ISC_R_SUCCESS);
2701 if (!zone_check_srv(zone, db, &srv.target, name))
2702 ok = ISC_FALSE;
2703 dns_rdata_reset(&rdata);
2704 result = dns_rdataset_next(&rdataset);
2705 }
2706 dns_rdataset_disassociate(&rdataset);
2707
2708 checkspf:
2709 /*
2710 * Check if there is a type SPF record without an
2711 * SPF-formatted type TXT record also being present.
2712 */
2713 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKSPF))
2714 goto next;
2715 if (zone->rdclass != dns_rdataclass_in)
2716 goto next;
2717 have_spf = have_txt = ISC_FALSE;
2718 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_spf,
2719 0, 0, &rdataset, NULL);
2720 if (result == ISC_R_SUCCESS) {
2721 dns_rdataset_disassociate(&rdataset);
2722 have_spf = ISC_TRUE;
2723 }
2724 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_txt,
2725 0, 0, &rdataset, NULL);
2726 if (result != ISC_R_SUCCESS)
2727 goto notxt;
2728 result = dns_rdataset_first(&rdataset);
2729 while (result == ISC_R_SUCCESS) {
2730 dns_rdataset_current(&rdataset, &rdata);
2731 have_txt = isspf(&rdata);
2732 dns_rdata_reset(&rdata);
2733 if (have_txt)
2734 break;
2735 result = dns_rdataset_next(&rdataset);
2736 }
2737 dns_rdataset_disassociate(&rdataset);
2738
2739 notxt:
2740 if (have_spf && !have_txt) {
2741 char namebuf[DNS_NAME_FORMATSIZE];
2742
2743 dns_name_format(name, namebuf, sizeof(namebuf));
2744 dns_zone_log(zone, ISC_LOG_WARNING, "'%s' found type "
2745 "SPF record but no SPF TXT record found, "
2746 "add matching type TXT record", namebuf);
2747 }
2748
2749 next:
2750 dns_db_detachnode(db, &node);
2751 result = dns_dbiterator_next(dbiterator);
2752 }
2753
2754 cleanup:
2755 if (node != NULL)
2756 dns_db_detachnode(db, &node);
2757 dns_dbiterator_destroy(&dbiterator);
2758
2759 return (ok);
2760 }
2761
2762 /*
2763 * OpenSSL verification of RSA keys with exponent 3 is known to be
2764 * broken prior OpenSSL 0.9.8c/0.9.7k. Look for such keys and warn
2765 * if they are in use.
2766 */
2767 static void
zone_check_dnskeys(dns_zone_t * zone,dns_db_t * db)2768 zone_check_dnskeys(dns_zone_t *zone, dns_db_t *db) {
2769 dns_dbnode_t *node = NULL;
2770 dns_dbversion_t *version = NULL;
2771 dns_rdata_dnskey_t dnskey;
2772 dns_rdata_t rdata = DNS_RDATA_INIT;
2773 dns_rdataset_t rdataset;
2774 isc_result_t result;
2775 isc_boolean_t logit, foundrsa = ISC_FALSE, foundmd5 = ISC_FALSE;
2776 const char *algorithm;
2777
2778 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node);
2779 if (result != ISC_R_SUCCESS)
2780 goto cleanup;
2781
2782 dns_db_currentversion(db, &version);
2783 dns_rdataset_init(&rdataset);
2784 result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey,
2785 dns_rdatatype_none, 0, &rdataset, NULL);
2786 if (result != ISC_R_SUCCESS)
2787 goto cleanup;
2788
2789 for (result = dns_rdataset_first(&rdataset);
2790 result == ISC_R_SUCCESS;
2791 result = dns_rdataset_next(&rdataset))
2792 {
2793 dns_rdataset_current(&rdataset, &rdata);
2794 result = dns_rdata_tostruct(&rdata, &dnskey, NULL);
2795 INSIST(result == ISC_R_SUCCESS);
2796
2797 if ((dnskey.algorithm == DST_ALG_RSASHA1 ||
2798 dnskey.algorithm == DST_ALG_RSAMD5) &&
2799 dnskey.datalen > 1 && dnskey.data[0] == 1 &&
2800 dnskey.data[1] == 3)
2801 {
2802 if (dnskey.algorithm == DST_ALG_RSASHA1) {
2803 logit = !foundrsa;
2804 foundrsa = ISC_TRUE;
2805 algorithm = "RSASHA1";
2806 } else {
2807 logit = !foundmd5;
2808 foundmd5 = ISC_TRUE;
2809 algorithm = "RSAMD5";
2810 }
2811 if (logit)
2812 dns_zone_log(zone, ISC_LOG_WARNING,
2813 "weak %s (%u) key found "
2814 "(exponent=3)", algorithm,
2815 dnskey.algorithm);
2816 if (foundrsa && foundmd5)
2817 break;
2818 }
2819 dns_rdata_reset(&rdata);
2820 }
2821 dns_rdataset_disassociate(&rdataset);
2822
2823 cleanup:
2824 if (node != NULL)
2825 dns_db_detachnode(db, &node);
2826 if (version != NULL)
2827 dns_db_closeversion(db, &version, ISC_FALSE);
2828 }
2829
2830 static void
resume_signingwithkey(dns_zone_t * zone)2831 resume_signingwithkey(dns_zone_t *zone) {
2832 dns_dbnode_t *node = NULL;
2833 dns_dbversion_t *version = NULL;
2834 dns_rdata_t rdata = DNS_RDATA_INIT;
2835 dns_rdataset_t rdataset;
2836 isc_result_t result;
2837 dns_db_t *db = NULL;
2838
2839 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
2840 if (zone->db != NULL)
2841 dns_db_attach(zone->db, &db);
2842 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
2843 if (db == NULL)
2844 goto cleanup;
2845
2846 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node);
2847 if (result != ISC_R_SUCCESS)
2848 goto cleanup;
2849
2850 dns_db_currentversion(db, &version);
2851 dns_rdataset_init(&rdataset);
2852 result = dns_db_findrdataset(db, node, version,
2853 zone->privatetype,
2854 dns_rdatatype_none, 0,
2855 &rdataset, NULL);
2856 if (result != ISC_R_SUCCESS) {
2857 INSIST(!dns_rdataset_isassociated(&rdataset));
2858 goto cleanup;
2859 }
2860
2861 for (result = dns_rdataset_first(&rdataset);
2862 result == ISC_R_SUCCESS;
2863 result = dns_rdataset_next(&rdataset))
2864 {
2865 dns_rdataset_current(&rdataset, &rdata);
2866 if (rdata.length != 5 ||
2867 rdata.data[0] == 0 || rdata.data[4] != 0) {
2868 dns_rdata_reset(&rdata);
2869 continue;
2870 }
2871
2872 result = zone_signwithkey(zone, rdata.data[0],
2873 (rdata.data[1] << 8) | rdata.data[2],
2874 ISC_TF(rdata.data[3]));
2875 if (result != ISC_R_SUCCESS) {
2876 dns_zone_log(zone, ISC_LOG_ERROR,
2877 "zone_signwithkey failed: %s",
2878 dns_result_totext(result));
2879 }
2880 dns_rdata_reset(&rdata);
2881 }
2882 dns_rdataset_disassociate(&rdataset);
2883
2884 cleanup:
2885 if (db != NULL) {
2886 if (node != NULL)
2887 dns_db_detachnode(db, &node);
2888 if (version != NULL)
2889 dns_db_closeversion(db, &version, ISC_FALSE);
2890 dns_db_detach(&db);
2891 }
2892 }
2893
2894 static isc_result_t
zone_addnsec3chain(dns_zone_t * zone,dns_rdata_nsec3param_t * nsec3param)2895 zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) {
2896 dns_nsec3chain_t *nsec3chain, *current;
2897 dns_dbversion_t *version = NULL;
2898 isc_boolean_t nseconly = ISC_FALSE, nsec3ok = ISC_FALSE;
2899 isc_result_t result;
2900 isc_time_t now;
2901 unsigned int options = 0;
2902 char saltbuf[255*2+1];
2903 char flags[sizeof("INITIAL|REMOVE|CREATE|NONSEC|OPTOUT")];
2904 dns_db_t *db = NULL;
2905 int i;
2906
2907 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
2908 if (zone->db != NULL)
2909 dns_db_attach(zone->db, &db);
2910 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
2911
2912 if (db == NULL) {
2913 result = ISC_R_SUCCESS;
2914 goto cleanup;
2915 }
2916
2917 dns_db_currentversion(db, &version);
2918 result = dns_nsec_nseconly(db, version, &nseconly);
2919 nsec3ok = (result == ISC_R_SUCCESS && !nseconly);
2920 dns_db_closeversion(db, &version, ISC_FALSE);
2921 if (!nsec3ok && (nsec3param->flags & DNS_NSEC3FLAG_REMOVE) == 0) {
2922 result = ISC_R_SUCCESS;
2923 goto cleanup;
2924 }
2925
2926 nsec3chain = isc_mem_get(zone->mctx, sizeof *nsec3chain);
2927 if (nsec3chain == NULL) {
2928 result = ISC_R_NOMEMORY;
2929 goto cleanup;
2930 }
2931
2932 nsec3chain->magic = 0;
2933 nsec3chain->done = ISC_FALSE;
2934 nsec3chain->db = NULL;
2935 nsec3chain->dbiterator = NULL;
2936 nsec3chain->nsec3param.common.rdclass = nsec3param->common.rdclass;
2937 nsec3chain->nsec3param.common.rdtype = nsec3param->common.rdtype;
2938 nsec3chain->nsec3param.hash = nsec3param->hash;
2939 nsec3chain->nsec3param.iterations = nsec3param->iterations;
2940 nsec3chain->nsec3param.flags = nsec3param->flags;
2941 nsec3chain->nsec3param.salt_length = nsec3param->salt_length;
2942 memmove(nsec3chain->salt, nsec3param->salt, nsec3param->salt_length);
2943 nsec3chain->nsec3param.salt = nsec3chain->salt;
2944 nsec3chain->seen_nsec = ISC_FALSE;
2945 nsec3chain->delete_nsec = ISC_FALSE;
2946 nsec3chain->save_delete_nsec = ISC_FALSE;
2947
2948 if (nsec3param->flags == 0)
2949 strlcpy(flags, "NONE", sizeof(flags));
2950 else {
2951 flags[0] = '\0';
2952 if (nsec3param->flags & DNS_NSEC3FLAG_REMOVE)
2953 strlcat(flags, "REMOVE", sizeof(flags));
2954 if (nsec3param->flags & DNS_NSEC3FLAG_INITIAL) {
2955 if (flags[0] == '\0')
2956 strlcpy(flags, "INITIAL", sizeof(flags));
2957 else
2958 strlcat(flags, "|INITIAL", sizeof(flags));
2959 }
2960 if (nsec3param->flags & DNS_NSEC3FLAG_CREATE) {
2961 if (flags[0] == '\0')
2962 strlcpy(flags, "CREATE", sizeof(flags));
2963 else
2964 strlcat(flags, "|CREATE", sizeof(flags));
2965 }
2966 if (nsec3param->flags & DNS_NSEC3FLAG_NONSEC) {
2967 if (flags[0] == '\0')
2968 strlcpy(flags, "NONSEC", sizeof(flags));
2969 else
2970 strlcat(flags, "|NONSEC", sizeof(flags));
2971 }
2972 if (nsec3param->flags & DNS_NSEC3FLAG_OPTOUT) {
2973 if (flags[0] == '\0')
2974 strlcpy(flags, "OPTOUT", sizeof(flags));
2975 else
2976 strlcat(flags, "|OPTOUT", sizeof(flags));
2977 }
2978 }
2979 if (nsec3param->salt_length == 0)
2980 strlcpy(saltbuf, "-", sizeof(saltbuf));
2981 else
2982 for (i = 0; i < nsec3param->salt_length; i++)
2983 sprintf(&saltbuf[i*2], "%02X", nsec3chain->salt[i]);
2984 dns_zone_log(zone, ISC_LOG_INFO,
2985 "zone_addnsec3chain(%u,%s,%u,%s)",
2986 nsec3param->hash, flags, nsec3param->iterations,
2987 saltbuf);
2988
2989 for (current = ISC_LIST_HEAD(zone->nsec3chain);
2990 current != NULL;
2991 current = ISC_LIST_NEXT(current, link)) {
2992 if (current->db == db &&
2993 current->nsec3param.hash == nsec3param->hash &&
2994 current->nsec3param.iterations == nsec3param->iterations &&
2995 current->nsec3param.salt_length == nsec3param->salt_length
2996 && !memcmp(current->nsec3param.salt, nsec3param->salt,
2997 nsec3param->salt_length))
2998 current->done = ISC_TRUE;
2999 }
3000
3001 dns_db_attach(db, &nsec3chain->db);
3002 if ((nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0)
3003 options = DNS_DB_NONSEC3;
3004 result = dns_db_createiterator(nsec3chain->db, options,
3005 &nsec3chain->dbiterator);
3006 if (result == ISC_R_SUCCESS)
3007 dns_dbiterator_first(nsec3chain->dbiterator);
3008 if (result == ISC_R_SUCCESS) {
3009 dns_dbiterator_pause(nsec3chain->dbiterator);
3010 ISC_LIST_INITANDAPPEND(zone->nsec3chain,
3011 nsec3chain, link);
3012 nsec3chain = NULL;
3013 if (isc_time_isepoch(&zone->nsec3chaintime)) {
3014 TIME_NOW(&now);
3015 zone->nsec3chaintime = now;
3016 if (zone->task != NULL)
3017 zone_settimer(zone, &now);
3018 }
3019 }
3020
3021 if (nsec3chain != NULL) {
3022 if (nsec3chain->db != NULL)
3023 dns_db_detach(&nsec3chain->db);
3024 if (nsec3chain->dbiterator != NULL)
3025 dns_dbiterator_destroy(&nsec3chain->dbiterator);
3026 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
3027 }
3028
3029 cleanup:
3030 if (db != NULL)
3031 dns_db_detach(&db);
3032 return (result);
3033 }
3034
3035 static void
resume_addnsec3chain(dns_zone_t * zone)3036 resume_addnsec3chain(dns_zone_t *zone) {
3037 dns_dbnode_t *node = NULL;
3038 dns_dbversion_t *version = NULL;
3039 dns_rdataset_t rdataset;
3040 isc_result_t result;
3041 dns_rdata_nsec3param_t nsec3param;
3042 isc_boolean_t nseconly = ISC_FALSE, nsec3ok = ISC_FALSE;
3043 dns_db_t *db = NULL;
3044
3045 if (zone->privatetype == 0)
3046 return;
3047
3048 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
3049 if (zone->db != NULL)
3050 dns_db_attach(zone->db, &db);
3051 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
3052 if (db == NULL)
3053 goto cleanup;
3054
3055 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node);
3056 if (result != ISC_R_SUCCESS)
3057 goto cleanup;
3058
3059 dns_db_currentversion(db, &version);
3060
3061 result = dns_nsec_nseconly(db, version, &nseconly);
3062 nsec3ok = (result == ISC_R_SUCCESS && !nseconly);
3063
3064 dns_rdataset_init(&rdataset);
3065 result = dns_db_findrdataset(db, node, version,
3066 zone->privatetype, dns_rdatatype_none,
3067 0, &rdataset, NULL);
3068 if (result != ISC_R_SUCCESS) {
3069 INSIST(!dns_rdataset_isassociated(&rdataset));
3070 goto cleanup;
3071 }
3072
3073 for (result = dns_rdataset_first(&rdataset);
3074 result == ISC_R_SUCCESS;
3075 result = dns_rdataset_next(&rdataset))
3076 {
3077 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
3078 dns_rdata_t rdata = DNS_RDATA_INIT;
3079 dns_rdata_t private = DNS_RDATA_INIT;
3080
3081 dns_rdataset_current(&rdataset, &private);
3082 if (!dns_nsec3param_fromprivate(&private, &rdata, buf,
3083 sizeof(buf)))
3084 continue;
3085 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
3086 RUNTIME_CHECK(result == ISC_R_SUCCESS);
3087 if (((nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) ||
3088 ((nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0 && nsec3ok))
3089 {
3090 result = zone_addnsec3chain(zone, &nsec3param);
3091 if (result != ISC_R_SUCCESS) {
3092 dns_zone_log(zone, ISC_LOG_ERROR,
3093 "zone_addnsec3chain failed: %s",
3094 dns_result_totext(result));
3095 }
3096 }
3097 }
3098 dns_rdataset_disassociate(&rdataset);
3099 cleanup:
3100 if (db != NULL) {
3101 if (node != NULL)
3102 dns_db_detachnode(db, &node);
3103 if (version != NULL)
3104 dns_db_closeversion(db, &version, ISC_FALSE);
3105 dns_db_detach(&db);
3106 }
3107 }
3108
3109 static void
set_resigntime(dns_zone_t * zone)3110 set_resigntime(dns_zone_t *zone) {
3111 dns_rdataset_t rdataset;
3112 dns_fixedname_t fixed;
3113 unsigned int resign;
3114 isc_result_t result;
3115 isc_uint32_t nanosecs;
3116 dns_db_t *db = NULL;
3117
3118 dns_rdataset_init(&rdataset);
3119 dns_fixedname_init(&fixed);
3120
3121 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
3122 if (zone->db != NULL)
3123 dns_db_attach(zone->db, &db);
3124 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
3125 if (db == NULL) {
3126 isc_time_settoepoch(&zone->resigntime);
3127 return;
3128 }
3129
3130 result = dns_db_getsigningtime(db, &rdataset,
3131 dns_fixedname_name(&fixed));
3132 if (result != ISC_R_SUCCESS) {
3133 isc_time_settoepoch(&zone->resigntime);
3134 goto cleanup;
3135 }
3136
3137 resign = rdataset.resign - zone->sigresigninginterval;
3138 dns_rdataset_disassociate(&rdataset);
3139 isc_random_get(&nanosecs);
3140 nanosecs %= 1000000000;
3141 isc_time_set(&zone->resigntime, resign, nanosecs);
3142 cleanup:
3143 dns_db_detach(&db);
3144 return;
3145 }
3146
3147 static isc_result_t
check_nsec3param(dns_zone_t * zone,dns_db_t * db)3148 check_nsec3param(dns_zone_t *zone, dns_db_t *db) {
3149 dns_dbnode_t *node = NULL;
3150 dns_rdataset_t rdataset;
3151 dns_dbversion_t *version = NULL;
3152 dns_rdata_nsec3param_t nsec3param;
3153 isc_boolean_t ok = ISC_FALSE;
3154 isc_result_t result;
3155 dns_rdata_t rdata = DNS_RDATA_INIT;
3156 isc_boolean_t dynamic = (zone->type == dns_zone_master) ?
3157 dns_zone_isdynamic(zone, ISC_FALSE) : ISC_FALSE;
3158
3159 dns_rdataset_init(&rdataset);
3160 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node);
3161 if (result != ISC_R_SUCCESS) {
3162 dns_zone_log(zone, ISC_LOG_ERROR,
3163 "nsec3param lookup failure: %s",
3164 dns_result_totext(result));
3165 return (result);
3166 }
3167 dns_db_currentversion(db, &version);
3168
3169 result = dns_db_findrdataset(db, node, version,
3170 dns_rdatatype_nsec3param,
3171 dns_rdatatype_none, 0, &rdataset, NULL);
3172 if (result == ISC_R_NOTFOUND) {
3173 INSIST(!dns_rdataset_isassociated(&rdataset));
3174 result = ISC_R_SUCCESS;
3175 goto cleanup;
3176 }
3177 if (result != ISC_R_SUCCESS) {
3178 INSIST(!dns_rdataset_isassociated(&rdataset));
3179 dns_zone_log(zone, ISC_LOG_ERROR,
3180 "nsec3param lookup failure: %s",
3181 dns_result_totext(result));
3182 goto cleanup;
3183 }
3184
3185 /*
3186 * For dynamic zones we must support every algorithm so we can
3187 * regenerate all the NSEC3 chains.
3188 * For non-dynamic zones we only need to find a supported algorithm.
3189 */
3190 for (result = dns_rdataset_first(&rdataset);
3191 result == ISC_R_SUCCESS;
3192 result = dns_rdataset_next(&rdataset))
3193 {
3194 dns_rdataset_current(&rdataset, &rdata);
3195 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
3196 dns_rdata_reset(&rdata);
3197 INSIST(result == ISC_R_SUCCESS);
3198 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NSEC3TESTZONE) &&
3199 nsec3param.hash == DNS_NSEC3_UNKNOWNALG && !dynamic)
3200 {
3201 dns_zone_log(zone, ISC_LOG_WARNING,
3202 "nsec3 test \"unknown\" hash algorithm found: %u",
3203 nsec3param.hash);
3204 ok = ISC_TRUE;
3205 } else if (!dns_nsec3_supportedhash(nsec3param.hash)) {
3206 if (dynamic) {
3207 dns_zone_log(zone, ISC_LOG_ERROR,
3208 "unsupported nsec3 hash algorithm"
3209 " in dynamic zone: %u",
3210 nsec3param.hash);
3211 result = DNS_R_BADZONE;
3212 /* Stop second error message. */
3213 ok = ISC_TRUE;
3214 break;
3215 } else
3216 dns_zone_log(zone, ISC_LOG_WARNING,
3217 "unsupported nsec3 hash algorithm: %u",
3218 nsec3param.hash);
3219 } else
3220 ok = ISC_TRUE;
3221 }
3222 if (result == ISC_R_NOMORE)
3223 result = ISC_R_SUCCESS;
3224
3225 if (!ok) {
3226 result = DNS_R_BADZONE;
3227 dns_zone_log(zone, ISC_LOG_ERROR,
3228 "no supported nsec3 hash algorithm");
3229 }
3230
3231 cleanup:
3232 if (dns_rdataset_isassociated(&rdataset))
3233 dns_rdataset_disassociate(&rdataset);
3234 dns_db_closeversion(db, &version, ISC_FALSE);
3235 dns_db_detachnode(db, &node);
3236 return (result);
3237 }
3238
3239 /*
3240 * Set the timer for refreshing the key zone to the soonest future time
3241 * of the set (current timer, keydata->refresh, keydata->addhd,
3242 * keydata->removehd).
3243 */
3244 static void
set_refreshkeytimer(dns_zone_t * zone,dns_rdata_keydata_t * key,isc_stdtime_t now,isc_boolean_t force)3245 set_refreshkeytimer(dns_zone_t *zone, dns_rdata_keydata_t *key,
3246 isc_stdtime_t now, isc_boolean_t force)
3247 {
3248 const char me[] = "set_refreshkeytimer";
3249 isc_stdtime_t then;
3250 isc_time_t timenow, timethen;
3251 char timebuf[80];
3252
3253 ENTER;
3254 then = key->refresh;
3255 if (force)
3256 then = now;
3257 if (key->addhd > now && key->addhd < then)
3258 then = key->addhd;
3259 if (key->removehd > now && key->removehd < then)
3260 then = key->removehd;
3261
3262 TIME_NOW(&timenow);
3263 if (then > now)
3264 DNS_ZONE_TIME_ADD(&timenow, then - now, &timethen);
3265 else
3266 timethen = timenow;
3267 if (isc_time_compare(&zone->refreshkeytime, &timenow) < 0 ||
3268 isc_time_compare(&timethen, &zone->refreshkeytime) < 0)
3269 zone->refreshkeytime = timethen;
3270
3271 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
3272 dns_zone_log(zone, ISC_LOG_DEBUG(1), "next key refresh: %s", timebuf);
3273 zone_settimer(zone, &timenow);
3274 }
3275
3276 /*
3277 * Convert key(s) linked from 'keynode' to KEYDATA and add to the key zone.
3278 * If the key zone is changed, set '*changed' to ISC_TRUE.
3279 */
3280 static isc_result_t
create_keydata(dns_zone_t * zone,dns_db_t * db,dns_dbversion_t * ver,dns_diff_t * diff,dns_keytable_t * keytable,dns_keynode_t ** keynodep,isc_boolean_t * changed)3281 create_keydata(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
3282 dns_diff_t *diff, dns_keytable_t *keytable,
3283 dns_keynode_t **keynodep, isc_boolean_t *changed)
3284 {
3285 const char me[] = "create_keydata";
3286 isc_result_t result = ISC_R_SUCCESS;
3287 isc_buffer_t keyb, dstb;
3288 unsigned char key_buf[4096], dst_buf[DST_KEY_MAXSIZE];
3289 dns_rdata_keydata_t keydata;
3290 dns_rdata_dnskey_t dnskey;
3291 dns_rdata_t rdata = DNS_RDATA_INIT;
3292 dns_keynode_t *keynode;
3293 isc_stdtime_t now;
3294 isc_region_t r;
3295 dst_key_t *key;
3296
3297 REQUIRE(keynodep != NULL);
3298 keynode = *keynodep;
3299
3300 ENTER;
3301 isc_stdtime_get(&now);
3302
3303 /* Loop in case there's more than one key. */
3304 while (result == ISC_R_SUCCESS) {
3305 dns_keynode_t *nextnode = NULL;
3306
3307 key = dns_keynode_key(keynode);
3308 if (key == NULL)
3309 goto skip;
3310
3311 isc_buffer_init(&dstb, dst_buf, sizeof(dst_buf));
3312 CHECK(dst_key_todns(key, &dstb));
3313
3314 /* Convert DST key to DNSKEY. */
3315 dns_rdata_reset(&rdata);
3316 isc_buffer_usedregion(&dstb, &r);
3317 dns_rdata_fromregion(&rdata, dst_key_class(key),
3318 dns_rdatatype_dnskey, &r);
3319
3320 /* DSTKEY to KEYDATA. */
3321 CHECK(dns_rdata_tostruct(&rdata, &dnskey, NULL));
3322 CHECK(dns_keydata_fromdnskey(&keydata, &dnskey, now, 0, 0,
3323 NULL));
3324
3325 /* KEYDATA to rdata. */
3326 dns_rdata_reset(&rdata);
3327 isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
3328 CHECK(dns_rdata_fromstruct(&rdata,
3329 zone->rdclass, dns_rdatatype_keydata,
3330 &keydata, &keyb));
3331
3332 /* Add rdata to zone. */
3333 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD,
3334 dst_key_name(key), 0, &rdata));
3335 *changed = ISC_TRUE;
3336
3337 /* Refresh new keys from the zone apex as soon as possible. */
3338 set_refreshkeytimer(zone, &keydata, now, ISC_TRUE);
3339
3340 skip:
3341 result = dns_keytable_nextkeynode(keytable, keynode, &nextnode);
3342 if (result != ISC_R_NOTFOUND) {
3343 dns_keytable_detachkeynode(keytable, &keynode);
3344 keynode = nextnode;
3345 }
3346 }
3347
3348 if (keynode != NULL)
3349 dns_keytable_detachkeynode(keytable, &keynode);
3350 *keynodep = NULL;
3351
3352 return (ISC_R_SUCCESS);
3353
3354 failure:
3355 return (result);
3356 }
3357
3358 /*
3359 * Remove from the key zone all the KEYDATA records found in rdataset.
3360 */
3361 static isc_result_t
delete_keydata(dns_db_t * db,dns_dbversion_t * ver,dns_diff_t * diff,dns_name_t * name,dns_rdataset_t * rdataset)3362 delete_keydata(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff,
3363 dns_name_t *name, dns_rdataset_t *rdataset)
3364 {
3365 dns_rdata_t rdata = DNS_RDATA_INIT;
3366 isc_result_t result, uresult;
3367
3368 for (result = dns_rdataset_first(rdataset);
3369 result == ISC_R_SUCCESS;
3370 result = dns_rdataset_next(rdataset)) {
3371 dns_rdata_reset(&rdata);
3372 dns_rdataset_current(rdataset, &rdata);
3373 uresult = update_one_rr(db, ver, diff, DNS_DIFFOP_DEL,
3374 name, 0, &rdata);
3375 if (uresult != ISC_R_SUCCESS)
3376 return (uresult);
3377 }
3378 if (result == ISC_R_NOMORE)
3379 result = ISC_R_SUCCESS;
3380 return (result);
3381 }
3382
3383 /*
3384 * Compute the DNSSEC key ID for a DNSKEY record.
3385 */
3386 static isc_result_t
compute_tag(dns_name_t * name,dns_rdata_dnskey_t * dnskey,isc_mem_t * mctx,dns_keytag_t * tag)3387 compute_tag(dns_name_t *name, dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx,
3388 dns_keytag_t *tag)
3389 {
3390 isc_result_t result;
3391 dns_rdata_t rdata = DNS_RDATA_INIT;
3392 unsigned char data[4096];
3393 isc_buffer_t buffer;
3394 dst_key_t *dstkey = NULL;
3395
3396 isc_buffer_init(&buffer, data, sizeof(data));
3397 dns_rdata_fromstruct(&rdata, dnskey->common.rdclass,
3398 dns_rdatatype_dnskey, dnskey, &buffer);
3399
3400 result = dns_dnssec_keyfromrdata(name, &rdata, mctx, &dstkey);
3401 if (result == ISC_R_SUCCESS)
3402 *tag = dst_key_id(dstkey);
3403 dst_key_free(&dstkey);
3404
3405 return (result);
3406 }
3407
3408 /*
3409 * Add key to the security roots.
3410 */
3411 static void
trust_key(dns_zone_t * zone,dns_name_t * keyname,dns_rdata_dnskey_t * dnskey,isc_mem_t * mctx)3412 trust_key(dns_zone_t *zone, dns_name_t *keyname,
3413 dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx)
3414 {
3415 isc_result_t result;
3416 dns_rdata_t rdata = DNS_RDATA_INIT;
3417 unsigned char data[4096];
3418 isc_buffer_t buffer;
3419 dns_keytable_t *sr = NULL;
3420 dst_key_t *dstkey = NULL;
3421
3422 /* Convert dnskey to DST key. */
3423 isc_buffer_init(&buffer, data, sizeof(data));
3424 dns_rdata_fromstruct(&rdata, dnskey->common.rdclass,
3425 dns_rdatatype_dnskey, dnskey, &buffer);
3426
3427 result = dns_view_getsecroots(zone->view, &sr);
3428 if (result != ISC_R_SUCCESS)
3429 goto failure;
3430
3431 CHECK(dns_dnssec_keyfromrdata(keyname, &rdata, mctx, &dstkey));
3432 CHECK(dns_keytable_add(sr, ISC_TRUE, &dstkey));
3433 dns_keytable_detach(&sr);
3434
3435 failure:
3436 if (dstkey != NULL)
3437 dst_key_free(&dstkey);
3438 if (sr != NULL)
3439 dns_keytable_detach(&sr);
3440 return;
3441 }
3442
3443 /*
3444 * Add a null key to the security roots for so that all queries
3445 * to the zone will fail.
3446 */
3447 static void
fail_secure(dns_zone_t * zone,dns_name_t * keyname)3448 fail_secure(dns_zone_t *zone, dns_name_t *keyname) {
3449 isc_result_t result;
3450 dns_keytable_t *sr = NULL;
3451
3452 result = dns_view_getsecroots(zone->view, &sr);
3453 if (result == ISC_R_SUCCESS) {
3454 dns_keytable_marksecure(sr, keyname);
3455 dns_keytable_detach(&sr);
3456 }
3457 }
3458
3459 /*
3460 * Scan a set of KEYDATA records from the key zone. The ones that are
3461 * valid (i.e., the add holddown timer has expired) become trusted keys.
3462 */
3463 static void
load_secroots(dns_zone_t * zone,dns_name_t * name,dns_rdataset_t * rdataset)3464 load_secroots(dns_zone_t *zone, dns_name_t *name, dns_rdataset_t *rdataset) {
3465 isc_result_t result;
3466 dns_rdata_t rdata = DNS_RDATA_INIT;
3467 dns_rdata_keydata_t keydata;
3468 dns_rdata_dnskey_t dnskey;
3469 isc_mem_t *mctx = zone->mctx;
3470 int trusted = 0, revoked = 0, pending = 0;
3471 isc_stdtime_t now;
3472 dns_keytable_t *sr = NULL;
3473
3474 isc_stdtime_get(&now);
3475
3476 result = dns_view_getsecroots(zone->view, &sr);
3477 if (result == ISC_R_SUCCESS) {
3478 dns_keytable_delete(sr, name);
3479 dns_keytable_detach(&sr);
3480 }
3481
3482 /* Now insert all the accepted trust anchors from this keydata set. */
3483 for (result = dns_rdataset_first(rdataset);
3484 result == ISC_R_SUCCESS;
3485 result = dns_rdataset_next(rdataset)) {
3486 dns_rdata_reset(&rdata);
3487 dns_rdataset_current(rdataset, &rdata);
3488
3489 /* Convert rdata to keydata. */
3490 result = dns_rdata_tostruct(&rdata, &keydata, NULL);
3491 if (result == ISC_R_UNEXPECTEDEND)
3492 continue;
3493 RUNTIME_CHECK(result == ISC_R_SUCCESS);
3494
3495 /* Set the key refresh timer to force a fast refresh. */
3496 set_refreshkeytimer(zone, &keydata, now, ISC_TRUE);
3497
3498 /* If the removal timer is nonzero, this key was revoked. */
3499 if (keydata.removehd != 0) {
3500 revoked++;
3501 continue;
3502 }
3503
3504 /*
3505 * If the add timer is still pending, this key is not
3506 * trusted yet.
3507 */
3508 if (now < keydata.addhd) {
3509 pending++;
3510 continue;
3511 }
3512
3513 /* Convert keydata to dnskey. */
3514 dns_keydata_todnskey(&keydata, &dnskey, NULL);
3515
3516 /* Add to keytables. */
3517 trusted++;
3518 trust_key(zone, name, &dnskey, mctx);
3519 }
3520
3521 if (trusted == 0 && pending != 0) {
3522 char namebuf[DNS_NAME_FORMATSIZE];
3523 dns_name_format(name, namebuf, sizeof namebuf);
3524 dns_zone_log(zone, ISC_LOG_ERROR,
3525 "No valid trust anchors for '%s'!", namebuf);
3526 dns_zone_log(zone, ISC_LOG_ERROR,
3527 "%d key(s) revoked, %d still pending",
3528 revoked, pending);
3529 dns_zone_log(zone, ISC_LOG_ERROR,
3530 "All queries to '%s' will fail", namebuf);
3531 fail_secure(zone, name);
3532 }
3533 }
3534
3535 static isc_result_t
do_one_tuple(dns_difftuple_t ** tuple,dns_db_t * db,dns_dbversion_t * ver,dns_diff_t * diff)3536 do_one_tuple(dns_difftuple_t **tuple, dns_db_t *db, dns_dbversion_t *ver,
3537 dns_diff_t *diff)
3538 {
3539 dns_diff_t temp_diff;
3540 isc_result_t result;
3541
3542 /*
3543 * Create a singleton diff.
3544 */
3545 dns_diff_init(diff->mctx, &temp_diff);
3546 ISC_LIST_APPEND(temp_diff.tuples, *tuple, link);
3547
3548 /*
3549 * Apply it to the database.
3550 */
3551 result = dns_diff_apply(&temp_diff, db, ver);
3552 ISC_LIST_UNLINK(temp_diff.tuples, *tuple, link);
3553 if (result != ISC_R_SUCCESS) {
3554 dns_difftuple_free(tuple);
3555 return (result);
3556 }
3557
3558 /*
3559 * Merge it into the current pending journal entry.
3560 */
3561 dns_diff_appendminimal(diff, tuple);
3562
3563 /*
3564 * Do not clear temp_diff.
3565 */
3566 return (ISC_R_SUCCESS);
3567 }
3568
3569 static isc_result_t
update_one_rr(dns_db_t * db,dns_dbversion_t * ver,dns_diff_t * diff,dns_diffop_t op,dns_name_t * name,dns_ttl_t ttl,dns_rdata_t * rdata)3570 update_one_rr(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff,
3571 dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl,
3572 dns_rdata_t *rdata)
3573 {
3574 dns_difftuple_t *tuple = NULL;
3575 isc_result_t result;
3576 result = dns_difftuple_create(diff->mctx, op,
3577 name, ttl, rdata, &tuple);
3578 if (result != ISC_R_SUCCESS)
3579 return (result);
3580 return (do_one_tuple(&tuple, db, ver, diff));
3581 }
3582
3583 static isc_result_t
update_soa_serial(dns_db_t * db,dns_dbversion_t * ver,dns_diff_t * diff,isc_mem_t * mctx,dns_updatemethod_t method)3584 update_soa_serial(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff,
3585 isc_mem_t *mctx, dns_updatemethod_t method) {
3586 dns_difftuple_t *deltuple = NULL;
3587 dns_difftuple_t *addtuple = NULL;
3588 isc_uint32_t serial;
3589 isc_result_t result;
3590
3591 CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_DEL, &deltuple));
3592 CHECK(dns_difftuple_copy(deltuple, &addtuple));
3593 addtuple->op = DNS_DIFFOP_ADD;
3594
3595 serial = dns_soa_getserial(&addtuple->rdata);
3596 serial = dns_update_soaserial(serial, method);
3597 dns_soa_setserial(serial, &addtuple->rdata);
3598 CHECK(do_one_tuple(&deltuple, db, ver, diff));
3599 CHECK(do_one_tuple(&addtuple, db, ver, diff));
3600 result = ISC_R_SUCCESS;
3601
3602 failure:
3603 if (addtuple != NULL)
3604 dns_difftuple_free(&addtuple);
3605 if (deltuple != NULL)
3606 dns_difftuple_free(&deltuple);
3607 return (result);
3608 }
3609
3610 /*
3611 * Write all transactions in 'diff' to the zone journal file.
3612 */
3613 static isc_result_t
zone_journal(dns_zone_t * zone,dns_diff_t * diff,isc_uint32_t * sourceserial,const char * caller)3614 zone_journal(dns_zone_t *zone, dns_diff_t *diff, isc_uint32_t *sourceserial,
3615 const char *caller)
3616 {
3617 const char me[] = "zone_journal";
3618 const char *journalfile;
3619 isc_result_t result = ISC_R_SUCCESS;
3620 dns_journal_t *journal = NULL;
3621 unsigned int mode = DNS_JOURNAL_CREATE|DNS_JOURNAL_WRITE;
3622
3623 ENTER;
3624 journalfile = dns_zone_getjournal(zone);
3625 if (journalfile != NULL) {
3626 result = dns_journal_open(zone->mctx, journalfile, mode,
3627 &journal);
3628 if (result != ISC_R_SUCCESS) {
3629 dns_zone_log(zone, ISC_LOG_ERROR,
3630 "%s:dns_journal_open -> %s",
3631 caller, dns_result_totext(result));
3632 return (result);
3633 }
3634
3635 if (sourceserial != NULL)
3636 dns_journal_set_sourceserial(journal, *sourceserial);
3637
3638 result = dns_journal_write_transaction(journal, diff);
3639 if (result != ISC_R_SUCCESS) {
3640 dns_zone_log(zone, ISC_LOG_ERROR,
3641 "%s:dns_journal_write_transaction -> %s",
3642 caller, dns_result_totext(result));
3643 }
3644 dns_journal_destroy(&journal);
3645 }
3646
3647 return (result);
3648 }
3649
3650 /*
3651 * Create an SOA record for a newly-created zone
3652 */
3653 static isc_result_t
add_soa(dns_zone_t * zone,dns_db_t * db)3654 add_soa(dns_zone_t *zone, dns_db_t *db) {
3655 isc_result_t result;
3656 dns_rdata_t rdata = DNS_RDATA_INIT;
3657 unsigned char buf[DNS_SOA_BUFFERSIZE];
3658 dns_dbversion_t *ver = NULL;
3659 dns_diff_t diff;
3660
3661 dns_zone_log(zone, ISC_LOG_DEBUG(1), "creating SOA");
3662
3663 dns_diff_init(zone->mctx, &diff);
3664 result = dns_db_newversion(db, &ver);
3665 if (result != ISC_R_SUCCESS) {
3666 dns_zone_log(zone, ISC_LOG_ERROR,
3667 "add_soa:dns_db_newversion -> %s",
3668 dns_result_totext(result));
3669 goto failure;
3670 }
3671
3672 /* Build SOA record */
3673 result = dns_soa_buildrdata(&zone->origin, dns_rootname, zone->rdclass,
3674 0, 0, 0, 0, 0, buf, &rdata);
3675 if (result != ISC_R_SUCCESS) {
3676 dns_zone_log(zone, ISC_LOG_ERROR,
3677 "add_soa:dns_soa_buildrdata -> %s",
3678 dns_result_totext(result));
3679 goto failure;
3680 }
3681
3682 result = update_one_rr(db, ver, &diff, DNS_DIFFOP_ADD,
3683 &zone->origin, 0, &rdata);
3684
3685 failure:
3686 dns_diff_clear(&diff);
3687 if (ver != NULL)
3688 dns_db_closeversion(db, &ver, ISC_TF(result == ISC_R_SUCCESS));
3689
3690 INSIST(ver == NULL);
3691
3692 return (result);
3693 }
3694
3695 /*
3696 * Synchronize the set of initializing keys found in managed-keys {}
3697 * statements with the set of trust anchors found in the managed-keys.bind
3698 * zone. If a domain is no longer named in managed-keys, delete all keys
3699 * from that domain from the key zone. If a domain is mentioned in in
3700 * managed-keys but there are no references to it in the key zone, load
3701 * the key zone with the initializing key(s) for that domain.
3702 */
3703 static isc_result_t
sync_keyzone(dns_zone_t * zone,dns_db_t * db)3704 sync_keyzone(dns_zone_t *zone, dns_db_t *db) {
3705 isc_result_t result = ISC_R_SUCCESS;
3706 isc_boolean_t changed = ISC_FALSE;
3707 isc_boolean_t commit = ISC_FALSE;
3708 dns_rbtnodechain_t chain;
3709 dns_fixedname_t fn;
3710 dns_name_t foundname, *origin;
3711 dns_keynode_t *keynode = NULL;
3712 dns_view_t *view = zone->view;
3713 dns_keytable_t *sr = NULL;
3714 dns_dbversion_t *ver = NULL;
3715 dns_diff_t diff;
3716 dns_rriterator_t rrit;
3717
3718 dns_zone_log(zone, ISC_LOG_DEBUG(1), "synchronizing trusted keys");
3719
3720 dns_name_init(&foundname, NULL);
3721 dns_fixedname_init(&fn);
3722 origin = dns_fixedname_name(&fn);
3723
3724 dns_diff_init(zone->mctx, &diff);
3725
3726 CHECK(dns_view_getsecroots(view, &sr));
3727
3728 result = dns_db_newversion(db, &ver);
3729 if (result != ISC_R_SUCCESS) {
3730 dns_zone_log(zone, ISC_LOG_ERROR,
3731 "sync_keyzone:dns_db_newversion -> %s",
3732 dns_result_totext(result));
3733 goto failure;
3734 }
3735
3736 /*
3737 * Walk the zone DB. If we find any keys whose names are no longer
3738 * in managed-keys (or *are* in trusted-keys, meaning they are
3739 * permanent and not RFC5011-maintained), delete them from the
3740 * zone. Otherwise call load_secroots(), which loads keys into
3741 * secroots as appropriate.
3742 */
3743 dns_rriterator_init(&rrit, db, ver, 0);
3744 for (result = dns_rriterator_first(&rrit);
3745 result == ISC_R_SUCCESS;
3746 result = dns_rriterator_nextrrset(&rrit)) {
3747 dns_rdataset_t *rdataset = NULL;
3748 dns_name_t *rrname = NULL;
3749 isc_uint32_t ttl;
3750
3751 dns_rriterator_current(&rrit, &rrname, &ttl,
3752 &rdataset, NULL);
3753 if (!dns_rdataset_isassociated(rdataset)) {
3754 dns_rriterator_destroy(&rrit);
3755 goto failure;
3756 }
3757
3758 if (rdataset->type != dns_rdatatype_keydata)
3759 continue;
3760
3761 result = dns_keytable_find(sr, rrname, &keynode);
3762 if ((result != ISC_R_SUCCESS &&
3763 result != DNS_R_PARTIALMATCH) ||
3764 dns_keynode_managed(keynode) == ISC_FALSE)
3765 {
3766 CHECK(delete_keydata(db, ver, &diff,
3767 rrname, rdataset));
3768 changed = ISC_TRUE;
3769 } else {
3770 load_secroots(zone, rrname, rdataset);
3771 }
3772
3773 if (keynode != NULL)
3774 dns_keytable_detachkeynode(sr, &keynode);
3775 }
3776 dns_rriterator_destroy(&rrit);
3777
3778 /*
3779 * Now walk secroots to find any managed keys that aren't
3780 * in the zone. If we find any, we add them to the zone.
3781 */
3782 RWLOCK(&sr->rwlock, isc_rwlocktype_write);
3783 dns_rbtnodechain_init(&chain, zone->mctx);
3784 result = dns_rbtnodechain_first(&chain, sr->table, &foundname, origin);
3785 if (result == ISC_R_NOTFOUND)
3786 result = ISC_R_NOMORE;
3787 while (result == DNS_R_NEWORIGIN || result == ISC_R_SUCCESS) {
3788 dns_rbtnode_t *rbtnode = NULL;
3789
3790 dns_rbtnodechain_current(&chain, &foundname, origin, &rbtnode);
3791 if (rbtnode->data == NULL)
3792 goto skip;
3793
3794 dns_keytable_attachkeynode(sr, rbtnode->data, &keynode);
3795 if (dns_keynode_managed(keynode)) {
3796 dns_fixedname_t fname;
3797 dns_name_t *keyname;
3798 dst_key_t *key;
3799
3800 key = dns_keynode_key(keynode);
3801 dns_fixedname_init(&fname);
3802
3803 if (key == NULL) /* fail_secure() was called. */
3804 goto skip;
3805
3806 keyname = dst_key_name(key);
3807 result = dns_db_find(db, keyname, ver,
3808 dns_rdatatype_keydata,
3809 DNS_DBFIND_NOWILD, 0, NULL,
3810 dns_fixedname_name(&fname),
3811 NULL, NULL);
3812 if (result != ISC_R_SUCCESS)
3813 result = create_keydata(zone, db, ver, &diff,
3814 sr, &keynode, &changed);
3815 if (result != ISC_R_SUCCESS)
3816 break;
3817 }
3818 skip:
3819 result = dns_rbtnodechain_next(&chain, &foundname, origin);
3820 if (keynode != NULL)
3821 dns_keytable_detachkeynode(sr, &keynode);
3822 }
3823 RWUNLOCK(&sr->rwlock, isc_rwlocktype_write);
3824
3825 if (result == ISC_R_NOMORE)
3826 result = ISC_R_SUCCESS;
3827
3828 if (changed) {
3829 /* Write changes to journal file. */
3830 CHECK(update_soa_serial(db, ver, &diff, zone->mctx,
3831 zone->updatemethod));
3832 CHECK(zone_journal(zone, &diff, NULL, "sync_keyzone"));
3833
3834 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
3835 zone_needdump(zone, 30);
3836 commit = ISC_TRUE;
3837 }
3838
3839 failure:
3840 if (result != ISC_R_SUCCESS &&
3841 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
3842 dns_zone_log(zone, ISC_LOG_ERROR,
3843 "unable to synchronize managed keys: %s",
3844 dns_result_totext(result));
3845 isc_time_settoepoch(&zone->refreshkeytime);
3846 }
3847 if (keynode != NULL)
3848 dns_keytable_detachkeynode(sr, &keynode);
3849 if (sr != NULL)
3850 dns_keytable_detach(&sr);
3851 if (ver != NULL)
3852 dns_db_closeversion(db, &ver, commit);
3853 dns_diff_clear(&diff);
3854
3855 INSIST(ver == NULL);
3856
3857 return (result);
3858 }
3859
3860 isc_result_t
dns_zone_synckeyzone(dns_zone_t * zone)3861 dns_zone_synckeyzone(dns_zone_t *zone) {
3862 isc_result_t result;
3863 dns_db_t *db = NULL;
3864
3865 if (zone->type != dns_zone_key)
3866 return (DNS_R_BADZONE);
3867
3868 CHECK(dns_zone_getdb(zone, &db));
3869
3870 LOCK_ZONE(zone);
3871 result = sync_keyzone(zone, db);
3872 UNLOCK_ZONE(zone);
3873
3874 failure:
3875 if (db != NULL)
3876 dns_db_detach(&db);
3877 return (result);
3878 }
3879
3880 static void
maybe_send_secure(dns_zone_t * zone)3881 maybe_send_secure(dns_zone_t *zone) {
3882 isc_result_t result;
3883
3884 /*
3885 * We've finished loading, or else failed to load, an inline-signing
3886 * 'secure' zone. We now need information about the status of the
3887 * 'raw' zone. If we failed to load, then we need it to send a
3888 * copy of its database; if we succeeded, we need it to send its
3889 * serial number so that we can sync with it. If it has not yet
3890 * loaded, we set a flag so that it will send the necessary
3891 * information when it has finished loading.
3892 */
3893 if (zone->raw->db != NULL) {
3894 if (zone->db != NULL) {
3895 isc_uint32_t serial;
3896 unsigned int soacount;
3897
3898 result = zone_get_from_db(zone->raw, zone->raw->db,
3899 NULL, &soacount, &serial, NULL,
3900 NULL, NULL, NULL, NULL);
3901 if (result == ISC_R_SUCCESS && soacount > 0U)
3902 zone_send_secureserial(zone->raw, serial);
3903 } else
3904 zone_send_securedb(zone->raw, zone->raw->db);
3905
3906 } else
3907 DNS_ZONE_SETFLAG(zone->raw, DNS_ZONEFLG_SENDSECURE);
3908 }
3909
3910 static isc_boolean_t
zone_unchanged(dns_db_t * db1,dns_db_t * db2,isc_mem_t * mctx)3911 zone_unchanged(dns_db_t *db1, dns_db_t *db2, isc_mem_t *mctx) {
3912 isc_result_t result;
3913 isc_boolean_t answer = ISC_FALSE;
3914 dns_diff_t diff;
3915
3916 dns_diff_init(mctx, &diff);
3917 result = dns_db_diffx(&diff, db1, NULL, db2, NULL, NULL);
3918 if (result == ISC_R_SUCCESS && ISC_LIST_EMPTY(diff.tuples))
3919 answer = ISC_TRUE;
3920 dns_diff_clear(&diff);
3921 return (answer);
3922 }
3923
3924 /*
3925 * The zone is presumed to be locked.
3926 * If this is a inline_raw zone the secure version is also locked.
3927 */
3928 static isc_result_t
zone_postload(dns_zone_t * zone,dns_db_t * db,isc_time_t loadtime,isc_result_t result)3929 zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
3930 isc_result_t result)
3931 {
3932 unsigned int soacount = 0;
3933 unsigned int nscount = 0;
3934 unsigned int errors = 0;
3935 isc_uint32_t serial, oldserial, refresh, retry, expire, minimum;
3936 isc_time_t now;
3937 isc_boolean_t needdump = ISC_FALSE;
3938 isc_boolean_t hasinclude = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE);
3939 isc_boolean_t nomaster = ISC_FALSE;
3940 unsigned int options;
3941
3942 INSIST(LOCKED_ZONE(zone));
3943 if (inline_raw(zone))
3944 INSIST(LOCKED_ZONE(zone->secure));
3945
3946 TIME_NOW(&now);
3947
3948 /*
3949 * Initiate zone transfer? We may need a error code that
3950 * indicates that the "permanent" form does not exist.
3951 * XXX better error feedback to log.
3952 */
3953 if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE) {
3954 if (zone->type == dns_zone_slave ||
3955 zone->type == dns_zone_stub ||
3956 (zone->type == dns_zone_redirect &&
3957 zone->masters == NULL)) {
3958 if (result == ISC_R_FILENOTFOUND)
3959 dns_zone_log(zone, ISC_LOG_DEBUG(1),
3960 "no master file");
3961 else if (result != DNS_R_NOMASTERFILE)
3962 dns_zone_log(zone, ISC_LOG_ERROR,
3963 "loading from master file %s "
3964 "failed: %s",
3965 zone->masterfile,
3966 dns_result_totext(result));
3967 } else if (zone->type == dns_zone_master &&
3968 inline_secure(zone) && result == ISC_R_FILENOTFOUND)
3969 {
3970 dns_zone_log(zone, ISC_LOG_DEBUG(1),
3971 "no master file, requesting db");
3972 maybe_send_secure(zone);
3973 } else {
3974 int level = ISC_LOG_ERROR;
3975 if (zone->type == dns_zone_key &&
3976 result == ISC_R_FILENOTFOUND)
3977 level = ISC_LOG_DEBUG(1);
3978 dns_zone_log(zone, level,
3979 "loading from master file %s failed: %s",
3980 zone->masterfile,
3981 dns_result_totext(result));
3982 nomaster = ISC_TRUE;
3983 }
3984
3985 if (zone->type != dns_zone_key)
3986 goto cleanup;
3987 }
3988
3989 dns_zone_log(zone, ISC_LOG_DEBUG(2),
3990 "number of nodes in database: %u",
3991 dns_db_nodecount(db));
3992
3993 if (result == DNS_R_SEENINCLUDE)
3994 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HASINCLUDE);
3995 else
3996 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HASINCLUDE);
3997
3998 /*
3999 * If there's no master file for a key zone, then the zone is new:
4000 * create an SOA record. (We do this now, instead of later, so that
4001 * if there happens to be a journal file, we can roll forward from
4002 * a sane starting point.)
4003 */
4004 if (nomaster && zone->type == dns_zone_key) {
4005 result = add_soa(zone, db);
4006 if (result != ISC_R_SUCCESS)
4007 goto cleanup;
4008 }
4009
4010 /*
4011 * Apply update log, if any, on initial load.
4012 */
4013 if (zone->journal != NULL &&
4014 ! DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOMERGE) &&
4015 ! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
4016 {
4017 if (zone->type == dns_zone_master &&
4018 (zone->update_acl != NULL || zone->ssutable != NULL))
4019 options = DNS_JOURNALOPT_RESIGN;
4020 else
4021 options = 0;
4022 result = dns_journal_rollforward2(zone->mctx, db, options,
4023 0, zone->journal);
4024 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND &&
4025 result != DNS_R_UPTODATE && result != DNS_R_NOJOURNAL &&
4026 result != ISC_R_RANGE) {
4027 dns_zone_log(zone, ISC_LOG_ERROR,
4028 "journal rollforward failed: %s",
4029 dns_result_totext(result));
4030 goto cleanup;
4031
4032
4033 }
4034 if (result == ISC_R_NOTFOUND || result == ISC_R_RANGE) {
4035 dns_zone_log(zone, ISC_LOG_ERROR,
4036 "journal rollforward failed: "
4037 "journal out of sync with zone");
4038 goto cleanup;
4039 }
4040 dns_zone_log(zone, ISC_LOG_DEBUG(1),
4041 "journal rollforward completed "
4042 "successfully: %s",
4043 dns_result_totext(result));
4044 if (result == ISC_R_SUCCESS)
4045 needdump = ISC_TRUE;
4046 }
4047
4048 /*
4049 * Obtain ns, soa and cname counts for top of zone.
4050 */
4051 INSIST(db != NULL);
4052 result = zone_get_from_db(zone, db, &nscount, &soacount, &serial,
4053 &refresh, &retry, &expire, &minimum,
4054 &errors);
4055 if (result != ISC_R_SUCCESS && zone->type != dns_zone_key) {
4056 dns_zone_log(zone, ISC_LOG_ERROR,
4057 "could not find NS and/or SOA records");
4058 }
4059
4060 /*
4061 * Check to make sure the journal is up to date, and remove the
4062 * journal file if it isn't, as we wouldn't be able to apply
4063 * updates otherwise.
4064 */
4065 if (zone->journal != NULL && dns_zone_isdynamic(zone, ISC_TRUE) &&
4066 ! DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS)) {
4067 isc_uint32_t jserial;
4068 dns_journal_t *journal = NULL;
4069
4070 result = dns_journal_open(zone->mctx, zone->journal,
4071 DNS_JOURNAL_READ, &journal);
4072 if (result == ISC_R_SUCCESS) {
4073 jserial = dns_journal_last_serial(journal);
4074 dns_journal_destroy(&journal);
4075 } else {
4076 jserial = serial;
4077 result = ISC_R_SUCCESS;
4078 }
4079
4080 if (jserial != serial) {
4081 dns_zone_log(zone, ISC_LOG_INFO,
4082 "journal file is out of date: "
4083 "removing journal file");
4084 if (remove(zone->journal) < 0 && errno != ENOENT) {
4085 char strbuf[ISC_STRERRORSIZE];
4086 isc__strerror(errno, strbuf, sizeof(strbuf));
4087 isc_log_write(dns_lctx,
4088 DNS_LOGCATEGORY_GENERAL,
4089 DNS_LOGMODULE_ZONE,
4090 ISC_LOG_WARNING,
4091 "unable to remove journal "
4092 "'%s': '%s'",
4093 zone->journal, strbuf);
4094 }
4095 }
4096 }
4097
4098 dns_zone_log(zone, ISC_LOG_DEBUG(1), "loaded; checking validity");
4099
4100 /*
4101 * Master / Slave / Stub zones require both NS and SOA records at
4102 * the top of the zone.
4103 */
4104
4105 switch (zone->type) {
4106 case dns_zone_dlz:
4107 case dns_zone_master:
4108 case dns_zone_slave:
4109 case dns_zone_stub:
4110 case dns_zone_redirect:
4111 if (soacount != 1) {
4112 dns_zone_log(zone, ISC_LOG_ERROR,
4113 "has %d SOA records", soacount);
4114 result = DNS_R_BADZONE;
4115 }
4116 if (nscount == 0) {
4117 dns_zone_log(zone, ISC_LOG_ERROR,
4118 "has no NS records");
4119 result = DNS_R_BADZONE;
4120 }
4121 if (result != ISC_R_SUCCESS)
4122 goto cleanup;
4123 if (zone->type == dns_zone_master && errors != 0) {
4124 result = DNS_R_BADZONE;
4125 goto cleanup;
4126 }
4127 if (zone->type != dns_zone_stub &&
4128 zone->type != dns_zone_redirect) {
4129 result = check_nsec3param(zone, db);
4130 if (result != ISC_R_SUCCESS)
4131 goto cleanup;
4132 }
4133 if (zone->type == dns_zone_master &&
4134 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKINTEGRITY) &&
4135 !integrity_checks(zone, db)) {
4136 result = DNS_R_BADZONE;
4137 goto cleanup;
4138 }
4139 if (zone->type == dns_zone_master &&
4140 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKDUPRR) &&
4141 !zone_check_dup(zone, db)) {
4142 result = DNS_R_BADZONE;
4143 goto cleanup;
4144 }
4145
4146 if (zone->db != NULL) {
4147 unsigned int oldsoacount;
4148
4149 /*
4150 * This is checked in zone_replacedb() for slave zones
4151 * as they don't reload from disk.
4152 */
4153 result = zone_get_from_db(zone, zone->db, NULL,
4154 &oldsoacount, &oldserial,
4155 NULL, NULL, NULL, NULL,
4156 NULL);
4157 RUNTIME_CHECK(result == ISC_R_SUCCESS);
4158 RUNTIME_CHECK(soacount > 0U);
4159 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) &&
4160 !isc_serial_gt(serial, oldserial)) {
4161 isc_uint32_t serialmin, serialmax;
4162
4163 INSIST(zone->type == dns_zone_master);
4164
4165 if (serial == oldserial &&
4166 zone_unchanged(zone->db, db, zone->mctx)) {
4167 dns_zone_log(zone, ISC_LOG_INFO,
4168 "ixfr-from-differences: "
4169 "unchanged");
4170 return(ISC_R_SUCCESS);
4171 }
4172
4173 serialmin = (oldserial + 1) & 0xffffffffU;
4174 serialmax = (oldserial + 0x7fffffffU) &
4175 0xffffffffU;
4176 dns_zone_log(zone, ISC_LOG_ERROR,
4177 "ixfr-from-differences: "
4178 "new serial (%u) out of range "
4179 "[%u - %u]", serial, serialmin,
4180 serialmax);
4181 result = DNS_R_BADZONE;
4182 goto cleanup;
4183 } else if (!isc_serial_ge(serial, oldserial))
4184 dns_zone_log(zone, ISC_LOG_ERROR,
4185 "zone serial (%u/%u) has gone "
4186 "backwards", serial, oldserial);
4187 else if (serial == oldserial && !hasinclude &&
4188 strcmp(zone->db_argv[0], "_builtin") != 0)
4189 dns_zone_log(zone, ISC_LOG_ERROR,
4190 "zone serial (%u) unchanged. "
4191 "zone may fail to transfer "
4192 "to slaves.", serial);
4193 }
4194
4195 if (zone->type == dns_zone_master &&
4196 (zone->update_acl != NULL || zone->ssutable != NULL) &&
4197 zone->sigresigninginterval < (3 * refresh) &&
4198 dns_db_issecure(db))
4199 {
4200 dns_zone_log(zone, ISC_LOG_WARNING,
4201 "sig-re-signing-interval less than "
4202 "3 * refresh.");
4203 }
4204
4205 zone->refresh = RANGE(refresh,
4206 zone->minrefresh, zone->maxrefresh);
4207 zone->retry = RANGE(retry,
4208 zone->minretry, zone->maxretry);
4209 zone->expire = RANGE(expire, zone->refresh + zone->retry,
4210 DNS_MAX_EXPIRE);
4211 zone->minimum = minimum;
4212 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
4213
4214 if (zone->type == dns_zone_slave ||
4215 zone->type == dns_zone_stub ||
4216 (zone->type == dns_zone_redirect &&
4217 zone->masters != NULL)) {
4218 isc_time_t t;
4219 isc_uint32_t delay;
4220
4221 result = isc_file_getmodtime(zone->journal, &t);
4222 if (result != ISC_R_SUCCESS)
4223 result = isc_file_getmodtime(zone->masterfile,
4224 &t);
4225 if (result == ISC_R_SUCCESS)
4226 DNS_ZONE_TIME_ADD(&t, zone->expire,
4227 &zone->expiretime);
4228 else
4229 DNS_ZONE_TIME_ADD(&now, zone->retry,
4230 &zone->expiretime);
4231
4232 delay = isc_random_jitter(zone->retry,
4233 (zone->retry * 3) / 4);
4234 DNS_ZONE_TIME_ADD(&now, delay, &zone->refreshtime);
4235 if (isc_time_compare(&zone->refreshtime,
4236 &zone->expiretime) >= 0)
4237 zone->refreshtime = now;
4238 }
4239
4240 break;
4241
4242 case dns_zone_key:
4243 result = sync_keyzone(zone, db);
4244 if (result != ISC_R_SUCCESS)
4245 goto cleanup;
4246 break;
4247
4248 default:
4249 UNEXPECTED_ERROR(__FILE__, __LINE__,
4250 "unexpected zone type %d", zone->type);
4251 result = ISC_R_UNEXPECTED;
4252 goto cleanup;
4253 }
4254
4255 /*
4256 * Check for weak DNSKEY's.
4257 */
4258 if (zone->type == dns_zone_master)
4259 zone_check_dnskeys(zone, db);
4260
4261 /*
4262 * Schedule DNSSEC key refresh.
4263 */
4264 if (zone->type == dns_zone_master &&
4265 DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN))
4266 zone->refreshkeytime = now;
4267
4268 #if 0
4269 /* destroy notification example. */
4270 {
4271 isc_event_t *e = isc_event_allocate(zone->mctx, NULL,
4272 DNS_EVENT_DBDESTROYED,
4273 dns_zonemgr_dbdestroyed,
4274 zone,
4275 sizeof(isc_event_t));
4276 dns_db_ondestroy(db, zone->task, &e);
4277 }
4278 #endif
4279
4280 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
4281 if (zone->db != NULL) {
4282 result = zone_replacedb(zone, db, ISC_FALSE);
4283 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
4284 if (result != ISC_R_SUCCESS)
4285 goto cleanup;
4286 } else {
4287 zone_attachdb(zone, db);
4288 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
4289 DNS_ZONE_SETFLAG(zone,
4290 DNS_ZONEFLG_LOADED|
4291 DNS_ZONEFLG_NEEDSTARTUPNOTIFY);
4292 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SENDSECURE) &&
4293 inline_raw(zone))
4294 {
4295 if (zone->secure->db == NULL)
4296 zone_send_securedb(zone, db);
4297 else
4298 zone_send_secureserial(zone, serial);
4299 }
4300 }
4301
4302 /*
4303 * Finished loading inline-signing zone; need to get status
4304 * from the raw side now.
4305 */
4306 if (zone->type == dns_zone_master && inline_secure(zone))
4307 maybe_send_secure(zone);
4308
4309
4310 result = ISC_R_SUCCESS;
4311
4312 if (needdump) {
4313 if (zone->type == dns_zone_key)
4314 zone_needdump(zone, 30);
4315 else
4316 zone_needdump(zone, DNS_DUMP_DELAY);
4317 }
4318
4319 if (zone->task != NULL) {
4320 if (zone->type == dns_zone_master) {
4321 set_resigntime(zone);
4322 resume_signingwithkey(zone);
4323 resume_addnsec3chain(zone);
4324 }
4325
4326 if (zone->type == dns_zone_master &&
4327 !DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_NORESIGN) &&
4328 dns_zone_isdynamic(zone, ISC_FALSE) &&
4329 dns_db_issecure(db)) {
4330 dns_name_t *name;
4331 dns_fixedname_t fixed;
4332 dns_rdataset_t next;
4333
4334 dns_rdataset_init(&next);
4335 dns_fixedname_init(&fixed);
4336 name = dns_fixedname_name(&fixed);
4337
4338 result = dns_db_getsigningtime(db, &next, name);
4339 if (result == ISC_R_SUCCESS) {
4340 isc_stdtime_t timenow;
4341 char namebuf[DNS_NAME_FORMATSIZE];
4342 char typebuf[DNS_RDATATYPE_FORMATSIZE];
4343
4344 isc_stdtime_get(&timenow);
4345 dns_name_format(name, namebuf, sizeof(namebuf));
4346 dns_rdatatype_format(next.covers,
4347 typebuf, sizeof(typebuf));
4348 dns_zone_log(zone, ISC_LOG_DEBUG(3),
4349 "next resign: %s/%s in %d seconds",
4350 namebuf, typebuf,
4351 next.resign - timenow -
4352 zone->sigresigninginterval);
4353 dns_rdataset_disassociate(&next);
4354 } else
4355 dns_zone_log(zone, ISC_LOG_WARNING,
4356 "signed dynamic zone has no "
4357 "resign event scheduled");
4358 }
4359
4360 zone_settimer(zone, &now);
4361 }
4362
4363 if (! dns_db_ispersistent(db))
4364 dns_zone_log(zone, ISC_LOG_INFO, "loaded serial %u%s", serial,
4365 dns_db_issecure(db) ? " (DNSSEC signed)" : "");
4366
4367 zone->loadtime = loadtime;
4368 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADPENDING);
4369 return (result);
4370
4371 cleanup:
4372 if (zone->type == dns_zone_slave ||
4373 zone->type == dns_zone_stub ||
4374 zone->type == dns_zone_key ||
4375 (zone->type == dns_zone_redirect && zone->masters != NULL)) {
4376 if (result != ISC_R_NOMEMORY) {
4377 if (zone->journal != NULL)
4378 zone_saveunique(zone, zone->journal,
4379 "jn-XXXXXXXX");
4380 if (zone->masterfile != NULL)
4381 zone_saveunique(zone, zone->masterfile,
4382 "db-XXXXXXXX");
4383 }
4384
4385 /* Mark the zone for immediate refresh. */
4386 zone->refreshtime = now;
4387 if (zone->task != NULL)
4388 zone_settimer(zone, &now);
4389 result = ISC_R_SUCCESS;
4390 } else if (zone->type == dns_zone_master ||
4391 zone->type == dns_zone_redirect) {
4392 if (!(inline_secure(zone) && result == ISC_R_FILENOTFOUND))
4393 dns_zone_log(zone, ISC_LOG_ERROR,
4394 "not loaded due to errors.");
4395 else if (zone->type == dns_zone_master)
4396 result = ISC_R_SUCCESS;
4397 }
4398
4399 return (result);
4400 }
4401
4402 static isc_boolean_t
exit_check(dns_zone_t * zone)4403 exit_check(dns_zone_t *zone) {
4404 REQUIRE(LOCKED_ZONE(zone));
4405
4406 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SHUTDOWN) && zone->irefs == 0) {
4407 /*
4408 * DNS_ZONEFLG_SHUTDOWN can only be set if erefs == 0.
4409 */
4410 INSIST(isc_refcount_current(&zone->erefs) == 0);
4411 return (ISC_TRUE);
4412 }
4413 return (ISC_FALSE);
4414 }
4415
4416 static isc_boolean_t
zone_check_ns(dns_zone_t * zone,dns_db_t * db,dns_dbversion_t * version,dns_name_t * name,isc_boolean_t logit)4417 zone_check_ns(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
4418 dns_name_t *name, isc_boolean_t logit)
4419 {
4420 isc_result_t result;
4421 char namebuf[DNS_NAME_FORMATSIZE];
4422 char altbuf[DNS_NAME_FORMATSIZE];
4423 dns_fixedname_t fixed;
4424 dns_name_t *foundname;
4425 int level;
4426
4427 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOCHECKNS))
4428 return (ISC_TRUE);
4429
4430 if (zone->type == dns_zone_master)
4431 level = ISC_LOG_ERROR;
4432 else
4433 level = ISC_LOG_WARNING;
4434
4435 dns_fixedname_init(&fixed);
4436 foundname = dns_fixedname_name(&fixed);
4437
4438 result = dns_db_find(db, name, version, dns_rdatatype_a,
4439 0, 0, NULL, foundname, NULL, NULL);
4440 if (result == ISC_R_SUCCESS)
4441 return (ISC_TRUE);
4442
4443 if (result == DNS_R_NXRRSET) {
4444 result = dns_db_find(db, name, version, dns_rdatatype_aaaa,
4445 0, 0, NULL, foundname, NULL, NULL);
4446 if (result == ISC_R_SUCCESS)
4447 return (ISC_TRUE);
4448 }
4449
4450 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
4451 result == DNS_R_EMPTYNAME) {
4452 if (logit) {
4453 dns_name_format(name, namebuf, sizeof namebuf);
4454 dns_zone_log(zone, level, "NS '%s' has no address "
4455 "records (A or AAAA)", namebuf);
4456 }
4457 return (ISC_FALSE);
4458 }
4459
4460 if (result == DNS_R_CNAME) {
4461 if (logit) {
4462 dns_name_format(name, namebuf, sizeof namebuf);
4463 dns_zone_log(zone, level, "NS '%s' is a CNAME "
4464 "(illegal)", namebuf);
4465 }
4466 return (ISC_FALSE);
4467 }
4468
4469 if (result == DNS_R_DNAME) {
4470 if (logit) {
4471 dns_name_format(name, namebuf, sizeof namebuf);
4472 dns_name_format(foundname, altbuf, sizeof altbuf);
4473 dns_zone_log(zone, level, "NS '%s' is below a DNAME "
4474 "'%s' (illegal)", namebuf, altbuf);
4475 }
4476 return (ISC_FALSE);
4477 }
4478
4479 return (ISC_TRUE);
4480 }
4481
4482 static isc_result_t
zone_count_ns_rr(dns_zone_t * zone,dns_db_t * db,dns_dbnode_t * node,dns_dbversion_t * version,unsigned int * nscount,unsigned int * errors,isc_boolean_t logit)4483 zone_count_ns_rr(dns_zone_t *zone, dns_db_t *db, dns_dbnode_t *node,
4484 dns_dbversion_t *version, unsigned int *nscount,
4485 unsigned int *errors, isc_boolean_t logit)
4486 {
4487 isc_result_t result;
4488 unsigned int count = 0;
4489 unsigned int ecount = 0;
4490 dns_rdataset_t rdataset;
4491 dns_rdata_t rdata;
4492 dns_rdata_ns_t ns;
4493
4494 dns_rdataset_init(&rdataset);
4495 result = dns_db_findrdataset(db, node, version, dns_rdatatype_ns,
4496 dns_rdatatype_none, 0, &rdataset, NULL);
4497 if (result == ISC_R_NOTFOUND) {
4498 INSIST(!dns_rdataset_isassociated(&rdataset));
4499 goto success;
4500 }
4501 if (result != ISC_R_SUCCESS) {
4502 INSIST(!dns_rdataset_isassociated(&rdataset));
4503 goto invalidate_rdataset;
4504 }
4505
4506 result = dns_rdataset_first(&rdataset);
4507 while (result == ISC_R_SUCCESS) {
4508 if (errors != NULL && zone->rdclass == dns_rdataclass_in &&
4509 (zone->type == dns_zone_master ||
4510 zone->type == dns_zone_slave)) {
4511 dns_rdata_init(&rdata);
4512 dns_rdataset_current(&rdataset, &rdata);
4513 result = dns_rdata_tostruct(&rdata, &ns, NULL);
4514 RUNTIME_CHECK(result == ISC_R_SUCCESS);
4515 if (dns_name_issubdomain(&ns.name, &zone->origin) &&
4516 !zone_check_ns(zone, db, version, &ns.name, logit))
4517 ecount++;
4518 }
4519 count++;
4520 result = dns_rdataset_next(&rdataset);
4521 }
4522 dns_rdataset_disassociate(&rdataset);
4523
4524 success:
4525 if (nscount != NULL)
4526 *nscount = count;
4527 if (errors != NULL)
4528 *errors = ecount;
4529
4530 result = ISC_R_SUCCESS;
4531
4532 invalidate_rdataset:
4533 dns_rdataset_invalidate(&rdataset);
4534
4535 return (result);
4536 }
4537
4538 static isc_result_t
zone_load_soa_rr(dns_db_t * db,dns_dbnode_t * node,dns_dbversion_t * version,unsigned int * soacount,isc_uint32_t * serial,isc_uint32_t * refresh,isc_uint32_t * retry,isc_uint32_t * expire,isc_uint32_t * minimum)4539 zone_load_soa_rr(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
4540 unsigned int *soacount,
4541 isc_uint32_t *serial, isc_uint32_t *refresh,
4542 isc_uint32_t *retry, isc_uint32_t *expire,
4543 isc_uint32_t *minimum)
4544 {
4545 isc_result_t result;
4546 unsigned int count;
4547 dns_rdataset_t rdataset;
4548 dns_rdata_t rdata = DNS_RDATA_INIT;
4549 dns_rdata_soa_t soa;
4550
4551 dns_rdataset_init(&rdataset);
4552 result = dns_db_findrdataset(db, node, version, dns_rdatatype_soa,
4553 dns_rdatatype_none, 0, &rdataset, NULL);
4554 if (result == ISC_R_NOTFOUND) {
4555 INSIST(!dns_rdataset_isassociated(&rdataset));
4556 if (soacount != NULL)
4557 *soacount = 0;
4558 if (serial != NULL)
4559 *serial = 0;
4560 if (refresh != NULL)
4561 *refresh = 0;
4562 if (retry != NULL)
4563 *retry = 0;
4564 if (expire != NULL)
4565 *expire = 0;
4566 if (minimum != NULL)
4567 *minimum = 0;
4568 result = ISC_R_SUCCESS;
4569 goto invalidate_rdataset;
4570 }
4571 if (result != ISC_R_SUCCESS) {
4572 INSIST(!dns_rdataset_isassociated(&rdataset));
4573 goto invalidate_rdataset;
4574 }
4575
4576 count = 0;
4577 result = dns_rdataset_first(&rdataset);
4578 while (result == ISC_R_SUCCESS) {
4579 dns_rdata_init(&rdata);
4580 dns_rdataset_current(&rdataset, &rdata);
4581 count++;
4582 if (count == 1) {
4583 result = dns_rdata_tostruct(&rdata, &soa, NULL);
4584 RUNTIME_CHECK(result == ISC_R_SUCCESS);
4585 }
4586
4587 result = dns_rdataset_next(&rdataset);
4588 dns_rdata_reset(&rdata);
4589 }
4590 dns_rdataset_disassociate(&rdataset);
4591
4592 if (soacount != NULL)
4593 *soacount = count;
4594
4595 if (count > 0) {
4596 if (serial != NULL)
4597 *serial = soa.serial;
4598 if (refresh != NULL)
4599 *refresh = soa.refresh;
4600 if (retry != NULL)
4601 *retry = soa.retry;
4602 if (expire != NULL)
4603 *expire = soa.expire;
4604 if (minimum != NULL)
4605 *minimum = soa.minimum;
4606 } else {
4607 if (soacount != NULL)
4608 *soacount = 0;
4609 if (serial != NULL)
4610 *serial = 0;
4611 if (refresh != NULL)
4612 *refresh = 0;
4613 if (retry != NULL)
4614 *retry = 0;
4615 if (expire != NULL)
4616 *expire = 0;
4617 if (minimum != NULL)
4618 *minimum = 0;
4619 }
4620
4621 result = ISC_R_SUCCESS;
4622
4623 invalidate_rdataset:
4624 dns_rdataset_invalidate(&rdataset);
4625
4626 return (result);
4627 }
4628
4629 /*
4630 * zone must be locked.
4631 */
4632 static isc_result_t
zone_get_from_db(dns_zone_t * zone,dns_db_t * db,unsigned int * nscount,unsigned int * soacount,isc_uint32_t * serial,isc_uint32_t * refresh,isc_uint32_t * retry,isc_uint32_t * expire,isc_uint32_t * minimum,unsigned int * errors)4633 zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount,
4634 unsigned int *soacount, isc_uint32_t *serial,
4635 isc_uint32_t *refresh, isc_uint32_t *retry,
4636 isc_uint32_t *expire, isc_uint32_t *minimum,
4637 unsigned int *errors)
4638 {
4639 isc_result_t result;
4640 isc_result_t answer = ISC_R_SUCCESS;
4641 dns_dbversion_t *version = NULL;
4642 dns_dbnode_t *node;
4643
4644 REQUIRE(db != NULL);
4645 REQUIRE(zone != NULL);
4646
4647 dns_db_currentversion(db, &version);
4648
4649 if (nscount != NULL)
4650 *nscount = 0;
4651 if (soacount != NULL)
4652 *soacount = 0;
4653 if (serial != NULL)
4654 *serial = 0;
4655 if (refresh != NULL)
4656 *refresh = 0;
4657 if (retry != NULL)
4658 *retry = 0;
4659 if (expire != NULL)
4660 *expire = 0;
4661 if (errors != NULL)
4662 *errors = 0;
4663
4664 node = NULL;
4665 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node);
4666 if (result != ISC_R_SUCCESS) {
4667 answer = result;
4668 goto closeversion;
4669 }
4670
4671 if (nscount != NULL || errors != NULL) {
4672 result = zone_count_ns_rr(zone, db, node, version,
4673 nscount, errors, ISC_TRUE);
4674 if (result != ISC_R_SUCCESS)
4675 answer = result;
4676 }
4677
4678 if (soacount != NULL || serial != NULL || refresh != NULL
4679 || retry != NULL || expire != NULL || minimum != NULL) {
4680 result = zone_load_soa_rr(db, node, version, soacount,
4681 serial, refresh, retry, expire,
4682 minimum);
4683 if (result != ISC_R_SUCCESS)
4684 answer = result;
4685 }
4686
4687 dns_db_detachnode(db, &node);
4688 closeversion:
4689 dns_db_closeversion(db, &version, ISC_FALSE);
4690
4691 return (answer);
4692 }
4693
4694 void
dns_zone_attach(dns_zone_t * source,dns_zone_t ** target)4695 dns_zone_attach(dns_zone_t *source, dns_zone_t **target) {
4696 REQUIRE(DNS_ZONE_VALID(source));
4697 REQUIRE(target != NULL && *target == NULL);
4698 isc_refcount_increment(&source->erefs, NULL);
4699 *target = source;
4700 }
4701
4702 void
dns_zone_detach(dns_zone_t ** zonep)4703 dns_zone_detach(dns_zone_t **zonep) {
4704 dns_zone_t *zone;
4705 dns_zone_t *raw = NULL;
4706 dns_zone_t *secure = NULL;
4707 unsigned int refs;
4708 isc_boolean_t free_now = ISC_FALSE;
4709
4710 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
4711
4712 zone = *zonep;
4713
4714 isc_refcount_decrement(&zone->erefs, &refs);
4715
4716 if (refs == 0) {
4717 LOCK_ZONE(zone);
4718 /*
4719 * We just detached the last external reference.
4720 */
4721 if (zone->task != NULL) {
4722 /*
4723 * This zone is being managed. Post
4724 * its control event and let it clean
4725 * up synchronously in the context of
4726 * its task.
4727 */
4728 isc_event_t *ev = &zone->ctlevent;
4729 isc_task_send(zone->task, &ev);
4730 } else {
4731 /*
4732 * This zone is not being managed; it has
4733 * no task and can have no outstanding
4734 * events. Free it immediately.
4735 */
4736 /*
4737 * Unmanaged zones should not have non-null views;
4738 * we have no way of detaching from the view here
4739 * without causing deadlock because this code is called
4740 * with the view already locked.
4741 */
4742 INSIST(zone->view == NULL);
4743 free_now = ISC_TRUE;
4744 raw = zone->raw;
4745 zone->raw = NULL;
4746 secure = zone->secure;
4747 zone->secure = NULL;
4748 }
4749 UNLOCK_ZONE(zone);
4750 }
4751 *zonep = NULL;
4752 if (free_now) {
4753 if (raw != NULL)
4754 dns_zone_detach(&raw);
4755 if (secure != NULL)
4756 dns_zone_idetach(&secure);
4757 zone_free(zone);
4758 }
4759 }
4760
4761 void
dns_zone_iattach(dns_zone_t * source,dns_zone_t ** target)4762 dns_zone_iattach(dns_zone_t *source, dns_zone_t **target) {
4763 REQUIRE(DNS_ZONE_VALID(source));
4764 REQUIRE(target != NULL && *target == NULL);
4765 LOCK_ZONE(source);
4766 zone_iattach(source, target);
4767 UNLOCK_ZONE(source);
4768 }
4769
4770 static void
zone_iattach(dns_zone_t * source,dns_zone_t ** target)4771 zone_iattach(dns_zone_t *source, dns_zone_t **target) {
4772
4773 /*
4774 * 'source' locked by caller.
4775 */
4776 REQUIRE(LOCKED_ZONE(source));
4777 REQUIRE(DNS_ZONE_VALID(source));
4778 REQUIRE(target != NULL && *target == NULL);
4779 INSIST(source->irefs + isc_refcount_current(&source->erefs) > 0);
4780 source->irefs++;
4781 INSIST(source->irefs != 0);
4782 *target = source;
4783 }
4784
4785 static void
zone_idetach(dns_zone_t ** zonep)4786 zone_idetach(dns_zone_t **zonep) {
4787 dns_zone_t *zone;
4788
4789 /*
4790 * 'zone' locked by caller.
4791 */
4792 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
4793 zone = *zonep;
4794 REQUIRE(LOCKED_ZONE(*zonep));
4795 *zonep = NULL;
4796
4797 INSIST(zone->irefs > 0);
4798 zone->irefs--;
4799 INSIST(zone->irefs + isc_refcount_current(&zone->erefs) > 0);
4800 }
4801
4802 void
dns_zone_idetach(dns_zone_t ** zonep)4803 dns_zone_idetach(dns_zone_t **zonep) {
4804 dns_zone_t *zone;
4805 isc_boolean_t free_needed;
4806
4807 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
4808 zone = *zonep;
4809 *zonep = NULL;
4810
4811 LOCK_ZONE(zone);
4812 INSIST(zone->irefs > 0);
4813 zone->irefs--;
4814 free_needed = exit_check(zone);
4815 UNLOCK_ZONE(zone);
4816 if (free_needed)
4817 zone_free(zone);
4818 }
4819
4820 isc_mem_t *
dns_zone_getmctx(dns_zone_t * zone)4821 dns_zone_getmctx(dns_zone_t *zone) {
4822 REQUIRE(DNS_ZONE_VALID(zone));
4823
4824 return (zone->mctx);
4825 }
4826
4827 dns_zonemgr_t *
dns_zone_getmgr(dns_zone_t * zone)4828 dns_zone_getmgr(dns_zone_t *zone) {
4829 REQUIRE(DNS_ZONE_VALID(zone));
4830
4831 return (zone->zmgr);
4832 }
4833
4834 void
dns_zone_setflag(dns_zone_t * zone,unsigned int flags,isc_boolean_t value)4835 dns_zone_setflag(dns_zone_t *zone, unsigned int flags, isc_boolean_t value) {
4836 REQUIRE(DNS_ZONE_VALID(zone));
4837
4838 LOCK_ZONE(zone);
4839 if (value)
4840 DNS_ZONE_SETFLAG(zone, flags);
4841 else
4842 DNS_ZONE_CLRFLAG(zone, flags);
4843 UNLOCK_ZONE(zone);
4844 }
4845
4846 void
dns_zone_setoption(dns_zone_t * zone,unsigned int option,isc_boolean_t value)4847 dns_zone_setoption(dns_zone_t *zone, unsigned int option, isc_boolean_t value)
4848 {
4849 REQUIRE(DNS_ZONE_VALID(zone));
4850
4851 LOCK_ZONE(zone);
4852 if (value)
4853 zone->options |= option;
4854 else
4855 zone->options &= ~option;
4856 UNLOCK_ZONE(zone);
4857 }
4858
4859 unsigned int
dns_zone_getoptions(dns_zone_t * zone)4860 dns_zone_getoptions(dns_zone_t *zone) {
4861
4862 REQUIRE(DNS_ZONE_VALID(zone));
4863
4864 return (zone->options);
4865 }
4866
4867 void
dns_zone_setkeyopt(dns_zone_t * zone,unsigned int keyopt,isc_boolean_t value)4868 dns_zone_setkeyopt(dns_zone_t *zone, unsigned int keyopt, isc_boolean_t value)
4869 {
4870 REQUIRE(DNS_ZONE_VALID(zone));
4871
4872 LOCK_ZONE(zone);
4873 if (value)
4874 zone->keyopts |= keyopt;
4875 else
4876 zone->keyopts &= ~keyopt;
4877 UNLOCK_ZONE(zone);
4878 }
4879
4880 unsigned int
dns_zone_getkeyopts(dns_zone_t * zone)4881 dns_zone_getkeyopts(dns_zone_t *zone) {
4882
4883 REQUIRE(DNS_ZONE_VALID(zone));
4884
4885 return (zone->keyopts);
4886 }
4887
4888 isc_result_t
dns_zone_setxfrsource4(dns_zone_t * zone,const isc_sockaddr_t * xfrsource)4889 dns_zone_setxfrsource4(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) {
4890 REQUIRE(DNS_ZONE_VALID(zone));
4891
4892 LOCK_ZONE(zone);
4893 zone->xfrsource4 = *xfrsource;
4894 UNLOCK_ZONE(zone);
4895
4896 return (ISC_R_SUCCESS);
4897 }
4898
4899 isc_sockaddr_t *
dns_zone_getxfrsource4(dns_zone_t * zone)4900 dns_zone_getxfrsource4(dns_zone_t *zone) {
4901 REQUIRE(DNS_ZONE_VALID(zone));
4902 return (&zone->xfrsource4);
4903 }
4904
4905 isc_result_t
dns_zone_setxfrsource6(dns_zone_t * zone,const isc_sockaddr_t * xfrsource)4906 dns_zone_setxfrsource6(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) {
4907 REQUIRE(DNS_ZONE_VALID(zone));
4908
4909 LOCK_ZONE(zone);
4910 zone->xfrsource6 = *xfrsource;
4911 UNLOCK_ZONE(zone);
4912
4913 return (ISC_R_SUCCESS);
4914 }
4915
4916 isc_sockaddr_t *
dns_zone_getxfrsource6(dns_zone_t * zone)4917 dns_zone_getxfrsource6(dns_zone_t *zone) {
4918 REQUIRE(DNS_ZONE_VALID(zone));
4919 return (&zone->xfrsource6);
4920 }
4921
4922 isc_result_t
dns_zone_setaltxfrsource4(dns_zone_t * zone,const isc_sockaddr_t * altxfrsource)4923 dns_zone_setaltxfrsource4(dns_zone_t *zone,
4924 const isc_sockaddr_t *altxfrsource)
4925 {
4926 REQUIRE(DNS_ZONE_VALID(zone));
4927
4928 LOCK_ZONE(zone);
4929 zone->altxfrsource4 = *altxfrsource;
4930 UNLOCK_ZONE(zone);
4931
4932 return (ISC_R_SUCCESS);
4933 }
4934
4935 isc_sockaddr_t *
dns_zone_getaltxfrsource4(dns_zone_t * zone)4936 dns_zone_getaltxfrsource4(dns_zone_t *zone) {
4937 REQUIRE(DNS_ZONE_VALID(zone));
4938 return (&zone->altxfrsource4);
4939 }
4940
4941 isc_result_t
dns_zone_setaltxfrsource6(dns_zone_t * zone,const isc_sockaddr_t * altxfrsource)4942 dns_zone_setaltxfrsource6(dns_zone_t *zone,
4943 const isc_sockaddr_t *altxfrsource)
4944 {
4945 REQUIRE(DNS_ZONE_VALID(zone));
4946
4947 LOCK_ZONE(zone);
4948 zone->altxfrsource6 = *altxfrsource;
4949 UNLOCK_ZONE(zone);
4950
4951 return (ISC_R_SUCCESS);
4952 }
4953
4954 isc_sockaddr_t *
dns_zone_getaltxfrsource6(dns_zone_t * zone)4955 dns_zone_getaltxfrsource6(dns_zone_t *zone) {
4956 REQUIRE(DNS_ZONE_VALID(zone));
4957 return (&zone->altxfrsource6);
4958 }
4959
4960 isc_result_t
dns_zone_setnotifysrc4(dns_zone_t * zone,const isc_sockaddr_t * notifysrc)4961 dns_zone_setnotifysrc4(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) {
4962 REQUIRE(DNS_ZONE_VALID(zone));
4963
4964 LOCK_ZONE(zone);
4965 zone->notifysrc4 = *notifysrc;
4966 UNLOCK_ZONE(zone);
4967
4968 return (ISC_R_SUCCESS);
4969 }
4970
4971 isc_sockaddr_t *
dns_zone_getnotifysrc4(dns_zone_t * zone)4972 dns_zone_getnotifysrc4(dns_zone_t *zone) {
4973 REQUIRE(DNS_ZONE_VALID(zone));
4974 return (&zone->notifysrc4);
4975 }
4976
4977 isc_result_t
dns_zone_setnotifysrc6(dns_zone_t * zone,const isc_sockaddr_t * notifysrc)4978 dns_zone_setnotifysrc6(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) {
4979 REQUIRE(DNS_ZONE_VALID(zone));
4980
4981 LOCK_ZONE(zone);
4982 zone->notifysrc6 = *notifysrc;
4983 UNLOCK_ZONE(zone);
4984
4985 return (ISC_R_SUCCESS);
4986 }
4987
4988 isc_sockaddr_t *
dns_zone_getnotifysrc6(dns_zone_t * zone)4989 dns_zone_getnotifysrc6(dns_zone_t *zone) {
4990 REQUIRE(DNS_ZONE_VALID(zone));
4991 return (&zone->notifysrc6);
4992 }
4993
4994 static isc_boolean_t
same_addrs(const isc_sockaddr_t * old,const isc_sockaddr_t * new,isc_uint32_t count)4995 same_addrs(const isc_sockaddr_t *old, const isc_sockaddr_t *new,
4996 isc_uint32_t count)
4997 {
4998 unsigned int i;
4999
5000 for (i = 0; i < count; i++)
5001 if (!isc_sockaddr_equal(&old[i], &new[i]))
5002 return (ISC_FALSE);
5003 return (ISC_TRUE);
5004 }
5005
5006 static isc_boolean_t
same_keynames(dns_name_t ** old,dns_name_t ** new,isc_uint32_t count)5007 same_keynames(dns_name_t **old, dns_name_t **new, isc_uint32_t count) {
5008 unsigned int i;
5009
5010 if (old == NULL && new == NULL)
5011 return (ISC_TRUE);
5012 if (old == NULL || new == NULL)
5013 return (ISC_FALSE);
5014
5015 for (i = 0; i < count; i++) {
5016 if (old[i] == NULL && new[i] == NULL)
5017 continue;
5018 if (old[i] == NULL || new[i] == NULL ||
5019 !dns_name_equal(old[i], new[i]))
5020 return (ISC_FALSE);
5021 }
5022 return (ISC_TRUE);
5023 }
5024
5025 static void
clear_addresskeylist(isc_sockaddr_t ** addrsp,dns_name_t *** keynamesp,unsigned int * countp,isc_mem_t * mctx)5026 clear_addresskeylist(isc_sockaddr_t **addrsp, dns_name_t ***keynamesp,
5027 unsigned int *countp, isc_mem_t *mctx)
5028 {
5029 unsigned int count;
5030 isc_sockaddr_t *addrs;
5031 dns_name_t **keynames;
5032
5033 REQUIRE(countp != NULL && addrsp != NULL && keynamesp != NULL);
5034
5035 count = *countp;
5036 *countp = 0;
5037 addrs = *addrsp;
5038 *addrsp = NULL;
5039 keynames = *keynamesp;
5040 *keynamesp = NULL;
5041
5042 if (addrs != NULL)
5043 isc_mem_put(mctx, addrs, count * sizeof(isc_sockaddr_t));
5044
5045 if (keynames != NULL) {
5046 unsigned int i;
5047 for (i = 0; i < count; i++) {
5048 if (keynames[i] != NULL) {
5049 dns_name_free(keynames[i], mctx);
5050 isc_mem_put(mctx, keynames[i],
5051 sizeof(dns_name_t));
5052 keynames[i] = NULL;
5053 }
5054 }
5055 isc_mem_put(mctx, keynames, count * sizeof(dns_name_t *));
5056 }
5057 }
5058
5059 static isc_result_t
set_addrkeylist(unsigned int count,const isc_sockaddr_t * addrs,isc_sockaddr_t ** newaddrsp,dns_name_t ** names,dns_name_t *** newnamesp,isc_mem_t * mctx)5060 set_addrkeylist(unsigned int count,
5061 const isc_sockaddr_t *addrs, isc_sockaddr_t **newaddrsp,
5062 dns_name_t **names, dns_name_t ***newnamesp,
5063 isc_mem_t *mctx)
5064 {
5065 isc_result_t result;
5066 isc_sockaddr_t *newaddrs = NULL;
5067 dns_name_t **newnames = NULL;
5068 unsigned int i;
5069
5070 REQUIRE(newaddrsp != NULL && *newaddrsp == NULL);
5071 REQUIRE(newnamesp != NULL && *newnamesp == NULL);
5072
5073 newaddrs = isc_mem_get(mctx, count * sizeof(*newaddrs));
5074 if (newaddrs == NULL)
5075 return (ISC_R_NOMEMORY);
5076 memmove(newaddrs, addrs, count * sizeof(*newaddrs));
5077
5078 newnames = NULL;
5079 if (names != NULL) {
5080 newnames = isc_mem_get(mctx, count * sizeof(*newnames));
5081 if (newnames == NULL) {
5082 isc_mem_put(mctx, newaddrs, count * sizeof(*newaddrs));
5083 return (ISC_R_NOMEMORY);
5084 }
5085 for (i = 0; i < count; i++)
5086 newnames[i] = NULL;
5087 for (i = 0; i < count; i++) {
5088 if (names[i] != NULL) {
5089 newnames[i] = isc_mem_get(mctx,
5090 sizeof(dns_name_t));
5091 if (newnames[i] == NULL)
5092 goto allocfail;
5093 dns_name_init(newnames[i], NULL);
5094 result = dns_name_dup(names[i], mctx,
5095 newnames[i]);
5096 if (result != ISC_R_SUCCESS) {
5097 allocfail:
5098 for (i = 0; i < count; i++)
5099 if (newnames[i] != NULL)
5100 dns_name_free(
5101 newnames[i],
5102 mctx);
5103 isc_mem_put(mctx, newaddrs,
5104 count * sizeof(*newaddrs));
5105 isc_mem_put(mctx, newnames,
5106 count * sizeof(*newnames));
5107 return (ISC_R_NOMEMORY);
5108 }
5109 }
5110 }
5111 }
5112
5113 *newaddrsp = newaddrs;
5114 *newnamesp = newnames;
5115 return (ISC_R_SUCCESS);
5116 }
5117
5118 isc_result_t
dns_zone_setalsonotify(dns_zone_t * zone,const isc_sockaddr_t * notify,isc_uint32_t count)5119 dns_zone_setalsonotify(dns_zone_t *zone, const isc_sockaddr_t *notify,
5120 isc_uint32_t count)
5121 {
5122 return (dns_zone_setalsonotifywithkeys(zone, notify, NULL, count));
5123 }
5124
5125 isc_result_t
dns_zone_setalsonotifywithkeys(dns_zone_t * zone,const isc_sockaddr_t * notify,dns_name_t ** keynames,isc_uint32_t count)5126 dns_zone_setalsonotifywithkeys(dns_zone_t *zone, const isc_sockaddr_t *notify,
5127 dns_name_t **keynames, isc_uint32_t count)
5128 {
5129 isc_result_t result;
5130 isc_sockaddr_t *newaddrs = NULL;
5131 dns_name_t **newnames = NULL;
5132
5133 REQUIRE(DNS_ZONE_VALID(zone));
5134 REQUIRE(count == 0 || notify != NULL);
5135 if (keynames != NULL)
5136 REQUIRE(count != 0);
5137
5138 LOCK_ZONE(zone);
5139
5140 if (count == zone->notifycnt &&
5141 same_addrs(zone->notify, notify, count) &&
5142 same_keynames(zone->notifykeynames, keynames, count))
5143 goto unlock;
5144
5145 clear_addresskeylist(&zone->notify, &zone->notifykeynames,
5146 &zone->notifycnt, zone->mctx);
5147
5148 if (count == 0)
5149 goto unlock;
5150
5151 /*
5152 * Set up the notify and notifykey lists
5153 */
5154 result = set_addrkeylist(count, notify, &newaddrs,
5155 keynames, &newnames, zone->mctx);
5156 if (result != ISC_R_SUCCESS)
5157 goto unlock;
5158
5159 /*
5160 * Everything is ok so attach to the zone.
5161 */
5162 zone->notify = newaddrs;
5163 zone->notifykeynames = newnames;
5164 zone->notifycnt = count;
5165 unlock:
5166 UNLOCK_ZONE(zone);
5167 return (ISC_R_SUCCESS);
5168 }
5169
5170 isc_result_t
dns_zone_setmasters(dns_zone_t * zone,const isc_sockaddr_t * masters,isc_uint32_t count)5171 dns_zone_setmasters(dns_zone_t *zone, const isc_sockaddr_t *masters,
5172 isc_uint32_t count)
5173 {
5174 isc_result_t result;
5175
5176 result = dns_zone_setmasterswithkeys(zone, masters, NULL, count);
5177 return (result);
5178 }
5179
5180 isc_result_t
dns_zone_setmasterswithkeys(dns_zone_t * zone,const isc_sockaddr_t * masters,dns_name_t ** keynames,isc_uint32_t count)5181 dns_zone_setmasterswithkeys(dns_zone_t *zone,
5182 const isc_sockaddr_t *masters,
5183 dns_name_t **keynames,
5184 isc_uint32_t count)
5185 {
5186 isc_result_t result = ISC_R_SUCCESS;
5187 isc_sockaddr_t *newaddrs = NULL;
5188 dns_name_t **newnames = NULL;
5189 isc_boolean_t *newok;
5190 unsigned int i;
5191
5192 REQUIRE(DNS_ZONE_VALID(zone));
5193 REQUIRE(count == 0 || masters != NULL);
5194 if (keynames != NULL) {
5195 REQUIRE(count != 0);
5196 }
5197
5198 LOCK_ZONE(zone);
5199 /*
5200 * The refresh code assumes that 'masters' wouldn't change under it.
5201 * If it will change then kill off any current refresh in progress
5202 * and update the masters info. If it won't change then we can just
5203 * unlock and exit.
5204 */
5205 if (count != zone->masterscnt ||
5206 !same_addrs(zone->masters, masters, count) ||
5207 !same_keynames(zone->masterkeynames, keynames, count)) {
5208 if (zone->request != NULL)
5209 dns_request_cancel(zone->request);
5210 } else
5211 goto unlock;
5212
5213 /*
5214 * This needs to happen before clear_addresskeylist() sets
5215 * zone->masterscnt to 0:
5216 */
5217 if (zone->mastersok != NULL) {
5218 isc_mem_put(zone->mctx, zone->mastersok,
5219 zone->masterscnt * sizeof(isc_boolean_t));
5220 zone->mastersok = NULL;
5221 }
5222 clear_addresskeylist(&zone->masters, &zone->masterkeynames,
5223 &zone->masterscnt, zone->mctx);
5224 /*
5225 * If count == 0, don't allocate any space for masters, mastersok or
5226 * keynames so internally, those pointers are NULL if count == 0
5227 */
5228 if (count == 0)
5229 goto unlock;
5230
5231 /*
5232 * mastersok must contain count elements
5233 */
5234 newok = isc_mem_get(zone->mctx, count * sizeof(*newok));
5235 if (newok == NULL) {
5236 result = ISC_R_NOMEMORY;
5237 isc_mem_put(zone->mctx, newaddrs, count * sizeof(*newaddrs));
5238 goto unlock;
5239 };
5240 for (i = 0; i < count; i++)
5241 newok[i] = ISC_FALSE;
5242
5243 /*
5244 * Now set up the masters and masterkey lists
5245 */
5246 result = set_addrkeylist(count, masters, &newaddrs,
5247 keynames, &newnames, zone->mctx);
5248 if (result != ISC_R_SUCCESS) {
5249 isc_mem_put(zone->mctx, newok, count * sizeof(*newok));
5250 goto unlock;
5251 }
5252
5253 /*
5254 * Everything is ok so attach to the zone.
5255 */
5256 zone->curmaster = 0;
5257 zone->mastersok = newok;
5258 zone->masters = newaddrs;
5259 zone->masterkeynames = newnames;
5260 zone->masterscnt = count;
5261 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOMASTERS);
5262
5263 unlock:
5264 UNLOCK_ZONE(zone);
5265 return (result);
5266 }
5267
5268 isc_result_t
dns_zone_getdb(dns_zone_t * zone,dns_db_t ** dpb)5269 dns_zone_getdb(dns_zone_t *zone, dns_db_t **dpb) {
5270 isc_result_t result = ISC_R_SUCCESS;
5271
5272 REQUIRE(DNS_ZONE_VALID(zone));
5273
5274 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
5275 if (zone->db == NULL)
5276 result = DNS_R_NOTLOADED;
5277 else
5278 dns_db_attach(zone->db, dpb);
5279 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
5280
5281 return (result);
5282 }
5283
5284 void
dns_zone_setdb(dns_zone_t * zone,dns_db_t * db)5285 dns_zone_setdb(dns_zone_t *zone, dns_db_t *db) {
5286 REQUIRE(DNS_ZONE_VALID(zone));
5287 REQUIRE(zone->type == dns_zone_staticstub);
5288
5289 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
5290 REQUIRE(zone->db == NULL);
5291 dns_db_attach(db, &zone->db);
5292 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
5293 }
5294
5295 /*
5296 * Co-ordinates the starting of routine jobs.
5297 */
5298
5299 void
dns_zone_maintenance(dns_zone_t * zone)5300 dns_zone_maintenance(dns_zone_t *zone) {
5301 const char me[] = "dns_zone_maintenance";
5302 isc_time_t now;
5303
5304 REQUIRE(DNS_ZONE_VALID(zone));
5305 ENTER;
5306
5307 LOCK_ZONE(zone);
5308 TIME_NOW(&now);
5309 zone_settimer(zone, &now);
5310 UNLOCK_ZONE(zone);
5311 }
5312
5313 static inline isc_boolean_t
was_dumping(dns_zone_t * zone)5314 was_dumping(dns_zone_t *zone) {
5315 isc_boolean_t dumping;
5316
5317 REQUIRE(LOCKED_ZONE(zone));
5318
5319 dumping = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING);
5320 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
5321 if (!dumping) {
5322 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
5323 isc_time_settoepoch(&zone->dumptime);
5324 }
5325 return (dumping);
5326 }
5327
5328 static isc_result_t
find_zone_keys(dns_zone_t * zone,dns_db_t * db,dns_dbversion_t * ver,isc_mem_t * mctx,unsigned int maxkeys,dst_key_t ** keys,unsigned int * nkeys)5329 find_zone_keys(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
5330 isc_mem_t *mctx, unsigned int maxkeys,
5331 dst_key_t **keys, unsigned int *nkeys)
5332 {
5333 isc_result_t result;
5334 dns_dbnode_t *node = NULL;
5335 const char *directory = dns_zone_getkeydirectory(zone);
5336
5337 CHECK(dns_db_findnode(db, dns_db_origin(db), ISC_FALSE, &node));
5338 memset(keys, 0, sizeof(*keys) * maxkeys);
5339 result = dns_dnssec_findzonekeys2(db, ver, node, dns_db_origin(db),
5340 directory, mctx, maxkeys, keys,
5341 nkeys);
5342 if (result == ISC_R_NOTFOUND)
5343 result = ISC_R_SUCCESS;
5344 failure:
5345 if (node != NULL)
5346 dns_db_detachnode(db, &node);
5347 return (result);
5348 }
5349
5350 static isc_result_t
offline(dns_db_t * db,dns_dbversion_t * ver,zonediff_t * zonediff,dns_name_t * name,dns_ttl_t ttl,dns_rdata_t * rdata)5351 offline(dns_db_t *db, dns_dbversion_t *ver, zonediff_t *zonediff,
5352 dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata)
5353 {
5354 isc_result_t result;
5355
5356 if ((rdata->flags & DNS_RDATA_OFFLINE) != 0)
5357 return (ISC_R_SUCCESS);
5358 result = update_one_rr(db, ver, zonediff->diff, DNS_DIFFOP_DELRESIGN,
5359 name, ttl, rdata);
5360 if (result != ISC_R_SUCCESS)
5361 return (result);
5362 rdata->flags |= DNS_RDATA_OFFLINE;
5363 result = update_one_rr(db, ver, zonediff->diff, DNS_DIFFOP_ADDRESIGN,
5364 name, ttl, rdata);
5365 zonediff->offline = ISC_TRUE;
5366 return (result);
5367 }
5368
5369 static void
set_key_expiry_warning(dns_zone_t * zone,isc_stdtime_t when,isc_stdtime_t now)5370 set_key_expiry_warning(dns_zone_t *zone, isc_stdtime_t when, isc_stdtime_t now)
5371 {
5372 unsigned int delta;
5373 char timebuf[80];
5374
5375 zone->key_expiry = when;
5376 if (when <= now) {
5377 dns_zone_log(zone, ISC_LOG_ERROR,
5378 "DNSKEY RRSIG(s) have expired");
5379 isc_time_settoepoch(&zone->keywarntime);
5380 } else if (when < now + 7 * 24 * 3600) {
5381 isc_time_t t;
5382 isc_time_set(&t, when, 0);
5383 isc_time_formattimestamp(&t, timebuf, 80);
5384 dns_zone_log(zone, ISC_LOG_WARNING,
5385 "DNSKEY RRSIG(s) will expire within 7 days: %s",
5386 timebuf);
5387 delta = when - now;
5388 delta--; /* loop prevention */
5389 delta /= 24 * 3600; /* to whole days */
5390 delta *= 24 * 3600; /* to seconds */
5391 isc_time_set(&zone->keywarntime, when - delta, 0);
5392 } else {
5393 isc_time_set(&zone->keywarntime, when - 7 * 24 * 3600, 0);
5394 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
5395 dns_zone_log(zone, ISC_LOG_NOTICE,
5396 "setting keywarntime to %s", timebuf);
5397 }
5398 }
5399
5400 /*
5401 * Helper function to del_sigs(). We don't want to delete RRSIGs that
5402 * have no new key.
5403 */
5404 static isc_boolean_t
delsig_ok(dns_rdata_rrsig_t * rrsig_ptr,dst_key_t ** keys,unsigned int nkeys,isc_boolean_t * warn)5405 delsig_ok(dns_rdata_rrsig_t *rrsig_ptr, dst_key_t **keys, unsigned int nkeys,
5406 isc_boolean_t *warn)
5407 {
5408 unsigned int i = 0;
5409 isc_boolean_t have_ksk = ISC_FALSE, have_zsk = ISC_FALSE;
5410 isc_boolean_t have_pksk = ISC_FALSE, have_pzsk = ISC_FALSE;
5411
5412 for (i = 0; i < nkeys; i++) {
5413 if (rrsig_ptr->algorithm != dst_key_alg(keys[i]))
5414 continue;
5415 if (dst_key_isprivate(keys[i])) {
5416 if (KSK(keys[i]))
5417 have_ksk = have_pksk = ISC_TRUE;
5418 else
5419 have_zsk = have_pzsk = ISC_TRUE;
5420 } else {
5421 if (KSK(keys[i]))
5422 have_ksk = ISC_TRUE;
5423 else
5424 have_zsk = ISC_TRUE;
5425 }
5426 }
5427
5428 if (have_zsk && have_ksk && !have_pzsk)
5429 *warn = ISC_TRUE;
5430
5431 /*
5432 * It's okay to delete a signature if there is an active key
5433 * with the same algorithm to replace it.
5434 */
5435 if (have_pksk || have_pzsk)
5436 return (ISC_TRUE);
5437
5438 /*
5439 * Failing that, it is *not* okay to delete a signature
5440 * if the associated public key is still in the DNSKEY RRset
5441 */
5442 for (i = 0; i < nkeys; i++) {
5443 if ((rrsig_ptr->algorithm == dst_key_alg(keys[i])) &&
5444 (rrsig_ptr->keyid == dst_key_id(keys[i])))
5445 return (ISC_FALSE);
5446 }
5447
5448 /*
5449 * But if the key is gone, then go ahead.
5450 */
5451 return (ISC_TRUE);
5452 }
5453
5454 /*
5455 * Delete expired RRsigs and any RRsigs we are about to re-sign.
5456 * See also update.c:del_keysigs().
5457 */
5458 static isc_result_t
del_sigs(dns_zone_t * zone,dns_db_t * db,dns_dbversion_t * ver,dns_name_t * name,dns_rdatatype_t type,zonediff_t * zonediff,dst_key_t ** keys,unsigned int nkeys,isc_stdtime_t now,isc_boolean_t incremental)5459 del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
5460 dns_rdatatype_t type, zonediff_t *zonediff, dst_key_t **keys,
5461 unsigned int nkeys, isc_stdtime_t now, isc_boolean_t incremental)
5462 {
5463 isc_result_t result;
5464 dns_dbnode_t *node = NULL;
5465 dns_rdataset_t rdataset;
5466 unsigned int i;
5467 dns_rdata_rrsig_t rrsig;
5468 isc_boolean_t found;
5469 isc_int64_t timewarn = 0, timemaybe = 0;
5470
5471 dns_rdataset_init(&rdataset);
5472
5473 if (type == dns_rdatatype_nsec3)
5474 result = dns_db_findnsec3node(db, name, ISC_FALSE, &node);
5475 else
5476 result = dns_db_findnode(db, name, ISC_FALSE, &node);
5477 if (result == ISC_R_NOTFOUND)
5478 return (ISC_R_SUCCESS);
5479 if (result != ISC_R_SUCCESS)
5480 goto failure;
5481 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_rrsig, type,
5482 (isc_stdtime_t) 0, &rdataset, NULL);
5483 dns_db_detachnode(db, &node);
5484
5485 if (result == ISC_R_NOTFOUND) {
5486 INSIST(!dns_rdataset_isassociated(&rdataset));
5487 return (ISC_R_SUCCESS);
5488 }
5489 if (result != ISC_R_SUCCESS) {
5490 INSIST(!dns_rdataset_isassociated(&rdataset));
5491 goto failure;
5492 }
5493
5494 for (result = dns_rdataset_first(&rdataset);
5495 result == ISC_R_SUCCESS;
5496 result = dns_rdataset_next(&rdataset)) {
5497 dns_rdata_t rdata = DNS_RDATA_INIT;
5498
5499 dns_rdataset_current(&rdataset, &rdata);
5500 result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
5501 RUNTIME_CHECK(result == ISC_R_SUCCESS);
5502
5503 if (type != dns_rdatatype_dnskey) {
5504 isc_boolean_t warn = ISC_FALSE, deleted = ISC_FALSE;
5505 if (delsig_ok(&rrsig, keys, nkeys, &warn)) {
5506 result = update_one_rr(db, ver, zonediff->diff,
5507 DNS_DIFFOP_DELRESIGN, name,
5508 rdataset.ttl, &rdata);
5509 if (result != ISC_R_SUCCESS)
5510 break;
5511 deleted = ISC_TRUE;
5512 }
5513 if (warn) {
5514 /*
5515 * At this point, we've got an RRSIG,
5516 * which is signed by an inactive key.
5517 * An administrator needs to provide a new
5518 * key/alg, but until that time, we want to
5519 * keep the old RRSIG. Marking the key as
5520 * offline will prevent us spinning waiting
5521 * for the private part.
5522 */
5523 if (incremental && !deleted) {
5524 result = offline(db, ver, zonediff,
5525 name, rdataset.ttl,
5526 &rdata);
5527 if (result != ISC_R_SUCCESS)
5528 break;
5529 }
5530
5531 /*
5532 * Log the key id and algorithm of
5533 * the inactive key with no replacement
5534 */
5535 if (zone->log_key_expired_timer <= now) {
5536 char origin[DNS_NAME_FORMATSIZE];
5537 char algbuf[DNS_NAME_FORMATSIZE];
5538 dns_name_format(&zone->origin, origin,
5539 sizeof(origin));
5540 dns_secalg_format(rrsig.algorithm,
5541 algbuf,
5542 sizeof(algbuf));
5543 dns_zone_log(zone, ISC_LOG_WARNING,
5544 "Key %s/%s/%d "
5545 "missing or inactive "
5546 "and has no replacement: "
5547 "retaining signatures.",
5548 origin, algbuf,
5549 rrsig.keyid);
5550 zone->log_key_expired_timer = now +
5551 3600;
5552 }
5553 }
5554 continue;
5555 }
5556
5557 /*
5558 * RRSIG(DNSKEY) requires special processing.
5559 */
5560 found = ISC_FALSE;
5561 for (i = 0; i < nkeys; i++) {
5562 if (rrsig.algorithm == dst_key_alg(keys[i]) &&
5563 rrsig.keyid == dst_key_id(keys[i])) {
5564 found = ISC_TRUE;
5565 /*
5566 * Mark offline RRSIG(DNSKEY).
5567 * We want the earliest offline expire time
5568 * iff there is a new offline signature.
5569 */
5570 if (!dst_key_inactive(keys[i]) &&
5571 !dst_key_isprivate(keys[i]))
5572 {
5573 isc_int64_t timeexpire =
5574 dns_time64_from32(rrsig.timeexpire);
5575 if (timewarn != 0 &&
5576 timewarn > timeexpire)
5577 timewarn = timeexpire;
5578 if (rdata.flags & DNS_RDATA_OFFLINE) {
5579 if (timemaybe == 0 ||
5580 timemaybe > timeexpire)
5581 timemaybe = timeexpire;
5582 break;
5583 }
5584 if (timewarn == 0)
5585 timewarn = timemaybe;
5586 if (timewarn == 0 ||
5587 timewarn > timeexpire)
5588 timewarn = timeexpire;
5589 result = offline(db, ver, zonediff,
5590 name, rdataset.ttl,
5591 &rdata);
5592 break;
5593 }
5594 result = update_one_rr(db, ver, zonediff->diff,
5595 DNS_DIFFOP_DELRESIGN,
5596 name, rdataset.ttl,
5597 &rdata);
5598 break;
5599 }
5600 }
5601
5602 /*
5603 * If there is not a matching DNSKEY then
5604 * delete the RRSIG.
5605 */
5606 if (!found)
5607 result = update_one_rr(db, ver, zonediff->diff,
5608 DNS_DIFFOP_DELRESIGN, name,
5609 rdataset.ttl, &rdata);
5610 if (result != ISC_R_SUCCESS)
5611 break;
5612 }
5613
5614 dns_rdataset_disassociate(&rdataset);
5615 if (result == ISC_R_NOMORE)
5616 result = ISC_R_SUCCESS;
5617 if (timewarn > 0) {
5618 #if defined(STDTIME_ON_32BITS)
5619 isc_stdtime_t stdwarn = (isc_stdtime_t)timewarn;
5620 if (timewarn == stdwarn)
5621 #endif
5622 set_key_expiry_warning(zone, (isc_stdtime_t)timewarn,
5623 now);
5624 #if defined(STDTIME_ON_32BITS)
5625 else
5626 dns_zone_log(zone, ISC_LOG_ERROR,
5627 "key expiry warning time out of range");
5628 #endif
5629 }
5630 failure:
5631 if (node != NULL)
5632 dns_db_detachnode(db, &node);
5633 return (result);
5634 }
5635
5636 static isc_result_t
add_sigs(dns_db_t * db,dns_dbversion_t * ver,dns_name_t * name,dns_rdatatype_t type,dns_diff_t * diff,dst_key_t ** keys,unsigned int nkeys,isc_mem_t * mctx,isc_stdtime_t inception,isc_stdtime_t expire,isc_boolean_t check_ksk,isc_boolean_t keyset_kskonly)5637 add_sigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
5638 dns_rdatatype_t type, dns_diff_t *diff, dst_key_t **keys,
5639 unsigned int nkeys, isc_mem_t *mctx, isc_stdtime_t inception,
5640 isc_stdtime_t expire, isc_boolean_t check_ksk,
5641 isc_boolean_t keyset_kskonly)
5642 {
5643 isc_result_t result;
5644 dns_dbnode_t *node = NULL;
5645 dns_rdataset_t rdataset;
5646 dns_rdata_t sig_rdata = DNS_RDATA_INIT;
5647 unsigned char data[1024]; /* XXX */
5648 isc_buffer_t buffer;
5649 unsigned int i, j;
5650
5651 dns_rdataset_init(&rdataset);
5652 isc_buffer_init(&buffer, data, sizeof(data));
5653
5654 if (type == dns_rdatatype_nsec3)
5655 result = dns_db_findnsec3node(db, name, ISC_FALSE, &node);
5656 else
5657 result = dns_db_findnode(db, name, ISC_FALSE, &node);
5658 if (result == ISC_R_NOTFOUND)
5659 return (ISC_R_SUCCESS);
5660 if (result != ISC_R_SUCCESS)
5661 goto failure;
5662 result = dns_db_findrdataset(db, node, ver, type, 0,
5663 (isc_stdtime_t) 0, &rdataset, NULL);
5664 dns_db_detachnode(db, &node);
5665 if (result == ISC_R_NOTFOUND) {
5666 INSIST(!dns_rdataset_isassociated(&rdataset));
5667 return (ISC_R_SUCCESS);
5668 }
5669 if (result != ISC_R_SUCCESS) {
5670 INSIST(!dns_rdataset_isassociated(&rdataset));
5671 goto failure;
5672 }
5673
5674 for (i = 0; i < nkeys; i++) {
5675 isc_boolean_t both = ISC_FALSE;
5676
5677 if (!dst_key_isprivate(keys[i]))
5678 continue;
5679
5680 if (check_ksk && !REVOKE(keys[i])) {
5681 isc_boolean_t have_ksk, have_nonksk;
5682 if (KSK(keys[i])) {
5683 have_ksk = ISC_TRUE;
5684 have_nonksk = ISC_FALSE;
5685 } else {
5686 have_ksk = ISC_FALSE;
5687 have_nonksk = ISC_TRUE;
5688 }
5689 for (j = 0; j < nkeys; j++) {
5690 if (j == i || ALG(keys[i]) != ALG(keys[j]))
5691 continue;
5692 if (REVOKE(keys[j]))
5693 continue;
5694 if (KSK(keys[j]))
5695 have_ksk = ISC_TRUE;
5696 else
5697 have_nonksk = ISC_TRUE;
5698 both = have_ksk && have_nonksk;
5699 if (both)
5700 break;
5701 }
5702 }
5703 if (both) {
5704 if (type == dns_rdatatype_dnskey) {
5705 if (!KSK(keys[i]) && keyset_kskonly)
5706 continue;
5707 } else if (KSK(keys[i]))
5708 continue;
5709 } else if (REVOKE(keys[i]) && type != dns_rdatatype_dnskey)
5710 continue;
5711
5712 /* Calculate the signature, creating a RRSIG RDATA. */
5713 isc_buffer_clear(&buffer);
5714 CHECK(dns_dnssec_sign(name, &rdataset, keys[i],
5715 &inception, &expire,
5716 mctx, &buffer, &sig_rdata));
5717 /* Update the database and journal with the RRSIG. */
5718 /* XXX inefficient - will cause dataset merging */
5719 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADDRESIGN,
5720 name, rdataset.ttl, &sig_rdata));
5721 dns_rdata_reset(&sig_rdata);
5722 isc_buffer_init(&buffer, data, sizeof(data));
5723 }
5724
5725 failure:
5726 if (dns_rdataset_isassociated(&rdataset))
5727 dns_rdataset_disassociate(&rdataset);
5728 if (node != NULL)
5729 dns_db_detachnode(db, &node);
5730 return (result);
5731 }
5732
5733 static void
zone_resigninc(dns_zone_t * zone)5734 zone_resigninc(dns_zone_t *zone) {
5735 const char *me = "zone_resigninc";
5736 dns_db_t *db = NULL;
5737 dns_dbversion_t *version = NULL;
5738 dns_diff_t _sig_diff;
5739 zonediff_t zonediff;
5740 dns_fixedname_t fixed;
5741 dns_name_t *name;
5742 dns_rdataset_t rdataset;
5743 dns_rdatatype_t covers;
5744 dst_key_t *zone_keys[DNS_MAXZONEKEYS];
5745 isc_boolean_t check_ksk, keyset_kskonly = ISC_FALSE;
5746 isc_result_t result;
5747 isc_stdtime_t now, inception, soaexpire, expire, stop;
5748 isc_uint32_t jitter;
5749 unsigned int i;
5750 unsigned int nkeys = 0;
5751 unsigned int resign;
5752
5753 ENTER;
5754
5755 dns_rdataset_init(&rdataset);
5756 dns_fixedname_init(&fixed);
5757 dns_diff_init(zone->mctx, &_sig_diff);
5758 zonediff_init(&zonediff, &_sig_diff);
5759
5760 /*
5761 * Zone is frozen or automatic resigning is disabled.
5762 * Pause for 5 minutes.
5763 */
5764 if (zone->update_disabled ||
5765 DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_NORESIGN))
5766 {
5767 result = ISC_R_FAILURE;
5768 goto failure;
5769 }
5770
5771 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
5772 dns_db_attach(zone->db, &db);
5773 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
5774
5775 result = dns_db_newversion(db, &version);
5776 if (result != ISC_R_SUCCESS) {
5777 dns_zone_log(zone, ISC_LOG_ERROR,
5778 "zone_resigninc:dns_db_newversion -> %s",
5779 dns_result_totext(result));
5780 goto failure;
5781 }
5782
5783 result = find_zone_keys(zone, db, version, zone->mctx, DNS_MAXZONEKEYS,
5784 zone_keys, &nkeys);
5785 if (result != ISC_R_SUCCESS) {
5786 dns_zone_log(zone, ISC_LOG_ERROR,
5787 "zone_resigninc:find_zone_keys -> %s",
5788 dns_result_totext(result));
5789 goto failure;
5790 }
5791
5792 isc_stdtime_get(&now);
5793 inception = now - 3600; /* Allow for clock skew. */
5794 soaexpire = now + dns_zone_getsigvalidityinterval(zone);
5795 /*
5796 * Spread out signatures over time if they happen to be
5797 * clumped. We don't do this for each add_sigs() call as
5798 * we still want some clustering to occur.
5799 */
5800 isc_random_get(&jitter);
5801 expire = soaexpire - jitter % 3600;
5802 stop = now + 5;
5803
5804 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
5805 keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
5806
5807 name = dns_fixedname_name(&fixed);
5808 result = dns_db_getsigningtime(db, &rdataset, name);
5809 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
5810 dns_zone_log(zone, ISC_LOG_ERROR,
5811 "zone_resigninc:dns_db_getsigningtime -> %s",
5812 dns_result_totext(result));
5813 }
5814
5815 i = 0;
5816 while (result == ISC_R_SUCCESS) {
5817 resign = rdataset.resign - zone->sigresigninginterval;
5818 covers = rdataset.covers;
5819 dns_rdataset_disassociate(&rdataset);
5820
5821 /*
5822 * Stop if we hit the SOA as that means we have walked the
5823 * entire zone. The SOA record should always be the most
5824 * recent signature.
5825 */
5826 /* XXXMPA increase number of RRsets signed pre call */
5827 if (covers == dns_rdatatype_soa || i++ > zone->signatures ||
5828 resign > stop)
5829 break;
5830
5831 result = del_sigs(zone, db, version, name, covers, &zonediff,
5832 zone_keys, nkeys, now, ISC_TRUE);
5833 if (result != ISC_R_SUCCESS) {
5834 dns_zone_log(zone, ISC_LOG_ERROR,
5835 "zone_resigninc:del_sigs -> %s",
5836 dns_result_totext(result));
5837 break;
5838 }
5839
5840 result = add_sigs(db, version, name, covers, zonediff.diff,
5841 zone_keys, nkeys, zone->mctx, inception,
5842 expire, check_ksk, keyset_kskonly);
5843 if (result != ISC_R_SUCCESS) {
5844 dns_zone_log(zone, ISC_LOG_ERROR,
5845 "zone_resigninc:add_sigs -> %s",
5846 dns_result_totext(result));
5847 break;
5848 }
5849 result = dns_db_getsigningtime(db, &rdataset, name);
5850 if (nkeys == 0 && result == ISC_R_NOTFOUND) {
5851 result = ISC_R_SUCCESS;
5852 break;
5853 }
5854 if (result != ISC_R_SUCCESS)
5855 dns_zone_log(zone, ISC_LOG_ERROR,
5856 "zone_resigninc:dns_db_getsigningtime -> %s",
5857 dns_result_totext(result));
5858 }
5859
5860 if (result != ISC_R_NOMORE && result != ISC_R_SUCCESS)
5861 goto failure;
5862
5863 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
5864 &zonediff, zone_keys, nkeys, now, ISC_TRUE);
5865 if (result != ISC_R_SUCCESS) {
5866 dns_zone_log(zone, ISC_LOG_ERROR,
5867 "zone_resigninc:del_sigs -> %s",
5868 dns_result_totext(result));
5869 goto failure;
5870 }
5871
5872 /*
5873 * Did we change anything in the zone?
5874 */
5875 if (ISC_LIST_EMPTY(zonediff.diff->tuples)) {
5876 /*
5877 * Commit the changes if any key has been marked as offline. */
5878 if (zonediff.offline)
5879 dns_db_closeversion(db, &version, ISC_TRUE);
5880 goto failure;
5881 }
5882
5883 /* Increment SOA serial if we have made changes */
5884 result = update_soa_serial(db, version, zonediff.diff, zone->mctx,
5885 zone->updatemethod);
5886 if (result != ISC_R_SUCCESS) {
5887 dns_zone_log(zone, ISC_LOG_ERROR,
5888 "zone_resigninc:update_soa_serial -> %s",
5889 dns_result_totext(result));
5890 goto failure;
5891 }
5892
5893 /*
5894 * Generate maximum life time signatures so that the above loop
5895 * termination is sensible.
5896 */
5897 result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa,
5898 zonediff.diff, zone_keys, nkeys, zone->mctx,
5899 inception, soaexpire, check_ksk, keyset_kskonly);
5900 if (result != ISC_R_SUCCESS) {
5901 dns_zone_log(zone, ISC_LOG_ERROR,
5902 "zone_resigninc:add_sigs -> %s",
5903 dns_result_totext(result));
5904 goto failure;
5905 }
5906
5907 /* Write changes to journal file. */
5908 CHECK(zone_journal(zone, zonediff.diff, NULL, "zone_resigninc"));
5909
5910 /* Everything has succeeded. Commit the changes. */
5911 dns_db_closeversion(db, &version, ISC_TRUE);
5912
5913 failure:
5914 dns_diff_clear(&_sig_diff);
5915 for (i = 0; i < nkeys; i++)
5916 dst_key_free(&zone_keys[i]);
5917 if (version != NULL) {
5918 dns_db_closeversion(zone->db, &version, ISC_FALSE);
5919 dns_db_detach(&db);
5920 } else if (db != NULL)
5921 dns_db_detach(&db);
5922 if (result == ISC_R_SUCCESS) {
5923 set_resigntime(zone);
5924 LOCK_ZONE(zone);
5925 zone_needdump(zone, DNS_DUMP_DELAY);
5926 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
5927 UNLOCK_ZONE(zone);
5928 } else {
5929 /*
5930 * Something failed. Retry in 5 minutes.
5931 */
5932 isc_interval_t ival;
5933 isc_interval_set(&ival, 300, 0);
5934 isc_time_nowplusinterval(&zone->resigntime, &ival);
5935 }
5936
5937 INSIST(version == NULL);
5938 }
5939
5940 static isc_result_t
next_active(dns_db_t * db,dns_dbversion_t * version,dns_name_t * oldname,dns_name_t * newname,isc_boolean_t bottom)5941 next_active(dns_db_t *db, dns_dbversion_t *version, dns_name_t *oldname,
5942 dns_name_t *newname, isc_boolean_t bottom)
5943 {
5944 isc_result_t result;
5945 dns_dbiterator_t *dbit = NULL;
5946 dns_rdatasetiter_t *rdsit = NULL;
5947 dns_dbnode_t *node = NULL;
5948
5949 CHECK(dns_db_createiterator(db, DNS_DB_NONSEC3, &dbit));
5950 CHECK(dns_dbiterator_seek(dbit, oldname));
5951 do {
5952 result = dns_dbiterator_next(dbit);
5953 if (result == ISC_R_NOMORE)
5954 CHECK(dns_dbiterator_first(dbit));
5955 CHECK(dns_dbiterator_current(dbit, &node, newname));
5956 if (bottom && dns_name_issubdomain(newname, oldname) &&
5957 !dns_name_equal(newname, oldname)) {
5958 dns_db_detachnode(db, &node);
5959 continue;
5960 }
5961 /*
5962 * Is this node empty?
5963 */
5964 CHECK(dns_db_allrdatasets(db, node, version, 0, &rdsit));
5965 result = dns_rdatasetiter_first(rdsit);
5966 dns_db_detachnode(db, &node);
5967 dns_rdatasetiter_destroy(&rdsit);
5968 if (result != ISC_R_NOMORE)
5969 break;
5970 } while (1);
5971 failure:
5972 if (node != NULL)
5973 dns_db_detachnode(db, &node);
5974 if (dbit != NULL)
5975 dns_dbiterator_destroy(&dbit);
5976 return (result);
5977 }
5978
5979 static isc_boolean_t
signed_with_key(dns_db_t * db,dns_dbnode_t * node,dns_dbversion_t * version,dns_rdatatype_t type,dst_key_t * key)5980 signed_with_key(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
5981 dns_rdatatype_t type, dst_key_t *key)
5982 {
5983 isc_result_t result;
5984 dns_rdataset_t rdataset;
5985 dns_rdata_t rdata = DNS_RDATA_INIT;
5986 dns_rdata_rrsig_t rrsig;
5987
5988 dns_rdataset_init(&rdataset);
5989 result = dns_db_findrdataset(db, node, version, dns_rdatatype_rrsig,
5990 type, 0, &rdataset, NULL);
5991 if (result != ISC_R_SUCCESS) {
5992 INSIST(!dns_rdataset_isassociated(&rdataset));
5993 return (ISC_FALSE);
5994 }
5995 for (result = dns_rdataset_first(&rdataset);
5996 result == ISC_R_SUCCESS;
5997 result = dns_rdataset_next(&rdataset)) {
5998 dns_rdataset_current(&rdataset, &rdata);
5999 result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
6000 INSIST(result == ISC_R_SUCCESS);
6001 if (rrsig.algorithm == dst_key_alg(key) &&
6002 rrsig.keyid == dst_key_id(key)) {
6003 dns_rdataset_disassociate(&rdataset);
6004 return (ISC_TRUE);
6005 }
6006 dns_rdata_reset(&rdata);
6007 }
6008 dns_rdataset_disassociate(&rdataset);
6009 return (ISC_FALSE);
6010 }
6011
6012 static isc_result_t
add_nsec(dns_db_t * db,dns_dbversion_t * version,dns_name_t * name,dns_dbnode_t * node,dns_ttl_t ttl,isc_boolean_t bottom,dns_diff_t * diff)6013 add_nsec(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
6014 dns_dbnode_t *node, dns_ttl_t ttl, isc_boolean_t bottom,
6015 dns_diff_t *diff)
6016 {
6017 dns_fixedname_t fixed;
6018 dns_name_t *next;
6019 dns_rdata_t rdata = DNS_RDATA_INIT;
6020 isc_result_t result;
6021 unsigned char nsecbuffer[DNS_NSEC_BUFFERSIZE];
6022
6023 dns_fixedname_init(&fixed);
6024 next = dns_fixedname_name(&fixed);
6025
6026 CHECK(next_active(db, version, name, next, bottom));
6027 CHECK(dns_nsec_buildrdata(db, version, node, next, nsecbuffer,
6028 &rdata));
6029 CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADD, name, ttl,
6030 &rdata));
6031 failure:
6032 return (result);
6033 }
6034
6035 static isc_result_t
sign_a_node(dns_db_t * db,dns_name_t * name,dns_dbnode_t * node,dns_dbversion_t * version,isc_boolean_t build_nsec3,isc_boolean_t build_nsec,dst_key_t * key,isc_stdtime_t inception,isc_stdtime_t expire,unsigned int minimum,isc_boolean_t is_ksk,isc_boolean_t keyset_kskonly,isc_boolean_t * delegation,dns_diff_t * diff,isc_int32_t * signatures,isc_mem_t * mctx)6036 sign_a_node(dns_db_t *db, dns_name_t *name, dns_dbnode_t *node,
6037 dns_dbversion_t *version, isc_boolean_t build_nsec3,
6038 isc_boolean_t build_nsec, dst_key_t *key,
6039 isc_stdtime_t inception, isc_stdtime_t expire,
6040 unsigned int minimum, isc_boolean_t is_ksk,
6041 isc_boolean_t keyset_kskonly, isc_boolean_t *delegation,
6042 dns_diff_t *diff, isc_int32_t *signatures, isc_mem_t *mctx)
6043 {
6044 isc_result_t result;
6045 dns_rdatasetiter_t *iterator = NULL;
6046 dns_rdataset_t rdataset;
6047 dns_rdata_t rdata = DNS_RDATA_INIT;
6048 isc_buffer_t buffer;
6049 unsigned char data[1024];
6050 isc_boolean_t seen_soa, seen_ns, seen_rr, seen_dname, seen_nsec,
6051 seen_nsec3, seen_ds;
6052 isc_boolean_t bottom;
6053
6054 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
6055 if (result != ISC_R_SUCCESS) {
6056 if (result == ISC_R_NOTFOUND)
6057 result = ISC_R_SUCCESS;
6058 return (result);
6059 }
6060
6061 dns_rdataset_init(&rdataset);
6062 isc_buffer_init(&buffer, data, sizeof(data));
6063 seen_rr = seen_soa = seen_ns = seen_dname = seen_nsec =
6064 seen_nsec3 = seen_ds = ISC_FALSE;
6065 for (result = dns_rdatasetiter_first(iterator);
6066 result == ISC_R_SUCCESS;
6067 result = dns_rdatasetiter_next(iterator)) {
6068 dns_rdatasetiter_current(iterator, &rdataset);
6069 if (rdataset.type == dns_rdatatype_soa)
6070 seen_soa = ISC_TRUE;
6071 else if (rdataset.type == dns_rdatatype_ns)
6072 seen_ns = ISC_TRUE;
6073 else if (rdataset.type == dns_rdatatype_ds)
6074 seen_ds = ISC_TRUE;
6075 else if (rdataset.type == dns_rdatatype_dname)
6076 seen_dname = ISC_TRUE;
6077 else if (rdataset.type == dns_rdatatype_nsec)
6078 seen_nsec = ISC_TRUE;
6079 else if (rdataset.type == dns_rdatatype_nsec3)
6080 seen_nsec3 = ISC_TRUE;
6081 if (rdataset.type != dns_rdatatype_rrsig)
6082 seen_rr = ISC_TRUE;
6083 dns_rdataset_disassociate(&rdataset);
6084 }
6085 if (result != ISC_R_NOMORE)
6086 goto failure;
6087 if (seen_ns && !seen_soa)
6088 *delegation = ISC_TRUE;
6089 /*
6090 * Going from insecure to NSEC3.
6091 * Don't generate NSEC3 records for NSEC3 records.
6092 */
6093 if (build_nsec3 && !seen_nsec3 && seen_rr) {
6094 isc_boolean_t unsecure = !seen_ds && seen_ns && !seen_soa;
6095 CHECK(dns_nsec3_addnsec3s(db, version, name, minimum,
6096 unsecure, diff));
6097 (*signatures)--;
6098 }
6099 /*
6100 * Going from insecure to NSEC.
6101 * Don't generate NSEC records for NSEC3 records.
6102 */
6103 if (build_nsec && !seen_nsec3 && !seen_nsec && seen_rr) {
6104 /* Build and add NSEC. */
6105 bottom = (seen_ns && !seen_soa) || seen_dname;
6106 /*
6107 * Build a NSEC record except at the origin.
6108 */
6109 if (!dns_name_equal(name, dns_db_origin(db))) {
6110 CHECK(add_nsec(db, version, name, node, minimum,
6111 bottom, diff));
6112 /* Count a NSEC generation as a signature generation. */
6113 (*signatures)--;
6114 }
6115 }
6116 result = dns_rdatasetiter_first(iterator);
6117 while (result == ISC_R_SUCCESS) {
6118 dns_rdatasetiter_current(iterator, &rdataset);
6119 if (rdataset.type == dns_rdatatype_soa ||
6120 rdataset.type == dns_rdatatype_rrsig)
6121 goto next_rdataset;
6122 if (rdataset.type == dns_rdatatype_dnskey) {
6123 if (!is_ksk && keyset_kskonly)
6124 goto next_rdataset;
6125 } else if (is_ksk) {
6126 /*
6127 * CDS and CDNSKEY are signed with KSK (RFC 7344, 4.1).
6128 */
6129 if (rdataset.type != dns_rdatatype_cds &&
6130 rdataset.type != dns_rdatatype_cdnskey)
6131 goto next_rdataset;
6132 }
6133 if (*delegation &&
6134 rdataset.type != dns_rdatatype_ds &&
6135 rdataset.type != dns_rdatatype_nsec)
6136 goto next_rdataset;
6137 if (signed_with_key(db, node, version, rdataset.type, key))
6138 goto next_rdataset;
6139 /* Calculate the signature, creating a RRSIG RDATA. */
6140 isc_buffer_clear(&buffer);
6141 CHECK(dns_dnssec_sign(name, &rdataset, key, &inception,
6142 &expire, mctx, &buffer, &rdata));
6143 /* Update the database and journal with the RRSIG. */
6144 /* XXX inefficient - will cause dataset merging */
6145 CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADDRESIGN,
6146 name, rdataset.ttl, &rdata));
6147 dns_rdata_reset(&rdata);
6148 (*signatures)--;
6149 next_rdataset:
6150 dns_rdataset_disassociate(&rdataset);
6151 result = dns_rdatasetiter_next(iterator);
6152 }
6153 if (result == ISC_R_NOMORE)
6154 result = ISC_R_SUCCESS;
6155 if (seen_dname)
6156 *delegation = ISC_TRUE;
6157 failure:
6158 if (dns_rdataset_isassociated(&rdataset))
6159 dns_rdataset_disassociate(&rdataset);
6160 if (iterator != NULL)
6161 dns_rdatasetiter_destroy(&iterator);
6162 return (result);
6163 }
6164
6165 /*
6166 * If 'update_only' is set then don't create a NSEC RRset if it doesn't exist.
6167 */
6168 static isc_result_t
updatesecure(dns_db_t * db,dns_dbversion_t * version,dns_name_t * name,dns_ttl_t minimum,isc_boolean_t update_only,dns_diff_t * diff)6169 updatesecure(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
6170 dns_ttl_t minimum, isc_boolean_t update_only, dns_diff_t *diff)
6171 {
6172 isc_result_t result;
6173 dns_rdataset_t rdataset;
6174 dns_dbnode_t *node = NULL;
6175
6176 CHECK(dns_db_getoriginnode(db, &node));
6177 if (update_only) {
6178 dns_rdataset_init(&rdataset);
6179 result = dns_db_findrdataset(db, node, version,
6180 dns_rdatatype_nsec,
6181 dns_rdatatype_none,
6182 0, &rdataset, NULL);
6183 if (dns_rdataset_isassociated(&rdataset))
6184 dns_rdataset_disassociate(&rdataset);
6185 if (result == ISC_R_NOTFOUND)
6186 goto success;
6187 if (result != ISC_R_SUCCESS)
6188 goto failure;
6189 }
6190 CHECK(delete_nsec(db, version, node, name, diff));
6191 CHECK(add_nsec(db, version, name, node, minimum, ISC_FALSE, diff));
6192 success:
6193 result = ISC_R_SUCCESS;
6194 failure:
6195 if (node != NULL)
6196 dns_db_detachnode(db, &node);
6197 return (result);
6198 }
6199
6200 static isc_result_t
updatesignwithkey(dns_zone_t * zone,dns_signing_t * signing,dns_dbversion_t * version,isc_boolean_t build_nsec3,dns_ttl_t minimum,dns_diff_t * diff)6201 updatesignwithkey(dns_zone_t *zone, dns_signing_t *signing,
6202 dns_dbversion_t *version, isc_boolean_t build_nsec3,
6203 dns_ttl_t minimum, dns_diff_t *diff)
6204 {
6205 isc_result_t result;
6206 dns_dbnode_t *node = NULL;
6207 dns_rdataset_t rdataset;
6208 dns_rdata_t rdata = DNS_RDATA_INIT;
6209 unsigned char data[5];
6210 isc_boolean_t seen_done = ISC_FALSE;
6211 isc_boolean_t have_rr = ISC_FALSE;
6212
6213 dns_rdataset_init(&rdataset);
6214 result = dns_db_getoriginnode(signing->db, &node);
6215 if (result != ISC_R_SUCCESS)
6216 goto failure;
6217
6218 result = dns_db_findrdataset(signing->db, node, version,
6219 zone->privatetype, dns_rdatatype_none,
6220 0, &rdataset, NULL);
6221 if (result == ISC_R_NOTFOUND) {
6222 INSIST(!dns_rdataset_isassociated(&rdataset));
6223 result = ISC_R_SUCCESS;
6224 goto failure;
6225 }
6226 if (result != ISC_R_SUCCESS) {
6227 INSIST(!dns_rdataset_isassociated(&rdataset));
6228 goto failure;
6229 }
6230 for (result = dns_rdataset_first(&rdataset);
6231 result == ISC_R_SUCCESS;
6232 result = dns_rdataset_next(&rdataset)) {
6233 dns_rdataset_current(&rdataset, &rdata);
6234 /*
6235 * If we don't match the algorithm or keyid skip the record.
6236 */
6237 if (rdata.length != 5 ||
6238 rdata.data[0] != signing->algorithm ||
6239 rdata.data[1] != ((signing->keyid >> 8) & 0xff) ||
6240 rdata.data[2] != (signing->keyid & 0xff)) {
6241 have_rr = ISC_TRUE;
6242 dns_rdata_reset(&rdata);
6243 continue;
6244 }
6245 /*
6246 * We have a match. If we were signing (!signing->delete)
6247 * and we already have a record indicating that we have
6248 * finished signing (rdata.data[4] != 0) then keep it.
6249 * Otherwise it needs to be deleted as we have removed all
6250 * the signatures (signing->delete), so any record indicating
6251 * completion is now out of date, or we have finished signing
6252 * with the new record so we no longer need to remember that
6253 * we need to sign the zone with the matching key across a
6254 * nameserver re-start.
6255 */
6256 if (!signing->delete && rdata.data[4] != 0) {
6257 seen_done = ISC_TRUE;
6258 have_rr = ISC_TRUE;
6259 } else
6260 CHECK(update_one_rr(signing->db, version, diff,
6261 DNS_DIFFOP_DEL, &zone->origin,
6262 rdataset.ttl, &rdata));
6263 dns_rdata_reset(&rdata);
6264 }
6265 if (result == ISC_R_NOMORE)
6266 result = ISC_R_SUCCESS;
6267 if (!signing->delete && !seen_done) {
6268 /*
6269 * If we were signing then we need to indicate that we have
6270 * finished signing the zone with this key. If it is already
6271 * there we don't need to add it a second time.
6272 */
6273 data[0] = signing->algorithm;
6274 data[1] = (signing->keyid >> 8) & 0xff;
6275 data[2] = signing->keyid & 0xff;
6276 data[3] = 0;
6277 data[4] = 1;
6278 rdata.length = sizeof(data);
6279 rdata.data = data;
6280 rdata.type = zone->privatetype;
6281 rdata.rdclass = dns_db_class(signing->db);
6282 CHECK(update_one_rr(signing->db, version, diff, DNS_DIFFOP_ADD,
6283 &zone->origin, rdataset.ttl, &rdata));
6284 } else if (!have_rr) {
6285 dns_name_t *origin = dns_db_origin(signing->db);
6286 /*
6287 * Rebuild the NSEC/NSEC3 record for the origin as we no
6288 * longer have any private records.
6289 */
6290 if (build_nsec3)
6291 CHECK(dns_nsec3_addnsec3s(signing->db, version, origin,
6292 minimum, ISC_FALSE, diff));
6293 CHECK(updatesecure(signing->db, version, origin, minimum,
6294 ISC_TRUE, diff));
6295 }
6296
6297 failure:
6298 if (dns_rdataset_isassociated(&rdataset))
6299 dns_rdataset_disassociate(&rdataset);
6300 if (node != NULL)
6301 dns_db_detachnode(signing->db, &node);
6302 return (result);
6303 }
6304
6305 /*
6306 * If 'active' is set then we are not done with the chain yet so only
6307 * delete the nsec3param record which indicates a full chain exists
6308 * (flags == 0).
6309 */
6310 static isc_result_t
fixup_nsec3param(dns_db_t * db,dns_dbversion_t * ver,dns_nsec3chain_t * chain,isc_boolean_t active,dns_rdatatype_t privatetype,dns_diff_t * diff)6311 fixup_nsec3param(dns_db_t *db, dns_dbversion_t *ver, dns_nsec3chain_t *chain,
6312 isc_boolean_t active, dns_rdatatype_t privatetype,
6313 dns_diff_t *diff)
6314 {
6315 dns_dbnode_t *node = NULL;
6316 dns_name_t *name = dns_db_origin(db);
6317 dns_rdata_t rdata = DNS_RDATA_INIT;
6318 dns_rdataset_t rdataset;
6319 dns_rdata_nsec3param_t nsec3param;
6320 isc_result_t result;
6321 isc_buffer_t buffer;
6322 unsigned char parambuf[DNS_NSEC3PARAM_BUFFERSIZE];
6323 dns_ttl_t ttl = 0;
6324 isc_boolean_t nseconly = ISC_FALSE, nsec3ok = ISC_FALSE;
6325
6326 dns_rdataset_init(&rdataset);
6327
6328 result = dns_db_getoriginnode(db, &node);
6329 RUNTIME_CHECK(result == ISC_R_SUCCESS);
6330 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param,
6331 0, 0, &rdataset, NULL);
6332 if (result == ISC_R_NOTFOUND)
6333 goto try_private;
6334 if (result != ISC_R_SUCCESS)
6335 goto failure;
6336
6337 /*
6338 * Preserve the existing ttl.
6339 */
6340 ttl = rdataset.ttl;
6341
6342 /*
6343 * Delete all NSEC3PARAM records which match that in nsec3chain.
6344 */
6345 for (result = dns_rdataset_first(&rdataset);
6346 result == ISC_R_SUCCESS;
6347 result = dns_rdataset_next(&rdataset)) {
6348
6349 dns_rdataset_current(&rdataset, &rdata);
6350 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
6351
6352 if (nsec3param.hash != chain->nsec3param.hash ||
6353 (active && nsec3param.flags != 0) ||
6354 nsec3param.iterations != chain->nsec3param.iterations ||
6355 nsec3param.salt_length != chain->nsec3param.salt_length ||
6356 memcmp(nsec3param.salt, chain->nsec3param.salt,
6357 nsec3param.salt_length)) {
6358 dns_rdata_reset(&rdata);
6359 continue;
6360 }
6361
6362 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL,
6363 name, rdataset.ttl, &rdata));
6364 dns_rdata_reset(&rdata);
6365 }
6366 if (result != ISC_R_NOMORE)
6367 goto failure;
6368
6369 dns_rdataset_disassociate(&rdataset);
6370
6371 try_private:
6372
6373 if (active)
6374 goto add;
6375
6376 result = dns_nsec_nseconly(db, ver, &nseconly);
6377 nsec3ok = (result == ISC_R_SUCCESS && !nseconly);
6378
6379 /*
6380 * Delete all private records which match that in nsec3chain.
6381 */
6382 result = dns_db_findrdataset(db, node, ver, privatetype,
6383 0, 0, &rdataset, NULL);
6384 if (result == ISC_R_NOTFOUND)
6385 goto add;
6386 if (result != ISC_R_SUCCESS)
6387 goto failure;
6388
6389 for (result = dns_rdataset_first(&rdataset);
6390 result == ISC_R_SUCCESS;
6391 result = dns_rdataset_next(&rdataset)) {
6392 dns_rdata_t private = DNS_RDATA_INIT;
6393 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
6394
6395 dns_rdataset_current(&rdataset, &private);
6396 if (!dns_nsec3param_fromprivate(&private, &rdata,
6397 buf, sizeof(buf)))
6398 continue;
6399 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
6400
6401 if ((!nsec3ok &&
6402 (nsec3param.flags & DNS_NSEC3FLAG_INITIAL) != 0) ||
6403 nsec3param.hash != chain->nsec3param.hash ||
6404 nsec3param.iterations != chain->nsec3param.iterations ||
6405 nsec3param.salt_length != chain->nsec3param.salt_length ||
6406 memcmp(nsec3param.salt, chain->nsec3param.salt,
6407 nsec3param.salt_length)) {
6408 dns_rdata_reset(&rdata);
6409 continue;
6410 }
6411
6412 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL,
6413 name, rdataset.ttl, &private));
6414 dns_rdata_reset(&rdata);
6415 }
6416 if (result != ISC_R_NOMORE)
6417 goto failure;
6418
6419 add:
6420 if ((chain->nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) {
6421 result = ISC_R_SUCCESS;
6422 goto failure;
6423 }
6424
6425 /*
6426 * Add a NSEC3PARAM record which matches that in nsec3chain but
6427 * with all flags bits cleared.
6428 *
6429 * Note: we do not clear chain->nsec3param.flags as this change
6430 * may be reversed.
6431 */
6432 isc_buffer_init(&buffer, ¶mbuf, sizeof(parambuf));
6433 CHECK(dns_rdata_fromstruct(&rdata, dns_db_class(db),
6434 dns_rdatatype_nsec3param,
6435 &chain->nsec3param, &buffer));
6436 rdata.data[1] = 0; /* Clear flag bits. */
6437 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD, name, ttl, &rdata));
6438
6439 failure:
6440 dns_db_detachnode(db, &node);
6441 if (dns_rdataset_isassociated(&rdataset))
6442 dns_rdataset_disassociate(&rdataset);
6443 return (result);
6444 }
6445
6446 static isc_result_t
delete_nsec(dns_db_t * db,dns_dbversion_t * ver,dns_dbnode_t * node,dns_name_t * name,dns_diff_t * diff)6447 delete_nsec(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node,
6448 dns_name_t *name, dns_diff_t *diff)
6449 {
6450 dns_rdataset_t rdataset;
6451 isc_result_t result;
6452
6453 dns_rdataset_init(&rdataset);
6454
6455 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec,
6456 0, 0, &rdataset, NULL);
6457 if (result == ISC_R_NOTFOUND)
6458 return (ISC_R_SUCCESS);
6459 if (result != ISC_R_SUCCESS)
6460 return (result);
6461 for (result = dns_rdataset_first(&rdataset);
6462 result == ISC_R_SUCCESS;
6463 result = dns_rdataset_next(&rdataset)) {
6464 dns_rdata_t rdata = DNS_RDATA_INIT;
6465
6466 dns_rdataset_current(&rdataset, &rdata);
6467 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name,
6468 rdataset.ttl, &rdata));
6469 }
6470 if (result == ISC_R_NOMORE)
6471 result = ISC_R_SUCCESS;
6472 failure:
6473 dns_rdataset_disassociate(&rdataset);
6474 return (result);
6475 }
6476
6477 static isc_result_t
deletematchingnsec3(dns_db_t * db,dns_dbversion_t * ver,dns_dbnode_t * node,dns_name_t * name,const dns_rdata_nsec3param_t * param,dns_diff_t * diff)6478 deletematchingnsec3(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node,
6479 dns_name_t *name, const dns_rdata_nsec3param_t *param,
6480 dns_diff_t *diff)
6481 {
6482 dns_rdataset_t rdataset;
6483 dns_rdata_nsec3_t nsec3;
6484 isc_result_t result;
6485
6486 dns_rdataset_init(&rdataset);
6487 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3,
6488 0, 0, &rdataset, NULL);
6489 if (result == ISC_R_NOTFOUND)
6490 return (ISC_R_SUCCESS);
6491 if (result != ISC_R_SUCCESS)
6492 return (result);
6493
6494 for (result = dns_rdataset_first(&rdataset);
6495 result == ISC_R_SUCCESS;
6496 result = dns_rdataset_next(&rdataset)) {
6497 dns_rdata_t rdata = DNS_RDATA_INIT;
6498
6499 dns_rdataset_current(&rdataset, &rdata);
6500 CHECK(dns_rdata_tostruct(&rdata, &nsec3, NULL));
6501 if (nsec3.hash != param->hash ||
6502 nsec3.iterations != param->iterations ||
6503 nsec3.salt_length != param->salt_length ||
6504 memcmp(nsec3.salt, param->salt, nsec3.salt_length))
6505 continue;
6506 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name,
6507 rdataset.ttl, &rdata));
6508 }
6509 if (result == ISC_R_NOMORE)
6510 result = ISC_R_SUCCESS;
6511 failure:
6512 dns_rdataset_disassociate(&rdataset);
6513 return (result);
6514 }
6515
6516 static isc_result_t
need_nsec_chain(dns_db_t * db,dns_dbversion_t * ver,const dns_rdata_nsec3param_t * param,isc_boolean_t * answer)6517 need_nsec_chain(dns_db_t *db, dns_dbversion_t *ver,
6518 const dns_rdata_nsec3param_t *param,
6519 isc_boolean_t *answer)
6520 {
6521 dns_dbnode_t *node = NULL;
6522 dns_rdata_t rdata = DNS_RDATA_INIT;
6523 dns_rdata_nsec3param_t myparam;
6524 dns_rdataset_t rdataset;
6525 isc_result_t result;
6526
6527 *answer = ISC_FALSE;
6528
6529 result = dns_db_getoriginnode(db, &node);
6530 RUNTIME_CHECK(result == ISC_R_SUCCESS);
6531
6532 dns_rdataset_init(&rdataset);
6533
6534 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec,
6535 0, 0, &rdataset, NULL);
6536 if (result == ISC_R_SUCCESS) {
6537 dns_rdataset_disassociate(&rdataset);
6538 dns_db_detachnode(db, &node);
6539 return (result);
6540 }
6541 if (result != ISC_R_NOTFOUND) {
6542 dns_db_detachnode(db, &node);
6543 return (result);
6544 }
6545
6546 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param,
6547 0, 0, &rdataset, NULL);
6548 if (result == ISC_R_NOTFOUND) {
6549 *answer = ISC_TRUE;
6550 dns_db_detachnode(db, &node);
6551 return (ISC_R_SUCCESS);
6552 }
6553 if (result != ISC_R_SUCCESS) {
6554 dns_db_detachnode(db, &node);
6555 return (result);
6556 }
6557
6558 for (result = dns_rdataset_first(&rdataset);
6559 result == ISC_R_SUCCESS;
6560 result = dns_rdataset_next(&rdataset)) {
6561 dns_rdataset_current(&rdataset, &rdata);
6562 CHECK(dns_rdata_tostruct(&rdata, &myparam, NULL));
6563 dns_rdata_reset(&rdata);
6564 /*
6565 * Ignore any NSEC3PARAM removals.
6566 */
6567 if (NSEC3REMOVE(myparam.flags))
6568 continue;
6569 /*
6570 * Ignore the chain that we are in the process of deleting.
6571 */
6572 if (myparam.hash == param->hash &&
6573 myparam.iterations == param->iterations &&
6574 myparam.salt_length == param->salt_length &&
6575 !memcmp(myparam.salt, param->salt, myparam.salt_length))
6576 continue;
6577 /*
6578 * Found an active NSEC3 chain.
6579 */
6580 break;
6581 }
6582 if (result == ISC_R_NOMORE) {
6583 *answer = ISC_TRUE;
6584 result = ISC_R_SUCCESS;
6585 }
6586
6587 failure:
6588 if (dns_rdataset_isassociated(&rdataset))
6589 dns_rdataset_disassociate(&rdataset);
6590 dns_db_detachnode(db, &node);
6591 return (result);
6592 }
6593
6594 static isc_result_t
update_sigs(dns_diff_t * diff,dns_db_t * db,dns_dbversion_t * version,dst_key_t * zone_keys[],unsigned int nkeys,dns_zone_t * zone,isc_stdtime_t inception,isc_stdtime_t expire,isc_stdtime_t now,isc_boolean_t check_ksk,isc_boolean_t keyset_kskonly,zonediff_t * zonediff)6595 update_sigs(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *version,
6596 dst_key_t *zone_keys[], unsigned int nkeys, dns_zone_t *zone,
6597 isc_stdtime_t inception, isc_stdtime_t expire, isc_stdtime_t now,
6598 isc_boolean_t check_ksk, isc_boolean_t keyset_kskonly,
6599 zonediff_t *zonediff)
6600 {
6601 dns_difftuple_t *tuple;
6602 isc_result_t result;
6603
6604 for (tuple = ISC_LIST_HEAD(diff->tuples);
6605 tuple != NULL;
6606 tuple = ISC_LIST_HEAD(diff->tuples)) {
6607 result = del_sigs(zone, db, version, &tuple->name,
6608 tuple->rdata.type, zonediff,
6609 zone_keys, nkeys, now, ISC_FALSE);
6610 if (result != ISC_R_SUCCESS) {
6611 dns_zone_log(zone, ISC_LOG_ERROR,
6612 "update_sigs:del_sigs -> %s",
6613 dns_result_totext(result));
6614 return (result);
6615 }
6616 result = add_sigs(db, version, &tuple->name,
6617 tuple->rdata.type, zonediff->diff,
6618 zone_keys, nkeys, zone->mctx, inception,
6619 expire, check_ksk, keyset_kskonly);
6620 if (result != ISC_R_SUCCESS) {
6621 dns_zone_log(zone, ISC_LOG_ERROR,
6622 "update_sigs:add_sigs -> %s",
6623 dns_result_totext(result));
6624 return (result);
6625 }
6626
6627 do {
6628 dns_difftuple_t *next = ISC_LIST_NEXT(tuple, link);
6629 while (next != NULL &&
6630 (tuple->rdata.type != next->rdata.type ||
6631 !dns_name_equal(&tuple->name, &next->name)))
6632 next = ISC_LIST_NEXT(next, link);
6633 ISC_LIST_UNLINK(diff->tuples, tuple, link);
6634 dns_diff_appendminimal(zonediff->diff, &tuple);
6635 INSIST(tuple == NULL);
6636 tuple = next;
6637 } while (tuple != NULL);
6638 }
6639 return (ISC_R_SUCCESS);
6640 }
6641
6642 /*
6643 * Incrementally build and sign a new NSEC3 chain using the parameters
6644 * requested.
6645 */
6646 static void
zone_nsec3chain(dns_zone_t * zone)6647 zone_nsec3chain(dns_zone_t *zone) {
6648 const char *me = "zone_nsec3chain";
6649 dns_db_t *db = NULL;
6650 dns_dbnode_t *node = NULL;
6651 dns_dbversion_t *version = NULL;
6652 dns_diff_t _sig_diff;
6653 dns_diff_t nsec_diff;
6654 dns_diff_t nsec3_diff;
6655 dns_diff_t param_diff;
6656 zonediff_t zonediff;
6657 dns_fixedname_t fixed;
6658 dns_fixedname_t nextfixed;
6659 dns_name_t *name, *nextname;
6660 dns_rdataset_t rdataset;
6661 dns_nsec3chain_t *nsec3chain = NULL, *nextnsec3chain;
6662 dns_nsec3chainlist_t cleanup;
6663 dst_key_t *zone_keys[DNS_MAXZONEKEYS];
6664 isc_int32_t signatures;
6665 isc_boolean_t check_ksk, keyset_kskonly;
6666 isc_boolean_t delegation;
6667 isc_boolean_t first;
6668 isc_result_t result;
6669 isc_stdtime_t now, inception, soaexpire, expire;
6670 isc_uint32_t jitter;
6671 unsigned int i;
6672 unsigned int nkeys = 0;
6673 isc_uint32_t nodes;
6674 isc_boolean_t unsecure = ISC_FALSE;
6675 isc_boolean_t seen_soa, seen_ns, seen_dname, seen_ds;
6676 isc_boolean_t seen_nsec, seen_nsec3, seen_rr;
6677 dns_rdatasetiter_t *iterator = NULL;
6678 isc_boolean_t buildnsecchain;
6679 isc_boolean_t updatensec = ISC_FALSE;
6680 dns_rdatatype_t privatetype = zone->privatetype;
6681
6682 ENTER;
6683
6684 dns_rdataset_init(&rdataset);
6685 dns_fixedname_init(&fixed);
6686 name = dns_fixedname_name(&fixed);
6687 dns_fixedname_init(&nextfixed);
6688 nextname = dns_fixedname_name(&nextfixed);
6689 dns_diff_init(zone->mctx, ¶m_diff);
6690 dns_diff_init(zone->mctx, &nsec3_diff);
6691 dns_diff_init(zone->mctx, &nsec_diff);
6692 dns_diff_init(zone->mctx, &_sig_diff);
6693 zonediff_init(&zonediff, &_sig_diff);
6694 ISC_LIST_INIT(cleanup);
6695
6696 /*
6697 * Updates are disabled. Pause for 5 minutes.
6698 */
6699 if (zone->update_disabled) {
6700 result = ISC_R_FAILURE;
6701 goto failure;
6702 }
6703
6704 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
6705 dns_db_attach(zone->db, &db);
6706 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
6707
6708 result = dns_db_newversion(db, &version);
6709 if (result != ISC_R_SUCCESS) {
6710 dns_zone_log(zone, ISC_LOG_ERROR,
6711 "zone_nsec3chain:dns_db_newversion -> %s",
6712 dns_result_totext(result));
6713 goto failure;
6714 }
6715
6716 result = find_zone_keys(zone, db, version, zone->mctx,
6717 DNS_MAXZONEKEYS, zone_keys, &nkeys);
6718 if (result != ISC_R_SUCCESS) {
6719 dns_zone_log(zone, ISC_LOG_ERROR,
6720 "zone_nsec3chain:find_zone_keys -> %s",
6721 dns_result_totext(result));
6722 goto failure;
6723 }
6724
6725 isc_stdtime_get(&now);
6726 inception = now - 3600; /* Allow for clock skew. */
6727 soaexpire = now + dns_zone_getsigvalidityinterval(zone);
6728
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 isc_random_get(&jitter);
6735 expire = soaexpire - jitter % 3600;
6736
6737 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
6738 keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
6739
6740 /*
6741 * We keep pulling nodes off each iterator in turn until
6742 * we have no more nodes to pull off or we reach the limits
6743 * for this quantum.
6744 */
6745 nodes = zone->nodes;
6746 signatures = zone->signatures;
6747 LOCK_ZONE(zone);
6748 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
6749 UNLOCK_ZONE(zone);
6750 first = ISC_TRUE;
6751
6752 if (nsec3chain != NULL)
6753 nsec3chain->save_delete_nsec = nsec3chain->delete_nsec;
6754 /*
6755 * Generate new NSEC3 chains first.
6756 */
6757 while (nsec3chain != NULL && nodes-- > 0 && signatures > 0) {
6758 LOCK_ZONE(zone);
6759 nextnsec3chain = ISC_LIST_NEXT(nsec3chain, link);
6760
6761 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
6762 if (nsec3chain->done || nsec3chain->db != zone->db) {
6763 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link);
6764 ISC_LIST_APPEND(cleanup, nsec3chain, link);
6765 }
6766 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
6767 UNLOCK_ZONE(zone);
6768 if (ISC_LIST_TAIL(cleanup) == nsec3chain)
6769 goto next_addchain;
6770
6771 /*
6772 * Possible future db.
6773 */
6774 if (nsec3chain->db != db) {
6775 goto next_addchain;
6776 }
6777
6778 if (NSEC3REMOVE(nsec3chain->nsec3param.flags))
6779 goto next_addchain;
6780
6781 dns_dbiterator_current(nsec3chain->dbiterator, &node, name);
6782
6783 if (nsec3chain->delete_nsec) {
6784 delegation = ISC_FALSE;
6785 dns_dbiterator_pause(nsec3chain->dbiterator);
6786 CHECK(delete_nsec(db, version, node, name, &nsec_diff));
6787 goto next_addnode;
6788 }
6789 /*
6790 * On the first pass we need to check if the current node
6791 * has not been obscured.
6792 */
6793 delegation = ISC_FALSE;
6794 unsecure = ISC_FALSE;
6795 if (first) {
6796 dns_fixedname_t ffound;
6797 dns_name_t *found;
6798 dns_fixedname_init(&ffound);
6799 found = dns_fixedname_name(&ffound);
6800 result = dns_db_find(db, name, version,
6801 dns_rdatatype_soa,
6802 DNS_DBFIND_NOWILD, 0, NULL, found,
6803 NULL, NULL);
6804 if ((result == DNS_R_DELEGATION ||
6805 result == DNS_R_DNAME) &&
6806 !dns_name_equal(name, found)) {
6807 /*
6808 * Remember the obscuring name so that
6809 * we skip all obscured names.
6810 */
6811 dns_name_copy(found, name, NULL);
6812 delegation = ISC_TRUE;
6813 goto next_addnode;
6814 }
6815 }
6816
6817 /*
6818 * Check to see if this is a bottom of zone node.
6819 */
6820 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
6821 if (result == ISC_R_NOTFOUND) /* Empty node? */
6822 goto next_addnode;
6823 if (result != ISC_R_SUCCESS)
6824 goto failure;
6825
6826 seen_soa = seen_ns = seen_dname = seen_ds = seen_nsec =
6827 ISC_FALSE;
6828 for (result = dns_rdatasetiter_first(iterator);
6829 result == ISC_R_SUCCESS;
6830 result = dns_rdatasetiter_next(iterator)) {
6831 dns_rdatasetiter_current(iterator, &rdataset);
6832 INSIST(rdataset.type != dns_rdatatype_nsec3);
6833 if (rdataset.type == dns_rdatatype_soa)
6834 seen_soa = ISC_TRUE;
6835 else if (rdataset.type == dns_rdatatype_ns)
6836 seen_ns = ISC_TRUE;
6837 else if (rdataset.type == dns_rdatatype_dname)
6838 seen_dname = ISC_TRUE;
6839 else if (rdataset.type == dns_rdatatype_ds)
6840 seen_ds = ISC_TRUE;
6841 else if (rdataset.type == dns_rdatatype_nsec)
6842 seen_nsec = ISC_TRUE;
6843 dns_rdataset_disassociate(&rdataset);
6844 }
6845 dns_rdatasetiter_destroy(&iterator);
6846 /*
6847 * Is there a NSEC chain than needs to be cleaned up?
6848 */
6849 if (seen_nsec)
6850 nsec3chain->seen_nsec = ISC_TRUE;
6851 if (seen_ns && !seen_soa && !seen_ds)
6852 unsecure = ISC_TRUE;
6853 if ((seen_ns && !seen_soa) || seen_dname)
6854 delegation = ISC_TRUE;
6855
6856 /*
6857 * Process one node.
6858 */
6859 dns_dbiterator_pause(nsec3chain->dbiterator);
6860 result = dns_nsec3_addnsec3(db, version, name,
6861 &nsec3chain->nsec3param,
6862 zone->minimum, unsecure,
6863 &nsec3_diff);
6864 if (result != ISC_R_SUCCESS) {
6865 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
6866 "dns_nsec3_addnsec3 -> %s",
6867 dns_result_totext(result));
6868 goto failure;
6869 }
6870
6871 /*
6872 * Treat each call to dns_nsec3_addnsec3() as if it's cost is
6873 * two signatures. Additionally there will, in general, be
6874 * two signature generated below.
6875 *
6876 * If we are only changing the optout flag the cost is half
6877 * that of the cost of generating a completely new chain.
6878 */
6879 signatures -= 4;
6880
6881 /*
6882 * Go onto next node.
6883 */
6884 next_addnode:
6885 first = ISC_FALSE;
6886 dns_db_detachnode(db, &node);
6887 do {
6888 result = dns_dbiterator_next(nsec3chain->dbiterator);
6889
6890 if (result == ISC_R_NOMORE && nsec3chain->delete_nsec) {
6891 dns_dbiterator_pause(nsec3chain->dbiterator);
6892 CHECK(fixup_nsec3param(db, version, nsec3chain,
6893 ISC_FALSE, privatetype,
6894 ¶m_diff));
6895 LOCK_ZONE(zone);
6896 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
6897 link);
6898 UNLOCK_ZONE(zone);
6899 ISC_LIST_APPEND(cleanup, nsec3chain, link);
6900 goto next_addchain;
6901 }
6902 if (result == ISC_R_NOMORE) {
6903 dns_dbiterator_pause(nsec3chain->dbiterator);
6904 if (nsec3chain->seen_nsec) {
6905 CHECK(fixup_nsec3param(db, version,
6906 nsec3chain,
6907 ISC_TRUE,
6908 privatetype,
6909 ¶m_diff));
6910 nsec3chain->delete_nsec = ISC_TRUE;
6911 goto same_addchain;
6912 }
6913 CHECK(fixup_nsec3param(db, version, nsec3chain,
6914 ISC_FALSE, privatetype,
6915 ¶m_diff));
6916 LOCK_ZONE(zone);
6917 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
6918 link);
6919 UNLOCK_ZONE(zone);
6920 ISC_LIST_APPEND(cleanup, nsec3chain, link);
6921 goto next_addchain;
6922 } else if (result != ISC_R_SUCCESS) {
6923 dns_zone_log(zone, ISC_LOG_ERROR,
6924 "zone_nsec3chain:"
6925 "dns_dbiterator_next -> %s",
6926 dns_result_totext(result));
6927 goto failure;
6928 } else if (delegation) {
6929 dns_dbiterator_current(nsec3chain->dbiterator,
6930 &node, nextname);
6931 dns_db_detachnode(db, &node);
6932 if (!dns_name_issubdomain(nextname, name))
6933 break;
6934 } else
6935 break;
6936 } while (1);
6937 continue;
6938
6939 same_addchain:
6940 CHECK(dns_dbiterator_first(nsec3chain->dbiterator));
6941 first = ISC_TRUE;
6942 continue;
6943
6944 next_addchain:
6945 dns_dbiterator_pause(nsec3chain->dbiterator);
6946 nsec3chain = nextnsec3chain;
6947 first = ISC_TRUE;
6948 if (nsec3chain != NULL)
6949 nsec3chain->save_delete_nsec = nsec3chain->delete_nsec;
6950 }
6951
6952 /*
6953 * Process removals.
6954 */
6955 LOCK_ZONE(zone);
6956 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
6957 UNLOCK_ZONE(zone);
6958 first = ISC_TRUE;
6959 buildnsecchain = ISC_FALSE;
6960 while (nsec3chain != NULL && nodes-- > 0 && signatures > 0) {
6961 LOCK_ZONE(zone);
6962 nextnsec3chain = ISC_LIST_NEXT(nsec3chain, link);
6963 UNLOCK_ZONE(zone);
6964
6965 if (nsec3chain->db != db)
6966 goto next_removechain;
6967
6968 if (!NSEC3REMOVE(nsec3chain->nsec3param.flags))
6969 goto next_removechain;
6970
6971 /*
6972 * Work out if we need to build a NSEC chain as a consequence
6973 * of removing this NSEC3 chain.
6974 */
6975 if (first && !updatensec &&
6976 (nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_NONSEC) == 0)
6977 {
6978 result = need_nsec_chain(db, version,
6979 &nsec3chain->nsec3param,
6980 &buildnsecchain);
6981 if (result != ISC_R_SUCCESS) {
6982 dns_zone_log(zone, ISC_LOG_ERROR,
6983 "zone_nsec3chain:"
6984 "need_nsec_chain -> %s",
6985 dns_result_totext(result));
6986 goto failure;
6987 }
6988 }
6989
6990 if (first)
6991 dns_zone_log(zone, ISC_LOG_DEBUG(3), "zone_nsec3chain:"
6992 "buildnsecchain = %u\n", buildnsecchain);
6993
6994 dns_dbiterator_current(nsec3chain->dbiterator, &node, name);
6995 delegation = ISC_FALSE;
6996
6997 if (!buildnsecchain) {
6998 /*
6999 * Delete the NSECPARAM record that matches this chain.
7000 */
7001 if (first) {
7002 result = fixup_nsec3param(db, version,
7003 nsec3chain,
7004 ISC_TRUE, privatetype,
7005 ¶m_diff);
7006 if (result != ISC_R_SUCCESS) {
7007 dns_zone_log(zone, ISC_LOG_ERROR,
7008 "zone_nsec3chain:"
7009 "fixup_nsec3param -> %s",
7010 dns_result_totext(result));
7011 goto failure;
7012 }
7013 }
7014
7015 /*
7016 * Delete the NSEC3 records.
7017 */
7018 result = deletematchingnsec3(db, version, node, name,
7019 &nsec3chain->nsec3param,
7020 &nsec3_diff);
7021 if (result != ISC_R_SUCCESS) {
7022 dns_zone_log(zone, ISC_LOG_ERROR,
7023 "zone_nsec3chain:"
7024 "deletematchingnsec3 -> %s",
7025 dns_result_totext(result));
7026 goto failure;
7027 }
7028 goto next_removenode;
7029 }
7030
7031 if (first) {
7032 dns_fixedname_t ffound;
7033 dns_name_t *found;
7034 dns_fixedname_init(&ffound);
7035 found = dns_fixedname_name(&ffound);
7036 result = dns_db_find(db, name, version,
7037 dns_rdatatype_soa,
7038 DNS_DBFIND_NOWILD, 0, NULL, found,
7039 NULL, NULL);
7040 if ((result == DNS_R_DELEGATION ||
7041 result == DNS_R_DNAME) &&
7042 !dns_name_equal(name, found)) {
7043 /*
7044 * Remember the obscuring name so that
7045 * we skip all obscured names.
7046 */
7047 dns_name_copy(found, name, NULL);
7048 delegation = ISC_TRUE;
7049 goto next_removenode;
7050 }
7051 }
7052
7053 /*
7054 * Check to see if this is a bottom of zone node.
7055 */
7056 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
7057 if (result == ISC_R_NOTFOUND) /* Empty node? */
7058 goto next_removenode;
7059 if (result != ISC_R_SUCCESS)
7060 goto failure;
7061
7062 seen_soa = seen_ns = seen_dname = seen_nsec3 = seen_nsec =
7063 seen_rr = ISC_FALSE;
7064 for (result = dns_rdatasetiter_first(iterator);
7065 result == ISC_R_SUCCESS;
7066 result = dns_rdatasetiter_next(iterator)) {
7067 dns_rdatasetiter_current(iterator, &rdataset);
7068 if (rdataset.type == dns_rdatatype_soa)
7069 seen_soa = ISC_TRUE;
7070 else if (rdataset.type == dns_rdatatype_ns)
7071 seen_ns = ISC_TRUE;
7072 else if (rdataset.type == dns_rdatatype_dname)
7073 seen_dname = ISC_TRUE;
7074 else if (rdataset.type == dns_rdatatype_nsec)
7075 seen_nsec = ISC_TRUE;
7076 else if (rdataset.type == dns_rdatatype_nsec3)
7077 seen_nsec3 = ISC_TRUE;
7078 if (rdataset.type != dns_rdatatype_rrsig)
7079 seen_rr = ISC_TRUE;
7080 dns_rdataset_disassociate(&rdataset);
7081 }
7082 dns_rdatasetiter_destroy(&iterator);
7083
7084 if (!seen_rr || seen_nsec3 || seen_nsec)
7085 goto next_removenode;
7086 if ((seen_ns && !seen_soa) || seen_dname)
7087 delegation = ISC_TRUE;
7088
7089 /*
7090 * Add a NSEC record except at the origin.
7091 */
7092 if (!dns_name_equal(name, dns_db_origin(db))) {
7093 dns_dbiterator_pause(nsec3chain->dbiterator);
7094 CHECK(add_nsec(db, version, name, node, zone->minimum,
7095 delegation, &nsec_diff));
7096 }
7097
7098 next_removenode:
7099 first = ISC_FALSE;
7100 dns_db_detachnode(db, &node);
7101 do {
7102 result = dns_dbiterator_next(nsec3chain->dbiterator);
7103 if (result == ISC_R_NOMORE && buildnsecchain) {
7104 /*
7105 * The NSEC chain should now be built.
7106 * We can now remove the NSEC3 chain.
7107 */
7108 updatensec = ISC_TRUE;
7109 goto same_removechain;
7110 }
7111 if (result == ISC_R_NOMORE) {
7112 LOCK_ZONE(zone);
7113 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
7114 link);
7115 UNLOCK_ZONE(zone);
7116 ISC_LIST_APPEND(cleanup, nsec3chain, link);
7117 dns_dbiterator_pause(nsec3chain->dbiterator);
7118 result = fixup_nsec3param(db, version,
7119 nsec3chain, ISC_FALSE,
7120 privatetype,
7121 ¶m_diff);
7122 if (result != ISC_R_SUCCESS) {
7123 dns_zone_log(zone, ISC_LOG_ERROR,
7124 "zone_nsec3chain:"
7125 "fixup_nsec3param -> %s",
7126 dns_result_totext(result));
7127 goto failure;
7128 }
7129 goto next_removechain;
7130 } else if (result != ISC_R_SUCCESS) {
7131 dns_zone_log(zone, ISC_LOG_ERROR,
7132 "zone_nsec3chain:"
7133 "dns_dbiterator_next -> %s",
7134 dns_result_totext(result));
7135 goto failure;
7136 } else if (delegation) {
7137 dns_dbiterator_current(nsec3chain->dbiterator,
7138 &node, nextname);
7139 dns_db_detachnode(db, &node);
7140 if (!dns_name_issubdomain(nextname, name))
7141 break;
7142 } else
7143 break;
7144 } while (1);
7145 continue;
7146
7147 same_removechain:
7148 CHECK(dns_dbiterator_first(nsec3chain->dbiterator));
7149 buildnsecchain = ISC_FALSE;
7150 first = ISC_TRUE;
7151 continue;
7152
7153 next_removechain:
7154 dns_dbiterator_pause(nsec3chain->dbiterator);
7155 nsec3chain = nextnsec3chain;
7156 first = ISC_TRUE;
7157 }
7158
7159 /*
7160 * We may need to update the NSEC/NSEC3 records for the zone apex.
7161 */
7162 if (!ISC_LIST_EMPTY(param_diff.tuples)) {
7163 isc_boolean_t rebuild_nsec = ISC_FALSE,
7164 rebuild_nsec3 = ISC_FALSE;
7165 result = dns_db_getoriginnode(db, &node);
7166 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7167 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
7168 if (result != ISC_R_SUCCESS) {
7169 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
7170 "dns_db_allrdatasets -> %s",
7171 dns_result_totext(result));
7172 goto failure;
7173 }
7174 for (result = dns_rdatasetiter_first(iterator);
7175 result == ISC_R_SUCCESS;
7176 result = dns_rdatasetiter_next(iterator)) {
7177 dns_rdatasetiter_current(iterator, &rdataset);
7178 if (rdataset.type == dns_rdatatype_nsec)
7179 rebuild_nsec = ISC_TRUE;
7180 if (rdataset.type == dns_rdatatype_nsec3param)
7181 rebuild_nsec3 = ISC_TRUE;
7182 dns_rdataset_disassociate(&rdataset);
7183 }
7184 dns_rdatasetiter_destroy(&iterator);
7185 dns_db_detachnode(db, &node);
7186
7187 if (rebuild_nsec) {
7188 if (nsec3chain != NULL)
7189 dns_dbiterator_pause(nsec3chain->dbiterator);
7190
7191 result = updatesecure(db, version, &zone->origin,
7192 zone->minimum, ISC_TRUE,
7193 &nsec_diff);
7194 if (result != ISC_R_SUCCESS) {
7195 dns_zone_log(zone, ISC_LOG_ERROR,
7196 "zone_nsec3chain:"
7197 "updatesecure -> %s",
7198 dns_result_totext(result));
7199 goto failure;
7200 }
7201 }
7202
7203 if (rebuild_nsec3) {
7204 if (nsec3chain != NULL)
7205 dns_dbiterator_pause(nsec3chain->dbiterator);
7206
7207 result = dns_nsec3_addnsec3s(db, version,
7208 dns_db_origin(db),
7209 zone->minimum, ISC_FALSE,
7210 &nsec3_diff);
7211 if (result != ISC_R_SUCCESS) {
7212 dns_zone_log(zone, ISC_LOG_ERROR,
7213 "zone_nsec3chain:"
7214 "dns_nsec3_addnsec3s -> %s",
7215 dns_result_totext(result));
7216 goto failure;
7217 }
7218 }
7219 }
7220
7221 if (nsec3chain != NULL)
7222 dns_dbiterator_pause(nsec3chain->dbiterator);
7223
7224 /*
7225 * Add / update signatures for the NSEC3 records.
7226 */
7227 if (nsec3chain != NULL)
7228 dns_dbiterator_pause(nsec3chain->dbiterator);
7229 result = update_sigs(&nsec3_diff, db, version, zone_keys,
7230 nkeys, zone, inception, expire, now,
7231 check_ksk, keyset_kskonly, &zonediff);
7232 if (result != ISC_R_SUCCESS) {
7233 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
7234 "update_sigs -> %s", dns_result_totext(result));
7235 goto failure;
7236 }
7237
7238 /*
7239 * We have changed the NSEC3PARAM or private RRsets
7240 * above so we need to update the signatures.
7241 */
7242 result = update_sigs(¶m_diff, db, version, zone_keys,
7243 nkeys, zone, inception, expire, now,
7244 check_ksk, keyset_kskonly, &zonediff);
7245 if (result != ISC_R_SUCCESS) {
7246 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
7247 "update_sigs -> %s", dns_result_totext(result));
7248 goto failure;
7249 }
7250
7251 if (updatensec) {
7252 result = updatesecure(db, version, &zone->origin,
7253 zone->minimum, ISC_FALSE, &nsec_diff);
7254 if (result != ISC_R_SUCCESS) {
7255 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
7256 "updatesecure -> %s",
7257 dns_result_totext(result));
7258 goto failure;
7259 }
7260 }
7261
7262 result = update_sigs(&nsec_diff, db, version, zone_keys,
7263 nkeys, zone, inception, expire, now,
7264 check_ksk, keyset_kskonly, &zonediff);
7265 if (result != ISC_R_SUCCESS) {
7266 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
7267 "update_sigs -> %s", dns_result_totext(result));
7268 goto failure;
7269 }
7270
7271 /*
7272 * If we made no effective changes to the zone then we can just
7273 * cleanup otherwise we need to increment the serial.
7274 */
7275 if (ISC_LIST_EMPTY(zonediff.diff->tuples)) {
7276 /*
7277 * No need to call dns_db_closeversion() here as it is
7278 * called with commit = ISC_TRUE below.
7279 */
7280 goto done;
7281 }
7282
7283 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
7284 &zonediff, zone_keys, nkeys, now, ISC_FALSE);
7285 if (result != ISC_R_SUCCESS) {
7286 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
7287 "del_sigs -> %s", dns_result_totext(result));
7288 goto failure;
7289 }
7290
7291 result = update_soa_serial(db, version, zonediff.diff, zone->mctx,
7292 zone->updatemethod);
7293 if (result != ISC_R_SUCCESS) {
7294 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
7295 "update_soa_serial -> %s",
7296 dns_result_totext(result));
7297 goto failure;
7298 }
7299
7300 result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa,
7301 zonediff.diff, zone_keys, nkeys, zone->mctx,
7302 inception, soaexpire, check_ksk, keyset_kskonly);
7303 if (result != ISC_R_SUCCESS) {
7304 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
7305 "add_sigs -> %s", dns_result_totext(result));
7306 goto failure;
7307 }
7308
7309 /* Write changes to journal file. */
7310 CHECK(zone_journal(zone, zonediff.diff, NULL, "zone_nsec3chain"));
7311
7312 LOCK_ZONE(zone);
7313 zone_needdump(zone, DNS_DUMP_DELAY);
7314 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
7315 UNLOCK_ZONE(zone);
7316
7317 done:
7318 /*
7319 * Pause all iterators so that dns_db_closeversion() can succeed.
7320 */
7321 LOCK_ZONE(zone);
7322 for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
7323 nsec3chain != NULL;
7324 nsec3chain = ISC_LIST_NEXT(nsec3chain, link))
7325 dns_dbiterator_pause(nsec3chain->dbiterator);
7326 UNLOCK_ZONE(zone);
7327
7328 /*
7329 * Everything has succeeded. Commit the changes.
7330 * Unconditionally commit as zonediff.offline not checked above.
7331 */
7332 dns_db_closeversion(db, &version, ISC_TRUE);
7333
7334 /*
7335 * Everything succeeded so we can clean these up now.
7336 */
7337 nsec3chain = ISC_LIST_HEAD(cleanup);
7338 while (nsec3chain != NULL) {
7339 ISC_LIST_UNLINK(cleanup, nsec3chain, link);
7340 dns_db_detach(&nsec3chain->db);
7341 dns_dbiterator_destroy(&nsec3chain->dbiterator);
7342 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
7343 nsec3chain = ISC_LIST_HEAD(cleanup);
7344 }
7345
7346 set_resigntime(zone);
7347
7348 failure:
7349 if (result != ISC_R_SUCCESS)
7350 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain: %s",
7351 dns_result_totext(result));
7352 /*
7353 * On error roll back the current nsec3chain.
7354 */
7355 if (result != ISC_R_SUCCESS && nsec3chain != NULL) {
7356 if (nsec3chain->done) {
7357 dns_db_detach(&nsec3chain->db);
7358 dns_dbiterator_destroy(&nsec3chain->dbiterator);
7359 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
7360 } else {
7361 result = dns_dbiterator_first(nsec3chain->dbiterator);
7362 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7363 dns_dbiterator_pause(nsec3chain->dbiterator);
7364 nsec3chain->delete_nsec = nsec3chain->save_delete_nsec;
7365 }
7366 }
7367
7368 /*
7369 * Rollback the cleanup list.
7370 */
7371 nsec3chain = ISC_LIST_TAIL(cleanup);
7372 while (nsec3chain != NULL) {
7373 ISC_LIST_UNLINK(cleanup, nsec3chain, link);
7374 if (nsec3chain->done) {
7375 dns_db_detach(&nsec3chain->db);
7376 dns_dbiterator_destroy(&nsec3chain->dbiterator);
7377 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
7378 } else {
7379 LOCK_ZONE(zone);
7380 ISC_LIST_PREPEND(zone->nsec3chain, nsec3chain, link);
7381 UNLOCK_ZONE(zone);
7382 result = dns_dbiterator_first(nsec3chain->dbiterator);
7383 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7384 dns_dbiterator_pause(nsec3chain->dbiterator);
7385 nsec3chain->delete_nsec = nsec3chain->save_delete_nsec;
7386 }
7387 nsec3chain = ISC_LIST_TAIL(cleanup);
7388 }
7389
7390 LOCK_ZONE(zone);
7391 for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
7392 nsec3chain != NULL;
7393 nsec3chain = ISC_LIST_NEXT(nsec3chain, link))
7394 dns_dbiterator_pause(nsec3chain->dbiterator);
7395 UNLOCK_ZONE(zone);
7396
7397 dns_diff_clear(¶m_diff);
7398 dns_diff_clear(&nsec3_diff);
7399 dns_diff_clear(&nsec_diff);
7400 dns_diff_clear(&_sig_diff);
7401
7402 if (iterator != NULL)
7403 dns_rdatasetiter_destroy(&iterator);
7404
7405 for (i = 0; i < nkeys; i++)
7406 dst_key_free(&zone_keys[i]);
7407
7408 if (node != NULL)
7409 dns_db_detachnode(db, &node);
7410 if (version != NULL) {
7411 dns_db_closeversion(db, &version, ISC_FALSE);
7412 dns_db_detach(&db);
7413 } else if (db != NULL)
7414 dns_db_detach(&db);
7415
7416 LOCK_ZONE(zone);
7417 if (ISC_LIST_HEAD(zone->nsec3chain) != NULL) {
7418 isc_interval_t interval;
7419 if (zone->update_disabled || result != ISC_R_SUCCESS)
7420 isc_interval_set(&interval, 60, 0); /* 1 minute */
7421 else
7422 isc_interval_set(&interval, 0, 10000000); /* 10 ms */
7423 isc_time_nowplusinterval(&zone->nsec3chaintime, &interval);
7424 } else
7425 isc_time_settoepoch(&zone->nsec3chaintime);
7426 UNLOCK_ZONE(zone);
7427
7428 INSIST(version == NULL);
7429 }
7430
7431 static isc_result_t
del_sig(dns_db_t * db,dns_dbversion_t * version,dns_name_t * name,dns_dbnode_t * node,unsigned int nkeys,dns_secalg_t algorithm,isc_uint16_t keyid,dns_diff_t * diff)7432 del_sig(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
7433 dns_dbnode_t *node, unsigned int nkeys, dns_secalg_t algorithm,
7434 isc_uint16_t keyid, dns_diff_t *diff)
7435 {
7436 dns_rdata_rrsig_t rrsig;
7437 dns_rdataset_t rdataset;
7438 dns_rdatasetiter_t *iterator = NULL;
7439 isc_result_t result;
7440
7441 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
7442 if (result != ISC_R_SUCCESS) {
7443 if (result == ISC_R_NOTFOUND)
7444 result = ISC_R_SUCCESS;
7445 return (result);
7446 }
7447
7448 dns_rdataset_init(&rdataset);
7449 for (result = dns_rdatasetiter_first(iterator);
7450 result == ISC_R_SUCCESS;
7451 result = dns_rdatasetiter_next(iterator)) {
7452 dns_rdatasetiter_current(iterator, &rdataset);
7453 if (nkeys == 0 && rdataset.type == dns_rdatatype_nsec) {
7454 for (result = dns_rdataset_first(&rdataset);
7455 result == ISC_R_SUCCESS;
7456 result = dns_rdataset_next(&rdataset)) {
7457 dns_rdata_t rdata = DNS_RDATA_INIT;
7458 dns_rdataset_current(&rdataset, &rdata);
7459 CHECK(update_one_rr(db, version, diff,
7460 DNS_DIFFOP_DEL, name,
7461 rdataset.ttl, &rdata));
7462 }
7463 if (result != ISC_R_NOMORE)
7464 goto failure;
7465 dns_rdataset_disassociate(&rdataset);
7466 continue;
7467 }
7468 if (rdataset.type != dns_rdatatype_rrsig) {
7469 dns_rdataset_disassociate(&rdataset);
7470 continue;
7471 }
7472 for (result = dns_rdataset_first(&rdataset);
7473 result == ISC_R_SUCCESS;
7474 result = dns_rdataset_next(&rdataset)) {
7475 dns_rdata_t rdata = DNS_RDATA_INIT;
7476 dns_rdataset_current(&rdataset, &rdata);
7477 CHECK(dns_rdata_tostruct(&rdata, &rrsig, NULL));
7478 if (rrsig.algorithm != algorithm ||
7479 rrsig.keyid != keyid)
7480 continue;
7481 CHECK(update_one_rr(db, version, diff,
7482 DNS_DIFFOP_DELRESIGN, name,
7483 rdataset.ttl, &rdata));
7484 }
7485 dns_rdataset_disassociate(&rdataset);
7486 if (result != ISC_R_NOMORE)
7487 break;
7488 }
7489 if (result == ISC_R_NOMORE)
7490 result = ISC_R_SUCCESS;
7491 failure:
7492 if (dns_rdataset_isassociated(&rdataset))
7493 dns_rdataset_disassociate(&rdataset);
7494 dns_rdatasetiter_destroy(&iterator);
7495 return (result);
7496 }
7497
7498 /*
7499 * Incrementally sign the zone using the keys requested.
7500 * Builds the NSEC chain if required.
7501 */
7502 static void
zone_sign(dns_zone_t * zone)7503 zone_sign(dns_zone_t *zone) {
7504 const char *me = "zone_sign";
7505 dns_db_t *db = NULL;
7506 dns_dbnode_t *node = NULL;
7507 dns_dbversion_t *version = NULL;
7508 dns_diff_t _sig_diff;
7509 dns_diff_t post_diff;
7510 zonediff_t zonediff;
7511 dns_fixedname_t fixed;
7512 dns_fixedname_t nextfixed;
7513 dns_name_t *name, *nextname;
7514 dns_rdataset_t rdataset;
7515 dns_signing_t *signing, *nextsigning;
7516 dns_signinglist_t cleanup;
7517 dst_key_t *zone_keys[DNS_MAXZONEKEYS];
7518 isc_int32_t signatures;
7519 isc_boolean_t check_ksk, keyset_kskonly, is_ksk;
7520 isc_boolean_t commit = ISC_FALSE;
7521 isc_boolean_t delegation;
7522 isc_boolean_t build_nsec = ISC_FALSE;
7523 isc_boolean_t build_nsec3 = ISC_FALSE;
7524 isc_boolean_t first;
7525 isc_result_t result;
7526 isc_stdtime_t now, inception, soaexpire, expire;
7527 isc_uint32_t jitter;
7528 unsigned int i, j;
7529 unsigned int nkeys = 0;
7530 isc_uint32_t nodes;
7531
7532 ENTER;
7533
7534 dns_rdataset_init(&rdataset);
7535 dns_fixedname_init(&fixed);
7536 name = dns_fixedname_name(&fixed);
7537 dns_fixedname_init(&nextfixed);
7538 nextname = dns_fixedname_name(&nextfixed);
7539 dns_diff_init(zone->mctx, &_sig_diff);
7540 dns_diff_init(zone->mctx, &post_diff);
7541 zonediff_init(&zonediff, &_sig_diff);
7542 ISC_LIST_INIT(cleanup);
7543
7544 /*
7545 * Updates are disabled. Pause for 5 minutes.
7546 */
7547 if (zone->update_disabled) {
7548 result = ISC_R_FAILURE;
7549 goto failure;
7550 }
7551
7552 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
7553 if (zone->db != NULL)
7554 dns_db_attach(zone->db, &db);
7555 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
7556 if (db == NULL) {
7557 result = ISC_R_FAILURE;
7558 goto failure;
7559 }
7560
7561 result = dns_db_newversion(db, &version);
7562 if (result != ISC_R_SUCCESS) {
7563 dns_zone_log(zone, ISC_LOG_ERROR,
7564 "zone_sign:dns_db_newversion -> %s",
7565 dns_result_totext(result));
7566 goto failure;
7567 }
7568
7569 result = find_zone_keys(zone, db, version, zone->mctx,
7570 DNS_MAXZONEKEYS, zone_keys, &nkeys);
7571 if (result != ISC_R_SUCCESS) {
7572 dns_zone_log(zone, ISC_LOG_ERROR,
7573 "zone_sign:find_zone_keys -> %s",
7574 dns_result_totext(result));
7575 goto failure;
7576 }
7577
7578 isc_stdtime_get(&now);
7579 inception = now - 3600; /* Allow for clock skew. */
7580 soaexpire = now + dns_zone_getsigvalidityinterval(zone);
7581
7582 /*
7583 * Spread out signatures over time if they happen to be
7584 * clumped. We don't do this for each add_sigs() call as
7585 * we still want some clustering to occur.
7586 */
7587 isc_random_get(&jitter);
7588 expire = soaexpire - jitter % 3600;
7589
7590 /*
7591 * We keep pulling nodes off each iterator in turn until
7592 * we have no more nodes to pull off or we reach the limits
7593 * for this quantum.
7594 */
7595 nodes = zone->nodes;
7596 signatures = zone->signatures;
7597 signing = ISC_LIST_HEAD(zone->signing);
7598 first = ISC_TRUE;
7599
7600 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
7601 keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
7602
7603 /* Determine which type of chain to build */
7604 CHECK(dns_private_chains(db, version, zone->privatetype,
7605 &build_nsec, &build_nsec3));
7606
7607 /* If neither chain is found, default to NSEC */
7608 if (!build_nsec && !build_nsec3)
7609 build_nsec = ISC_TRUE;
7610
7611 while (signing != NULL && nodes-- > 0 && signatures > 0) {
7612 nextsigning = ISC_LIST_NEXT(signing, link);
7613
7614 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
7615 if (signing->done || signing->db != zone->db) {
7616 /*
7617 * The zone has been reloaded. We will have
7618 * created new signings as part of the reload
7619 * process so we can destroy this one.
7620 */
7621 ISC_LIST_UNLINK(zone->signing, signing, link);
7622 ISC_LIST_APPEND(cleanup, signing, link);
7623 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
7624 goto next_signing;
7625 }
7626 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
7627
7628 if (signing->db != db)
7629 goto next_signing;
7630
7631 delegation = ISC_FALSE;
7632
7633 if (first && signing->delete) {
7634 /*
7635 * Remove the key we are deleting from consideration.
7636 */
7637 for (i = 0, j = 0; i < nkeys; i++) {
7638 /*
7639 * Find the key we want to remove.
7640 */
7641 if (ALG(zone_keys[i]) == signing->algorithm &&
7642 dst_key_id(zone_keys[i]) == signing->keyid)
7643 {
7644 if (KSK(zone_keys[i]))
7645 dst_key_free(&zone_keys[i]);
7646 continue;
7647 }
7648 zone_keys[j] = zone_keys[i];
7649 j++;
7650 }
7651 nkeys = j;
7652 }
7653
7654 dns_dbiterator_current(signing->dbiterator, &node, name);
7655
7656 if (signing->delete) {
7657 dns_dbiterator_pause(signing->dbiterator);
7658 CHECK(del_sig(db, version, name, node, nkeys,
7659 signing->algorithm, signing->keyid,
7660 zonediff.diff));
7661 }
7662
7663 /*
7664 * On the first pass we need to check if the current node
7665 * has not been obscured.
7666 */
7667 if (first) {
7668 dns_fixedname_t ffound;
7669 dns_name_t *found;
7670 dns_fixedname_init(&ffound);
7671 found = dns_fixedname_name(&ffound);
7672 result = dns_db_find(db, name, version,
7673 dns_rdatatype_soa,
7674 DNS_DBFIND_NOWILD, 0, NULL, found,
7675 NULL, NULL);
7676 if ((result == DNS_R_DELEGATION ||
7677 result == DNS_R_DNAME) &&
7678 !dns_name_equal(name, found)) {
7679 /*
7680 * Remember the obscuring name so that
7681 * we skip all obscured names.
7682 */
7683 dns_name_copy(found, name, NULL);
7684 delegation = ISC_TRUE;
7685 goto next_node;
7686 }
7687 }
7688
7689 /*
7690 * Process one node.
7691 */
7692 dns_dbiterator_pause(signing->dbiterator);
7693 for (i = 0; i < nkeys; i++) {
7694 isc_boolean_t both = ISC_FALSE;
7695
7696 /*
7697 * Find the keys we want to sign with.
7698 */
7699 if (!dst_key_isprivate(zone_keys[i]))
7700 continue;
7701
7702 /*
7703 * When adding look for the specific key.
7704 */
7705 if (!signing->delete &&
7706 (dst_key_alg(zone_keys[i]) != signing->algorithm ||
7707 dst_key_id(zone_keys[i]) != signing->keyid))
7708 continue;
7709
7710 /*
7711 * When deleting make sure we are properly signed
7712 * with the algorithm that was being removed.
7713 */
7714 if (signing->delete &&
7715 ALG(zone_keys[i]) != signing->algorithm)
7716 continue;
7717
7718 /*
7719 * Do we do KSK processing?
7720 */
7721 if (check_ksk && !REVOKE(zone_keys[i])) {
7722 isc_boolean_t have_ksk, have_nonksk;
7723 if (KSK(zone_keys[i])) {
7724 have_ksk = ISC_TRUE;
7725 have_nonksk = ISC_FALSE;
7726 } else {
7727 have_ksk = ISC_FALSE;
7728 have_nonksk = ISC_TRUE;
7729 }
7730 for (j = 0; j < nkeys; j++) {
7731 if (j == i ||
7732 ALG(zone_keys[i]) !=
7733 ALG(zone_keys[j]))
7734 continue;
7735 if (REVOKE(zone_keys[j]))
7736 continue;
7737 if (KSK(zone_keys[j]))
7738 have_ksk = ISC_TRUE;
7739 else
7740 have_nonksk = ISC_TRUE;
7741 both = have_ksk && have_nonksk;
7742 if (both)
7743 break;
7744 }
7745 }
7746 if (both || REVOKE(zone_keys[i]))
7747 is_ksk = KSK(zone_keys[i]);
7748 else
7749 is_ksk = ISC_FALSE;
7750
7751 CHECK(sign_a_node(db, name, node, version, build_nsec3,
7752 build_nsec, zone_keys[i], inception,
7753 expire, zone->minimum, is_ksk,
7754 ISC_TF(both && keyset_kskonly),
7755 &delegation, zonediff.diff,
7756 &signatures, zone->mctx));
7757 /*
7758 * If we are adding we are done. Look for other keys
7759 * of the same algorithm if deleting.
7760 */
7761 if (!signing->delete)
7762 break;
7763 }
7764
7765 /*
7766 * Go onto next node.
7767 */
7768 next_node:
7769 first = ISC_FALSE;
7770 dns_db_detachnode(db, &node);
7771 do {
7772 result = dns_dbiterator_next(signing->dbiterator);
7773 if (result == ISC_R_NOMORE) {
7774 ISC_LIST_UNLINK(zone->signing, signing, link);
7775 ISC_LIST_APPEND(cleanup, signing, link);
7776 dns_dbiterator_pause(signing->dbiterator);
7777 if (nkeys != 0 && build_nsec) {
7778 /*
7779 * We have finished regenerating the
7780 * zone with a zone signing key.
7781 * The NSEC chain is now complete and
7782 * there is a full set of signatures
7783 * for the zone. We can now clear the
7784 * OPT bit from the NSEC record.
7785 */
7786 result = updatesecure(db, version,
7787 &zone->origin,
7788 zone->minimum,
7789 ISC_FALSE,
7790 &post_diff);
7791 if (result != ISC_R_SUCCESS) {
7792 dns_zone_log(zone,
7793 ISC_LOG_ERROR,
7794 "updatesecure -> %s",
7795 dns_result_totext(result));
7796 goto failure;
7797 }
7798 }
7799 result = updatesignwithkey(zone, signing,
7800 version,
7801 build_nsec3,
7802 zone->minimum,
7803 &post_diff);
7804 if (result != ISC_R_SUCCESS) {
7805 dns_zone_log(zone, ISC_LOG_ERROR,
7806 "updatesignwithkey -> %s",
7807 dns_result_totext(result));
7808 goto failure;
7809 }
7810 build_nsec = ISC_FALSE;
7811 goto next_signing;
7812 } else if (result != ISC_R_SUCCESS) {
7813 dns_zone_log(zone, ISC_LOG_ERROR,
7814 "zone_sign:dns_dbiterator_next -> %s",
7815 dns_result_totext(result));
7816 goto failure;
7817 } else if (delegation) {
7818 dns_dbiterator_current(signing->dbiterator,
7819 &node, nextname);
7820 dns_db_detachnode(db, &node);
7821 if (!dns_name_issubdomain(nextname, name))
7822 break;
7823 } else
7824 break;
7825 } while (1);
7826 continue;
7827
7828 next_signing:
7829 dns_dbiterator_pause(signing->dbiterator);
7830 signing = nextsigning;
7831 first = ISC_TRUE;
7832 }
7833
7834 if (ISC_LIST_HEAD(post_diff.tuples) != NULL) {
7835 result = update_sigs(&post_diff, db, version, zone_keys,
7836 nkeys, zone, inception, expire, now,
7837 check_ksk, keyset_kskonly, &zonediff);
7838 if (result != ISC_R_SUCCESS) {
7839 dns_zone_log(zone, ISC_LOG_ERROR, "zone_sign:"
7840 "update_sigs -> %s",
7841 dns_result_totext(result));
7842 goto failure;
7843 }
7844 }
7845
7846 /*
7847 * Have we changed anything?
7848 */
7849 if (ISC_LIST_EMPTY(zonediff.diff->tuples)) {
7850 if (zonediff.offline)
7851 commit = ISC_TRUE;
7852 result = ISC_R_SUCCESS;
7853 goto pauseall;
7854 }
7855
7856 commit = ISC_TRUE;
7857
7858 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
7859 &zonediff, zone_keys, nkeys, now, ISC_FALSE);
7860 if (result != ISC_R_SUCCESS) {
7861 dns_zone_log(zone, ISC_LOG_ERROR,
7862 "zone_sign:del_sigs -> %s",
7863 dns_result_totext(result));
7864 goto failure;
7865 }
7866
7867 result = update_soa_serial(db, version, zonediff.diff, zone->mctx,
7868 zone->updatemethod);
7869 if (result != ISC_R_SUCCESS) {
7870 dns_zone_log(zone, ISC_LOG_ERROR,
7871 "zone_sign:update_soa_serial -> %s",
7872 dns_result_totext(result));
7873 goto failure;
7874 }
7875
7876 /*
7877 * Generate maximum life time signatures so that the above loop
7878 * termination is sensible.
7879 */
7880 result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa,
7881 zonediff.diff, zone_keys, nkeys, zone->mctx,
7882 inception, soaexpire, check_ksk, keyset_kskonly);
7883 if (result != ISC_R_SUCCESS) {
7884 dns_zone_log(zone, ISC_LOG_ERROR,
7885 "zone_sign:add_sigs -> %s",
7886 dns_result_totext(result));
7887 goto failure;
7888 }
7889
7890 /*
7891 * Write changes to journal file.
7892 */
7893 CHECK(zone_journal(zone, zonediff.diff, NULL, "zone_sign"));
7894
7895 pauseall:
7896 /*
7897 * Pause all iterators so that dns_db_closeversion() can succeed.
7898 */
7899 for (signing = ISC_LIST_HEAD(zone->signing);
7900 signing != NULL;
7901 signing = ISC_LIST_NEXT(signing, link))
7902 dns_dbiterator_pause(signing->dbiterator);
7903
7904 for (signing = ISC_LIST_HEAD(cleanup);
7905 signing != NULL;
7906 signing = ISC_LIST_NEXT(signing, link))
7907 dns_dbiterator_pause(signing->dbiterator);
7908
7909 /*
7910 * Everything has succeeded. Commit the changes.
7911 */
7912 dns_db_closeversion(db, &version, commit);
7913
7914 /*
7915 * Everything succeeded so we can clean these up now.
7916 */
7917 signing = ISC_LIST_HEAD(cleanup);
7918 while (signing != NULL) {
7919 ISC_LIST_UNLINK(cleanup, signing, link);
7920 dns_db_detach(&signing->db);
7921 dns_dbiterator_destroy(&signing->dbiterator);
7922 isc_mem_put(zone->mctx, signing, sizeof *signing);
7923 signing = ISC_LIST_HEAD(cleanup);
7924 }
7925
7926 set_resigntime(zone);
7927
7928 if (commit) {
7929 LOCK_ZONE(zone);
7930 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
7931 zone_needdump(zone, DNS_DUMP_DELAY);
7932 UNLOCK_ZONE(zone);
7933 }
7934
7935 failure:
7936 /*
7937 * Rollback the cleanup list.
7938 */
7939 signing = ISC_LIST_HEAD(cleanup);
7940 while (signing != NULL) {
7941 ISC_LIST_UNLINK(cleanup, signing, link);
7942 ISC_LIST_PREPEND(zone->signing, signing, link);
7943 dns_dbiterator_first(signing->dbiterator);
7944 dns_dbiterator_pause(signing->dbiterator);
7945 signing = ISC_LIST_HEAD(cleanup);
7946 }
7947
7948 for (signing = ISC_LIST_HEAD(zone->signing);
7949 signing != NULL;
7950 signing = ISC_LIST_NEXT(signing, link))
7951 dns_dbiterator_pause(signing->dbiterator);
7952
7953 dns_diff_clear(&_sig_diff);
7954
7955 for (i = 0; i < nkeys; i++)
7956 dst_key_free(&zone_keys[i]);
7957
7958 if (node != NULL)
7959 dns_db_detachnode(db, &node);
7960
7961 if (version != NULL) {
7962 dns_db_closeversion(db, &version, ISC_FALSE);
7963 dns_db_detach(&db);
7964 } else if (db != NULL)
7965 dns_db_detach(&db);
7966
7967 if (ISC_LIST_HEAD(zone->signing) != NULL) {
7968 isc_interval_t interval;
7969 if (zone->update_disabled || result != ISC_R_SUCCESS)
7970 isc_interval_set(&interval, 60, 0); /* 1 minute */
7971 else
7972 isc_interval_set(&interval, 0, 10000000); /* 10 ms */
7973 isc_time_nowplusinterval(&zone->signingtime, &interval);
7974 } else
7975 isc_time_settoepoch(&zone->signingtime);
7976
7977 INSIST(version == NULL);
7978 }
7979
7980 static isc_result_t
normalize_key(dns_rdata_t * rr,dns_rdata_t * target,unsigned char * data,int size)7981 normalize_key(dns_rdata_t *rr, dns_rdata_t *target,
7982 unsigned char *data, int size)
7983 {
7984 dns_rdata_dnskey_t dnskey;
7985 dns_rdata_keydata_t keydata;
7986 isc_buffer_t buf;
7987 isc_result_t result;
7988
7989 dns_rdata_reset(target);
7990 isc_buffer_init(&buf, data, size);
7991
7992 switch (rr->type) {
7993 case dns_rdatatype_dnskey:
7994 result = dns_rdata_tostruct(rr, &dnskey, NULL);
7995 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7996 dnskey.flags &= ~DNS_KEYFLAG_REVOKE;
7997 dns_rdata_fromstruct(target, rr->rdclass, dns_rdatatype_dnskey,
7998 &dnskey, &buf);
7999 break;
8000 case dns_rdatatype_keydata:
8001 result = dns_rdata_tostruct(rr, &keydata, NULL);
8002 if (result == ISC_R_UNEXPECTEDEND)
8003 return (result);
8004 RUNTIME_CHECK(result == ISC_R_SUCCESS);
8005 dns_keydata_todnskey(&keydata, &dnskey, NULL);
8006 dns_rdata_fromstruct(target, rr->rdclass, dns_rdatatype_dnskey,
8007 &dnskey, &buf);
8008 break;
8009 default:
8010 INSIST(0);
8011 }
8012 return (ISC_R_SUCCESS);
8013 }
8014
8015 /*
8016 * 'rdset' contains either a DNSKEY rdataset from the zone apex, or
8017 * a KEYDATA rdataset from the key zone.
8018 *
8019 * 'rr' contains either a DNSKEY record, or a KEYDATA record
8020 *
8021 * After normalizing keys to the same format (DNSKEY, with revoke bit
8022 * cleared), return ISC_TRUE if a key that matches 'rr' is found in
8023 * 'rdset', or ISC_FALSE if not.
8024 */
8025
8026 static isc_boolean_t
matchkey(dns_rdataset_t * rdset,dns_rdata_t * rr)8027 matchkey(dns_rdataset_t *rdset, dns_rdata_t *rr) {
8028 unsigned char data1[4096], data2[4096];
8029 dns_rdata_t rdata, rdata1, rdata2;
8030 isc_result_t result;
8031
8032 dns_rdata_init(&rdata);
8033 dns_rdata_init(&rdata1);
8034 dns_rdata_init(&rdata2);
8035
8036 result = normalize_key(rr, &rdata1, data1, sizeof(data1));
8037 if (result != ISC_R_SUCCESS)
8038 return (ISC_FALSE);
8039
8040 for (result = dns_rdataset_first(rdset);
8041 result == ISC_R_SUCCESS;
8042 result = dns_rdataset_next(rdset)) {
8043 dns_rdata_reset(&rdata);
8044 dns_rdataset_current(rdset, &rdata);
8045 result = normalize_key(&rdata, &rdata2, data2, sizeof(data2));
8046 if (result != ISC_R_SUCCESS)
8047 continue;
8048 if (dns_rdata_compare(&rdata1, &rdata2) == 0)
8049 return (ISC_TRUE);
8050 }
8051
8052 return (ISC_FALSE);
8053 }
8054
8055 /*
8056 * Calculate the refresh interval for a keydata zone, per
8057 * RFC5011: MAX(1 hr,
8058 * MIN(15 days,
8059 * 1/2 * OrigTTL,
8060 * 1/2 * RRSigExpirationInterval))
8061 * or for retries: MAX(1 hr,
8062 * MIN(1 day,
8063 * 1/10 * OrigTTL,
8064 * 1/10 * RRSigExpirationInterval))
8065 */
8066 static inline isc_stdtime_t
refresh_time(dns_keyfetch_t * kfetch,isc_boolean_t retry)8067 refresh_time(dns_keyfetch_t *kfetch, isc_boolean_t retry) {
8068 isc_result_t result;
8069 isc_uint32_t t;
8070 dns_rdataset_t *rdset;
8071 dns_rdata_t sigrr = DNS_RDATA_INIT;
8072 dns_rdata_sig_t sig;
8073 isc_stdtime_t now;
8074
8075 isc_stdtime_get(&now);
8076
8077 if (dns_rdataset_isassociated(&kfetch->dnskeysigset))
8078 rdset = &kfetch->dnskeysigset;
8079 else
8080 return (now + dns_zone_mkey_hour);
8081
8082 result = dns_rdataset_first(rdset);
8083 if (result != ISC_R_SUCCESS)
8084 return (now + dns_zone_mkey_hour);
8085
8086 dns_rdataset_current(rdset, &sigrr);
8087 result = dns_rdata_tostruct(&sigrr, &sig, NULL);
8088 RUNTIME_CHECK(result == ISC_R_SUCCESS);
8089
8090 if (!retry) {
8091 t = sig.originalttl / 2;
8092
8093 if (isc_serial_gt(sig.timeexpire, now)) {
8094 isc_uint32_t exp = (sig.timeexpire - now) / 2;
8095 if (t > exp)
8096 t = exp;
8097 }
8098
8099 if (t > (15 * dns_zone_mkey_day))
8100 t = (15 * dns_zone_mkey_day);
8101
8102 if (t < dns_zone_mkey_hour)
8103 t = dns_zone_mkey_hour;
8104 } else {
8105 t = sig.originalttl / 10;
8106
8107 if (isc_serial_gt(sig.timeexpire, now)) {
8108 isc_uint32_t exp = (sig.timeexpire - now) / 10;
8109 if (t > exp)
8110 t = exp;
8111 }
8112
8113 if (t > dns_zone_mkey_day)
8114 t = dns_zone_mkey_day;
8115
8116 if (t < dns_zone_mkey_hour)
8117 t = dns_zone_mkey_hour;
8118 }
8119
8120 return (now + t);
8121 }
8122
8123 /*
8124 * This routine is called when no changes are needed in a KEYDATA
8125 * record except to simply update the refresh timer. Caller should
8126 * hold zone lock.
8127 */
8128 static isc_result_t
minimal_update(dns_keyfetch_t * kfetch,dns_dbversion_t * ver,dns_diff_t * diff)8129 minimal_update(dns_keyfetch_t *kfetch, dns_dbversion_t *ver, dns_diff_t *diff)
8130 {
8131 isc_result_t result;
8132 isc_buffer_t keyb;
8133 unsigned char key_buf[4096];
8134 dns_rdata_t rdata = DNS_RDATA_INIT;
8135 dns_rdata_keydata_t keydata;
8136 dns_name_t *name;
8137 dns_zone_t *zone = kfetch->zone;
8138 isc_stdtime_t now;
8139
8140 name = dns_fixedname_name(&kfetch->name);
8141 isc_stdtime_get(&now);
8142
8143 for (result = dns_rdataset_first(&kfetch->keydataset);
8144 result == ISC_R_SUCCESS;
8145 result = dns_rdataset_next(&kfetch->keydataset)) {
8146 dns_rdata_reset(&rdata);
8147 dns_rdataset_current(&kfetch->keydataset, &rdata);
8148
8149 /* Delete old version */
8150 CHECK(update_one_rr(kfetch->db, ver, diff, DNS_DIFFOP_DEL,
8151 name, 0, &rdata));
8152
8153 /* Update refresh timer */
8154 result = dns_rdata_tostruct(&rdata, &keydata, NULL);
8155 if (result == ISC_R_UNEXPECTEDEND)
8156 continue;
8157 if (result != ISC_R_SUCCESS)
8158 goto failure;
8159 keydata.refresh = refresh_time(kfetch, ISC_TRUE);
8160 set_refreshkeytimer(zone, &keydata, now, ISC_FALSE);
8161
8162 dns_rdata_reset(&rdata);
8163 isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
8164 CHECK(dns_rdata_fromstruct(&rdata,
8165 zone->rdclass, dns_rdatatype_keydata,
8166 &keydata, &keyb));
8167
8168 /* Insert updated version */
8169 CHECK(update_one_rr(kfetch->db, ver, diff, DNS_DIFFOP_ADD,
8170 name, 0, &rdata));
8171 }
8172 result = ISC_R_SUCCESS;
8173 failure:
8174 return (result);
8175 }
8176
8177 /*
8178 * Verify that DNSKEY set is signed by the key specified in 'keydata'.
8179 */
8180 static isc_boolean_t
revocable(dns_keyfetch_t * kfetch,dns_rdata_keydata_t * keydata)8181 revocable(dns_keyfetch_t *kfetch, dns_rdata_keydata_t *keydata) {
8182 isc_result_t result;
8183 dns_name_t *keyname;
8184 isc_mem_t *mctx;
8185 dns_rdata_t sigrr = DNS_RDATA_INIT;
8186 dns_rdata_t rr = DNS_RDATA_INIT;
8187 dns_rdata_rrsig_t sig;
8188 dns_rdata_dnskey_t dnskey;
8189 dst_key_t *dstkey = NULL;
8190 unsigned char key_buf[4096];
8191 isc_buffer_t keyb;
8192 isc_boolean_t answer = ISC_FALSE;
8193
8194 REQUIRE(kfetch != NULL && keydata != NULL);
8195 REQUIRE(dns_rdataset_isassociated(&kfetch->dnskeysigset));
8196
8197 keyname = dns_fixedname_name(&kfetch->name);
8198 mctx = kfetch->zone->view->mctx;
8199
8200 /* Generate a key from keydata */
8201 isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
8202 dns_keydata_todnskey(keydata, &dnskey, NULL);
8203 dns_rdata_fromstruct(&rr, keydata->common.rdclass,
8204 dns_rdatatype_dnskey, &dnskey, &keyb);
8205 result = dns_dnssec_keyfromrdata(keyname, &rr, mctx, &dstkey);
8206 if (result != ISC_R_SUCCESS)
8207 return (ISC_FALSE);
8208
8209 /* See if that key generated any of the signatures */
8210 for (result = dns_rdataset_first(&kfetch->dnskeysigset);
8211 result == ISC_R_SUCCESS;
8212 result = dns_rdataset_next(&kfetch->dnskeysigset))
8213 {
8214 dns_fixedname_t fixed;
8215 dns_fixedname_init(&fixed);
8216
8217 dns_rdata_reset(&sigrr);
8218 dns_rdataset_current(&kfetch->dnskeysigset, &sigrr);
8219 result = dns_rdata_tostruct(&sigrr, &sig, NULL);
8220 RUNTIME_CHECK(result == ISC_R_SUCCESS);
8221
8222 if (dst_key_alg(dstkey) == sig.algorithm &&
8223 dst_key_rid(dstkey) == sig.keyid)
8224 {
8225 result = dns_dnssec_verify2(keyname,
8226 &kfetch->dnskeyset,
8227 dstkey, ISC_FALSE, mctx, &sigrr,
8228 dns_fixedname_name(&fixed));
8229
8230 dns_zone_log(kfetch->zone, ISC_LOG_DEBUG(3),
8231 "Confirm revoked DNSKEY is self-signed: "
8232 "%s", dns_result_totext(result));
8233
8234 if (result == ISC_R_SUCCESS) {
8235 answer = ISC_TRUE;
8236 break;
8237 }
8238 }
8239 }
8240
8241 dst_key_free(&dstkey);
8242 return (answer);
8243 }
8244
8245 /*
8246 * A DNSKEY set has been fetched from the zone apex of a zone whose trust
8247 * anchors are being managed; scan the keyset, and update the key zone and the
8248 * local trust anchors according to RFC5011.
8249 */
8250 static void
keyfetch_done(isc_task_t * task,isc_event_t * event)8251 keyfetch_done(isc_task_t *task, isc_event_t *event) {
8252 isc_result_t result, eresult;
8253 dns_fetchevent_t *devent;
8254 dns_keyfetch_t *kfetch;
8255 dns_zone_t *zone;
8256 isc_mem_t *mctx = NULL;
8257 dns_keytable_t *secroots = NULL;
8258 dns_dbversion_t *ver = NULL;
8259 dns_diff_t diff;
8260 isc_boolean_t alldone = ISC_FALSE;
8261 isc_boolean_t commit = ISC_FALSE;
8262 dns_name_t *keyname;
8263 dns_rdata_t sigrr = DNS_RDATA_INIT;
8264 dns_rdata_t dnskeyrr = DNS_RDATA_INIT;
8265 dns_rdata_t keydatarr = DNS_RDATA_INIT;
8266 dns_rdata_rrsig_t sig;
8267 dns_rdata_dnskey_t dnskey;
8268 dns_rdata_keydata_t keydata;
8269 isc_boolean_t initializing;
8270 char namebuf[DNS_NAME_FORMATSIZE];
8271 unsigned char key_buf[4096];
8272 isc_buffer_t keyb;
8273 dst_key_t *dstkey;
8274 isc_stdtime_t now;
8275 int pending = 0;
8276 isc_boolean_t secure;
8277 isc_boolean_t free_needed;
8278
8279 UNUSED(task);
8280 INSIST(event != NULL && event->ev_type == DNS_EVENT_FETCHDONE);
8281 INSIST(event->ev_arg != NULL);
8282
8283 kfetch = event->ev_arg;
8284 zone = kfetch->zone;
8285 isc_mem_attach(zone->mctx, &mctx);
8286 keyname = dns_fixedname_name(&kfetch->name);
8287
8288 devent = (dns_fetchevent_t *) event;
8289 eresult = devent->result;
8290
8291 /* Free resources which are not of interest */
8292 if (devent->node != NULL)
8293 dns_db_detachnode(devent->db, &devent->node);
8294 if (devent->db != NULL)
8295 dns_db_detach(&devent->db);
8296 isc_event_free(&event);
8297 dns_resolver_destroyfetch(&kfetch->fetch);
8298
8299 LOCK_ZONE(zone);
8300 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) || zone->view == NULL)
8301 goto cleanup;
8302
8303 isc_stdtime_get(&now);
8304 dns_name_format(keyname, namebuf, sizeof(namebuf));
8305
8306 result = dns_view_getsecroots(zone->view, &secroots);
8307 INSIST(result == ISC_R_SUCCESS);
8308
8309 dns_diff_init(mctx, &diff);
8310
8311 CHECK(dns_db_newversion(kfetch->db, &ver));
8312
8313 zone->refreshkeycount--;
8314 alldone = ISC_TF(zone->refreshkeycount == 0);
8315
8316 if (alldone)
8317 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESHING);
8318
8319 /* Fetch failed */
8320 if (eresult != ISC_R_SUCCESS ||
8321 !dns_rdataset_isassociated(&kfetch->dnskeyset)) {
8322 dns_zone_log(zone, ISC_LOG_WARNING,
8323 "Unable to fetch DNSKEY set "
8324 "'%s': %s", namebuf, dns_result_totext(eresult));
8325 CHECK(minimal_update(kfetch, ver, &diff));
8326 goto done;
8327 }
8328
8329 /* No RRSIGs found */
8330 if (!dns_rdataset_isassociated(&kfetch->dnskeysigset)) {
8331 dns_zone_log(zone, ISC_LOG_WARNING,
8332 "No DNSKEY RRSIGs found for "
8333 "'%s': %s", namebuf, dns_result_totext(eresult));
8334 CHECK(minimal_update(kfetch, ver, &diff));
8335 goto done;
8336 }
8337
8338 /*
8339 * Clear any cached trust level, as we need to run validation
8340 * over again; trusted keys might have changed.
8341 */
8342 kfetch->dnskeyset.trust = kfetch->dnskeysigset.trust = dns_trust_none;
8343
8344 /*
8345 * Validate the dnskeyset against the current trusted keys.
8346 */
8347 for (result = dns_rdataset_first(&kfetch->dnskeysigset);
8348 result == ISC_R_SUCCESS;
8349 result = dns_rdataset_next(&kfetch->dnskeysigset)) {
8350 dns_keynode_t *keynode = NULL;
8351
8352 dns_rdata_reset(&sigrr);
8353 dns_rdataset_current(&kfetch->dnskeysigset, &sigrr);
8354 result = dns_rdata_tostruct(&sigrr, &sig, NULL);
8355 RUNTIME_CHECK(result == ISC_R_SUCCESS);
8356
8357 result = dns_keytable_find(secroots, keyname, &keynode);
8358 while (result == ISC_R_SUCCESS) {
8359 dns_keynode_t *nextnode = NULL;
8360 dns_fixedname_t fixed;
8361 dns_fixedname_init(&fixed);
8362
8363 dstkey = dns_keynode_key(keynode);
8364 if (dstkey == NULL) /* fail_secure() was called */
8365 break;
8366
8367 if (dst_key_alg(dstkey) == sig.algorithm &&
8368 dst_key_id(dstkey) == sig.keyid) {
8369 result = dns_dnssec_verify2(keyname,
8370 &kfetch->dnskeyset,
8371 dstkey, ISC_FALSE,
8372 zone->view->mctx, &sigrr,
8373 dns_fixedname_name(&fixed));
8374
8375 dns_zone_log(zone, ISC_LOG_DEBUG(3),
8376 "Verifying DNSKEY set for zone "
8377 "'%s' using key %d/%d: %s",
8378 namebuf, sig.keyid, sig.algorithm,
8379 dns_result_totext(result));
8380
8381 if (result == ISC_R_SUCCESS) {
8382 kfetch->dnskeyset.trust =
8383 dns_trust_secure;
8384 kfetch->dnskeysigset.trust =
8385 dns_trust_secure;
8386 break;
8387 }
8388 }
8389
8390 result = dns_keytable_nextkeynode(secroots,
8391 keynode, &nextnode);
8392 dns_keytable_detachkeynode(secroots, &keynode);
8393 keynode = nextnode;
8394 }
8395
8396 if (keynode != NULL)
8397 dns_keytable_detachkeynode(secroots, &keynode);
8398
8399 if (kfetch->dnskeyset.trust == dns_trust_secure)
8400 break;
8401 }
8402
8403 /*
8404 * If we were not able to verify the answer using the current
8405 * trusted keys then all we can do is look at any revoked keys.
8406 */
8407 secure = ISC_TF(kfetch->dnskeyset.trust == dns_trust_secure);
8408
8409 /*
8410 * First scan keydataset to find keys that are not in dnskeyset
8411 * - Missing keys which are not scheduled for removal,
8412 * log a warning
8413 * - Missing keys which are scheduled for removal and
8414 * the remove hold-down timer has completed should
8415 * be removed from the key zone
8416 * - Missing keys whose acceptance timers have not yet
8417 * completed, log a warning and reset the acceptance
8418 * timer to 30 days in the future
8419 * - All keys not being removed have their refresh timers
8420 * updated
8421 */
8422 initializing = ISC_TRUE;
8423 for (result = dns_rdataset_first(&kfetch->keydataset);
8424 result == ISC_R_SUCCESS;
8425 result = dns_rdataset_next(&kfetch->keydataset)) {
8426 dns_rdata_reset(&keydatarr);
8427 dns_rdataset_current(&kfetch->keydataset, &keydatarr);
8428 result = dns_rdata_tostruct(&keydatarr, &keydata, NULL);
8429 RUNTIME_CHECK(result == ISC_R_SUCCESS);
8430
8431 /*
8432 * If any keydata record has a nonzero add holddown, then
8433 * there was a pre-existing trust anchor for this domain;
8434 * that means we are *not* initializing it and shouldn't
8435 * automatically trust all the keys we find at the zone apex.
8436 */
8437 initializing = initializing && ISC_TF(keydata.addhd == 0);
8438
8439 if (! matchkey(&kfetch->dnskeyset, &keydatarr)) {
8440 isc_boolean_t deletekey = ISC_FALSE;
8441
8442 if (!secure) {
8443 if (keydata.removehd != 0 &&
8444 keydata.removehd <= now)
8445 deletekey = ISC_TRUE;
8446 } else if (keydata.addhd == 0) {
8447 deletekey = ISC_TRUE;
8448 } else if (keydata.addhd > now) {
8449 dns_zone_log(zone, ISC_LOG_WARNING,
8450 "Pending key unexpectedly missing "
8451 "from %s; restarting acceptance "
8452 "timer", namebuf);
8453 if (keydata.addhd < now + dns_zone_mkey_month)
8454 keydata.addhd =
8455 now + dns_zone_mkey_month;
8456 keydata.refresh = refresh_time(kfetch,
8457 ISC_FALSE);
8458 } else if (keydata.removehd == 0) {
8459 dns_zone_log(zone, ISC_LOG_WARNING,
8460 "Active key unexpectedly missing "
8461 "from %s", namebuf);
8462 keydata.refresh = now + dns_zone_mkey_hour;
8463 } else if (keydata.removehd <= now) {
8464 deletekey = ISC_TRUE;
8465 } else {
8466 keydata.refresh = refresh_time(kfetch,
8467 ISC_FALSE);
8468 }
8469
8470 if (secure || deletekey) {
8471 /* Delete old version */
8472 CHECK(update_one_rr(kfetch->db, ver, &diff,
8473 DNS_DIFFOP_DEL, keyname, 0,
8474 &keydatarr));
8475 }
8476
8477 if (!secure || deletekey)
8478 continue;
8479
8480 dns_rdata_reset(&keydatarr);
8481 isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
8482 dns_rdata_fromstruct(&keydatarr, zone->rdclass,
8483 dns_rdatatype_keydata,
8484 &keydata, &keyb);
8485
8486 /* Insert updated version */
8487 CHECK(update_one_rr(kfetch->db, ver, &diff,
8488 DNS_DIFFOP_ADD, keyname, 0,
8489 &keydatarr));
8490
8491 set_refreshkeytimer(zone, &keydata, now, ISC_FALSE);
8492 }
8493 }
8494
8495 /*
8496 * Next scan dnskeyset:
8497 * - If new keys are found (i.e., lacking a match in keydataset)
8498 * add them to the key zone and set the acceptance timer
8499 * to 30 days in the future (or to immediately if we've
8500 * determined that we're initializing the zone for the
8501 * first time)
8502 * - Previously-known keys that have been revoked
8503 * must be scheduled for removal from the key zone (or,
8504 * if they hadn't been accepted as trust anchors yet
8505 * anyway, removed at once)
8506 * - Previously-known unrevoked keys whose acceptance timers
8507 * have completed are promoted to trust anchors
8508 * - All keys not being removed have their refresh
8509 * timers updated
8510 */
8511 for (result = dns_rdataset_first(&kfetch->dnskeyset);
8512 result == ISC_R_SUCCESS;
8513 result = dns_rdataset_next(&kfetch->dnskeyset))
8514 {
8515 isc_boolean_t revoked = ISC_FALSE;
8516 isc_boolean_t newkey = ISC_FALSE;
8517 isc_boolean_t updatekey = ISC_FALSE;
8518 isc_boolean_t deletekey = ISC_FALSE;
8519 isc_boolean_t trustkey = ISC_FALSE;
8520
8521 dns_rdata_reset(&dnskeyrr);
8522 dns_rdataset_current(&kfetch->dnskeyset, &dnskeyrr);
8523 result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
8524 RUNTIME_CHECK(result == ISC_R_SUCCESS);
8525
8526 /* Skip ZSK's */
8527 if (!ISC_TF(dnskey.flags & DNS_KEYFLAG_KSK))
8528 continue;
8529
8530 revoked = ISC_TF(dnskey.flags & DNS_KEYFLAG_REVOKE);
8531
8532 if (matchkey(&kfetch->keydataset, &dnskeyrr)) {
8533 dns_rdata_reset(&keydatarr);
8534 dns_rdataset_current(&kfetch->keydataset, &keydatarr);
8535 result = dns_rdata_tostruct(&keydatarr, &keydata, NULL);
8536 RUNTIME_CHECK(result == ISC_R_SUCCESS);
8537
8538 if (revoked && revocable(kfetch, &keydata)) {
8539 if (keydata.addhd > now) {
8540 /*
8541 * Key wasn't trusted yet, and now
8542 * it's been revoked? Just remove it
8543 */
8544 deletekey = ISC_TRUE;
8545 } else if (keydata.removehd == 0) {
8546 /*
8547 * Remove key from secroots.
8548 */
8549 dns_view_untrust(zone->view, keyname,
8550 &dnskey, mctx);
8551
8552 /* If initializing, delete now */
8553 if (keydata.addhd == 0)
8554 deletekey = ISC_TRUE;
8555 else {
8556 keydata.removehd = now +
8557 dns_zone_mkey_month;
8558 keydata.flags |=
8559 DNS_KEYFLAG_REVOKE;
8560 }
8561 } else if (keydata.removehd < now) {
8562 /* Scheduled for removal */
8563 deletekey = ISC_TRUE;
8564 }
8565 } else if (revoked && keydata.removehd == 0) {
8566 dns_zone_log(zone, ISC_LOG_WARNING,
8567 "Active key for zone "
8568 "'%s' is revoked but "
8569 "did not self-sign; "
8570 "ignoring.", namebuf);
8571 continue;
8572 } else if (secure) {
8573 if (keydata.removehd != 0) {
8574 /*
8575 * Key isn't revoked--but it
8576 * seems it used to be.
8577 * Remove it now and add it
8578 * back as if it were a fresh key,
8579 * with a 30 day acceptance timer.
8580 */
8581 deletekey = ISC_TRUE;
8582 newkey = ISC_TRUE;
8583 keydata.removehd = 0;
8584 keydata.addhd =
8585 now + dns_zone_mkey_month;
8586 } else if (keydata.addhd > now)
8587 pending++;
8588 else if (keydata.addhd == 0)
8589 keydata.addhd = now;
8590
8591 if (keydata.addhd <= now)
8592 trustkey = ISC_TRUE;
8593 } else if (keydata.addhd > now) {
8594 /*
8595 * Not secure, and key is pending:
8596 * reset the acceptance timer
8597 */
8598 pending++;
8599 keydata.addhd = now + dns_zone_mkey_month;
8600 }
8601
8602 if (!deletekey && !newkey)
8603 updatekey = ISC_TRUE;
8604 } else if (secure) {
8605 /*
8606 * Key wasn't in the key zone but it's
8607 * revoked now anyway, so just skip it
8608 */
8609 if (revoked)
8610 continue;
8611
8612 /* Key wasn't in the key zone: add it */
8613 newkey = ISC_TRUE;
8614
8615 if (initializing) {
8616 dns_keytag_t tag = 0;
8617 CHECK(compute_tag(keyname, &dnskey,
8618 mctx, &tag));
8619 dns_zone_log(zone, ISC_LOG_WARNING,
8620 "Initializing automatic trust "
8621 "anchor management for zone '%s'; "
8622 "DNSKEY ID %d is now trusted, "
8623 "waiving the normal 30-day "
8624 "waiting period.",
8625 namebuf, tag);
8626 trustkey = ISC_TRUE;
8627 }
8628 } else {
8629 /*
8630 * No previously known key, and the key is not
8631 * secure, so skip it.
8632 */
8633 continue;
8634 }
8635
8636 /* Delete old version */
8637 if (deletekey || !newkey)
8638 CHECK(update_one_rr(kfetch->db, ver, &diff,
8639 DNS_DIFFOP_DEL, keyname, 0,
8640 &keydatarr));
8641
8642 if (updatekey) {
8643 /* Set refresh timer */
8644 keydata.refresh = refresh_time(kfetch, ISC_FALSE);
8645 dns_rdata_reset(&keydatarr);
8646 isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
8647 dns_rdata_fromstruct(&keydatarr, zone->rdclass,
8648 dns_rdatatype_keydata,
8649 &keydata, &keyb);
8650
8651 /* Insert updated version */
8652 CHECK(update_one_rr(kfetch->db, ver, &diff,
8653 DNS_DIFFOP_ADD, keyname, 0,
8654 &keydatarr));
8655 } else if (newkey) {
8656 /* Convert DNSKEY to KEYDATA */
8657 result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
8658 RUNTIME_CHECK(result == ISC_R_SUCCESS);
8659 dns_keydata_fromdnskey(&keydata, &dnskey, 0, 0, 0,
8660 NULL);
8661 keydata.addhd = initializing
8662 ? now : now + dns_zone_mkey_month;
8663 keydata.refresh = refresh_time(kfetch, ISC_FALSE);
8664 dns_rdata_reset(&keydatarr);
8665 isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
8666 dns_rdata_fromstruct(&keydatarr, zone->rdclass,
8667 dns_rdatatype_keydata,
8668 &keydata, &keyb);
8669
8670 /* Insert into key zone */
8671 CHECK(update_one_rr(kfetch->db, ver, &diff,
8672 DNS_DIFFOP_ADD, keyname, 0,
8673 &keydatarr));
8674 }
8675
8676 if (trustkey) {
8677 /* Trust this key. */
8678 result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
8679 RUNTIME_CHECK(result == ISC_R_SUCCESS);
8680 trust_key(zone, keyname, &dnskey, mctx);
8681 }
8682
8683 if (secure && !deletekey) {
8684 INSIST(newkey || updatekey);
8685 set_refreshkeytimer(zone, &keydata, now, ISC_FALSE);
8686 }
8687 }
8688
8689 /*
8690 * RFC5011 says, "A trust point that has all of its trust anchors
8691 * revoked is considered deleted and is treated as if the trust
8692 * point was never configured." But if someone revoked their
8693 * active key before the standby was trusted, that would mean the
8694 * zone would suddenly be nonsecured. We avoid this by checking to
8695 * see if there's pending keydata. If so, we put a null key in
8696 * the security roots; then all queries to the zone will fail.
8697 */
8698 if (pending != 0)
8699 fail_secure(zone, keyname);
8700
8701 done:
8702
8703 if (!ISC_LIST_EMPTY(diff.tuples)) {
8704 /* Write changes to journal file. */
8705 CHECK(update_soa_serial(kfetch->db, ver, &diff, mctx,
8706 zone->updatemethod));
8707 CHECK(zone_journal(zone, &diff, NULL, "keyfetch_done"));
8708 commit = ISC_TRUE;
8709
8710 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
8711 zone_needdump(zone, 30);
8712 }
8713
8714 failure:
8715
8716 dns_diff_clear(&diff);
8717 if (ver != NULL)
8718 dns_db_closeversion(kfetch->db, &ver, commit);
8719
8720 cleanup:
8721 dns_db_detach(&kfetch->db);
8722
8723 INSIST(zone->irefs > 0);
8724 zone->irefs--;
8725 kfetch->zone = NULL;
8726
8727 if (dns_rdataset_isassociated(&kfetch->keydataset))
8728 dns_rdataset_disassociate(&kfetch->keydataset);
8729 if (dns_rdataset_isassociated(&kfetch->dnskeyset))
8730 dns_rdataset_disassociate(&kfetch->dnskeyset);
8731 if (dns_rdataset_isassociated(&kfetch->dnskeysigset))
8732 dns_rdataset_disassociate(&kfetch->dnskeysigset);
8733
8734 dns_name_free(keyname, mctx);
8735 isc_mem_put(mctx, kfetch, sizeof(dns_keyfetch_t));
8736 isc_mem_detach(&mctx);
8737
8738 if (secroots != NULL)
8739 dns_keytable_detach(&secroots);
8740
8741 free_needed = exit_check(zone);
8742 UNLOCK_ZONE(zone);
8743 if (free_needed)
8744 zone_free(zone);
8745
8746 INSIST(ver == NULL);
8747 }
8748
8749 /*
8750 * Refresh the data in the key zone. Initiate a fetch to get new DNSKEY
8751 * records from the zone apex.
8752 */
8753 static void
zone_refreshkeys(dns_zone_t * zone)8754 zone_refreshkeys(dns_zone_t *zone) {
8755 const char me[] = "zone_refreshkeys";
8756 isc_result_t result;
8757 dns_rriterator_t rrit;
8758 dns_db_t *db = NULL;
8759 dns_dbversion_t *ver = NULL;
8760 dns_diff_t diff;
8761 dns_rdata_t rdata = DNS_RDATA_INIT;
8762 dns_rdata_keydata_t kd;
8763 isc_stdtime_t now;
8764 isc_boolean_t commit = ISC_FALSE;
8765 isc_boolean_t fetching = ISC_FALSE, fetch_err = ISC_FALSE;
8766
8767 ENTER;
8768 REQUIRE(zone->db != NULL);
8769
8770 isc_stdtime_get(&now);
8771
8772 LOCK_ZONE(zone);
8773 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
8774 isc_time_settoepoch(&zone->refreshkeytime);
8775 UNLOCK_ZONE(zone);
8776 return;
8777 }
8778
8779 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
8780 dns_db_attach(zone->db, &db);
8781 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
8782
8783 dns_diff_init(zone->mctx, &diff);
8784
8785 CHECK(dns_db_newversion(db, &ver));
8786
8787 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESHING);
8788
8789 dns_rriterator_init(&rrit, db, ver, 0);
8790 for (result = dns_rriterator_first(&rrit);
8791 result == ISC_R_SUCCESS;
8792 result = dns_rriterator_nextrrset(&rrit)) {
8793 isc_stdtime_t timer = 0xffffffff;
8794 dns_name_t *name = NULL, *kname = NULL;
8795 dns_rdataset_t *kdset = NULL;
8796 dns_keyfetch_t *kfetch;
8797 isc_uint32_t ttl;
8798
8799 dns_rriterator_current(&rrit, &name, &ttl, &kdset, NULL);
8800 if (kdset == NULL || kdset->type != dns_rdatatype_keydata ||
8801 !dns_rdataset_isassociated(kdset))
8802 continue;
8803
8804 /*
8805 * Scan the stored keys looking for ones that need
8806 * removal or refreshing
8807 */
8808 for (result = dns_rdataset_first(kdset);
8809 result == ISC_R_SUCCESS;
8810 result = dns_rdataset_next(kdset)) {
8811 dns_rdata_reset(&rdata);
8812 dns_rdataset_current(kdset, &rdata);
8813 result = dns_rdata_tostruct(&rdata, &kd, NULL);
8814 RUNTIME_CHECK(result == ISC_R_SUCCESS);
8815
8816 /* Removal timer expired? */
8817 if (kd.removehd != 0 && kd.removehd < now) {
8818 CHECK(update_one_rr(db, ver, &diff,
8819 DNS_DIFFOP_DEL, name, ttl,
8820 &rdata));
8821 continue;
8822 }
8823
8824 /* Acceptance timer expired? */
8825 if (kd.addhd != 0 && kd.addhd < now)
8826 timer = kd.addhd;
8827
8828 /* Or do we just need to refresh the keyset? */
8829 if (timer > kd.refresh)
8830 timer = kd.refresh;
8831 }
8832
8833 if (timer > now)
8834 continue;
8835
8836 kfetch = isc_mem_get(zone->mctx, sizeof(dns_keyfetch_t));
8837 if (kfetch == NULL) {
8838 fetch_err = ISC_TRUE;
8839 goto failure;
8840 }
8841
8842 zone->refreshkeycount++;
8843 kfetch->zone = zone;
8844 zone->irefs++;
8845 INSIST(zone->irefs != 0);
8846 dns_fixedname_init(&kfetch->name);
8847 kname = dns_fixedname_name(&kfetch->name);
8848 dns_name_dup(name, zone->mctx, kname);
8849 dns_rdataset_init(&kfetch->dnskeyset);
8850 dns_rdataset_init(&kfetch->dnskeysigset);
8851 dns_rdataset_init(&kfetch->keydataset);
8852 dns_rdataset_clone(kdset, &kfetch->keydataset);
8853 kfetch->db = NULL;
8854 dns_db_attach(db, &kfetch->db);
8855 kfetch->fetch = NULL;
8856
8857 result = dns_resolver_createfetch(zone->view->resolver,
8858 kname, dns_rdatatype_dnskey,
8859 NULL, NULL, NULL,
8860 DNS_FETCHOPT_NOVALIDATE|
8861 DNS_FETCHOPT_UNSHARED,
8862 zone->task,
8863 keyfetch_done, kfetch,
8864 &kfetch->dnskeyset,
8865 &kfetch->dnskeysigset,
8866 &kfetch->fetch);
8867 if (result == ISC_R_SUCCESS)
8868 fetching = ISC_TRUE;
8869 else {
8870 zone->refreshkeycount--;
8871 zone->irefs--;
8872 dns_db_detach(&kfetch->db);
8873 dns_rdataset_disassociate(&kfetch->keydataset);
8874 dns_name_free(kname, zone->mctx);
8875 isc_mem_put(zone->mctx, kfetch, sizeof(dns_keyfetch_t));
8876 dns_zone_log(zone, ISC_LOG_WARNING,
8877 "Failed to create fetch for "
8878 "DNSKEY update");
8879 fetch_err = ISC_TRUE;
8880 }
8881 }
8882 if (!ISC_LIST_EMPTY(diff.tuples)) {
8883 CHECK(update_soa_serial(db, ver, &diff, zone->mctx,
8884 zone->updatemethod));
8885 CHECK(zone_journal(zone, &diff, NULL, "zone_refreshkeys"));
8886 commit = ISC_TRUE;
8887 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
8888 zone_needdump(zone, 30);
8889 }
8890
8891 failure:
8892 if (fetch_err) {
8893 /*
8894 * Error during a key fetch; retry in an hour.
8895 */
8896 isc_time_t timenow, timethen;
8897 char timebuf[80];
8898
8899 TIME_NOW(&timenow);
8900 DNS_ZONE_TIME_ADD(&timenow, dns_zone_mkey_hour, &timethen);
8901 zone->refreshkeytime = timethen;
8902 zone_settimer(zone, &timenow);
8903
8904 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
8905 dns_zone_log(zone, ISC_LOG_DEBUG(1), "retry key refresh: %s",
8906 timebuf);
8907
8908 if (!fetching)
8909 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESHING);
8910 }
8911
8912 UNLOCK_ZONE(zone);
8913
8914 dns_diff_clear(&diff);
8915 if (ver != NULL) {
8916 dns_rriterator_destroy(&rrit);
8917 dns_db_closeversion(db, &ver, commit);
8918 }
8919 dns_db_detach(&db);
8920
8921 INSIST(ver == NULL);
8922 }
8923
8924 static void
zone_maintenance(dns_zone_t * zone)8925 zone_maintenance(dns_zone_t *zone) {
8926 const char me[] = "zone_maintenance";
8927 isc_time_t now;
8928 isc_result_t result;
8929 isc_boolean_t dumping;
8930
8931 REQUIRE(DNS_ZONE_VALID(zone));
8932 ENTER;
8933
8934 /*
8935 * Are we pending load/reload?
8936 */
8937 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING))
8938 return;
8939
8940 /*
8941 * Configuring the view of this zone may have
8942 * failed, for example because the config file
8943 * had a syntax error. In that case, the view
8944 * adb or resolver will be NULL, and we had better not try
8945 * to do further maintenance on it.
8946 */
8947 if (zone->view == NULL || zone->view->adb == NULL)
8948 return;
8949
8950 TIME_NOW(&now);
8951
8952 /*
8953 * Expire check.
8954 */
8955 switch (zone->type) {
8956 case dns_zone_redirect:
8957 if (zone->masters == NULL)
8958 break;
8959 case dns_zone_slave:
8960 case dns_zone_stub:
8961 LOCK_ZONE(zone);
8962 if (isc_time_compare(&now, &zone->expiretime) >= 0 &&
8963 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
8964 zone_expire(zone);
8965 zone->refreshtime = now;
8966 }
8967 UNLOCK_ZONE(zone);
8968 break;
8969 default:
8970 break;
8971 }
8972
8973 /*
8974 * Up to date check.
8975 */
8976 switch (zone->type) {
8977 case dns_zone_redirect:
8978 if (zone->masters == NULL)
8979 break;
8980 case dns_zone_slave:
8981 case dns_zone_stub:
8982 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH) &&
8983 isc_time_compare(&now, &zone->refreshtime) >= 0)
8984 dns_zone_refresh(zone);
8985 break;
8986 default:
8987 break;
8988 }
8989
8990 /*
8991 * Slaves send notifies before backing up to disk, masters after.
8992 */
8993 if (zone->type == dns_zone_slave &&
8994 (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) ||
8995 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY)) &&
8996 isc_time_compare(&now, &zone->notifytime) >= 0)
8997 zone_notify(zone, &now);
8998
8999 /*
9000 * Do we need to consolidate the backing store?
9001 */
9002 switch (zone->type) {
9003 case dns_zone_master:
9004 case dns_zone_slave:
9005 case dns_zone_key:
9006 case dns_zone_redirect:
9007 case dns_zone_stub:
9008 LOCK_ZONE(zone);
9009 if (zone->masterfile != NULL &&
9010 isc_time_compare(&now, &zone->dumptime) >= 0 &&
9011 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
9012 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP)) {
9013 dumping = was_dumping(zone);
9014 } else
9015 dumping = ISC_TRUE;
9016 UNLOCK_ZONE(zone);
9017 if (!dumping) {
9018 result = zone_dump(zone, ISC_TRUE); /* task locked */
9019 if (result != ISC_R_SUCCESS)
9020 dns_zone_log(zone, ISC_LOG_WARNING,
9021 "dump failed: %s",
9022 dns_result_totext(result));
9023 }
9024 break;
9025 default:
9026 break;
9027 }
9028
9029 /*
9030 * Master/redirect zones send notifies now, if needed
9031 */
9032 switch (zone->type) {
9033 case dns_zone_master:
9034 case dns_zone_redirect:
9035 if ((DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) ||
9036 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY))&&
9037 isc_time_compare(&now, &zone->notifytime) >= 0)
9038 zone_notify(zone, &now);
9039 default:
9040 break;
9041 }
9042
9043 /*
9044 * Do we need to refresh keys?
9045 */
9046 switch (zone->type) {
9047 case dns_zone_key:
9048 if (isc_time_compare(&now, &zone->refreshkeytime) >= 0) {
9049 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
9050 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING)) {
9051 zone_refreshkeys(zone);
9052 }
9053 }
9054 break;
9055 case dns_zone_master:
9056 if (!isc_time_isepoch(&zone->refreshkeytime) &&
9057 isc_time_compare(&now, &zone->refreshkeytime) >= 0 &&
9058 zone->rss_event == NULL)
9059 zone_rekey(zone);
9060 default:
9061 break;
9062 }
9063
9064 switch (zone->type) {
9065 case dns_zone_master:
9066 case dns_zone_redirect:
9067 case dns_zone_slave:
9068 /*
9069 * Do we need to sign/resign some RRsets?
9070 */
9071 if (zone->rss_event != NULL)
9072 break;
9073 if (!isc_time_isepoch(&zone->signingtime) &&
9074 isc_time_compare(&now, &zone->signingtime) >= 0)
9075 zone_sign(zone);
9076 else if (!isc_time_isepoch(&zone->resigntime) &&
9077 isc_time_compare(&now, &zone->resigntime) >= 0)
9078 zone_resigninc(zone);
9079 else if (!isc_time_isepoch(&zone->nsec3chaintime) &&
9080 isc_time_compare(&now, &zone->nsec3chaintime) >= 0)
9081 zone_nsec3chain(zone);
9082 /*
9083 * Do we need to issue a key expiry warning?
9084 */
9085 if (!isc_time_isepoch(&zone->keywarntime) &&
9086 isc_time_compare(&now, &zone->keywarntime) >= 0)
9087 set_key_expiry_warning(zone, zone->key_expiry,
9088 isc_time_seconds(&now));
9089 break;
9090
9091 default:
9092 break;
9093 }
9094 zone_settimer(zone, &now);
9095 }
9096
9097 void
dns_zone_markdirty(dns_zone_t * zone)9098 dns_zone_markdirty(dns_zone_t *zone) {
9099 isc_uint32_t serial;
9100 isc_result_t result = ISC_R_SUCCESS;
9101 dns_zone_t *secure = NULL;
9102
9103 /*
9104 * Obtaining a lock on the zone->secure (see zone_send_secureserial)
9105 * could result in a deadlock due to a LOR so we will spin if we
9106 * can't obtain the both locks.
9107 */
9108 again:
9109 LOCK_ZONE(zone);
9110 if (zone->type == dns_zone_master) {
9111 if (inline_raw(zone)) {
9112 unsigned int soacount;
9113 secure = zone->secure;
9114 INSIST(secure != zone);
9115 TRYLOCK_ZONE(result, secure);
9116 if (result != ISC_R_SUCCESS) {
9117 UNLOCK_ZONE(zone);
9118 secure = NULL;
9119 #ifdef ISC_PLATFORM_USETHREADS
9120 isc_thread_yield();
9121 #endif
9122 goto again;
9123 }
9124
9125 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
9126 if (zone->db != NULL) {
9127 result = zone_get_from_db(zone, zone->db, NULL,
9128 &soacount, &serial,
9129 NULL, NULL, NULL,
9130 NULL, NULL);
9131 } else
9132 result = DNS_R_NOTLOADED;
9133 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
9134 if (result == ISC_R_SUCCESS && soacount > 0U)
9135 zone_send_secureserial(zone, serial);
9136 }
9137
9138 /* XXXMPA make separate call back */
9139 if (result == ISC_R_SUCCESS)
9140 set_resigntime(zone);
9141 }
9142 if (secure != NULL)
9143 UNLOCK_ZONE(secure);
9144 zone_needdump(zone, DNS_DUMP_DELAY);
9145 UNLOCK_ZONE(zone);
9146 }
9147
9148 void
dns_zone_expire(dns_zone_t * zone)9149 dns_zone_expire(dns_zone_t *zone) {
9150 REQUIRE(DNS_ZONE_VALID(zone));
9151
9152 LOCK_ZONE(zone);
9153 zone_expire(zone);
9154 UNLOCK_ZONE(zone);
9155 }
9156
9157 static void
zone_expire(dns_zone_t * zone)9158 zone_expire(dns_zone_t *zone) {
9159 /*
9160 * 'zone' locked by caller.
9161 */
9162
9163 REQUIRE(LOCKED_ZONE(zone));
9164
9165 dns_zone_log(zone, ISC_LOG_WARNING, "expired");
9166
9167 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXPIRED);
9168 zone->refresh = DNS_ZONE_DEFAULTREFRESH;
9169 zone->retry = DNS_ZONE_DEFAULTRETRY;
9170 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
9171 zone_unload(zone);
9172 }
9173
9174 void
dns_zone_refresh(dns_zone_t * zone)9175 dns_zone_refresh(dns_zone_t *zone) {
9176 isc_interval_t i;
9177 isc_uint32_t oldflags;
9178 unsigned int j;
9179 isc_result_t result;
9180
9181 REQUIRE(DNS_ZONE_VALID(zone));
9182
9183 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
9184 return;
9185
9186 /*
9187 * Set DNS_ZONEFLG_REFRESH so that there is only one refresh operation
9188 * in progress at a time.
9189 */
9190
9191 LOCK_ZONE(zone);
9192 oldflags = zone->flags;
9193 if (zone->masterscnt == 0) {
9194 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOMASTERS);
9195 if ((oldflags & DNS_ZONEFLG_NOMASTERS) == 0)
9196 dns_zone_log(zone, ISC_LOG_ERROR,
9197 "cannot refresh: no masters");
9198 goto unlock;
9199 }
9200 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
9201 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
9202 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
9203 if ((oldflags & (DNS_ZONEFLG_REFRESH|DNS_ZONEFLG_LOADING)) != 0)
9204 goto unlock;
9205
9206 /*
9207 * Set the next refresh time as if refresh check has failed.
9208 * Setting this to the retry time will do that. XXXMLG
9209 * If we are successful it will be reset using zone->refresh.
9210 */
9211 isc_interval_set(&i, isc_random_jitter(zone->retry, zone->retry / 4),
9212 0);
9213 result = isc_time_nowplusinterval(&zone->refreshtime, &i);
9214 if (result != ISC_R_SUCCESS)
9215 dns_zone_log(zone, ISC_LOG_WARNING,
9216 "isc_time_nowplusinterval() failed: %s",
9217 dns_result_totext(result));
9218
9219 /*
9220 * When lacking user-specified timer values from the SOA,
9221 * do exponential backoff of the retry time up to a
9222 * maximum of six hours.
9223 */
9224 if (! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HAVETIMERS))
9225 zone->retry = ISC_MIN(zone->retry * 2, 6 * 3600);
9226
9227 zone->curmaster = 0;
9228 for (j = 0; j < zone->masterscnt; j++)
9229 zone->mastersok[j] = ISC_FALSE;
9230 /* initiate soa query */
9231 queue_soa_query(zone);
9232 unlock:
9233 UNLOCK_ZONE(zone);
9234 }
9235
9236 isc_result_t
dns_zone_flush(dns_zone_t * zone)9237 dns_zone_flush(dns_zone_t *zone) {
9238 isc_result_t result = ISC_R_SUCCESS;
9239 isc_boolean_t dumping;
9240
9241 REQUIRE(DNS_ZONE_VALID(zone));
9242
9243 LOCK_ZONE(zone);
9244 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FLUSH);
9245 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
9246 zone->masterfile != NULL) {
9247 result = ISC_R_ALREADYRUNNING;
9248 dumping = was_dumping(zone);
9249 } else
9250 dumping = ISC_TRUE;
9251 UNLOCK_ZONE(zone);
9252 if (!dumping)
9253 result = zone_dump(zone, ISC_FALSE); /* Unknown task. */
9254 return (result);
9255 }
9256
9257 isc_result_t
dns_zone_dump(dns_zone_t * zone)9258 dns_zone_dump(dns_zone_t *zone) {
9259 isc_result_t result = ISC_R_ALREADYRUNNING;
9260 isc_boolean_t dumping;
9261
9262 REQUIRE(DNS_ZONE_VALID(zone));
9263
9264 LOCK_ZONE(zone);
9265 dumping = was_dumping(zone);
9266 UNLOCK_ZONE(zone);
9267 if (!dumping)
9268 result = zone_dump(zone, ISC_FALSE); /* Unknown task. */
9269 return (result);
9270 }
9271
9272 static void
zone_needdump(dns_zone_t * zone,unsigned int delay)9273 zone_needdump(dns_zone_t *zone, unsigned int delay) {
9274 const char me[] = "zone_needdump";
9275 isc_time_t dumptime;
9276 isc_time_t now;
9277
9278 /*
9279 * 'zone' locked by caller
9280 */
9281
9282 REQUIRE(DNS_ZONE_VALID(zone));
9283 REQUIRE(LOCKED_ZONE(zone));
9284 ENTER;
9285
9286 /*
9287 * Do we have a place to dump to and are we loaded?
9288 */
9289 if (zone->masterfile == NULL ||
9290 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0)
9291 return;
9292
9293 TIME_NOW(&now);
9294 /* add some noise */
9295 DNS_ZONE_JITTER_ADD(&now, delay, &dumptime);
9296
9297 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
9298 if (isc_time_isepoch(&zone->dumptime) ||
9299 isc_time_compare(&zone->dumptime, &dumptime) > 0)
9300 zone->dumptime = dumptime;
9301 if (zone->task != NULL)
9302 zone_settimer(zone, &now);
9303 }
9304
9305 static void
dump_done(void * arg,isc_result_t result)9306 dump_done(void *arg, isc_result_t result) {
9307 const char me[] = "dump_done";
9308 dns_zone_t *zone = arg;
9309 dns_zone_t *secure = NULL;
9310 dns_db_t *db;
9311 dns_dbversion_t *version;
9312 isc_boolean_t again = ISC_FALSE;
9313 isc_boolean_t compact = ISC_FALSE;
9314 isc_uint32_t serial;
9315 isc_result_t tresult;
9316
9317 REQUIRE(DNS_ZONE_VALID(zone));
9318
9319 ENTER;
9320
9321 if (result == ISC_R_SUCCESS && zone->journal != NULL &&
9322 zone->journalsize != -1) {
9323 /*
9324 * We don't own these, zone->dctx must stay valid.
9325 */
9326 db = dns_dumpctx_db(zone->dctx);
9327 version = dns_dumpctx_version(zone->dctx);
9328 tresult = dns_db_getsoaserial(db, version, &serial);
9329
9330 /*
9331 * Handle lock order inversion.
9332 */
9333 again:
9334 LOCK_ZONE(zone);
9335 if (inline_raw(zone)) {
9336 secure = zone->secure;
9337 INSIST(secure != zone);
9338 TRYLOCK_ZONE(result, secure);
9339 if (result != ISC_R_SUCCESS) {
9340 UNLOCK_ZONE(zone);
9341 secure = NULL;
9342 #if ISC_PLATFORM_USETHREADS
9343 isc_thread_yield();
9344 #endif
9345 goto again;
9346 }
9347 }
9348
9349 /*
9350 * If there is a secure version of this zone
9351 * use its serial if it is less than ours.
9352 */
9353 if (tresult == ISC_R_SUCCESS && secure != NULL) {
9354 isc_uint32_t sserial;
9355 isc_result_t mresult;
9356
9357 ZONEDB_LOCK(&secure->dblock, isc_rwlocktype_read);
9358 if (secure->db != NULL) {
9359 mresult = dns_db_getsoaserial(zone->secure->db,
9360 NULL, &sserial);
9361 if (mresult == ISC_R_SUCCESS &&
9362 isc_serial_lt(sserial, serial))
9363 serial = sserial;
9364 }
9365 ZONEDB_UNLOCK(&secure->dblock, isc_rwlocktype_read);
9366 }
9367 if (secure != NULL)
9368 UNLOCK_ZONE(secure);
9369 UNLOCK_ZONE(zone);
9370
9371 /*
9372 * Note: we are task locked here so we can test
9373 * zone->xfr safely.
9374 */
9375 if (tresult == ISC_R_SUCCESS && zone->xfr == NULL) {
9376 tresult = dns_journal_compact(zone->mctx,
9377 zone->journal,
9378 serial,
9379 zone->journalsize);
9380 switch (tresult) {
9381 case ISC_R_SUCCESS:
9382 case ISC_R_NOSPACE:
9383 case ISC_R_NOTFOUND:
9384 dns_zone_log(zone, ISC_LOG_DEBUG(3),
9385 "dns_journal_compact: %s",
9386 dns_result_totext(tresult));
9387 break;
9388 default:
9389 dns_zone_log(zone, ISC_LOG_ERROR,
9390 "dns_journal_compact failed: %s",
9391 dns_result_totext(tresult));
9392 break;
9393 }
9394 } else if (tresult == ISC_R_SUCCESS) {
9395 compact = ISC_TRUE;
9396 zone->compact_serial = serial;
9397 }
9398 }
9399
9400 LOCK_ZONE(zone);
9401 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING);
9402 if (compact)
9403 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT);
9404 if (result != ISC_R_SUCCESS && result != ISC_R_CANCELED) {
9405 /*
9406 * Try again in a short while.
9407 */
9408 zone_needdump(zone, DNS_DUMP_DELAY);
9409 } else if (result == ISC_R_SUCCESS &&
9410 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) &&
9411 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
9412 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
9413 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
9414 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
9415 isc_time_settoepoch(&zone->dumptime);
9416 again = ISC_TRUE;
9417 } else if (result == ISC_R_SUCCESS)
9418 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH);
9419
9420 if (zone->dctx != NULL)
9421 dns_dumpctx_detach(&zone->dctx);
9422 zonemgr_putio(&zone->writeio);
9423 UNLOCK_ZONE(zone);
9424 if (again)
9425 (void)zone_dump(zone, ISC_FALSE);
9426 dns_zone_idetach(&zone);
9427 }
9428
9429 static isc_result_t
zone_dump(dns_zone_t * zone,isc_boolean_t compact)9430 zone_dump(dns_zone_t *zone, isc_boolean_t compact) {
9431 const char me[] = "zone_dump";
9432 isc_result_t result;
9433 dns_dbversion_t *version = NULL;
9434 isc_boolean_t again;
9435 dns_db_t *db = NULL;
9436 char *masterfile = NULL;
9437 dns_masterformat_t masterformat = dns_masterformat_none;
9438
9439 /*
9440 * 'compact' MUST only be set if we are task locked.
9441 */
9442
9443 REQUIRE(DNS_ZONE_VALID(zone));
9444 ENTER;
9445
9446 redo:
9447 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
9448 if (zone->db != NULL)
9449 dns_db_attach(zone->db, &db);
9450 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
9451 LOCK_ZONE(zone);
9452 if (zone->masterfile != NULL) {
9453 masterfile = isc_mem_strdup(zone->mctx, zone->masterfile);
9454 masterformat = zone->masterformat;
9455 }
9456 UNLOCK_ZONE(zone);
9457 if (db == NULL) {
9458 result = DNS_R_NOTLOADED;
9459 goto fail;
9460 }
9461 if (masterfile == NULL) {
9462 result = DNS_R_NOMASTERFILE;
9463 goto fail;
9464 }
9465
9466 if (compact && zone->type != dns_zone_stub) {
9467 dns_zone_t *dummy = NULL;
9468 LOCK_ZONE(zone);
9469 zone_iattach(zone, &dummy);
9470 result = zonemgr_getio(zone->zmgr, ISC_FALSE, zone->task,
9471 zone_gotwritehandle, zone,
9472 &zone->writeio);
9473 if (result != ISC_R_SUCCESS)
9474 zone_idetach(&dummy);
9475 else
9476 result = DNS_R_CONTINUE;
9477 UNLOCK_ZONE(zone);
9478 } else {
9479 const dns_master_style_t *output_style;
9480
9481 dns_masterrawheader_t rawdata;
9482 dns_db_currentversion(db, &version);
9483 dns_master_initrawheader(&rawdata);
9484 if (inline_secure(zone))
9485 get_raw_serial(zone->raw, &rawdata);
9486 if (zone->type == dns_zone_key)
9487 output_style = &dns_master_style_keyzone;
9488 else
9489 output_style = &dns_master_style_default;
9490 result = dns_master_dump3(zone->mctx, db, version,
9491 output_style, masterfile,
9492 masterformat, &rawdata);
9493 dns_db_closeversion(db, &version, ISC_FALSE);
9494 }
9495 fail:
9496 if (db != NULL)
9497 dns_db_detach(&db);
9498 if (masterfile != NULL)
9499 isc_mem_free(zone->mctx, masterfile);
9500 masterfile = NULL;
9501
9502 if (result == DNS_R_CONTINUE)
9503 return (ISC_R_SUCCESS); /* XXXMPA */
9504
9505 again = ISC_FALSE;
9506 LOCK_ZONE(zone);
9507 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING);
9508 if (result != ISC_R_SUCCESS) {
9509 /*
9510 * Try again in a short while.
9511 */
9512 zone_needdump(zone, DNS_DUMP_DELAY);
9513 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) &&
9514 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
9515 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
9516 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
9517 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
9518 isc_time_settoepoch(&zone->dumptime);
9519 again = ISC_TRUE;
9520 } else
9521 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH);
9522 UNLOCK_ZONE(zone);
9523 if (again)
9524 goto redo;
9525
9526 return (result);
9527 }
9528
9529 static isc_result_t
dumptostream(dns_zone_t * zone,FILE * fd,const dns_master_style_t * style,dns_masterformat_t format,const isc_uint32_t rawversion)9530 dumptostream(dns_zone_t *zone, FILE *fd, const dns_master_style_t *style,
9531 dns_masterformat_t format, const isc_uint32_t rawversion)
9532 {
9533 isc_result_t result;
9534 dns_dbversion_t *version = NULL;
9535 dns_db_t *db = NULL;
9536 dns_masterrawheader_t rawdata;
9537
9538 REQUIRE(DNS_ZONE_VALID(zone));
9539
9540 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
9541 if (zone->db != NULL)
9542 dns_db_attach(zone->db, &db);
9543 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
9544 if (db == NULL)
9545 return (DNS_R_NOTLOADED);
9546
9547 dns_db_currentversion(db, &version);
9548 dns_master_initrawheader(&rawdata);
9549 if (rawversion == 0)
9550 rawdata.flags |= DNS_MASTERRAW_COMPAT;
9551 else if (inline_secure(zone))
9552 get_raw_serial(zone->raw, &rawdata);
9553 else if (zone->sourceserialset) {
9554 rawdata.flags = DNS_MASTERRAW_SOURCESERIALSET;
9555 rawdata.sourceserial = zone->sourceserial;
9556 }
9557 result = dns_master_dumptostream3(zone->mctx, db, version, style,
9558 format, &rawdata, fd);
9559 dns_db_closeversion(db, &version, ISC_FALSE);
9560 dns_db_detach(&db);
9561 return (result);
9562 }
9563
9564 isc_result_t
dns_zone_dumptostream3(dns_zone_t * zone,FILE * fd,dns_masterformat_t format,const dns_master_style_t * style,const isc_uint32_t rawversion)9565 dns_zone_dumptostream3(dns_zone_t *zone, FILE *fd, dns_masterformat_t format,
9566 const dns_master_style_t *style,
9567 const isc_uint32_t rawversion)
9568 {
9569 return (dumptostream(zone, fd, style, format, rawversion));
9570 }
9571
9572 isc_result_t
dns_zone_dumptostream2(dns_zone_t * zone,FILE * fd,dns_masterformat_t format,const dns_master_style_t * style)9573 dns_zone_dumptostream2(dns_zone_t *zone, FILE *fd, dns_masterformat_t format,
9574 const dns_master_style_t *style) {
9575 return (dumptostream(zone, fd, style, format, DNS_RAWFORMAT_VERSION));
9576 }
9577
9578 isc_result_t
dns_zone_dumptostream(dns_zone_t * zone,FILE * fd)9579 dns_zone_dumptostream(dns_zone_t *zone, FILE *fd) {
9580 return (dumptostream(zone, fd, &dns_master_style_default,
9581 dns_masterformat_text, 0));
9582 }
9583
9584 isc_result_t
dns_zone_fulldumptostream(dns_zone_t * zone,FILE * fd)9585 dns_zone_fulldumptostream(dns_zone_t *zone, FILE *fd) {
9586 return (dumptostream(zone, fd, &dns_master_style_full,
9587 dns_masterformat_text, 0));
9588 }
9589
9590 void
dns_zone_unload(dns_zone_t * zone)9591 dns_zone_unload(dns_zone_t *zone) {
9592 REQUIRE(DNS_ZONE_VALID(zone));
9593
9594 LOCK_ZONE(zone);
9595 zone_unload(zone);
9596 UNLOCK_ZONE(zone);
9597 }
9598
9599 static void
notify_cancel(dns_zone_t * zone)9600 notify_cancel(dns_zone_t *zone) {
9601 dns_notify_t *notify;
9602
9603 /*
9604 * 'zone' locked by caller.
9605 */
9606
9607 REQUIRE(LOCKED_ZONE(zone));
9608
9609 for (notify = ISC_LIST_HEAD(zone->notifies);
9610 notify != NULL;
9611 notify = ISC_LIST_NEXT(notify, link)) {
9612 if (notify->find != NULL)
9613 dns_adb_cancelfind(notify->find);
9614 if (notify->request != NULL)
9615 dns_request_cancel(notify->request);
9616 }
9617 }
9618
9619 static void
forward_cancel(dns_zone_t * zone)9620 forward_cancel(dns_zone_t *zone) {
9621 dns_forward_t *forward;
9622
9623 /*
9624 * 'zone' locked by caller.
9625 */
9626
9627 REQUIRE(LOCKED_ZONE(zone));
9628
9629 for (forward = ISC_LIST_HEAD(zone->forwards);
9630 forward != NULL;
9631 forward = ISC_LIST_NEXT(forward, link)) {
9632 if (forward->request != NULL)
9633 dns_request_cancel(forward->request);
9634 }
9635 }
9636
9637 static void
zone_unload(dns_zone_t * zone)9638 zone_unload(dns_zone_t *zone) {
9639 /*
9640 * 'zone' locked by caller.
9641 */
9642
9643 REQUIRE(LOCKED_ZONE(zone));
9644
9645 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) ||
9646 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
9647 if (zone->writeio != NULL)
9648 zonemgr_cancelio(zone->writeio);
9649
9650 if (zone->dctx != NULL)
9651 dns_dumpctx_cancel(zone->dctx);
9652 }
9653 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
9654 zone_detachdb(zone);
9655 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
9656 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADED);
9657 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
9658 }
9659
9660 void
dns_zone_setminrefreshtime(dns_zone_t * zone,isc_uint32_t val)9661 dns_zone_setminrefreshtime(dns_zone_t *zone, isc_uint32_t val) {
9662 REQUIRE(DNS_ZONE_VALID(zone));
9663 REQUIRE(val > 0);
9664
9665 zone->minrefresh = val;
9666 }
9667
9668 void
dns_zone_setmaxrefreshtime(dns_zone_t * zone,isc_uint32_t val)9669 dns_zone_setmaxrefreshtime(dns_zone_t *zone, isc_uint32_t val) {
9670 REQUIRE(DNS_ZONE_VALID(zone));
9671 REQUIRE(val > 0);
9672
9673 zone->maxrefresh = val;
9674 }
9675
9676 void
dns_zone_setminretrytime(dns_zone_t * zone,isc_uint32_t val)9677 dns_zone_setminretrytime(dns_zone_t *zone, isc_uint32_t val) {
9678 REQUIRE(DNS_ZONE_VALID(zone));
9679 REQUIRE(val > 0);
9680
9681 zone->minretry = val;
9682 }
9683
9684 void
dns_zone_setmaxretrytime(dns_zone_t * zone,isc_uint32_t val)9685 dns_zone_setmaxretrytime(dns_zone_t *zone, isc_uint32_t val) {
9686 REQUIRE(DNS_ZONE_VALID(zone));
9687 REQUIRE(val > 0);
9688
9689 zone->maxretry = val;
9690 }
9691
9692 static isc_boolean_t
notify_isqueued(dns_zone_t * zone,unsigned int flags,dns_name_t * name,isc_sockaddr_t * addr,dns_tsigkey_t * key)9693 notify_isqueued(dns_zone_t *zone, unsigned int flags, dns_name_t *name,
9694 isc_sockaddr_t *addr, dns_tsigkey_t *key)
9695 {
9696 dns_notify_t *notify;
9697 dns_zonemgr_t *zmgr;
9698 isc_result_t result;
9699
9700 for (notify = ISC_LIST_HEAD(zone->notifies);
9701 notify != NULL;
9702 notify = ISC_LIST_NEXT(notify, link)) {
9703 if (notify->request != NULL)
9704 continue;
9705 if (name != NULL && dns_name_dynamic(¬ify->ns) &&
9706 dns_name_equal(name, ¬ify->ns))
9707 goto requeue;
9708 if (addr != NULL && isc_sockaddr_equal(addr, ¬ify->dst) &&
9709 notify->key == key)
9710 goto requeue;
9711 }
9712 return (ISC_FALSE);
9713
9714 requeue:
9715 /*
9716 * If we are enqueued on the startup ratelimiter and this is
9717 * not a startup notify, re-enqueue on the normal notify
9718 * ratelimiter.
9719 */
9720 if (notify->event != NULL && (flags & DNS_NOTIFY_STARTUP) == 0 &&
9721 (notify->flags & DNS_NOTIFY_STARTUP) != 0) {
9722 zmgr = notify->zone->zmgr;
9723 result = isc_ratelimiter_dequeue(zmgr->startupnotifyrl,
9724 notify->event);
9725 if (result != ISC_R_SUCCESS)
9726 return (ISC_TRUE);
9727
9728 notify->flags &= ~DNS_NOTIFY_STARTUP;
9729 result = isc_ratelimiter_enqueue(notify->zone->zmgr->notifyrl,
9730 notify->zone->task,
9731 ¬ify->event);
9732 if (result != ISC_R_SUCCESS) {
9733 isc_event_free(¬ify->event);
9734 return (ISC_FALSE);
9735 }
9736 }
9737
9738 return (ISC_TRUE);
9739 }
9740
9741 static isc_boolean_t
notify_isself(dns_zone_t * zone,isc_sockaddr_t * dst)9742 notify_isself(dns_zone_t *zone, isc_sockaddr_t *dst) {
9743 dns_tsigkey_t *key = NULL;
9744 isc_sockaddr_t src;
9745 isc_sockaddr_t any;
9746 isc_boolean_t isself;
9747 isc_netaddr_t dstaddr;
9748 isc_result_t result;
9749
9750 if (zone->view == NULL || zone->isself == NULL)
9751 return (ISC_FALSE);
9752
9753 switch (isc_sockaddr_pf(dst)) {
9754 case PF_INET:
9755 src = zone->notifysrc4;
9756 isc_sockaddr_any(&any);
9757 break;
9758 case PF_INET6:
9759 src = zone->notifysrc6;
9760 isc_sockaddr_any6(&any);
9761 break;
9762 default:
9763 return (ISC_FALSE);
9764 }
9765
9766 /*
9767 * When sending from any the kernel will assign a source address
9768 * that matches the destination address.
9769 */
9770 if (isc_sockaddr_eqaddr(&any, &src))
9771 src = *dst;
9772
9773 isc_netaddr_fromsockaddr(&dstaddr, dst);
9774 result = dns_view_getpeertsig(zone->view, &dstaddr, &key);
9775 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
9776 return (ISC_FALSE);
9777 isself = (zone->isself)(zone->view, key, &src, dst, zone->rdclass,
9778 zone->isselfarg);
9779 if (key != NULL)
9780 dns_tsigkey_detach(&key);
9781 return (isself);
9782 }
9783
9784 static void
notify_destroy(dns_notify_t * notify,isc_boolean_t locked)9785 notify_destroy(dns_notify_t *notify, isc_boolean_t locked) {
9786 isc_mem_t *mctx;
9787
9788 REQUIRE(DNS_NOTIFY_VALID(notify));
9789
9790 if (notify->zone != NULL) {
9791 if (!locked)
9792 LOCK_ZONE(notify->zone);
9793 REQUIRE(LOCKED_ZONE(notify->zone));
9794 if (ISC_LINK_LINKED(notify, link))
9795 ISC_LIST_UNLINK(notify->zone->notifies, notify, link);
9796 if (!locked)
9797 UNLOCK_ZONE(notify->zone);
9798 if (locked)
9799 zone_idetach(¬ify->zone);
9800 else
9801 dns_zone_idetach(¬ify->zone);
9802 }
9803 if (notify->find != NULL)
9804 dns_adb_destroyfind(¬ify->find);
9805 if (notify->request != NULL)
9806 dns_request_destroy(¬ify->request);
9807 if (dns_name_dynamic(¬ify->ns))
9808 dns_name_free(¬ify->ns, notify->mctx);
9809 if (notify->key != NULL)
9810 dns_tsigkey_detach(¬ify->key);
9811 mctx = notify->mctx;
9812 isc_mem_put(notify->mctx, notify, sizeof(*notify));
9813 isc_mem_detach(&mctx);
9814 }
9815
9816 static isc_result_t
notify_create(isc_mem_t * mctx,unsigned int flags,dns_notify_t ** notifyp)9817 notify_create(isc_mem_t *mctx, unsigned int flags, dns_notify_t **notifyp) {
9818 dns_notify_t *notify;
9819
9820 REQUIRE(notifyp != NULL && *notifyp == NULL);
9821
9822 notify = isc_mem_get(mctx, sizeof(*notify));
9823 if (notify == NULL)
9824 return (ISC_R_NOMEMORY);
9825
9826 notify->mctx = NULL;
9827 isc_mem_attach(mctx, ¬ify->mctx);
9828 notify->flags = flags;
9829 notify->zone = NULL;
9830 notify->find = NULL;
9831 notify->request = NULL;
9832 notify->key = NULL;
9833 notify->event = NULL;
9834 isc_sockaddr_any(¬ify->dst);
9835 dns_name_init(¬ify->ns, NULL);
9836 ISC_LINK_INIT(notify, link);
9837 notify->magic = NOTIFY_MAGIC;
9838 *notifyp = notify;
9839 return (ISC_R_SUCCESS);
9840 }
9841
9842 /*
9843 * XXXAG should check for DNS_ZONEFLG_EXITING
9844 */
9845 static void
process_adb_event(isc_task_t * task,isc_event_t * ev)9846 process_adb_event(isc_task_t *task, isc_event_t *ev) {
9847 dns_notify_t *notify;
9848 isc_eventtype_t result;
9849
9850 UNUSED(task);
9851
9852 notify = ev->ev_arg;
9853 REQUIRE(DNS_NOTIFY_VALID(notify));
9854 INSIST(task == notify->zone->task);
9855 result = ev->ev_type;
9856 isc_event_free(&ev);
9857 if (result == DNS_EVENT_ADBMOREADDRESSES) {
9858 dns_adb_destroyfind(¬ify->find);
9859 notify_find_address(notify);
9860 return;
9861 }
9862 if (result == DNS_EVENT_ADBNOMOREADDRESSES) {
9863 LOCK_ZONE(notify->zone);
9864 notify_send(notify);
9865 UNLOCK_ZONE(notify->zone);
9866 }
9867 notify_destroy(notify, ISC_FALSE);
9868 }
9869
9870 static void
notify_find_address(dns_notify_t * notify)9871 notify_find_address(dns_notify_t *notify) {
9872 isc_result_t result;
9873 unsigned int options;
9874
9875 REQUIRE(DNS_NOTIFY_VALID(notify));
9876 options = DNS_ADBFIND_WANTEVENT | DNS_ADBFIND_INET |
9877 DNS_ADBFIND_INET6 | DNS_ADBFIND_RETURNLAME;
9878
9879 if (notify->zone->view->adb == NULL)
9880 goto destroy;
9881
9882 result = dns_adb_createfind(notify->zone->view->adb,
9883 notify->zone->task,
9884 process_adb_event, notify,
9885 ¬ify->ns, dns_rootname, 0,
9886 options, 0, NULL,
9887 notify->zone->view->dstport,
9888 ¬ify->find);
9889
9890 /* Something failed? */
9891 if (result != ISC_R_SUCCESS)
9892 goto destroy;
9893
9894 /* More addresses pending? */
9895 if ((notify->find->options & DNS_ADBFIND_WANTEVENT) != 0)
9896 return;
9897
9898 /* We have as many addresses as we can get. */
9899 LOCK_ZONE(notify->zone);
9900 notify_send(notify);
9901 UNLOCK_ZONE(notify->zone);
9902
9903 destroy:
9904 notify_destroy(notify, ISC_FALSE);
9905 }
9906
9907
9908 static isc_result_t
notify_send_queue(dns_notify_t * notify,isc_boolean_t startup)9909 notify_send_queue(dns_notify_t *notify, isc_boolean_t startup) {
9910 isc_event_t *e;
9911 isc_result_t result;
9912
9913 INSIST(notify->event == NULL);
9914 e = isc_event_allocate(notify->mctx, NULL, DNS_EVENT_NOTIFYSENDTOADDR,
9915 notify_send_toaddr, notify, sizeof(isc_event_t));
9916 if (e == NULL)
9917 return (ISC_R_NOMEMORY);
9918 if (startup)
9919 notify->event = e;
9920 e->ev_arg = notify;
9921 e->ev_sender = NULL;
9922 result = isc_ratelimiter_enqueue(startup
9923 ? notify->zone->zmgr->startupnotifyrl
9924 : notify->zone->zmgr->notifyrl,
9925 notify->zone->task, &e);
9926 if (result != ISC_R_SUCCESS) {
9927 isc_event_free(&e);
9928 notify->event = NULL;
9929 }
9930 return (result);
9931 }
9932
9933 static void
notify_send_toaddr(isc_task_t * task,isc_event_t * event)9934 notify_send_toaddr(isc_task_t *task, isc_event_t *event) {
9935 dns_notify_t *notify;
9936 isc_result_t result;
9937 dns_message_t *message = NULL;
9938 isc_netaddr_t dstip;
9939 dns_tsigkey_t *key = NULL;
9940 char addrbuf[ISC_SOCKADDR_FORMATSIZE];
9941 isc_sockaddr_t src;
9942 int timeout;
9943 isc_boolean_t have_notifysource = ISC_FALSE;
9944
9945 notify = event->ev_arg;
9946 REQUIRE(DNS_NOTIFY_VALID(notify));
9947
9948 UNUSED(task);
9949
9950 LOCK_ZONE(notify->zone);
9951
9952 notify->event = NULL;
9953
9954 if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_LOADED) == 0) {
9955 result = ISC_R_CANCELED;
9956 goto cleanup;
9957 }
9958
9959 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0 ||
9960 DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_EXITING) ||
9961 notify->zone->view->requestmgr == NULL ||
9962 notify->zone->db == NULL) {
9963 result = ISC_R_CANCELED;
9964 goto cleanup;
9965 }
9966
9967 /*
9968 * The raw IPv4 address should also exist. Don't send to the
9969 * mapped form.
9970 */
9971 if (isc_sockaddr_pf(¬ify->dst) == PF_INET6 &&
9972 IN6_IS_ADDR_V4MAPPED(¬ify->dst.type.sin6.sin6_addr)) {
9973 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf));
9974 notify_log(notify->zone, ISC_LOG_DEBUG(3),
9975 "notify: ignoring IPv6 mapped IPV4 address: %s",
9976 addrbuf);
9977 result = ISC_R_CANCELED;
9978 goto cleanup;
9979 }
9980
9981 result = notify_createmessage(notify->zone, notify->flags, &message);
9982 if (result != ISC_R_SUCCESS)
9983 goto cleanup;
9984
9985 if (notify->key != NULL) {
9986 /* Transfer ownership of key */
9987 key = notify->key;
9988 notify->key = NULL;
9989 } else {
9990 isc_netaddr_fromsockaddr(&dstip, ¬ify->dst);
9991 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf));
9992 result = dns_view_getpeertsig(notify->zone->view, &dstip, &key);
9993 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
9994 notify_log(notify->zone, ISC_LOG_ERROR,
9995 "NOTIFY to %s not sent. "
9996 "Peer TSIG key lookup failure.", addrbuf);
9997 goto cleanup_message;
9998 }
9999 }
10000
10001 /* XXX: should we log the tsig key too? */
10002 notify_log(notify->zone, ISC_LOG_DEBUG(3), "sending notify to %s",
10003 addrbuf);
10004 if (notify->zone->view->peers != NULL) {
10005 dns_peer_t *peer = NULL;
10006 result = dns_peerlist_peerbyaddr(notify->zone->view->peers,
10007 &dstip, &peer);
10008 if (result == ISC_R_SUCCESS) {
10009 result = dns_peer_getnotifysource(peer, &src);
10010 if (result == ISC_R_SUCCESS)
10011 have_notifysource = ISC_TRUE;
10012 }
10013 }
10014 switch (isc_sockaddr_pf(¬ify->dst)) {
10015 case PF_INET:
10016 if (!have_notifysource)
10017 src = notify->zone->notifysrc4;
10018 break;
10019 case PF_INET6:
10020 if (!have_notifysource)
10021 src = notify->zone->notifysrc6;
10022 break;
10023 default:
10024 result = ISC_R_NOTIMPLEMENTED;
10025 goto cleanup_key;
10026 }
10027 timeout = 15;
10028 if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_DIALNOTIFY))
10029 timeout = 30;
10030 result = dns_request_createvia2(notify->zone->view->requestmgr,
10031 message, &src, ¬ify->dst, 0, key,
10032 timeout * 3, timeout,
10033 notify->zone->task, notify_done,
10034 notify, ¬ify->request);
10035 if (result == ISC_R_SUCCESS) {
10036 if (isc_sockaddr_pf(¬ify->dst) == AF_INET) {
10037 inc_stats(notify->zone,
10038 dns_zonestatscounter_notifyoutv4);
10039 } else {
10040 inc_stats(notify->zone,
10041 dns_zonestatscounter_notifyoutv6);
10042 }
10043 }
10044
10045 cleanup_key:
10046 if (key != NULL)
10047 dns_tsigkey_detach(&key);
10048 cleanup_message:
10049 dns_message_destroy(&message);
10050 cleanup:
10051 UNLOCK_ZONE(notify->zone);
10052 isc_event_free(&event);
10053 if (result != ISC_R_SUCCESS)
10054 notify_destroy(notify, ISC_FALSE);
10055 }
10056
10057 static void
notify_send(dns_notify_t * notify)10058 notify_send(dns_notify_t *notify) {
10059 dns_adbaddrinfo_t *ai;
10060 isc_sockaddr_t dst;
10061 isc_result_t result;
10062 dns_notify_t *new = NULL;
10063 unsigned int flags;
10064 isc_boolean_t startup;
10065
10066 /*
10067 * Zone lock held by caller.
10068 */
10069 REQUIRE(DNS_NOTIFY_VALID(notify));
10070 REQUIRE(LOCKED_ZONE(notify->zone));
10071
10072 if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_EXITING))
10073 return;
10074
10075 for (ai = ISC_LIST_HEAD(notify->find->list);
10076 ai != NULL;
10077 ai = ISC_LIST_NEXT(ai, publink)) {
10078 dst = ai->sockaddr;
10079 if (notify_isqueued(notify->zone, notify->flags, NULL, &dst,
10080 NULL))
10081 continue;
10082 if (notify_isself(notify->zone, &dst))
10083 continue;
10084 new = NULL;
10085 flags = notify->flags & DNS_NOTIFY_NOSOA;
10086 result = notify_create(notify->mctx, flags, &new);
10087 if (result != ISC_R_SUCCESS)
10088 goto cleanup;
10089 zone_iattach(notify->zone, &new->zone);
10090 ISC_LIST_APPEND(new->zone->notifies, new, link);
10091 new->dst = dst;
10092 startup = ISC_TF((notify->flags & DNS_NOTIFY_STARTUP) != 0);
10093 result = notify_send_queue(new, startup);
10094 if (result != ISC_R_SUCCESS)
10095 goto cleanup;
10096 new = NULL;
10097 }
10098
10099 cleanup:
10100 if (new != NULL)
10101 notify_destroy(new, ISC_TRUE);
10102 }
10103
10104 void
dns_zone_notify(dns_zone_t * zone)10105 dns_zone_notify(dns_zone_t *zone) {
10106 isc_time_t now;
10107
10108 REQUIRE(DNS_ZONE_VALID(zone));
10109
10110 LOCK_ZONE(zone);
10111 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
10112
10113 TIME_NOW(&now);
10114 zone_settimer(zone, &now);
10115 UNLOCK_ZONE(zone);
10116 }
10117
10118 static void
zone_notify(dns_zone_t * zone,isc_time_t * now)10119 zone_notify(dns_zone_t *zone, isc_time_t *now) {
10120 dns_dbnode_t *node = NULL;
10121 dns_db_t *zonedb = NULL;
10122 dns_dbversion_t *version = NULL;
10123 dns_name_t *origin = NULL;
10124 dns_name_t master;
10125 dns_rdata_ns_t ns;
10126 dns_rdata_soa_t soa;
10127 isc_uint32_t serial;
10128 dns_rdata_t rdata = DNS_RDATA_INIT;
10129 dns_rdataset_t nsrdset;
10130 dns_rdataset_t soardset;
10131 isc_result_t result;
10132 unsigned int i;
10133 isc_sockaddr_t dst;
10134 isc_boolean_t isqueued;
10135 dns_notifytype_t notifytype;
10136 unsigned int flags = 0;
10137 isc_boolean_t loggednotify = ISC_FALSE;
10138 isc_boolean_t startup;
10139
10140 REQUIRE(DNS_ZONE_VALID(zone));
10141
10142 LOCK_ZONE(zone);
10143 startup = !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
10144 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
10145 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY);
10146 notifytype = zone->notifytype;
10147 DNS_ZONE_TIME_ADD(now, zone->notifydelay, &zone->notifytime);
10148 UNLOCK_ZONE(zone);
10149
10150 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) ||
10151 ! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
10152 return;
10153
10154 if (notifytype == dns_notifytype_no)
10155 return;
10156
10157 if (notifytype == dns_notifytype_masteronly &&
10158 zone->type != dns_zone_master)
10159 return;
10160
10161 origin = &zone->origin;
10162
10163 /*
10164 * If the zone is dialup we are done as we don't want to send
10165 * the current soa so as to force a refresh query.
10166 */
10167 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY))
10168 flags |= DNS_NOTIFY_NOSOA;
10169
10170 /*
10171 * Record that this was a notify due to starting up.
10172 */
10173 if (startup)
10174 flags |= DNS_NOTIFY_STARTUP;
10175
10176 /*
10177 * Get SOA RRset.
10178 */
10179 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
10180 if (zone->db != NULL)
10181 dns_db_attach(zone->db, &zonedb);
10182 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
10183 if (zonedb == NULL)
10184 return;
10185 dns_db_currentversion(zonedb, &version);
10186 result = dns_db_findnode(zonedb, origin, ISC_FALSE, &node);
10187 if (result != ISC_R_SUCCESS)
10188 goto cleanup1;
10189
10190 dns_rdataset_init(&soardset);
10191 result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_soa,
10192 dns_rdatatype_none, 0, &soardset, NULL);
10193 if (result != ISC_R_SUCCESS)
10194 goto cleanup2;
10195
10196 /*
10197 * Find serial and master server's name.
10198 */
10199 dns_name_init(&master, NULL);
10200 result = dns_rdataset_first(&soardset);
10201 if (result != ISC_R_SUCCESS)
10202 goto cleanup3;
10203 dns_rdataset_current(&soardset, &rdata);
10204 result = dns_rdata_tostruct(&rdata, &soa, NULL);
10205 RUNTIME_CHECK(result == ISC_R_SUCCESS);
10206 dns_rdata_reset(&rdata);
10207 result = dns_name_dup(&soa.origin, zone->mctx, &master);
10208 serial = soa.serial;
10209 dns_rdataset_disassociate(&soardset);
10210 if (result != ISC_R_SUCCESS)
10211 goto cleanup3;
10212
10213 /*
10214 * Enqueue notify requests for 'also-notify' servers.
10215 */
10216 LOCK_ZONE(zone);
10217 for (i = 0; i < zone->notifycnt; i++) {
10218 dns_tsigkey_t *key = NULL;
10219 dns_notify_t *notify = NULL;
10220
10221 if ((zone->notifykeynames != NULL) &&
10222 (zone->notifykeynames[i] != NULL)) {
10223 dns_view_t *view = dns_zone_getview(zone);
10224 dns_name_t *keyname = zone->notifykeynames[i];
10225 (void)dns_view_gettsig(view, keyname, &key);
10226 }
10227
10228 dst = zone->notify[i];
10229 if (notify_isqueued(zone, flags, NULL, &dst, key)) {
10230 if (key != NULL)
10231 dns_tsigkey_detach(&key);
10232 continue;
10233 }
10234
10235 result = notify_create(zone->mctx, flags, ¬ify);
10236 if (result != ISC_R_SUCCESS) {
10237 if (key != NULL)
10238 dns_tsigkey_detach(&key);
10239 continue;
10240 }
10241
10242 zone_iattach(zone, ¬ify->zone);
10243 notify->dst = dst;
10244
10245 INSIST(notify->key == NULL);
10246
10247 if (key != NULL) {
10248 notify->key = key;
10249 key = NULL;
10250 }
10251
10252 ISC_LIST_APPEND(zone->notifies, notify, link);
10253 result = notify_send_queue(notify, startup);
10254 if (result != ISC_R_SUCCESS)
10255 notify_destroy(notify, ISC_TRUE);
10256 if (!loggednotify) {
10257 notify_log(zone, ISC_LOG_INFO,
10258 "sending notifies (serial %u)",
10259 serial);
10260 loggednotify = ISC_TRUE;
10261 }
10262 }
10263 UNLOCK_ZONE(zone);
10264
10265 if (notifytype == dns_notifytype_explicit)
10266 goto cleanup3;
10267
10268 /*
10269 * Process NS RRset to generate notifies.
10270 */
10271
10272 dns_rdataset_init(&nsrdset);
10273 result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_ns,
10274 dns_rdatatype_none, 0, &nsrdset, NULL);
10275 if (result != ISC_R_SUCCESS)
10276 goto cleanup3;
10277
10278 result = dns_rdataset_first(&nsrdset);
10279 while (result == ISC_R_SUCCESS) {
10280 dns_notify_t *notify = NULL;
10281
10282 dns_rdataset_current(&nsrdset, &rdata);
10283 result = dns_rdata_tostruct(&rdata, &ns, NULL);
10284 RUNTIME_CHECK(result == ISC_R_SUCCESS);
10285 dns_rdata_reset(&rdata);
10286 /*
10287 * Don't notify the master server unless explicitly
10288 * configured to do so.
10289 */
10290 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOTIFYTOSOA) &&
10291 dns_name_compare(&master, &ns.name) == 0) {
10292 result = dns_rdataset_next(&nsrdset);
10293 continue;
10294 }
10295
10296 if (!loggednotify) {
10297 notify_log(zone, ISC_LOG_INFO,
10298 "sending notifies (serial %u)",
10299 serial);
10300 loggednotify = ISC_TRUE;
10301 }
10302
10303 LOCK_ZONE(zone);
10304 isqueued = notify_isqueued(zone, flags, &ns.name, NULL, NULL);
10305 UNLOCK_ZONE(zone);
10306 if (isqueued) {
10307 result = dns_rdataset_next(&nsrdset);
10308 continue;
10309 }
10310 result = notify_create(zone->mctx, flags, ¬ify);
10311 if (result != ISC_R_SUCCESS)
10312 continue;
10313 dns_zone_iattach(zone, ¬ify->zone);
10314 result = dns_name_dup(&ns.name, zone->mctx, ¬ify->ns);
10315 if (result != ISC_R_SUCCESS) {
10316 LOCK_ZONE(zone);
10317 notify_destroy(notify, ISC_TRUE);
10318 UNLOCK_ZONE(zone);
10319 continue;
10320 }
10321 LOCK_ZONE(zone);
10322 ISC_LIST_APPEND(zone->notifies, notify, link);
10323 UNLOCK_ZONE(zone);
10324 notify_find_address(notify);
10325 result = dns_rdataset_next(&nsrdset);
10326 }
10327 dns_rdataset_disassociate(&nsrdset);
10328
10329 cleanup3:
10330 if (dns_name_dynamic(&master))
10331 dns_name_free(&master, zone->mctx);
10332 cleanup2:
10333 dns_db_detachnode(zonedb, &node);
10334 cleanup1:
10335 dns_db_closeversion(zonedb, &version, ISC_FALSE);
10336 dns_db_detach(&zonedb);
10337 }
10338
10339 /***
10340 *** Private
10341 ***/
10342
10343 static inline isc_result_t
save_nsrrset(dns_message_t * message,dns_name_t * name,dns_db_t * db,dns_dbversion_t * version)10344 save_nsrrset(dns_message_t *message, dns_name_t *name,
10345 dns_db_t *db, dns_dbversion_t *version)
10346 {
10347 dns_rdataset_t *nsrdataset = NULL;
10348 dns_rdataset_t *rdataset = NULL;
10349 dns_dbnode_t *node = NULL;
10350 dns_rdata_ns_t ns;
10351 isc_result_t result;
10352 dns_rdata_t rdata = DNS_RDATA_INIT;
10353
10354 /*
10355 * Extract NS RRset from message.
10356 */
10357 result = dns_message_findname(message, DNS_SECTION_ANSWER, name,
10358 dns_rdatatype_ns, dns_rdatatype_none,
10359 NULL, &nsrdataset);
10360 if (result != ISC_R_SUCCESS)
10361 goto fail;
10362
10363 /*
10364 * Add NS rdataset.
10365 */
10366 result = dns_db_findnode(db, name, ISC_TRUE, &node);
10367 if (result != ISC_R_SUCCESS)
10368 goto fail;
10369 result = dns_db_addrdataset(db, node, version, 0,
10370 nsrdataset, 0, NULL);
10371 dns_db_detachnode(db, &node);
10372 if (result != ISC_R_SUCCESS)
10373 goto fail;
10374 /*
10375 * Add glue rdatasets.
10376 */
10377 for (result = dns_rdataset_first(nsrdataset);
10378 result == ISC_R_SUCCESS;
10379 result = dns_rdataset_next(nsrdataset)) {
10380 dns_rdataset_current(nsrdataset, &rdata);
10381 result = dns_rdata_tostruct(&rdata, &ns, NULL);
10382 RUNTIME_CHECK(result == ISC_R_SUCCESS);
10383 dns_rdata_reset(&rdata);
10384 if (!dns_name_issubdomain(&ns.name, name))
10385 continue;
10386 rdataset = NULL;
10387 result = dns_message_findname(message, DNS_SECTION_ADDITIONAL,
10388 &ns.name, dns_rdatatype_aaaa,
10389 dns_rdatatype_none, NULL,
10390 &rdataset);
10391 if (result == ISC_R_SUCCESS) {
10392 result = dns_db_findnode(db, &ns.name,
10393 ISC_TRUE, &node);
10394 if (result != ISC_R_SUCCESS)
10395 goto fail;
10396 result = dns_db_addrdataset(db, node, version, 0,
10397 rdataset, 0, NULL);
10398 dns_db_detachnode(db, &node);
10399 if (result != ISC_R_SUCCESS)
10400 goto fail;
10401 }
10402 rdataset = NULL;
10403 result = dns_message_findname(message, DNS_SECTION_ADDITIONAL,
10404 &ns.name, dns_rdatatype_a,
10405 dns_rdatatype_none, NULL,
10406 &rdataset);
10407 if (result == ISC_R_SUCCESS) {
10408 result = dns_db_findnode(db, &ns.name,
10409 ISC_TRUE, &node);
10410 if (result != ISC_R_SUCCESS)
10411 goto fail;
10412 result = dns_db_addrdataset(db, node, version, 0,
10413 rdataset, 0, NULL);
10414 dns_db_detachnode(db, &node);
10415 if (result != ISC_R_SUCCESS)
10416 goto fail;
10417 }
10418 }
10419 if (result != ISC_R_NOMORE)
10420 goto fail;
10421
10422 return (ISC_R_SUCCESS);
10423
10424 fail:
10425 return (result);
10426 }
10427
10428 static void
stub_callback(isc_task_t * task,isc_event_t * event)10429 stub_callback(isc_task_t *task, isc_event_t *event) {
10430 const char me[] = "stub_callback";
10431 dns_requestevent_t *revent = (dns_requestevent_t *)event;
10432 dns_stub_t *stub = NULL;
10433 dns_message_t *msg = NULL;
10434 dns_zone_t *zone = NULL;
10435 char master[ISC_SOCKADDR_FORMATSIZE];
10436 char source[ISC_SOCKADDR_FORMATSIZE];
10437 isc_uint32_t nscnt, cnamecnt, refresh, retry, expire;
10438 isc_result_t result;
10439 isc_time_t now;
10440 isc_boolean_t exiting = ISC_FALSE;
10441 isc_interval_t i;
10442 unsigned int j, soacount;
10443
10444 stub = revent->ev_arg;
10445 INSIST(DNS_STUB_VALID(stub));
10446
10447 UNUSED(task);
10448
10449 zone = stub->zone;
10450
10451 ENTER;
10452
10453 TIME_NOW(&now);
10454
10455 LOCK_ZONE(zone);
10456
10457 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
10458 zone_debuglog(zone, me, 1, "exiting");
10459 exiting = ISC_TRUE;
10460 goto next_master;
10461 }
10462
10463 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
10464 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
10465
10466 if (revent->result != ISC_R_SUCCESS) {
10467 if (revent->result == ISC_R_TIMEDOUT &&
10468 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
10469 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
10470 dns_zone_log(zone, ISC_LOG_DEBUG(1),
10471 "refreshing stub: timeout retrying "
10472 " without EDNS master %s (source %s)",
10473 master, source);
10474 goto same_master;
10475 }
10476 dns_zonemgr_unreachableadd(zone->zmgr, &zone->masteraddr,
10477 &zone->sourceaddr, &now);
10478 dns_zone_log(zone, ISC_LOG_INFO,
10479 "could not refresh stub from master %s"
10480 " (source %s): %s", master, source,
10481 dns_result_totext(revent->result));
10482 goto next_master;
10483 }
10484
10485 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
10486 if (result != ISC_R_SUCCESS)
10487 goto next_master;
10488
10489 result = dns_request_getresponse(revent->request, msg, 0);
10490 if (result != ISC_R_SUCCESS)
10491 goto next_master;
10492
10493 /*
10494 * Unexpected rcode.
10495 */
10496 if (msg->rcode != dns_rcode_noerror) {
10497 char rcode[128];
10498 isc_buffer_t rb;
10499
10500 isc_buffer_init(&rb, rcode, sizeof(rcode));
10501 (void)dns_rcode_totext(msg->rcode, &rb);
10502
10503 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) &&
10504 (msg->rcode == dns_rcode_servfail ||
10505 msg->rcode == dns_rcode_notimp ||
10506 msg->rcode == dns_rcode_formerr)) {
10507 dns_zone_log(zone, ISC_LOG_DEBUG(1),
10508 "refreshing stub: rcode (%.*s) retrying "
10509 "without EDNS master %s (source %s)",
10510 (int)rb.used, rcode, master, source);
10511 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
10512 goto same_master;
10513 }
10514
10515 dns_zone_log(zone, ISC_LOG_INFO,
10516 "refreshing stub: "
10517 "unexpected rcode (%.*s) from %s (source %s)",
10518 (int)rb.used, rcode, master, source);
10519 goto next_master;
10520 }
10521
10522 /*
10523 * We need complete messages.
10524 */
10525 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) {
10526 if (dns_request_usedtcp(revent->request)) {
10527 dns_zone_log(zone, ISC_LOG_INFO,
10528 "refreshing stub: truncated TCP "
10529 "response from master %s (source %s)",
10530 master, source);
10531 goto next_master;
10532 }
10533 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC);
10534 goto same_master;
10535 }
10536
10537 /*
10538 * If non-auth log and next master.
10539 */
10540 if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
10541 dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: "
10542 "non-authoritative answer from "
10543 "master %s (source %s)", master, source);
10544 goto next_master;
10545 }
10546
10547 /*
10548 * Sanity checks.
10549 */
10550 cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname);
10551 nscnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_ns);
10552
10553 if (cnamecnt != 0) {
10554 dns_zone_log(zone, ISC_LOG_INFO,
10555 "refreshing stub: unexpected CNAME response "
10556 "from master %s (source %s)", master, source);
10557 goto next_master;
10558 }
10559
10560 if (nscnt == 0) {
10561 dns_zone_log(zone, ISC_LOG_INFO,
10562 "refreshing stub: no NS records in response "
10563 "from master %s (source %s)", master, source);
10564 goto next_master;
10565 }
10566
10567 /*
10568 * Save answer.
10569 */
10570 result = save_nsrrset(msg, &zone->origin, stub->db, stub->version);
10571 if (result != ISC_R_SUCCESS) {
10572 dns_zone_log(zone, ISC_LOG_INFO,
10573 "refreshing stub: unable to save NS records "
10574 "from master %s (source %s)", master, source);
10575 goto next_master;
10576 }
10577
10578 /*
10579 * Tidy up.
10580 */
10581 dns_db_closeversion(stub->db, &stub->version, ISC_TRUE);
10582 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
10583 if (zone->db == NULL)
10584 zone_attachdb(zone, stub->db);
10585 result = zone_get_from_db(zone, zone->db, NULL, &soacount, NULL,
10586 &refresh, &retry, &expire, NULL, NULL);
10587 if (result == ISC_R_SUCCESS && soacount > 0U) {
10588 zone->refresh = RANGE(refresh, zone->minrefresh,
10589 zone->maxrefresh);
10590 zone->retry = RANGE(retry, zone->minretry, zone->maxretry);
10591 zone->expire = RANGE(expire, zone->refresh + zone->retry,
10592 DNS_MAX_EXPIRE);
10593 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
10594 }
10595 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
10596 dns_db_detach(&stub->db);
10597
10598 dns_message_destroy(&msg);
10599 isc_event_free(&event);
10600 dns_request_destroy(&zone->request);
10601
10602 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
10603 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
10604 DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime);
10605 isc_interval_set(&i, zone->expire, 0);
10606 DNS_ZONE_TIME_ADD(&now, zone->expire, &zone->expiretime);
10607
10608 if (zone->masterfile != NULL)
10609 zone_needdump(zone, 0);
10610
10611 zone_settimer(zone, &now);
10612 goto free_stub;
10613
10614 next_master:
10615 if (stub->version != NULL)
10616 dns_db_closeversion(stub->db, &stub->version, ISC_FALSE);
10617 if (stub->db != NULL)
10618 dns_db_detach(&stub->db);
10619 if (msg != NULL)
10620 dns_message_destroy(&msg);
10621 isc_event_free(&event);
10622 dns_request_destroy(&zone->request);
10623 /*
10624 * Skip to next failed / untried master.
10625 */
10626 do {
10627 zone->curmaster++;
10628 } while (zone->curmaster < zone->masterscnt &&
10629 zone->mastersok[zone->curmaster]);
10630 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
10631 if (exiting || zone->curmaster >= zone->masterscnt) {
10632 isc_boolean_t done = ISC_TRUE;
10633 if (!exiting &&
10634 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
10635 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
10636 /*
10637 * Did we get a good answer from all the masters?
10638 */
10639 for (j = 0; j < zone->masterscnt; j++)
10640 if (zone->mastersok[j] == ISC_FALSE) {
10641 done = ISC_FALSE;
10642 break;
10643 }
10644 } else
10645 done = ISC_TRUE;
10646 if (!done) {
10647 zone->curmaster = 0;
10648 /*
10649 * Find the next failed master.
10650 */
10651 while (zone->curmaster < zone->masterscnt &&
10652 zone->mastersok[zone->curmaster])
10653 zone->curmaster++;
10654 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
10655 } else {
10656 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
10657
10658 zone_settimer(zone, &now);
10659 goto free_stub;
10660 }
10661 }
10662 queue_soa_query(zone);
10663 goto free_stub;
10664
10665 same_master:
10666 if (msg != NULL)
10667 dns_message_destroy(&msg);
10668 isc_event_free(&event);
10669 dns_request_destroy(&zone->request);
10670 ns_query(zone, NULL, stub);
10671 UNLOCK_ZONE(zone);
10672 goto done;
10673
10674 free_stub:
10675 UNLOCK_ZONE(zone);
10676 stub->magic = 0;
10677 dns_zone_idetach(&stub->zone);
10678 INSIST(stub->db == NULL);
10679 INSIST(stub->version == NULL);
10680 isc_mem_put(stub->mctx, stub, sizeof(*stub));
10681
10682 done:
10683 INSIST(event == NULL);
10684 return;
10685 }
10686
10687 /*
10688 * An SOA query has finished (successfully or not).
10689 */
10690 static void
refresh_callback(isc_task_t * task,isc_event_t * event)10691 refresh_callback(isc_task_t *task, isc_event_t *event) {
10692 const char me[] = "refresh_callback";
10693 dns_requestevent_t *revent = (dns_requestevent_t *)event;
10694 dns_zone_t *zone;
10695 dns_message_t *msg = NULL;
10696 isc_uint32_t soacnt, cnamecnt, soacount, nscount;
10697 isc_time_t now;
10698 char master[ISC_SOCKADDR_FORMATSIZE];
10699 char source[ISC_SOCKADDR_FORMATSIZE];
10700 dns_rdataset_t *rdataset = NULL;
10701 dns_rdata_t rdata = DNS_RDATA_INIT;
10702 dns_rdata_soa_t soa;
10703 isc_result_t result;
10704 isc_uint32_t serial, oldserial = 0;
10705 unsigned int j;
10706 isc_boolean_t do_queue_xfrin = ISC_FALSE;
10707
10708 zone = revent->ev_arg;
10709 INSIST(DNS_ZONE_VALID(zone));
10710
10711 UNUSED(task);
10712
10713 ENTER;
10714
10715 TIME_NOW(&now);
10716
10717 LOCK_ZONE(zone);
10718
10719 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
10720 isc_event_free(&event);
10721 dns_request_destroy(&zone->request);
10722 goto detach;
10723 }
10724
10725 /*
10726 * if timeout log and next master;
10727 */
10728
10729 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
10730 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
10731
10732 if (revent->result != ISC_R_SUCCESS) {
10733 if (revent->result == ISC_R_TIMEDOUT &&
10734 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
10735 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
10736 dns_zone_log(zone, ISC_LOG_DEBUG(1),
10737 "refresh: timeout retrying without EDNS "
10738 "master %s (source %s)", master, source);
10739 goto same_master;
10740 }
10741 if (revent->result == ISC_R_TIMEDOUT &&
10742 !dns_request_usedtcp(revent->request)) {
10743 dns_zone_log(zone, ISC_LOG_INFO,
10744 "refresh: retry limit for "
10745 "master %s exceeded (source %s)",
10746 master, source);
10747 /* Try with slave with TCP. */
10748 if ((zone->type == dns_zone_slave ||
10749 zone->type == dns_zone_redirect) &&
10750 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_TRYTCPREFRESH)) {
10751 if (!dns_zonemgr_unreachable(zone->zmgr,
10752 &zone->masteraddr,
10753 &zone->sourceaddr,
10754 &now))
10755 {
10756 DNS_ZONE_SETFLAG(zone,
10757 DNS_ZONEFLG_SOABEFOREAXFR);
10758 goto tcp_transfer;
10759 }
10760 dns_zone_log(zone, ISC_LOG_DEBUG(1),
10761 "refresh: skipped tcp fallback "
10762 "as master %s (source %s) is "
10763 "unreachable (cached)",
10764 master, source);
10765 }
10766 } else
10767 dns_zone_log(zone, ISC_LOG_INFO,
10768 "refresh: failure trying master "
10769 "%s (source %s): %s", master, source,
10770 dns_result_totext(revent->result));
10771 goto next_master;
10772 }
10773
10774 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
10775 if (result != ISC_R_SUCCESS)
10776 goto next_master;
10777 result = dns_request_getresponse(revent->request, msg, 0);
10778 if (result != ISC_R_SUCCESS) {
10779 dns_zone_log(zone, ISC_LOG_INFO,
10780 "refresh: failure trying master "
10781 "%s (source %s): %s", master, source,
10782 dns_result_totext(result));
10783 goto next_master;
10784 }
10785
10786 /*
10787 * Unexpected rcode.
10788 */
10789 if (msg->rcode != dns_rcode_noerror) {
10790 char rcode[128];
10791 isc_buffer_t rb;
10792
10793 isc_buffer_init(&rb, rcode, sizeof(rcode));
10794 (void)dns_rcode_totext(msg->rcode, &rb);
10795
10796 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) &&
10797 (msg->rcode == dns_rcode_servfail ||
10798 msg->rcode == dns_rcode_notimp ||
10799 msg->rcode == dns_rcode_formerr)) {
10800 dns_zone_log(zone, ISC_LOG_DEBUG(1),
10801 "refresh: rcode (%.*s) retrying without "
10802 "EDNS master %s (source %s)",
10803 (int)rb.used, rcode, master, source);
10804 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
10805 goto same_master;
10806 }
10807 dns_zone_log(zone, ISC_LOG_INFO,
10808 "refresh: unexpected rcode (%.*s) from "
10809 "master %s (source %s)", (int)rb.used, rcode,
10810 master, source);
10811 /*
10812 * Perhaps AXFR/IXFR is allowed even if SOA queries aren't.
10813 */
10814 if (msg->rcode == dns_rcode_refused &&
10815 (zone->type == dns_zone_slave ||
10816 zone->type == dns_zone_redirect))
10817 goto tcp_transfer;
10818 goto next_master;
10819 }
10820
10821 /*
10822 * If truncated punt to zone transfer which will query again.
10823 */
10824 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) {
10825 if (zone->type == dns_zone_slave ||
10826 zone->type == dns_zone_redirect) {
10827 dns_zone_log(zone, ISC_LOG_INFO,
10828 "refresh: truncated UDP answer, "
10829 "initiating TCP zone xfer "
10830 "for master %s (source %s)",
10831 master, source);
10832 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR);
10833 goto tcp_transfer;
10834 } else {
10835 INSIST(zone->type == dns_zone_stub);
10836 if (dns_request_usedtcp(revent->request)) {
10837 dns_zone_log(zone, ISC_LOG_INFO,
10838 "refresh: truncated TCP response "
10839 "from master %s (source %s)",
10840 master, source);
10841 goto next_master;
10842 }
10843 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC);
10844 goto same_master;
10845 }
10846 }
10847
10848 /*
10849 * if non-auth log and next master;
10850 */
10851 if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
10852 dns_zone_log(zone, ISC_LOG_INFO,
10853 "refresh: non-authoritative answer from "
10854 "master %s (source %s)", master, source);
10855 goto next_master;
10856 }
10857
10858 cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname);
10859 soacnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_soa);
10860 nscount = message_count(msg, DNS_SECTION_AUTHORITY, dns_rdatatype_ns);
10861 soacount = message_count(msg, DNS_SECTION_AUTHORITY,
10862 dns_rdatatype_soa);
10863
10864 /*
10865 * There should not be a CNAME record at top of zone.
10866 */
10867 if (cnamecnt != 0) {
10868 dns_zone_log(zone, ISC_LOG_INFO,
10869 "refresh: CNAME at top of zone "
10870 "in master %s (source %s)", master, source);
10871 goto next_master;
10872 }
10873
10874 /*
10875 * if referral log and next master;
10876 */
10877 if (soacnt == 0 && soacount == 0 && nscount != 0) {
10878 dns_zone_log(zone, ISC_LOG_INFO,
10879 "refresh: referral response "
10880 "from master %s (source %s)", master, source);
10881 goto next_master;
10882 }
10883
10884 /*
10885 * if nodata log and next master;
10886 */
10887 if (soacnt == 0 && (nscount == 0 || soacount != 0)) {
10888 dns_zone_log(zone, ISC_LOG_INFO,
10889 "refresh: NODATA response "
10890 "from master %s (source %s)", master, source);
10891 goto next_master;
10892 }
10893
10894 /*
10895 * Only one soa at top of zone.
10896 */
10897 if (soacnt != 1) {
10898 dns_zone_log(zone, ISC_LOG_INFO,
10899 "refresh: answer SOA count (%d) != 1 "
10900 "from master %s (source %s)",
10901 soacnt, master, source);
10902 goto next_master;
10903 }
10904
10905 /*
10906 * Extract serial
10907 */
10908 rdataset = NULL;
10909 result = dns_message_findname(msg, DNS_SECTION_ANSWER, &zone->origin,
10910 dns_rdatatype_soa, dns_rdatatype_none,
10911 NULL, &rdataset);
10912 if (result != ISC_R_SUCCESS) {
10913 dns_zone_log(zone, ISC_LOG_INFO,
10914 "refresh: unable to get SOA record "
10915 "from master %s (source %s)", master, source);
10916 goto next_master;
10917 }
10918
10919 result = dns_rdataset_first(rdataset);
10920 if (result != ISC_R_SUCCESS) {
10921 dns_zone_log(zone, ISC_LOG_INFO,
10922 "refresh: dns_rdataset_first() failed");
10923 goto next_master;
10924 }
10925
10926 dns_rdataset_current(rdataset, &rdata);
10927 result = dns_rdata_tostruct(&rdata, &soa, NULL);
10928 RUNTIME_CHECK(result == ISC_R_SUCCESS);
10929
10930 serial = soa.serial;
10931 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
10932 unsigned int dbsoacount;
10933 result = zone_get_from_db(zone, zone->db, NULL, &dbsoacount,
10934 &oldserial, NULL, NULL, NULL, NULL,
10935 NULL);
10936 RUNTIME_CHECK(result == ISC_R_SUCCESS);
10937 RUNTIME_CHECK(dbsoacount > 0U);
10938 zone_debuglog(zone, me, 1, "serial: new %u, old %u",
10939 serial, oldserial);
10940 } else
10941 zone_debuglog(zone, me, 1, "serial: new %u, old not loaded",
10942 serial);
10943
10944 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) ||
10945 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) ||
10946 isc_serial_gt(serial, oldserial)) {
10947 if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr,
10948 &zone->sourceaddr, &now))
10949 {
10950 dns_zone_log(zone, ISC_LOG_INFO,
10951 "refresh: skipping %s as master %s "
10952 "(source %s) is unreachable (cached)",
10953 (zone->type == dns_zone_slave ||
10954 zone->type == dns_zone_redirect) ?
10955 "zone transfer" : "NS query",
10956 master, source);
10957 goto next_master;
10958 }
10959 tcp_transfer:
10960 isc_event_free(&event);
10961 dns_request_destroy(&zone->request);
10962 if (zone->type == dns_zone_slave ||
10963 zone->type == dns_zone_redirect) {
10964 do_queue_xfrin = ISC_TRUE;
10965 } else {
10966 INSIST(zone->type == dns_zone_stub);
10967 ns_query(zone, rdataset, NULL);
10968 }
10969 if (msg != NULL)
10970 dns_message_destroy(&msg);
10971 } else if (isc_serial_eq(soa.serial, oldserial)) {
10972 if (zone->masterfile != NULL) {
10973 result = ISC_R_FAILURE;
10974 if (zone->journal != NULL)
10975 result = isc_file_settime(zone->journal, &now);
10976 if (result == ISC_R_SUCCESS &&
10977 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
10978 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
10979 result = isc_file_settime(zone->masterfile,
10980 &now);
10981 } else if (result != ISC_R_SUCCESS)
10982 result = isc_file_settime(zone->masterfile,
10983 &now);
10984 /* Someone removed the file from underneath us! */
10985 if (result == ISC_R_FILENOTFOUND) {
10986 zone_needdump(zone, DNS_DUMP_DELAY);
10987 } else if (result != ISC_R_SUCCESS)
10988 dns_zone_log(zone, ISC_LOG_ERROR,
10989 "refresh: could not set file "
10990 "modification time of '%s': %s",
10991 zone->masterfile,
10992 dns_result_totext(result));
10993 }
10994 DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime);
10995 DNS_ZONE_TIME_ADD(&now, zone->expire, &zone->expiretime);
10996 zone->mastersok[zone->curmaster] = ISC_TRUE;
10997 goto next_master;
10998 } else {
10999 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MULTIMASTER))
11000 dns_zone_log(zone, ISC_LOG_INFO, "serial number (%u) "
11001 "received from master %s < ours (%u)",
11002 soa.serial, master, oldserial);
11003 else
11004 zone_debuglog(zone, me, 1, "ahead");
11005 zone->mastersok[zone->curmaster] = ISC_TRUE;
11006 goto next_master;
11007 }
11008 if (msg != NULL)
11009 dns_message_destroy(&msg);
11010 goto detach;
11011
11012 next_master:
11013 if (msg != NULL)
11014 dns_message_destroy(&msg);
11015 isc_event_free(&event);
11016 dns_request_destroy(&zone->request);
11017 /*
11018 * Skip to next failed / untried master.
11019 */
11020 do {
11021 zone->curmaster++;
11022 } while (zone->curmaster < zone->masterscnt &&
11023 zone->mastersok[zone->curmaster]);
11024 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
11025 if (zone->curmaster >= zone->masterscnt) {
11026 isc_boolean_t done = ISC_TRUE;
11027 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
11028 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
11029 /*
11030 * Did we get a good answer from all the masters?
11031 */
11032 for (j = 0; j < zone->masterscnt; j++)
11033 if (zone->mastersok[j] == ISC_FALSE) {
11034 done = ISC_FALSE;
11035 break;
11036 }
11037 } else
11038 done = ISC_TRUE;
11039 if (!done) {
11040 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
11041 zone->curmaster = 0;
11042 /*
11043 * Find the next failed master.
11044 */
11045 while (zone->curmaster < zone->masterscnt &&
11046 zone->mastersok[zone->curmaster])
11047 zone->curmaster++;
11048 goto requeue;
11049 }
11050 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
11051 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) {
11052 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
11053 zone->refreshtime = now;
11054 }
11055 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
11056 zone_settimer(zone, &now);
11057 goto detach;
11058 }
11059
11060 requeue:
11061 queue_soa_query(zone);
11062 goto detach;
11063
11064 same_master:
11065 if (msg != NULL)
11066 dns_message_destroy(&msg);
11067 isc_event_free(&event);
11068 dns_request_destroy(&zone->request);
11069 queue_soa_query(zone);
11070
11071 detach:
11072 UNLOCK_ZONE(zone);
11073 if (do_queue_xfrin)
11074 queue_xfrin(zone);
11075 dns_zone_idetach(&zone);
11076 return;
11077 }
11078
11079 static void
queue_soa_query(dns_zone_t * zone)11080 queue_soa_query(dns_zone_t *zone) {
11081 const char me[] = "queue_soa_query";
11082 isc_event_t *e;
11083 dns_zone_t *dummy = NULL;
11084 isc_result_t result;
11085
11086 ENTER;
11087 /*
11088 * Locked by caller
11089 */
11090 REQUIRE(LOCKED_ZONE(zone));
11091
11092 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
11093 cancel_refresh(zone);
11094 return;
11095 }
11096
11097 e = isc_event_allocate(zone->mctx, NULL, DNS_EVENT_ZONE,
11098 soa_query, zone, sizeof(isc_event_t));
11099 if (e == NULL) {
11100 cancel_refresh(zone);
11101 return;
11102 }
11103
11104 /*
11105 * Attach so that we won't clean up
11106 * until the event is delivered.
11107 */
11108 zone_iattach(zone, &dummy);
11109
11110 e->ev_arg = zone;
11111 e->ev_sender = NULL;
11112 result = isc_ratelimiter_enqueue(zone->zmgr->refreshrl, zone->task, &e);
11113 if (result != ISC_R_SUCCESS) {
11114 zone_idetach(&dummy);
11115 isc_event_free(&e);
11116 cancel_refresh(zone);
11117 }
11118 }
11119
11120 static inline isc_result_t
create_query(dns_zone_t * zone,dns_rdatatype_t rdtype,dns_message_t ** messagep)11121 create_query(dns_zone_t *zone, dns_rdatatype_t rdtype,
11122 dns_message_t **messagep)
11123 {
11124 dns_message_t *message = NULL;
11125 dns_name_t *qname = NULL;
11126 dns_rdataset_t *qrdataset = NULL;
11127 isc_result_t result;
11128
11129 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER,
11130 &message);
11131 if (result != ISC_R_SUCCESS)
11132 goto cleanup;
11133
11134 message->opcode = dns_opcode_query;
11135 message->rdclass = zone->rdclass;
11136
11137 result = dns_message_gettempname(message, &qname);
11138 if (result != ISC_R_SUCCESS)
11139 goto cleanup;
11140
11141 result = dns_message_gettemprdataset(message, &qrdataset);
11142 if (result != ISC_R_SUCCESS)
11143 goto cleanup;
11144
11145 /*
11146 * Make question.
11147 */
11148 dns_name_init(qname, NULL);
11149 dns_name_clone(&zone->origin, qname);
11150 dns_rdataset_init(qrdataset);
11151 dns_rdataset_makequestion(qrdataset, zone->rdclass, rdtype);
11152 ISC_LIST_APPEND(qname->list, qrdataset, link);
11153 dns_message_addname(message, qname, DNS_SECTION_QUESTION);
11154
11155 *messagep = message;
11156 return (ISC_R_SUCCESS);
11157
11158 cleanup:
11159 if (qname != NULL)
11160 dns_message_puttempname(message, &qname);
11161 if (qrdataset != NULL)
11162 dns_message_puttemprdataset(message, &qrdataset);
11163 if (message != NULL)
11164 dns_message_destroy(&message);
11165 return (result);
11166 }
11167
11168 static isc_result_t
add_opt(dns_message_t * message,isc_uint16_t udpsize,isc_boolean_t reqnsid)11169 add_opt(dns_message_t *message, isc_uint16_t udpsize, isc_boolean_t reqnsid) {
11170 isc_result_t result;
11171 dns_rdataset_t *rdataset = NULL;
11172 dns_ednsopt_t ednsopts[DNS_EDNSOPTIONS];
11173 int count = 0;
11174
11175 /* Set EDNS options if applicable */
11176 if (reqnsid) {
11177 INSIST(count < DNS_EDNSOPTIONS);
11178 ednsopts[count].code = DNS_OPT_NSID;
11179 ednsopts[count].length = 0;
11180 ednsopts[count].value = NULL;
11181 count++;
11182 }
11183 result = dns_message_buildopt(message, &rdataset, 0, udpsize, 0,
11184 ednsopts, count);
11185 if (result != ISC_R_SUCCESS)
11186 return (result);
11187
11188 return (dns_message_setopt(message, rdataset));
11189 }
11190
11191 static void
soa_query(isc_task_t * task,isc_event_t * event)11192 soa_query(isc_task_t *task, isc_event_t *event) {
11193 const char me[] = "soa_query";
11194 isc_result_t result = ISC_R_FAILURE;
11195 dns_message_t *message = NULL;
11196 dns_zone_t *zone = event->ev_arg;
11197 dns_zone_t *dummy = NULL;
11198 isc_netaddr_t masterip;
11199 dns_tsigkey_t *key = NULL;
11200 isc_uint32_t options;
11201 isc_boolean_t cancel = ISC_TRUE;
11202 int timeout;
11203 isc_boolean_t have_xfrsource, reqnsid;
11204 isc_uint16_t udpsize = SEND_BUFFER_SIZE;
11205
11206 REQUIRE(DNS_ZONE_VALID(zone));
11207
11208 UNUSED(task);
11209
11210 ENTER;
11211
11212 LOCK_ZONE(zone);
11213 if (((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0) ||
11214 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) ||
11215 zone->view->requestmgr == NULL) {
11216 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
11217 cancel = ISC_FALSE;
11218 goto cleanup;
11219 }
11220
11221 again:
11222 result = create_query(zone, dns_rdatatype_soa, &message);
11223 if (result != ISC_R_SUCCESS)
11224 goto cleanup;
11225
11226 INSIST(zone->masterscnt > 0);
11227 INSIST(zone->curmaster < zone->masterscnt);
11228
11229 zone->masteraddr = zone->masters[zone->curmaster];
11230
11231 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
11232 /*
11233 * First, look for a tsig key in the master statement, then
11234 * try for a server key.
11235 */
11236 if ((zone->masterkeynames != NULL) &&
11237 (zone->masterkeynames[zone->curmaster] != NULL)) {
11238 dns_view_t *view = dns_zone_getview(zone);
11239 dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
11240 result = dns_view_gettsig(view, keyname, &key);
11241 if (result != ISC_R_SUCCESS) {
11242 char namebuf[DNS_NAME_FORMATSIZE];
11243 dns_name_format(keyname, namebuf, sizeof(namebuf));
11244 dns_zone_log(zone, ISC_LOG_ERROR,
11245 "unable to find key: %s", namebuf);
11246 goto skip_master;
11247 }
11248 }
11249 if (key == NULL) {
11250 result = dns_view_getpeertsig(zone->view, &masterip, &key);
11251 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
11252 char addrbuf[ISC_NETADDR_FORMATSIZE];
11253 isc_netaddr_format(&masterip, addrbuf, sizeof(addrbuf));
11254 dns_zone_log(zone, ISC_LOG_ERROR,
11255 "unable to find TSIG key for %s", addrbuf);
11256 goto skip_master;
11257 }
11258 }
11259
11260 have_xfrsource = ISC_FALSE;
11261 reqnsid = zone->view->requestnsid;
11262 if (zone->view->peers != NULL) {
11263 dns_peer_t *peer = NULL;
11264 isc_boolean_t edns;
11265 result = dns_peerlist_peerbyaddr(zone->view->peers,
11266 &masterip, &peer);
11267 if (result == ISC_R_SUCCESS) {
11268 result = dns_peer_getsupportedns(peer, &edns);
11269 if (result == ISC_R_SUCCESS && !edns)
11270 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
11271 result = dns_peer_gettransfersource(peer,
11272 &zone->sourceaddr);
11273 if (result == ISC_R_SUCCESS)
11274 have_xfrsource = ISC_TRUE;
11275 if (zone->view->resolver != NULL)
11276 udpsize =
11277 dns_resolver_getudpsize(zone->view->resolver);
11278 (void)dns_peer_getudpsize(peer, &udpsize);
11279 (void)dns_peer_getrequestnsid(peer, &reqnsid);
11280 }
11281 }
11282
11283 switch (isc_sockaddr_pf(&zone->masteraddr)) {
11284 case PF_INET:
11285 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
11286 if (isc_sockaddr_equal(&zone->altxfrsource4,
11287 &zone->xfrsource4))
11288 goto skip_master;
11289 zone->sourceaddr = zone->altxfrsource4;
11290 } else if (!have_xfrsource)
11291 zone->sourceaddr = zone->xfrsource4;
11292 break;
11293 case PF_INET6:
11294 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
11295 if (isc_sockaddr_equal(&zone->altxfrsource6,
11296 &zone->xfrsource6))
11297 goto skip_master;
11298 zone->sourceaddr = zone->altxfrsource6;
11299 } else if (!have_xfrsource)
11300 zone->sourceaddr = zone->xfrsource6;
11301 break;
11302 default:
11303 result = ISC_R_NOTIMPLEMENTED;
11304 goto cleanup;
11305 }
11306
11307 options = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEVC) ?
11308 DNS_REQUESTOPT_TCP : 0;
11309
11310 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
11311 result = add_opt(message, udpsize, reqnsid);
11312 if (result != ISC_R_SUCCESS)
11313 zone_debuglog(zone, me, 1,
11314 "unable to add opt record: %s",
11315 dns_result_totext(result));
11316 }
11317
11318 zone_iattach(zone, &dummy);
11319 timeout = 15;
11320 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
11321 timeout = 30;
11322 result = dns_request_createvia2(zone->view->requestmgr, message,
11323 &zone->sourceaddr, &zone->masteraddr,
11324 options, key, timeout * 3, timeout,
11325 zone->task, refresh_callback, zone,
11326 &zone->request);
11327 if (result != ISC_R_SUCCESS) {
11328 zone_idetach(&dummy);
11329 zone_debuglog(zone, me, 1,
11330 "dns_request_createvia4() failed: %s",
11331 dns_result_totext(result));
11332 goto skip_master;
11333 } else {
11334 if (isc_sockaddr_pf(&zone->masteraddr) == PF_INET)
11335 inc_stats(zone, dns_zonestatscounter_soaoutv4);
11336 else
11337 inc_stats(zone, dns_zonestatscounter_soaoutv6);
11338 }
11339 cancel = ISC_FALSE;
11340
11341 cleanup:
11342 if (key != NULL)
11343 dns_tsigkey_detach(&key);
11344 if (result != ISC_R_SUCCESS)
11345 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
11346 if (message != NULL)
11347 dns_message_destroy(&message);
11348 if (cancel)
11349 cancel_refresh(zone);
11350 isc_event_free(&event);
11351 UNLOCK_ZONE(zone);
11352 dns_zone_idetach(&zone);
11353 return;
11354
11355 skip_master:
11356 if (key != NULL)
11357 dns_tsigkey_detach(&key);
11358 dns_message_destroy(&message);
11359 /*
11360 * Skip to next failed / untried master.
11361 */
11362 do {
11363 zone->curmaster++;
11364 } while (zone->curmaster < zone->masterscnt &&
11365 zone->mastersok[zone->curmaster]);
11366 if (zone->curmaster < zone->masterscnt)
11367 goto again;
11368 zone->curmaster = 0;
11369 goto cleanup;
11370 }
11371
11372 static void
ns_query(dns_zone_t * zone,dns_rdataset_t * soardataset,dns_stub_t * stub)11373 ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) {
11374 const char me[] = "ns_query";
11375 isc_result_t result;
11376 dns_message_t *message = NULL;
11377 isc_netaddr_t masterip;
11378 dns_tsigkey_t *key = NULL;
11379 dns_dbnode_t *node = NULL;
11380 int timeout;
11381 isc_boolean_t have_xfrsource = ISC_FALSE, reqnsid;
11382 isc_uint16_t udpsize = SEND_BUFFER_SIZE;
11383
11384 REQUIRE(DNS_ZONE_VALID(zone));
11385 REQUIRE(LOCKED_ZONE(zone));
11386 REQUIRE((soardataset != NULL && stub == NULL) ||
11387 (soardataset == NULL && stub != NULL));
11388 REQUIRE(stub == NULL || DNS_STUB_VALID(stub));
11389
11390 ENTER;
11391
11392 if (stub == NULL) {
11393 stub = isc_mem_get(zone->mctx, sizeof(*stub));
11394 if (stub == NULL)
11395 goto cleanup;
11396 stub->magic = STUB_MAGIC;
11397 stub->mctx = zone->mctx;
11398 stub->zone = NULL;
11399 stub->db = NULL;
11400 stub->version = NULL;
11401
11402 /*
11403 * Attach so that the zone won't disappear from under us.
11404 */
11405 zone_iattach(zone, &stub->zone);
11406
11407 /*
11408 * If a db exists we will update it, otherwise we create a
11409 * new one and attach it to the zone once we have the NS
11410 * RRset and glue.
11411 */
11412 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
11413 if (zone->db != NULL) {
11414 dns_db_attach(zone->db, &stub->db);
11415 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
11416 } else {
11417 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
11418
11419 INSIST(zone->db_argc >= 1);
11420 result = dns_db_create(zone->mctx, zone->db_argv[0],
11421 &zone->origin, dns_dbtype_stub,
11422 zone->rdclass,
11423 zone->db_argc - 1,
11424 zone->db_argv + 1,
11425 &stub->db);
11426 if (result != ISC_R_SUCCESS) {
11427 dns_zone_log(zone, ISC_LOG_ERROR,
11428 "refreshing stub: "
11429 "could not create "
11430 "database: %s",
11431 dns_result_totext(result));
11432 goto cleanup;
11433 }
11434 dns_db_settask(stub->db, zone->task);
11435 }
11436
11437 result = dns_db_newversion(stub->db, &stub->version);
11438 if (result != ISC_R_SUCCESS) {
11439 dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: "
11440 "dns_db_newversion() failed: %s",
11441 dns_result_totext(result));
11442 goto cleanup;
11443 }
11444
11445 /*
11446 * Update SOA record.
11447 */
11448 result = dns_db_findnode(stub->db, &zone->origin, ISC_TRUE,
11449 &node);
11450 if (result != ISC_R_SUCCESS) {
11451 dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: "
11452 "dns_db_findnode() failed: %s",
11453 dns_result_totext(result));
11454 goto cleanup;
11455 }
11456
11457 result = dns_db_addrdataset(stub->db, node, stub->version, 0,
11458 soardataset, 0, NULL);
11459 dns_db_detachnode(stub->db, &node);
11460 if (result != ISC_R_SUCCESS) {
11461 dns_zone_log(zone, ISC_LOG_INFO,
11462 "refreshing stub: "
11463 "dns_db_addrdataset() failed: %s",
11464 dns_result_totext(result));
11465 goto cleanup;
11466 }
11467 }
11468
11469 /*
11470 * XXX Optimisation: Create message when zone is setup and reuse.
11471 */
11472 result = create_query(zone, dns_rdatatype_ns, &message);
11473 INSIST(result == ISC_R_SUCCESS);
11474
11475 INSIST(zone->masterscnt > 0);
11476 INSIST(zone->curmaster < zone->masterscnt);
11477 zone->masteraddr = zone->masters[zone->curmaster];
11478
11479 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
11480 /*
11481 * First, look for a tsig key in the master statement, then
11482 * try for a server key.
11483 */
11484 if ((zone->masterkeynames != NULL) &&
11485 (zone->masterkeynames[zone->curmaster] != NULL)) {
11486 dns_view_t *view = dns_zone_getview(zone);
11487 dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
11488 result = dns_view_gettsig(view, keyname, &key);
11489 if (result != ISC_R_SUCCESS) {
11490 char namebuf[DNS_NAME_FORMATSIZE];
11491 dns_name_format(keyname, namebuf, sizeof(namebuf));
11492 dns_zone_log(zone, ISC_LOG_ERROR,
11493 "unable to find key: %s", namebuf);
11494 }
11495 }
11496 if (key == NULL)
11497 (void)dns_view_getpeertsig(zone->view, &masterip, &key);
11498
11499 reqnsid = zone->view->requestnsid;
11500 if (zone->view->peers != NULL) {
11501 dns_peer_t *peer = NULL;
11502 isc_boolean_t edns;
11503 result = dns_peerlist_peerbyaddr(zone->view->peers,
11504 &masterip, &peer);
11505 if (result == ISC_R_SUCCESS) {
11506 result = dns_peer_getsupportedns(peer, &edns);
11507 if (result == ISC_R_SUCCESS && !edns)
11508 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
11509 result = dns_peer_gettransfersource(peer,
11510 &zone->sourceaddr);
11511 if (result == ISC_R_SUCCESS)
11512 have_xfrsource = ISC_TRUE;
11513 if (zone->view->resolver != NULL)
11514 udpsize =
11515 dns_resolver_getudpsize(zone->view->resolver);
11516 (void)dns_peer_getudpsize(peer, &udpsize);
11517 (void)dns_peer_getrequestnsid(peer, &reqnsid);
11518 }
11519
11520 }
11521 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
11522 result = add_opt(message, udpsize, reqnsid);
11523 if (result != ISC_R_SUCCESS)
11524 zone_debuglog(zone, me, 1,
11525 "unable to add opt record: %s",
11526 dns_result_totext(result));
11527 }
11528
11529 /*
11530 * Always use TCP so that we shouldn't truncate in additional section.
11531 */
11532 switch (isc_sockaddr_pf(&zone->masteraddr)) {
11533 case PF_INET:
11534 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC))
11535 zone->sourceaddr = zone->altxfrsource4;
11536 else if (!have_xfrsource)
11537 zone->sourceaddr = zone->xfrsource4;
11538 break;
11539 case PF_INET6:
11540 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC))
11541 zone->sourceaddr = zone->altxfrsource6;
11542 else if (!have_xfrsource)
11543 zone->sourceaddr = zone->xfrsource6;
11544 break;
11545 default:
11546 result = ISC_R_NOTIMPLEMENTED;
11547 POST(result);
11548 goto cleanup;
11549 }
11550 timeout = 15;
11551 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
11552 timeout = 30;
11553 result = dns_request_createvia2(zone->view->requestmgr, message,
11554 &zone->sourceaddr, &zone->masteraddr,
11555 DNS_REQUESTOPT_TCP, key, timeout * 3,
11556 timeout, zone->task, stub_callback,
11557 stub, &zone->request);
11558 if (result != ISC_R_SUCCESS) {
11559 zone_debuglog(zone, me, 1,
11560 "dns_request_createvia() failed: %s",
11561 dns_result_totext(result));
11562 goto cleanup;
11563 }
11564 dns_message_destroy(&message);
11565 goto unlock;
11566
11567 cleanup:
11568 cancel_refresh(zone);
11569 if (stub != NULL) {
11570 stub->magic = 0;
11571 if (stub->version != NULL)
11572 dns_db_closeversion(stub->db, &stub->version,
11573 ISC_FALSE);
11574 if (stub->db != NULL)
11575 dns_db_detach(&stub->db);
11576 if (stub->zone != NULL)
11577 zone_idetach(&stub->zone);
11578 isc_mem_put(stub->mctx, stub, sizeof(*stub));
11579 }
11580 if (message != NULL)
11581 dns_message_destroy(&message);
11582 unlock:
11583 if (key != NULL)
11584 dns_tsigkey_detach(&key);
11585 return;
11586 }
11587
11588 /*
11589 * Handle the control event. Note that although this event causes the zone
11590 * to shut down, it is not a shutdown event in the sense of the task library.
11591 */
11592 static void
zone_shutdown(isc_task_t * task,isc_event_t * event)11593 zone_shutdown(isc_task_t *task, isc_event_t *event) {
11594 dns_zone_t *zone = (dns_zone_t *) event->ev_arg;
11595 isc_boolean_t free_needed, linked = ISC_FALSE;
11596 dns_zone_t *raw = NULL, *secure = NULL;
11597
11598 UNUSED(task);
11599 REQUIRE(DNS_ZONE_VALID(zone));
11600 INSIST(event->ev_type == DNS_EVENT_ZONECONTROL);
11601 INSIST(isc_refcount_current(&zone->erefs) == 0);
11602
11603 zone_debuglog(zone, "zone_shutdown", 3, "shutting down");
11604
11605 /*
11606 * Stop things being restarted after we cancel them below.
11607 */
11608 LOCK_ZONE(zone);
11609 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXITING);
11610 UNLOCK_ZONE(zone);
11611
11612 /*
11613 * If we were waiting for xfrin quota, step out of
11614 * the queue.
11615 * If there's no zone manager, we can't be waiting for the
11616 * xfrin quota
11617 */
11618 if (zone->zmgr != NULL) {
11619 RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
11620 if (zone->statelist == &zone->zmgr->waiting_for_xfrin) {
11621 ISC_LIST_UNLINK(zone->zmgr->waiting_for_xfrin, zone,
11622 statelink);
11623 linked = ISC_TRUE;
11624 zone->statelist = NULL;
11625 }
11626 if (zone->statelist == &zone->zmgr->xfrin_in_progress) {
11627 ISC_LIST_UNLINK(zone->zmgr->xfrin_in_progress, zone,
11628 statelink);
11629 zone->statelist = NULL;
11630 zmgr_resume_xfrs(zone->zmgr, ISC_FALSE);
11631 }
11632 RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
11633 }
11634
11635 /*
11636 * In task context, no locking required. See zone_xfrdone().
11637 */
11638 if (zone->xfr != NULL)
11639 dns_xfrin_shutdown(zone->xfr);
11640
11641 /* Safe to release the zone now */
11642 if (zone->zmgr != NULL)
11643 dns_zonemgr_releasezone(zone->zmgr, zone);
11644
11645 LOCK_ZONE(zone);
11646 if (linked) {
11647 INSIST(zone->irefs > 0);
11648 zone->irefs--;
11649 }
11650 if (zone->request != NULL) {
11651 dns_request_cancel(zone->request);
11652 }
11653
11654 if (zone->readio != NULL)
11655 zonemgr_cancelio(zone->readio);
11656
11657 if (zone->lctx != NULL)
11658 dns_loadctx_cancel(zone->lctx);
11659
11660 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) ||
11661 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
11662 if (zone->writeio != NULL)
11663 zonemgr_cancelio(zone->writeio);
11664
11665 if (zone->dctx != NULL)
11666 dns_dumpctx_cancel(zone->dctx);
11667 }
11668
11669 notify_cancel(zone);
11670
11671 forward_cancel(zone);
11672
11673 if (zone->timer != NULL) {
11674 isc_timer_detach(&zone->timer);
11675 INSIST(zone->irefs > 0);
11676 zone->irefs--;
11677 }
11678
11679 /*
11680 * We have now canceled everything set the flag to allow exit_check()
11681 * to succeed. We must not unlock between setting this flag and
11682 * calling exit_check().
11683 */
11684 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SHUTDOWN);
11685 free_needed = exit_check(zone);
11686 if (inline_secure(zone)) {
11687 raw = zone->raw;
11688 zone->raw = NULL;
11689 }
11690 if (inline_raw(zone)) {
11691 secure = zone->secure;
11692 zone->secure = NULL;
11693 }
11694 UNLOCK_ZONE(zone);
11695 if (raw != NULL)
11696 dns_zone_detach(&raw);
11697 if (secure != NULL)
11698 dns_zone_idetach(&secure);
11699 if (free_needed)
11700 zone_free(zone);
11701 }
11702
11703 static void
zone_timer(isc_task_t * task,isc_event_t * event)11704 zone_timer(isc_task_t *task, isc_event_t *event) {
11705 const char me[] = "zone_timer";
11706 dns_zone_t *zone = (dns_zone_t *)event->ev_arg;
11707
11708 UNUSED(task);
11709 REQUIRE(DNS_ZONE_VALID(zone));
11710
11711 ENTER;
11712
11713 zone_maintenance(zone);
11714
11715 isc_event_free(&event);
11716 }
11717
11718 static void
zone_settimer(dns_zone_t * zone,isc_time_t * now)11719 zone_settimer(dns_zone_t *zone, isc_time_t *now) {
11720 const char me[] = "zone_settimer";
11721 isc_time_t next;
11722 isc_result_t result;
11723
11724 ENTER;
11725 REQUIRE(DNS_ZONE_VALID(zone));
11726 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
11727 return;
11728
11729 isc_time_settoepoch(&next);
11730
11731 switch (zone->type) {
11732 case dns_zone_redirect:
11733 if (zone->masters != NULL)
11734 goto treat_as_slave;
11735 /* FALLTHROUGH */
11736
11737 case dns_zone_master:
11738 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) ||
11739 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY))
11740 next = zone->notifytime;
11741 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
11742 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
11743 INSIST(!isc_time_isepoch(&zone->dumptime));
11744 if (isc_time_isepoch(&next) ||
11745 isc_time_compare(&zone->dumptime, &next) < 0)
11746 next = zone->dumptime;
11747 }
11748 if (zone->type == dns_zone_redirect)
11749 break;
11750 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING) &&
11751 !isc_time_isepoch(&zone->refreshkeytime)) {
11752 if (isc_time_isepoch(&next) ||
11753 isc_time_compare(&zone->refreshkeytime, &next) < 0)
11754 next = zone->refreshkeytime;
11755 }
11756 if (!isc_time_isepoch(&zone->resigntime)) {
11757 if (isc_time_isepoch(&next) ||
11758 isc_time_compare(&zone->resigntime, &next) < 0)
11759 next = zone->resigntime;
11760 }
11761 if (!isc_time_isepoch(&zone->keywarntime)) {
11762 if (isc_time_isepoch(&next) ||
11763 isc_time_compare(&zone->keywarntime, &next) < 0)
11764 next = zone->keywarntime;
11765 }
11766 if (!isc_time_isepoch(&zone->signingtime)) {
11767 if (isc_time_isepoch(&next) ||
11768 isc_time_compare(&zone->signingtime, &next) < 0)
11769 next = zone->signingtime;
11770 }
11771 if (!isc_time_isepoch(&zone->nsec3chaintime)) {
11772 if (isc_time_isepoch(&next) ||
11773 isc_time_compare(&zone->nsec3chaintime, &next) < 0)
11774 next = zone->nsec3chaintime;
11775 }
11776 break;
11777
11778 case dns_zone_slave:
11779 treat_as_slave:
11780 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) ||
11781 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY))
11782 next = zone->notifytime;
11783 /* FALLTHROUGH */
11784
11785 case dns_zone_stub:
11786 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH) &&
11787 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOMASTERS) &&
11788 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH) &&
11789 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING)) {
11790 INSIST(!isc_time_isepoch(&zone->refreshtime));
11791 if (isc_time_isepoch(&next) ||
11792 isc_time_compare(&zone->refreshtime, &next) < 0)
11793 next = zone->refreshtime;
11794 }
11795 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
11796 !isc_time_isepoch(&zone->expiretime)) {
11797 if (isc_time_isepoch(&next) ||
11798 isc_time_compare(&zone->expiretime, &next) < 0)
11799 next = zone->expiretime;
11800 }
11801 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
11802 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
11803 INSIST(!isc_time_isepoch(&zone->dumptime));
11804 if (isc_time_isepoch(&next) ||
11805 isc_time_compare(&zone->dumptime, &next) < 0)
11806 next = zone->dumptime;
11807 }
11808 break;
11809
11810 case dns_zone_key:
11811 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
11812 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
11813 INSIST(!isc_time_isepoch(&zone->dumptime));
11814 if (isc_time_isepoch(&next) ||
11815 isc_time_compare(&zone->dumptime, &next) < 0)
11816 next = zone->dumptime;
11817 }
11818 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING)) {
11819 if (isc_time_isepoch(&next) ||
11820 (!isc_time_isepoch(&zone->refreshkeytime) &&
11821 isc_time_compare(&zone->refreshkeytime, &next) < 0))
11822 next = zone->refreshkeytime;
11823 }
11824 break;
11825
11826 default:
11827 break;
11828 }
11829
11830 if (isc_time_isepoch(&next)) {
11831 zone_debuglog(zone, me, 10, "settimer inactive");
11832 result = isc_timer_reset(zone->timer, isc_timertype_inactive,
11833 NULL, NULL, ISC_TRUE);
11834 if (result != ISC_R_SUCCESS)
11835 dns_zone_log(zone, ISC_LOG_ERROR,
11836 "could not deactivate zone timer: %s",
11837 isc_result_totext(result));
11838 } else {
11839 if (isc_time_compare(&next, now) <= 0)
11840 next = *now;
11841 result = isc_timer_reset(zone->timer, isc_timertype_once,
11842 &next, NULL, ISC_TRUE);
11843 if (result != ISC_R_SUCCESS)
11844 dns_zone_log(zone, ISC_LOG_ERROR,
11845 "could not reset zone timer: %s",
11846 isc_result_totext(result));
11847 }
11848 }
11849
11850 static void
cancel_refresh(dns_zone_t * zone)11851 cancel_refresh(dns_zone_t *zone) {
11852 const char me[] = "cancel_refresh";
11853 isc_time_t now;
11854
11855 /*
11856 * 'zone' locked by caller.
11857 */
11858
11859 REQUIRE(DNS_ZONE_VALID(zone));
11860 REQUIRE(LOCKED_ZONE(zone));
11861
11862 ENTER;
11863
11864 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
11865 TIME_NOW(&now);
11866 zone_settimer(zone, &now);
11867 }
11868
11869 static isc_result_t
notify_createmessage(dns_zone_t * zone,unsigned int flags,dns_message_t ** messagep)11870 notify_createmessage(dns_zone_t *zone, unsigned int flags,
11871 dns_message_t **messagep)
11872 {
11873 dns_db_t *zonedb = NULL;
11874 dns_dbnode_t *node = NULL;
11875 dns_dbversion_t *version = NULL;
11876 dns_message_t *message = NULL;
11877 dns_rdataset_t rdataset;
11878 dns_rdata_t rdata = DNS_RDATA_INIT;
11879
11880 dns_name_t *tempname = NULL;
11881 dns_rdata_t *temprdata = NULL;
11882 dns_rdatalist_t *temprdatalist = NULL;
11883 dns_rdataset_t *temprdataset = NULL;
11884
11885 isc_result_t result;
11886 isc_region_t r;
11887 isc_buffer_t *b = NULL;
11888
11889 REQUIRE(DNS_ZONE_VALID(zone));
11890 REQUIRE(messagep != NULL && *messagep == NULL);
11891
11892 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER,
11893 &message);
11894 if (result != ISC_R_SUCCESS)
11895 return (result);
11896
11897 message->opcode = dns_opcode_notify;
11898 message->flags |= DNS_MESSAGEFLAG_AA;
11899 message->rdclass = zone->rdclass;
11900
11901 result = dns_message_gettempname(message, &tempname);
11902 if (result != ISC_R_SUCCESS)
11903 goto cleanup;
11904
11905 result = dns_message_gettemprdataset(message, &temprdataset);
11906 if (result != ISC_R_SUCCESS)
11907 goto cleanup;
11908
11909 /*
11910 * Make question.
11911 */
11912 dns_name_init(tempname, NULL);
11913 dns_name_clone(&zone->origin, tempname);
11914 dns_rdataset_init(temprdataset);
11915 dns_rdataset_makequestion(temprdataset, zone->rdclass,
11916 dns_rdatatype_soa);
11917 ISC_LIST_APPEND(tempname->list, temprdataset, link);
11918 dns_message_addname(message, tempname, DNS_SECTION_QUESTION);
11919 tempname = NULL;
11920 temprdataset = NULL;
11921
11922 if ((flags & DNS_NOTIFY_NOSOA) != 0)
11923 goto done;
11924
11925 result = dns_message_gettempname(message, &tempname);
11926 if (result != ISC_R_SUCCESS)
11927 goto soa_cleanup;
11928 result = dns_message_gettemprdata(message, &temprdata);
11929 if (result != ISC_R_SUCCESS)
11930 goto soa_cleanup;
11931 result = dns_message_gettemprdataset(message, &temprdataset);
11932 if (result != ISC_R_SUCCESS)
11933 goto soa_cleanup;
11934 result = dns_message_gettemprdatalist(message, &temprdatalist);
11935 if (result != ISC_R_SUCCESS)
11936 goto soa_cleanup;
11937
11938 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
11939 INSIST(zone->db != NULL); /* XXXJT: is this assumption correct? */
11940 dns_db_attach(zone->db, &zonedb);
11941 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
11942
11943 dns_name_init(tempname, NULL);
11944 dns_name_clone(&zone->origin, tempname);
11945 dns_db_currentversion(zonedb, &version);
11946 result = dns_db_findnode(zonedb, tempname, ISC_FALSE, &node);
11947 if (result != ISC_R_SUCCESS)
11948 goto soa_cleanup;
11949
11950 dns_rdataset_init(&rdataset);
11951 result = dns_db_findrdataset(zonedb, node, version,
11952 dns_rdatatype_soa,
11953 dns_rdatatype_none, 0, &rdataset,
11954 NULL);
11955 if (result != ISC_R_SUCCESS)
11956 goto soa_cleanup;
11957 result = dns_rdataset_first(&rdataset);
11958 if (result != ISC_R_SUCCESS)
11959 goto soa_cleanup;
11960 dns_rdataset_current(&rdataset, &rdata);
11961 dns_rdata_toregion(&rdata, &r);
11962 result = isc_buffer_allocate(zone->mctx, &b, r.length);
11963 if (result != ISC_R_SUCCESS)
11964 goto soa_cleanup;
11965 isc_buffer_putmem(b, r.base, r.length);
11966 isc_buffer_usedregion(b, &r);
11967 dns_rdata_init(temprdata);
11968 dns_rdata_fromregion(temprdata, rdata.rdclass, rdata.type, &r);
11969 dns_message_takebuffer(message, &b);
11970 result = dns_rdataset_next(&rdataset);
11971 dns_rdataset_disassociate(&rdataset);
11972 if (result != ISC_R_NOMORE)
11973 goto soa_cleanup;
11974 temprdatalist->rdclass = rdata.rdclass;
11975 temprdatalist->type = rdata.type;
11976 temprdatalist->ttl = rdataset.ttl;
11977 ISC_LIST_APPEND(temprdatalist->rdata, temprdata, link);
11978
11979 dns_rdataset_init(temprdataset);
11980 result = dns_rdatalist_tordataset(temprdatalist, temprdataset);
11981 if (result != ISC_R_SUCCESS)
11982 goto soa_cleanup;
11983
11984 ISC_LIST_APPEND(tempname->list, temprdataset, link);
11985 dns_message_addname(message, tempname, DNS_SECTION_ANSWER);
11986 temprdatalist = NULL;
11987 temprdataset = NULL;
11988 temprdata = NULL;
11989 tempname = NULL;
11990
11991 soa_cleanup:
11992 if (node != NULL)
11993 dns_db_detachnode(zonedb, &node);
11994 if (version != NULL)
11995 dns_db_closeversion(zonedb, &version, ISC_FALSE);
11996 if (zonedb != NULL)
11997 dns_db_detach(&zonedb);
11998 if (tempname != NULL)
11999 dns_message_puttempname(message, &tempname);
12000 if (temprdata != NULL)
12001 dns_message_puttemprdata(message, &temprdata);
12002 if (temprdataset != NULL)
12003 dns_message_puttemprdataset(message, &temprdataset);
12004 if (temprdatalist != NULL)
12005 dns_message_puttemprdatalist(message, &temprdatalist);
12006
12007 done:
12008 *messagep = message;
12009 return (ISC_R_SUCCESS);
12010
12011 cleanup:
12012 if (tempname != NULL)
12013 dns_message_puttempname(message, &tempname);
12014 if (temprdataset != NULL)
12015 dns_message_puttemprdataset(message, &temprdataset);
12016 dns_message_destroy(&message);
12017 return (result);
12018 }
12019
12020 isc_result_t
dns_zone_notifyreceive(dns_zone_t * zone,isc_sockaddr_t * from,dns_message_t * msg)12021 dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from,
12022 dns_message_t *msg)
12023 {
12024 unsigned int i;
12025 dns_rdata_soa_t soa;
12026 dns_rdataset_t *rdataset = NULL;
12027 dns_rdata_t rdata = DNS_RDATA_INIT;
12028 isc_result_t result;
12029 char fromtext[ISC_SOCKADDR_FORMATSIZE];
12030 int match = 0;
12031 isc_netaddr_t netaddr;
12032 isc_sockaddr_t local, remote;
12033 dns_tsigkey_t *tsigkey;
12034 dns_name_t *tsig;
12035
12036 REQUIRE(DNS_ZONE_VALID(zone));
12037
12038 /*
12039 * If type != T_SOA return DNS_R_NOTIMP. We don't yet support
12040 * ROLLOVER.
12041 *
12042 * SOA: RFC1996
12043 * Check that 'from' is a valid notify source, (zone->masters).
12044 * Return DNS_R_REFUSED if not.
12045 *
12046 * If the notify message contains a serial number check it
12047 * against the zones serial and return if <= current serial
12048 *
12049 * If a refresh check is progress, if so just record the
12050 * fact we received a NOTIFY and from where and return.
12051 * We will perform a new refresh check when the current one
12052 * completes. Return ISC_R_SUCCESS.
12053 *
12054 * Otherwise initiate a refresh check using 'from' as the
12055 * first address to check. Return ISC_R_SUCCESS.
12056 */
12057
12058 isc_sockaddr_format(from, fromtext, sizeof(fromtext));
12059
12060 /*
12061 * Notify messages are processed by the raw zone.
12062 */
12063 LOCK_ZONE(zone);
12064 if (inline_secure(zone)) {
12065 result = dns_zone_notifyreceive(zone->raw, from, msg);
12066 UNLOCK_ZONE(zone);
12067 return (result);
12068 }
12069 /*
12070 * We only handle NOTIFY (SOA) at the present.
12071 */
12072 if (isc_sockaddr_pf(from) == PF_INET)
12073 inc_stats(zone, dns_zonestatscounter_notifyinv4);
12074 else
12075 inc_stats(zone, dns_zonestatscounter_notifyinv6);
12076 if (msg->counts[DNS_SECTION_QUESTION] == 0 ||
12077 dns_message_findname(msg, DNS_SECTION_QUESTION, &zone->origin,
12078 dns_rdatatype_soa, dns_rdatatype_none,
12079 NULL, NULL) != ISC_R_SUCCESS) {
12080 UNLOCK_ZONE(zone);
12081 if (msg->counts[DNS_SECTION_QUESTION] == 0) {
12082 dns_zone_log(zone, ISC_LOG_NOTICE,
12083 "NOTIFY with no "
12084 "question section from: %s", fromtext);
12085 return (DNS_R_FORMERR);
12086 }
12087 dns_zone_log(zone, ISC_LOG_NOTICE,
12088 "NOTIFY zone does not match");
12089 return (DNS_R_NOTIMP);
12090 }
12091
12092 /*
12093 * If we are a master zone just succeed.
12094 */
12095 if (zone->type == dns_zone_master) {
12096 UNLOCK_ZONE(zone);
12097 return (ISC_R_SUCCESS);
12098 }
12099
12100 isc_netaddr_fromsockaddr(&netaddr, from);
12101 for (i = 0; i < zone->masterscnt; i++) {
12102 if (isc_sockaddr_eqaddr(from, &zone->masters[i]))
12103 break;
12104 if (zone->view->aclenv.match_mapped &&
12105 IN6_IS_ADDR_V4MAPPED(&from->type.sin6.sin6_addr) &&
12106 isc_sockaddr_pf(&zone->masters[i]) == AF_INET) {
12107 isc_netaddr_t na1, na2;
12108 isc_netaddr_fromv4mapped(&na1, &netaddr);
12109 isc_netaddr_fromsockaddr(&na2, &zone->masters[i]);
12110 if (isc_netaddr_equal(&na1, &na2))
12111 break;
12112 }
12113 }
12114
12115 /*
12116 * Accept notify requests from non masters if they are on
12117 * 'zone->notify_acl'.
12118 */
12119 tsigkey = dns_message_gettsigkey(msg);
12120 tsig = dns_tsigkey_identity(tsigkey);
12121 if (i >= zone->masterscnt && zone->notify_acl != NULL &&
12122 dns_acl_match(&netaddr, tsig, zone->notify_acl,
12123 &zone->view->aclenv,
12124 &match, NULL) == ISC_R_SUCCESS &&
12125 match > 0)
12126 {
12127 /* Accept notify. */
12128 } else if (i >= zone->masterscnt) {
12129 UNLOCK_ZONE(zone);
12130 dns_zone_log(zone, ISC_LOG_INFO,
12131 "refused notify from non-master: %s", fromtext);
12132 inc_stats(zone, dns_zonestatscounter_notifyrej);
12133 return (DNS_R_REFUSED);
12134 }
12135
12136 /*
12137 * If the zone is loaded and there are answers check the serial
12138 * to see if we need to do a refresh. Do not worry about this
12139 * check if we are a dialup zone as we use the notify request
12140 * to trigger a refresh check.
12141 */
12142 if (msg->counts[DNS_SECTION_ANSWER] > 0 &&
12143 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
12144 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH)) {
12145 result = dns_message_findname(msg, DNS_SECTION_ANSWER,
12146 &zone->origin,
12147 dns_rdatatype_soa,
12148 dns_rdatatype_none, NULL,
12149 &rdataset);
12150 if (result == ISC_R_SUCCESS)
12151 result = dns_rdataset_first(rdataset);
12152 if (result == ISC_R_SUCCESS) {
12153 isc_uint32_t serial = 0, oldserial;
12154 unsigned int soacount;
12155
12156 dns_rdataset_current(rdataset, &rdata);
12157 result = dns_rdata_tostruct(&rdata, &soa, NULL);
12158 RUNTIME_CHECK(result == ISC_R_SUCCESS);
12159 serial = soa.serial;
12160 /*
12161 * The following should safely be performed without DB
12162 * lock and succeed in this context.
12163 */
12164 result = zone_get_from_db(zone, zone->db, NULL,
12165 &soacount, &oldserial, NULL,
12166 NULL, NULL, NULL, NULL);
12167 RUNTIME_CHECK(result == ISC_R_SUCCESS);
12168 RUNTIME_CHECK(soacount > 0U);
12169 if (isc_serial_le(serial, oldserial)) {
12170 dns_zone_log(zone,
12171 ISC_LOG_INFO,
12172 "notify from %s: "
12173 "zone is up to date",
12174 fromtext);
12175 UNLOCK_ZONE(zone);
12176 return (ISC_R_SUCCESS);
12177 }
12178 }
12179 }
12180
12181 /*
12182 * If we got this far and there was a refresh in progress just
12183 * let it complete. Record where we got the notify from so we
12184 * can perform a refresh check when the current one completes
12185 */
12186 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH)) {
12187 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
12188 zone->notifyfrom = *from;
12189 UNLOCK_ZONE(zone);
12190 dns_zone_log(zone, ISC_LOG_INFO,
12191 "notify from %s: refresh in progress, "
12192 "refresh check queued",
12193 fromtext);
12194 return (ISC_R_SUCCESS);
12195 }
12196 zone->notifyfrom = *from;
12197 remote = zone->masteraddr;
12198 local = zone->sourceaddr;
12199 UNLOCK_ZONE(zone);
12200 dns_zonemgr_unreachabledel(zone->zmgr, &remote, &local);
12201 dns_zone_refresh(zone);
12202 return (ISC_R_SUCCESS);
12203 }
12204
12205 void
dns_zone_setnotifyacl(dns_zone_t * zone,dns_acl_t * acl)12206 dns_zone_setnotifyacl(dns_zone_t *zone, dns_acl_t *acl) {
12207
12208 REQUIRE(DNS_ZONE_VALID(zone));
12209
12210 LOCK_ZONE(zone);
12211 if (zone->notify_acl != NULL)
12212 dns_acl_detach(&zone->notify_acl);
12213 dns_acl_attach(acl, &zone->notify_acl);
12214 UNLOCK_ZONE(zone);
12215 }
12216
12217 void
dns_zone_setqueryacl(dns_zone_t * zone,dns_acl_t * acl)12218 dns_zone_setqueryacl(dns_zone_t *zone, dns_acl_t *acl) {
12219
12220 REQUIRE(DNS_ZONE_VALID(zone));
12221
12222 LOCK_ZONE(zone);
12223 if (zone->query_acl != NULL)
12224 dns_acl_detach(&zone->query_acl);
12225 dns_acl_attach(acl, &zone->query_acl);
12226 UNLOCK_ZONE(zone);
12227 }
12228
12229 void
dns_zone_setqueryonacl(dns_zone_t * zone,dns_acl_t * acl)12230 dns_zone_setqueryonacl(dns_zone_t *zone, dns_acl_t *acl) {
12231
12232 REQUIRE(DNS_ZONE_VALID(zone));
12233
12234 LOCK_ZONE(zone);
12235 if (zone->queryon_acl != NULL)
12236 dns_acl_detach(&zone->queryon_acl);
12237 dns_acl_attach(acl, &zone->queryon_acl);
12238 UNLOCK_ZONE(zone);
12239 }
12240
12241 void
dns_zone_setupdateacl(dns_zone_t * zone,dns_acl_t * acl)12242 dns_zone_setupdateacl(dns_zone_t *zone, dns_acl_t *acl) {
12243
12244 REQUIRE(DNS_ZONE_VALID(zone));
12245
12246 LOCK_ZONE(zone);
12247 if (zone->update_acl != NULL)
12248 dns_acl_detach(&zone->update_acl);
12249 dns_acl_attach(acl, &zone->update_acl);
12250 UNLOCK_ZONE(zone);
12251 }
12252
12253 void
dns_zone_setforwardacl(dns_zone_t * zone,dns_acl_t * acl)12254 dns_zone_setforwardacl(dns_zone_t *zone, dns_acl_t *acl) {
12255
12256 REQUIRE(DNS_ZONE_VALID(zone));
12257
12258 LOCK_ZONE(zone);
12259 if (zone->forward_acl != NULL)
12260 dns_acl_detach(&zone->forward_acl);
12261 dns_acl_attach(acl, &zone->forward_acl);
12262 UNLOCK_ZONE(zone);
12263 }
12264
12265 void
dns_zone_setxfracl(dns_zone_t * zone,dns_acl_t * acl)12266 dns_zone_setxfracl(dns_zone_t *zone, dns_acl_t *acl) {
12267
12268 REQUIRE(DNS_ZONE_VALID(zone));
12269
12270 LOCK_ZONE(zone);
12271 if (zone->xfr_acl != NULL)
12272 dns_acl_detach(&zone->xfr_acl);
12273 dns_acl_attach(acl, &zone->xfr_acl);
12274 UNLOCK_ZONE(zone);
12275 }
12276
12277 dns_acl_t *
dns_zone_getnotifyacl(dns_zone_t * zone)12278 dns_zone_getnotifyacl(dns_zone_t *zone) {
12279
12280 REQUIRE(DNS_ZONE_VALID(zone));
12281
12282 return (zone->notify_acl);
12283 }
12284
12285 dns_acl_t *
dns_zone_getqueryacl(dns_zone_t * zone)12286 dns_zone_getqueryacl(dns_zone_t *zone) {
12287
12288 REQUIRE(DNS_ZONE_VALID(zone));
12289
12290 return (zone->query_acl);
12291 }
12292
12293 dns_acl_t *
dns_zone_getqueryonacl(dns_zone_t * zone)12294 dns_zone_getqueryonacl(dns_zone_t *zone) {
12295
12296 REQUIRE(DNS_ZONE_VALID(zone));
12297
12298 return (zone->queryon_acl);
12299 }
12300
12301 dns_acl_t *
dns_zone_getupdateacl(dns_zone_t * zone)12302 dns_zone_getupdateacl(dns_zone_t *zone) {
12303
12304 REQUIRE(DNS_ZONE_VALID(zone));
12305
12306 return (zone->update_acl);
12307 }
12308
12309 dns_acl_t *
dns_zone_getforwardacl(dns_zone_t * zone)12310 dns_zone_getforwardacl(dns_zone_t *zone) {
12311
12312 REQUIRE(DNS_ZONE_VALID(zone));
12313
12314 return (zone->forward_acl);
12315 }
12316
12317 dns_acl_t *
dns_zone_getxfracl(dns_zone_t * zone)12318 dns_zone_getxfracl(dns_zone_t *zone) {
12319
12320 REQUIRE(DNS_ZONE_VALID(zone));
12321
12322 return (zone->xfr_acl);
12323 }
12324
12325 void
dns_zone_clearupdateacl(dns_zone_t * zone)12326 dns_zone_clearupdateacl(dns_zone_t *zone) {
12327
12328 REQUIRE(DNS_ZONE_VALID(zone));
12329
12330 LOCK_ZONE(zone);
12331 if (zone->update_acl != NULL)
12332 dns_acl_detach(&zone->update_acl);
12333 UNLOCK_ZONE(zone);
12334 }
12335
12336 void
dns_zone_clearforwardacl(dns_zone_t * zone)12337 dns_zone_clearforwardacl(dns_zone_t *zone) {
12338
12339 REQUIRE(DNS_ZONE_VALID(zone));
12340
12341 LOCK_ZONE(zone);
12342 if (zone->forward_acl != NULL)
12343 dns_acl_detach(&zone->forward_acl);
12344 UNLOCK_ZONE(zone);
12345 }
12346
12347 void
dns_zone_clearnotifyacl(dns_zone_t * zone)12348 dns_zone_clearnotifyacl(dns_zone_t *zone) {
12349
12350 REQUIRE(DNS_ZONE_VALID(zone));
12351
12352 LOCK_ZONE(zone);
12353 if (zone->notify_acl != NULL)
12354 dns_acl_detach(&zone->notify_acl);
12355 UNLOCK_ZONE(zone);
12356 }
12357
12358 void
dns_zone_clearqueryacl(dns_zone_t * zone)12359 dns_zone_clearqueryacl(dns_zone_t *zone) {
12360
12361 REQUIRE(DNS_ZONE_VALID(zone));
12362
12363 LOCK_ZONE(zone);
12364 if (zone->query_acl != NULL)
12365 dns_acl_detach(&zone->query_acl);
12366 UNLOCK_ZONE(zone);
12367 }
12368
12369 void
dns_zone_clearqueryonacl(dns_zone_t * zone)12370 dns_zone_clearqueryonacl(dns_zone_t *zone) {
12371
12372 REQUIRE(DNS_ZONE_VALID(zone));
12373
12374 LOCK_ZONE(zone);
12375 if (zone->queryon_acl != NULL)
12376 dns_acl_detach(&zone->queryon_acl);
12377 UNLOCK_ZONE(zone);
12378 }
12379
12380 void
dns_zone_clearxfracl(dns_zone_t * zone)12381 dns_zone_clearxfracl(dns_zone_t *zone) {
12382
12383 REQUIRE(DNS_ZONE_VALID(zone));
12384
12385 LOCK_ZONE(zone);
12386 if (zone->xfr_acl != NULL)
12387 dns_acl_detach(&zone->xfr_acl);
12388 UNLOCK_ZONE(zone);
12389 }
12390
12391 isc_boolean_t
dns_zone_getupdatedisabled(dns_zone_t * zone)12392 dns_zone_getupdatedisabled(dns_zone_t *zone) {
12393 REQUIRE(DNS_ZONE_VALID(zone));
12394 return (zone->update_disabled);
12395
12396 }
12397
12398 void
dns_zone_setupdatedisabled(dns_zone_t * zone,isc_boolean_t state)12399 dns_zone_setupdatedisabled(dns_zone_t *zone, isc_boolean_t state) {
12400 REQUIRE(DNS_ZONE_VALID(zone));
12401 zone->update_disabled = state;
12402 }
12403
12404 isc_boolean_t
dns_zone_getzeronosoattl(dns_zone_t * zone)12405 dns_zone_getzeronosoattl(dns_zone_t *zone) {
12406 REQUIRE(DNS_ZONE_VALID(zone));
12407 return (zone->zero_no_soa_ttl);
12408
12409 }
12410
12411 void
dns_zone_setzeronosoattl(dns_zone_t * zone,isc_boolean_t state)12412 dns_zone_setzeronosoattl(dns_zone_t *zone, isc_boolean_t state) {
12413 REQUIRE(DNS_ZONE_VALID(zone));
12414 zone->zero_no_soa_ttl = state;
12415 }
12416
12417 void
dns_zone_setchecknames(dns_zone_t * zone,dns_severity_t severity)12418 dns_zone_setchecknames(dns_zone_t *zone, dns_severity_t severity) {
12419
12420 REQUIRE(DNS_ZONE_VALID(zone));
12421
12422 zone->check_names = severity;
12423 }
12424
12425 dns_severity_t
dns_zone_getchecknames(dns_zone_t * zone)12426 dns_zone_getchecknames(dns_zone_t *zone) {
12427
12428 REQUIRE(DNS_ZONE_VALID(zone));
12429
12430 return (zone->check_names);
12431 }
12432
12433 void
dns_zone_setjournalsize(dns_zone_t * zone,isc_int32_t size)12434 dns_zone_setjournalsize(dns_zone_t *zone, isc_int32_t size) {
12435
12436 REQUIRE(DNS_ZONE_VALID(zone));
12437
12438 zone->journalsize = size;
12439 }
12440
12441 isc_int32_t
dns_zone_getjournalsize(dns_zone_t * zone)12442 dns_zone_getjournalsize(dns_zone_t *zone) {
12443
12444 REQUIRE(DNS_ZONE_VALID(zone));
12445
12446 return (zone->journalsize);
12447 }
12448
12449 static void
zone_namerd_tostr(dns_zone_t * zone,char * buf,size_t length)12450 zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length) {
12451 isc_result_t result = ISC_R_FAILURE;
12452 isc_buffer_t buffer;
12453
12454 REQUIRE(buf != NULL);
12455 REQUIRE(length > 1U);
12456
12457 /*
12458 * Leave space for terminating '\0'.
12459 */
12460 isc_buffer_init(&buffer, buf, (unsigned int)length - 1);
12461 if (zone->type != dns_zone_redirect && zone->type != dns_zone_key) {
12462 if (dns_name_dynamic(&zone->origin))
12463 result = dns_name_totext(&zone->origin, ISC_TRUE, &buffer);
12464 if (result != ISC_R_SUCCESS &&
12465 isc_buffer_availablelength(&buffer) >= (sizeof("<UNKNOWN>") - 1))
12466 isc_buffer_putstr(&buffer, "<UNKNOWN>");
12467
12468 if (isc_buffer_availablelength(&buffer) > 0)
12469 isc_buffer_putstr(&buffer, "/");
12470 (void)dns_rdataclass_totext(zone->rdclass, &buffer);
12471 }
12472
12473 if (zone->view != NULL && strcmp(zone->view->name, "_bind") != 0 &&
12474 strcmp(zone->view->name, "_default") != 0 &&
12475 strlen(zone->view->name) < isc_buffer_availablelength(&buffer)) {
12476 isc_buffer_putstr(&buffer, "/");
12477 isc_buffer_putstr(&buffer, zone->view->name);
12478 }
12479 if (inline_secure(zone) && 9U < isc_buffer_availablelength(&buffer))
12480 isc_buffer_putstr(&buffer, " (signed)");
12481 if (inline_raw(zone) && 11U < isc_buffer_availablelength(&buffer))
12482 isc_buffer_putstr(&buffer, " (unsigned)");
12483
12484 buf[isc_buffer_usedlength(&buffer)] = '\0';
12485 }
12486
12487 static void
zone_name_tostr(dns_zone_t * zone,char * buf,size_t length)12488 zone_name_tostr(dns_zone_t *zone, char *buf, size_t length) {
12489 isc_result_t result = ISC_R_FAILURE;
12490 isc_buffer_t buffer;
12491
12492 REQUIRE(buf != NULL);
12493 REQUIRE(length > 1U);
12494
12495 /*
12496 * Leave space for terminating '\0'.
12497 */
12498 isc_buffer_init(&buffer, buf, (unsigned int)length - 1);
12499 if (dns_name_dynamic(&zone->origin))
12500 result = dns_name_totext(&zone->origin, ISC_TRUE, &buffer);
12501 if (result != ISC_R_SUCCESS &&
12502 isc_buffer_availablelength(&buffer) >= (sizeof("<UNKNOWN>") - 1))
12503 isc_buffer_putstr(&buffer, "<UNKNOWN>");
12504
12505 buf[isc_buffer_usedlength(&buffer)] = '\0';
12506 }
12507
12508 static void
zone_rdclass_tostr(dns_zone_t * zone,char * buf,size_t length)12509 zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length) {
12510 isc_buffer_t buffer;
12511
12512 REQUIRE(buf != NULL);
12513 REQUIRE(length > 1U);
12514
12515 /*
12516 * Leave space for terminating '\0'.
12517 */
12518 isc_buffer_init(&buffer, buf, (unsigned int)length - 1);
12519 (void)dns_rdataclass_totext(zone->rdclass, &buffer);
12520
12521 buf[isc_buffer_usedlength(&buffer)] = '\0';
12522 }
12523
12524 static void
zone_viewname_tostr(dns_zone_t * zone,char * buf,size_t length)12525 zone_viewname_tostr(dns_zone_t *zone, char *buf, size_t length) {
12526 isc_buffer_t buffer;
12527
12528 REQUIRE(buf != NULL);
12529 REQUIRE(length > 1U);
12530
12531
12532 /*
12533 * Leave space for terminating '\0'.
12534 */
12535 isc_buffer_init(&buffer, buf, (unsigned int)length - 1);
12536
12537 if (zone->view == NULL) {
12538 isc_buffer_putstr(&buffer, "_none");
12539 } else if (strlen(zone->view->name)
12540 < isc_buffer_availablelength(&buffer)) {
12541 isc_buffer_putstr(&buffer, zone->view->name);
12542 } else {
12543 isc_buffer_putstr(&buffer, "_toolong");
12544 }
12545
12546 buf[isc_buffer_usedlength(&buffer)] = '\0';
12547 }
12548
12549 void
dns_zone_name(dns_zone_t * zone,char * buf,size_t length)12550 dns_zone_name(dns_zone_t *zone, char *buf, size_t length) {
12551 REQUIRE(DNS_ZONE_VALID(zone));
12552 REQUIRE(buf != NULL);
12553 zone_namerd_tostr(zone, buf, length);
12554 }
12555
12556 void
dns_zone_nameonly(dns_zone_t * zone,char * buf,size_t length)12557 dns_zone_nameonly(dns_zone_t *zone, char *buf, size_t length) {
12558 REQUIRE(DNS_ZONE_VALID(zone));
12559 REQUIRE(buf != NULL);
12560 zone_name_tostr(zone, buf, length);
12561 }
12562
12563 static void
notify_log(dns_zone_t * zone,int level,const char * fmt,...)12564 notify_log(dns_zone_t *zone, int level, const char *fmt, ...) {
12565 va_list ap;
12566 char message[4096];
12567
12568 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
12569 return;
12570
12571 va_start(ap, fmt);
12572 vsnprintf(message, sizeof(message), fmt, ap);
12573 va_end(ap);
12574 isc_log_write(dns_lctx, DNS_LOGCATEGORY_NOTIFY, DNS_LOGMODULE_ZONE,
12575 level, "zone %s: %s", zone->strnamerd, message);
12576 }
12577
12578 void
dns_zone_logc(dns_zone_t * zone,isc_logcategory_t * category,int level,const char * fmt,...)12579 dns_zone_logc(dns_zone_t *zone, isc_logcategory_t *category,
12580 int level, const char *fmt, ...) {
12581 va_list ap;
12582 char message[4096];
12583
12584 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
12585 return;
12586
12587 va_start(ap, fmt);
12588 vsnprintf(message, sizeof(message), fmt, ap);
12589 va_end(ap);
12590 isc_log_write(dns_lctx, category, DNS_LOGMODULE_ZONE,
12591 level, "%s%s: %s", (zone->type == dns_zone_key) ?
12592 "managed-keys-zone" : (zone->type == dns_zone_redirect) ?
12593 "redirect-zone" : "zone ", zone->strnamerd, message);
12594 }
12595
12596 void
dns_zone_log(dns_zone_t * zone,int level,const char * fmt,...)12597 dns_zone_log(dns_zone_t *zone, int level, const char *fmt, ...) {
12598 va_list ap;
12599 char message[4096];
12600
12601 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
12602 return;
12603
12604 va_start(ap, fmt);
12605 vsnprintf(message, sizeof(message), fmt, ap);
12606 va_end(ap);
12607 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE,
12608 level, "%s%s: %s", (zone->type == dns_zone_key) ?
12609 "managed-keys-zone" : (zone->type == dns_zone_redirect) ?
12610 "redirect-zone" : "zone ", zone->strnamerd, message);
12611 }
12612
12613 static void
zone_debuglog(dns_zone_t * zone,const char * me,int debuglevel,const char * fmt,...)12614 zone_debuglog(dns_zone_t *zone, const char *me, int debuglevel,
12615 const char *fmt, ...)
12616 {
12617 va_list ap;
12618 char message[4096];
12619 int level = ISC_LOG_DEBUG(debuglevel);
12620 const char *zstr;
12621
12622 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
12623 return;
12624
12625 va_start(ap, fmt);
12626 vsnprintf(message, sizeof(message), fmt, ap);
12627 va_end(ap);
12628
12629 switch (zone->type) {
12630 case dns_zone_key:
12631 zstr = "managed-keys-zone";
12632 break;
12633 case dns_zone_redirect:
12634 zstr = "redirect-zone";
12635 break;
12636 default:
12637 zstr = "zone";
12638 }
12639
12640 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE,
12641 level, "%s: %s %s: %s", me, zstr, zone->strnamerd,
12642 message);
12643 }
12644
12645 static int
message_count(dns_message_t * msg,dns_section_t section,dns_rdatatype_t type)12646 message_count(dns_message_t *msg, dns_section_t section, dns_rdatatype_t type)
12647 {
12648 isc_result_t result;
12649 dns_name_t *name;
12650 dns_rdataset_t *curr;
12651 int count = 0;
12652
12653 result = dns_message_firstname(msg, section);
12654 while (result == ISC_R_SUCCESS) {
12655 name = NULL;
12656 dns_message_currentname(msg, section, &name);
12657
12658 for (curr = ISC_LIST_TAIL(name->list); curr != NULL;
12659 curr = ISC_LIST_PREV(curr, link)) {
12660 if (curr->type == type)
12661 count++;
12662 }
12663 result = dns_message_nextname(msg, section);
12664 }
12665
12666 return (count);
12667 }
12668
12669 void
dns_zone_setmaxxfrin(dns_zone_t * zone,isc_uint32_t maxxfrin)12670 dns_zone_setmaxxfrin(dns_zone_t *zone, isc_uint32_t maxxfrin) {
12671 REQUIRE(DNS_ZONE_VALID(zone));
12672
12673 zone->maxxfrin = maxxfrin;
12674 }
12675
12676 isc_uint32_t
dns_zone_getmaxxfrin(dns_zone_t * zone)12677 dns_zone_getmaxxfrin(dns_zone_t *zone) {
12678 REQUIRE(DNS_ZONE_VALID(zone));
12679
12680 return (zone->maxxfrin);
12681 }
12682
12683 void
dns_zone_setmaxxfrout(dns_zone_t * zone,isc_uint32_t maxxfrout)12684 dns_zone_setmaxxfrout(dns_zone_t *zone, isc_uint32_t maxxfrout) {
12685 REQUIRE(DNS_ZONE_VALID(zone));
12686 zone->maxxfrout = maxxfrout;
12687 }
12688
12689 isc_uint32_t
dns_zone_getmaxxfrout(dns_zone_t * zone)12690 dns_zone_getmaxxfrout(dns_zone_t *zone) {
12691 REQUIRE(DNS_ZONE_VALID(zone));
12692
12693 return (zone->maxxfrout);
12694 }
12695
12696 dns_zonetype_t
dns_zone_gettype(dns_zone_t * zone)12697 dns_zone_gettype(dns_zone_t *zone) {
12698 REQUIRE(DNS_ZONE_VALID(zone));
12699
12700 return (zone->type);
12701 }
12702
12703 dns_name_t *
dns_zone_getorigin(dns_zone_t * zone)12704 dns_zone_getorigin(dns_zone_t *zone) {
12705 REQUIRE(DNS_ZONE_VALID(zone));
12706
12707 return (&zone->origin);
12708 }
12709
12710 void
dns_zone_settask(dns_zone_t * zone,isc_task_t * task)12711 dns_zone_settask(dns_zone_t *zone, isc_task_t *task) {
12712 REQUIRE(DNS_ZONE_VALID(zone));
12713
12714 LOCK_ZONE(zone);
12715 if (zone->task != NULL)
12716 isc_task_detach(&zone->task);
12717 isc_task_attach(task, &zone->task);
12718 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
12719 if (zone->db != NULL)
12720 dns_db_settask(zone->db, zone->task);
12721 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
12722 UNLOCK_ZONE(zone);
12723 }
12724
12725 void
dns_zone_gettask(dns_zone_t * zone,isc_task_t ** target)12726 dns_zone_gettask(dns_zone_t *zone, isc_task_t **target) {
12727 REQUIRE(DNS_ZONE_VALID(zone));
12728 isc_task_attach(zone->task, target);
12729 }
12730
12731 void
dns_zone_setidlein(dns_zone_t * zone,isc_uint32_t idlein)12732 dns_zone_setidlein(dns_zone_t *zone, isc_uint32_t idlein) {
12733 REQUIRE(DNS_ZONE_VALID(zone));
12734
12735 if (idlein == 0)
12736 idlein = DNS_DEFAULT_IDLEIN;
12737 zone->idlein = idlein;
12738 }
12739
12740 isc_uint32_t
dns_zone_getidlein(dns_zone_t * zone)12741 dns_zone_getidlein(dns_zone_t *zone) {
12742 REQUIRE(DNS_ZONE_VALID(zone));
12743
12744 return (zone->idlein);
12745 }
12746
12747 void
dns_zone_setidleout(dns_zone_t * zone,isc_uint32_t idleout)12748 dns_zone_setidleout(dns_zone_t *zone, isc_uint32_t idleout) {
12749 REQUIRE(DNS_ZONE_VALID(zone));
12750
12751 zone->idleout = idleout;
12752 }
12753
12754 isc_uint32_t
dns_zone_getidleout(dns_zone_t * zone)12755 dns_zone_getidleout(dns_zone_t *zone) {
12756 REQUIRE(DNS_ZONE_VALID(zone));
12757
12758 return (zone->idleout);
12759 }
12760
12761 static void
notify_done(isc_task_t * task,isc_event_t * event)12762 notify_done(isc_task_t *task, isc_event_t *event) {
12763 dns_requestevent_t *revent = (dns_requestevent_t *)event;
12764 dns_notify_t *notify;
12765 isc_result_t result;
12766 dns_message_t *message = NULL;
12767 isc_buffer_t buf;
12768 char rcode[128];
12769 char addrbuf[ISC_SOCKADDR_FORMATSIZE];
12770
12771 UNUSED(task);
12772
12773 notify = event->ev_arg;
12774 REQUIRE(DNS_NOTIFY_VALID(notify));
12775 INSIST(task == notify->zone->task);
12776
12777 isc_buffer_init(&buf, rcode, sizeof(rcode));
12778 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf));
12779
12780 result = revent->result;
12781 if (result == ISC_R_SUCCESS)
12782 result = dns_message_create(notify->zone->mctx,
12783 DNS_MESSAGE_INTENTPARSE, &message);
12784 if (result == ISC_R_SUCCESS)
12785 result = dns_request_getresponse(revent->request, message,
12786 DNS_MESSAGEPARSE_PRESERVEORDER);
12787 if (result == ISC_R_SUCCESS)
12788 result = dns_rcode_totext(message->rcode, &buf);
12789 if (result == ISC_R_SUCCESS)
12790 notify_log(notify->zone, ISC_LOG_DEBUG(3),
12791 "notify response from %s: %.*s",
12792 addrbuf, (int)buf.used, rcode);
12793 else
12794 notify_log(notify->zone, ISC_LOG_DEBUG(2),
12795 "notify to %s failed: %s", addrbuf,
12796 dns_result_totext(result));
12797
12798 /*
12799 * Old bind's return formerr if they see a soa record. Retry w/o
12800 * the soa if we see a formerr and had sent a SOA.
12801 */
12802 isc_event_free(&event);
12803 if (message != NULL && message->rcode == dns_rcode_formerr &&
12804 (notify->flags & DNS_NOTIFY_NOSOA) == 0) {
12805 isc_boolean_t startup;
12806
12807 notify->flags |= DNS_NOTIFY_NOSOA;
12808 dns_request_destroy(¬ify->request);
12809 startup = ISC_TF((notify->flags & DNS_NOTIFY_STARTUP) != 0);
12810 result = notify_send_queue(notify, startup);
12811 if (result != ISC_R_SUCCESS)
12812 notify_destroy(notify, ISC_FALSE);
12813 } else {
12814 if (result == ISC_R_TIMEDOUT)
12815 notify_log(notify->zone, ISC_LOG_DEBUG(1),
12816 "notify to %s: retries exceeded", addrbuf);
12817 notify_destroy(notify, ISC_FALSE);
12818 }
12819 if (message != NULL)
12820 dns_message_destroy(&message);
12821 }
12822
12823 struct secure_event {
12824 isc_event_t e;
12825 dns_db_t *db;
12826 isc_uint32_t serial;
12827 };
12828
12829 static void
update_log_cb(void * arg,dns_zone_t * zone,int level,const char * message)12830 update_log_cb(void *arg, dns_zone_t *zone, int level, const char *message) {
12831 UNUSED(arg);
12832 dns_zone_log(zone, level, "%s", message);
12833 }
12834
12835 static isc_result_t
sync_secure_journal(dns_zone_t * zone,dns_zone_t * raw,dns_journal_t * journal,isc_uint32_t start,isc_uint32_t end,dns_difftuple_t ** soatuplep,dns_diff_t * diff)12836 sync_secure_journal(dns_zone_t *zone, dns_zone_t *raw, dns_journal_t *journal,
12837 isc_uint32_t start, isc_uint32_t end,
12838 dns_difftuple_t **soatuplep, dns_diff_t *diff)
12839 {
12840 isc_result_t result;
12841 dns_difftuple_t *tuple = NULL;
12842 dns_diffop_t op = DNS_DIFFOP_ADD;
12843 int n_soa = 0;
12844
12845 REQUIRE(soatuplep != NULL);
12846
12847 if (start == end)
12848 return (DNS_R_UNCHANGED);
12849
12850 CHECK(dns_journal_iter_init(journal, start, end));
12851 for (result = dns_journal_first_rr(journal);
12852 result == ISC_R_SUCCESS;
12853 result = dns_journal_next_rr(journal))
12854 {
12855 dns_name_t *name = NULL;
12856 isc_uint32_t ttl;
12857 dns_rdata_t *rdata = NULL;
12858 dns_journal_current_rr(journal, &name, &ttl, &rdata);
12859
12860 if (rdata->type == dns_rdatatype_soa) {
12861 n_soa++;
12862 if (n_soa == 2) {
12863 /*
12864 * Save the latest raw SOA record.
12865 */
12866 if (*soatuplep != NULL)
12867 dns_difftuple_free(soatuplep);
12868 CHECK(dns_difftuple_create(diff->mctx,
12869 DNS_DIFFOP_ADD,
12870 name, ttl, rdata,
12871 soatuplep));
12872 }
12873 if (n_soa == 3)
12874 n_soa = 1;
12875 continue;
12876 }
12877
12878 /* Sanity. */
12879 if (n_soa == 0) {
12880 dns_zone_log(raw, ISC_LOG_ERROR,
12881 "corrupt journal file: '%s'\n",
12882 raw->journal);
12883 return (ISC_R_FAILURE);
12884 }
12885
12886 if (zone->privatetype != 0 &&
12887 rdata->type == zone->privatetype)
12888 continue;
12889
12890 if (rdata->type == dns_rdatatype_nsec ||
12891 rdata->type == dns_rdatatype_rrsig ||
12892 rdata->type == dns_rdatatype_nsec3 ||
12893 rdata->type == dns_rdatatype_dnskey ||
12894 rdata->type == dns_rdatatype_nsec3param)
12895 continue;
12896
12897 op = (n_soa == 1) ? DNS_DIFFOP_DEL : DNS_DIFFOP_ADD;
12898
12899 CHECK(dns_difftuple_create(diff->mctx, op, name, ttl, rdata,
12900 &tuple));
12901 dns_diff_appendminimal(diff, &tuple);
12902 }
12903 if (result == ISC_R_NOMORE)
12904 result = ISC_R_SUCCESS;
12905
12906 failure:
12907 return(result);
12908 }
12909
12910 static isc_result_t
sync_secure_db(dns_zone_t * seczone,dns_zone_t * raw,dns_db_t * secdb,dns_dbversion_t * secver,dns_difftuple_t ** soatuple,dns_diff_t * diff)12911 sync_secure_db(dns_zone_t *seczone, dns_zone_t *raw, dns_db_t *secdb,
12912 dns_dbversion_t *secver, dns_difftuple_t **soatuple,
12913 dns_diff_t *diff)
12914 {
12915 isc_result_t result;
12916 dns_db_t *rawdb = NULL;
12917 dns_dbversion_t *rawver = NULL;
12918 dns_difftuple_t *tuple = NULL, *next;
12919 dns_difftuple_t *oldtuple = NULL, *newtuple = NULL;
12920 dns_rdata_soa_t oldsoa, newsoa;
12921
12922 REQUIRE(DNS_ZONE_VALID(seczone));
12923 REQUIRE(soatuple != NULL && *soatuple == NULL);
12924
12925 if (!seczone->sourceserialset)
12926 return (DNS_R_UNCHANGED);
12927
12928 dns_db_attach(raw->db, &rawdb);
12929 dns_db_currentversion(rawdb, &rawver);
12930 result = dns_db_diffx(diff, rawdb, rawver, secdb, secver, NULL);
12931 dns_db_closeversion(rawdb, &rawver, ISC_FALSE);
12932 dns_db_detach(&rawdb);
12933
12934 if (result != ISC_R_SUCCESS)
12935 return (result);
12936
12937 for (tuple = ISC_LIST_HEAD(diff->tuples);
12938 tuple != NULL;
12939 tuple = next)
12940 {
12941 next = ISC_LIST_NEXT(tuple, link);
12942 if (tuple->rdata.type == dns_rdatatype_nsec ||
12943 tuple->rdata.type == dns_rdatatype_rrsig ||
12944 tuple->rdata.type == dns_rdatatype_dnskey ||
12945 tuple->rdata.type == dns_rdatatype_nsec3 ||
12946 tuple->rdata.type == dns_rdatatype_nsec3param)
12947 {
12948 ISC_LIST_UNLINK(diff->tuples, tuple, link);
12949 dns_difftuple_free(&tuple);
12950 continue;
12951 }
12952 if (tuple->rdata.type == dns_rdatatype_soa) {
12953 if (tuple->op == DNS_DIFFOP_DEL) {
12954 INSIST(oldtuple == NULL);
12955 oldtuple = tuple;
12956 }
12957 if (tuple->op == DNS_DIFFOP_ADD) {
12958 INSIST(newtuple == NULL);
12959 newtuple = tuple;
12960 }
12961 }
12962 }
12963
12964 if (oldtuple != NULL && newtuple != NULL) {
12965
12966 result = dns_rdata_tostruct(&oldtuple->rdata, &oldsoa, NULL);
12967 RUNTIME_CHECK(result == ISC_R_SUCCESS);
12968
12969 result = dns_rdata_tostruct(&newtuple->rdata, &newsoa, NULL);
12970 RUNTIME_CHECK(result == ISC_R_SUCCESS);
12971
12972 /*
12973 * If the SOA records are the same except for the serial
12974 * remove them from the diff.
12975 */
12976 if (oldsoa.refresh == newsoa.refresh &&
12977 oldsoa.retry == newsoa.retry &&
12978 oldsoa.minimum == newsoa.minimum &&
12979 oldsoa.expire == newsoa.expire &&
12980 dns_name_equal(&oldsoa.origin, &newsoa.origin) &&
12981 dns_name_equal(&oldsoa.contact, &newsoa.contact)) {
12982 ISC_LIST_UNLINK(diff->tuples, oldtuple, link);
12983 dns_difftuple_free(&oldtuple);
12984 ISC_LIST_UNLINK(diff->tuples, newtuple, link);
12985 dns_difftuple_free(&newtuple);
12986 }
12987 }
12988
12989 if (ISC_LIST_EMPTY(diff->tuples))
12990 return (DNS_R_UNCHANGED);
12991
12992 /*
12993 * If there are still SOA records in the diff they can now be removed
12994 * saving the new SOA record.
12995 */
12996 if (oldtuple != NULL) {
12997 ISC_LIST_UNLINK(diff->tuples, oldtuple, link);
12998 dns_difftuple_free(&oldtuple);
12999 }
13000
13001 if (newtuple != NULL) {
13002 ISC_LIST_UNLINK(diff->tuples, newtuple, link);
13003 *soatuple = newtuple;
13004 }
13005
13006 return (ISC_R_SUCCESS);
13007 }
13008
13009 static void
receive_secure_serial(isc_task_t * task,isc_event_t * event)13010 receive_secure_serial(isc_task_t *task, isc_event_t *event) {
13011 static char me[] = "receive_secure_serial";
13012 isc_result_t result = ISC_R_SUCCESS;
13013 dns_journal_t *rjournal = NULL;
13014 dns_journal_t *sjournal = NULL;
13015 isc_uint32_t start, end;
13016 dns_zone_t *zone;
13017 dns_difftuple_t *tuple = NULL, *soatuple = NULL;
13018 dns_update_log_t log = { update_log_cb, NULL };
13019 isc_time_t timenow;
13020
13021 UNUSED(task);
13022
13023 zone = event->ev_arg;
13024 end = ((struct secure_event *)event)->serial;
13025
13026 ENTER;
13027
13028 LOCK_ZONE(zone);
13029
13030 /*
13031 * If we are already processing a receive secure serial event
13032 * for the zone, just queue the new one and exit.
13033 */
13034 if (zone->rss_event != NULL && zone->rss_event != event) {
13035 ISC_LIST_APPEND(zone->rss_events, event, ev_link);
13036 UNLOCK_ZONE(zone);
13037 return;
13038 }
13039
13040 nextevent:
13041 if (zone->rss_event != NULL) {
13042 INSIST(zone->rss_event == event);
13043 UNLOCK_ZONE(zone);
13044 } else {
13045 zone->rss_event = event;
13046 dns_diff_init(zone->mctx, &zone->rss_diff);
13047
13048 /*
13049 * zone->db may be NULL, if the load from disk failed.
13050 */
13051 result = ISC_R_SUCCESS;
13052 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
13053 if (zone->db != NULL)
13054 dns_db_attach(zone->db, &zone->rss_db);
13055 else
13056 result = ISC_R_FAILURE;
13057 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
13058
13059 if (result == ISC_R_SUCCESS && zone->raw != NULL)
13060 dns_zone_attach(zone->raw, &zone->rss_raw);
13061 else
13062 result = ISC_R_FAILURE;
13063
13064 UNLOCK_ZONE(zone);
13065
13066 CHECK(result);
13067
13068 /*
13069 * We first attempt to sync the raw zone to the secure zone
13070 * by using the raw zone's journal, applying all the deltas
13071 * from the latest source-serial of the secure zone up to
13072 * the current serial number of the raw zone.
13073 *
13074 * If that fails, then we'll fall back to a direct comparison
13075 * between raw and secure zones.
13076 */
13077 CHECK(dns_journal_open(zone->rss_raw->mctx,
13078 zone->rss_raw->journal,
13079 DNS_JOURNAL_WRITE, &rjournal));
13080
13081 result = dns_journal_open(zone->mctx, zone->journal,
13082 DNS_JOURNAL_READ, &sjournal);
13083 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
13084 goto failure;
13085
13086 if (!dns_journal_get_sourceserial(rjournal, &start)) {
13087 start = dns_journal_first_serial(rjournal);
13088 dns_journal_set_sourceserial(rjournal, start);
13089 }
13090 if (sjournal != NULL) {
13091 isc_uint32_t serial;
13092 /*
13093 * We read the secure journal first, if that
13094 * exists use its value provided it is greater
13095 * that from the raw journal.
13096 */
13097 if (dns_journal_get_sourceserial(sjournal, &serial)) {
13098 if (isc_serial_gt(serial, start))
13099 start = serial;
13100 }
13101 dns_journal_destroy(&sjournal);
13102 }
13103
13104 dns_db_currentversion(zone->rss_db, &zone->rss_oldver);
13105 CHECK(dns_db_newversion(zone->rss_db, &zone->rss_newver));
13106
13107 /*
13108 * Try to apply diffs from the raw zone's journal to the secure
13109 * zone. If that fails, we recover by syncing up the databases
13110 * directly.
13111 */
13112 result = sync_secure_journal(zone, zone->rss_raw, rjournal,
13113 start, end, &soatuple,
13114 &zone->rss_diff);
13115 if (result == DNS_R_UNCHANGED)
13116 goto failure;
13117 else if (result != ISC_R_SUCCESS)
13118 CHECK(sync_secure_db(zone, zone->rss_raw, zone->rss_db,
13119 zone->rss_oldver, &soatuple,
13120 &zone->rss_diff));
13121
13122 CHECK(dns_diff_apply(&zone->rss_diff, zone->rss_db,
13123 zone->rss_newver));
13124
13125 if (soatuple != NULL) {
13126 isc_uint32_t oldserial, newserial, desired;
13127
13128 CHECK(dns_db_createsoatuple(zone->rss_db,
13129 zone->rss_oldver,
13130 zone->rss_diff.mctx,
13131 DNS_DIFFOP_DEL, &tuple));
13132 oldserial = dns_soa_getserial(&tuple->rdata);
13133 newserial = desired =
13134 dns_soa_getserial(&soatuple->rdata);
13135 if (!isc_serial_gt(newserial, oldserial)) {
13136 newserial = oldserial + 1;
13137 if (newserial == 0)
13138 newserial++;
13139 dns_soa_setserial(newserial, &soatuple->rdata);
13140 }
13141 CHECK(do_one_tuple(&tuple, zone->rss_db,
13142 zone->rss_newver, &zone->rss_diff));
13143 CHECK(do_one_tuple(&soatuple, zone->rss_db,
13144 zone->rss_newver, &zone->rss_diff));
13145 dns_zone_log(zone, ISC_LOG_INFO,
13146 "serial %u (unsigned %u)",
13147 newserial, desired);
13148 } else
13149 CHECK(update_soa_serial(zone->rss_db, zone->rss_newver,
13150 &zone->rss_diff, zone->mctx,
13151 zone->updatemethod));
13152
13153 }
13154 result = dns_update_signaturesinc(&log, zone, zone->rss_db,
13155 zone->rss_oldver, zone->rss_newver,
13156 &zone->rss_diff,
13157 zone->sigvalidityinterval,
13158 &zone->rss_state);
13159 if (result == DNS_R_CONTINUE) {
13160 if (rjournal != NULL)
13161 dns_journal_destroy(&rjournal);
13162 isc_task_send(task, &event);
13163 fprintf(stderr, "looping on dns_update_signaturesinc\n");
13164 return;
13165 }
13166 if (result != ISC_R_SUCCESS)
13167 goto failure;
13168
13169 if (rjournal == NULL)
13170 CHECK(dns_journal_open(zone->rss_raw->mctx,
13171 zone->rss_raw->journal,
13172 DNS_JOURNAL_WRITE, &rjournal));
13173 CHECK(zone_journal(zone, &zone->rss_diff, &end,
13174 "receive_secure_serial"));
13175
13176 dns_journal_set_sourceserial(rjournal, end);
13177 dns_journal_commit(rjournal);
13178
13179 LOCK_ZONE(zone);
13180 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
13181
13182 zone->sourceserial = end;
13183 zone->sourceserialset = ISC_TRUE;
13184 zone_needdump(zone, DNS_DUMP_DELAY);
13185
13186 TIME_NOW(&timenow);
13187 zone_settimer(zone, &timenow);
13188 UNLOCK_ZONE(zone);
13189
13190 dns_db_closeversion(zone->rss_db, &zone->rss_oldver, ISC_FALSE);
13191 dns_db_closeversion(zone->rss_db, &zone->rss_newver, ISC_TRUE);
13192
13193 failure:
13194 isc_event_free(&zone->rss_event);
13195 event = ISC_LIST_HEAD(zone->rss_events);
13196
13197 if (zone->rss_raw != NULL)
13198 dns_zone_detach(&zone->rss_raw);
13199 if (result != ISC_R_SUCCESS)
13200 dns_zone_log(zone, ISC_LOG_ERROR, "receive_secure_serial: %s",
13201 dns_result_totext(result));
13202 if (tuple != NULL)
13203 dns_difftuple_free(&tuple);
13204 if (soatuple != NULL)
13205 dns_difftuple_free(&soatuple);
13206 if (zone->rss_db != NULL) {
13207 if (zone->rss_oldver != NULL)
13208 dns_db_closeversion(zone->rss_db, &zone->rss_oldver,
13209 ISC_FALSE);
13210 if (zone->rss_newver != NULL)
13211 dns_db_closeversion(zone->rss_db, &zone->rss_newver,
13212 ISC_FALSE);
13213 dns_db_detach(&zone->rss_db);
13214 }
13215 INSIST(zone->rss_oldver == NULL);
13216 INSIST(zone->rss_newver == NULL);
13217 if (rjournal != NULL)
13218 dns_journal_destroy(&rjournal);
13219 dns_diff_clear(&zone->rss_diff);
13220
13221 if (event != NULL) {
13222 LOCK_ZONE(zone);
13223 INSIST(zone->irefs > 1);
13224 zone->irefs--;
13225 goto nextevent;
13226 }
13227 dns_zone_idetach(&zone);
13228 }
13229
13230 static isc_result_t
zone_send_secureserial(dns_zone_t * zone,isc_uint32_t serial)13231 zone_send_secureserial(dns_zone_t *zone, isc_uint32_t serial) {
13232 isc_event_t *e;
13233 dns_zone_t *dummy = NULL;
13234
13235 e = isc_event_allocate(zone->secure->mctx, zone,
13236 DNS_EVENT_ZONESECURESERIAL,
13237 receive_secure_serial, zone->secure,
13238 sizeof(struct secure_event));
13239 if (e == NULL)
13240 return (ISC_R_NOMEMORY);
13241 ((struct secure_event *)e)->serial = serial;
13242 INSIST(LOCKED_ZONE(zone->secure));
13243 zone_iattach(zone->secure, &dummy);
13244 isc_task_send(zone->secure->task, &e);
13245
13246 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SENDSECURE);
13247 return (ISC_R_SUCCESS);
13248 }
13249
13250 static isc_result_t
checkandaddsoa(dns_db_t * db,dns_dbnode_t * node,dns_dbversion_t * version,dns_rdataset_t * rdataset,isc_uint32_t oldserial)13251 checkandaddsoa(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
13252 dns_rdataset_t *rdataset, isc_uint32_t oldserial)
13253 {
13254 dns_rdata_soa_t soa;
13255 dns_rdata_t rdata = DNS_RDATA_INIT;
13256 dns_rdatalist_t temprdatalist;
13257 dns_rdataset_t temprdataset;
13258 isc_buffer_t b;
13259 isc_result_t result;
13260 unsigned char buf[DNS_SOA_BUFFERSIZE];
13261
13262 result = dns_rdataset_first(rdataset);
13263 RUNTIME_CHECK(result == ISC_R_SUCCESS);
13264 dns_rdataset_current(rdataset, &rdata);
13265 result = dns_rdata_tostruct(&rdata, &soa, NULL);
13266 RUNTIME_CHECK(result == ISC_R_SUCCESS);
13267
13268 if (isc_serial_gt(soa.serial, oldserial))
13269 return (dns_db_addrdataset(db, node, version, 0, rdataset, 0,
13270 NULL));
13271 /*
13272 * Always bump the serial.
13273 */
13274 oldserial++;
13275 if (oldserial == 0)
13276 oldserial++;
13277 soa.serial = oldserial;
13278
13279 /*
13280 * Construct a replacement rdataset.
13281 */
13282 dns_rdata_reset(&rdata);
13283 isc_buffer_init(&b, buf, sizeof(buf));
13284 result = dns_rdata_fromstruct(&rdata, rdataset->rdclass,
13285 dns_rdatatype_soa, &soa, &b);
13286 RUNTIME_CHECK(result == ISC_R_SUCCESS);
13287 dns_rdatalist_init(&temprdatalist);
13288 temprdatalist.rdclass = rdata.rdclass;
13289 temprdatalist.type = rdata.type;
13290 temprdatalist.ttl = rdataset->ttl;
13291 ISC_LIST_APPEND(temprdatalist.rdata, &rdata, link);
13292
13293 dns_rdataset_init(&temprdataset);
13294 result = dns_rdatalist_tordataset(&temprdatalist, &temprdataset);
13295 RUNTIME_CHECK(result == ISC_R_SUCCESS);
13296 return (dns_db_addrdataset(db, node, version, 0, &temprdataset,
13297 0, NULL));
13298 }
13299
13300 /*
13301 * This function should populate an nsec3paramlist_t with the
13302 * nsecparam_t data from a zone.
13303 */
13304 static isc_result_t
save_nsec3param(dns_zone_t * zone,nsec3paramlist_t * nsec3list)13305 save_nsec3param(dns_zone_t *zone, nsec3paramlist_t *nsec3list) {
13306 isc_result_t result;
13307 dns_dbnode_t *node = NULL;
13308 dns_rdataset_t rdataset, prdataset;
13309 dns_dbversion_t *version = NULL;
13310 nsec3param_t *nsec3param = NULL;
13311 nsec3param_t *nsec3p = NULL;
13312 nsec3param_t *next;
13313 dns_db_t *db = NULL;
13314 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
13315
13316 REQUIRE(DNS_ZONE_VALID(zone));
13317 REQUIRE(nsec3list != NULL);
13318 REQUIRE(ISC_LIST_EMPTY(*nsec3list));
13319
13320 dns_rdataset_init(&rdataset);
13321 dns_rdataset_init(&prdataset);
13322
13323 dns_db_attach(zone->db, &db);
13324 CHECK(dns_db_getoriginnode(db, &node));
13325
13326 dns_db_currentversion(db, &version);
13327 result = dns_db_findrdataset(db, node, version,
13328 dns_rdatatype_nsec3param,
13329 dns_rdatatype_none, 0, &rdataset, NULL);
13330
13331 if (result != ISC_R_SUCCESS)
13332 goto getprivate;
13333
13334 /*
13335 * walk nsec3param rdataset making a list of parameters (note that
13336 * multiple simultaneous nsec3 chains are annoyingly legal -- this
13337 * is why we use an nsec3list, even tho we will usually only have
13338 * one)
13339 */
13340 for (result = dns_rdataset_first(&rdataset);
13341 result == ISC_R_SUCCESS;
13342 result = dns_rdataset_next(&rdataset))
13343 {
13344 dns_rdata_t rdata = DNS_RDATA_INIT;
13345 dns_rdata_t private = DNS_RDATA_INIT;
13346
13347 dns_rdataset_current(&rdataset, &rdata);
13348 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
13349 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
13350 "looping through nsec3param data");
13351 nsec3param = isc_mem_get(zone->mctx, sizeof(nsec3param_t));
13352 if (nsec3param == NULL)
13353 CHECK(ISC_R_NOMEMORY);
13354 ISC_LINK_INIT(nsec3param, link);
13355
13356 /*
13357 * now transfer the data from the rdata to
13358 * the nsec3param
13359 */
13360 dns_nsec3param_toprivate(&rdata, &private,
13361 zone->privatetype, nsec3param->data,
13362 sizeof(nsec3param->data));
13363 nsec3param->length = private.length;
13364 ISC_LIST_APPEND(*nsec3list, nsec3param, link);
13365 }
13366
13367 getprivate:
13368 result = dns_db_findrdataset(db, node, version, zone->privatetype,
13369 dns_rdatatype_none, 0, &prdataset, NULL);
13370 if (result != ISC_R_SUCCESS)
13371 goto done;
13372
13373 /*
13374 * walk private type records, converting them to nsec3 parameters
13375 * using dns_nsec3param_fromprivate(), do the right thing based on
13376 * CREATE and REMOVE flags
13377 */
13378 for (result = dns_rdataset_first(&prdataset);
13379 result == ISC_R_SUCCESS;
13380 result = dns_rdataset_next(&prdataset))
13381 {
13382 dns_rdata_t rdata = DNS_RDATA_INIT;
13383 dns_rdata_t private = DNS_RDATA_INIT;
13384
13385 dns_rdataset_current(&prdataset, &private);
13386 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
13387 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
13388 "looping through nsec3param private data");
13389
13390 /*
13391 * Do we have a valid private record?
13392 */
13393 if (!dns_nsec3param_fromprivate(&private, &rdata,
13394 buf, sizeof(buf)))
13395 continue;
13396
13397 /*
13398 * Remove any NSEC3PARAM records scheduled to be removed.
13399 */
13400 if (NSEC3REMOVE(rdata.data[1])) {
13401 /*
13402 * Zero out the flags.
13403 */
13404 rdata.data[1] = 0;
13405
13406 for (nsec3p = ISC_LIST_HEAD(*nsec3list);
13407 nsec3p != NULL;
13408 nsec3p = next)
13409 {
13410 next = ISC_LIST_NEXT(nsec3p, link);
13411
13412 if (nsec3p->length == rdata.length + 1 &&
13413 memcmp(rdata.data, nsec3p->data + 1,
13414 nsec3p->length - 1) == 0) {
13415 ISC_LIST_UNLINK(*nsec3list,
13416 nsec3p, link);
13417 isc_mem_put(zone->mctx, nsec3p,
13418 sizeof(nsec3param_t));
13419 }
13420 }
13421 continue;
13422 }
13423
13424 nsec3param = isc_mem_get(zone->mctx, sizeof(nsec3param_t));
13425 if (nsec3param == NULL)
13426 CHECK(ISC_R_NOMEMORY);
13427 ISC_LINK_INIT(nsec3param, link);
13428
13429 /*
13430 * Copy the remaining private records so the nsec/nsec3
13431 * chain gets created.
13432 */
13433 INSIST(private.length <= sizeof(nsec3param->data));
13434 memmove(nsec3param->data, private.data, private.length);
13435 nsec3param->length = private.length;
13436 ISC_LIST_APPEND(*nsec3list, nsec3param, link);
13437 }
13438
13439 done:
13440 if (result == ISC_R_NOMORE || result == ISC_R_NOTFOUND)
13441 result = ISC_R_SUCCESS;
13442
13443 failure:
13444 if (node != NULL)
13445 dns_db_detachnode(db, &node);
13446 if (version != NULL)
13447 dns_db_closeversion(db, &version, ISC_FALSE);
13448 if (db != NULL)
13449 dns_db_detach(&db);
13450 if (dns_rdataset_isassociated(&rdataset))
13451 dns_rdataset_disassociate(&rdataset);
13452 if (dns_rdataset_isassociated(&prdataset))
13453 dns_rdataset_disassociate(&prdataset);
13454 return (result);
13455 }
13456
13457 /*
13458 * Walk the list of the nsec3 chains desired for the zone, converting
13459 * parameters to private type records using dns_nsec3param_toprivate(),
13460 * and insert them into the new zone db.
13461 */
13462 static isc_result_t
restore_nsec3param(dns_zone_t * zone,dns_db_t * db,dns_dbversion_t * version,nsec3paramlist_t * nsec3list)13463 restore_nsec3param(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
13464 nsec3paramlist_t *nsec3list)
13465 {
13466 isc_result_t result;
13467 dns_diff_t diff;
13468 dns_rdata_t rdata;
13469 nsec3param_t *nsec3p = NULL;
13470 nsec3param_t *next;
13471
13472 REQUIRE(DNS_ZONE_VALID(zone));
13473 REQUIRE(!ISC_LIST_EMPTY(*nsec3list));
13474
13475 dns_diff_init(zone->mctx, &diff);
13476
13477 /*
13478 * Loop through the list of private-type records, set the INITIAL
13479 * and CREATE flags, and the add the record to the apex of the tree
13480 * in db.
13481 */
13482 for (nsec3p = ISC_LIST_HEAD(*nsec3list);
13483 nsec3p != NULL;
13484 nsec3p = next)
13485 {
13486 next = ISC_LIST_NEXT(nsec3p, link);
13487 dns_rdata_init(&rdata);
13488 nsec3p->data[2] = DNS_NSEC3FLAG_CREATE | DNS_NSEC3FLAG_INITIAL;
13489 rdata.length = nsec3p->length;
13490 rdata.data = nsec3p->data;
13491 rdata.type = zone->privatetype;
13492 rdata.rdclass = zone->rdclass;
13493 CHECK(update_one_rr(db, version, &diff, DNS_DIFFOP_ADD,
13494 &zone->origin, 0, &rdata));
13495 }
13496
13497 result = ISC_R_SUCCESS;
13498
13499 failure:
13500 for (nsec3p = ISC_LIST_HEAD(*nsec3list);
13501 nsec3p != NULL;
13502 nsec3p = next)
13503 {
13504 next = ISC_LIST_NEXT(nsec3p, link);
13505 ISC_LIST_UNLINK(*nsec3list, nsec3p, link);
13506 isc_mem_put(zone->mctx, nsec3p, sizeof(nsec3param_t));
13507 }
13508
13509 dns_diff_clear(&diff);
13510 return (result);
13511 }
13512
13513 static void
receive_secure_db(isc_task_t * task,isc_event_t * event)13514 receive_secure_db(isc_task_t *task, isc_event_t *event) {
13515 isc_result_t result;
13516 dns_zone_t *zone;
13517 dns_db_t *rawdb, *db = NULL;
13518 dns_dbnode_t *rawnode = NULL, *node = NULL;
13519 dns_fixedname_t fname;
13520 dns_name_t *name;
13521 dns_dbiterator_t *dbiterator = NULL;
13522 dns_rdatasetiter_t *rdsit = NULL;
13523 dns_rdataset_t rdataset;
13524 dns_dbversion_t *version = NULL;
13525 isc_time_t loadtime;
13526 unsigned int oldserial = 0;
13527 isc_boolean_t have_oldserial = ISC_FALSE;
13528 nsec3paramlist_t nsec3list;
13529
13530 UNUSED(task);
13531
13532 ISC_LIST_INIT(nsec3list);
13533
13534 zone = event->ev_arg;
13535 rawdb = ((struct secure_event *)event)->db;
13536 isc_event_free(&event);
13537
13538 dns_fixedname_init(&fname);
13539 name = dns_fixedname_name(&fname);
13540 dns_rdataset_init(&rdataset);
13541
13542 LOCK_ZONE(zone);
13543 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) || !inline_secure(zone)) {
13544 result = ISC_R_SHUTTINGDOWN;
13545 goto failure;
13546 }
13547
13548 TIME_NOW(&loadtime);
13549 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
13550 if (zone->db != NULL) {
13551 result = dns_db_getsoaserial(zone->db, NULL, &oldserial);
13552 if (result == ISC_R_SUCCESS)
13553 have_oldserial = ISC_TRUE;
13554
13555 /*
13556 * assemble nsec3parameters from the old zone, and set a flag
13557 * if any are found
13558 */
13559 result = save_nsec3param(zone, &nsec3list);
13560 if (result != ISC_R_SUCCESS) {
13561 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
13562 goto failure;
13563 }
13564 }
13565 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
13566
13567 result = dns_db_create(zone->mctx, zone->db_argv[0],
13568 &zone->origin, dns_dbtype_zone, zone->rdclass,
13569 zone->db_argc - 1, zone->db_argv + 1, &db);
13570 if (result != ISC_R_SUCCESS)
13571 goto failure;
13572
13573 result = dns_db_newversion(db, &version);
13574 if (result != ISC_R_SUCCESS)
13575 goto failure;
13576
13577 result = dns_db_createiterator(rawdb, 0, &dbiterator);
13578 if (result != ISC_R_SUCCESS)
13579 goto failure;
13580
13581 for (result = dns_dbiterator_first(dbiterator);
13582 result == ISC_R_SUCCESS;
13583 result = dns_dbiterator_next(dbiterator)) {
13584 result = dns_dbiterator_current(dbiterator, &rawnode, name);
13585 if (result != ISC_R_SUCCESS)
13586 continue;
13587
13588 result = dns_db_findnode(db, name, ISC_TRUE, &node);
13589 if (result != ISC_R_SUCCESS)
13590 goto failure;
13591
13592 result = dns_db_allrdatasets(rawdb, rawnode, NULL, 0, &rdsit);
13593 if (result != ISC_R_SUCCESS)
13594 goto failure;
13595
13596 for (result = dns_rdatasetiter_first(rdsit);
13597 result == ISC_R_SUCCESS;
13598 result = dns_rdatasetiter_next(rdsit)) {
13599 dns_rdatasetiter_current(rdsit, &rdataset);
13600 if (rdataset.type == dns_rdatatype_nsec ||
13601 rdataset.type == dns_rdatatype_rrsig ||
13602 rdataset.type == dns_rdatatype_nsec3 ||
13603 rdataset.type == dns_rdatatype_dnskey ||
13604 rdataset.type == dns_rdatatype_nsec3param) {
13605 dns_rdataset_disassociate(&rdataset);
13606 continue;
13607 }
13608 if (rdataset.type == dns_rdatatype_soa &&
13609 have_oldserial) {
13610 result = checkandaddsoa(db, node, version,
13611 &rdataset, oldserial);
13612 } else
13613 result = dns_db_addrdataset(db, node, version,
13614 0, &rdataset, 0,
13615 NULL);
13616 if (result != ISC_R_SUCCESS)
13617 goto failure;
13618
13619 dns_rdataset_disassociate(&rdataset);
13620 }
13621 dns_rdatasetiter_destroy(&rdsit);
13622 dns_db_detachnode(rawdb, &rawnode);
13623 dns_db_detachnode(db, &node);
13624 }
13625
13626 /*
13627 * Call restore_nsec3param() to create private-type records from
13628 * the old nsec3 parameters and insert them into db
13629 */
13630 if (!ISC_LIST_EMPTY(nsec3list))
13631 restore_nsec3param(zone, db, version, &nsec3list);
13632
13633 dns_db_closeversion(db, &version, ISC_TRUE);
13634
13635 /*
13636 * Lock hierarchy: zmgr, zone, raw.
13637 */
13638 INSIST(zone != zone->raw);
13639 LOCK_ZONE(zone->raw);
13640 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
13641 result = zone_postload(zone, db, loadtime, ISC_R_SUCCESS);
13642 zone_needdump(zone, 0); /* XXXMPA */
13643 UNLOCK_ZONE(zone->raw);
13644
13645 failure:
13646 UNLOCK_ZONE(zone);
13647 if (result != ISC_R_SUCCESS)
13648 dns_zone_log(zone, ISC_LOG_ERROR, "receive_secure_db: %s",
13649 dns_result_totext(result));
13650
13651 while (!ISC_LIST_EMPTY(nsec3list)) {
13652 nsec3param_t *nsec3p;
13653 nsec3p = ISC_LIST_HEAD(nsec3list);
13654 ISC_LIST_UNLINK(nsec3list, nsec3p, link);
13655 isc_mem_put(zone->mctx, nsec3p, sizeof(nsec3param_t));
13656 }
13657 if (dns_rdataset_isassociated(&rdataset))
13658 dns_rdataset_disassociate(&rdataset);
13659 if (db != NULL) {
13660 if (node != NULL)
13661 dns_db_detachnode(db, &node);
13662 if (version != NULL)
13663 dns_db_closeversion(db, &version, ISC_FALSE);
13664 dns_db_detach(&db);
13665 }
13666 if (rawnode != NULL)
13667 dns_db_detachnode(rawdb, &rawnode);
13668 dns_db_detach(&rawdb);
13669 if (dbiterator != NULL)
13670 dns_dbiterator_destroy(&dbiterator);
13671 dns_zone_idetach(&zone);
13672
13673 INSIST(version == NULL);
13674 }
13675
13676 static isc_result_t
zone_send_securedb(dns_zone_t * zone,dns_db_t * db)13677 zone_send_securedb(dns_zone_t *zone, dns_db_t *db) {
13678 isc_event_t *e;
13679 dns_db_t *dummy = NULL;
13680 dns_zone_t *secure = NULL;
13681
13682 e = isc_event_allocate(zone->secure->mctx, zone,
13683 DNS_EVENT_ZONESECUREDB,
13684 receive_secure_db, zone->secure,
13685 sizeof(struct secure_event));
13686 if (e == NULL)
13687 return (ISC_R_NOMEMORY);
13688 dns_db_attach(db, &dummy);
13689 ((struct secure_event *)e)->db = dummy;
13690 INSIST(LOCKED_ZONE(zone->secure));
13691 zone_iattach(zone->secure, &secure);
13692 isc_task_send(zone->secure->task, &e);
13693 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SENDSECURE);
13694 return (ISC_R_SUCCESS);
13695 }
13696
13697 isc_result_t
dns_zone_replacedb(dns_zone_t * zone,dns_db_t * db,isc_boolean_t dump)13698 dns_zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) {
13699 isc_result_t result;
13700 dns_zone_t *secure = NULL;
13701
13702 REQUIRE(DNS_ZONE_VALID(zone));
13703 again:
13704 LOCK_ZONE(zone);
13705 if (inline_raw(zone)) {
13706 secure = zone->secure;
13707 INSIST(secure != zone);
13708 TRYLOCK_ZONE(result, secure);
13709 if (result != ISC_R_SUCCESS) {
13710 UNLOCK_ZONE(zone);
13711 secure = NULL;
13712 #if ISC_PLATFORM_USETHREADS
13713 isc_thread_yield();
13714 #endif
13715 goto again;
13716 }
13717 }
13718 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
13719 result = zone_replacedb(zone, db, dump);
13720 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
13721 if (secure != NULL)
13722 UNLOCK_ZONE(secure);
13723 UNLOCK_ZONE(zone);
13724 return (result);
13725 }
13726
13727 static isc_result_t
zone_replacedb(dns_zone_t * zone,dns_db_t * db,isc_boolean_t dump)13728 zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) {
13729 dns_dbversion_t *ver;
13730 isc_result_t result;
13731 unsigned int soacount = 0;
13732 unsigned int nscount = 0;
13733
13734 /*
13735 * 'zone' and 'zonedb' locked by caller.
13736 */
13737 REQUIRE(DNS_ZONE_VALID(zone));
13738 REQUIRE(LOCKED_ZONE(zone));
13739 if (inline_raw(zone))
13740 REQUIRE(LOCKED_ZONE(zone->secure));
13741
13742 result = zone_get_from_db(zone, db, &nscount, &soacount,
13743 NULL, NULL, NULL, NULL, NULL, NULL);
13744 if (result == ISC_R_SUCCESS) {
13745 if (soacount != 1) {
13746 dns_zone_log(zone, ISC_LOG_ERROR,
13747 "has %d SOA records", soacount);
13748 result = DNS_R_BADZONE;
13749 }
13750 if (nscount == 0 && zone->type != dns_zone_key) {
13751 dns_zone_log(zone, ISC_LOG_ERROR, "has no NS records");
13752 result = DNS_R_BADZONE;
13753 }
13754 if (result != ISC_R_SUCCESS)
13755 return (result);
13756 } else {
13757 dns_zone_log(zone, ISC_LOG_ERROR,
13758 "retrieving SOA and NS records failed: %s",
13759 dns_result_totext(result));
13760 return (result);
13761 }
13762
13763 result = check_nsec3param(zone, db);
13764 if (result != ISC_R_SUCCESS)
13765 return (result);
13766
13767 ver = NULL;
13768 dns_db_currentversion(db, &ver);
13769
13770 /*
13771 * The initial version of a slave zone is always dumped;
13772 * subsequent versions may be journaled instead if this
13773 * is enabled in the configuration.
13774 */
13775 if (zone->db != NULL && zone->journal != NULL &&
13776 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) &&
13777 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER))
13778 {
13779 isc_uint32_t serial, oldserial;
13780
13781 dns_zone_log(zone, ISC_LOG_DEBUG(3), "generating diffs");
13782
13783 result = dns_db_getsoaserial(db, ver, &serial);
13784 if (result != ISC_R_SUCCESS) {
13785 dns_zone_log(zone, ISC_LOG_ERROR,
13786 "ixfr-from-differences: unable to get "
13787 "new serial");
13788 goto fail;
13789 }
13790
13791 /*
13792 * This is checked in zone_postload() for master zones.
13793 */
13794 result = zone_get_from_db(zone, zone->db, NULL, &soacount,
13795 &oldserial, NULL, NULL, NULL, NULL,
13796 NULL);
13797 RUNTIME_CHECK(result == ISC_R_SUCCESS);
13798 RUNTIME_CHECK(soacount > 0U);
13799 if ((zone->type == dns_zone_slave ||
13800 (zone->type == dns_zone_redirect &&
13801 zone->masters != NULL))
13802 && !isc_serial_gt(serial, oldserial)) {
13803 isc_uint32_t serialmin, serialmax;
13804 serialmin = (oldserial + 1) & 0xffffffffU;
13805 serialmax = (oldserial + 0x7fffffffU) & 0xffffffffU;
13806 dns_zone_log(zone, ISC_LOG_ERROR,
13807 "ixfr-from-differences: failed: "
13808 "new serial (%u) out of range [%u - %u]",
13809 serial, serialmin, serialmax);
13810 result = ISC_R_RANGE;
13811 goto fail;
13812 }
13813
13814 result = dns_db_diff(zone->mctx, db, ver, zone->db, NULL,
13815 zone->journal);
13816 if (result != ISC_R_SUCCESS)
13817 goto fail;
13818 if (dump)
13819 zone_needdump(zone, DNS_DUMP_DELAY);
13820 else if (zone->journalsize != -1) {
13821 result = dns_journal_compact(zone->mctx, zone->journal,
13822 serial, zone->journalsize);
13823 switch (result) {
13824 case ISC_R_SUCCESS:
13825 case ISC_R_NOSPACE:
13826 case ISC_R_NOTFOUND:
13827 dns_zone_log(zone, ISC_LOG_DEBUG(3),
13828 "dns_journal_compact: %s",
13829 dns_result_totext(result));
13830 break;
13831 default:
13832 dns_zone_log(zone, ISC_LOG_ERROR,
13833 "dns_journal_compact failed: %s",
13834 dns_result_totext(result));
13835 break;
13836 }
13837 }
13838 if (zone->type == dns_zone_master && inline_raw(zone))
13839 zone_send_secureserial(zone, serial);
13840 } else {
13841 if (dump && zone->masterfile != NULL) {
13842 /*
13843 * If DNS_ZONEFLG_FORCEXFER was set we don't want
13844 * to keep the old masterfile.
13845 */
13846 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) &&
13847 remove(zone->masterfile) < 0 && errno != ENOENT) {
13848 char strbuf[ISC_STRERRORSIZE];
13849 isc__strerror(errno, strbuf, sizeof(strbuf));
13850 isc_log_write(dns_lctx,
13851 DNS_LOGCATEGORY_GENERAL,
13852 DNS_LOGMODULE_ZONE,
13853 ISC_LOG_WARNING,
13854 "unable to remove masterfile "
13855 "'%s': '%s'",
13856 zone->masterfile, strbuf);
13857 }
13858 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0)
13859 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NODELAY);
13860 else
13861 zone_needdump(zone, 0);
13862 }
13863 if (dump && zone->journal != NULL) {
13864 /*
13865 * The in-memory database just changed, and
13866 * because 'dump' is set, it didn't change by
13867 * being loaded from disk. Also, we have not
13868 * journaled diffs for this change.
13869 * Therefore, the on-disk journal is missing
13870 * the deltas for this change. Since it can
13871 * no longer be used to bring the zone
13872 * up-to-date, it is useless and should be
13873 * removed.
13874 */
13875 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
13876 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
13877 "removing journal file");
13878 if (remove(zone->journal) < 0 && errno != ENOENT) {
13879 char strbuf[ISC_STRERRORSIZE];
13880 isc__strerror(errno, strbuf, sizeof(strbuf));
13881 isc_log_write(dns_lctx,
13882 DNS_LOGCATEGORY_GENERAL,
13883 DNS_LOGMODULE_ZONE,
13884 ISC_LOG_WARNING,
13885 "unable to remove journal "
13886 "'%s': '%s'",
13887 zone->journal, strbuf);
13888 }
13889 }
13890
13891 if (inline_raw(zone))
13892 zone_send_securedb(zone, db);
13893 }
13894
13895 dns_db_closeversion(db, &ver, ISC_FALSE);
13896
13897 dns_zone_log(zone, ISC_LOG_DEBUG(3), "replacing zone database");
13898
13899 if (zone->db != NULL)
13900 zone_detachdb(zone);
13901 zone_attachdb(zone, db);
13902 dns_db_settask(zone->db, zone->task);
13903 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED|DNS_ZONEFLG_NEEDNOTIFY);
13904 return (ISC_R_SUCCESS);
13905
13906 fail:
13907 dns_db_closeversion(db, &ver, ISC_FALSE);
13908 return (result);
13909 }
13910
13911 /* The caller must hold the dblock as a writer. */
13912 static inline void
zone_attachdb(dns_zone_t * zone,dns_db_t * db)13913 zone_attachdb(dns_zone_t *zone, dns_db_t *db) {
13914 REQUIRE(zone->db == NULL && db != NULL);
13915
13916 dns_db_attach(db, &zone->db);
13917 if (zone->acache != NULL) {
13918 isc_result_t result;
13919 result = dns_acache_setdb(zone->acache, db);
13920 if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) {
13921 UNEXPECTED_ERROR(__FILE__, __LINE__,
13922 "dns_acache_setdb() failed: %s",
13923 isc_result_totext(result));
13924 }
13925 }
13926 }
13927
13928 /* The caller must hold the dblock as a writer. */
13929 static inline void
zone_detachdb(dns_zone_t * zone)13930 zone_detachdb(dns_zone_t *zone) {
13931 REQUIRE(zone->db != NULL);
13932
13933 if (zone->acache != NULL)
13934 (void)dns_acache_putdb(zone->acache, zone->db);
13935 dns_db_detach(&zone->db);
13936 }
13937
13938 static void
zone_xfrdone(dns_zone_t * zone,isc_result_t result)13939 zone_xfrdone(dns_zone_t *zone, isc_result_t result) {
13940 isc_time_t now;
13941 isc_boolean_t again = ISC_FALSE;
13942 unsigned int soacount;
13943 unsigned int nscount;
13944 isc_uint32_t serial, refresh, retry, expire, minimum;
13945 isc_result_t xfrresult = result;
13946 isc_boolean_t free_needed;
13947 dns_zone_t *secure = NULL;
13948
13949 REQUIRE(DNS_ZONE_VALID(zone));
13950
13951 dns_zone_log(zone, ISC_LOG_DEBUG(1),
13952 "zone transfer finished: %s", dns_result_totext(result));
13953
13954 /*
13955 * Obtaining a lock on the zone->secure (see zone_send_secureserial)
13956 * could result in a deadlock due to a LOR so we will spin if we
13957 * can't obtain the both locks.
13958 */
13959 again:
13960 LOCK_ZONE(zone);
13961 if (inline_raw(zone)) {
13962 secure = zone->secure;
13963 INSIST(secure != zone);
13964 TRYLOCK_ZONE(result, secure);
13965 if (result != ISC_R_SUCCESS) {
13966 UNLOCK_ZONE(zone);
13967 secure = NULL;
13968 #if ISC_PLATFORM_USETHREADS
13969 isc_thread_yield();
13970 #endif
13971 goto again;
13972 }
13973 }
13974
13975 INSIST((zone->flags & DNS_ZONEFLG_REFRESH) != 0);
13976 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
13977 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR);
13978
13979 TIME_NOW(&now);
13980 switch (result) {
13981 case ISC_R_SUCCESS:
13982 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
13983 /*FALLTHROUGH*/
13984 case DNS_R_UPTODATE:
13985 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FORCEXFER);
13986 /*
13987 * Has the zone expired underneath us?
13988 */
13989 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
13990 if (zone->db == NULL) {
13991 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
13992 goto same_master;
13993 }
13994
13995 /*
13996 * Update the zone structure's data from the actual
13997 * SOA received.
13998 */
13999 nscount = 0;
14000 soacount = 0;
14001 INSIST(zone->db != NULL);
14002 result = zone_get_from_db(zone, zone->db, &nscount,
14003 &soacount, &serial, &refresh,
14004 &retry, &expire, &minimum, NULL);
14005 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
14006 if (result == ISC_R_SUCCESS) {
14007 if (soacount != 1)
14008 dns_zone_log(zone, ISC_LOG_ERROR,
14009 "transferred zone "
14010 "has %d SOA record%s", soacount,
14011 (soacount != 0) ? "s" : "");
14012 if (nscount == 0) {
14013 dns_zone_log(zone, ISC_LOG_ERROR,
14014 "transferred zone "
14015 "has no NS records");
14016 if (DNS_ZONE_FLAG(zone,
14017 DNS_ZONEFLG_HAVETIMERS)) {
14018 zone->refresh = DNS_ZONE_DEFAULTREFRESH;
14019 zone->retry = DNS_ZONE_DEFAULTRETRY;
14020 }
14021 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
14022 zone_unload(zone);
14023 goto next_master;
14024 }
14025 zone->refresh = RANGE(refresh, zone->minrefresh,
14026 zone->maxrefresh);
14027 zone->retry = RANGE(retry, zone->minretry,
14028 zone->maxretry);
14029 zone->expire = RANGE(expire,
14030 zone->refresh + zone->retry,
14031 DNS_MAX_EXPIRE);
14032 zone->minimum = minimum;
14033 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
14034 }
14035
14036 /*
14037 * Set our next update/expire times.
14038 */
14039 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) {
14040 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
14041 zone->refreshtime = now;
14042 DNS_ZONE_TIME_ADD(&now, zone->expire,
14043 &zone->expiretime);
14044 } else {
14045 DNS_ZONE_JITTER_ADD(&now, zone->refresh,
14046 &zone->refreshtime);
14047 DNS_ZONE_TIME_ADD(&now, zone->expire,
14048 &zone->expiretime);
14049 }
14050 if (result == ISC_R_SUCCESS && xfrresult == ISC_R_SUCCESS) {
14051 char buf[DNS_NAME_FORMATSIZE + sizeof(": TSIG ''")];
14052 if (zone->tsigkey != NULL) {
14053 char namebuf[DNS_NAME_FORMATSIZE];
14054 dns_name_format(&zone->tsigkey->name, namebuf,
14055 sizeof(namebuf));
14056 snprintf(buf, sizeof(buf), ": TSIG '%s'",
14057 namebuf);
14058 } else
14059 buf[0] = '\0';
14060 dns_zone_log(zone, ISC_LOG_INFO,
14061 "transferred serial %u%s",
14062 serial, buf);
14063 if (inline_raw(zone))
14064 zone_send_secureserial(zone, serial);
14065 }
14066
14067 /*
14068 * This is not necessary if we just performed a AXFR
14069 * however it is necessary for an IXFR / UPTODATE and
14070 * won't hurt with an AXFR.
14071 */
14072 if (zone->masterfile != NULL || zone->journal != NULL) {
14073 unsigned int delay = DNS_DUMP_DELAY;
14074
14075 result = ISC_R_FAILURE;
14076 if (zone->journal != NULL)
14077 result = isc_file_settime(zone->journal, &now);
14078 if (result != ISC_R_SUCCESS &&
14079 zone->masterfile != NULL)
14080 result = isc_file_settime(zone->masterfile,
14081 &now);
14082
14083 if ((DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NODELAY) != 0) ||
14084 result == ISC_R_FILENOTFOUND)
14085 delay = 0;
14086
14087 if ((result == ISC_R_SUCCESS ||
14088 result == ISC_R_FILENOTFOUND) &&
14089 zone->masterfile != NULL)
14090 zone_needdump(zone, delay);
14091 else if (result != ISC_R_SUCCESS)
14092 dns_zone_log(zone, ISC_LOG_ERROR,
14093 "transfer: could not set file "
14094 "modification time of '%s': %s",
14095 zone->masterfile,
14096 dns_result_totext(result));
14097 }
14098 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NODELAY);
14099 inc_stats(zone, dns_zonestatscounter_xfrsuccess);
14100 break;
14101
14102 case DNS_R_BADIXFR:
14103 /* Force retry with AXFR. */
14104 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLAG_NOIXFR);
14105 goto same_master;
14106
14107 default:
14108 next_master:
14109 /*
14110 * Skip to next failed / untried master.
14111 */
14112 do {
14113 zone->curmaster++;
14114 } while (zone->curmaster < zone->masterscnt &&
14115 zone->mastersok[zone->curmaster]);
14116 /* FALLTHROUGH */
14117 same_master:
14118 if (zone->curmaster >= zone->masterscnt) {
14119 zone->curmaster = 0;
14120 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
14121 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
14122 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
14123 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
14124 while (zone->curmaster < zone->masterscnt &&
14125 zone->mastersok[zone->curmaster])
14126 zone->curmaster++;
14127 again = ISC_TRUE;
14128 } else
14129 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
14130 } else {
14131 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
14132 again = ISC_TRUE;
14133 }
14134 inc_stats(zone, dns_zonestatscounter_xfrfail);
14135 break;
14136 }
14137 zone_settimer(zone, &now);
14138
14139 /*
14140 * If creating the transfer object failed, zone->xfr is NULL.
14141 * Otherwise, we are called as the done callback of a zone
14142 * transfer object that just entered its shutting-down
14143 * state. Since we are no longer responsible for shutting
14144 * it down, we can detach our reference.
14145 */
14146 if (zone->xfr != NULL)
14147 dns_xfrin_detach(&zone->xfr);
14148
14149 if (zone->tsigkey != NULL)
14150 dns_tsigkey_detach(&zone->tsigkey);
14151
14152 /*
14153 * Handle any deferred journal compaction.
14154 */
14155 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDCOMPACT)) {
14156 result = dns_journal_compact(zone->mctx, zone->journal,
14157 zone->compact_serial,
14158 zone->journalsize);
14159 switch (result) {
14160 case ISC_R_SUCCESS:
14161 case ISC_R_NOSPACE:
14162 case ISC_R_NOTFOUND:
14163 dns_zone_log(zone, ISC_LOG_DEBUG(3),
14164 "dns_journal_compact: %s",
14165 dns_result_totext(result));
14166 break;
14167 default:
14168 dns_zone_log(zone, ISC_LOG_ERROR,
14169 "dns_journal_compact failed: %s",
14170 dns_result_totext(result));
14171 break;
14172 }
14173 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT);
14174 }
14175
14176 if (secure != NULL)
14177 UNLOCK_ZONE(secure);
14178 /*
14179 * This transfer finishing freed up a transfer quota slot.
14180 * Let any other zones waiting for quota have it.
14181 */
14182 if (zone->zmgr != NULL &&
14183 zone->statelist == &zone->zmgr->xfrin_in_progress) {
14184 UNLOCK_ZONE(zone);
14185 RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
14186 ISC_LIST_UNLINK(zone->zmgr->xfrin_in_progress, zone, statelink);
14187 zone->statelist = NULL;
14188 zmgr_resume_xfrs(zone->zmgr, ISC_FALSE);
14189 RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
14190 LOCK_ZONE(zone);
14191 }
14192
14193 /*
14194 * Retry with a different server if necessary.
14195 */
14196 if (again && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
14197 queue_soa_query(zone);
14198
14199 INSIST(zone->irefs > 0);
14200 zone->irefs--;
14201 free_needed = exit_check(zone);
14202 UNLOCK_ZONE(zone);
14203 if (free_needed)
14204 zone_free(zone);
14205 }
14206
14207 static void
zone_loaddone(void * arg,isc_result_t result)14208 zone_loaddone(void *arg, isc_result_t result) {
14209 static char me[] = "zone_loaddone";
14210 dns_load_t *load = arg;
14211 dns_zone_t *zone;
14212 isc_result_t tresult;
14213 dns_zone_t *secure = NULL;
14214
14215 REQUIRE(DNS_LOAD_VALID(load));
14216 zone = load->zone;
14217
14218 ENTER;
14219
14220 tresult = dns_db_endload(load->db, &load->callbacks.add_private);
14221 if (tresult != ISC_R_SUCCESS &&
14222 (result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE))
14223 result = tresult;
14224
14225 /*
14226 * Lock hierarchy: zmgr, zone, raw.
14227 */
14228 again:
14229 LOCK_ZONE(zone);
14230 if (inline_secure(zone))
14231 LOCK_ZONE(zone->raw);
14232 else if (inline_raw(zone)) {
14233 secure = zone->secure;
14234 TRYLOCK_ZONE(result, secure);
14235 if (result != ISC_R_SUCCESS) {
14236 UNLOCK_ZONE(zone);
14237 secure = NULL;
14238 #if ISC_PLATFORM_USETHREADS
14239 isc_thread_yield();
14240 #endif
14241 goto again;
14242 }
14243 }
14244 (void)zone_postload(zone, load->db, load->loadtime, result);
14245 zonemgr_putio(&zone->readio);
14246 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADING);
14247 zone_idetach(&load->callbacks.zone);
14248 /*
14249 * Leave the zone frozen if the reload fails.
14250 */
14251 if ((result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE) &&
14252 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_THAW))
14253 zone->update_disabled = ISC_FALSE;
14254 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_THAW);
14255 if (inline_secure(zone))
14256 UNLOCK_ZONE(zone->raw);
14257 else if (secure != NULL)
14258 UNLOCK_ZONE(secure);
14259 UNLOCK_ZONE(zone);
14260
14261 load->magic = 0;
14262 dns_db_detach(&load->db);
14263 if (load->zone->lctx != NULL)
14264 dns_loadctx_detach(&load->zone->lctx);
14265 dns_zone_idetach(&load->zone);
14266 isc_mem_putanddetach(&load->mctx, load, sizeof(*load));
14267 }
14268
14269 void
dns_zone_getssutable(dns_zone_t * zone,dns_ssutable_t ** table)14270 dns_zone_getssutable(dns_zone_t *zone, dns_ssutable_t **table) {
14271 REQUIRE(DNS_ZONE_VALID(zone));
14272 REQUIRE(table != NULL);
14273 REQUIRE(*table == NULL);
14274
14275 LOCK_ZONE(zone);
14276 if (zone->ssutable != NULL)
14277 dns_ssutable_attach(zone->ssutable, table);
14278 UNLOCK_ZONE(zone);
14279 }
14280
14281 void
dns_zone_setssutable(dns_zone_t * zone,dns_ssutable_t * table)14282 dns_zone_setssutable(dns_zone_t *zone, dns_ssutable_t *table) {
14283 REQUIRE(DNS_ZONE_VALID(zone));
14284
14285 LOCK_ZONE(zone);
14286 if (zone->ssutable != NULL)
14287 dns_ssutable_detach(&zone->ssutable);
14288 if (table != NULL)
14289 dns_ssutable_attach(table, &zone->ssutable);
14290 UNLOCK_ZONE(zone);
14291 }
14292
14293 void
dns_zone_setsigvalidityinterval(dns_zone_t * zone,isc_uint32_t interval)14294 dns_zone_setsigvalidityinterval(dns_zone_t *zone, isc_uint32_t interval) {
14295 REQUIRE(DNS_ZONE_VALID(zone));
14296
14297 zone->sigvalidityinterval = interval;
14298 }
14299
14300 isc_uint32_t
dns_zone_getsigvalidityinterval(dns_zone_t * zone)14301 dns_zone_getsigvalidityinterval(dns_zone_t *zone) {
14302 REQUIRE(DNS_ZONE_VALID(zone));
14303
14304 return (zone->sigvalidityinterval);
14305 }
14306
14307 void
dns_zone_setsigresigninginterval(dns_zone_t * zone,isc_uint32_t interval)14308 dns_zone_setsigresigninginterval(dns_zone_t *zone, isc_uint32_t interval) {
14309 isc_time_t now;
14310
14311 REQUIRE(DNS_ZONE_VALID(zone));
14312
14313 LOCK_ZONE(zone);
14314 zone->sigresigninginterval = interval;
14315 set_resigntime(zone);
14316 if (zone->task != NULL) {
14317 TIME_NOW(&now);
14318 zone_settimer(zone, &now);
14319 }
14320 UNLOCK_ZONE(zone);
14321 }
14322
14323 isc_uint32_t
dns_zone_getsigresigninginterval(dns_zone_t * zone)14324 dns_zone_getsigresigninginterval(dns_zone_t *zone) {
14325 REQUIRE(DNS_ZONE_VALID(zone));
14326
14327 return (zone->sigresigninginterval);
14328 }
14329
14330 static void
queue_xfrin(dns_zone_t * zone)14331 queue_xfrin(dns_zone_t *zone) {
14332 const char me[] = "queue_xfrin";
14333 isc_result_t result;
14334 dns_zonemgr_t *zmgr = zone->zmgr;
14335
14336 ENTER;
14337
14338 INSIST(zone->statelist == NULL);
14339
14340 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
14341 ISC_LIST_APPEND(zmgr->waiting_for_xfrin, zone, statelink);
14342 LOCK_ZONE(zone);
14343 zone->irefs++;
14344 UNLOCK_ZONE(zone);
14345 zone->statelist = &zmgr->waiting_for_xfrin;
14346 result = zmgr_start_xfrin_ifquota(zmgr, zone);
14347 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
14348
14349 if (result == ISC_R_QUOTA) {
14350 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO,
14351 "zone transfer deferred due to quota");
14352 } else if (result != ISC_R_SUCCESS) {
14353 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_ERROR,
14354 "starting zone transfer: %s",
14355 isc_result_totext(result));
14356 }
14357 }
14358
14359 /*
14360 * This event callback is called when a zone has received
14361 * any necessary zone transfer quota. This is the time
14362 * to go ahead and start the transfer.
14363 */
14364 static void
got_transfer_quota(isc_task_t * task,isc_event_t * event)14365 got_transfer_quota(isc_task_t *task, isc_event_t *event) {
14366 isc_result_t result = ISC_R_SUCCESS;
14367 dns_peer_t *peer = NULL;
14368 char master[ISC_SOCKADDR_FORMATSIZE];
14369 char source[ISC_SOCKADDR_FORMATSIZE];
14370 dns_rdatatype_t xfrtype;
14371 dns_zone_t *zone = event->ev_arg;
14372 isc_netaddr_t masterip;
14373 isc_sockaddr_t sourceaddr;
14374 isc_sockaddr_t masteraddr;
14375 isc_time_t now;
14376 const char *soa_before = "";
14377 isc_boolean_t loaded;
14378
14379 UNUSED(task);
14380
14381 INSIST(task == zone->task);
14382
14383 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
14384 result = ISC_R_CANCELED;
14385 goto cleanup;
14386 }
14387
14388 TIME_NOW(&now);
14389
14390 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
14391 if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr,
14392 &zone->sourceaddr, &now))
14393 {
14394 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
14395 dns_zone_log(zone, ISC_LOG_INFO,
14396 "got_transfer_quota: skipping zone transfer as "
14397 "master %s (source %s) is unreachable (cached)",
14398 master, source);
14399 result = ISC_R_CANCELED;
14400 goto cleanup;
14401 }
14402
14403 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
14404 (void)dns_peerlist_peerbyaddr(zone->view->peers, &masterip, &peer);
14405
14406 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR))
14407 soa_before = "SOA before ";
14408 /*
14409 * Decide whether we should request IXFR or AXFR.
14410 */
14411 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
14412 loaded = ISC_TF(zone->db != NULL);
14413 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
14414
14415 if (!loaded) {
14416 dns_zone_log(zone, ISC_LOG_DEBUG(1),
14417 "no database exists yet, requesting AXFR of "
14418 "initial version from %s", master);
14419 xfrtype = dns_rdatatype_axfr;
14420 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) {
14421 dns_zone_log(zone, ISC_LOG_DEBUG(1),
14422 "forced reload, requesting AXFR of "
14423 "initial version from %s", master);
14424 xfrtype = dns_rdatatype_axfr;
14425 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLAG_NOIXFR)) {
14426 dns_zone_log(zone, ISC_LOG_DEBUG(1),
14427 "retrying with AXFR from %s due to "
14428 "previous IXFR failure", master);
14429 xfrtype = dns_rdatatype_axfr;
14430 LOCK_ZONE(zone);
14431 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLAG_NOIXFR);
14432 UNLOCK_ZONE(zone);
14433 } else {
14434 isc_boolean_t use_ixfr = ISC_TRUE;
14435 if (peer != NULL)
14436 result = dns_peer_getrequestixfr(peer, &use_ixfr);
14437 if (peer == NULL || result != ISC_R_SUCCESS)
14438 use_ixfr = zone->requestixfr;
14439 if (use_ixfr == ISC_FALSE) {
14440 dns_zone_log(zone, ISC_LOG_DEBUG(1),
14441 "IXFR disabled, requesting %sAXFR from %s",
14442 soa_before, master);
14443 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR))
14444 xfrtype = dns_rdatatype_soa;
14445 else
14446 xfrtype = dns_rdatatype_axfr;
14447 } else {
14448 dns_zone_log(zone, ISC_LOG_DEBUG(1),
14449 "requesting IXFR from %s", master);
14450 xfrtype = dns_rdatatype_ixfr;
14451 }
14452 }
14453
14454 /*
14455 * Determine if we should attempt to sign the request with TSIG.
14456 */
14457 result = ISC_R_NOTFOUND;
14458 /*
14459 * First, look for a tsig key in the master statement, then
14460 * try for a server key.
14461 */
14462 if ((zone->masterkeynames != NULL) &&
14463 (zone->masterkeynames[zone->curmaster] != NULL)) {
14464 dns_view_t *view = dns_zone_getview(zone);
14465 dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
14466 result = dns_view_gettsig(view, keyname, &zone->tsigkey);
14467 }
14468 if (zone->tsigkey == NULL)
14469 result = dns_view_getpeertsig(zone->view, &masterip,
14470 &zone->tsigkey);
14471
14472 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
14473 dns_zone_log(zone, ISC_LOG_ERROR,
14474 "could not get TSIG key for zone transfer: %s",
14475 isc_result_totext(result));
14476 }
14477
14478 LOCK_ZONE(zone);
14479 masteraddr = zone->masteraddr;
14480 sourceaddr = zone->sourceaddr;
14481 UNLOCK_ZONE(zone);
14482 INSIST(isc_sockaddr_pf(&masteraddr) == isc_sockaddr_pf(&sourceaddr));
14483 result = dns_xfrin_create2(zone, xfrtype, &masteraddr, &sourceaddr,
14484 zone->tsigkey, zone->mctx,
14485 zone->zmgr->timermgr, zone->zmgr->socketmgr,
14486 zone->task, zone_xfrdone, &zone->xfr);
14487 if (result == ISC_R_SUCCESS) {
14488 LOCK_ZONE(zone);
14489 if (xfrtype == dns_rdatatype_axfr) {
14490 if (isc_sockaddr_pf(&masteraddr) == PF_INET)
14491 inc_stats(zone, dns_zonestatscounter_axfrreqv4);
14492 else
14493 inc_stats(zone, dns_zonestatscounter_axfrreqv6);
14494 } else if (xfrtype == dns_rdatatype_ixfr) {
14495 if (isc_sockaddr_pf(&masteraddr) == PF_INET)
14496 inc_stats(zone, dns_zonestatscounter_ixfrreqv4);
14497 else
14498 inc_stats(zone, dns_zonestatscounter_ixfrreqv6);
14499 }
14500 UNLOCK_ZONE(zone);
14501 }
14502 cleanup:
14503 /*
14504 * Any failure in this function is handled like a failed
14505 * zone transfer. This ensures that we get removed from
14506 * zmgr->xfrin_in_progress.
14507 */
14508 if (result != ISC_R_SUCCESS)
14509 zone_xfrdone(zone, result);
14510
14511 isc_event_free(&event);
14512 }
14513
14514 /*
14515 * Update forwarding support.
14516 */
14517
14518 static void
forward_destroy(dns_forward_t * forward)14519 forward_destroy(dns_forward_t *forward) {
14520
14521 forward->magic = 0;
14522 if (forward->request != NULL)
14523 dns_request_destroy(&forward->request);
14524 if (forward->msgbuf != NULL)
14525 isc_buffer_free(&forward->msgbuf);
14526 if (forward->zone != NULL) {
14527 LOCK(&forward->zone->lock);
14528 if (ISC_LINK_LINKED(forward, link))
14529 ISC_LIST_UNLINK(forward->zone->forwards, forward, link);
14530 UNLOCK(&forward->zone->lock);
14531 dns_zone_idetach(&forward->zone);
14532 }
14533 isc_mem_putanddetach(&forward->mctx, forward, sizeof(*forward));
14534 }
14535
14536 static isc_result_t
sendtomaster(dns_forward_t * forward)14537 sendtomaster(dns_forward_t *forward) {
14538 isc_result_t result;
14539 isc_sockaddr_t src;
14540
14541 LOCK_ZONE(forward->zone);
14542
14543 if (DNS_ZONE_FLAG(forward->zone, DNS_ZONEFLG_EXITING)) {
14544 UNLOCK_ZONE(forward->zone);
14545 return (ISC_R_CANCELED);
14546 }
14547
14548 if (forward->which >= forward->zone->masterscnt) {
14549 UNLOCK_ZONE(forward->zone);
14550 return (ISC_R_NOMORE);
14551 }
14552
14553 forward->addr = forward->zone->masters[forward->which];
14554 /*
14555 * Always use TCP regardless of whether the original update
14556 * used TCP.
14557 * XXX The timeout may but a bit small if we are far down a
14558 * transfer graph and the master has to try several masters.
14559 */
14560 switch (isc_sockaddr_pf(&forward->addr)) {
14561 case PF_INET:
14562 src = forward->zone->xfrsource4;
14563 break;
14564 case PF_INET6:
14565 src = forward->zone->xfrsource6;
14566 break;
14567 default:
14568 result = ISC_R_NOTIMPLEMENTED;
14569 goto unlock;
14570 }
14571 result = dns_request_createraw(forward->zone->view->requestmgr,
14572 forward->msgbuf,
14573 &src, &forward->addr,
14574 forward->options, 15 /* XXX */,
14575 forward->zone->task,
14576 forward_callback, forward,
14577 &forward->request);
14578 if (result == ISC_R_SUCCESS) {
14579 if (!ISC_LINK_LINKED(forward, link))
14580 ISC_LIST_APPEND(forward->zone->forwards, forward, link);
14581 }
14582
14583 unlock:
14584 UNLOCK_ZONE(forward->zone);
14585 return (result);
14586 }
14587
14588 static void
forward_callback(isc_task_t * task,isc_event_t * event)14589 forward_callback(isc_task_t *task, isc_event_t *event) {
14590 const char me[] = "forward_callback";
14591 dns_requestevent_t *revent = (dns_requestevent_t *)event;
14592 dns_message_t *msg = NULL;
14593 char master[ISC_SOCKADDR_FORMATSIZE];
14594 isc_result_t result;
14595 dns_forward_t *forward;
14596 dns_zone_t *zone;
14597
14598 UNUSED(task);
14599
14600 forward = revent->ev_arg;
14601 INSIST(DNS_FORWARD_VALID(forward));
14602 zone = forward->zone;
14603 INSIST(DNS_ZONE_VALID(zone));
14604
14605 ENTER;
14606
14607 isc_sockaddr_format(&forward->addr, master, sizeof(master));
14608
14609 if (revent->result != ISC_R_SUCCESS) {
14610 dns_zone_log(zone, ISC_LOG_INFO,
14611 "could not forward dynamic update to %s: %s",
14612 master, dns_result_totext(revent->result));
14613 goto next_master;
14614 }
14615
14616 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
14617 if (result != ISC_R_SUCCESS)
14618 goto next_master;
14619
14620 result = dns_request_getresponse(revent->request, msg,
14621 DNS_MESSAGEPARSE_PRESERVEORDER |
14622 DNS_MESSAGEPARSE_CLONEBUFFER);
14623 if (result != ISC_R_SUCCESS)
14624 goto next_master;
14625
14626 switch (msg->rcode) {
14627 /*
14628 * Pass these rcodes back to client.
14629 */
14630 case dns_rcode_noerror:
14631 case dns_rcode_yxdomain:
14632 case dns_rcode_yxrrset:
14633 case dns_rcode_nxrrset:
14634 case dns_rcode_refused:
14635 case dns_rcode_nxdomain: {
14636 char rcode[128];
14637 isc_buffer_t rb;
14638
14639 isc_buffer_init(&rb, rcode, sizeof(rcode));
14640 (void)dns_rcode_totext(msg->rcode, &rb);
14641 dns_zone_log(zone, ISC_LOG_INFO,
14642 "forwarded dynamic update: "
14643 "master %s returned: %.*s",
14644 master, (int)rb.used, rcode);
14645 break;
14646 }
14647
14648 /* These should not occur if the masters/zone are valid. */
14649 case dns_rcode_notzone:
14650 case dns_rcode_notauth: {
14651 char rcode[128];
14652 isc_buffer_t rb;
14653
14654 isc_buffer_init(&rb, rcode, sizeof(rcode));
14655 (void)dns_rcode_totext(msg->rcode, &rb);
14656 dns_zone_log(zone, ISC_LOG_WARNING,
14657 "forwarding dynamic update: "
14658 "unexpected response: master %s returned: %.*s",
14659 master, (int)rb.used, rcode);
14660 goto next_master;
14661 }
14662
14663 /* Try another server for these rcodes. */
14664 case dns_rcode_formerr:
14665 case dns_rcode_servfail:
14666 case dns_rcode_notimp:
14667 case dns_rcode_badvers:
14668 default:
14669 goto next_master;
14670 }
14671
14672 /* call callback */
14673 (forward->callback)(forward->callback_arg, ISC_R_SUCCESS, msg);
14674 msg = NULL;
14675 dns_request_destroy(&forward->request);
14676 forward_destroy(forward);
14677 isc_event_free(&event);
14678 return;
14679
14680 next_master:
14681 if (msg != NULL)
14682 dns_message_destroy(&msg);
14683 isc_event_free(&event);
14684 forward->which++;
14685 dns_request_destroy(&forward->request);
14686 result = sendtomaster(forward);
14687 if (result != ISC_R_SUCCESS) {
14688 /* call callback */
14689 dns_zone_log(zone, ISC_LOG_DEBUG(3),
14690 "exhausted dynamic update forwarder list");
14691 (forward->callback)(forward->callback_arg, result, NULL);
14692 forward_destroy(forward);
14693 }
14694 }
14695
14696 isc_result_t
dns_zone_forwardupdate(dns_zone_t * zone,dns_message_t * msg,dns_updatecallback_t callback,void * callback_arg)14697 dns_zone_forwardupdate(dns_zone_t *zone, dns_message_t *msg,
14698 dns_updatecallback_t callback, void *callback_arg)
14699 {
14700 dns_forward_t *forward;
14701 isc_result_t result;
14702 isc_region_t *mr;
14703
14704 REQUIRE(DNS_ZONE_VALID(zone));
14705 REQUIRE(msg != NULL);
14706 REQUIRE(callback != NULL);
14707
14708 forward = isc_mem_get(zone->mctx, sizeof(*forward));
14709 if (forward == NULL)
14710 return (ISC_R_NOMEMORY);
14711
14712 forward->request = NULL;
14713 forward->zone = NULL;
14714 forward->msgbuf = NULL;
14715 forward->which = 0;
14716 forward->mctx = 0;
14717 forward->callback = callback;
14718 forward->callback_arg = callback_arg;
14719 ISC_LINK_INIT(forward, link);
14720 forward->magic = FORWARD_MAGIC;
14721 forward->options = DNS_REQUESTOPT_TCP;
14722 /*
14723 * If we have a SIG(0) signed message we need to preserve the
14724 * query id as that is included in the SIG(0) computation.
14725 */
14726 if (msg->sig0 != NULL)
14727 forward->options |= DNS_REQUESTOPT_FIXEDID;
14728
14729 mr = dns_message_getrawmessage(msg);
14730 if (mr == NULL) {
14731 result = ISC_R_UNEXPECTEDEND;
14732 goto cleanup;
14733 }
14734
14735 result = isc_buffer_allocate(zone->mctx, &forward->msgbuf, mr->length);
14736 if (result != ISC_R_SUCCESS)
14737 goto cleanup;
14738 result = isc_buffer_copyregion(forward->msgbuf, mr);
14739 if (result != ISC_R_SUCCESS)
14740 goto cleanup;
14741
14742 isc_mem_attach(zone->mctx, &forward->mctx);
14743 dns_zone_iattach(zone, &forward->zone);
14744 result = sendtomaster(forward);
14745
14746 cleanup:
14747 if (result != ISC_R_SUCCESS) {
14748 forward_destroy(forward);
14749 }
14750 return (result);
14751 }
14752
14753 isc_result_t
dns_zone_next(dns_zone_t * zone,dns_zone_t ** next)14754 dns_zone_next(dns_zone_t *zone, dns_zone_t **next) {
14755 REQUIRE(DNS_ZONE_VALID(zone));
14756 REQUIRE(next != NULL && *next == NULL);
14757
14758 *next = ISC_LIST_NEXT(zone, link);
14759 if (*next == NULL)
14760 return (ISC_R_NOMORE);
14761 else
14762 return (ISC_R_SUCCESS);
14763 }
14764
14765 isc_result_t
dns_zone_first(dns_zonemgr_t * zmgr,dns_zone_t ** first)14766 dns_zone_first(dns_zonemgr_t *zmgr, dns_zone_t **first) {
14767 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
14768 REQUIRE(first != NULL && *first == NULL);
14769
14770 *first = ISC_LIST_HEAD(zmgr->zones);
14771 if (*first == NULL)
14772 return (ISC_R_NOMORE);
14773 else
14774 return (ISC_R_SUCCESS);
14775 }
14776
14777 /***
14778 *** Zone manager.
14779 ***/
14780
14781 isc_result_t
dns_zonemgr_create(isc_mem_t * mctx,isc_taskmgr_t * taskmgr,isc_timermgr_t * timermgr,isc_socketmgr_t * socketmgr,dns_zonemgr_t ** zmgrp)14782 dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
14783 isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr,
14784 dns_zonemgr_t **zmgrp)
14785 {
14786 dns_zonemgr_t *zmgr;
14787 isc_result_t result;
14788
14789 zmgr = isc_mem_get(mctx, sizeof(*zmgr));
14790 if (zmgr == NULL)
14791 return (ISC_R_NOMEMORY);
14792 zmgr->mctx = NULL;
14793 zmgr->refs = 1;
14794 isc_mem_attach(mctx, &zmgr->mctx);
14795 zmgr->taskmgr = taskmgr;
14796 zmgr->timermgr = timermgr;
14797 zmgr->socketmgr = socketmgr;
14798 zmgr->zonetasks = NULL;
14799 zmgr->loadtasks = NULL;
14800 zmgr->mctxpool = NULL;
14801 zmgr->task = NULL;
14802 zmgr->notifyrl = NULL;
14803 zmgr->refreshrl = NULL;
14804 zmgr->startupnotifyrl = NULL;
14805 zmgr->startuprefreshrl = NULL;
14806 ISC_LIST_INIT(zmgr->zones);
14807 ISC_LIST_INIT(zmgr->waiting_for_xfrin);
14808 ISC_LIST_INIT(zmgr->xfrin_in_progress);
14809 memset(zmgr->unreachable, 0, sizeof(zmgr->unreachable));
14810 result = isc_rwlock_init(&zmgr->rwlock, 0, 0);
14811 if (result != ISC_R_SUCCESS)
14812 goto free_mem;
14813
14814 zmgr->transfersin = 10;
14815 zmgr->transfersperns = 2;
14816
14817 /* Unreachable lock. */
14818 result = isc_rwlock_init(&zmgr->urlock, 0, 0);
14819 if (result != ISC_R_SUCCESS)
14820 goto free_rwlock;
14821
14822 /* Create a single task for queueing of SOA queries. */
14823 result = isc_task_create(taskmgr, 1, &zmgr->task);
14824 if (result != ISC_R_SUCCESS)
14825 goto free_urlock;
14826
14827 isc_task_setname(zmgr->task, "zmgr", zmgr);
14828 result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
14829 &zmgr->notifyrl);
14830 if (result != ISC_R_SUCCESS)
14831 goto free_task;
14832
14833 result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
14834 &zmgr->refreshrl);
14835 if (result != ISC_R_SUCCESS)
14836 goto free_notifyrl;
14837
14838 result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
14839 &zmgr->startupnotifyrl);
14840 if (result != ISC_R_SUCCESS)
14841 goto free_refreshrl;
14842
14843 result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
14844 &zmgr->startuprefreshrl);
14845 if (result != ISC_R_SUCCESS)
14846 goto free_startupnotifyrl;
14847
14848 /* default to 20 refresh queries / notifies per second. */
14849 setrl(zmgr->notifyrl, &zmgr->notifyrate, 20);
14850 setrl(zmgr->startupnotifyrl, &zmgr->startupnotifyrate, 20);
14851 setrl(zmgr->refreshrl, &zmgr->serialqueryrate, 20);
14852 setrl(zmgr->startuprefreshrl, &zmgr->startupserialqueryrate, 20);
14853
14854 zmgr->iolimit = 1;
14855 zmgr->ioactive = 0;
14856 ISC_LIST_INIT(zmgr->high);
14857 ISC_LIST_INIT(zmgr->low);
14858
14859 result = isc_mutex_init(&zmgr->iolock);
14860 if (result != ISC_R_SUCCESS)
14861 goto free_startuprefreshrl;
14862
14863 zmgr->magic = ZONEMGR_MAGIC;
14864
14865 *zmgrp = zmgr;
14866 return (ISC_R_SUCCESS);
14867
14868 #if 0
14869 free_iolock:
14870 DESTROYLOCK(&zmgr->iolock);
14871 #endif
14872 free_startuprefreshrl:
14873 isc_ratelimiter_detach(&zmgr->startuprefreshrl);
14874 free_startupnotifyrl:
14875 isc_ratelimiter_detach(&zmgr->startupnotifyrl);
14876 free_refreshrl:
14877 isc_ratelimiter_detach(&zmgr->refreshrl);
14878 free_notifyrl:
14879 isc_ratelimiter_detach(&zmgr->notifyrl);
14880 free_task:
14881 isc_task_detach(&zmgr->task);
14882 free_urlock:
14883 isc_rwlock_destroy(&zmgr->urlock);
14884 free_rwlock:
14885 isc_rwlock_destroy(&zmgr->rwlock);
14886 free_mem:
14887 isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr));
14888 isc_mem_detach(&mctx);
14889 return (result);
14890 }
14891
14892 isc_result_t
dns_zonemgr_createzone(dns_zonemgr_t * zmgr,dns_zone_t ** zonep)14893 dns_zonemgr_createzone(dns_zonemgr_t *zmgr, dns_zone_t **zonep) {
14894 isc_result_t result;
14895 isc_mem_t *mctx = NULL;
14896 dns_zone_t *zone = NULL;
14897 void *item;
14898
14899 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
14900 REQUIRE(zonep != NULL && *zonep == NULL);
14901
14902 if (zmgr->mctxpool == NULL)
14903 return (ISC_R_FAILURE);
14904
14905 item = isc_pool_get(zmgr->mctxpool);
14906 if (item == NULL)
14907 return (ISC_R_FAILURE);
14908
14909 isc_mem_attach((isc_mem_t *) item, &mctx);
14910 result = dns_zone_create(&zone, mctx);
14911 isc_mem_detach(&mctx);
14912
14913 if (result == ISC_R_SUCCESS)
14914 *zonep = zone;
14915
14916 return (result);
14917 }
14918
14919 isc_result_t
dns_zonemgr_managezone(dns_zonemgr_t * zmgr,dns_zone_t * zone)14920 dns_zonemgr_managezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
14921 isc_result_t result;
14922
14923 REQUIRE(DNS_ZONE_VALID(zone));
14924 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
14925
14926 if (zmgr->zonetasks == NULL)
14927 return (ISC_R_FAILURE);
14928
14929 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
14930 LOCK_ZONE(zone);
14931 REQUIRE(zone->task == NULL);
14932 REQUIRE(zone->timer == NULL);
14933 REQUIRE(zone->zmgr == NULL);
14934
14935 isc_taskpool_gettask(zmgr->zonetasks, &zone->task);
14936 isc_taskpool_gettask(zmgr->loadtasks, &zone->loadtask);
14937
14938 /*
14939 * Set the task name. The tag will arbitrarily point to one
14940 * of the zones sharing the task (in practice, the one
14941 * to be managed last).
14942 */
14943 isc_task_setname(zone->task, "zone", zone);
14944 isc_task_setname(zone->loadtask, "loadzone", zone);
14945
14946 result = isc_timer_create(zmgr->timermgr, isc_timertype_inactive,
14947 NULL, NULL,
14948 zone->task, zone_timer, zone,
14949 &zone->timer);
14950
14951 if (result != ISC_R_SUCCESS)
14952 goto cleanup_tasks;
14953
14954 /*
14955 * The timer "holds" a iref.
14956 */
14957 zone->irefs++;
14958 INSIST(zone->irefs != 0);
14959
14960 ISC_LIST_APPEND(zmgr->zones, zone, link);
14961 zone->zmgr = zmgr;
14962 zmgr->refs++;
14963
14964 goto unlock;
14965
14966 cleanup_tasks:
14967 isc_task_detach(&zone->loadtask);
14968 isc_task_detach(&zone->task);
14969
14970 unlock:
14971 UNLOCK_ZONE(zone);
14972 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
14973 return (result);
14974 }
14975
14976 void
dns_zonemgr_releasezone(dns_zonemgr_t * zmgr,dns_zone_t * zone)14977 dns_zonemgr_releasezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
14978 isc_boolean_t free_now = ISC_FALSE;
14979
14980 REQUIRE(DNS_ZONE_VALID(zone));
14981 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
14982 REQUIRE(zone->zmgr == zmgr);
14983
14984 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
14985 LOCK_ZONE(zone);
14986
14987 ISC_LIST_UNLINK(zmgr->zones, zone, link);
14988 zone->zmgr = NULL;
14989 zmgr->refs--;
14990 if (zmgr->refs == 0)
14991 free_now = ISC_TRUE;
14992
14993 UNLOCK_ZONE(zone);
14994 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
14995
14996 if (free_now)
14997 zonemgr_free(zmgr);
14998 ENSURE(zone->zmgr == NULL);
14999 }
15000
15001 void
dns_zonemgr_attach(dns_zonemgr_t * source,dns_zonemgr_t ** target)15002 dns_zonemgr_attach(dns_zonemgr_t *source, dns_zonemgr_t **target) {
15003 REQUIRE(DNS_ZONEMGR_VALID(source));
15004 REQUIRE(target != NULL && *target == NULL);
15005
15006 RWLOCK(&source->rwlock, isc_rwlocktype_write);
15007 REQUIRE(source->refs > 0);
15008 source->refs++;
15009 INSIST(source->refs > 0);
15010 RWUNLOCK(&source->rwlock, isc_rwlocktype_write);
15011 *target = source;
15012 }
15013
15014 void
dns_zonemgr_detach(dns_zonemgr_t ** zmgrp)15015 dns_zonemgr_detach(dns_zonemgr_t **zmgrp) {
15016 dns_zonemgr_t *zmgr;
15017 isc_boolean_t free_now = ISC_FALSE;
15018
15019 REQUIRE(zmgrp != NULL);
15020 zmgr = *zmgrp;
15021 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15022
15023 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
15024 zmgr->refs--;
15025 if (zmgr->refs == 0)
15026 free_now = ISC_TRUE;
15027 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
15028
15029 if (free_now)
15030 zonemgr_free(zmgr);
15031 *zmgrp = NULL;
15032 }
15033
15034 isc_result_t
dns_zonemgr_forcemaint(dns_zonemgr_t * zmgr)15035 dns_zonemgr_forcemaint(dns_zonemgr_t *zmgr) {
15036 dns_zone_t *p;
15037
15038 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15039
15040 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
15041 for (p = ISC_LIST_HEAD(zmgr->zones);
15042 p != NULL;
15043 p = ISC_LIST_NEXT(p, link))
15044 {
15045 dns_zone_maintenance(p);
15046 }
15047 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
15048
15049 /*
15050 * Recent configuration changes may have increased the
15051 * amount of available transfers quota. Make sure any
15052 * transfers currently blocked on quota get started if
15053 * possible.
15054 */
15055 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
15056 zmgr_resume_xfrs(zmgr, ISC_TRUE);
15057 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
15058 return (ISC_R_SUCCESS);
15059 }
15060
15061 void
dns_zonemgr_resumexfrs(dns_zonemgr_t * zmgr)15062 dns_zonemgr_resumexfrs(dns_zonemgr_t *zmgr) {
15063
15064 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15065
15066 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
15067 zmgr_resume_xfrs(zmgr, ISC_TRUE);
15068 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
15069 }
15070
15071 void
dns_zonemgr_shutdown(dns_zonemgr_t * zmgr)15072 dns_zonemgr_shutdown(dns_zonemgr_t *zmgr) {
15073 dns_zone_t *zone;
15074
15075 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15076
15077 isc_ratelimiter_shutdown(zmgr->notifyrl);
15078 isc_ratelimiter_shutdown(zmgr->refreshrl);
15079 isc_ratelimiter_shutdown(zmgr->startupnotifyrl);
15080 isc_ratelimiter_shutdown(zmgr->startuprefreshrl);
15081
15082 if (zmgr->task != NULL)
15083 isc_task_destroy(&zmgr->task);
15084 if (zmgr->zonetasks != NULL)
15085 isc_taskpool_destroy(&zmgr->zonetasks);
15086 if (zmgr->loadtasks != NULL)
15087 isc_taskpool_destroy(&zmgr->loadtasks);
15088 if (zmgr->mctxpool != NULL)
15089 isc_pool_destroy(&zmgr->mctxpool);
15090
15091 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
15092 for (zone = ISC_LIST_HEAD(zmgr->zones);
15093 zone != NULL;
15094 zone = ISC_LIST_NEXT(zone, link))
15095 {
15096 LOCK_ZONE(zone);
15097 forward_cancel(zone);
15098 UNLOCK_ZONE(zone);
15099 }
15100 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
15101 }
15102
15103 static isc_result_t
mctxinit(void ** target,void * arg)15104 mctxinit(void **target, void *arg) {
15105 isc_result_t result;
15106 isc_mem_t *mctx = NULL;
15107
15108 UNUSED(arg);
15109
15110 REQUIRE(target != NULL && *target == NULL);
15111
15112 result = isc_mem_create(0, 0, &mctx);
15113 if (result != ISC_R_SUCCESS)
15114 return (result);
15115 isc_mem_setname(mctx, "zonemgr-pool", NULL);
15116
15117 *target = mctx;
15118 return (ISC_R_SUCCESS);
15119 }
15120
15121 static void
mctxfree(void ** target)15122 mctxfree(void **target) {
15123 isc_mem_t *mctx = *(isc_mem_t **) target;
15124 isc_mem_detach(&mctx);
15125 *target = NULL;
15126 }
15127
15128 #define ZONES_PER_TASK 100
15129 #define ZONES_PER_MCTX 1000
15130
15131 isc_result_t
dns_zonemgr_setsize(dns_zonemgr_t * zmgr,int num_zones)15132 dns_zonemgr_setsize(dns_zonemgr_t *zmgr, int num_zones) {
15133 isc_result_t result;
15134 int ntasks = num_zones / ZONES_PER_TASK;
15135 int nmctx = num_zones / ZONES_PER_MCTX;
15136 isc_taskpool_t *pool = NULL;
15137 isc_pool_t *mctxpool = NULL;
15138
15139 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15140
15141 /*
15142 * For anything fewer than 1000 zones we use 10 tasks in
15143 * the task pools. More than that, and we'll scale at one
15144 * task per 100 zones. Similarly, for anything smaller than
15145 * 2000 zones we use 2 memory contexts, then scale at 1:1000.
15146 */
15147 if (ntasks < 10)
15148 ntasks = 10;
15149 if (nmctx < 2)
15150 nmctx = 2;
15151
15152 /* Create or resize the zone task pools. */
15153 if (zmgr->zonetasks == NULL)
15154 result = isc_taskpool_create(zmgr->taskmgr, zmgr->mctx,
15155 ntasks, 2, &pool);
15156 else
15157 result = isc_taskpool_expand(&zmgr->zonetasks, ntasks, &pool);
15158
15159 if (result == ISC_R_SUCCESS)
15160 zmgr->zonetasks = pool;
15161
15162 pool = NULL;
15163 if (zmgr->loadtasks == NULL)
15164 result = isc_taskpool_create(zmgr->taskmgr, zmgr->mctx,
15165 ntasks, 2, &pool);
15166 else
15167 result = isc_taskpool_expand(&zmgr->loadtasks, ntasks, &pool);
15168
15169 if (result == ISC_R_SUCCESS)
15170 zmgr->loadtasks = pool;
15171
15172 #ifdef BIND9
15173 /*
15174 * We always set all tasks in the zone-load task pool to
15175 * privileged. This prevents other tasks in the system from
15176 * running while the server task manager is in privileged
15177 * mode.
15178 *
15179 * NOTE: If we start using task privileges for any other
15180 * part of the system than zone tasks, then this will need to be
15181 * revisted. In that case we'd want to turn on privileges for
15182 * zone tasks only when we were loading, and turn them off the
15183 * rest of the time. For now, however, it's okay to just
15184 * set it and forget it.
15185 */
15186 isc_taskpool_setprivilege(zmgr->loadtasks, ISC_TRUE);
15187 #endif
15188
15189 /* Create or resize the zone memory context pool. */
15190 if (zmgr->mctxpool == NULL)
15191 result = isc_pool_create(zmgr->mctx, nmctx, mctxfree,
15192 mctxinit, NULL, &mctxpool);
15193 else
15194 result = isc_pool_expand(&zmgr->mctxpool, nmctx, &mctxpool);
15195
15196 if (result == ISC_R_SUCCESS)
15197 zmgr->mctxpool = mctxpool;
15198
15199 return (result);
15200 }
15201
15202 static void
zonemgr_free(dns_zonemgr_t * zmgr)15203 zonemgr_free(dns_zonemgr_t *zmgr) {
15204 isc_mem_t *mctx;
15205
15206 INSIST(zmgr->refs == 0);
15207 INSIST(ISC_LIST_EMPTY(zmgr->zones));
15208
15209 zmgr->magic = 0;
15210
15211 DESTROYLOCK(&zmgr->iolock);
15212 isc_ratelimiter_detach(&zmgr->notifyrl);
15213 isc_ratelimiter_detach(&zmgr->refreshrl);
15214 isc_ratelimiter_detach(&zmgr->startupnotifyrl);
15215 isc_ratelimiter_detach(&zmgr->startuprefreshrl);
15216
15217 isc_rwlock_destroy(&zmgr->urlock);
15218 isc_rwlock_destroy(&zmgr->rwlock);
15219 mctx = zmgr->mctx;
15220 isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr));
15221 isc_mem_detach(&mctx);
15222 }
15223
15224 void
dns_zonemgr_settransfersin(dns_zonemgr_t * zmgr,isc_uint32_t value)15225 dns_zonemgr_settransfersin(dns_zonemgr_t *zmgr, isc_uint32_t value) {
15226 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15227
15228 zmgr->transfersin = value;
15229 }
15230
15231 isc_uint32_t
dns_zonemgr_getttransfersin(dns_zonemgr_t * zmgr)15232 dns_zonemgr_getttransfersin(dns_zonemgr_t *zmgr) {
15233 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15234
15235 return (zmgr->transfersin);
15236 }
15237
15238 void
dns_zonemgr_settransfersperns(dns_zonemgr_t * zmgr,isc_uint32_t value)15239 dns_zonemgr_settransfersperns(dns_zonemgr_t *zmgr, isc_uint32_t value) {
15240 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15241
15242 zmgr->transfersperns = value;
15243 }
15244
15245 isc_uint32_t
dns_zonemgr_getttransfersperns(dns_zonemgr_t * zmgr)15246 dns_zonemgr_getttransfersperns(dns_zonemgr_t *zmgr) {
15247 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15248
15249 return (zmgr->transfersperns);
15250 }
15251
15252 /*
15253 * Try to start a new incoming zone transfer to fill a quota
15254 * slot that was just vacated.
15255 *
15256 * Requires:
15257 * The zone manager is locked by the caller.
15258 */
15259 static void
zmgr_resume_xfrs(dns_zonemgr_t * zmgr,isc_boolean_t multi)15260 zmgr_resume_xfrs(dns_zonemgr_t *zmgr, isc_boolean_t multi) {
15261 dns_zone_t *zone;
15262 dns_zone_t *next;
15263
15264 for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin);
15265 zone != NULL;
15266 zone = next)
15267 {
15268 isc_result_t result;
15269 next = ISC_LIST_NEXT(zone, statelink);
15270 result = zmgr_start_xfrin_ifquota(zmgr, zone);
15271 if (result == ISC_R_SUCCESS) {
15272 if (multi)
15273 continue;
15274 /*
15275 * We successfully filled the slot. We're done.
15276 */
15277 break;
15278 } else if (result == ISC_R_QUOTA) {
15279 /*
15280 * Not enough quota. This is probably the per-server
15281 * quota, because we usually get called when a unit of
15282 * global quota has just been freed. Try the next
15283 * zone, it may succeed if it uses another master.
15284 */
15285 continue;
15286 } else {
15287 dns_zone_log(zone, ISC_LOG_DEBUG(1),
15288 "starting zone transfer: %s",
15289 isc_result_totext(result));
15290 break;
15291 }
15292 }
15293 }
15294
15295 /*
15296 * Try to start an incoming zone transfer for 'zone', quota permitting.
15297 *
15298 * Requires:
15299 * The zone manager is locked by the caller.
15300 *
15301 * Returns:
15302 * ISC_R_SUCCESS There was enough quota and we attempted to
15303 * start a transfer. zone_xfrdone() has been or will
15304 * be called.
15305 * ISC_R_QUOTA Not enough quota.
15306 * Others Failure.
15307 */
15308 static isc_result_t
zmgr_start_xfrin_ifquota(dns_zonemgr_t * zmgr,dns_zone_t * zone)15309 zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
15310 dns_peer_t *peer = NULL;
15311 isc_netaddr_t masterip;
15312 isc_uint32_t nxfrsin, nxfrsperns;
15313 dns_zone_t *x;
15314 isc_uint32_t maxtransfersin, maxtransfersperns;
15315 isc_event_t *e;
15316
15317 /*
15318 * If we are exiting just pretend we got quota so the zone will
15319 * be cleaned up in the zone's task context.
15320 */
15321 LOCK_ZONE(zone);
15322 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
15323 UNLOCK_ZONE(zone);
15324 goto gotquota;
15325 }
15326
15327 /*
15328 * Find any configured information about the server we'd
15329 * like to transfer this zone from.
15330 */
15331 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
15332 (void)dns_peerlist_peerbyaddr(zone->view->peers, &masterip, &peer);
15333 UNLOCK_ZONE(zone);
15334
15335 /*
15336 * Determine the total maximum number of simultaneous
15337 * transfers allowed, and the maximum for this specific
15338 * master.
15339 */
15340 maxtransfersin = zmgr->transfersin;
15341 maxtransfersperns = zmgr->transfersperns;
15342 if (peer != NULL)
15343 (void)dns_peer_gettransfers(peer, &maxtransfersperns);
15344
15345 /*
15346 * Count the total number of transfers that are in progress,
15347 * and the number of transfers in progress from this master.
15348 * We linearly scan a list of all transfers; if this turns
15349 * out to be too slow, we could hash on the master address.
15350 */
15351 nxfrsin = nxfrsperns = 0;
15352 for (x = ISC_LIST_HEAD(zmgr->xfrin_in_progress);
15353 x != NULL;
15354 x = ISC_LIST_NEXT(x, statelink))
15355 {
15356 isc_netaddr_t xip;
15357
15358 LOCK_ZONE(x);
15359 isc_netaddr_fromsockaddr(&xip, &x->masteraddr);
15360 UNLOCK_ZONE(x);
15361
15362 nxfrsin++;
15363 if (isc_netaddr_equal(&xip, &masterip))
15364 nxfrsperns++;
15365 }
15366
15367 /* Enforce quota. */
15368 if (nxfrsin >= maxtransfersin)
15369 return (ISC_R_QUOTA);
15370
15371 if (nxfrsperns >= maxtransfersperns)
15372 return (ISC_R_QUOTA);
15373
15374 gotquota:
15375 /*
15376 * We have sufficient quota. Move the zone to the "xfrin_in_progress"
15377 * list and send it an event to let it start the actual transfer in the
15378 * context of its own task.
15379 */
15380 e = isc_event_allocate(zmgr->mctx, zmgr, DNS_EVENT_ZONESTARTXFRIN,
15381 got_transfer_quota, zone, sizeof(isc_event_t));
15382 if (e == NULL)
15383 return (ISC_R_NOMEMORY);
15384
15385 LOCK_ZONE(zone);
15386 INSIST(zone->statelist == &zmgr->waiting_for_xfrin);
15387 ISC_LIST_UNLINK(zmgr->waiting_for_xfrin, zone, statelink);
15388 ISC_LIST_APPEND(zmgr->xfrin_in_progress, zone, statelink);
15389 zone->statelist = &zmgr->xfrin_in_progress;
15390 isc_task_send(zone->task, &e);
15391 dns_zone_log(zone, ISC_LOG_INFO, "Transfer started.");
15392 UNLOCK_ZONE(zone);
15393
15394 return (ISC_R_SUCCESS);
15395 }
15396
15397 void
dns_zonemgr_setiolimit(dns_zonemgr_t * zmgr,isc_uint32_t iolimit)15398 dns_zonemgr_setiolimit(dns_zonemgr_t *zmgr, isc_uint32_t iolimit) {
15399
15400 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15401 REQUIRE(iolimit > 0);
15402
15403 zmgr->iolimit = iolimit;
15404 }
15405
15406 isc_uint32_t
dns_zonemgr_getiolimit(dns_zonemgr_t * zmgr)15407 dns_zonemgr_getiolimit(dns_zonemgr_t *zmgr) {
15408
15409 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15410
15411 return (zmgr->iolimit);
15412 }
15413
15414 /*
15415 * Get permission to request a file handle from the OS.
15416 * An event will be sent to action when one is available.
15417 * There are two queues available (high and low), the high
15418 * queue will be serviced before the low one.
15419 *
15420 * zonemgr_putio() must be called after the event is delivered to
15421 * 'action'.
15422 */
15423
15424 static isc_result_t
zonemgr_getio(dns_zonemgr_t * zmgr,isc_boolean_t high,isc_task_t * task,isc_taskaction_t action,void * arg,dns_io_t ** iop)15425 zonemgr_getio(dns_zonemgr_t *zmgr, isc_boolean_t high,
15426 isc_task_t *task, isc_taskaction_t action, void *arg,
15427 dns_io_t **iop)
15428 {
15429 dns_io_t *io;
15430 isc_boolean_t queue;
15431
15432 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15433 REQUIRE(iop != NULL && *iop == NULL);
15434
15435 io = isc_mem_get(zmgr->mctx, sizeof(*io));
15436 if (io == NULL)
15437 return (ISC_R_NOMEMORY);
15438
15439 io->event = isc_event_allocate(zmgr->mctx, task, DNS_EVENT_IOREADY,
15440 action, arg, sizeof(*io->event));
15441 if (io->event == NULL) {
15442 isc_mem_put(zmgr->mctx, io, sizeof(*io));
15443 return (ISC_R_NOMEMORY);
15444 }
15445
15446 io->zmgr = zmgr;
15447 io->high = high;
15448 io->task = NULL;
15449 isc_task_attach(task, &io->task);
15450 ISC_LINK_INIT(io, link);
15451 io->magic = IO_MAGIC;
15452
15453 LOCK(&zmgr->iolock);
15454 zmgr->ioactive++;
15455 queue = ISC_TF(zmgr->ioactive > zmgr->iolimit);
15456 if (queue) {
15457 if (io->high)
15458 ISC_LIST_APPEND(zmgr->high, io, link);
15459 else
15460 ISC_LIST_APPEND(zmgr->low, io, link);
15461 }
15462 UNLOCK(&zmgr->iolock);
15463 *iop = io;
15464
15465 if (!queue)
15466 isc_task_send(io->task, &io->event);
15467 return (ISC_R_SUCCESS);
15468 }
15469
15470 static void
zonemgr_putio(dns_io_t ** iop)15471 zonemgr_putio(dns_io_t **iop) {
15472 dns_io_t *io;
15473 dns_io_t *next;
15474 dns_zonemgr_t *zmgr;
15475
15476 REQUIRE(iop != NULL);
15477 io = *iop;
15478 REQUIRE(DNS_IO_VALID(io));
15479
15480 *iop = NULL;
15481
15482 INSIST(!ISC_LINK_LINKED(io, link));
15483 INSIST(io->event == NULL);
15484
15485 zmgr = io->zmgr;
15486 isc_task_detach(&io->task);
15487 io->magic = 0;
15488 isc_mem_put(zmgr->mctx, io, sizeof(*io));
15489
15490 LOCK(&zmgr->iolock);
15491 INSIST(zmgr->ioactive > 0);
15492 zmgr->ioactive--;
15493 next = HEAD(zmgr->high);
15494 if (next == NULL)
15495 next = HEAD(zmgr->low);
15496 if (next != NULL) {
15497 if (next->high)
15498 ISC_LIST_UNLINK(zmgr->high, next, link);
15499 else
15500 ISC_LIST_UNLINK(zmgr->low, next, link);
15501 INSIST(next->event != NULL);
15502 }
15503 UNLOCK(&zmgr->iolock);
15504 if (next != NULL)
15505 isc_task_send(next->task, &next->event);
15506 }
15507
15508 static void
zonemgr_cancelio(dns_io_t * io)15509 zonemgr_cancelio(dns_io_t *io) {
15510 isc_boolean_t send_event = ISC_FALSE;
15511
15512 REQUIRE(DNS_IO_VALID(io));
15513
15514 /*
15515 * If we are queued to be run then dequeue.
15516 */
15517 LOCK(&io->zmgr->iolock);
15518 if (ISC_LINK_LINKED(io, link)) {
15519 if (io->high)
15520 ISC_LIST_UNLINK(io->zmgr->high, io, link);
15521 else
15522 ISC_LIST_UNLINK(io->zmgr->low, io, link);
15523
15524 send_event = ISC_TRUE;
15525 INSIST(io->event != NULL);
15526 }
15527 UNLOCK(&io->zmgr->iolock);
15528 if (send_event) {
15529 io->event->ev_attributes |= ISC_EVENTATTR_CANCELED;
15530 isc_task_send(io->task, &io->event);
15531 }
15532 }
15533
15534 static void
zone_saveunique(dns_zone_t * zone,const char * path,const char * templat)15535 zone_saveunique(dns_zone_t *zone, const char *path, const char *templat) {
15536 char *buf;
15537 int buflen;
15538 isc_result_t result;
15539
15540 buflen = strlen(path) + strlen(templat) + 2;
15541
15542 buf = isc_mem_get(zone->mctx, buflen);
15543 if (buf == NULL)
15544 return;
15545
15546 result = isc_file_template(path, templat, buf, buflen);
15547 if (result != ISC_R_SUCCESS)
15548 goto cleanup;
15549
15550 result = isc_file_renameunique(path, buf);
15551 if (result != ISC_R_SUCCESS)
15552 goto cleanup;
15553
15554 dns_zone_log(zone, ISC_LOG_WARNING, "unable to load from '%s'; "
15555 "renaming file to '%s' for failure analysis and "
15556 "retransferring.", path, buf);
15557
15558 cleanup:
15559 isc_mem_put(zone->mctx, buf, buflen);
15560 }
15561
15562 #if 0
15563 /* Hook for ondestroy notification from a database. */
15564
15565 static void
15566 dns_zonemgr_dbdestroyed(isc_task_t *task, isc_event_t *event) {
15567 dns_db_t *db = event->sender;
15568 UNUSED(task);
15569
15570 isc_event_free(&event);
15571
15572 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
15573 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
15574 "database (%p) destroyed", (void*) db);
15575 }
15576 #endif
15577
15578 static void
setrl(isc_ratelimiter_t * rl,unsigned int * rate,unsigned int value)15579 setrl(isc_ratelimiter_t *rl, unsigned int *rate, unsigned int value) {
15580 isc_interval_t interval;
15581 isc_uint32_t s, ns;
15582 isc_uint32_t pertic;
15583 isc_result_t result;
15584
15585 if (value == 0)
15586 value = 1;
15587
15588 if (value == 1) {
15589 s = 1;
15590 ns = 0;
15591 pertic = 1;
15592 } else if (value <= 10) {
15593 s = 0;
15594 ns = 1000000000 / value;
15595 pertic = 1;
15596 } else {
15597 s = 0;
15598 ns = (1000000000 / value) * 10;
15599 pertic = 10;
15600 }
15601
15602 isc_interval_set(&interval, s, ns);
15603
15604 result = isc_ratelimiter_setinterval(rl, &interval);
15605 RUNTIME_CHECK(result == ISC_R_SUCCESS);
15606 isc_ratelimiter_setpertic(rl, pertic);
15607
15608 *rate = value;
15609 }
15610
15611 void
dns_zonemgr_setserialqueryrate(dns_zonemgr_t * zmgr,unsigned int value)15612 dns_zonemgr_setserialqueryrate(dns_zonemgr_t *zmgr, unsigned int value) {
15613
15614 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15615
15616 setrl(zmgr->refreshrl, &zmgr->serialqueryrate, value);
15617
15618 /* Seperately controlled in BIND 9.11.x */
15619 setrl(zmgr->notifyrl, &zmgr->notifyrate, value);
15620 setrl(zmgr->startupnotifyrl, &zmgr->startupnotifyrate, value);
15621
15622 /* XXXMPA seperate out once we have the code to support this. */
15623 setrl(zmgr->startuprefreshrl, &zmgr->startupserialqueryrate, value);
15624 }
15625
15626 unsigned int
dns_zonemgr_getserialqueryrate(dns_zonemgr_t * zmgr)15627 dns_zonemgr_getserialqueryrate(dns_zonemgr_t *zmgr) {
15628 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15629
15630 return (zmgr->serialqueryrate);
15631 }
15632
15633 isc_boolean_t
dns_zonemgr_unreachable(dns_zonemgr_t * zmgr,isc_sockaddr_t * remote,isc_sockaddr_t * local,isc_time_t * now)15634 dns_zonemgr_unreachable(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
15635 isc_sockaddr_t *local, isc_time_t *now)
15636 {
15637 unsigned int i;
15638 isc_rwlocktype_t locktype;
15639 isc_result_t result;
15640 isc_uint32_t seconds = isc_time_seconds(now);
15641 isc_uint32_t count = 0;
15642
15643 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15644
15645 locktype = isc_rwlocktype_read;
15646 RWLOCK(&zmgr->urlock, locktype);
15647 for (i = 0; i < UNREACH_CHACHE_SIZE; i++) {
15648 if (zmgr->unreachable[i].expire >= seconds &&
15649 isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
15650 isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) {
15651 result = isc_rwlock_tryupgrade(&zmgr->urlock);
15652 if (result == ISC_R_SUCCESS) {
15653 locktype = isc_rwlocktype_write;
15654 zmgr->unreachable[i].last = seconds;
15655 count = zmgr->unreachable[i].count;
15656 }
15657 break;
15658 }
15659 }
15660 RWUNLOCK(&zmgr->urlock, locktype);
15661 return (ISC_TF(i < UNREACH_CHACHE_SIZE && count > 1U));
15662 }
15663
15664 void
dns_zonemgr_unreachabledel(dns_zonemgr_t * zmgr,isc_sockaddr_t * remote,isc_sockaddr_t * local)15665 dns_zonemgr_unreachabledel(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
15666 isc_sockaddr_t *local)
15667 {
15668 unsigned int i;
15669 isc_rwlocktype_t locktype;
15670 isc_result_t result;
15671
15672 char master[ISC_SOCKADDR_FORMATSIZE];
15673 char source[ISC_SOCKADDR_FORMATSIZE];
15674
15675 isc_sockaddr_format(remote, master, sizeof(master));
15676 isc_sockaddr_format(local, source, sizeof(source));
15677
15678 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15679
15680 locktype = isc_rwlocktype_read;
15681 RWLOCK(&zmgr->urlock, locktype);
15682 for (i = 0; i < UNREACH_CHACHE_SIZE; i++) {
15683 if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
15684 isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) {
15685 if (zmgr->unreachable[i].expire == 0)
15686 break;
15687 result = isc_rwlock_tryupgrade(&zmgr->urlock);
15688 if (result == ISC_R_SUCCESS) {
15689 locktype = isc_rwlocktype_write;
15690 zmgr->unreachable[i].expire = 0;
15691 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
15692 DNS_LOGMODULE_ZONE, ISC_LOG_INFO,
15693 "master %s (source %s) deleted "
15694 "from unreachable cache",
15695 master, source);
15696 }
15697 break;
15698 }
15699 }
15700 RWUNLOCK(&zmgr->urlock, locktype);
15701 }
15702
15703 void
dns_zonemgr_unreachableadd(dns_zonemgr_t * zmgr,isc_sockaddr_t * remote,isc_sockaddr_t * local,isc_time_t * now)15704 dns_zonemgr_unreachableadd(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
15705 isc_sockaddr_t *local, isc_time_t *now)
15706 {
15707 isc_uint32_t seconds = isc_time_seconds(now);
15708 isc_uint32_t last = seconds;
15709 unsigned int i, slot = UNREACH_CHACHE_SIZE, oldest = 0;
15710
15711 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15712
15713 RWLOCK(&zmgr->urlock, isc_rwlocktype_write);
15714 for (i = 0; i < UNREACH_CHACHE_SIZE; i++) {
15715 /* Existing entry? */
15716 if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
15717 isc_sockaddr_equal(&zmgr->unreachable[i].local, local))
15718 break;
15719 /* Empty slot? */
15720 if (zmgr->unreachable[i].expire < seconds)
15721 slot = i;
15722 /* Least recently used slot? */
15723 if (zmgr->unreachable[i].last < last) {
15724 last = zmgr->unreachable[i].last;
15725 oldest = i;
15726 }
15727 }
15728 if (i < UNREACH_CHACHE_SIZE) {
15729 /*
15730 * Found a existing entry. Update the expire timer and
15731 * last usage timestamps.
15732 */
15733 zmgr->unreachable[i].expire = seconds + UNREACH_HOLD_TIME;
15734 zmgr->unreachable[i].last = seconds;
15735 if (zmgr->unreachable[i].expire < seconds)
15736 zmgr->unreachable[i].count = 1;
15737 else
15738 zmgr->unreachable[i].count++;
15739 } else if (slot != UNREACH_CHACHE_SIZE) {
15740 /*
15741 * Found a empty slot. Add a new entry to the cache.
15742 */
15743 zmgr->unreachable[slot].expire = seconds + UNREACH_HOLD_TIME;
15744 zmgr->unreachable[slot].last = seconds;
15745 zmgr->unreachable[slot].remote = *remote;
15746 zmgr->unreachable[slot].local = *local;
15747 zmgr->unreachable[slot].count = 1;
15748 } else {
15749 /*
15750 * Replace the least recently used entry in the cache.
15751 */
15752 zmgr->unreachable[oldest].expire = seconds + UNREACH_HOLD_TIME;
15753 zmgr->unreachable[oldest].last = seconds;
15754 zmgr->unreachable[oldest].remote = *remote;
15755 zmgr->unreachable[oldest].local = *local;
15756 zmgr->unreachable[oldest].count = 1;
15757 }
15758 RWUNLOCK(&zmgr->urlock, isc_rwlocktype_write);
15759 }
15760
15761 void
dns_zone_forcereload(dns_zone_t * zone)15762 dns_zone_forcereload(dns_zone_t *zone) {
15763 REQUIRE(DNS_ZONE_VALID(zone));
15764
15765 if (zone->type == dns_zone_master ||
15766 (zone->type == dns_zone_redirect && zone->masters == NULL))
15767 return;
15768
15769 LOCK_ZONE(zone);
15770 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FORCEXFER);
15771 UNLOCK_ZONE(zone);
15772 dns_zone_refresh(zone);
15773 }
15774
15775 isc_boolean_t
dns_zone_isforced(dns_zone_t * zone)15776 dns_zone_isforced(dns_zone_t *zone) {
15777 REQUIRE(DNS_ZONE_VALID(zone));
15778
15779 return (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER));
15780 }
15781
15782 isc_result_t
dns_zone_setstatistics(dns_zone_t * zone,isc_boolean_t on)15783 dns_zone_setstatistics(dns_zone_t *zone, isc_boolean_t on) {
15784 /*
15785 * This function is obsoleted.
15786 */
15787 UNUSED(zone);
15788 UNUSED(on);
15789 return (ISC_R_NOTIMPLEMENTED);
15790 }
15791
15792 isc_uint64_t *
dns_zone_getstatscounters(dns_zone_t * zone)15793 dns_zone_getstatscounters(dns_zone_t *zone) {
15794 /*
15795 * This function is obsoleted.
15796 */
15797 UNUSED(zone);
15798 return (NULL);
15799 }
15800
15801 void
dns_zone_setstats(dns_zone_t * zone,isc_stats_t * stats)15802 dns_zone_setstats(dns_zone_t *zone, isc_stats_t *stats) {
15803 REQUIRE(DNS_ZONE_VALID(zone));
15804 REQUIRE(zone->stats == NULL);
15805
15806 LOCK_ZONE(zone);
15807 zone->stats = NULL;
15808 isc_stats_attach(stats, &zone->stats);
15809 UNLOCK_ZONE(zone);
15810 }
15811
15812 void
dns_zone_setrequeststats(dns_zone_t * zone,isc_stats_t * stats)15813 dns_zone_setrequeststats(dns_zone_t *zone, isc_stats_t *stats) {
15814
15815 REQUIRE(DNS_ZONE_VALID(zone));
15816
15817 LOCK_ZONE(zone);
15818 if (zone->requeststats_on && stats == NULL)
15819 zone->requeststats_on = ISC_FALSE;
15820 else if (!zone->requeststats_on && stats != NULL) {
15821 if (zone->requeststats == NULL) {
15822 isc_stats_attach(stats, &zone->requeststats);
15823 zone->requeststats_on = ISC_TRUE;
15824 }
15825 }
15826 UNLOCK_ZONE(zone);
15827 }
15828
15829 #ifdef NEWSTATS
15830 void
dns_zone_setrcvquerystats(dns_zone_t * zone,dns_stats_t * stats)15831 dns_zone_setrcvquerystats(dns_zone_t *zone, dns_stats_t *stats) {
15832
15833 REQUIRE(DNS_ZONE_VALID(zone));
15834
15835 LOCK_ZONE(zone);
15836 if (zone->requeststats_on && stats != NULL) {
15837 if (zone->rcvquerystats == NULL) {
15838 dns_stats_attach(stats, &zone->rcvquerystats);
15839 zone->requeststats_on = ISC_TRUE;
15840 }
15841 }
15842 UNLOCK_ZONE(zone);
15843 }
15844 #endif
15845
15846 isc_stats_t *
dns_zone_getrequeststats(dns_zone_t * zone)15847 dns_zone_getrequeststats(dns_zone_t *zone) {
15848 /*
15849 * We don't lock zone for efficiency reason. This is not catastrophic
15850 * because requeststats must always be valid when requeststats_on is
15851 * true.
15852 * Some counters may be incremented while requeststats_on is becoming
15853 * false, or some cannot be incremented just after the statistics are
15854 * installed, but it shouldn't matter much in practice.
15855 */
15856 if (zone->requeststats_on)
15857 return (zone->requeststats);
15858 else
15859 return (NULL);
15860 }
15861
15862 #ifdef NEWSTATS
15863 /*
15864 * Return the received query stats bucket
15865 * see note from dns_zone_getrequeststats()
15866 */
15867 dns_stats_t *
dns_zone_getrcvquerystats(dns_zone_t * zone)15868 dns_zone_getrcvquerystats(dns_zone_t *zone) {
15869 if (zone->requeststats_on)
15870 return (zone->rcvquerystats);
15871 else
15872 return (NULL);
15873 }
15874 #endif
15875
15876 void
dns_zone_dialup(dns_zone_t * zone)15877 dns_zone_dialup(dns_zone_t *zone) {
15878
15879 REQUIRE(DNS_ZONE_VALID(zone));
15880
15881 zone_debuglog(zone, "dns_zone_dialup", 3,
15882 "notify = %d, refresh = %d",
15883 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY),
15884 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH));
15885
15886 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY))
15887 dns_zone_notify(zone);
15888 if (zone->type != dns_zone_master && zone->masters != NULL &&
15889 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
15890 dns_zone_refresh(zone);
15891 }
15892
15893 void
dns_zone_setdialup(dns_zone_t * zone,dns_dialuptype_t dialup)15894 dns_zone_setdialup(dns_zone_t *zone, dns_dialuptype_t dialup) {
15895 REQUIRE(DNS_ZONE_VALID(zone));
15896
15897 LOCK_ZONE(zone);
15898 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DIALNOTIFY |
15899 DNS_ZONEFLG_DIALREFRESH |
15900 DNS_ZONEFLG_NOREFRESH);
15901 switch (dialup) {
15902 case dns_dialuptype_no:
15903 break;
15904 case dns_dialuptype_yes:
15905 DNS_ZONE_SETFLAG(zone, (DNS_ZONEFLG_DIALNOTIFY |
15906 DNS_ZONEFLG_DIALREFRESH |
15907 DNS_ZONEFLG_NOREFRESH));
15908 break;
15909 case dns_dialuptype_notify:
15910 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY);
15911 break;
15912 case dns_dialuptype_notifypassive:
15913 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY);
15914 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
15915 break;
15916 case dns_dialuptype_refresh:
15917 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALREFRESH);
15918 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
15919 break;
15920 case dns_dialuptype_passive:
15921 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
15922 break;
15923 default:
15924 INSIST(0);
15925 }
15926 UNLOCK_ZONE(zone);
15927 }
15928
15929 isc_result_t
dns_zone_setkeydirectory(dns_zone_t * zone,const char * directory)15930 dns_zone_setkeydirectory(dns_zone_t *zone, const char *directory) {
15931 isc_result_t result = ISC_R_SUCCESS;
15932
15933 REQUIRE(DNS_ZONE_VALID(zone));
15934
15935 LOCK_ZONE(zone);
15936 result = dns_zone_setstring(zone, &zone->keydirectory, directory);
15937 UNLOCK_ZONE(zone);
15938
15939 return (result);
15940 }
15941
15942 const char *
dns_zone_getkeydirectory(dns_zone_t * zone)15943 dns_zone_getkeydirectory(dns_zone_t *zone) {
15944 REQUIRE(DNS_ZONE_VALID(zone));
15945
15946 return (zone->keydirectory);
15947 }
15948
15949 unsigned int
dns_zonemgr_getcount(dns_zonemgr_t * zmgr,int state)15950 dns_zonemgr_getcount(dns_zonemgr_t *zmgr, int state) {
15951 dns_zone_t *zone;
15952 unsigned int count = 0;
15953
15954 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15955
15956 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
15957 switch (state) {
15958 case DNS_ZONESTATE_XFERRUNNING:
15959 for (zone = ISC_LIST_HEAD(zmgr->xfrin_in_progress);
15960 zone != NULL;
15961 zone = ISC_LIST_NEXT(zone, statelink))
15962 count++;
15963 break;
15964 case DNS_ZONESTATE_XFERDEFERRED:
15965 for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin);
15966 zone != NULL;
15967 zone = ISC_LIST_NEXT(zone, statelink))
15968 count++;
15969 break;
15970 case DNS_ZONESTATE_SOAQUERY:
15971 for (zone = ISC_LIST_HEAD(zmgr->zones);
15972 zone != NULL;
15973 zone = ISC_LIST_NEXT(zone, link))
15974 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH))
15975 count++;
15976 break;
15977 case DNS_ZONESTATE_ANY:
15978 for (zone = ISC_LIST_HEAD(zmgr->zones);
15979 zone != NULL;
15980 zone = ISC_LIST_NEXT(zone, link)) {
15981 dns_view_t *view = zone->view;
15982 if (view != NULL && strcmp(view->name, "_bind") == 0)
15983 continue;
15984 count++;
15985 }
15986 break;
15987 default:
15988 INSIST(0);
15989 }
15990
15991 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
15992
15993 return (count);
15994 }
15995
15996 isc_result_t
dns_zone_checknames(dns_zone_t * zone,dns_name_t * name,dns_rdata_t * rdata)15997 dns_zone_checknames(dns_zone_t *zone, dns_name_t *name, dns_rdata_t *rdata) {
15998 isc_boolean_t ok = ISC_TRUE;
15999 isc_boolean_t fail = ISC_FALSE;
16000 char namebuf[DNS_NAME_FORMATSIZE];
16001 char namebuf2[DNS_NAME_FORMATSIZE];
16002 char typebuf[DNS_RDATATYPE_FORMATSIZE];
16003 int level = ISC_LOG_WARNING;
16004 dns_name_t bad;
16005
16006 REQUIRE(DNS_ZONE_VALID(zone));
16007
16008 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES) &&
16009 rdata->type != dns_rdatatype_nsec3)
16010 return (ISC_R_SUCCESS);
16011
16012 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL) ||
16013 rdata->type == dns_rdatatype_nsec3) {
16014 level = ISC_LOG_ERROR;
16015 fail = ISC_TRUE;
16016 }
16017
16018 ok = dns_rdata_checkowner(name, rdata->rdclass, rdata->type, ISC_TRUE);
16019 if (!ok) {
16020 dns_name_format(name, namebuf, sizeof(namebuf));
16021 dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf));
16022 dns_zone_log(zone, level, "%s/%s: %s", namebuf, typebuf,
16023 dns_result_totext(DNS_R_BADOWNERNAME));
16024 if (fail)
16025 return (DNS_R_BADOWNERNAME);
16026 }
16027
16028 dns_name_init(&bad, NULL);
16029 ok = dns_rdata_checknames(rdata, name, &bad);
16030 if (!ok) {
16031 dns_name_format(name, namebuf, sizeof(namebuf));
16032 dns_name_format(&bad, namebuf2, sizeof(namebuf2));
16033 dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf));
16034 dns_zone_log(zone, level, "%s/%s: %s: %s ", namebuf, typebuf,
16035 namebuf2, dns_result_totext(DNS_R_BADNAME));
16036 if (fail)
16037 return (DNS_R_BADNAME);
16038 }
16039
16040 return (ISC_R_SUCCESS);
16041 }
16042
16043 void
dns_zone_setcheckmx(dns_zone_t * zone,dns_checkmxfunc_t checkmx)16044 dns_zone_setcheckmx(dns_zone_t *zone, dns_checkmxfunc_t checkmx) {
16045 REQUIRE(DNS_ZONE_VALID(zone));
16046 zone->checkmx = checkmx;
16047 }
16048
16049 void
dns_zone_setchecksrv(dns_zone_t * zone,dns_checksrvfunc_t checksrv)16050 dns_zone_setchecksrv(dns_zone_t *zone, dns_checksrvfunc_t checksrv) {
16051 REQUIRE(DNS_ZONE_VALID(zone));
16052 zone->checksrv = checksrv;
16053 }
16054
16055 void
dns_zone_setcheckns(dns_zone_t * zone,dns_checknsfunc_t checkns)16056 dns_zone_setcheckns(dns_zone_t *zone, dns_checknsfunc_t checkns) {
16057 REQUIRE(DNS_ZONE_VALID(zone));
16058 zone->checkns = checkns;
16059 }
16060
16061 void
dns_zone_setisself(dns_zone_t * zone,dns_isselffunc_t isself,void * arg)16062 dns_zone_setisself(dns_zone_t *zone, dns_isselffunc_t isself, void *arg) {
16063 REQUIRE(DNS_ZONE_VALID(zone));
16064
16065 LOCK_ZONE(zone);
16066 zone->isself = isself;
16067 zone->isselfarg = arg;
16068 UNLOCK_ZONE(zone);
16069 }
16070
16071 void
dns_zone_setnotifydelay(dns_zone_t * zone,isc_uint32_t delay)16072 dns_zone_setnotifydelay(dns_zone_t *zone, isc_uint32_t delay) {
16073 REQUIRE(DNS_ZONE_VALID(zone));
16074
16075 LOCK_ZONE(zone);
16076 zone->notifydelay = delay;
16077 UNLOCK_ZONE(zone);
16078 }
16079
16080 isc_uint32_t
dns_zone_getnotifydelay(dns_zone_t * zone)16081 dns_zone_getnotifydelay(dns_zone_t *zone) {
16082 REQUIRE(DNS_ZONE_VALID(zone));
16083
16084 return (zone->notifydelay);
16085 }
16086
16087 isc_result_t
dns_zone_signwithkey(dns_zone_t * zone,dns_secalg_t algorithm,isc_uint16_t keyid,isc_boolean_t delete)16088 dns_zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm,
16089 isc_uint16_t keyid, isc_boolean_t delete)
16090 {
16091 isc_result_t result;
16092 REQUIRE(DNS_ZONE_VALID(zone));
16093
16094 dns_zone_log(zone, ISC_LOG_NOTICE,
16095 "dns_zone_signwithkey(algorithm=%u, keyid=%u)",
16096 algorithm, keyid);
16097 LOCK_ZONE(zone);
16098 result = zone_signwithkey(zone, algorithm, keyid, delete);
16099 UNLOCK_ZONE(zone);
16100
16101 return (result);
16102 }
16103
16104 static const char *hex = "0123456789ABCDEF";
16105
16106 isc_result_t
dns_zone_addnsec3chain(dns_zone_t * zone,dns_rdata_nsec3param_t * nsec3param)16107 dns_zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) {
16108 isc_result_t result;
16109 char salt[255*2+1];
16110 unsigned int i, j;
16111
16112 REQUIRE(DNS_ZONE_VALID(zone));
16113
16114 if (nsec3param->salt_length != 0) {
16115 INSIST((nsec3param->salt_length * 2U) < sizeof(salt));
16116 for (i = 0, j = 0; i < nsec3param->salt_length; i++) {
16117 salt[j++] = hex[(nsec3param->salt[i] >> 4) & 0xf];
16118 salt[j++] = hex[nsec3param->salt[i] & 0xf];
16119 }
16120 salt[j] = '\0';
16121 } else
16122 strcpy(salt, "-");
16123 dns_zone_log(zone, ISC_LOG_NOTICE,
16124 "dns_zone_addnsec3chain(hash=%u, iterations=%u, salt=%s)",
16125 nsec3param->hash, nsec3param->iterations,
16126 salt);
16127 LOCK_ZONE(zone);
16128 result = zone_addnsec3chain(zone, nsec3param);
16129 UNLOCK_ZONE(zone);
16130
16131 return (result);
16132 }
16133
16134 void
dns_zone_setnodes(dns_zone_t * zone,isc_uint32_t nodes)16135 dns_zone_setnodes(dns_zone_t *zone, isc_uint32_t nodes) {
16136 REQUIRE(DNS_ZONE_VALID(zone));
16137
16138 if (nodes == 0)
16139 nodes = 1;
16140 zone->nodes = nodes;
16141 }
16142
16143 void
dns_zone_setsignatures(dns_zone_t * zone,isc_uint32_t signatures)16144 dns_zone_setsignatures(dns_zone_t *zone, isc_uint32_t signatures) {
16145 REQUIRE(DNS_ZONE_VALID(zone));
16146
16147 /*
16148 * We treat signatures as a signed value so explicitly
16149 * limit its range here.
16150 */
16151 if (signatures > ISC_INT32_MAX)
16152 signatures = ISC_INT32_MAX;
16153 else if (signatures == 0)
16154 signatures = 1;
16155 zone->signatures = signatures;
16156 }
16157
16158 isc_uint32_t
dns_zone_getsignatures(dns_zone_t * zone)16159 dns_zone_getsignatures(dns_zone_t *zone) {
16160 REQUIRE(DNS_ZONE_VALID(zone));
16161 return (zone->signatures);
16162 }
16163
16164 void
dns_zone_setprivatetype(dns_zone_t * zone,dns_rdatatype_t type)16165 dns_zone_setprivatetype(dns_zone_t *zone, dns_rdatatype_t type) {
16166 REQUIRE(DNS_ZONE_VALID(zone));
16167 zone->privatetype = type;
16168 }
16169
16170 dns_rdatatype_t
dns_zone_getprivatetype(dns_zone_t * zone)16171 dns_zone_getprivatetype(dns_zone_t *zone) {
16172 REQUIRE(DNS_ZONE_VALID(zone));
16173 return (zone->privatetype);
16174 }
16175
16176 static isc_result_t
zone_signwithkey(dns_zone_t * zone,dns_secalg_t algorithm,isc_uint16_t keyid,isc_boolean_t delete)16177 zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, isc_uint16_t keyid,
16178 isc_boolean_t delete)
16179 {
16180 dns_signing_t *signing;
16181 dns_signing_t *current;
16182 isc_result_t result = ISC_R_SUCCESS;
16183 isc_time_t now;
16184 dns_db_t *db = NULL;
16185
16186 signing = isc_mem_get(zone->mctx, sizeof *signing);
16187 if (signing == NULL)
16188 return (ISC_R_NOMEMORY);
16189
16190 signing->magic = 0;
16191 signing->db = NULL;
16192 signing->dbiterator = NULL;
16193 signing->algorithm = algorithm;
16194 signing->keyid = keyid;
16195 signing->delete = delete;
16196 signing->done = ISC_FALSE;
16197
16198 TIME_NOW(&now);
16199
16200 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
16201 if (zone->db != NULL)
16202 dns_db_attach(zone->db, &db);
16203 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
16204
16205 if (db == NULL) {
16206 result = ISC_R_NOTFOUND;
16207 goto cleanup;
16208 }
16209
16210 dns_db_attach(db, &signing->db);
16211
16212 for (current = ISC_LIST_HEAD(zone->signing);
16213 current != NULL;
16214 current = ISC_LIST_NEXT(current, link)) {
16215 if (current->db == signing->db &&
16216 current->algorithm == signing->algorithm &&
16217 current->keyid == signing->keyid) {
16218 if (current->delete != signing->delete)
16219 current->done = ISC_TRUE;
16220 else
16221 goto cleanup;
16222 }
16223 }
16224
16225 result = dns_db_createiterator(signing->db, 0,
16226 &signing->dbiterator);
16227
16228 if (result == ISC_R_SUCCESS)
16229 result = dns_dbiterator_first(signing->dbiterator);
16230 if (result == ISC_R_SUCCESS) {
16231 dns_dbiterator_pause(signing->dbiterator);
16232 ISC_LIST_INITANDAPPEND(zone->signing, signing, link);
16233 signing = NULL;
16234 if (isc_time_isepoch(&zone->signingtime)) {
16235 zone->signingtime = now;
16236 if (zone->task != NULL)
16237 zone_settimer(zone, &now);
16238 }
16239 }
16240
16241 cleanup:
16242 if (signing != NULL) {
16243 if (signing->db != NULL)
16244 dns_db_detach(&signing->db);
16245 if (signing->dbiterator != NULL)
16246 dns_dbiterator_destroy(&signing->dbiterator);
16247 isc_mem_put(zone->mctx, signing, sizeof *signing);
16248 }
16249 if (db != NULL)
16250 dns_db_detach(&db);
16251 return (result);
16252 }
16253
16254 static void
logmsg(const char * format,...)16255 logmsg(const char *format, ...) {
16256 va_list args;
16257 va_start(args, format);
16258 isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE,
16259 ISC_LOG_DEBUG(1), format, args);
16260 va_end(args);
16261 }
16262
16263 static void
clear_keylist(dns_dnsseckeylist_t * list,isc_mem_t * mctx)16264 clear_keylist(dns_dnsseckeylist_t *list, isc_mem_t *mctx) {
16265 dns_dnsseckey_t *key;
16266 while (!ISC_LIST_EMPTY(*list)) {
16267 key = ISC_LIST_HEAD(*list);
16268 ISC_LIST_UNLINK(*list, key, link);
16269 dns_dnsseckey_destroy(mctx, &key);
16270 }
16271 }
16272
16273 /* Called once; *timep should be set to the current time. */
16274 static isc_result_t
next_keyevent(dst_key_t * key,isc_stdtime_t * timep)16275 next_keyevent(dst_key_t *key, isc_stdtime_t *timep) {
16276 isc_result_t result;
16277 isc_stdtime_t now, then = 0, event;
16278 int i;
16279
16280 now = *timep;
16281
16282 for (i = 0; i <= DST_MAX_TIMES; i++) {
16283 result = dst_key_gettime(key, i, &event);
16284 if (result == ISC_R_SUCCESS && event > now &&
16285 (then == 0 || event < then))
16286 then = event;
16287 }
16288
16289 if (then != 0) {
16290 *timep = then;
16291 return (ISC_R_SUCCESS);
16292 }
16293
16294 return (ISC_R_NOTFOUND);
16295 }
16296
16297 static isc_result_t
rr_exists(dns_db_t * db,dns_dbversion_t * ver,dns_name_t * name,const dns_rdata_t * rdata,isc_boolean_t * flag)16298 rr_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
16299 const dns_rdata_t *rdata, isc_boolean_t *flag)
16300 {
16301 dns_rdataset_t rdataset;
16302 dns_dbnode_t *node = NULL;
16303 isc_result_t result;
16304
16305 dns_rdataset_init(&rdataset);
16306 if (rdata->type == dns_rdatatype_nsec3)
16307 CHECK(dns_db_findnsec3node(db, name, ISC_FALSE, &node));
16308 else
16309 CHECK(dns_db_findnode(db, name, ISC_FALSE, &node));
16310 result = dns_db_findrdataset(db, node, ver, rdata->type, 0,
16311 (isc_stdtime_t) 0, &rdataset, NULL);
16312 if (result == ISC_R_NOTFOUND) {
16313 *flag = ISC_FALSE;
16314 result = ISC_R_SUCCESS;
16315 goto failure;
16316 }
16317
16318 for (result = dns_rdataset_first(&rdataset);
16319 result == ISC_R_SUCCESS;
16320 result = dns_rdataset_next(&rdataset)) {
16321 dns_rdata_t myrdata = DNS_RDATA_INIT;
16322 dns_rdataset_current(&rdataset, &myrdata);
16323 if (!dns_rdata_compare(&myrdata, rdata))
16324 break;
16325 }
16326 dns_rdataset_disassociate(&rdataset);
16327 if (result == ISC_R_SUCCESS) {
16328 *flag = ISC_TRUE;
16329 } else if (result == ISC_R_NOMORE) {
16330 *flag = ISC_FALSE;
16331 result = ISC_R_SUCCESS;
16332 }
16333
16334 failure:
16335 if (node != NULL)
16336 dns_db_detachnode(db, &node);
16337 return (result);
16338 }
16339
16340 /*
16341 * Add records to signal the state of signing or of key removal.
16342 */
16343 static isc_result_t
add_signing_records(dns_db_t * db,dns_rdatatype_t privatetype,dns_dbversion_t * ver,dns_diff_t * diff,isc_boolean_t sign_all)16344 add_signing_records(dns_db_t *db, dns_rdatatype_t privatetype,
16345 dns_dbversion_t *ver, dns_diff_t *diff,
16346 isc_boolean_t sign_all)
16347 {
16348 dns_difftuple_t *tuple, *newtuple = NULL;
16349 dns_rdata_dnskey_t dnskey;
16350 dns_rdata_t rdata = DNS_RDATA_INIT;
16351 isc_boolean_t flag;
16352 isc_region_t r;
16353 isc_result_t result = ISC_R_SUCCESS;
16354 isc_uint16_t keyid;
16355 unsigned char buf[5];
16356 dns_name_t *name = dns_db_origin(db);
16357
16358 for (tuple = ISC_LIST_HEAD(diff->tuples);
16359 tuple != NULL;
16360 tuple = ISC_LIST_NEXT(tuple, link)) {
16361 if (tuple->rdata.type != dns_rdatatype_dnskey)
16362 continue;
16363
16364 result = dns_rdata_tostruct(&tuple->rdata, &dnskey, NULL);
16365 RUNTIME_CHECK(result == ISC_R_SUCCESS);
16366 if ((dnskey.flags &
16367 (DNS_KEYFLAG_OWNERMASK|DNS_KEYTYPE_NOAUTH))
16368 != DNS_KEYOWNER_ZONE)
16369 continue;
16370
16371 dns_rdata_toregion(&tuple->rdata, &r);
16372
16373 keyid = dst_region_computeid(&r, dnskey.algorithm);
16374
16375 buf[0] = dnskey.algorithm;
16376 buf[1] = (keyid & 0xff00) >> 8;
16377 buf[2] = (keyid & 0xff);
16378 buf[3] = (tuple->op == DNS_DIFFOP_ADD) ? 0 : 1;
16379 buf[4] = 0;
16380 rdata.data = buf;
16381 rdata.length = sizeof(buf);
16382 rdata.type = privatetype;
16383 rdata.rdclass = tuple->rdata.rdclass;
16384
16385 if (sign_all || tuple->op == DNS_DIFFOP_DEL) {
16386 CHECK(rr_exists(db, ver, name, &rdata, &flag));
16387 if (flag)
16388 continue;
16389 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
16390 name, 0, &rdata, &newtuple));
16391 CHECK(do_one_tuple(&newtuple, db, ver, diff));
16392 INSIST(newtuple == NULL);
16393 }
16394
16395 /*
16396 * Remove any record which says this operation has already
16397 * completed.
16398 */
16399 buf[4] = 1;
16400 CHECK(rr_exists(db, ver, name, &rdata, &flag));
16401 if (flag) {
16402 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL,
16403 name, 0, &rdata, &newtuple));
16404 CHECK(do_one_tuple(&newtuple, db, ver, diff));
16405 INSIST(newtuple == NULL);
16406 }
16407 }
16408 failure:
16409 return (result);
16410 }
16411
16412 static isc_result_t
sign_apex(dns_zone_t * zone,dns_db_t * db,dns_dbversion_t * ver,dns_diff_t * diff,zonediff_t * zonediff)16413 sign_apex(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
16414 dns_diff_t *diff, zonediff_t *zonediff)
16415 {
16416 isc_result_t result;
16417 isc_stdtime_t now, inception, soaexpire;
16418 isc_boolean_t check_ksk, keyset_kskonly;
16419 dst_key_t *zone_keys[DNS_MAXZONEKEYS];
16420 unsigned int nkeys = 0, i;
16421 dns_difftuple_t *tuple;
16422
16423 result = find_zone_keys(zone, db, ver, zone->mctx, DNS_MAXZONEKEYS,
16424 zone_keys, &nkeys);
16425 if (result != ISC_R_SUCCESS) {
16426 dns_zone_log(zone, ISC_LOG_ERROR,
16427 "sign_apex:find_zone_keys -> %s",
16428 dns_result_totext(result));
16429 return (result);
16430 }
16431
16432 isc_stdtime_get(&now);
16433 inception = now - 3600; /* Allow for clock skew. */
16434 soaexpire = now + dns_zone_getsigvalidityinterval(zone);
16435
16436 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
16437 keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
16438
16439 /*
16440 * See if update_sigs will update DNSKEY signature and if not
16441 * cause them to sign so that so that newly activated keys
16442 * are used.
16443 */
16444 for (tuple = ISC_LIST_HEAD(diff->tuples);
16445 tuple != NULL;
16446 tuple = ISC_LIST_NEXT(tuple, link)) {
16447 if (tuple->rdata.type == dns_rdatatype_dnskey &&
16448 dns_name_equal(&tuple->name, &zone->origin))
16449 break;
16450 }
16451
16452 if (tuple == NULL) {
16453 result = del_sigs(zone, db, ver, &zone->origin,
16454 dns_rdatatype_dnskey, zonediff,
16455 zone_keys, nkeys, now, ISC_FALSE);
16456 if (result != ISC_R_SUCCESS) {
16457 dns_zone_log(zone, ISC_LOG_ERROR,
16458 "sign_apex:del_sigs -> %s",
16459 dns_result_totext(result));
16460 goto failure;
16461 }
16462 result = add_sigs(db, ver, &zone->origin, dns_rdatatype_dnskey,
16463 zonediff->diff, zone_keys, nkeys, zone->mctx,
16464 inception, soaexpire, check_ksk,
16465 keyset_kskonly);
16466 if (result != ISC_R_SUCCESS) {
16467 dns_zone_log(zone, ISC_LOG_ERROR,
16468 "sign_apex:add_sigs -> %s",
16469 dns_result_totext(result));
16470 goto failure;
16471 }
16472 }
16473
16474 result = update_sigs(diff, db, ver, zone_keys, nkeys, zone,
16475 inception, soaexpire, now, check_ksk,
16476 keyset_kskonly, zonediff);
16477
16478 if (result != ISC_R_SUCCESS) {
16479 dns_zone_log(zone, ISC_LOG_ERROR,
16480 "sign_apex:update_sigs -> %s",
16481 dns_result_totext(result));
16482 goto failure;
16483 }
16484
16485 failure:
16486 for (i = 0; i < nkeys; i++)
16487 dst_key_free(&zone_keys[i]);
16488 return (result);
16489 }
16490
16491 /*
16492 * Prevent the zone entering a inconsistent state where
16493 * NSEC only DNSKEYs are present with NSEC3 chains.
16494 * See update.c:check_dnssec()
16495 */
16496 static isc_boolean_t
dnskey_sane(dns_zone_t * zone,dns_db_t * db,dns_dbversion_t * ver,dns_diff_t * diff)16497 dnskey_sane(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
16498 dns_diff_t *diff)
16499 {
16500 isc_result_t result;
16501 dns_difftuple_t *tuple;
16502 isc_boolean_t nseconly = ISC_FALSE, nsec3 = ISC_FALSE;
16503 dns_rdatatype_t privatetype = dns_zone_getprivatetype(zone);
16504
16505 /* Scan the tuples for an NSEC-only DNSKEY */
16506 for (tuple = ISC_LIST_HEAD(diff->tuples);
16507 tuple != NULL;
16508 tuple = ISC_LIST_NEXT(tuple, link)) {
16509 isc_uint8_t alg;
16510 if (tuple->rdata.type != dns_rdatatype_dnskey ||
16511 tuple->op != DNS_DIFFOP_ADD)
16512 continue;
16513
16514 alg = tuple->rdata.data[3];
16515 if (alg == DST_ALG_RSAMD5 || alg == DST_ALG_RSASHA1 ||
16516 alg == DST_ALG_DSA || alg == DST_ALG_ECC) {
16517 nseconly = ISC_TRUE;
16518 break;
16519 }
16520 }
16521
16522 /* Check existing DB for NSEC-only DNSKEY */
16523 if (!nseconly) {
16524 result = dns_nsec_nseconly(db, ver, &nseconly);
16525 if (result == ISC_R_NOTFOUND)
16526 result = ISC_R_SUCCESS;
16527 CHECK(result);
16528 }
16529
16530 /* Check existing DB for NSEC3 */
16531 if (!nsec3)
16532 CHECK(dns_nsec3_activex(db, ver, ISC_FALSE,
16533 privatetype, &nsec3));
16534
16535 /* Refuse to allow NSEC3 with NSEC-only keys */
16536 if (nseconly && nsec3) {
16537 dns_zone_log(zone, ISC_LOG_ERROR,
16538 "NSEC only DNSKEYs and NSEC3 chains not allowed");
16539 goto failure;
16540 }
16541
16542 return (ISC_TRUE);
16543
16544 failure:
16545 return (ISC_FALSE);
16546 }
16547
16548 static isc_result_t
clean_nsec3param(dns_zone_t * zone,dns_db_t * db,dns_dbversion_t * ver,dns_diff_t * diff)16549 clean_nsec3param(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
16550 dns_diff_t *diff)
16551 {
16552 isc_result_t result;
16553 dns_dbnode_t *node = NULL;
16554 dns_rdataset_t rdataset;
16555
16556 dns_rdataset_init(&rdataset);
16557 CHECK(dns_db_getoriginnode(db, &node));
16558
16559 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey,
16560 dns_rdatatype_none, 0, &rdataset, NULL);
16561 if (dns_rdataset_isassociated(&rdataset))
16562 dns_rdataset_disassociate(&rdataset);
16563 if (result != ISC_R_NOTFOUND)
16564 goto failure;
16565
16566 result = dns_nsec3param_deletechains(db, ver, zone, ISC_TRUE, diff);
16567
16568 failure:
16569 if (node != NULL)
16570 dns_db_detachnode(db, &node);
16571 return (result);
16572 }
16573
16574 /*
16575 * Given an RRSIG rdataset and an algorithm, determine whether there
16576 * are any signatures using that algorithm.
16577 */
16578 static isc_boolean_t
signed_with_alg(dns_rdataset_t * rdataset,dns_secalg_t alg)16579 signed_with_alg(dns_rdataset_t *rdataset, dns_secalg_t alg) {
16580 dns_rdata_t rdata = DNS_RDATA_INIT;
16581 dns_rdata_rrsig_t rrsig;
16582 isc_result_t result;
16583
16584 REQUIRE(rdataset == NULL || rdataset->type == dns_rdatatype_rrsig);
16585 if (rdataset == NULL || !dns_rdataset_isassociated(rdataset)) {
16586 return (ISC_FALSE);
16587 }
16588
16589 for (result = dns_rdataset_first(rdataset);
16590 result == ISC_R_SUCCESS;
16591 result = dns_rdataset_next(rdataset))
16592 {
16593 dns_rdataset_current(rdataset, &rdata);
16594 result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
16595 RUNTIME_CHECK(result == ISC_R_SUCCESS);
16596 dns_rdata_reset(&rdata);
16597 if (rrsig.algorithm == alg)
16598 return (ISC_TRUE);
16599 }
16600
16601 return (ISC_FALSE);
16602 }
16603
16604 static isc_result_t
add_chains(dns_zone_t * zone,dns_db_t * db,dns_dbversion_t * ver,dns_diff_t * diff)16605 add_chains(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
16606 dns_diff_t *diff)
16607 {
16608 dns_name_t *origin;
16609 isc_boolean_t build_nsec3;
16610 isc_result_t result;
16611
16612 origin = dns_db_origin(db);
16613 CHECK(dns_private_chains(db, ver, zone->privatetype, NULL,
16614 &build_nsec3));
16615 if (build_nsec3)
16616 CHECK(dns_nsec3_addnsec3sx(db, ver, origin, zone->minimum,
16617 ISC_FALSE, zone->privatetype, diff));
16618 CHECK(updatesecure(db, ver, origin, zone->minimum, ISC_TRUE, diff));
16619
16620 failure:
16621 return (result);
16622 }
16623
16624 static void
zone_rekey(dns_zone_t * zone)16625 zone_rekey(dns_zone_t *zone) {
16626 isc_result_t result;
16627 dns_db_t *db = NULL;
16628 dns_dbnode_t *node = NULL;
16629 dns_dbversion_t *ver = NULL;
16630 dns_rdataset_t soaset, soasigs, keyset, keysigs;
16631 dns_dnsseckeylist_t dnskeys, keys, rmkeys;
16632 dns_dnsseckey_t *key;
16633 dns_diff_t diff, _sig_diff;
16634 zonediff_t zonediff;
16635 isc_boolean_t commit = ISC_FALSE, newactive = ISC_FALSE;
16636 isc_boolean_t newalg = ISC_FALSE;
16637 isc_boolean_t fullsign;
16638 dns_ttl_t ttl = 3600;
16639 const char *dir;
16640 isc_mem_t *mctx;
16641 isc_stdtime_t now;
16642 isc_time_t timenow;
16643 isc_interval_t ival;
16644 char timebuf[80];
16645
16646 REQUIRE(DNS_ZONE_VALID(zone));
16647
16648 ISC_LIST_INIT(dnskeys);
16649 ISC_LIST_INIT(keys);
16650 ISC_LIST_INIT(rmkeys);
16651 dns_rdataset_init(&soaset);
16652 dns_rdataset_init(&soasigs);
16653 dns_rdataset_init(&keyset);
16654 dns_rdataset_init(&keysigs);
16655 dir = dns_zone_getkeydirectory(zone);
16656 mctx = zone->mctx;
16657 dns_diff_init(mctx, &diff);
16658 dns_diff_init(mctx, &_sig_diff);
16659 zonediff_init(&zonediff, &_sig_diff);
16660
16661 CHECK(dns_zone_getdb(zone, &db));
16662 CHECK(dns_db_newversion(db, &ver));
16663 CHECK(dns_db_getoriginnode(db, &node));
16664
16665 TIME_NOW(&timenow);
16666 now = isc_time_seconds(&timenow);
16667
16668 dns_zone_log(zone, ISC_LOG_INFO, "reconfiguring zone keys");
16669
16670 /* Get the SOA record's TTL */
16671 CHECK(dns_db_findrdataset(db, node, ver, dns_rdatatype_soa,
16672 dns_rdatatype_none, 0, &soaset, &soasigs));
16673 ttl = soaset.ttl;
16674 dns_rdataset_disassociate(&soaset);
16675
16676 /* Get the DNSKEY rdataset */
16677 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey,
16678 dns_rdatatype_none, 0, &keyset, &keysigs);
16679 if (result == ISC_R_SUCCESS) {
16680 ttl = keyset.ttl;
16681 CHECK(dns_dnssec_keylistfromrdataset(&zone->origin, dir,
16682 mctx, &keyset,
16683 &keysigs, &soasigs,
16684 ISC_FALSE, ISC_FALSE,
16685 &dnskeys));
16686 } else if (result != ISC_R_NOTFOUND)
16687 goto failure;
16688
16689 /*
16690 * True when called from "rndc sign". Indicates the zone should be
16691 * fully signed now.
16692 */
16693 fullsign = ISC_TF(DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_FULLSIGN) != 0);
16694
16695 result = dns_dnssec_findmatchingkeys(&zone->origin, dir, mctx, &keys);
16696 if (result == ISC_R_SUCCESS) {
16697 isc_boolean_t check_ksk;
16698 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
16699
16700 result = dns_dnssec_updatekeys(&dnskeys, &keys, &rmkeys,
16701 &zone->origin, ttl, &diff,
16702 ISC_TF(!check_ksk),
16703 mctx, logmsg);
16704
16705 /* Keys couldn't be updated for some reason;
16706 * try again later. */
16707 if (result != ISC_R_SUCCESS) {
16708 dns_zone_log(zone, ISC_LOG_ERROR, "zone_rekey:"
16709 "couldn't update zone keys: %s",
16710 isc_result_totext(result));
16711 goto failure;
16712 }
16713
16714 /*
16715 * See if any pre-existing keys have newly become active;
16716 * also, see if any new key is for a new algorithm, as in that
16717 * event, we need to sign the zone fully. (If there's a new
16718 * key, but it's for an already-existing algorithm, then
16719 * the zone signing can be handled incrementally.)
16720 */
16721 for (key = ISC_LIST_HEAD(dnskeys);
16722 key != NULL;
16723 key = ISC_LIST_NEXT(key, link)) {
16724 if (!key->first_sign)
16725 continue;
16726
16727 newactive = ISC_TRUE;
16728
16729 if (!dns_rdataset_isassociated(&keysigs)) {
16730 newalg = ISC_TRUE;
16731 break;
16732 }
16733
16734 if (signed_with_alg(&keysigs, dst_key_alg(key->key))) {
16735 /*
16736 * This isn't a new algorithm; clear
16737 * first_sign so we won't sign the
16738 * whole zone with this key later
16739 */
16740 key->first_sign = ISC_FALSE;
16741 } else {
16742 newalg = ISC_TRUE;
16743 break;
16744 }
16745 }
16746
16747 if ((newactive || fullsign || !ISC_LIST_EMPTY(diff.tuples)) &&
16748 dnskey_sane(zone, db, ver, &diff)) {
16749 CHECK(dns_diff_apply(&diff, db, ver));
16750 CHECK(clean_nsec3param(zone, db, ver, &diff));
16751 CHECK(add_signing_records(db, zone->privatetype,
16752 ver, &diff,
16753 ISC_TF(newalg || fullsign)));
16754 CHECK(update_soa_serial(db, ver, &diff, mctx,
16755 zone->updatemethod));
16756 CHECK(add_chains(zone, db, ver, &diff));
16757 CHECK(sign_apex(zone, db, ver, &diff, &zonediff));
16758 CHECK(zone_journal(zone, zonediff.diff, NULL,
16759 "zone_rekey"));
16760 commit = ISC_TRUE;
16761 }
16762 }
16763
16764 dns_db_closeversion(db, &ver, ISC_TRUE);
16765
16766 if (commit) {
16767 dns_difftuple_t *tuple;
16768
16769 LOCK_ZONE(zone);
16770 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
16771
16772 zone_needdump(zone, DNS_DUMP_DELAY);
16773
16774 zone_settimer(zone, &timenow);
16775
16776 /* Remove any signatures from removed keys. */
16777 if (!ISC_LIST_EMPTY(rmkeys)) {
16778 for (key = ISC_LIST_HEAD(rmkeys);
16779 key != NULL;
16780 key = ISC_LIST_NEXT(key, link)) {
16781 result = zone_signwithkey(zone,
16782 dst_key_alg(key->key),
16783 dst_key_id(key->key),
16784 ISC_TRUE);
16785 if (result != ISC_R_SUCCESS) {
16786 dns_zone_log(zone, ISC_LOG_ERROR,
16787 "zone_signwithkey failed: %s",
16788 dns_result_totext(result));
16789 }
16790 }
16791 }
16792
16793 if (fullsign) {
16794 /*
16795 * "rndc sign" was called, so we now sign the zone
16796 * with all active keys, whether they're new or not.
16797 */
16798 for (key = ISC_LIST_HEAD(dnskeys);
16799 key != NULL;
16800 key = ISC_LIST_NEXT(key, link)) {
16801 if (!key->force_sign && !key->hint_sign)
16802 continue;
16803
16804 result = zone_signwithkey(zone,
16805 dst_key_alg(key->key),
16806 dst_key_id(key->key),
16807 ISC_FALSE);
16808 if (result != ISC_R_SUCCESS) {
16809 dns_zone_log(zone, ISC_LOG_ERROR,
16810 "zone_signwithkey failed: %s",
16811 dns_result_totext(result));
16812 }
16813 }
16814 } else if (newalg) {
16815 /*
16816 * We haven't been told to sign fully, but a new
16817 * algorithm was added to the DNSKEY. We sign
16818 * the full zone, but only with newly active
16819 * keys.
16820 */
16821 for (key = ISC_LIST_HEAD(dnskeys);
16822 key != NULL;
16823 key = ISC_LIST_NEXT(key, link)) {
16824 if (!key->first_sign)
16825 continue;
16826
16827 result = zone_signwithkey(zone,
16828 dst_key_alg(key->key),
16829 dst_key_id(key->key),
16830 ISC_FALSE);
16831 if (result != ISC_R_SUCCESS) {
16832 dns_zone_log(zone, ISC_LOG_ERROR,
16833 "zone_signwithkey failed: %s",
16834 dns_result_totext(result));
16835 }
16836 }
16837 }
16838
16839 /*
16840 * Clear fullsign flag, if it was set, so we don't do
16841 * another full signing next time
16842 */
16843 zone->keyopts &= ~DNS_ZONEKEY_FULLSIGN;
16844
16845 /*
16846 * Cause the zone to add/delete NSEC3 chains for the
16847 * deferred NSEC3PARAM changes.
16848 */
16849 for (tuple = ISC_LIST_HEAD(zonediff.diff->tuples);
16850 tuple != NULL;
16851 tuple = ISC_LIST_NEXT(tuple, link)) {
16852 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
16853 dns_rdata_t rdata = DNS_RDATA_INIT;
16854 dns_rdata_nsec3param_t nsec3param;
16855
16856 if (tuple->rdata.type != zone->privatetype ||
16857 tuple->op != DNS_DIFFOP_ADD)
16858 continue;
16859
16860 if (!dns_nsec3param_fromprivate(&tuple->rdata, &rdata,
16861 buf, sizeof(buf)))
16862 continue;
16863 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
16864 RUNTIME_CHECK(result == ISC_R_SUCCESS);
16865 if (nsec3param.flags == 0)
16866 continue;
16867
16868 result = zone_addnsec3chain(zone, &nsec3param);
16869 if (result != ISC_R_SUCCESS) {
16870 dns_zone_log(zone, ISC_LOG_ERROR,
16871 "zone_addnsec3chain failed: %s",
16872 dns_result_totext(result));
16873 }
16874 }
16875
16876 /*
16877 * Activate any NSEC3 chain updates that may have
16878 * been scheduled before this rekey.
16879 */
16880 if (fullsign || newalg)
16881 resume_addnsec3chain(zone);
16882
16883 /*
16884 * Schedule the next resigning event
16885 */
16886 set_resigntime(zone);
16887 UNLOCK_ZONE(zone);
16888 }
16889
16890 isc_time_settoepoch(&zone->refreshkeytime);
16891
16892 /*
16893 * If we're doing key maintenance, set the key refresh timer to
16894 * the next scheduled key event or to 'dnssec-loadkeys-interval'
16895 * seconds in the future, whichever is sooner.
16896 */
16897 if (DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN)) {
16898 isc_time_t timethen;
16899 isc_stdtime_t then;
16900
16901 LOCK_ZONE(zone);
16902 DNS_ZONE_TIME_ADD(&timenow, zone->refreshkeyinterval,
16903 &timethen);
16904 zone->refreshkeytime = timethen;
16905 UNLOCK_ZONE(zone);
16906
16907 for (key = ISC_LIST_HEAD(dnskeys);
16908 key != NULL;
16909 key = ISC_LIST_NEXT(key, link)) {
16910 then = now;
16911 result = next_keyevent(key->key, &then);
16912 if (result != ISC_R_SUCCESS)
16913 continue;
16914
16915 DNS_ZONE_TIME_ADD(&timenow, then - now, &timethen);
16916 LOCK_ZONE(zone);
16917 if (isc_time_compare(&timethen,
16918 &zone->refreshkeytime) < 0) {
16919 zone->refreshkeytime = timethen;
16920 }
16921 UNLOCK_ZONE(zone);
16922 }
16923
16924 zone_settimer(zone, &timenow);
16925
16926 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
16927 dns_zone_log(zone, ISC_LOG_INFO, "next key event: %s", timebuf);
16928 }
16929
16930 done:
16931 dns_diff_clear(&diff);
16932 dns_diff_clear(&_sig_diff);
16933
16934 clear_keylist(&dnskeys, mctx);
16935 clear_keylist(&keys, mctx);
16936 clear_keylist(&rmkeys, mctx);
16937
16938 if (ver != NULL)
16939 dns_db_closeversion(db, &ver, ISC_FALSE);
16940 if (dns_rdataset_isassociated(&keyset))
16941 dns_rdataset_disassociate(&keyset);
16942 if (dns_rdataset_isassociated(&keysigs))
16943 dns_rdataset_disassociate(&keysigs);
16944 if (dns_rdataset_isassociated(&soasigs))
16945 dns_rdataset_disassociate(&soasigs);
16946 if (node != NULL)
16947 dns_db_detachnode(db, &node);
16948 if (db != NULL)
16949 dns_db_detach(&db);
16950
16951 INSIST(ver == NULL);
16952 return;
16953
16954 failure:
16955 /*
16956 * Something went wrong; try again in ten minutes or
16957 * after a key refresh interval, whichever is shorter.
16958 */
16959 isc_interval_set(&ival, ISC_MIN(zone->refreshkeyinterval, 600), 0);
16960 isc_time_nowplusinterval(&zone->refreshkeytime, &ival);
16961 goto done;
16962 }
16963
16964 void
dns_zone_rekey(dns_zone_t * zone,isc_boolean_t fullsign)16965 dns_zone_rekey(dns_zone_t *zone, isc_boolean_t fullsign) {
16966 isc_time_t now;
16967
16968 if (zone->type == dns_zone_master && zone->task != NULL) {
16969 LOCK_ZONE(zone);
16970
16971 if (fullsign)
16972 zone->keyopts |= DNS_ZONEKEY_FULLSIGN;
16973
16974 TIME_NOW(&now);
16975 zone->refreshkeytime = now;
16976 zone_settimer(zone, &now);
16977
16978 UNLOCK_ZONE(zone);
16979 }
16980 }
16981
16982 isc_result_t
dns_zone_nscheck(dns_zone_t * zone,dns_db_t * db,dns_dbversion_t * version,unsigned int * errors)16983 dns_zone_nscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
16984 unsigned int *errors)
16985 {
16986 isc_result_t result;
16987 dns_dbnode_t *node = NULL;
16988
16989 REQUIRE(DNS_ZONE_VALID(zone));
16990 REQUIRE(errors != NULL);
16991
16992 result = dns_db_getoriginnode(db, &node);
16993 if (result != ISC_R_SUCCESS)
16994 return (result);
16995 result = zone_count_ns_rr(zone, db, node, version, NULL, errors,
16996 ISC_FALSE);
16997 dns_db_detachnode(db, &node);
16998 return (result);
16999 }
17000
17001 isc_result_t
dns_zone_cdscheck(dns_zone_t * zone,dns_db_t * db,dns_dbversion_t * version)17002 dns_zone_cdscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version) {
17003 isc_result_t result;
17004 dns_dbnode_t *node = NULL;
17005 dns_rdataset_t dnskey, cds, cdnskey;
17006 unsigned char buffer[DNS_DS_BUFFERSIZE];
17007 unsigned char algorithms[256];
17008 unsigned int i;
17009
17010 REQUIRE(DNS_ZONE_VALID(zone));
17011
17012 result = dns_db_getoriginnode(db, &node);
17013 if (result != ISC_R_SUCCESS)
17014 return (result);
17015
17016 dns_rdataset_init(&cds);
17017 dns_rdataset_init(&dnskey);
17018 dns_rdataset_init(&cdnskey);
17019
17020 result = dns_db_findrdataset(db, node, version, dns_rdatatype_cds,
17021 dns_rdatatype_none, 0, &cds, NULL);
17022 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
17023 goto failure;
17024
17025 result = dns_db_findrdataset(db, node, version, dns_rdatatype_cdnskey,
17026 dns_rdatatype_none, 0, &cdnskey, NULL);
17027 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
17028 goto failure;
17029
17030 if (!dns_rdataset_isassociated(&cds) &&
17031 !dns_rdataset_isassociated(&cdnskey)) {
17032 result = ISC_R_SUCCESS;
17033 goto failure;
17034 }
17035
17036 result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey,
17037 dns_rdatatype_none, 0, &dnskey, NULL);
17038 if (result == ISC_R_NOTFOUND) {
17039 if (dns_rdataset_isassociated(&cds))
17040 result = DNS_R_BADCDS;
17041 else
17042 result = DNS_R_BADCDNSKEY;
17043 goto failure;
17044 }
17045 if (result != ISC_R_SUCCESS)
17046 goto failure;
17047
17048 /*
17049 * For each DNSSEC algorithm in the CDS RRset there must be
17050 * a matching DNSKEY record.
17051 */
17052 if (dns_rdataset_isassociated(&cds)) {
17053 memset(algorithms, 0, sizeof(algorithms));
17054 for (result = dns_rdataset_first(&cds);
17055 result == ISC_R_SUCCESS;
17056 result = dns_rdataset_next(&cds)) {
17057 dns_rdata_t crdata = DNS_RDATA_INIT;
17058 dns_rdata_cds_t structcds;
17059
17060 dns_rdataset_current(&cds, &crdata);
17061 CHECK(dns_rdata_tostruct(&crdata, &structcds, NULL));
17062 if (algorithms[structcds.algorithm] == 0)
17063 algorithms[structcds.algorithm] = 1;
17064 for (result = dns_rdataset_first(&dnskey);
17065 result == ISC_R_SUCCESS;
17066 result = dns_rdataset_next(&dnskey)) {
17067 dns_rdata_t rdata = DNS_RDATA_INIT;
17068 dns_rdata_t dsrdata = DNS_RDATA_INIT;
17069
17070 dns_rdataset_current(&dnskey, &rdata);
17071 CHECK(dns_ds_buildrdata(&zone->origin, &rdata,
17072 structcds.digest_type,
17073 buffer, &dsrdata));
17074 if (crdata.length == dsrdata.length &&
17075 memcmp(crdata.data, dsrdata.data,
17076 dsrdata.length) == 0) {
17077 algorithms[structcds.algorithm] = 2;
17078 }
17079 }
17080 if (result != ISC_R_NOMORE)
17081 goto failure;
17082 }
17083 for (i = 0; i < sizeof(algorithms); i++) {
17084 if (algorithms[i] == 1) {
17085 result = DNS_R_BADCDNSKEY;
17086 goto failure;
17087 }
17088 }
17089 }
17090
17091 /*
17092 * For each DNSSEC algorithm in the CDNSKEY RRset there must be
17093 * a matching DNSKEY record.
17094 */
17095 if (dns_rdataset_isassociated(&cdnskey)) {
17096 memset(algorithms, 0, sizeof(algorithms));
17097 for (result = dns_rdataset_first(&cdnskey);
17098 result == ISC_R_SUCCESS;
17099 result = dns_rdataset_next(&cdnskey)) {
17100 dns_rdata_t crdata = DNS_RDATA_INIT;
17101 dns_rdata_cdnskey_t structcdnskey;
17102
17103 dns_rdataset_current(&cdnskey, &crdata);
17104 CHECK(dns_rdata_tostruct(&crdata, &structcdnskey,
17105 NULL));
17106 if (algorithms[structcdnskey.algorithm] == 0)
17107 algorithms[structcdnskey.algorithm] = 1;
17108 for (result = dns_rdataset_first(&dnskey);
17109 result == ISC_R_SUCCESS;
17110 result = dns_rdataset_next(&dnskey)) {
17111 dns_rdata_t rdata = DNS_RDATA_INIT;
17112
17113 dns_rdataset_current(&dnskey, &rdata);
17114 if (crdata.length == rdata.length &&
17115 memcmp(crdata.data, rdata.data,
17116 rdata.length) == 0) {
17117 algorithms[structcdnskey.algorithm] = 2;
17118 }
17119 }
17120 if (result != ISC_R_NOMORE)
17121 goto failure;
17122 }
17123 for (i = 0; i < sizeof(algorithms); i++) {
17124 if (algorithms[i] == 1) {
17125 result = DNS_R_BADCDS;
17126 goto failure;
17127 }
17128 }
17129 }
17130 result = ISC_R_SUCCESS;
17131
17132 failure:
17133 if (dns_rdataset_isassociated(&cds))
17134 dns_rdataset_disassociate(&cds);
17135 if (dns_rdataset_isassociated(&dnskey))
17136 dns_rdataset_disassociate(&dnskey);
17137 if (dns_rdataset_isassociated(&cdnskey))
17138 dns_rdataset_disassociate(&cdnskey);
17139 dns_db_detachnode(db, &node);
17140 return (result);
17141 }
17142
17143 void
dns_zone_setadded(dns_zone_t * zone,isc_boolean_t added)17144 dns_zone_setadded(dns_zone_t *zone, isc_boolean_t added) {
17145 REQUIRE(DNS_ZONE_VALID(zone));
17146 LOCK_ZONE(zone);
17147 zone->added = added;
17148 UNLOCK_ZONE(zone);
17149 }
17150
17151 isc_boolean_t
dns_zone_getadded(dns_zone_t * zone)17152 dns_zone_getadded(dns_zone_t *zone) {
17153 REQUIRE(DNS_ZONE_VALID(zone));
17154 return (zone->added);
17155 }
17156
17157 isc_result_t
dns_zone_dlzpostload(dns_zone_t * zone,dns_db_t * db)17158 dns_zone_dlzpostload(dns_zone_t *zone, dns_db_t *db)
17159 {
17160 isc_time_t loadtime;
17161 isc_result_t result;
17162 dns_zone_t *secure = NULL;
17163
17164 TIME_NOW(&loadtime);
17165
17166 /*
17167 * Lock hierarchy: zmgr, zone, raw.
17168 */
17169 again:
17170 LOCK_ZONE(zone);
17171 if (inline_secure(zone))
17172 LOCK_ZONE(zone->raw);
17173 else if (inline_raw(zone)) {
17174 secure = zone->secure;
17175 TRYLOCK_ZONE(result, secure);
17176 if (result != ISC_R_SUCCESS) {
17177 UNLOCK_ZONE(zone);
17178 secure = NULL;
17179 #if ISC_PLATFORM_USETHREADS
17180 isc_thread_yield();
17181 #endif
17182 goto again;
17183 }
17184 }
17185 result = zone_postload(zone, db, loadtime, ISC_R_SUCCESS);
17186 if (inline_secure(zone))
17187 UNLOCK_ZONE(zone->raw);
17188 else if (secure != NULL)
17189 UNLOCK_ZONE(secure);
17190 UNLOCK_ZONE(zone);
17191 return result;
17192 }
17193
17194 isc_result_t
dns_zone_setrefreshkeyinterval(dns_zone_t * zone,isc_uint32_t interval)17195 dns_zone_setrefreshkeyinterval(dns_zone_t *zone, isc_uint32_t interval) {
17196 REQUIRE(DNS_ZONE_VALID(zone));
17197 if (interval == 0)
17198 return (ISC_R_RANGE);
17199 /* Maximum value: 24 hours (3600 minutes) */
17200 if (interval > (24 * 60))
17201 interval = (24 * 60);
17202 /* Multiply by 60 for seconds */
17203 zone->refreshkeyinterval = interval * 60;
17204 return (ISC_R_SUCCESS);
17205 }
17206
17207 void
dns_zone_setrequestixfr(dns_zone_t * zone,isc_boolean_t flag)17208 dns_zone_setrequestixfr(dns_zone_t *zone, isc_boolean_t flag) {
17209 REQUIRE(DNS_ZONE_VALID(zone));
17210 zone->requestixfr = flag;
17211 }
17212
17213 isc_boolean_t
dns_zone_getrequestixfr(dns_zone_t * zone)17214 dns_zone_getrequestixfr(dns_zone_t *zone) {
17215 REQUIRE(DNS_ZONE_VALID(zone));
17216 return (zone->requestixfr);
17217 }
17218
17219 void
dns_zone_setserialupdatemethod(dns_zone_t * zone,dns_updatemethod_t method)17220 dns_zone_setserialupdatemethod(dns_zone_t *zone, dns_updatemethod_t method) {
17221 REQUIRE(DNS_ZONE_VALID(zone));
17222 zone->updatemethod = method;
17223 }
17224
17225 dns_updatemethod_t
dns_zone_getserialupdatemethod(dns_zone_t * zone)17226 dns_zone_getserialupdatemethod(dns_zone_t *zone) {
17227 REQUIRE(DNS_ZONE_VALID(zone));
17228 return(zone->updatemethod);
17229 }
17230
17231 /*
17232 * Lock hierarchy: zmgr, zone, raw.
17233 */
17234 isc_result_t
dns_zone_link(dns_zone_t * zone,dns_zone_t * raw)17235 dns_zone_link(dns_zone_t *zone, dns_zone_t *raw) {
17236 isc_result_t result;
17237 dns_zonemgr_t *zmgr;
17238
17239 REQUIRE(DNS_ZONE_VALID(zone));
17240 REQUIRE(zone->zmgr != NULL);
17241 REQUIRE(zone->task != NULL);
17242 REQUIRE(zone->loadtask != NULL);
17243 REQUIRE(zone->raw == NULL);
17244
17245 REQUIRE(DNS_ZONE_VALID(raw));
17246 REQUIRE(raw->zmgr == NULL);
17247 REQUIRE(raw->task == NULL);
17248 REQUIRE(raw->loadtask == NULL);
17249 REQUIRE(raw->secure == NULL);
17250
17251 /*
17252 * Lock hierarchy: zmgr, zone, raw.
17253 */
17254 zmgr = zone->zmgr;
17255 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
17256 LOCK_ZONE(zone);
17257 LOCK_ZONE(raw);
17258
17259 result = isc_timer_create(zmgr->timermgr, isc_timertype_inactive,
17260 NULL, NULL, zone->task, zone_timer, raw,
17261 &raw->timer);
17262 if (result != ISC_R_SUCCESS)
17263 goto unlock;
17264
17265 /*
17266 * The timer "holds" a iref.
17267 */
17268 raw->irefs++;
17269 INSIST(raw->irefs != 0);
17270
17271
17272 /* dns_zone_attach(raw, &zone->raw); */
17273 isc_refcount_increment(&raw->erefs, NULL);
17274 zone->raw = raw;
17275
17276 /* dns_zone_iattach(zone, &raw->secure); */
17277 zone_iattach(zone, &raw->secure);
17278
17279 isc_task_attach(zone->task, &raw->task);
17280 isc_task_attach(zone->loadtask, &raw->loadtask);
17281
17282 ISC_LIST_APPEND(zmgr->zones, raw, link);
17283 raw->zmgr = zmgr;
17284 zmgr->refs++;
17285
17286 unlock:
17287 UNLOCK_ZONE(raw);
17288 UNLOCK_ZONE(zone);
17289 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
17290 return (result);
17291 }
17292
17293 void
dns_zone_getraw(dns_zone_t * zone,dns_zone_t ** raw)17294 dns_zone_getraw(dns_zone_t *zone, dns_zone_t **raw) {
17295 REQUIRE(DNS_ZONE_VALID(zone));
17296 REQUIRE(raw != NULL && *raw == NULL);
17297
17298 LOCK(&zone->lock);
17299 if (zone->raw != NULL)
17300 dns_zone_attach(zone->raw, raw);
17301 UNLOCK(&zone->lock);
17302 }
17303
17304 struct keydone {
17305 isc_event_t event;
17306 isc_boolean_t all;
17307 unsigned char data[5];
17308 };
17309
17310 #define PENDINGFLAGS (DNS_NSEC3FLAG_CREATE|DNS_NSEC3FLAG_INITIAL)
17311
17312 static void
keydone(isc_task_t * task,isc_event_t * event)17313 keydone(isc_task_t *task, isc_event_t *event) {
17314 const char *me = "keydone";
17315 isc_boolean_t commit = ISC_FALSE;
17316 isc_result_t result;
17317 dns_rdata_t rdata = DNS_RDATA_INIT;
17318 dns_dbversion_t *oldver = NULL, *newver = NULL;
17319 dns_zone_t *zone;
17320 dns_db_t *db = NULL;
17321 dns_dbnode_t *node = NULL;
17322 dns_rdataset_t rdataset;
17323 dns_diff_t diff;
17324 struct keydone *kd = (struct keydone *)event;
17325 dns_update_log_t log = { update_log_cb, NULL };
17326 isc_boolean_t clear_pending = ISC_FALSE;
17327
17328 UNUSED(task);
17329
17330 zone = event->ev_arg;
17331 INSIST(DNS_ZONE_VALID(zone));
17332
17333 ENTER;
17334
17335 dns_rdataset_init(&rdataset);
17336 dns_diff_init(zone->mctx, &diff);
17337
17338 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
17339 if (zone->db != NULL) {
17340 dns_db_attach(zone->db, &db);
17341 dns_db_currentversion(db, &oldver);
17342 result = dns_db_newversion(db, &newver);
17343 if (result != ISC_R_SUCCESS) {
17344 dns_zone_log(zone, ISC_LOG_ERROR,
17345 "keydone:dns_db_newversion -> %s",
17346 dns_result_totext(result));
17347 goto failure;
17348 }
17349 }
17350 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
17351 if (db == NULL)
17352 goto failure;
17353
17354 result = dns_db_getoriginnode(db, &node);
17355 if (result != ISC_R_SUCCESS)
17356 goto failure;
17357
17358 result = dns_db_findrdataset(db, node, newver, zone->privatetype,
17359 dns_rdatatype_none, 0, &rdataset, NULL);
17360 if (result == ISC_R_NOTFOUND) {
17361 INSIST(!dns_rdataset_isassociated(&rdataset));
17362 goto failure;
17363 }
17364 if (result != ISC_R_SUCCESS) {
17365 INSIST(!dns_rdataset_isassociated(&rdataset));
17366 goto failure;
17367 }
17368
17369 for (result = dns_rdataset_first(&rdataset);
17370 result == ISC_R_SUCCESS;
17371 result = dns_rdataset_next(&rdataset)) {
17372 isc_boolean_t found = ISC_FALSE;
17373
17374 dns_rdataset_current(&rdataset, &rdata);
17375
17376 if (kd->all) {
17377 if (rdata.length == 5 && rdata.data[0] != 0 &&
17378 rdata.data[3] == 0 && rdata.data[4] == 1)
17379 found = ISC_TRUE;
17380 else if (rdata.data[0] == 0 &&
17381 (rdata.data[2] & PENDINGFLAGS) != 0) {
17382 found = ISC_TRUE;
17383 clear_pending = ISC_TRUE;
17384 }
17385 } else if (rdata.length == 5 &&
17386 memcmp(rdata.data, kd->data, 5) == 0)
17387 found = ISC_TRUE;
17388
17389 if (found)
17390 CHECK(update_one_rr(db, newver, &diff, DNS_DIFFOP_DEL,
17391 &zone->origin, rdataset.ttl,
17392 &rdata));
17393 dns_rdata_reset(&rdata);
17394 }
17395
17396 if (!ISC_LIST_EMPTY(diff.tuples)) {
17397 /* Write changes to journal file. */
17398 CHECK(update_soa_serial(db, newver, &diff, zone->mctx,
17399 zone->updatemethod));
17400
17401 result = dns_update_signatures(&log, zone, db,
17402 oldver, newver, &diff,
17403 zone->sigvalidityinterval);
17404 if (!clear_pending)
17405 CHECK(result);
17406
17407 CHECK(zone_journal(zone, &diff, NULL, "keydone"));
17408 commit = ISC_TRUE;
17409
17410 LOCK_ZONE(zone);
17411 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
17412 zone_needdump(zone, 30);
17413 UNLOCK_ZONE(zone);
17414 }
17415
17416 failure:
17417 if (dns_rdataset_isassociated(&rdataset))
17418 dns_rdataset_disassociate(&rdataset);
17419 if (db != NULL) {
17420 if (node != NULL)
17421 dns_db_detachnode(db, &node);
17422 if (oldver != NULL)
17423 dns_db_closeversion(db, &oldver, ISC_FALSE);
17424 if (newver != NULL)
17425 dns_db_closeversion(db, &newver, commit);
17426 dns_db_detach(&db);
17427 }
17428 dns_diff_clear(&diff);
17429 isc_event_free(&event);
17430 dns_zone_idetach(&zone);
17431
17432 INSIST(oldver == NULL);
17433 INSIST(newver == NULL);
17434 }
17435
17436 isc_result_t
dns_zone_keydone(dns_zone_t * zone,const char * keystr)17437 dns_zone_keydone(dns_zone_t *zone, const char *keystr) {
17438 isc_result_t result = ISC_R_SUCCESS;
17439 isc_event_t *e;
17440 isc_buffer_t b;
17441 dns_zone_t *dummy = NULL;
17442 struct keydone *kd;
17443
17444 REQUIRE(DNS_ZONE_VALID(zone));
17445
17446 LOCK_ZONE(zone);
17447
17448 e = isc_event_allocate(zone->mctx, zone, DNS_EVENT_KEYDONE, keydone,
17449 zone, sizeof(struct keydone));
17450 if (e == NULL) {
17451 result = ISC_R_NOMEMORY;
17452 goto failure;
17453 }
17454
17455 kd = (struct keydone *) e;
17456 if (strcasecmp(keystr, "all") == 0)
17457 kd->all = ISC_TRUE;
17458 else {
17459 isc_textregion_t r;
17460 const char *algstr;
17461 dns_keytag_t keyid;
17462 dns_secalg_t alg;
17463 size_t n;
17464
17465 kd->all = ISC_FALSE;
17466
17467 n = sscanf(keystr, "%hd/", &keyid);
17468 if (n == 0U)
17469 CHECK(ISC_R_FAILURE);
17470
17471 algstr = strchr(keystr, '/');
17472 if (algstr != NULL)
17473 algstr++;
17474 else
17475 CHECK(ISC_R_FAILURE);
17476
17477 n = sscanf(algstr, "%hhd", &alg);
17478 if (n == 0U) {
17479 DE_CONST(algstr, r.base);
17480 r.length = strlen(algstr);
17481 CHECK(dns_secalg_fromtext(&alg, &r));
17482 }
17483
17484 /* construct a private-type rdata */
17485 isc_buffer_init(&b, kd->data, sizeof(kd->data));
17486 isc_buffer_putuint8(&b, alg);
17487 isc_buffer_putuint8(&b, (keyid & 0xff00) >> 8);
17488 isc_buffer_putuint8(&b, (keyid & 0xff));
17489 isc_buffer_putuint8(&b, 0);
17490 isc_buffer_putuint8(&b, 1);
17491 }
17492
17493 zone_iattach(zone, &dummy);
17494 isc_task_send(zone->task, &e);
17495
17496 failure:
17497 if (e != NULL)
17498 isc_event_free(&e);
17499 UNLOCK_ZONE(zone);
17500 return (result);
17501 }
17502
17503 static void
setnsec3param(isc_task_t * task,isc_event_t * event)17504 setnsec3param(isc_task_t *task, isc_event_t *event) {
17505 const char *me = "setnsec3param";
17506 isc_boolean_t commit = ISC_FALSE;
17507 isc_result_t result;
17508 dns_dbversion_t *oldver = NULL, *newver = NULL;
17509 dns_zone_t *zone;
17510 dns_db_t *db = NULL;
17511 dns_dbnode_t *node = NULL;
17512 dns_rdataset_t prdataset, nrdataset;
17513 dns_diff_t diff;
17514 struct np3event *npe = (struct np3event *)event;
17515 nsec3param_t *np;
17516 dns_update_log_t log = { update_log_cb, NULL };
17517 dns_rdata_t rdata;
17518 isc_boolean_t nseconly;
17519 isc_boolean_t exists = ISC_FALSE;
17520
17521 UNUSED(task);
17522
17523 zone = event->ev_arg;
17524 INSIST(DNS_ZONE_VALID(zone));
17525
17526 ENTER;
17527
17528 np = &npe->params;
17529
17530 dns_rdataset_init(&prdataset);
17531 dns_rdataset_init(&nrdataset);
17532 dns_diff_init(zone->mctx, &diff);
17533
17534 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
17535 if (zone->db != NULL) {
17536 dns_db_attach(zone->db, &db);
17537 dns_db_currentversion(db, &oldver);
17538 result = dns_db_newversion(db, &newver);
17539 if (result != ISC_R_SUCCESS) {
17540 dns_zone_log(zone, ISC_LOG_ERROR,
17541 "setnsec3param:dns_db_newversion -> %s",
17542 dns_result_totext(result));
17543 goto failure;
17544 }
17545 }
17546 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
17547 if (db == NULL)
17548 goto failure;
17549
17550 CHECK(dns_db_getoriginnode(db, &node));
17551
17552 /*
17553 * Does a private-type record already exist for this chain?
17554 */
17555 result = dns_db_findrdataset(db, node, newver, zone->privatetype,
17556 dns_rdatatype_none, 0, &prdataset, NULL);
17557 if (result == ISC_R_SUCCESS) {
17558 for (result = dns_rdataset_first(&prdataset);
17559 result == ISC_R_SUCCESS;
17560 result = dns_rdataset_next(&prdataset)) {
17561 dns_rdata_init(&rdata);
17562 dns_rdataset_current(&prdataset, &rdata);
17563
17564 if (np->length == rdata.length &&
17565 memcmp(rdata.data, np->data, np->length) == 0) {
17566 exists = ISC_TRUE;
17567 break;
17568 }
17569 }
17570 } else if (result != ISC_R_NOTFOUND) {
17571 INSIST(!dns_rdataset_isassociated(&prdataset));
17572 goto failure;
17573 }
17574
17575 /*
17576 * Does the chain already exist?
17577 */
17578 result = dns_db_findrdataset(db, node, newver,
17579 dns_rdatatype_nsec3param,
17580 dns_rdatatype_none, 0, &nrdataset, NULL);
17581 if (result == ISC_R_SUCCESS) {
17582 for (result = dns_rdataset_first(&nrdataset);
17583 result == ISC_R_SUCCESS;
17584 result = dns_rdataset_next(&nrdataset)) {
17585 dns_rdata_init(&rdata);
17586 dns_rdataset_current(&nrdataset, &rdata);
17587
17588 if (np->length == (rdata.length + 1) &&
17589 memcmp(rdata.data, np->data + 1,
17590 np->length - 1) == 0)
17591 {
17592 exists = ISC_TRUE;
17593 break;
17594 }
17595 }
17596 } else if (result != ISC_R_NOTFOUND) {
17597 INSIST(!dns_rdataset_isassociated(&nrdataset));
17598 goto failure;
17599 }
17600
17601
17602 /*
17603 * We need to remove any existing NSEC3 chains.
17604 */
17605 if (!exists && np->replace && (np->length != 0 || np->nsec))
17606 CHECK(dns_nsec3param_deletechains(db, newver, zone,
17607 !np->nsec, &diff));
17608
17609 if (!exists && np->length != 0) {
17610 /*
17611 * We're creating an NSEC3 chain.
17612 *
17613 * If the zone is not currently capable of supporting
17614 * an NSEC3 chain, add the INITIAL flag, so these
17615 * parameters can be used later when NSEC3 becomes
17616 * available.
17617 */
17618 dns_rdata_init(&rdata);
17619
17620 np->data[2] |= DNS_NSEC3FLAG_CREATE;
17621 result = dns_nsec_nseconly(db, newver, &nseconly);
17622 if (result == ISC_R_NOTFOUND || nseconly)
17623 np->data[2] |= DNS_NSEC3FLAG_INITIAL;
17624
17625 rdata.length = np->length;
17626 rdata.data = np->data;
17627 rdata.type = zone->privatetype;
17628 rdata.rdclass = zone->rdclass;
17629 CHECK(update_one_rr(db, newver, &diff, DNS_DIFFOP_ADD,
17630 &zone->origin, 0, &rdata));
17631 }
17632
17633 if (!ISC_LIST_EMPTY(diff.tuples)) {
17634 /* Write changes to journal file. */
17635 CHECK(update_soa_serial(db, newver, &diff, zone->mctx,
17636 zone->updatemethod));
17637 result = dns_update_signatures(&log, zone, db,
17638 oldver, newver, &diff,
17639 zone->sigvalidityinterval);
17640 if (result != ISC_R_NOTFOUND)
17641 CHECK(result);
17642 CHECK(zone_journal(zone, &diff, NULL, "setnsec3param"));
17643 commit = ISC_TRUE;
17644
17645 LOCK_ZONE(zone);
17646 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
17647 zone_needdump(zone, 30);
17648 UNLOCK_ZONE(zone);
17649 }
17650
17651 failure:
17652 if (dns_rdataset_isassociated(&prdataset))
17653 dns_rdataset_disassociate(&prdataset);
17654 if (dns_rdataset_isassociated(&nrdataset))
17655 dns_rdataset_disassociate(&nrdataset);
17656 if (node != NULL)
17657 dns_db_detachnode(db, &node);
17658 if (oldver != NULL)
17659 dns_db_closeversion(db, &oldver, ISC_FALSE);
17660 if (newver != NULL)
17661 dns_db_closeversion(db, &newver, commit);
17662 if (db != NULL)
17663 dns_db_detach(&db);
17664 if (commit)
17665 resume_addnsec3chain(zone);
17666 dns_diff_clear(&diff);
17667 isc_event_free(&event);
17668 dns_zone_idetach(&zone);
17669
17670 INSIST(oldver == NULL);
17671 INSIST(newver == NULL);
17672 }
17673
17674 isc_result_t
dns_zone_setnsec3param(dns_zone_t * zone,isc_uint8_t hash,isc_uint8_t flags,isc_uint16_t iter,isc_uint8_t saltlen,unsigned char * salt,isc_boolean_t replace)17675 dns_zone_setnsec3param(dns_zone_t *zone, isc_uint8_t hash, isc_uint8_t flags,
17676 isc_uint16_t iter, isc_uint8_t saltlen,
17677 unsigned char *salt, isc_boolean_t replace)
17678 {
17679 isc_result_t result = ISC_R_SUCCESS;
17680 dns_rdata_nsec3param_t param;
17681 dns_rdata_t nrdata = DNS_RDATA_INIT;
17682 dns_rdata_t prdata = DNS_RDATA_INIT;
17683 unsigned char nbuf[DNS_NSEC3PARAM_BUFFERSIZE];
17684 struct np3event *npe;
17685 nsec3param_t *np;
17686 dns_zone_t *dummy = NULL;
17687 isc_buffer_t b;
17688 isc_event_t *e;
17689
17690 REQUIRE(DNS_ZONE_VALID(zone));
17691 REQUIRE(salt != NULL);
17692
17693 LOCK_ZONE(zone);
17694
17695 e = isc_event_allocate(zone->mctx, zone, DNS_EVENT_SETNSEC3PARAM,
17696 setnsec3param, zone, sizeof(struct np3event));
17697 if (e == NULL) {
17698 result = ISC_R_NOMEMORY;
17699 goto failure;
17700 }
17701
17702 npe = (struct np3event *) e;
17703 np = &npe->params;
17704
17705 np->replace = replace;
17706 if (hash == 0) {
17707 np->length = 0;
17708 np->nsec = ISC_TRUE;
17709 } else {
17710 param.common.rdclass = zone->rdclass;
17711 param.common.rdtype = dns_rdatatype_nsec3param;
17712 ISC_LINK_INIT(¶m.common, link);
17713 param.mctx = NULL;
17714 param.hash = hash;
17715 param.flags = flags;
17716 param.iterations = iter;
17717 param.salt_length = saltlen;
17718 param.salt = salt;
17719 isc_buffer_init(&b, nbuf, sizeof(nbuf));
17720 CHECK(dns_rdata_fromstruct(&nrdata, zone->rdclass,
17721 dns_rdatatype_nsec3param,
17722 ¶m, &b));
17723 dns_nsec3param_toprivate(&nrdata, &prdata, zone->privatetype,
17724 np->data, sizeof(np->data));
17725 np->length = prdata.length;
17726 }
17727
17728 zone_iattach(zone, &dummy);
17729 isc_task_send(zone->task, &e);
17730
17731 failure:
17732 if (e != NULL)
17733 isc_event_free(&e);
17734 UNLOCK_ZONE(zone);
17735 return (result);
17736 }
17737
17738 void
dns_zone_setstatlevel(dns_zone_t * zone,dns_zonestat_level_t level)17739 dns_zone_setstatlevel(dns_zone_t *zone, dns_zonestat_level_t level) {
17740 REQUIRE(DNS_ZONE_VALID(zone));
17741
17742 zone->statlevel = level;
17743 }
17744
17745 dns_zonestat_level_t
dns_zone_getstatlevel(dns_zone_t * zone)17746 dns_zone_getstatlevel(dns_zone_t *zone) {
17747 REQUIRE(DNS_ZONE_VALID(zone));
17748
17749 return (zone->statlevel);
17750 }
17751