PageRenderTime 123ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 2ms

/contrib/bind9/lib/dns/zone.c

https://bitbucket.org/freebsd/freebsd-head/
C | 14592 lines | 11254 code | 1786 blank | 1552 comment | 3275 complexity | d13f256320707749935465f4f1a2a4ac MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, BSD-3-Clause, LGPL-2.0, LGPL-2.1, BSD-2-Clause, 0BSD, JSON, AGPL-1.0, GPL-2.0
  1. /*
  2. * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC")
  3. * Copyright (C) 1999-2003 Internet Software Consortium.
  4. *
  5. * Permission to use, copy, modify, and/or distribute this software for any
  6. * purpose with or without fee is hereby granted, provided that the above
  7. * copyright notice and this permission notice appear in all copies.
  8. *
  9. * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  10. * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  11. * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  12. * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  13. * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  14. * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  15. * PERFORMANCE OF THIS SOFTWARE.
  16. */
  17. /* $Id$ */
  18. /*! \file */
  19. #include <config.h>
  20. #include <errno.h>
  21. #include <isc/file.h>
  22. #include <isc/mutex.h>
  23. #include <isc/print.h>
  24. #include <isc/random.h>
  25. #include <isc/ratelimiter.h>
  26. #include <isc/refcount.h>
  27. #include <isc/rwlock.h>
  28. #include <isc/serial.h>
  29. #include <isc/strerror.h>
  30. #include <isc/stats.h>
  31. #include <isc/stdtime.h>
  32. #include <isc/string.h>
  33. #include <isc/taskpool.h>
  34. #include <isc/timer.h>
  35. #include <isc/util.h>
  36. #include <dns/acache.h>
  37. #include <dns/acl.h>
  38. #include <dns/adb.h>
  39. #include <dns/callbacks.h>
  40. #include <dns/db.h>
  41. #include <dns/dbiterator.h>
  42. #include <dns/dnssec.h>
  43. #include <dns/events.h>
  44. #include <dns/journal.h>
  45. #include <dns/keydata.h>
  46. #include <dns/keytable.h>
  47. #include <dns/keyvalues.h>
  48. #include <dns/log.h>
  49. #include <dns/master.h>
  50. #include <dns/masterdump.h>
  51. #include <dns/message.h>
  52. #include <dns/name.h>
  53. #include <dns/nsec.h>
  54. #include <dns/nsec3.h>
  55. #include <dns/peer.h>
  56. #include <dns/private.h>
  57. #include <dns/rbt.h>
  58. #include <dns/rcode.h>
  59. #include <dns/rdataclass.h>
  60. #include <dns/rdatalist.h>
  61. #include <dns/rdataset.h>
  62. #include <dns/rdatasetiter.h>
  63. #include <dns/rdatastruct.h>
  64. #include <dns/rdatatype.h>
  65. #include <dns/request.h>
  66. #include <dns/resolver.h>
  67. #include <dns/result.h>
  68. #include <dns/rriterator.h>
  69. #include <dns/soa.h>
  70. #include <dns/ssu.h>
  71. #include <dns/stats.h>
  72. #include <dns/time.h>
  73. #include <dns/tsig.h>
  74. #include <dns/xfrin.h>
  75. #include <dns/zone.h>
  76. #include <dst/dst.h>
  77. #define ZONE_MAGIC ISC_MAGIC('Z', 'O', 'N', 'E')
  78. #define DNS_ZONE_VALID(zone) ISC_MAGIC_VALID(zone, ZONE_MAGIC)
  79. #define NOTIFY_MAGIC ISC_MAGIC('N', 't', 'f', 'y')
  80. #define DNS_NOTIFY_VALID(notify) ISC_MAGIC_VALID(notify, NOTIFY_MAGIC)
  81. #define STUB_MAGIC ISC_MAGIC('S', 't', 'u', 'b')
  82. #define DNS_STUB_VALID(stub) ISC_MAGIC_VALID(stub, STUB_MAGIC)
  83. #define ZONEMGR_MAGIC ISC_MAGIC('Z', 'm', 'g', 'r')
  84. #define DNS_ZONEMGR_VALID(stub) ISC_MAGIC_VALID(stub, ZONEMGR_MAGIC)
  85. #define LOAD_MAGIC ISC_MAGIC('L', 'o', 'a', 'd')
  86. #define DNS_LOAD_VALID(load) ISC_MAGIC_VALID(load, LOAD_MAGIC)
  87. #define FORWARD_MAGIC ISC_MAGIC('F', 'o', 'r', 'w')
  88. #define DNS_FORWARD_VALID(load) ISC_MAGIC_VALID(load, FORWARD_MAGIC)
  89. #define IO_MAGIC ISC_MAGIC('Z', 'm', 'I', 'O')
  90. #define DNS_IO_VALID(load) ISC_MAGIC_VALID(load, IO_MAGIC)
  91. /*%
  92. * Ensure 'a' is at least 'min' but not more than 'max'.
  93. */
  94. #define RANGE(a, min, max) \
  95. (((a) < (min)) ? (min) : ((a) < (max) ? (a) : (max)))
  96. #define NSEC3REMOVE(x) (((x) & DNS_NSEC3FLAG_REMOVE) != 0)
  97. /*%
  98. * Key flags
  99. */
  100. #define REVOKE(x) ((dst_key_flags(x) & DNS_KEYFLAG_REVOKE) != 0)
  101. #define KSK(x) ((dst_key_flags(x) & DNS_KEYFLAG_KSK) != 0)
  102. #define ALG(x) dst_key_alg(x)
  103. /*
  104. * Default values.
  105. */
  106. #define DNS_DEFAULT_IDLEIN 3600 /*%< 1 hour */
  107. #define DNS_DEFAULT_IDLEOUT 3600 /*%< 1 hour */
  108. #define MAX_XFER_TIME (2*3600) /*%< Documented default is 2 hours */
  109. #define RESIGN_DELAY 3600 /*%< 1 hour */
  110. #ifndef DNS_MAX_EXPIRE
  111. #define DNS_MAX_EXPIRE 14515200 /*%< 24 weeks */
  112. #endif
  113. #ifndef DNS_DUMP_DELAY
  114. #define DNS_DUMP_DELAY 900 /*%< 15 minutes */
  115. #endif
  116. typedef struct dns_notify dns_notify_t;
  117. typedef struct dns_stub dns_stub_t;
  118. typedef struct dns_load dns_load_t;
  119. typedef struct dns_forward dns_forward_t;
  120. typedef ISC_LIST(dns_forward_t) dns_forwardlist_t;
  121. typedef struct dns_io dns_io_t;
  122. typedef ISC_LIST(dns_io_t) dns_iolist_t;
  123. typedef struct dns_signing dns_signing_t;
  124. typedef ISC_LIST(dns_signing_t) dns_signinglist_t;
  125. typedef struct dns_nsec3chain dns_nsec3chain_t;
  126. typedef ISC_LIST(dns_nsec3chain_t) dns_nsec3chainlist_t;
  127. typedef struct dns_keyfetch dns_keyfetch_t;
  128. #define DNS_ZONE_CHECKLOCK
  129. #ifdef DNS_ZONE_CHECKLOCK
  130. #define LOCK_ZONE(z) \
  131. do { LOCK(&(z)->lock); \
  132. INSIST((z)->locked == ISC_FALSE); \
  133. (z)->locked = ISC_TRUE; \
  134. } while (0)
  135. #define UNLOCK_ZONE(z) \
  136. do { (z)->locked = ISC_FALSE; UNLOCK(&(z)->lock); } while (0)
  137. #define LOCKED_ZONE(z) ((z)->locked)
  138. #else
  139. #define LOCK_ZONE(z) LOCK(&(z)->lock)
  140. #define UNLOCK_ZONE(z) UNLOCK(&(z)->lock)
  141. #define LOCKED_ZONE(z) ISC_TRUE
  142. #endif
  143. #ifdef ISC_RWLOCK_USEATOMIC
  144. #define ZONEDB_INITLOCK(l) isc_rwlock_init((l), 0, 0)
  145. #define ZONEDB_DESTROYLOCK(l) isc_rwlock_destroy(l)
  146. #define ZONEDB_LOCK(l, t) RWLOCK((l), (t))
  147. #define ZONEDB_UNLOCK(l, t) RWUNLOCK((l), (t))
  148. #else
  149. #define ZONEDB_INITLOCK(l) isc_mutex_init(l)
  150. #define ZONEDB_DESTROYLOCK(l) DESTROYLOCK(l)
  151. #define ZONEDB_LOCK(l, t) LOCK(l)
  152. #define ZONEDB_UNLOCK(l, t) UNLOCK(l)
  153. #endif
  154. struct dns_zone {
  155. /* Unlocked */
  156. unsigned int magic;
  157. isc_mutex_t lock;
  158. #ifdef DNS_ZONE_CHECKLOCK
  159. isc_boolean_t locked;
  160. #endif
  161. isc_mem_t *mctx;
  162. isc_refcount_t erefs;
  163. #ifdef ISC_RWLOCK_USEATOMIC
  164. isc_rwlock_t dblock;
  165. #else
  166. isc_mutex_t dblock;
  167. #endif
  168. dns_db_t *db; /* Locked by dblock */
  169. /* Locked */
  170. dns_zonemgr_t *zmgr;
  171. ISC_LINK(dns_zone_t) link; /* Used by zmgr. */
  172. isc_timer_t *timer;
  173. unsigned int irefs;
  174. dns_name_t origin;
  175. char *masterfile;
  176. dns_masterformat_t masterformat;
  177. char *journal;
  178. isc_int32_t journalsize;
  179. dns_rdataclass_t rdclass;
  180. dns_zonetype_t type;
  181. unsigned int flags;
  182. unsigned int options;
  183. unsigned int db_argc;
  184. char **db_argv;
  185. isc_time_t expiretime;
  186. isc_time_t refreshtime;
  187. isc_time_t dumptime;
  188. isc_time_t loadtime;
  189. isc_time_t notifytime;
  190. isc_time_t resigntime;
  191. isc_time_t keywarntime;
  192. isc_time_t signingtime;
  193. isc_time_t nsec3chaintime;
  194. isc_time_t refreshkeytime;
  195. isc_uint32_t refreshkeycount;
  196. isc_uint32_t refresh;
  197. isc_uint32_t retry;
  198. isc_uint32_t expire;
  199. isc_uint32_t minimum;
  200. isc_stdtime_t key_expiry;
  201. isc_stdtime_t log_key_expired_timer;
  202. char *keydirectory;
  203. isc_uint32_t maxrefresh;
  204. isc_uint32_t minrefresh;
  205. isc_uint32_t maxretry;
  206. isc_uint32_t minretry;
  207. isc_sockaddr_t *masters;
  208. dns_name_t **masterkeynames;
  209. isc_boolean_t *mastersok;
  210. unsigned int masterscnt;
  211. unsigned int curmaster;
  212. isc_sockaddr_t masteraddr;
  213. dns_notifytype_t notifytype;
  214. isc_sockaddr_t *notify;
  215. unsigned int notifycnt;
  216. isc_sockaddr_t notifyfrom;
  217. isc_task_t *task;
  218. isc_sockaddr_t notifysrc4;
  219. isc_sockaddr_t notifysrc6;
  220. isc_sockaddr_t xfrsource4;
  221. isc_sockaddr_t xfrsource6;
  222. isc_sockaddr_t altxfrsource4;
  223. isc_sockaddr_t altxfrsource6;
  224. isc_sockaddr_t sourceaddr;
  225. dns_xfrin_ctx_t *xfr; /* task locked */
  226. dns_tsigkey_t *tsigkey; /* key used for xfr */
  227. /* Access Control Lists */
  228. dns_acl_t *update_acl;
  229. dns_acl_t *forward_acl;
  230. dns_acl_t *notify_acl;
  231. dns_acl_t *query_acl;
  232. dns_acl_t *queryon_acl;
  233. dns_acl_t *xfr_acl;
  234. isc_boolean_t update_disabled;
  235. isc_boolean_t zero_no_soa_ttl;
  236. dns_severity_t check_names;
  237. ISC_LIST(dns_notify_t) notifies;
  238. dns_request_t *request;
  239. dns_loadctx_t *lctx;
  240. dns_io_t *readio;
  241. dns_dumpctx_t *dctx;
  242. dns_io_t *writeio;
  243. isc_uint32_t maxxfrin;
  244. isc_uint32_t maxxfrout;
  245. isc_uint32_t idlein;
  246. isc_uint32_t idleout;
  247. isc_event_t ctlevent;
  248. dns_ssutable_t *ssutable;
  249. isc_uint32_t sigvalidityinterval;
  250. isc_uint32_t sigresigninginterval;
  251. dns_view_t *view;
  252. dns_acache_t *acache;
  253. dns_checkmxfunc_t checkmx;
  254. dns_checksrvfunc_t checksrv;
  255. dns_checknsfunc_t checkns;
  256. /*%
  257. * Zones in certain states such as "waiting for zone transfer"
  258. * or "zone transfer in progress" are kept on per-state linked lists
  259. * in the zone manager using the 'statelink' field. The 'statelist'
  260. * field points at the list the zone is currently on. It the zone
  261. * is not on any such list, statelist is NULL.
  262. */
  263. ISC_LINK(dns_zone_t) statelink;
  264. dns_zonelist_t *statelist;
  265. /*%
  266. * Statistics counters about zone management.
  267. */
  268. isc_stats_t *stats;
  269. /*%
  270. * Optional per-zone statistics counters. Counted outside of this
  271. * module.
  272. */
  273. isc_boolean_t requeststats_on;
  274. isc_stats_t *requeststats;
  275. isc_uint32_t notifydelay;
  276. dns_isselffunc_t isself;
  277. void *isselfarg;
  278. char * strnamerd;
  279. char * strname;
  280. char * strrdclass;
  281. char * strviewname;
  282. /*%
  283. * Serial number for deferred journal compaction.
  284. */
  285. isc_uint32_t compact_serial;
  286. /*%
  287. * Keys that are signing the zone for the first time.
  288. */
  289. dns_signinglist_t signing;
  290. dns_nsec3chainlist_t nsec3chain;
  291. /*%
  292. * Signing / re-signing quantum stopping parameters.
  293. */
  294. isc_uint32_t signatures;
  295. isc_uint32_t nodes;
  296. dns_rdatatype_t privatetype;
  297. /*%
  298. * Autosigning/key-maintenance options
  299. */
  300. isc_uint32_t keyopts;
  301. /*%
  302. * True if added by "rndc addzone"
  303. */
  304. isc_boolean_t added;
  305. /*%
  306. * whether a rpz radix was needed when last loaded
  307. */
  308. isc_boolean_t rpz_zone;
  309. /*%
  310. * Outstanding forwarded UPDATE requests.
  311. */
  312. dns_forwardlist_t forwards;
  313. };
  314. #define DNS_ZONE_FLAG(z,f) (ISC_TF(((z)->flags & (f)) != 0))
  315. #define DNS_ZONE_SETFLAG(z,f) do { \
  316. INSIST(LOCKED_ZONE(z)); \
  317. (z)->flags |= (f); \
  318. } while (0)
  319. #define DNS_ZONE_CLRFLAG(z,f) do { \
  320. INSIST(LOCKED_ZONE(z)); \
  321. (z)->flags &= ~(f); \
  322. } while (0)
  323. /* XXX MPA these may need to go back into zone.h */
  324. #define DNS_ZONEFLG_REFRESH 0x00000001U /*%< refresh check in progress */
  325. #define DNS_ZONEFLG_NEEDDUMP 0x00000002U /*%< zone need consolidation */
  326. #define DNS_ZONEFLG_USEVC 0x00000004U /*%< use tcp for refresh query */
  327. #define DNS_ZONEFLG_DUMPING 0x00000008U /*%< a dump is in progress */
  328. #define DNS_ZONEFLG_HASINCLUDE 0x00000010U /*%< $INCLUDE in zone file */
  329. #define DNS_ZONEFLG_LOADED 0x00000020U /*%< database has loaded */
  330. #define DNS_ZONEFLG_EXITING 0x00000040U /*%< zone is being destroyed */
  331. #define DNS_ZONEFLG_EXPIRED 0x00000080U /*%< zone has expired */
  332. #define DNS_ZONEFLG_NEEDREFRESH 0x00000100U /*%< refresh check needed */
  333. #define DNS_ZONEFLG_UPTODATE 0x00000200U /*%< zone contents are
  334. * uptodate */
  335. #define DNS_ZONEFLG_NEEDNOTIFY 0x00000400U /*%< need to send out notify
  336. * messages */
  337. #define DNS_ZONEFLG_DIFFONRELOAD 0x00000800U /*%< generate a journal diff on
  338. * reload */
  339. #define DNS_ZONEFLG_NOMASTERS 0x00001000U /*%< an attempt to refresh a
  340. * zone with no masters
  341. * occurred */
  342. #define DNS_ZONEFLG_LOADING 0x00002000U /*%< load from disk in progress*/
  343. #define DNS_ZONEFLG_HAVETIMERS 0x00004000U /*%< timer values have been set
  344. * from SOA (if not set, we
  345. * are still using
  346. * default timer values) */
  347. #define DNS_ZONEFLG_FORCEXFER 0x00008000U /*%< Force a zone xfer */
  348. #define DNS_ZONEFLG_NOREFRESH 0x00010000U
  349. #define DNS_ZONEFLG_DIALNOTIFY 0x00020000U
  350. #define DNS_ZONEFLG_DIALREFRESH 0x00040000U
  351. #define DNS_ZONEFLG_SHUTDOWN 0x00080000U
  352. #define DNS_ZONEFLAG_NOIXFR 0x00100000U /*%< IXFR failed, force AXFR */
  353. #define DNS_ZONEFLG_FLUSH 0x00200000U
  354. #define DNS_ZONEFLG_NOEDNS 0x00400000U
  355. #define DNS_ZONEFLG_USEALTXFRSRC 0x00800000U
  356. #define DNS_ZONEFLG_SOABEFOREAXFR 0x01000000U
  357. #define DNS_ZONEFLG_NEEDCOMPACT 0x02000000U
  358. #define DNS_ZONEFLG_REFRESHING 0x04000000U /*%< Refreshing keydata */
  359. #define DNS_ZONEFLG_THAW 0x08000000U
  360. /* #define DNS_ZONEFLG_XXXXX 0x10000000U XXXMPA unused. */
  361. #define DNS_ZONEFLG_NODELAY 0x20000000U
  362. #define DNS_ZONE_OPTION(z,o) (((z)->options & (o)) != 0)
  363. #define DNS_ZONEKEY_OPTION(z,o) (((z)->keyopts & (o)) != 0)
  364. /* Flags for zone_load() */
  365. #define DNS_ZONELOADFLAG_NOSTAT 0x00000001U /* Do not stat() master files */
  366. #define DNS_ZONELOADFLAG_THAW 0x00000002U /* Thaw the zone on successful
  367. load. */
  368. #define UNREACH_CHACHE_SIZE 10U
  369. #define UNREACH_HOLD_TIME 600 /* 10 minutes */
  370. #define CHECK(op) \
  371. do { result = (op); \
  372. if (result != ISC_R_SUCCESS) goto failure; \
  373. } while (0)
  374. struct dns_unreachable {
  375. isc_sockaddr_t remote;
  376. isc_sockaddr_t local;
  377. isc_uint32_t expire;
  378. isc_uint32_t last;
  379. };
  380. struct dns_zonemgr {
  381. unsigned int magic;
  382. isc_mem_t * mctx;
  383. int refs; /* Locked by rwlock */
  384. isc_taskmgr_t * taskmgr;
  385. isc_timermgr_t * timermgr;
  386. isc_socketmgr_t * socketmgr;
  387. isc_taskpool_t * zonetasks;
  388. isc_task_t * task;
  389. isc_ratelimiter_t * rl;
  390. isc_rwlock_t rwlock;
  391. isc_mutex_t iolock;
  392. isc_rwlock_t urlock;
  393. /* Locked by rwlock. */
  394. dns_zonelist_t zones;
  395. dns_zonelist_t waiting_for_xfrin;
  396. dns_zonelist_t xfrin_in_progress;
  397. /* Configuration data. */
  398. isc_uint32_t transfersin;
  399. isc_uint32_t transfersperns;
  400. unsigned int serialqueryrate;
  401. /* Locked by iolock */
  402. isc_uint32_t iolimit;
  403. isc_uint32_t ioactive;
  404. dns_iolist_t high;
  405. dns_iolist_t low;
  406. /* Locked by urlock. */
  407. /* LRU cache */
  408. struct dns_unreachable unreachable[UNREACH_CHACHE_SIZE];
  409. };
  410. /*%
  411. * Hold notify state.
  412. */
  413. struct dns_notify {
  414. unsigned int magic;
  415. unsigned int flags;
  416. isc_mem_t *mctx;
  417. dns_zone_t *zone;
  418. dns_adbfind_t *find;
  419. dns_request_t *request;
  420. dns_name_t ns;
  421. isc_sockaddr_t dst;
  422. ISC_LINK(dns_notify_t) link;
  423. };
  424. #define DNS_NOTIFY_NOSOA 0x0001U
  425. /*%
  426. * dns_stub holds state while performing a 'stub' transfer.
  427. * 'db' is the zone's 'db' or a new one if this is the initial
  428. * transfer.
  429. */
  430. struct dns_stub {
  431. unsigned int magic;
  432. isc_mem_t *mctx;
  433. dns_zone_t *zone;
  434. dns_db_t *db;
  435. dns_dbversion_t *version;
  436. };
  437. /*%
  438. * Hold load state.
  439. */
  440. struct dns_load {
  441. unsigned int magic;
  442. isc_mem_t *mctx;
  443. dns_zone_t *zone;
  444. dns_db_t *db;
  445. isc_time_t loadtime;
  446. dns_rdatacallbacks_t callbacks;
  447. };
  448. /*%
  449. * Hold forward state.
  450. */
  451. struct dns_forward {
  452. unsigned int magic;
  453. isc_mem_t *mctx;
  454. dns_zone_t *zone;
  455. isc_buffer_t *msgbuf;
  456. dns_request_t *request;
  457. isc_uint32_t which;
  458. isc_sockaddr_t addr;
  459. dns_updatecallback_t callback;
  460. void *callback_arg;
  461. ISC_LINK(dns_forward_t) link;
  462. };
  463. /*%
  464. * Hold IO request state.
  465. */
  466. struct dns_io {
  467. unsigned int magic;
  468. dns_zonemgr_t *zmgr;
  469. isc_boolean_t high;
  470. isc_task_t *task;
  471. ISC_LINK(dns_io_t) link;
  472. isc_event_t *event;
  473. };
  474. /*%
  475. * Hold state for when we are signing a zone with a new
  476. * DNSKEY as result of an update.
  477. */
  478. struct dns_signing {
  479. unsigned int magic;
  480. dns_db_t *db;
  481. dns_dbiterator_t *dbiterator;
  482. dns_secalg_t algorithm;
  483. isc_uint16_t keyid;
  484. isc_boolean_t delete;
  485. isc_boolean_t done;
  486. ISC_LINK(dns_signing_t) link;
  487. };
  488. struct dns_nsec3chain {
  489. unsigned int magic;
  490. dns_db_t *db;
  491. dns_dbiterator_t *dbiterator;
  492. dns_rdata_nsec3param_t nsec3param;
  493. unsigned char salt[255];
  494. isc_boolean_t done;
  495. isc_boolean_t seen_nsec;
  496. isc_boolean_t delete_nsec;
  497. isc_boolean_t save_delete_nsec;
  498. ISC_LINK(dns_nsec3chain_t) link;
  499. };
  500. /*%<
  501. * 'dbiterator' contains a iterator for the database. If we are creating
  502. * a NSEC3 chain only the non-NSEC3 nodes will be iterated. If we are
  503. * removing a NSEC3 chain then both NSEC3 and non-NSEC3 nodes will be
  504. * iterated.
  505. *
  506. * 'nsec3param' contains the parameters of the NSEC3 chain being created
  507. * or removed.
  508. *
  509. * 'salt' is buffer space and is referenced via 'nsec3param.salt'.
  510. *
  511. * 'seen_nsec' will be set to true if, while iterating the zone to create a
  512. * NSEC3 chain, a NSEC record is seen.
  513. *
  514. * 'delete_nsec' will be set to true if, at the completion of the creation
  515. * of a NSEC3 chain, 'seen_nsec' is true. If 'delete_nsec' is true then we
  516. * are in the process of deleting the NSEC chain.
  517. *
  518. * 'save_delete_nsec' is used to store the initial state of 'delete_nsec'
  519. * so it can be recovered in the event of a error.
  520. */
  521. struct dns_keyfetch {
  522. dns_fixedname_t name;
  523. dns_rdataset_t keydataset;
  524. dns_rdataset_t dnskeyset;
  525. dns_rdataset_t dnskeysigset;
  526. dns_zone_t *zone;
  527. dns_db_t *db;
  528. dns_fetch_t *fetch;
  529. };
  530. #define HOUR 3600
  531. #define DAY (24*HOUR)
  532. #define MONTH (30*DAY)
  533. #define SEND_BUFFER_SIZE 2048
  534. static void zone_settimer(dns_zone_t *, isc_time_t *);
  535. static void cancel_refresh(dns_zone_t *);
  536. static void zone_debuglog(dns_zone_t *zone, const char *, int debuglevel,
  537. const char *msg, ...) ISC_FORMAT_PRINTF(4, 5);
  538. static void notify_log(dns_zone_t *zone, int level, const char *fmt, ...)
  539. ISC_FORMAT_PRINTF(3, 4);
  540. static void queue_xfrin(dns_zone_t *zone);
  541. static isc_result_t update_one_rr(dns_db_t *db, dns_dbversion_t *ver,
  542. dns_diff_t *diff, dns_diffop_t op,
  543. dns_name_t *name, dns_ttl_t ttl,
  544. dns_rdata_t *rdata);
  545. static void zone_unload(dns_zone_t *zone);
  546. static void zone_expire(dns_zone_t *zone);
  547. static void zone_iattach(dns_zone_t *source, dns_zone_t **target);
  548. static void zone_idetach(dns_zone_t **zonep);
  549. static isc_result_t zone_replacedb(dns_zone_t *zone, dns_db_t *db,
  550. isc_boolean_t dump);
  551. static inline void zone_attachdb(dns_zone_t *zone, dns_db_t *db);
  552. static inline void zone_detachdb(dns_zone_t *zone);
  553. static isc_result_t default_journal(dns_zone_t *zone);
  554. static void zone_xfrdone(dns_zone_t *zone, isc_result_t result);
  555. static isc_result_t zone_postload(dns_zone_t *zone, dns_db_t *db,
  556. isc_time_t loadtime, isc_result_t result);
  557. static void zone_needdump(dns_zone_t *zone, unsigned int delay);
  558. static void zone_shutdown(isc_task_t *, isc_event_t *);
  559. static void zone_loaddone(void *arg, isc_result_t result);
  560. static isc_result_t zone_startload(dns_db_t *db, dns_zone_t *zone,
  561. isc_time_t loadtime);
  562. static void zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length);
  563. static void zone_name_tostr(dns_zone_t *zone, char *buf, size_t length);
  564. static void zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length);
  565. static void zone_viewname_tostr(dns_zone_t *zone, char *buf, size_t length);
  566. #if 0
  567. /* ondestroy example */
  568. static void dns_zonemgr_dbdestroyed(isc_task_t *task, isc_event_t *event);
  569. #endif
  570. static void refresh_callback(isc_task_t *, isc_event_t *);
  571. static void stub_callback(isc_task_t *, isc_event_t *);
  572. static void queue_soa_query(dns_zone_t *zone);
  573. static void soa_query(isc_task_t *, isc_event_t *);
  574. static void ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset,
  575. dns_stub_t *stub);
  576. static int message_count(dns_message_t *msg, dns_section_t section,
  577. dns_rdatatype_t type);
  578. static void notify_cancel(dns_zone_t *zone);
  579. static void notify_find_address(dns_notify_t *notify);
  580. static void notify_send(dns_notify_t *notify);
  581. static isc_result_t notify_createmessage(dns_zone_t *zone,
  582. unsigned int flags,
  583. dns_message_t **messagep);
  584. static void notify_done(isc_task_t *task, isc_event_t *event);
  585. static void notify_send_toaddr(isc_task_t *task, isc_event_t *event);
  586. static isc_result_t zone_dump(dns_zone_t *, isc_boolean_t);
  587. static void got_transfer_quota(isc_task_t *task, isc_event_t *event);
  588. static isc_result_t zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr,
  589. dns_zone_t *zone);
  590. static void zmgr_resume_xfrs(dns_zonemgr_t *zmgr, isc_boolean_t multi);
  591. static void zonemgr_free(dns_zonemgr_t *zmgr);
  592. static isc_result_t zonemgr_getio(dns_zonemgr_t *zmgr, isc_boolean_t high,
  593. isc_task_t *task, isc_taskaction_t action,
  594. void *arg, dns_io_t **iop);
  595. static void zonemgr_putio(dns_io_t **iop);
  596. static void zonemgr_cancelio(dns_io_t *io);
  597. static isc_result_t
  598. zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount,
  599. unsigned int *soacount, isc_uint32_t *serial,
  600. isc_uint32_t *refresh, isc_uint32_t *retry,
  601. isc_uint32_t *expire, isc_uint32_t *minimum,
  602. unsigned int *errors);
  603. static void zone_freedbargs(dns_zone_t *zone);
  604. static void forward_callback(isc_task_t *task, isc_event_t *event);
  605. static void zone_saveunique(dns_zone_t *zone, const char *path,
  606. const char *templat);
  607. static void zone_maintenance(dns_zone_t *zone);
  608. static void zone_notify(dns_zone_t *zone, isc_time_t *now);
  609. static void dump_done(void *arg, isc_result_t result);
  610. static isc_result_t zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm,
  611. isc_uint16_t keyid, isc_boolean_t delete);
  612. static isc_result_t delete_nsec(dns_db_t *db, dns_dbversion_t *ver,
  613. dns_dbnode_t *node, dns_name_t *name,
  614. dns_diff_t *diff);
  615. static void zone_rekey(dns_zone_t *zone);
  616. static isc_boolean_t delsig_ok(dns_rdata_rrsig_t *rrsig_ptr,
  617. dst_key_t **keys, unsigned int nkeys);
  618. #define ENTER zone_debuglog(zone, me, 1, "enter")
  619. static const unsigned int dbargc_default = 1;
  620. static const char *dbargv_default[] = { "rbt" };
  621. #define DNS_ZONE_JITTER_ADD(a, b, c) \
  622. do { \
  623. isc_interval_t _i; \
  624. isc_uint32_t _j; \
  625. _j = isc_random_jitter((b), (b)/4); \
  626. isc_interval_set(&_i, _j, 0); \
  627. if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \
  628. dns_zone_log(zone, ISC_LOG_WARNING, \
  629. "epoch approaching: upgrade required: " \
  630. "now + %s failed", #b); \
  631. isc_interval_set(&_i, _j/2, 0); \
  632. (void)isc_time_add((a), &_i, (c)); \
  633. } \
  634. } while (0)
  635. #define DNS_ZONE_TIME_ADD(a, b, c) \
  636. do { \
  637. isc_interval_t _i; \
  638. isc_interval_set(&_i, (b), 0); \
  639. if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \
  640. dns_zone_log(zone, ISC_LOG_WARNING, \
  641. "epoch approaching: upgrade required: " \
  642. "now + %s failed", #b); \
  643. isc_interval_set(&_i, (b)/2, 0); \
  644. (void)isc_time_add((a), &_i, (c)); \
  645. } \
  646. } while (0)
  647. /*%
  648. * Increment resolver-related statistics counters. Zone must be locked.
  649. */
  650. static inline void
  651. inc_stats(dns_zone_t *zone, isc_statscounter_t counter) {
  652. if (zone->stats != NULL)
  653. isc_stats_increment(zone->stats, counter);
  654. }
  655. /***
  656. *** Public functions.
  657. ***/
  658. isc_result_t
  659. dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
  660. isc_result_t result;
  661. dns_zone_t *zone;
  662. isc_time_t now;
  663. REQUIRE(zonep != NULL && *zonep == NULL);
  664. REQUIRE(mctx != NULL);
  665. TIME_NOW(&now);
  666. zone = isc_mem_get(mctx, sizeof(*zone));
  667. if (zone == NULL)
  668. return (ISC_R_NOMEMORY);
  669. zone->mctx = NULL;
  670. isc_mem_attach(mctx, &zone->mctx);
  671. result = isc_mutex_init(&zone->lock);
  672. if (result != ISC_R_SUCCESS)
  673. goto free_zone;
  674. result = ZONEDB_INITLOCK(&zone->dblock);
  675. if (result != ISC_R_SUCCESS)
  676. goto free_mutex;
  677. /* XXX MPA check that all elements are initialised */
  678. #ifdef DNS_ZONE_CHECKLOCK
  679. zone->locked = ISC_FALSE;
  680. #endif
  681. zone->db = NULL;
  682. zone->zmgr = NULL;
  683. ISC_LINK_INIT(zone, link);
  684. result = isc_refcount_init(&zone->erefs, 1); /* Implicit attach. */
  685. if (result != ISC_R_SUCCESS)
  686. goto free_dblock;
  687. zone->irefs = 0;
  688. dns_name_init(&zone->origin, NULL);
  689. zone->strnamerd = NULL;
  690. zone->strname = NULL;
  691. zone->strrdclass = NULL;
  692. zone->strviewname = NULL;
  693. zone->masterfile = NULL;
  694. zone->masterformat = dns_masterformat_none;
  695. zone->keydirectory = NULL;
  696. zone->journalsize = -1;
  697. zone->journal = NULL;
  698. zone->rdclass = dns_rdataclass_none;
  699. zone->type = dns_zone_none;
  700. zone->flags = 0;
  701. zone->options = 0;
  702. zone->keyopts = 0;
  703. zone->db_argc = 0;
  704. zone->db_argv = NULL;
  705. isc_time_settoepoch(&zone->expiretime);
  706. isc_time_settoepoch(&zone->refreshtime);
  707. isc_time_settoepoch(&zone->dumptime);
  708. isc_time_settoepoch(&zone->loadtime);
  709. zone->notifytime = now;
  710. isc_time_settoepoch(&zone->resigntime);
  711. isc_time_settoepoch(&zone->keywarntime);
  712. isc_time_settoepoch(&zone->signingtime);
  713. isc_time_settoepoch(&zone->nsec3chaintime);
  714. isc_time_settoepoch(&zone->refreshkeytime);
  715. zone->refreshkeycount = 0;
  716. zone->refresh = DNS_ZONE_DEFAULTREFRESH;
  717. zone->retry = DNS_ZONE_DEFAULTRETRY;
  718. zone->expire = 0;
  719. zone->minimum = 0;
  720. zone->maxrefresh = DNS_ZONE_MAXREFRESH;
  721. zone->minrefresh = DNS_ZONE_MINREFRESH;
  722. zone->maxretry = DNS_ZONE_MAXRETRY;
  723. zone->minretry = DNS_ZONE_MINRETRY;
  724. zone->masters = NULL;
  725. zone->masterkeynames = NULL;
  726. zone->mastersok = NULL;
  727. zone->masterscnt = 0;
  728. zone->curmaster = 0;
  729. zone->notify = NULL;
  730. zone->notifytype = dns_notifytype_yes;
  731. zone->notifycnt = 0;
  732. zone->task = NULL;
  733. zone->update_acl = NULL;
  734. zone->forward_acl = NULL;
  735. zone->notify_acl = NULL;
  736. zone->query_acl = NULL;
  737. zone->queryon_acl = NULL;
  738. zone->xfr_acl = NULL;
  739. zone->update_disabled = ISC_FALSE;
  740. zone->zero_no_soa_ttl = ISC_TRUE;
  741. zone->check_names = dns_severity_ignore;
  742. zone->request = NULL;
  743. zone->lctx = NULL;
  744. zone->readio = NULL;
  745. zone->dctx = NULL;
  746. zone->writeio = NULL;
  747. zone->timer = NULL;
  748. zone->idlein = DNS_DEFAULT_IDLEIN;
  749. zone->idleout = DNS_DEFAULT_IDLEOUT;
  750. zone->log_key_expired_timer = 0;
  751. ISC_LIST_INIT(zone->notifies);
  752. isc_sockaddr_any(&zone->notifysrc4);
  753. isc_sockaddr_any6(&zone->notifysrc6);
  754. isc_sockaddr_any(&zone->xfrsource4);
  755. isc_sockaddr_any6(&zone->xfrsource6);
  756. isc_sockaddr_any(&zone->altxfrsource4);
  757. isc_sockaddr_any6(&zone->altxfrsource6);
  758. zone->xfr = NULL;
  759. zone->tsigkey = NULL;
  760. zone->maxxfrin = MAX_XFER_TIME;
  761. zone->maxxfrout = MAX_XFER_TIME;
  762. zone->ssutable = NULL;
  763. zone->sigvalidityinterval = 30 * 24 * 3600;
  764. zone->sigresigninginterval = 7 * 24 * 3600;
  765. zone->view = NULL;
  766. zone->acache = NULL;
  767. zone->checkmx = NULL;
  768. zone->checksrv = NULL;
  769. zone->checkns = NULL;
  770. ISC_LINK_INIT(zone, statelink);
  771. zone->statelist = NULL;
  772. zone->stats = NULL;
  773. zone->requeststats_on = ISC_FALSE;
  774. zone->requeststats = NULL;
  775. zone->notifydelay = 5;
  776. zone->isself = NULL;
  777. zone->isselfarg = NULL;
  778. ISC_LIST_INIT(zone->signing);
  779. ISC_LIST_INIT(zone->nsec3chain);
  780. zone->signatures = 10;
  781. zone->nodes = 100;
  782. zone->privatetype = (dns_rdatatype_t)0xffffU;
  783. zone->added = ISC_FALSE;
  784. zone->rpz_zone = ISC_FALSE;
  785. ISC_LIST_INIT(zone->forwards);
  786. zone->magic = ZONE_MAGIC;
  787. /* Must be after magic is set. */
  788. result = dns_zone_setdbtype(zone, dbargc_default, dbargv_default);
  789. if (result != ISC_R_SUCCESS)
  790. goto free_erefs;
  791. ISC_EVENT_INIT(&zone->ctlevent, sizeof(zone->ctlevent), 0, NULL,
  792. DNS_EVENT_ZONECONTROL, zone_shutdown, zone, zone,
  793. NULL, NULL);
  794. *zonep = zone;
  795. return (ISC_R_SUCCESS);
  796. free_erefs:
  797. isc_refcount_decrement(&zone->erefs, NULL);
  798. isc_refcount_destroy(&zone->erefs);
  799. free_dblock:
  800. ZONEDB_DESTROYLOCK(&zone->dblock);
  801. free_mutex:
  802. DESTROYLOCK(&zone->lock);
  803. free_zone:
  804. isc_mem_putanddetach(&zone->mctx, zone, sizeof(*zone));
  805. return (result);
  806. }
  807. /*
  808. * Free a zone. Because we require that there be no more
  809. * outstanding events or references, no locking is necessary.
  810. */
  811. static void
  812. zone_free(dns_zone_t *zone) {
  813. isc_mem_t *mctx = NULL;
  814. dns_signing_t *signing;
  815. dns_nsec3chain_t *nsec3chain;
  816. REQUIRE(DNS_ZONE_VALID(zone));
  817. REQUIRE(isc_refcount_current(&zone->erefs) == 0);
  818. REQUIRE(zone->irefs == 0);
  819. REQUIRE(!LOCKED_ZONE(zone));
  820. REQUIRE(zone->timer == NULL);
  821. /*
  822. * Managed objects. Order is important.
  823. */
  824. if (zone->request != NULL)
  825. dns_request_destroy(&zone->request); /* XXXMPA */
  826. INSIST(zone->readio == NULL);
  827. INSIST(zone->statelist == NULL);
  828. INSIST(zone->writeio == NULL);
  829. if (zone->task != NULL)
  830. isc_task_detach(&zone->task);
  831. if (zone->zmgr != NULL)
  832. dns_zonemgr_releasezone(zone->zmgr, zone);
  833. /* Unmanaged objects */
  834. for (signing = ISC_LIST_HEAD(zone->signing);
  835. signing != NULL;
  836. signing = ISC_LIST_HEAD(zone->signing)) {
  837. ISC_LIST_UNLINK(zone->signing, signing, link);
  838. dns_db_detach(&signing->db);
  839. dns_dbiterator_destroy(&signing->dbiterator);
  840. isc_mem_put(zone->mctx, signing, sizeof *signing);
  841. }
  842. for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
  843. nsec3chain != NULL;
  844. nsec3chain = ISC_LIST_HEAD(zone->nsec3chain)) {
  845. ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link);
  846. dns_db_detach(&nsec3chain->db);
  847. dns_dbiterator_destroy(&nsec3chain->dbiterator);
  848. isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
  849. }
  850. if (zone->masterfile != NULL)
  851. isc_mem_free(zone->mctx, zone->masterfile);
  852. zone->masterfile = NULL;
  853. if (zone->keydirectory != NULL)
  854. isc_mem_free(zone->mctx, zone->keydirectory);
  855. zone->keydirectory = NULL;
  856. zone->journalsize = -1;
  857. if (zone->journal != NULL)
  858. isc_mem_free(zone->mctx, zone->journal);
  859. zone->journal = NULL;
  860. if (zone->stats != NULL)
  861. isc_stats_detach(&zone->stats);
  862. if (zone->requeststats != NULL)
  863. isc_stats_detach(&zone->requeststats);
  864. if (zone->db != NULL)
  865. zone_detachdb(zone);
  866. if (zone->acache != NULL)
  867. dns_acache_detach(&zone->acache);
  868. zone_freedbargs(zone);
  869. RUNTIME_CHECK(dns_zone_setmasterswithkeys(zone, NULL, NULL, 0)
  870. == ISC_R_SUCCESS);
  871. RUNTIME_CHECK(dns_zone_setalsonotify(zone, NULL, 0)
  872. == ISC_R_SUCCESS);
  873. zone->check_names = dns_severity_ignore;
  874. if (zone->update_acl != NULL)
  875. dns_acl_detach(&zone->update_acl);
  876. if (zone->forward_acl != NULL)
  877. dns_acl_detach(&zone->forward_acl);
  878. if (zone->notify_acl != NULL)
  879. dns_acl_detach(&zone->notify_acl);
  880. if (zone->query_acl != NULL)
  881. dns_acl_detach(&zone->query_acl);
  882. if (zone->queryon_acl != NULL)
  883. dns_acl_detach(&zone->queryon_acl);
  884. if (zone->xfr_acl != NULL)
  885. dns_acl_detach(&zone->xfr_acl);
  886. if (dns_name_dynamic(&zone->origin))
  887. dns_name_free(&zone->origin, zone->mctx);
  888. if (zone->strnamerd != NULL)
  889. isc_mem_free(zone->mctx, zone->strnamerd);
  890. if (zone->strname != NULL)
  891. isc_mem_free(zone->mctx, zone->strname);
  892. if (zone->strrdclass != NULL)
  893. isc_mem_free(zone->mctx, zone->strrdclass);
  894. if (zone->strviewname != NULL)
  895. isc_mem_free(zone->mctx, zone->strviewname);
  896. if (zone->ssutable != NULL)
  897. dns_ssutable_detach(&zone->ssutable);
  898. /* last stuff */
  899. ZONEDB_DESTROYLOCK(&zone->dblock);
  900. DESTROYLOCK(&zone->lock);
  901. isc_refcount_destroy(&zone->erefs);
  902. zone->magic = 0;
  903. mctx = zone->mctx;
  904. isc_mem_put(mctx, zone, sizeof(*zone));
  905. isc_mem_detach(&mctx);
  906. }
  907. /*
  908. * Single shot.
  909. */
  910. void
  911. dns_zone_setclass(dns_zone_t *zone, dns_rdataclass_t rdclass) {
  912. char namebuf[1024];
  913. REQUIRE(DNS_ZONE_VALID(zone));
  914. REQUIRE(rdclass != dns_rdataclass_none);
  915. /*
  916. * Test and set.
  917. */
  918. LOCK_ZONE(zone);
  919. REQUIRE(zone->rdclass == dns_rdataclass_none ||
  920. zone->rdclass == rdclass);
  921. zone->rdclass = rdclass;
  922. if (zone->strnamerd != NULL)
  923. isc_mem_free(zone->mctx, zone->strnamerd);
  924. if (zone->strrdclass != NULL)
  925. isc_mem_free(zone->mctx, zone->strrdclass);
  926. zone_namerd_tostr(zone, namebuf, sizeof namebuf);
  927. zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
  928. zone_rdclass_tostr(zone, namebuf, sizeof namebuf);
  929. zone->strrdclass = isc_mem_strdup(zone->mctx, namebuf);
  930. UNLOCK_ZONE(zone);
  931. }
  932. dns_rdataclass_t
  933. dns_zone_getclass(dns_zone_t *zone) {
  934. REQUIRE(DNS_ZONE_VALID(zone));
  935. return (zone->rdclass);
  936. }
  937. void
  938. dns_zone_setnotifytype(dns_zone_t *zone, dns_notifytype_t notifytype) {
  939. REQUIRE(DNS_ZONE_VALID(zone));
  940. LOCK_ZONE(zone);
  941. zone->notifytype = notifytype;
  942. UNLOCK_ZONE(zone);
  943. }
  944. isc_result_t
  945. dns_zone_getserial2(dns_zone_t *zone, isc_uint32_t *serialp) {
  946. isc_result_t result;
  947. REQUIRE(DNS_ZONE_VALID(zone));
  948. REQUIRE(serialp != NULL);
  949. LOCK_ZONE(zone);
  950. ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
  951. if (zone->db != NULL) {
  952. result = zone_get_from_db(zone, zone->db, NULL, NULL, serialp,
  953. NULL, NULL, NULL, NULL, NULL);
  954. } else
  955. result = DNS_R_NOTLOADED;
  956. ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
  957. UNLOCK_ZONE(zone);
  958. return (result);
  959. }
  960. isc_uint32_t
  961. dns_zone_getserial(dns_zone_t *zone) {
  962. isc_result_t result;
  963. isc_uint32_t serial;
  964. result = dns_zone_getserial2(zone, &serial);
  965. if (result != ISC_R_SUCCESS)
  966. serial = 0; /* XXX: not really correct, but no other choice */
  967. return (serial);
  968. }
  969. /*
  970. * Single shot.
  971. */
  972. void
  973. dns_zone_settype(dns_zone_t *zone, dns_zonetype_t type) {
  974. REQUIRE(DNS_ZONE_VALID(zone));
  975. REQUIRE(type != dns_zone_none);
  976. /*
  977. * Test and set.
  978. */
  979. LOCK_ZONE(zone);
  980. REQUIRE(zone->type == dns_zone_none || zone->type == type);
  981. zone->type = type;
  982. UNLOCK_ZONE(zone);
  983. }
  984. static void
  985. zone_freedbargs(dns_zone_t *zone) {
  986. unsigned int i;
  987. /* Free the old database argument list. */
  988. if (zone->db_argv != NULL) {
  989. for (i = 0; i < zone->db_argc; i++)
  990. isc_mem_free(zone->mctx, zone->db_argv[i]);
  991. isc_mem_put(zone->mctx, zone->db_argv,
  992. zone->db_argc * sizeof(*zone->db_argv));
  993. }
  994. zone->db_argc = 0;
  995. zone->db_argv = NULL;
  996. }
  997. isc_result_t
  998. dns_zone_getdbtype(dns_zone_t *zone, char ***argv, isc_mem_t *mctx) {
  999. size_t size = 0;
  1000. unsigned int i;
  1001. isc_result_t result = ISC_R_SUCCESS;
  1002. void *mem;
  1003. char **tmp, *tmp2;
  1004. REQUIRE(DNS_ZONE_VALID(zone));
  1005. REQUIRE(argv != NULL && *argv == NULL);
  1006. LOCK_ZONE(zone);
  1007. size = (zone->db_argc + 1) * sizeof(char *);
  1008. for (i = 0; i < zone->db_argc; i++)
  1009. size += strlen(zone->db_argv[i]) + 1;
  1010. mem = isc_mem_allocate(mctx, size);
  1011. if (mem != NULL) {
  1012. tmp = mem;
  1013. tmp2 = mem;
  1014. tmp2 += (zone->db_argc + 1) * sizeof(char *);
  1015. for (i = 0; i < zone->db_argc; i++) {
  1016. *tmp++ = tmp2;
  1017. strcpy(tmp2, zone->db_argv[i]);
  1018. tmp2 += strlen(tmp2) + 1;
  1019. }
  1020. *tmp = NULL;
  1021. } else
  1022. result = ISC_R_NOMEMORY;
  1023. UNLOCK_ZONE(zone);
  1024. *argv = mem;
  1025. return (result);
  1026. }
  1027. isc_result_t
  1028. dns_zone_setdbtype(dns_zone_t *zone,
  1029. unsigned int dbargc, const char * const *dbargv) {
  1030. isc_result_t result = ISC_R_SUCCESS;
  1031. char **new = NULL;
  1032. unsigned int i;
  1033. REQUIRE(DNS_ZONE_VALID(zone));
  1034. REQUIRE(dbargc >= 1);
  1035. REQUIRE(dbargv != NULL);
  1036. LOCK_ZONE(zone);
  1037. /* Set up a new database argument list. */
  1038. new = isc_mem_get(zone->mctx, dbargc * sizeof(*new));
  1039. if (new == NULL)
  1040. goto nomem;
  1041. for (i = 0; i < dbargc; i++)
  1042. new[i] = NULL;
  1043. for (i = 0; i < dbargc; i++) {
  1044. new[i] = isc_mem_strdup(zone->mctx, dbargv[i]);
  1045. if (new[i] == NULL)
  1046. goto nomem;
  1047. }
  1048. /* Free the old list. */
  1049. zone_freedbargs(zone);
  1050. zone->db_argc = dbargc;
  1051. zone->db_argv = new;
  1052. result = ISC_R_SUCCESS;
  1053. goto unlock;
  1054. nomem:
  1055. if (new != NULL) {
  1056. for (i = 0; i < dbargc; i++)
  1057. if (new[i] != NULL)
  1058. isc_mem_free(zone->mctx, new[i]);
  1059. isc_mem_put(zone->mctx, new, dbargc * sizeof(*new));
  1060. }
  1061. result = ISC_R_NOMEMORY;
  1062. unlock:
  1063. UNLOCK_ZONE(zone);
  1064. return (result);
  1065. }
  1066. void
  1067. dns_zone_setview(dns_zone_t *zone, dns_view_t *view) {
  1068. char namebuf[1024];
  1069. REQUIRE(DNS_ZONE_VALID(zone));
  1070. LOCK_ZONE(zone);
  1071. if (zone->view != NULL)
  1072. dns_view_weakdetach(&zone->view);
  1073. dns_view_weakattach(view, &zone->view);
  1074. if (zone->strviewname != NULL)
  1075. isc_mem_free(zone->mctx, zone->strviewname);
  1076. if (zone->strnamerd != NULL)
  1077. isc_mem_free(zone->mctx, zone->strnamerd);
  1078. zone_namerd_tostr(zone, namebuf, sizeof namebuf);
  1079. zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
  1080. zone_viewname_tostr(zone, namebuf, sizeof namebuf);
  1081. zone->strviewname = isc_mem_strdup(zone->mctx, namebuf);
  1082. UNLOCK_ZONE(zone);
  1083. }
  1084. dns_view_t *
  1085. dns_zone_getview(dns_zone_t *zone) {
  1086. REQUIRE(DNS_ZONE_VALID(zone));
  1087. return (zone->view);
  1088. }
  1089. isc_result_t
  1090. dns_zone_setorigin(dns_zone_t *zone, const dns_name_t *origin) {
  1091. isc_result_t result;
  1092. char namebuf[1024];
  1093. REQUIRE(DNS_ZONE_VALID(zone));
  1094. REQUIRE(origin != NULL);
  1095. LOCK_ZONE(zone);
  1096. if (dns_name_dynamic(&zone->origin)) {
  1097. dns_name_free(&zone->origin, zone->mctx);
  1098. dns_name_init(&zone->origin, NULL);
  1099. }
  1100. result = dns_name_dup(origin, zone->mctx, &zone->origin);
  1101. if (zone->strnamerd != NULL)
  1102. isc_mem_free(zone->mctx, zone->strnamerd);
  1103. if (zone->strname != NULL)
  1104. isc_mem_free(zone->mctx, zone->strname);
  1105. zone_namerd_tostr(zone, namebuf, sizeof namebuf);
  1106. zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
  1107. zone_name_tostr(zone, namebuf, sizeof namebuf);
  1108. zone->strname = isc_mem_strdup(zone->mctx, namebuf);
  1109. UNLOCK_ZONE(zone);
  1110. return (result);
  1111. }
  1112. void
  1113. dns_zone_setacache(dns_zone_t *zone, dns_acache_t *acache) {
  1114. REQUIRE(DNS_ZONE_VALID(zone));
  1115. REQUIRE(acache != NULL);
  1116. LOCK_ZONE(zone);
  1117. if (zone->acache != NULL)
  1118. dns_acache_detach(&zone->acache);
  1119. dns_acache_attach(acache, &zone->acache);
  1120. ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
  1121. if (zone->db != NULL) {
  1122. isc_result_t result;
  1123. /*
  1124. * If the zone reuses an existing DB, the DB needs to be
  1125. * set in the acache explicitly. We can safely ignore the
  1126. * case where the DB is already set. If other error happens,
  1127. * the acache will not work effectively.
  1128. */
  1129. result = dns_acache_setdb(acache, zone->db);
  1130. if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) {
  1131. UNEXPECTED_ERROR(__FILE__, __LINE__,
  1132. "dns_acache_setdb() failed: %s",
  1133. isc_result_totext(result));
  1134. }
  1135. }
  1136. ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
  1137. UNLOCK_ZONE(zone);
  1138. }
  1139. static isc_result_t
  1140. dns_zone_setstring(dns_zone_t *zone, char **field, const char *value) {
  1141. char *copy;
  1142. if (value != NULL) {
  1143. copy = isc_mem_strdup(zone->mctx, value);
  1144. if (copy == NULL)
  1145. return (ISC_R_NOMEMORY);
  1146. } else {
  1147. copy = NULL;
  1148. }
  1149. if (*field != NULL)
  1150. isc_mem_free(zone->mctx, *field);
  1151. *field = copy;
  1152. return (ISC_R_SUCCESS);
  1153. }
  1154. isc_result_t
  1155. dns_zone_setfile(dns_zone_t *zone, const char *file) {
  1156. return (dns_zone_setfile2(zone, file, dns_masterformat_text));
  1157. }
  1158. isc_result_t
  1159. dns_zone_setfile2(dns_zone_t *zone, const char *file,
  1160. dns_masterformat_t format) {
  1161. isc_result_t result = ISC_R_SUCCESS;
  1162. REQUIRE(DNS_ZONE_VALID(zone));
  1163. LOCK_ZONE(zone);
  1164. result = dns_zone_setstring(zone, &zone->masterfile, file);
  1165. if (result == ISC_R_SUCCESS) {
  1166. zone->masterformat = format;
  1167. result = default_journal(zone);
  1168. }
  1169. UNLOCK_ZONE(zone);
  1170. return (result);
  1171. }
  1172. const char *
  1173. dns_zone_getfile(dns_zone_t *zone) {
  1174. REQUIRE(DNS_ZONE_VALID(zone));
  1175. return (zone->masterfile);
  1176. }
  1177. static isc_result_t
  1178. default_journal(dns_zone_t *zone) {
  1179. isc_result_t result;
  1180. char *journal;
  1181. REQUIRE(DNS_ZONE_VALID(zone));
  1182. REQUIRE(LOCKED_ZONE(zone));
  1183. if (zone->masterfile != NULL) {
  1184. /* Calculate string length including '\0'. */
  1185. int len = strlen(zone->masterfile) + sizeof(".jnl");
  1186. journal = isc_mem_allocate(zone->mctx, len);
  1187. if (journal == NULL)
  1188. return (ISC_R_NOMEMORY);
  1189. strcpy(journal, zone->masterfile);
  1190. strcat(journal, ".jnl");
  1191. } else {
  1192. journal = NULL;
  1193. }
  1194. result = dns_zone_setstring(zone, &zone->journal, journal);
  1195. if (journal != NULL)
  1196. isc_mem_free(zone->mctx, journal);
  1197. return (result);
  1198. }
  1199. isc_result_t
  1200. dns_zone_setjournal(dns_zone_t *zone, const char *journal) {
  1201. isc_result_t result = ISC_R_SUCCESS;
  1202. REQUIRE(DNS_ZONE_VALID(zone));
  1203. LOCK_ZONE(zone);
  1204. result = dns_zone_setstring(zone, &zone->journal, journal);
  1205. UNLOCK_ZONE(zone);
  1206. return (result);
  1207. }
  1208. char *
  1209. dns_zone_getjournal(dns_zone_t *zone) {
  1210. REQUIRE(DNS_ZONE_VALID(zone));
  1211. return (zone->journal);
  1212. }
  1213. /*
  1214. * Return true iff the zone is "dynamic", in the sense that the zone's
  1215. * master file (if any) is written by the server, rather than being
  1216. * updated manually and read by the server.
  1217. *
  1218. * This is true for slave zones, stub zones, key zones, and zones that
  1219. * allow dynamic updates either by having an update policy ("ssutable")
  1220. * or an "allow-update" ACL with a value other than exactly "{ none; }".
  1221. */
  1222. static isc_boolean_t
  1223. zone_isdynamic(dns_zone_t *zone) {
  1224. REQUIRE(DNS_ZONE_VALID(zone));
  1225. return (ISC_TF(zone->type == dns_zone_slave ||
  1226. zone->type == dns_zone_stub ||
  1227. zone->type == dns_zone_key ||
  1228. (!zone->update_disabled && zone->ssutable != NULL) ||
  1229. (!zone->update_disabled && zone->update_acl != NULL &&
  1230. !dns_acl_isnone(zone->update_acl))));
  1231. }
  1232. static isc_result_t
  1233. zone_load(dns_zone_t *zone, unsigned int flags) {
  1234. isc_result_t result;
  1235. isc_time_t now;
  1236. isc_time_t loadtime, filetime;
  1237. dns_db_t *db = NULL;
  1238. isc_boolean_t rbt;
  1239. REQUIRE(DNS_ZONE_VALID(zone));
  1240. LOCK_ZONE(zone);
  1241. TIME_NOW(&now);
  1242. INSIST(zone->type != dns_zone_none);
  1243. if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING)) {
  1244. if ((flags & DNS_ZONELOADFLAG_THAW) != 0)
  1245. DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW);
  1246. result = DNS_R_CONTINUE;
  1247. goto cleanup;
  1248. }
  1249. INSIST(zone->db_argc >= 1);
  1250. rbt = strcmp(zone->db_argv[0], "rbt") == 0 ||
  1251. strcmp(zone->db_argv[0], "rbt64") == 0;
  1252. if (zone->db != NULL && zone->masterfile == NULL && rbt) {
  1253. /*
  1254. * The zone has no master file configured.
  1255. */
  1256. result = ISC_R_SUCCESS;
  1257. goto cleanup;
  1258. }
  1259. if (zone->db != NULL && zone_isdynamic(zone)) {
  1260. /*
  1261. * This is a slave, stub, or dynamically updated
  1262. * zone being reloaded. Do nothing - the database
  1263. * we already have is guaranteed to be up-to-date.
  1264. */
  1265. if (zone->type == dns_zone_master)
  1266. result = DNS_R_DYNAMIC;
  1267. else
  1268. result = ISC_R_SUCCESS;
  1269. goto cleanup;
  1270. }
  1271. /*
  1272. * Store the current time before the zone is loaded, so that if the
  1273. * file changes between the time of the load and the time that
  1274. * zone->loadtime is set, then the file will still be reloaded
  1275. * the next time dns_zone_load is called.
  1276. */
  1277. TIME_NOW(&loadtime);
  1278. /*
  1279. * Don't do the load if the file that stores the zone is older
  1280. * than the last time the zone was loaded. If the zone has not
  1281. * been loaded yet, zone->loadtime will be the epoch.
  1282. */
  1283. if (zone->masterfile != NULL) {
  1284. /*
  1285. * The file is already loaded. If we are just doing a
  1286. * "rndc reconfig", we are done.
  1287. */
  1288. if (!isc_time_isepoch(&zone->loadtime) &&
  1289. (flags & DNS_ZONELOADFLAG_NOSTAT) != 0 &&
  1290. zone->rpz_zone == dns_rpz_needed()) {
  1291. result = ISC_R_SUCCESS;
  1292. goto cleanup;
  1293. }
  1294. result = isc_file_getmodtime(zone->masterfile, &filetime);
  1295. if (result == ISC_R_SUCCESS) {
  1296. if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
  1297. !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE) &&
  1298. isc_time_compare(&filetime, &zone->loadtime) <= 0 &&
  1299. zone->rpz_zone == dns_rpz_needed()) {
  1300. dns_zone_log(zone, ISC_LOG_DEBUG(1),
  1301. "skipping load: master file "
  1302. "older than last load");
  1303. result = DNS_R_UPTODATE;
  1304. goto cleanup;
  1305. }
  1306. loadtime = filetime;
  1307. zone->rpz_zone = dns_rpz_needed();
  1308. }
  1309. }
  1310. /*
  1311. * Built in zones (with the exception of empty zones) don't need
  1312. * to be reloaded.
  1313. */
  1314. if (zone->type == dns_zone_master &&
  1315. strcmp(zone->db_argv[0], "_builtin") == 0 &&
  1316. (zone->db_argc < 2 || strcmp(zone->db_argv[1], "empty") != 0) &&
  1317. DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
  1318. result = ISC_R_SUCCESS;
  1319. goto cleanup;
  1320. }
  1321. if ((zone->type == dns_zone_slave || zone->type == dns_zone_stub) &&
  1322. rbt) {
  1323. if (zone->masterfile == NULL ||
  1324. !isc_file_exists(zone->masterfile)) {
  1325. if (zone->masterfile != NULL) {
  1326. dns_zone_log(zone, ISC_LOG_DEBUG(1),
  1327. "no master file");
  1328. }
  1329. zone->refreshtime = now;
  1330. if (zone->task != NULL)
  1331. zone_settimer(zone, &now);
  1332. result = ISC_R_SUCCESS;
  1333. goto cleanup;
  1334. }
  1335. }
  1336. dns_zone_log(zone, ISC_LOG_DEBUG(1), "starting load");
  1337. result = dns_db_create(zone->mctx, zone->db_argv[0],
  1338. &zone->origin, (zone->type == dns_zone_stub) ?
  1339. dns_dbtype_stub : dns_dbtype_zone,
  1340. zone->rdclass,
  1341. zone->db_argc - 1, zone->db_argv + 1,
  1342. &db);
  1343. if (result != ISC_R_SUCCESS) {
  1344. dns_zone_log(zone, ISC_LOG_ERROR,
  1345. "loading zone: creating database: %s",
  1346. isc_result_totext(result));
  1347. goto cleanup;
  1348. }
  1349. dns_db_settask(db, zone->task);
  1350. if (! dns_db_ispersistent(db)) {
  1351. if (zone->masterfile != NULL) {
  1352. result = zone_startload(db, zone, loadtime);
  1353. } else {
  1354. result = DNS_R_NOMASTERFILE;
  1355. if (zone->type == dns_zone_master) {
  1356. dns_zone_log(zone, ISC_LOG_ERROR,
  1357. "loading zone: "
  1358. "no master file configured");
  1359. goto cleanup;
  1360. }
  1361. dns_zone_log(zone, ISC_LOG_INFO, "loading zone: "
  1362. "no master file configured: continuing");
  1363. }
  1364. }
  1365. if (result == DNS_R_CONTINUE) {
  1366. DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADING);
  1367. if ((flags & DNS_ZONELOADFLAG_THAW) != 0)
  1368. DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW);
  1369. goto cleanup;
  1370. }
  1371. result = zone_postload(zone, db, loadtime, result);
  1372. cleanup:
  1373. UNLOCK_ZONE(zone);
  1374. if (db != NULL)
  1375. dns_db_detach(&db);
  1376. return (result);
  1377. }
  1378. isc_result_t
  1379. dns_zone_load(dns_zone_t *zone) {
  1380. return (zone_load(zone, 0));
  1381. }
  1382. isc_result_t
  1383. dns_zone_loadnew(dns_zone_t *zone) {
  1384. return (zone_load(zone, DNS_ZONELOADFLAG_NOSTAT));
  1385. }
  1386. isc_result_t
  1387. dns_zone_loadandthaw(dns_zone_t *zone) {
  1388. isc_result_t result;
  1389. result = zone_load(zone, DNS_ZONELOADFLAG_THAW);
  1390. switch (result) {
  1391. case DNS_R_CONTINUE:
  1392. /* Deferred thaw. */
  1393. break;
  1394. case ISC_R_SUCCESS:
  1395. case DNS_R_UPTODATE:
  1396. case DNS_R_SEENINCLUDE:
  1397. zone->update_disabled = ISC_FALSE;
  1398. break;
  1399. case DNS_R_NOMASTERFILE:
  1400. zone->update_disabled = ISC_FALSE;
  1401. break;
  1402. default:
  1403. /* Error, remain in disabled state. */
  1404. break;
  1405. }
  1406. return (result);
  1407. }
  1408. static unsigned int
  1409. get_master_options(dns_zone_t *zone) {
  1410. unsigned int options;
  1411. options = DNS_MASTER_ZONE;
  1412. if (zone->type == dns_zone_slave)
  1413. options |= DNS_MASTER_SLAVE;
  1414. if (zone->type == dns_zone_key)
  1415. options |= DNS_MASTER_KEY;
  1416. if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNS))
  1417. options |= DNS_MASTER_CHECKNS;
  1418. if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_FATALNS))
  1419. options |= DNS_MASTER_FATALNS;
  1420. if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES))
  1421. options |= DNS_MASTER_CHECKNAMES;
  1422. if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL))
  1423. options |= DNS_MASTER_CHECKNAMESFAIL;
  1424. if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMX))
  1425. options |= DNS_MASTER_CHECKMX;
  1426. if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMXFAIL))
  1427. options |= DNS_MASTER_CHECKMXFAIL;
  1428. if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKWILDCARD))
  1429. options |= DNS_MASTER_CHECKWILDCARD;
  1430. if (zone->type == dns_zone_master &&
  1431. ((zone->update_acl != NULL && !dns_acl_isnone(zone->update_acl)) ||
  1432. zone->ssutable != NULL))
  1433. options |= DNS_MASTER_RESIGN;
  1434. return (options);
  1435. }
  1436. static void
  1437. zone_gotreadhandle(isc_task_t *task, isc_event_t *event) {
  1438. dns_load_t *load = event->ev_arg;
  1439. isc_result_t result = ISC_R_SUCCESS;
  1440. unsigned int options;
  1441. REQUIRE(DNS_LOAD_VALID(load));
  1442. if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0)
  1443. result = ISC_R_CANCELED;
  1444. isc_event_free(&event);
  1445. if (result == ISC_R_CANCELED)
  1446. goto fail;
  1447. options = get_master_options(load->zone);
  1448. result = dns_master_loadfileinc3(load->zone->masterfile,
  1449. dns_db_origin(load->db),
  1450. dns_db_origin(load->db),
  1451. load->zone->rdclass,
  1452. options,
  1453. load->zone->sigresigninginterval,
  1454. &load->callbacks, task,
  1455. zone_loaddone, load,
  1456. &load->zone->lctx, load->zone->mctx,
  1457. load->zone->masterformat);
  1458. if (result != ISC_R_SUCCESS && result != DNS_R_CONTINUE &&
  1459. result != DNS_R_SEENINCLUDE)
  1460. goto fail;
  1461. return;
  1462. fail:
  1463. zone_loaddone(load, result);
  1464. }
  1465. static void
  1466. zone_gotwritehandle(isc_task_t *task, isc_event_t *event) {
  1467. const char me[] = "zone_gotwritehandle";
  1468. dns_zone_t *zone = event->ev_arg;
  1469. isc_result_t result = ISC_R_SUCCESS;
  1470. dns_dbversion_t *version = NULL;
  1471. REQUIRE(DNS_ZONE_VALID(zone));
  1472. INSIST(task == zone->task);
  1473. ENTER;
  1474. if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0)
  1475. result = ISC_R_CANCELED;
  1476. isc_event_free(&event);
  1477. if (result == ISC_R_CANCELED)
  1478. goto fail;
  1479. LOCK_ZONE(zone);
  1480. ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
  1481. if (zone->db != NULL) {
  1482. dns_db_currentversion(zone->db, &version);
  1483. result = dns_master_dumpinc2(zone->mctx, zone->db, version,
  1484. &dns_master_style_default,
  1485. zone->masterfile, zone->task,
  1486. dump_done, zone, &zone->dctx,
  1487. zone->masterformat);
  1488. dns_db_closeversion(zone->db, &version, ISC_FALSE);
  1489. } else
  1490. result = ISC_R_CANCELED;
  1491. ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
  1492. UNLOCK_ZONE(zone);
  1493. if (result != DNS_R_CONTINUE)
  1494. goto fail;
  1495. return;
  1496. fail:
  1497. dump_done(zone, result);
  1498. }
  1499. static isc_result_t
  1500. zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) {
  1501. dns_load_t *load;
  1502. isc_result_t result;
  1503. isc_result_t tresult;
  1504. unsigned int options;
  1505. options = get_master_options(zone);
  1506. if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MANYERRORS))
  1507. options |= DNS_MASTER_MANYERRORS;
  1508. if (zone->zmgr != NULL && zone->db != NULL && zone->task != NULL) {
  1509. load = isc_mem_get(zone->mctx, sizeof(*load));
  1510. if (load == NULL)
  1511. return (ISC_R_NOMEMORY);
  1512. load->mctx = NULL;
  1513. load->zone = NULL;
  1514. load->db = NULL;
  1515. load->loadtime = loadtime;
  1516. load->magic = LOAD_MAGIC;
  1517. isc_mem_attach(zone->mctx, &load->mctx);
  1518. zone_iattach(zone, &load->zone);
  1519. dns_db_attach(db, &load->db);
  1520. dns_rdatacallbacks_init(&load->callbacks);
  1521. result = dns_db_beginload(db, &load->callbacks.add,
  1522. &load->callbacks.add_private);
  1523. if (result != ISC_R_SUCCESS)
  1524. goto cleanup;
  1525. result = zonemgr_getio(zone->zmgr, ISC_TRUE, zone->task,
  1526. zone_gotreadhandle, load,
  1527. &zone->readio);
  1528. if (result != ISC_R_SUCCESS) {
  1529. /*
  1530. * We can't report multiple errors so ignore
  1531. * the result of dns_db_endload().
  1532. */
  1533. (void)dns_db_endload(load->db,
  1534. &load->callbacks.add_private);
  1535. goto cleanup;
  1536. } else
  1537. result = DNS_R_CONTINUE;
  1538. } else {
  1539. dns_rdatacallbacks_t callbacks;
  1540. dns_rdatacallbacks_init(&callbacks);
  1541. result = dns_db_beginload(db, &callbacks.add,
  1542. &callbacks.add_private);
  1543. if (result != ISC_R_SUCCESS)
  1544. return (result);
  1545. result = dns_master_loadfile3(zone->masterfile, &zone->origin,
  1546. &zone->origin, zone->rdclass,
  1547. options, zone->sigresigninginterval,
  1548. &callbacks, zone->mctx,
  1549. zone->masterformat);
  1550. tresult = dns_db_endload(db, &callbacks.add_private);
  1551. if (result == ISC_R_SUCCESS)
  1552. result = tresult;
  1553. }
  1554. return (result);
  1555. cleanup:
  1556. load->magic = 0;
  1557. dns_db_detach(&load->db);
  1558. zone_idetach(&load->zone);
  1559. isc_mem_detach(&load->mctx);
  1560. isc_mem_put(zone->mctx, load, sizeof(*load));
  1561. return (result);
  1562. }
  1563. static isc_boolean_t
  1564. zone_check_mx(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
  1565. dns_name_t *owner)
  1566. {
  1567. isc_result_t result;
  1568. char ownerbuf[DNS_NAME_FORMATSIZE];
  1569. char namebuf[DNS_NAME_FORMATSIZE];
  1570. char altbuf[DNS_NAME_FORMATSIZE];
  1571. dns_fixedname_t fixed;
  1572. dns_name_t *foundname;
  1573. int level;
  1574. /*
  1575. * "." means the services does not exist.
  1576. */
  1577. if (dns_name_equal(name, dns_rootname))
  1578. return (ISC_TRUE);
  1579. /*
  1580. * Outside of zone.
  1581. */
  1582. if (!dns_name_issubdomain(name, &zone->origin)) {
  1583. if (zone->checkmx != NULL)
  1584. return ((zone->checkmx)(zone, name, owner));
  1585. return (ISC_TRUE);
  1586. }
  1587. if (zone->type == dns_zone_master)
  1588. level = ISC_LOG_ERROR;
  1589. else
  1590. level = ISC_LOG_WARNING;
  1591. dns_fixedname_init(&fixed);
  1592. foundname = dns_fixedname_name(&fixed);
  1593. result = dns_db_find(db, name, NULL, dns_rdatatype_a,
  1594. 0, 0, NULL, foundname, NULL, NULL);
  1595. if (result == ISC_R_SUCCESS)
  1596. return (ISC_TRUE);
  1597. if (result == DNS_R_NXRRSET) {
  1598. result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
  1599. 0, 0, NULL, foundname, NULL, NULL);
  1600. if (result == ISC_R_SUCCESS)
  1601. return (ISC_TRUE);
  1602. }
  1603. dns_name_format(owner, ownerbuf, sizeof ownerbuf);
  1604. dns_name_format(name, namebuf, sizeof namebuf);
  1605. if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
  1606. result == DNS_R_EMPTYNAME) {
  1607. if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMXFAIL))
  1608. level = ISC_LOG_WARNING;
  1609. dns_zone_log(zone, level,
  1610. "%s/MX '%s' has no address records (A or AAAA)",
  1611. ownerbuf, namebuf);
  1612. return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
  1613. }
  1614. if (result == DNS_R_CNAME) {
  1615. if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) ||
  1616. DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
  1617. level = ISC_LOG_WARNING;
  1618. if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
  1619. dns_zone_log(zone, level,
  1620. "%s/MX '%s' is a CNAME (illegal)",
  1621. ownerbuf, namebuf);
  1622. return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
  1623. }
  1624. if (result == DNS_R_DNAME) {
  1625. if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) ||
  1626. DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
  1627. level = ISC_LOG_WARNING;
  1628. if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) {
  1629. dns_name_format(foundname, altbuf, sizeof altbuf);
  1630. dns_zone_log(zone, level, "%s/MX '%s' is below a DNAME"
  1631. " '%s' (illegal)", ownerbuf, namebuf,
  1632. altbuf);
  1633. }
  1634. return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
  1635. }
  1636. if (zone->checkmx != NULL && result == DNS_R_DELEGATION)
  1637. return ((zone->checkmx)(zone, name, owner));
  1638. return (ISC_TRUE);
  1639. }
  1640. static isc_boolean_t
  1641. zone_check_srv(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
  1642. dns_name_t *owner)
  1643. {
  1644. isc_result_t result;
  1645. char ownerbuf[DNS_NAME_FORMATSIZE];
  1646. char namebuf[DNS_NAME_FORMATSIZE];
  1647. char altbuf[DNS_NAME_FORMATSIZE];
  1648. dns_fixedname_t fixed;
  1649. dns_name_t *foundname;
  1650. int level;
  1651. /*
  1652. * "." means the services does not exist.
  1653. */
  1654. if (dns_name_equal(name, dns_rootname))
  1655. return (ISC_TRUE);
  1656. /*
  1657. * Outside of zone.
  1658. */
  1659. if (!dns_name_issubdomain(name, &zone->origin)) {
  1660. if (zone->checksrv != NULL)
  1661. return ((zone->checksrv)(zone, name, owner));
  1662. return (ISC_TRUE);
  1663. }
  1664. if (zone->type == dns_zone_master)
  1665. level = ISC_LOG_ERROR;
  1666. else
  1667. level = ISC_LOG_WARNING;
  1668. dns_fixedname_init(&fixed);
  1669. foundname = dns_fixedname_name(&fixed);
  1670. result = dns_db_find(db, name, NULL, dns_rdatatype_a,
  1671. 0, 0, NULL, foundname, NULL, NULL);
  1672. if (result == ISC_R_SUCCESS)
  1673. return (ISC_TRUE);
  1674. if (result == DNS_R_NXRRSET) {
  1675. result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
  1676. 0, 0, NULL, foundname, NULL, NULL);
  1677. if (result == ISC_R_SUCCESS)
  1678. return (ISC_TRUE);
  1679. }
  1680. dns_name_format(owner, ownerbuf, sizeof ownerbuf);
  1681. dns_name_format(name, namebuf, sizeof namebuf);
  1682. if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
  1683. result == DNS_R_EMPTYNAME) {
  1684. dns_zone_log(zone, level,
  1685. "%s/SRV '%s' has no address records (A or AAAA)",
  1686. ownerbuf, namebuf);
  1687. /* XXX950 make fatal for 9.5.0. */
  1688. return (ISC_TRUE);
  1689. }
  1690. if (result == DNS_R_CNAME) {
  1691. if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) ||
  1692. DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
  1693. level = ISC_LOG_WARNING;
  1694. if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
  1695. dns_zone_log(zone, level,
  1696. "%s/SRV '%s' is a CNAME (illegal)",
  1697. ownerbuf, namebuf);
  1698. return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
  1699. }
  1700. if (result == DNS_R_DNAME) {
  1701. if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) ||
  1702. DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
  1703. level = ISC_LOG_WARNING;
  1704. if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) {
  1705. dns_name_format(foundname, altbuf, sizeof altbuf);
  1706. dns_zone_log(zone, level, "%s/SRV '%s' is below a "
  1707. "DNAME '%s' (illegal)", ownerbuf, namebuf,
  1708. altbuf);
  1709. }
  1710. return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
  1711. }
  1712. if (zone->checksrv != NULL && result == DNS_R_DELEGATION)
  1713. return ((zone->checksrv)(zone, name, owner));
  1714. return (ISC_TRUE);
  1715. }
  1716. static isc_boolean_t
  1717. zone_check_glue(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
  1718. dns_name_t *owner)
  1719. {
  1720. isc_boolean_t answer = ISC_TRUE;
  1721. isc_result_t result, tresult;
  1722. char ownerbuf[DNS_NAME_FORMATSIZE];
  1723. char namebuf[DNS_NAME_FORMATSIZE];
  1724. char altbuf[DNS_NAME_FORMATSIZE];
  1725. dns_fixedname_t fixed;
  1726. dns_name_t *foundname;
  1727. dns_rdataset_t a;
  1728. dns_rdataset_t aaaa;
  1729. int level;
  1730. /*
  1731. * Outside of zone.
  1732. */
  1733. if (!dns_name_issubdomain(name, &zone->origin)) {
  1734. if (zone->checkns != NULL)
  1735. return ((zone->checkns)(zone, name, owner, NULL, NULL));
  1736. return (ISC_TRUE);
  1737. }
  1738. if (zone->type == dns_zone_master)
  1739. level = ISC_LOG_ERROR;
  1740. else
  1741. level = ISC_LOG_WARNING;
  1742. dns_fixedname_init(&fixed);
  1743. foundname = dns_fixedname_name(&fixed);
  1744. dns_rdataset_init(&a);
  1745. dns_rdataset_init(&aaaa);
  1746. result = dns_db_find(db, name, NULL, dns_rdatatype_a,
  1747. DNS_DBFIND_GLUEOK, 0, NULL,
  1748. foundname, &a, NULL);
  1749. if (result == ISC_R_SUCCESS) {
  1750. dns_rdataset_disassociate(&a);
  1751. return (ISC_TRUE);
  1752. } else if (result == DNS_R_DELEGATION)
  1753. dns_rdataset_disassociate(&a);
  1754. if (result == DNS_R_NXRRSET || result == DNS_R_DELEGATION ||
  1755. result == DNS_R_GLUE) {
  1756. tresult = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
  1757. DNS_DBFIND_GLUEOK, 0, NULL,
  1758. foundname, &aaaa, NULL);
  1759. if (tresult == ISC_R_SUCCESS) {
  1760. dns_rdataset_disassociate(&aaaa);
  1761. return (ISC_TRUE);
  1762. }
  1763. if (tresult == DNS_R_DELEGATION)
  1764. dns_rdataset_disassociate(&aaaa);
  1765. if (result == DNS_R_GLUE || tresult == DNS_R_GLUE) {
  1766. /*
  1767. * Check glue against child zone.
  1768. */
  1769. if (zone->checkns != NULL)
  1770. answer = (zone->checkns)(zone, name, owner,
  1771. &a, &aaaa);
  1772. if (dns_rdataset_isassociated(&a))
  1773. dns_rdataset_disassociate(&a);
  1774. if (dns_rdataset_isassociated(&aaaa))
  1775. dns_rdataset_disassociate(&aaaa);
  1776. return (answer);
  1777. }
  1778. }
  1779. dns_name_format(owner, ownerbuf, sizeof ownerbuf);
  1780. dns_name_format(name, namebuf, sizeof namebuf);
  1781. if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
  1782. result == DNS_R_EMPTYNAME || result == DNS_R_DELEGATION) {
  1783. const char *what;
  1784. isc_boolean_t required = ISC_FALSE;
  1785. if (dns_name_issubdomain(name, owner)) {
  1786. what = "REQUIRED GLUE ";
  1787. required = ISC_TRUE;
  1788. } else if (result == DNS_R_DELEGATION)
  1789. what = "SIBLING GLUE ";
  1790. else
  1791. what = "";
  1792. if (result != DNS_R_DELEGATION || required ||
  1793. DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKSIBLING)) {
  1794. dns_zone_log(zone, level, "%s/NS '%s' has no %s"
  1795. "address records (A or AAAA)",
  1796. ownerbuf, namebuf, what);
  1797. /*
  1798. * Log missing address record.
  1799. */
  1800. if (result == DNS_R_DELEGATION && zone->checkns != NULL)
  1801. (void)(zone->checkns)(zone, name, owner,
  1802. &a, &aaaa);
  1803. /* XXX950 make fatal for 9.5.0. */
  1804. /* answer = ISC_FALSE; */
  1805. }
  1806. } else if (result == DNS_R_CNAME) {
  1807. dns_zone_log(zone, level, "%s/NS '%s' is a CNAME (illegal)",
  1808. ownerbuf, namebuf);
  1809. /* XXX950 make fatal for 9.5.0. */
  1810. /* answer = ISC_FALSE; */
  1811. } else if (result == DNS_R_DNAME) {
  1812. dns_name_format(foundname, altbuf, sizeof altbuf);
  1813. dns_zone_log(zone, level,
  1814. "%s/NS '%s' is below a DNAME '%s' (illegal)",
  1815. ownerbuf, namebuf, altbuf);
  1816. /* XXX950 make fatal for 9.5.0. */
  1817. /* answer = ISC_FALSE; */
  1818. }
  1819. if (dns_rdataset_isassociated(&a))
  1820. dns_rdataset_disassociate(&a);
  1821. if (dns_rdataset_isassociated(&aaaa))
  1822. dns_rdataset_disassociate(&aaaa);
  1823. return (answer);
  1824. }
  1825. static isc_boolean_t
  1826. zone_rrset_check_dup(dns_zone_t *zone, dns_name_t *owner,
  1827. dns_rdataset_t *rdataset)
  1828. {
  1829. dns_rdataset_t tmprdataset;
  1830. isc_result_t result;
  1831. isc_boolean_t answer = ISC_TRUE;
  1832. isc_boolean_t format = ISC_TRUE;
  1833. int level = ISC_LOG_WARNING;
  1834. char ownerbuf[DNS_NAME_FORMATSIZE];
  1835. char typebuf[DNS_RDATATYPE_FORMATSIZE];
  1836. unsigned int count1 = 0;
  1837. if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKDUPRRFAIL))
  1838. level = ISC_LOG_ERROR;
  1839. dns_rdataset_init(&tmprdataset);
  1840. for (result = dns_rdataset_first(rdataset);
  1841. result == ISC_R_SUCCESS;
  1842. result = dns_rdataset_next(rdataset)) {
  1843. dns_rdata_t rdata1 = DNS_RDATA_INIT;
  1844. unsigned int count2 = 0;
  1845. count1++;
  1846. dns_rdataset_current(rdataset, &rdata1);
  1847. dns_rdataset_clone(rdataset, &tmprdataset);
  1848. for (result = dns_rdataset_first(&tmprdataset);
  1849. result == ISC_R_SUCCESS;
  1850. result = dns_rdataset_next(&tmprdataset)) {
  1851. dns_rdata_t rdata2 = DNS_RDATA_INIT;
  1852. count2++;
  1853. if (count1 >= count2)
  1854. continue;
  1855. dns_rdataset_current(&tmprdataset, &rdata2);
  1856. if (dns_rdata_casecompare(&rdata1, &rdata2) == 0) {
  1857. if (format) {
  1858. dns_name_format(owner, ownerbuf,
  1859. sizeof ownerbuf);
  1860. dns_rdatatype_format(rdata1.type,
  1861. typebuf,
  1862. sizeof(typebuf));
  1863. format = ISC_FALSE;
  1864. }
  1865. dns_zone_log(zone, level, "%s/%s has "
  1866. "semantically identical records",
  1867. ownerbuf, typebuf);
  1868. if (level == ISC_LOG_ERROR)
  1869. answer = ISC_FALSE;
  1870. break;
  1871. }
  1872. }
  1873. dns_rdataset_disassociate(&tmprdataset);
  1874. if (!format)
  1875. break;
  1876. }
  1877. return (answer);
  1878. }
  1879. static isc_boolean_t
  1880. zone_check_dup(dns_zone_t *zone, dns_db_t *db) {
  1881. dns_dbiterator_t *dbiterator = NULL;
  1882. dns_dbnode_t *node = NULL;
  1883. dns_fixedname_t fixed;
  1884. dns_name_t *name;
  1885. dns_rdataset_t rdataset;
  1886. dns_rdatasetiter_t *rdsit = NULL;
  1887. isc_boolean_t ok = ISC_TRUE;
  1888. isc_result_t result;
  1889. dns_fixedname_init(&fixed);
  1890. name = dns_fixedname_name(&fixed);
  1891. dns_rdataset_init(&rdataset);
  1892. result = dns_db_createiterator(db, 0, &dbiterator);
  1893. if (result != ISC_R_SUCCESS)
  1894. return (ISC_TRUE);
  1895. for (result = dns_dbiterator_first(dbiterator);
  1896. result == ISC_R_SUCCESS;
  1897. result = dns_dbiterator_next(dbiterator)) {
  1898. result = dns_dbiterator_current(dbiterator, &node, name);
  1899. if (result != ISC_R_SUCCESS)
  1900. continue;
  1901. result = dns_db_allrdatasets(db, node, NULL, 0, &rdsit);
  1902. if (result != ISC_R_SUCCESS)
  1903. continue;
  1904. for (result = dns_rdatasetiter_first(rdsit);
  1905. result == ISC_R_SUCCESS;
  1906. result = dns_rdatasetiter_next(rdsit)) {
  1907. dns_rdatasetiter_current(rdsit, &rdataset);
  1908. if (!zone_rrset_check_dup(zone, name, &rdataset))
  1909. ok = ISC_FALSE;
  1910. dns_rdataset_disassociate(&rdataset);
  1911. }
  1912. dns_rdatasetiter_destroy(&rdsit);
  1913. dns_db_detachnode(db, &node);
  1914. }
  1915. if (node != NULL)
  1916. dns_db_detachnode(db, &node);
  1917. dns_dbiterator_destroy(&dbiterator);
  1918. return (ok);
  1919. }
  1920. static isc_boolean_t
  1921. integrity_checks(dns_zone_t *zone, dns_db_t *db) {
  1922. dns_dbiterator_t *dbiterator = NULL;
  1923. dns_dbnode_t *node = NULL;
  1924. dns_rdataset_t rdataset;
  1925. dns_fixedname_t fixed;
  1926. dns_fixedname_t fixedbottom;
  1927. dns_rdata_mx_t mx;
  1928. dns_rdata_ns_t ns;
  1929. dns_rdata_in_srv_t srv;
  1930. dns_rdata_t rdata;
  1931. dns_name_t *name;
  1932. dns_name_t *bottom;
  1933. isc_result_t result;
  1934. isc_boolean_t ok = ISC_TRUE;
  1935. dns_fixedname_init(&fixed);
  1936. name = dns_fixedname_name(&fixed);
  1937. dns_fixedname_init(&fixedbottom);
  1938. bottom = dns_fixedname_name(&fixedbottom);
  1939. dns_rdataset_init(&rdataset);
  1940. dns_rdata_init(&rdata);
  1941. result = dns_db_createiterator(db, 0, &dbiterator);
  1942. if (result != ISC_R_SUCCESS)
  1943. return (ISC_TRUE);
  1944. result = dns_dbiterator_first(dbiterator);
  1945. while (result == ISC_R_SUCCESS) {
  1946. result = dns_dbiterator_current(dbiterator, &node, name);
  1947. if (result != ISC_R_SUCCESS)
  1948. goto cleanup;
  1949. /*
  1950. * Is this name visible in the zone?
  1951. */
  1952. if (!dns_name_issubdomain(name, &zone->origin) ||
  1953. (dns_name_countlabels(bottom) > 0 &&
  1954. dns_name_issubdomain(name, bottom)))
  1955. goto next;
  1956. /*
  1957. * Don't check the NS records at the origin.
  1958. */
  1959. if (dns_name_equal(name, &zone->origin))
  1960. goto checkmx;
  1961. result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_ns,
  1962. 0, 0, &rdataset, NULL);
  1963. if (result != ISC_R_SUCCESS)
  1964. goto checkmx;
  1965. /*
  1966. * Remember bottom of zone.
  1967. */
  1968. dns_name_copy(name, bottom, NULL);
  1969. result = dns_rdataset_first(&rdataset);
  1970. while (result == ISC_R_SUCCESS) {
  1971. dns_rdataset_current(&rdataset, &rdata);
  1972. result = dns_rdata_tostruct(&rdata, &ns, NULL);
  1973. RUNTIME_CHECK(result == ISC_R_SUCCESS);
  1974. if (!zone_check_glue(zone, db, &ns.name, name))
  1975. ok = ISC_FALSE;
  1976. dns_rdata_reset(&rdata);
  1977. result = dns_rdataset_next(&rdataset);
  1978. }
  1979. dns_rdataset_disassociate(&rdataset);
  1980. goto next;
  1981. checkmx:
  1982. result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_mx,
  1983. 0, 0, &rdataset, NULL);
  1984. if (result != ISC_R_SUCCESS)
  1985. goto checksrv;
  1986. result = dns_rdataset_first(&rdataset);
  1987. while (result == ISC_R_SUCCESS) {
  1988. dns_rdataset_current(&rdataset, &rdata);
  1989. result = dns_rdata_tostruct(&rdata, &mx, NULL);
  1990. RUNTIME_CHECK(result == ISC_R_SUCCESS);
  1991. if (!zone_check_mx(zone, db, &mx.mx, name))
  1992. ok = ISC_FALSE;
  1993. dns_rdata_reset(&rdata);
  1994. result = dns_rdataset_next(&rdataset);
  1995. }
  1996. dns_rdataset_disassociate(&rdataset);
  1997. checksrv:
  1998. if (zone->rdclass != dns_rdataclass_in)
  1999. goto next;
  2000. result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_srv,
  2001. 0, 0, &rdataset, NULL);
  2002. if (result != ISC_R_SUCCESS)
  2003. goto next;
  2004. result = dns_rdataset_first(&rdataset);
  2005. while (result == ISC_R_SUCCESS) {
  2006. dns_rdataset_current(&rdataset, &rdata);
  2007. result = dns_rdata_tostruct(&rdata, &srv, NULL);
  2008. RUNTIME_CHECK(result == ISC_R_SUCCESS);
  2009. if (!zone_check_srv(zone, db, &srv.target, name))
  2010. ok = ISC_FALSE;
  2011. dns_rdata_reset(&rdata);
  2012. result = dns_rdataset_next(&rdataset);
  2013. }
  2014. dns_rdataset_disassociate(&rdataset);
  2015. next:
  2016. dns_db_detachnode(db, &node);
  2017. result = dns_dbiterator_next(dbiterator);
  2018. }
  2019. cleanup:
  2020. if (node != NULL)
  2021. dns_db_detachnode(db, &node);
  2022. dns_dbiterator_destroy(&dbiterator);
  2023. return (ok);
  2024. }
  2025. /*
  2026. * OpenSSL verification of RSA keys with exponent 3 is known to be
  2027. * broken prior OpenSSL 0.9.8c/0.9.7k. Look for such keys and warn
  2028. * if they are in use.
  2029. */
  2030. static void
  2031. zone_check_dnskeys(dns_zone_t *zone, dns_db_t *db) {
  2032. dns_dbnode_t *node = NULL;
  2033. dns_dbversion_t *version = NULL;
  2034. dns_rdata_dnskey_t dnskey;
  2035. dns_rdata_t rdata = DNS_RDATA_INIT;
  2036. dns_rdataset_t rdataset;
  2037. isc_result_t result;
  2038. isc_boolean_t logit, foundrsa = ISC_FALSE, foundmd5 = ISC_FALSE;
  2039. const char *algorithm;
  2040. result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node);
  2041. if (result != ISC_R_SUCCESS)
  2042. goto cleanup;
  2043. dns_db_currentversion(db, &version);
  2044. dns_rdataset_init(&rdataset);
  2045. result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey,
  2046. dns_rdatatype_none, 0, &rdataset, NULL);
  2047. if (result != ISC_R_SUCCESS)
  2048. goto cleanup;
  2049. for (result = dns_rdataset_first(&rdataset);
  2050. result == ISC_R_SUCCESS;
  2051. result = dns_rdataset_next(&rdataset))
  2052. {
  2053. dns_rdataset_current(&rdataset, &rdata);
  2054. result = dns_rdata_tostruct(&rdata, &dnskey, NULL);
  2055. INSIST(result == ISC_R_SUCCESS);
  2056. if ((dnskey.algorithm == DST_ALG_RSASHA1 ||
  2057. dnskey.algorithm == DST_ALG_RSAMD5) &&
  2058. dnskey.datalen > 1 && dnskey.data[0] == 1 &&
  2059. dnskey.data[1] == 3)
  2060. {
  2061. if (dnskey.algorithm == DST_ALG_RSASHA1) {
  2062. logit = !foundrsa;
  2063. foundrsa = ISC_TRUE;
  2064. algorithm = "RSASHA1";
  2065. } else {
  2066. logit = !foundmd5;
  2067. foundmd5 = ISC_TRUE;
  2068. algorithm = "RSAMD5";
  2069. }
  2070. if (logit)
  2071. dns_zone_log(zone, ISC_LOG_WARNING,
  2072. "weak %s (%u) key found "
  2073. "(exponent=3)", algorithm,
  2074. dnskey.algorithm);
  2075. if (foundrsa && foundmd5)
  2076. break;
  2077. }
  2078. dns_rdata_reset(&rdata);
  2079. }
  2080. dns_rdataset_disassociate(&rdataset);
  2081. cleanup:
  2082. if (node != NULL)
  2083. dns_db_detachnode(db, &node);
  2084. if (version != NULL)
  2085. dns_db_closeversion(db, &version, ISC_FALSE);
  2086. }
  2087. static void
  2088. resume_signingwithkey(dns_zone_t *zone) {
  2089. dns_dbnode_t *node = NULL;
  2090. dns_dbversion_t *version = NULL;
  2091. dns_rdata_t rdata = DNS_RDATA_INIT;
  2092. dns_rdataset_t rdataset;
  2093. isc_result_t result;
  2094. result = dns_db_findnode(zone->db, &zone->origin, ISC_FALSE, &node);
  2095. if (result != ISC_R_SUCCESS)
  2096. goto cleanup;
  2097. dns_db_currentversion(zone->db, &version);
  2098. dns_rdataset_init(&rdataset);
  2099. result = dns_db_findrdataset(zone->db, node, version,
  2100. zone->privatetype,
  2101. dns_rdatatype_none, 0,
  2102. &rdataset, NULL);
  2103. if (result != ISC_R_SUCCESS) {
  2104. INSIST(!dns_rdataset_isassociated(&rdataset));
  2105. goto cleanup;
  2106. }
  2107. for (result = dns_rdataset_first(&rdataset);
  2108. result == ISC_R_SUCCESS;
  2109. result = dns_rdataset_next(&rdataset))
  2110. {
  2111. dns_rdataset_current(&rdataset, &rdata);
  2112. if (rdata.length != 5 ||
  2113. rdata.data[0] == 0 || rdata.data[4] != 0) {
  2114. dns_rdata_reset(&rdata);
  2115. continue;
  2116. }
  2117. result = zone_signwithkey(zone, rdata.data[0],
  2118. (rdata.data[1] << 8) | rdata.data[2],
  2119. ISC_TF(rdata.data[3]));
  2120. if (result != ISC_R_SUCCESS) {
  2121. dns_zone_log(zone, ISC_LOG_ERROR,
  2122. "zone_signwithkey failed: %s",
  2123. dns_result_totext(result));
  2124. }
  2125. dns_rdata_reset(&rdata);
  2126. }
  2127. dns_rdataset_disassociate(&rdataset);
  2128. cleanup:
  2129. if (node != NULL)
  2130. dns_db_detachnode(zone->db, &node);
  2131. if (version != NULL)
  2132. dns_db_closeversion(zone->db, &version, ISC_FALSE);
  2133. }
  2134. static isc_result_t
  2135. zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) {
  2136. dns_nsec3chain_t *nsec3chain, *current;
  2137. isc_result_t result;
  2138. isc_time_t now;
  2139. unsigned int options = 0;
  2140. char saltbuf[255*2+1];
  2141. char flags[sizeof("REMOVE|CREATE|NONSEC|OPTOUT")];
  2142. int i;
  2143. nsec3chain = isc_mem_get(zone->mctx, sizeof *nsec3chain);
  2144. if (nsec3chain == NULL)
  2145. return (ISC_R_NOMEMORY);
  2146. nsec3chain->magic = 0;
  2147. nsec3chain->done = ISC_FALSE;
  2148. nsec3chain->db = NULL;
  2149. nsec3chain->dbiterator = NULL;
  2150. nsec3chain->nsec3param.common.rdclass = nsec3param->common.rdclass;
  2151. nsec3chain->nsec3param.common.rdtype = nsec3param->common.rdtype;
  2152. nsec3chain->nsec3param.hash = nsec3param->hash;
  2153. nsec3chain->nsec3param.iterations = nsec3param->iterations;
  2154. nsec3chain->nsec3param.flags = nsec3param->flags;
  2155. nsec3chain->nsec3param.salt_length = nsec3param->salt_length;
  2156. memcpy(nsec3chain->salt, nsec3param->salt, nsec3param->salt_length);
  2157. nsec3chain->nsec3param.salt = nsec3chain->salt;
  2158. nsec3chain->seen_nsec = ISC_FALSE;
  2159. nsec3chain->delete_nsec = ISC_FALSE;
  2160. nsec3chain->save_delete_nsec = ISC_FALSE;
  2161. if (nsec3param->flags == 0)
  2162. strlcpy(flags, "NONE", sizeof(flags));
  2163. else {
  2164. flags[0] = '\0';
  2165. if (nsec3param->flags & DNS_NSEC3FLAG_REMOVE)
  2166. strlcat(flags, "REMOVE", sizeof(flags));
  2167. if (nsec3param->flags & DNS_NSEC3FLAG_CREATE) {
  2168. if (flags[0] == '\0')
  2169. strlcpy(flags, "CREATE", sizeof(flags));
  2170. else
  2171. strlcat(flags, "|CREATE", sizeof(flags));
  2172. }
  2173. if (nsec3param->flags & DNS_NSEC3FLAG_NONSEC) {
  2174. if (flags[0] == '\0')
  2175. strlcpy(flags, "NONSEC", sizeof(flags));
  2176. else
  2177. strlcat(flags, "|NONSEC", sizeof(flags));
  2178. }
  2179. if (nsec3param->flags & DNS_NSEC3FLAG_OPTOUT) {
  2180. if (flags[0] == '\0')
  2181. strlcpy(flags, "OPTOUT", sizeof(flags));
  2182. else
  2183. strlcat(flags, "|OPTOUT", sizeof(flags));
  2184. }
  2185. }
  2186. if (nsec3param->salt_length == 0)
  2187. strlcpy(saltbuf, "-", sizeof(saltbuf));
  2188. else
  2189. for (i = 0; i < nsec3param->salt_length; i++)
  2190. sprintf(&saltbuf[i*2], "%02X", nsec3chain->salt[i]);
  2191. dns_zone_log(zone, ISC_LOG_INFO,
  2192. "zone_addnsec3chain(%u,%s,%u,%s)",
  2193. nsec3param->hash, flags, nsec3param->iterations,
  2194. saltbuf);
  2195. for (current = ISC_LIST_HEAD(zone->nsec3chain);
  2196. current != NULL;
  2197. current = ISC_LIST_NEXT(current, link)) {
  2198. if (current->db == zone->db &&
  2199. current->nsec3param.hash == nsec3param->hash &&
  2200. current->nsec3param.iterations == nsec3param->iterations &&
  2201. current->nsec3param.salt_length == nsec3param->salt_length
  2202. && !memcmp(current->nsec3param.salt, nsec3param->salt,
  2203. nsec3param->salt_length))
  2204. current->done = ISC_TRUE;
  2205. }
  2206. if (zone->db != NULL) {
  2207. dns_db_attach(zone->db, &nsec3chain->db);
  2208. if ((nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0)
  2209. options = DNS_DB_NONSEC3;
  2210. result = dns_db_createiterator(nsec3chain->db, options,
  2211. &nsec3chain->dbiterator);
  2212. if (result == ISC_R_SUCCESS)
  2213. dns_dbiterator_first(nsec3chain->dbiterator);
  2214. if (result == ISC_R_SUCCESS) {
  2215. dns_dbiterator_pause(nsec3chain->dbiterator);
  2216. ISC_LIST_INITANDAPPEND(zone->nsec3chain,
  2217. nsec3chain, link);
  2218. nsec3chain = NULL;
  2219. if (isc_time_isepoch(&zone->nsec3chaintime)) {
  2220. TIME_NOW(&now);
  2221. zone->nsec3chaintime = now;
  2222. if (zone->task != NULL)
  2223. zone_settimer(zone, &now);
  2224. }
  2225. }
  2226. } else
  2227. result = ISC_R_NOTFOUND;
  2228. if (nsec3chain != NULL) {
  2229. if (nsec3chain->db != NULL)
  2230. dns_db_detach(&nsec3chain->db);
  2231. if (nsec3chain->dbiterator != NULL)
  2232. dns_dbiterator_destroy(&nsec3chain->dbiterator);
  2233. isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
  2234. }
  2235. return (result);
  2236. }
  2237. static void
  2238. resume_addnsec3chain(dns_zone_t *zone) {
  2239. dns_dbnode_t *node = NULL;
  2240. dns_dbversion_t *version = NULL;
  2241. dns_rdataset_t rdataset;
  2242. isc_result_t result;
  2243. dns_rdata_nsec3param_t nsec3param;
  2244. if (zone->privatetype == 0)
  2245. return;
  2246. result = dns_db_findnode(zone->db, &zone->origin, ISC_FALSE, &node);
  2247. if (result != ISC_R_SUCCESS)
  2248. goto cleanup;
  2249. dns_db_currentversion(zone->db, &version);
  2250. dns_rdataset_init(&rdataset);
  2251. result = dns_db_findrdataset(zone->db, node, version,
  2252. zone->privatetype, dns_rdatatype_none,
  2253. 0, &rdataset, NULL);
  2254. if (result != ISC_R_SUCCESS) {
  2255. INSIST(!dns_rdataset_isassociated(&rdataset));
  2256. goto cleanup;
  2257. }
  2258. for (result = dns_rdataset_first(&rdataset);
  2259. result == ISC_R_SUCCESS;
  2260. result = dns_rdataset_next(&rdataset))
  2261. {
  2262. unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
  2263. dns_rdata_t rdata = DNS_RDATA_INIT;
  2264. dns_rdata_t private = DNS_RDATA_INIT;
  2265. dns_rdataset_current(&rdataset, &private);
  2266. if (!dns_nsec3param_fromprivate(&private, &rdata, buf,
  2267. sizeof(buf)))
  2268. continue;
  2269. result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
  2270. RUNTIME_CHECK(result == ISC_R_SUCCESS);
  2271. if ((nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0 ||
  2272. (nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) {
  2273. result = zone_addnsec3chain(zone, &nsec3param);
  2274. if (result != ISC_R_SUCCESS) {
  2275. dns_zone_log(zone, ISC_LOG_ERROR,
  2276. "zone_addnsec3chain failed: %s",
  2277. dns_result_totext(result));
  2278. }
  2279. }
  2280. }
  2281. dns_rdataset_disassociate(&rdataset);
  2282. cleanup:
  2283. if (node != NULL)
  2284. dns_db_detachnode(zone->db, &node);
  2285. if (version != NULL)
  2286. dns_db_closeversion(zone->db, &version, ISC_FALSE);
  2287. }
  2288. static void
  2289. set_resigntime(dns_zone_t *zone) {
  2290. dns_rdataset_t rdataset;
  2291. dns_fixedname_t fixed;
  2292. unsigned int resign;
  2293. isc_result_t result;
  2294. isc_uint32_t nanosecs;
  2295. dns_rdataset_init(&rdataset);
  2296. dns_fixedname_init(&fixed);
  2297. result = dns_db_getsigningtime(zone->db, &rdataset,
  2298. dns_fixedname_name(&fixed));
  2299. if (result != ISC_R_SUCCESS) {
  2300. isc_time_settoepoch(&zone->resigntime);
  2301. return;
  2302. }
  2303. resign = rdataset.resign;
  2304. dns_rdataset_disassociate(&rdataset);
  2305. isc_random_get(&nanosecs);
  2306. nanosecs %= 1000000000;
  2307. isc_time_set(&zone->resigntime, resign, nanosecs);
  2308. }
  2309. static isc_result_t
  2310. check_nsec3param(dns_zone_t *zone, dns_db_t *db) {
  2311. dns_dbnode_t *node = NULL;
  2312. dns_rdataset_t rdataset;
  2313. dns_dbversion_t *version = NULL;
  2314. dns_rdata_nsec3param_t nsec3param;
  2315. isc_boolean_t ok = ISC_FALSE;
  2316. isc_result_t result;
  2317. dns_rdata_t rdata = DNS_RDATA_INIT;
  2318. isc_boolean_t dynamic = (zone->type == dns_zone_master) ?
  2319. zone_isdynamic(zone) : ISC_FALSE;
  2320. dns_rdataset_init(&rdataset);
  2321. result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node);
  2322. if (result != ISC_R_SUCCESS) {
  2323. dns_zone_log(zone, ISC_LOG_ERROR,
  2324. "nsec3param lookup failure: %s",
  2325. dns_result_totext(result));
  2326. return (result);
  2327. }
  2328. dns_db_currentversion(db, &version);
  2329. result = dns_db_findrdataset(db, node, version,
  2330. dns_rdatatype_nsec3param,
  2331. dns_rdatatype_none, 0, &rdataset, NULL);
  2332. if (result == ISC_R_NOTFOUND) {
  2333. INSIST(!dns_rdataset_isassociated(&rdataset));
  2334. result = ISC_R_SUCCESS;
  2335. goto cleanup;
  2336. }
  2337. if (result != ISC_R_SUCCESS) {
  2338. INSIST(!dns_rdataset_isassociated(&rdataset));
  2339. dns_zone_log(zone, ISC_LOG_ERROR,
  2340. "nsec3param lookup failure: %s",
  2341. dns_result_totext(result));
  2342. goto cleanup;
  2343. }
  2344. /*
  2345. * For dynamic zones we must support every algorithm so we can
  2346. * regenerate all the NSEC3 chains.
  2347. * For non-dynamic zones we only need to find a supported algorithm.
  2348. */
  2349. for (result = dns_rdataset_first(&rdataset);
  2350. result == ISC_R_SUCCESS;
  2351. result = dns_rdataset_next(&rdataset))
  2352. {
  2353. dns_rdataset_current(&rdataset, &rdata);
  2354. result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
  2355. dns_rdata_reset(&rdata);
  2356. INSIST(result == ISC_R_SUCCESS);
  2357. if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NSEC3TESTZONE) &&
  2358. nsec3param.hash == DNS_NSEC3_UNKNOWNALG && !dynamic)
  2359. {
  2360. dns_zone_log(zone, ISC_LOG_WARNING,
  2361. "nsec3 test \"unknown\" hash algorithm found: %u",
  2362. nsec3param.hash);
  2363. ok = ISC_TRUE;
  2364. } else if (!dns_nsec3_supportedhash(nsec3param.hash)) {
  2365. if (dynamic) {
  2366. dns_zone_log(zone, ISC_LOG_ERROR,
  2367. "unsupported nsec3 hash algorithm"
  2368. " in dynamic zone: %u",
  2369. nsec3param.hash);
  2370. result = DNS_R_BADZONE;
  2371. /* Stop second error message. */
  2372. ok = ISC_TRUE;
  2373. break;
  2374. } else
  2375. dns_zone_log(zone, ISC_LOG_WARNING,
  2376. "unsupported nsec3 hash algorithm: %u",
  2377. nsec3param.hash);
  2378. } else
  2379. ok = ISC_TRUE;
  2380. }
  2381. if (result == ISC_R_NOMORE)
  2382. result = ISC_R_SUCCESS;
  2383. if (!ok) {
  2384. result = DNS_R_BADZONE;
  2385. dns_zone_log(zone, ISC_LOG_ERROR,
  2386. "no supported nsec3 hash algorithm");
  2387. }
  2388. cleanup:
  2389. if (dns_rdataset_isassociated(&rdataset))
  2390. dns_rdataset_disassociate(&rdataset);
  2391. dns_db_closeversion(db, &version, ISC_FALSE);
  2392. dns_db_detachnode(db, &node);
  2393. return (result);
  2394. }
  2395. /*
  2396. * Set the timer for refreshing the key zone to the soonest future time
  2397. * of the set (current timer, keydata->refresh, keydata->addhd,
  2398. * keydata->removehd).
  2399. */
  2400. static void
  2401. set_refreshkeytimer(dns_zone_t *zone, dns_rdata_keydata_t *key,
  2402. isc_stdtime_t now)
  2403. {
  2404. const char me[] = "set_refreshkeytimer";
  2405. isc_stdtime_t then;
  2406. isc_time_t timenow, timethen;
  2407. char timebuf[80];
  2408. ENTER;
  2409. then = key->refresh;
  2410. if (key->addhd > now && key->addhd < then)
  2411. then = key->addhd;
  2412. if (key->removehd > now && key->removehd < then)
  2413. then = key->removehd;
  2414. TIME_NOW(&timenow);
  2415. if (then > now)
  2416. DNS_ZONE_TIME_ADD(&timenow, then - now, &timethen);
  2417. else
  2418. timethen = timenow;
  2419. if (isc_time_compare(&zone->refreshkeytime, &timenow) < 0 ||
  2420. isc_time_compare(&timethen, &zone->refreshkeytime) < 0)
  2421. zone->refreshkeytime = timethen;
  2422. isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
  2423. dns_zone_log(zone, ISC_LOG_DEBUG(1), "next key refresh: %s", timebuf);
  2424. zone_settimer(zone, &timenow);
  2425. }
  2426. /*
  2427. * Convert key(s) linked from 'keynode' to KEYDATA and add to the key zone.
  2428. * If the key zone is changed, set '*changed' to ISC_TRUE.
  2429. */
  2430. static isc_result_t
  2431. create_keydata(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
  2432. dns_diff_t *diff, dns_keytable_t *keytable,
  2433. dns_keynode_t **keynodep, isc_boolean_t *changed)
  2434. {
  2435. const char me[] = "create_keydata";
  2436. isc_result_t result = ISC_R_SUCCESS;
  2437. isc_buffer_t keyb, dstb;
  2438. unsigned char key_buf[4096], dst_buf[DST_KEY_MAXSIZE];
  2439. dns_rdata_keydata_t keydata;
  2440. dns_rdata_dnskey_t dnskey;
  2441. dns_rdata_t rdata = DNS_RDATA_INIT;
  2442. dns_keynode_t *keynode;
  2443. isc_stdtime_t now;
  2444. isc_region_t r;
  2445. dst_key_t *key;
  2446. REQUIRE(keynodep != NULL);
  2447. keynode = *keynodep;
  2448. ENTER;
  2449. isc_stdtime_get(&now);
  2450. /* Loop in case there's more than one key. */
  2451. while (result == ISC_R_SUCCESS) {
  2452. dns_keynode_t *nextnode = NULL;
  2453. key = dns_keynode_key(keynode);
  2454. if (key == NULL)
  2455. goto skip;
  2456. isc_buffer_init(&dstb, dst_buf, sizeof(dst_buf));
  2457. CHECK(dst_key_todns(key, &dstb));
  2458. /* Convert DST key to DNSKEY. */
  2459. dns_rdata_reset(&rdata);
  2460. isc_buffer_usedregion(&dstb, &r);
  2461. dns_rdata_fromregion(&rdata, dst_key_class(key),
  2462. dns_rdatatype_dnskey, &r);
  2463. /* DSTKEY to KEYDATA. */
  2464. CHECK(dns_rdata_tostruct(&rdata, &dnskey, NULL));
  2465. CHECK(dns_keydata_fromdnskey(&keydata, &dnskey, now, 0, 0,
  2466. NULL));
  2467. /* KEYDATA to rdata. */
  2468. dns_rdata_reset(&rdata);
  2469. isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
  2470. CHECK(dns_rdata_fromstruct(&rdata,
  2471. zone->rdclass, dns_rdatatype_keydata,
  2472. &keydata, &keyb));
  2473. /* Add rdata to zone. */
  2474. CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD,
  2475. dst_key_name(key), 0, &rdata));
  2476. *changed = ISC_TRUE;
  2477. skip:
  2478. result = dns_keytable_nextkeynode(keytable, keynode, &nextnode);
  2479. if (result != ISC_R_NOTFOUND) {
  2480. dns_keytable_detachkeynode(keytable, &keynode);
  2481. keynode = nextnode;
  2482. }
  2483. }
  2484. /* Refresh new keys from the zone apex as soon as possible. */
  2485. if (*changed)
  2486. set_refreshkeytimer(zone, &keydata, now);
  2487. if (keynode != NULL)
  2488. dns_keytable_detachkeynode(keytable, &keynode);
  2489. *keynodep = NULL;
  2490. return (ISC_R_SUCCESS);
  2491. failure:
  2492. return (result);
  2493. }
  2494. /*
  2495. * Remove from the key zone all the KEYDATA records found in rdataset.
  2496. */
  2497. static isc_result_t
  2498. delete_keydata(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff,
  2499. dns_name_t *name, dns_rdataset_t *rdataset)
  2500. {
  2501. dns_rdata_t rdata = DNS_RDATA_INIT;
  2502. isc_result_t result, uresult;
  2503. for (result = dns_rdataset_first(rdataset);
  2504. result == ISC_R_SUCCESS;
  2505. result = dns_rdataset_next(rdataset)) {
  2506. dns_rdata_reset(&rdata);
  2507. dns_rdataset_current(rdataset, &rdata);
  2508. uresult = update_one_rr(db, ver, diff, DNS_DIFFOP_DEL,
  2509. name, 0, &rdata);
  2510. if (uresult != ISC_R_SUCCESS)
  2511. return (uresult);
  2512. }
  2513. if (result == ISC_R_NOMORE)
  2514. result = ISC_R_SUCCESS;
  2515. return (result);
  2516. }
  2517. /*
  2518. * Compute the DNSSEC key ID for a DNSKEY record.
  2519. */
  2520. static isc_result_t
  2521. compute_tag(dns_name_t *name, dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx,
  2522. dns_keytag_t *tag)
  2523. {
  2524. isc_result_t result;
  2525. dns_rdata_t rdata = DNS_RDATA_INIT;
  2526. unsigned char data[4096];
  2527. isc_buffer_t buffer;
  2528. dst_key_t *dstkey = NULL;
  2529. isc_buffer_init(&buffer, data, sizeof(data));
  2530. dns_rdata_fromstruct(&rdata, dnskey->common.rdclass,
  2531. dns_rdatatype_dnskey, dnskey, &buffer);
  2532. result = dns_dnssec_keyfromrdata(name, &rdata, mctx, &dstkey);
  2533. if (result == ISC_R_SUCCESS)
  2534. *tag = dst_key_id(dstkey);
  2535. dst_key_free(&dstkey);
  2536. return (result);
  2537. }
  2538. /*
  2539. * Add key to the security roots.
  2540. */
  2541. static void
  2542. trust_key(dns_zone_t *zone, dns_name_t *keyname,
  2543. dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx) {
  2544. isc_result_t result;
  2545. dns_rdata_t rdata = DNS_RDATA_INIT;
  2546. unsigned char data[4096];
  2547. isc_buffer_t buffer;
  2548. dns_keytable_t *sr = NULL;
  2549. dst_key_t *dstkey = NULL;
  2550. /* Convert dnskey to DST key. */
  2551. isc_buffer_init(&buffer, data, sizeof(data));
  2552. dns_rdata_fromstruct(&rdata, dnskey->common.rdclass,
  2553. dns_rdatatype_dnskey, dnskey, &buffer);
  2554. result = dns_view_getsecroots(zone->view, &sr);
  2555. if (result != ISC_R_SUCCESS)
  2556. goto failure;
  2557. CHECK(dns_dnssec_keyfromrdata(keyname, &rdata, mctx, &dstkey));
  2558. CHECK(dns_keytable_add(sr, ISC_TRUE, &dstkey));
  2559. dns_keytable_detach(&sr);
  2560. failure:
  2561. if (dstkey != NULL)
  2562. dst_key_free(&dstkey);
  2563. if (sr != NULL)
  2564. dns_keytable_detach(&sr);
  2565. return;
  2566. }
  2567. /*
  2568. * Add a null key to the security roots for so that all queries
  2569. * to the zone will fail.
  2570. */
  2571. static void
  2572. fail_secure(dns_zone_t *zone, dns_name_t *keyname) {
  2573. isc_result_t result;
  2574. dns_keytable_t *sr = NULL;
  2575. result = dns_view_getsecroots(zone->view, &sr);
  2576. if (result == ISC_R_SUCCESS) {
  2577. dns_keytable_marksecure(sr, keyname);
  2578. dns_keytable_detach(&sr);
  2579. }
  2580. }
  2581. /*
  2582. * Scan a set of KEYDATA records from the key zone. The ones that are
  2583. * valid (i.e., the add holddown timer has expired) become trusted keys.
  2584. */
  2585. static void
  2586. load_secroots(dns_zone_t *zone, dns_name_t *name, dns_rdataset_t *rdataset) {
  2587. isc_result_t result;
  2588. dns_rdata_t rdata = DNS_RDATA_INIT;
  2589. dns_rdata_keydata_t keydata;
  2590. dns_rdata_dnskey_t dnskey;
  2591. isc_mem_t *mctx = zone->mctx;
  2592. int trusted = 0, revoked = 0, pending = 0;
  2593. isc_stdtime_t now;
  2594. dns_keytable_t *sr = NULL;
  2595. isc_stdtime_get(&now);
  2596. result = dns_view_getsecroots(zone->view, &sr);
  2597. if (result == ISC_R_SUCCESS) {
  2598. dns_keytable_delete(sr, name);
  2599. dns_keytable_detach(&sr);
  2600. }
  2601. /* Now insert all the accepted trust anchors from this keydata set. */
  2602. for (result = dns_rdataset_first(rdataset);
  2603. result == ISC_R_SUCCESS;
  2604. result = dns_rdataset_next(rdataset)) {
  2605. dns_rdata_reset(&rdata);
  2606. dns_rdataset_current(rdataset, &rdata);
  2607. /* Convert rdata to keydata. */
  2608. dns_rdata_tostruct(&rdata, &keydata, NULL);
  2609. /* Set the key refresh timer. */
  2610. set_refreshkeytimer(zone, &keydata, now);
  2611. /* If the removal timer is nonzero, this key was revoked. */
  2612. if (keydata.removehd != 0) {
  2613. revoked++;
  2614. continue;
  2615. }
  2616. /*
  2617. * If the add timer is still pending, this key is not
  2618. * trusted yet.
  2619. */
  2620. if (now < keydata.addhd) {
  2621. pending++;
  2622. continue;
  2623. }
  2624. /* Convert keydata to dnskey. */
  2625. dns_keydata_todnskey(&keydata, &dnskey, NULL);
  2626. /* Add to keytables. */
  2627. trusted++;
  2628. trust_key(zone, name, &dnskey, mctx);
  2629. }
  2630. if (trusted == 0 && pending != 0) {
  2631. char namebuf[DNS_NAME_FORMATSIZE];
  2632. dns_name_format(name, namebuf, sizeof namebuf);
  2633. dns_zone_log(zone, ISC_LOG_ERROR,
  2634. "No valid trust anchors for '%s'!", namebuf);
  2635. dns_zone_log(zone, ISC_LOG_ERROR,
  2636. "%d key(s) revoked, %d still pending",
  2637. revoked, pending);
  2638. dns_zone_log(zone, ISC_LOG_ERROR,
  2639. "All queries to '%s' will fail", namebuf);
  2640. fail_secure(zone, name);
  2641. }
  2642. }
  2643. static isc_result_t
  2644. do_one_tuple(dns_difftuple_t **tuple, dns_db_t *db, dns_dbversion_t *ver,
  2645. dns_diff_t *diff)
  2646. {
  2647. dns_diff_t temp_diff;
  2648. isc_result_t result;
  2649. /*
  2650. * Create a singleton diff.
  2651. */
  2652. dns_diff_init(diff->mctx, &temp_diff);
  2653. temp_diff.resign = diff->resign;
  2654. ISC_LIST_APPEND(temp_diff.tuples, *tuple, link);
  2655. /*
  2656. * Apply it to the database.
  2657. */
  2658. result = dns_diff_apply(&temp_diff, db, ver);
  2659. ISC_LIST_UNLINK(temp_diff.tuples, *tuple, link);
  2660. if (result != ISC_R_SUCCESS) {
  2661. dns_difftuple_free(tuple);
  2662. return (result);
  2663. }
  2664. /*
  2665. * Merge it into the current pending journal entry.
  2666. */
  2667. dns_diff_appendminimal(diff, tuple);
  2668. /*
  2669. * Do not clear temp_diff.
  2670. */
  2671. return (ISC_R_SUCCESS);
  2672. }
  2673. static isc_result_t
  2674. update_one_rr(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff,
  2675. dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl,
  2676. dns_rdata_t *rdata)
  2677. {
  2678. dns_difftuple_t *tuple = NULL;
  2679. isc_result_t result;
  2680. result = dns_difftuple_create(diff->mctx, op,
  2681. name, ttl, rdata, &tuple);
  2682. if (result != ISC_R_SUCCESS)
  2683. return (result);
  2684. return (do_one_tuple(&tuple, db, ver, diff));
  2685. }
  2686. static isc_result_t
  2687. increment_soa_serial(dns_db_t *db, dns_dbversion_t *ver,
  2688. dns_diff_t *diff, isc_mem_t *mctx) {
  2689. dns_difftuple_t *deltuple = NULL;
  2690. dns_difftuple_t *addtuple = NULL;
  2691. isc_uint32_t serial;
  2692. isc_result_t result;
  2693. CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_DEL, &deltuple));
  2694. CHECK(dns_difftuple_copy(deltuple, &addtuple));
  2695. addtuple->op = DNS_DIFFOP_ADD;
  2696. serial = dns_soa_getserial(&addtuple->rdata);
  2697. /* RFC1982 */
  2698. serial = (serial + 1) & 0xFFFFFFFF;
  2699. if (serial == 0)
  2700. serial = 1;
  2701. dns_soa_setserial(serial, &addtuple->rdata);
  2702. CHECK(do_one_tuple(&deltuple, db, ver, diff));
  2703. CHECK(do_one_tuple(&addtuple, db, ver, diff));
  2704. result = ISC_R_SUCCESS;
  2705. failure:
  2706. if (addtuple != NULL)
  2707. dns_difftuple_free(&addtuple);
  2708. if (deltuple != NULL)
  2709. dns_difftuple_free(&deltuple);
  2710. return (result);
  2711. }
  2712. /*
  2713. * Write all transactions in 'diff' to the zone journal file.
  2714. */
  2715. static isc_result_t
  2716. zone_journal(dns_zone_t *zone, dns_diff_t *diff, const char *caller) {
  2717. const char me[] = "zone_journal";
  2718. const char *journalfile;
  2719. isc_result_t result = ISC_R_SUCCESS;
  2720. dns_journal_t *journal = NULL;
  2721. ENTER;
  2722. journalfile = dns_zone_getjournal(zone);
  2723. if (journalfile != NULL) {
  2724. result = dns_journal_open(zone->mctx, journalfile,
  2725. ISC_TRUE, &journal);
  2726. if (result != ISC_R_SUCCESS) {
  2727. dns_zone_log(zone, ISC_LOG_ERROR,
  2728. "%s:dns_journal_open -> %s\n",
  2729. caller, dns_result_totext(result));
  2730. return (result);
  2731. }
  2732. result = dns_journal_write_transaction(journal, diff);
  2733. dns_journal_destroy(&journal);
  2734. if (result != ISC_R_SUCCESS) {
  2735. dns_zone_log(zone, ISC_LOG_ERROR,
  2736. "%s:dns_journal_write_transaction -> %s\n",
  2737. caller, dns_result_totext(result));
  2738. return (result);
  2739. }
  2740. }
  2741. return (result);
  2742. }
  2743. /*
  2744. * Create an SOA record for a newly-created zone
  2745. */
  2746. static isc_result_t
  2747. add_soa(dns_zone_t *zone, dns_db_t *db) {
  2748. isc_result_t result;
  2749. dns_rdata_t rdata = DNS_RDATA_INIT;
  2750. unsigned char buf[DNS_SOA_BUFFERSIZE];
  2751. dns_dbversion_t *ver = NULL;
  2752. dns_diff_t diff;
  2753. dns_zone_log(zone, ISC_LOG_DEBUG(1), "creating SOA");
  2754. dns_diff_init(zone->mctx, &diff);
  2755. result = dns_db_newversion(db, &ver);
  2756. if (result != ISC_R_SUCCESS) {
  2757. dns_zone_log(zone, ISC_LOG_ERROR,
  2758. "add_soa:dns_db_newversion -> %s\n",
  2759. dns_result_totext(result));
  2760. goto failure;
  2761. }
  2762. /* Build SOA record */
  2763. result = dns_soa_buildrdata(&zone->origin, dns_rootname, zone->rdclass,
  2764. 0, 0, 0, 0, 0, buf, &rdata);
  2765. if (result != ISC_R_SUCCESS) {
  2766. dns_zone_log(zone, ISC_LOG_ERROR,
  2767. "add_soa:dns_soa_buildrdata -> %s\n",
  2768. dns_result_totext(result));
  2769. goto failure;
  2770. }
  2771. result = update_one_rr(db, ver, &diff, DNS_DIFFOP_ADD,
  2772. &zone->origin, 0, &rdata);
  2773. failure:
  2774. dns_diff_clear(&diff);
  2775. if (ver != NULL)
  2776. dns_db_closeversion(db, &ver, ISC_TF(result == ISC_R_SUCCESS));
  2777. return (result);
  2778. }
  2779. /*
  2780. * Synchronize the set of initializing keys found in managed-keys {}
  2781. * statements with the set of trust anchors found in the managed-keys.bind
  2782. * zone. If a domain is no longer named in managed-keys, delete all keys
  2783. * from that domain from the key zone. If a domain is mentioned in in
  2784. * managed-keys but there are no references to it in the key zone, load
  2785. * the key zone with the initializing key(s) for that domain.
  2786. */
  2787. static isc_result_t
  2788. sync_keyzone(dns_zone_t *zone, dns_db_t *db) {
  2789. isc_result_t result = ISC_R_SUCCESS;
  2790. isc_boolean_t changed = ISC_FALSE;
  2791. isc_boolean_t commit = ISC_FALSE;
  2792. dns_rbtnodechain_t chain;
  2793. dns_fixedname_t fn;
  2794. dns_name_t foundname, *origin;
  2795. dns_keynode_t *keynode = NULL;
  2796. dns_view_t *view = zone->view;
  2797. dns_keytable_t *sr = NULL;
  2798. dns_dbversion_t *ver = NULL;
  2799. dns_diff_t diff;
  2800. dns_rriterator_t rrit;
  2801. dns_zone_log(zone, ISC_LOG_DEBUG(1), "synchronizing trusted keys");
  2802. dns_name_init(&foundname, NULL);
  2803. dns_fixedname_init(&fn);
  2804. origin = dns_fixedname_name(&fn);
  2805. dns_diff_init(zone->mctx, &diff);
  2806. CHECK(dns_view_getsecroots(view, &sr));
  2807. result = dns_db_newversion(db, &ver);
  2808. if (result != ISC_R_SUCCESS) {
  2809. dns_zone_log(zone, ISC_LOG_ERROR,
  2810. "sync_keyzone:dns_db_newversion -> %s\n",
  2811. dns_result_totext(result));
  2812. goto failure;
  2813. }
  2814. /*
  2815. * Walk the zone DB. If we find any keys whose names are no longer
  2816. * in managed-keys (or *are* in trusted-keys, meaning they are
  2817. * permanent and not RFC5011-maintained), delete them from the
  2818. * zone. Otherwise call load_secroots(), which loads keys into
  2819. * secroots as appropriate.
  2820. */
  2821. dns_rriterator_init(&rrit, db, ver, 0);
  2822. for (result = dns_rriterator_first(&rrit);
  2823. result == ISC_R_SUCCESS;
  2824. result = dns_rriterator_nextrrset(&rrit)) {
  2825. dns_rdataset_t *rdataset = NULL;
  2826. dns_name_t *rrname = NULL;
  2827. isc_uint32_t ttl;
  2828. dns_rriterator_current(&rrit, &rrname, &ttl,
  2829. &rdataset, NULL);
  2830. if (!dns_rdataset_isassociated(rdataset)) {
  2831. dns_rriterator_destroy(&rrit);
  2832. goto failure;
  2833. }
  2834. if (rdataset->type != dns_rdatatype_keydata)
  2835. continue;
  2836. result = dns_keytable_find(sr, rrname, &keynode);
  2837. if ((result != ISC_R_SUCCESS &&
  2838. result != DNS_R_PARTIALMATCH) ||
  2839. dns_keynode_managed(keynode) == ISC_FALSE) {
  2840. CHECK(delete_keydata(db, ver, &diff,
  2841. rrname, rdataset));
  2842. changed = ISC_TRUE;
  2843. } else {
  2844. load_secroots(zone, rrname, rdataset);
  2845. }
  2846. if (keynode != NULL)
  2847. dns_keytable_detachkeynode(sr, &keynode);
  2848. }
  2849. dns_rriterator_destroy(&rrit);
  2850. /*
  2851. * Now walk secroots to find any managed keys that aren't
  2852. * in the zone. If we find any, we add them to the zone.
  2853. */
  2854. RWLOCK(&sr->rwlock, isc_rwlocktype_write);
  2855. dns_rbtnodechain_init(&chain, zone->mctx);
  2856. result = dns_rbtnodechain_first(&chain, sr->table, &foundname, origin);
  2857. if (result == ISC_R_NOTFOUND)
  2858. result = ISC_R_NOMORE;
  2859. while (result == DNS_R_NEWORIGIN || result == ISC_R_SUCCESS) {
  2860. dns_rbtnode_t *rbtnode = NULL;
  2861. dns_rbtnodechain_current(&chain, &foundname, origin, &rbtnode);
  2862. if (rbtnode->data == NULL)
  2863. goto skip;
  2864. dns_keytable_attachkeynode(sr, rbtnode->data, &keynode);
  2865. if (dns_keynode_managed(keynode)) {
  2866. dns_fixedname_t fname;
  2867. dns_name_t *keyname;
  2868. dst_key_t *key;
  2869. key = dns_keynode_key(keynode);
  2870. dns_fixedname_init(&fname);
  2871. if (key == NULL) /* fail_secure() was called. */
  2872. goto skip;
  2873. keyname = dst_key_name(key);
  2874. result = dns_db_find(db, keyname, ver,
  2875. dns_rdatatype_keydata,
  2876. DNS_DBFIND_NOWILD, 0, NULL,
  2877. dns_fixedname_name(&fname),
  2878. NULL, NULL);
  2879. if (result != ISC_R_SUCCESS)
  2880. result = create_keydata(zone, db, ver, &diff,
  2881. sr, &keynode, &changed);
  2882. if (result != ISC_R_SUCCESS)
  2883. break;
  2884. }
  2885. skip:
  2886. result = dns_rbtnodechain_next(&chain, &foundname, origin);
  2887. if (keynode != NULL)
  2888. dns_keytable_detachkeynode(sr, &keynode);
  2889. }
  2890. RWUNLOCK(&sr->rwlock, isc_rwlocktype_write);
  2891. if (result == ISC_R_NOMORE)
  2892. result = ISC_R_SUCCESS;
  2893. if (changed) {
  2894. /* Write changes to journal file. */
  2895. CHECK(increment_soa_serial(db, ver, &diff, zone->mctx));
  2896. CHECK(zone_journal(zone, &diff, "sync_keyzone"));
  2897. DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
  2898. zone_needdump(zone, 30);
  2899. commit = ISC_TRUE;
  2900. }
  2901. failure:
  2902. if (keynode != NULL)
  2903. dns_keytable_detachkeynode(sr, &keynode);
  2904. if (sr != NULL)
  2905. dns_keytable_detach(&sr);
  2906. if (ver != NULL)
  2907. dns_db_closeversion(db, &ver, commit);
  2908. dns_diff_clear(&diff);
  2909. return (result);
  2910. }
  2911. static isc_result_t
  2912. zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
  2913. isc_result_t result)
  2914. {
  2915. unsigned int soacount = 0;
  2916. unsigned int nscount = 0;
  2917. unsigned int errors = 0;
  2918. isc_uint32_t serial, oldserial, refresh, retry, expire, minimum;
  2919. isc_time_t now;
  2920. isc_boolean_t needdump = ISC_FALSE;
  2921. isc_boolean_t hasinclude = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE);
  2922. isc_boolean_t nomaster = ISC_FALSE;
  2923. unsigned int options;
  2924. TIME_NOW(&now);
  2925. /*
  2926. * Initiate zone transfer? We may need a error code that
  2927. * indicates that the "permanent" form does not exist.
  2928. * XXX better error feedback to log.
  2929. */
  2930. if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE) {
  2931. if (zone->type == dns_zone_slave ||
  2932. zone->type == dns_zone_stub) {
  2933. if (result == ISC_R_FILENOTFOUND)
  2934. dns_zone_log(zone, ISC_LOG_DEBUG(1),
  2935. "no master file");
  2936. else if (result != DNS_R_NOMASTERFILE)
  2937. dns_zone_log(zone, ISC_LOG_ERROR,
  2938. "loading from master file %s "
  2939. "failed: %s",
  2940. zone->masterfile,
  2941. dns_result_totext(result));
  2942. } else {
  2943. int level = ISC_LOG_ERROR;
  2944. if (zone->type == dns_zone_key &&
  2945. result == ISC_R_FILENOTFOUND)
  2946. level = ISC_LOG_DEBUG(1);
  2947. dns_zone_log(zone, level,
  2948. "loading from master file %s failed: %s",
  2949. zone->masterfile,
  2950. dns_result_totext(result));
  2951. nomaster = ISC_TRUE;
  2952. }
  2953. if (zone->type != dns_zone_key)
  2954. goto cleanup;
  2955. }
  2956. dns_zone_log(zone, ISC_LOG_DEBUG(2),
  2957. "number of nodes in database: %u",
  2958. dns_db_nodecount(db));
  2959. if (result == DNS_R_SEENINCLUDE)
  2960. DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HASINCLUDE);
  2961. else
  2962. DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HASINCLUDE);
  2963. /*
  2964. * If there's no master file for a key zone, then the zone is new:
  2965. * create an SOA record. (We do this now, instead of later, so that
  2966. * if there happens to be a journal file, we can roll forward from
  2967. * a sane starting point.)
  2968. */
  2969. if (nomaster && zone->type == dns_zone_key) {
  2970. result = add_soa(zone, db);
  2971. if (result != ISC_R_SUCCESS)
  2972. goto cleanup;
  2973. }
  2974. /*
  2975. * Apply update log, if any, on initial load.
  2976. */
  2977. if (zone->journal != NULL &&
  2978. ! DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOMERGE) &&
  2979. ! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
  2980. {
  2981. if (zone->type == dns_zone_master &&
  2982. (zone->update_acl != NULL || zone->ssutable != NULL))
  2983. options = DNS_JOURNALOPT_RESIGN;
  2984. else
  2985. options = 0;
  2986. result = dns_journal_rollforward2(zone->mctx, db, options,
  2987. zone->sigresigninginterval,
  2988. zone->journal);
  2989. if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND &&
  2990. result != DNS_R_UPTODATE && result != DNS_R_NOJOURNAL &&
  2991. result != ISC_R_RANGE) {
  2992. dns_zone_log(zone, ISC_LOG_ERROR,
  2993. "journal rollforward failed: %s",
  2994. dns_result_totext(result));
  2995. goto cleanup;
  2996. }
  2997. if (result == ISC_R_NOTFOUND || result == ISC_R_RANGE) {
  2998. dns_zone_log(zone, ISC_LOG_ERROR,
  2999. "journal rollforward failed: "
  3000. "journal out of sync with zone");
  3001. goto cleanup;
  3002. }
  3003. dns_zone_log(zone, ISC_LOG_DEBUG(1),
  3004. "journal rollforward completed "
  3005. "successfully: %s",
  3006. dns_result_totext(result));
  3007. if (result == ISC_R_SUCCESS)
  3008. needdump = ISC_TRUE;
  3009. }
  3010. dns_zone_log(zone, ISC_LOG_DEBUG(1), "loaded; checking validity");
  3011. /*
  3012. * Obtain ns, soa and cname counts for top of zone.
  3013. */
  3014. INSIST(db != NULL);
  3015. result = zone_get_from_db(zone, db, &nscount, &soacount, &serial,
  3016. &refresh, &retry, &expire, &minimum,
  3017. &errors);
  3018. if (result != ISC_R_SUCCESS && zone->type != dns_zone_key) {
  3019. dns_zone_log(zone, ISC_LOG_ERROR,
  3020. "could not find NS and/or SOA records");
  3021. }
  3022. /*
  3023. * Master / Slave / Stub zones require both NS and SOA records at
  3024. * the top of the zone.
  3025. */
  3026. switch (zone->type) {
  3027. case dns_zone_dlz:
  3028. case dns_zone_master:
  3029. case dns_zone_slave:
  3030. case dns_zone_stub:
  3031. if (soacount != 1) {
  3032. dns_zone_log(zone, ISC_LOG_ERROR,
  3033. "has %d SOA records", soacount);
  3034. result = DNS_R_BADZONE;
  3035. }
  3036. if (nscount == 0) {
  3037. dns_zone_log(zone, ISC_LOG_ERROR,
  3038. "has no NS records");
  3039. result = DNS_R_BADZONE;
  3040. }
  3041. if (result != ISC_R_SUCCESS)
  3042. goto cleanup;
  3043. if (zone->type == dns_zone_master && errors != 0) {
  3044. result = DNS_R_BADZONE;
  3045. goto cleanup;
  3046. }
  3047. if (zone->type != dns_zone_stub) {
  3048. result = check_nsec3param(zone, db);
  3049. if (result != ISC_R_SUCCESS)
  3050. goto cleanup;
  3051. }
  3052. if (zone->type == dns_zone_master &&
  3053. DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKINTEGRITY) &&
  3054. !integrity_checks(zone, db)) {
  3055. result = DNS_R_BADZONE;
  3056. goto cleanup;
  3057. }
  3058. if (zone->type == dns_zone_master &&
  3059. DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKDUPRR) &&
  3060. !zone_check_dup(zone, db)) {
  3061. result = DNS_R_BADZONE;
  3062. goto cleanup;
  3063. }
  3064. if (zone->db != NULL) {
  3065. /*
  3066. * This is checked in zone_replacedb() for slave zones
  3067. * as they don't reload from disk.
  3068. */
  3069. result = zone_get_from_db(zone, zone->db, NULL, NULL,
  3070. &oldserial, NULL, NULL, NULL,
  3071. NULL, NULL);
  3072. RUNTIME_CHECK(result == ISC_R_SUCCESS);
  3073. if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) &&
  3074. !isc_serial_gt(serial, oldserial)) {
  3075. isc_uint32_t serialmin, serialmax;
  3076. INSIST(zone->type == dns_zone_master);
  3077. serialmin = (oldserial + 1) & 0xffffffffU;
  3078. serialmax = (oldserial + 0x7fffffffU) &
  3079. 0xffffffffU;
  3080. dns_zone_log(zone, ISC_LOG_ERROR,
  3081. "ixfr-from-differences: "
  3082. "new serial (%u) out of range "
  3083. "[%u - %u]", serial, serialmin,
  3084. serialmax);
  3085. result = DNS_R_BADZONE;
  3086. goto cleanup;
  3087. } else if (!isc_serial_ge(serial, oldserial))
  3088. dns_zone_log(zone, ISC_LOG_ERROR,
  3089. "zone serial (%u/%u) has gone "
  3090. "backwards", serial, oldserial);
  3091. else if (serial == oldserial && !hasinclude &&
  3092. strcmp(zone->db_argv[0], "_builtin") != 0)
  3093. dns_zone_log(zone, ISC_LOG_ERROR,
  3094. "zone serial (%u) unchanged. "
  3095. "zone may fail to transfer "
  3096. "to slaves.", serial);
  3097. }
  3098. if (zone->type == dns_zone_master &&
  3099. (zone->update_acl != NULL || zone->ssutable != NULL) &&
  3100. zone->sigresigninginterval < (3 * refresh) &&
  3101. dns_db_issecure(db))
  3102. {
  3103. dns_zone_log(zone, ISC_LOG_WARNING,
  3104. "sig-re-signing-interval less than "
  3105. "3 * refresh.");
  3106. }
  3107. zone->refresh = RANGE(refresh,
  3108. zone->minrefresh, zone->maxrefresh);
  3109. zone->retry = RANGE(retry,
  3110. zone->minretry, zone->maxretry);
  3111. zone->expire = RANGE(expire, zone->refresh + zone->retry,
  3112. DNS_MAX_EXPIRE);
  3113. zone->minimum = minimum;
  3114. DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
  3115. if (zone->type == dns_zone_slave ||
  3116. zone->type == dns_zone_stub) {
  3117. isc_time_t t;
  3118. isc_uint32_t delay;
  3119. result = isc_file_getmodtime(zone->journal, &t);
  3120. if (result != ISC_R_SUCCESS)
  3121. result = isc_file_getmodtime(zone->masterfile,
  3122. &t);
  3123. if (result == ISC_R_SUCCESS)
  3124. DNS_ZONE_TIME_ADD(&t, zone->expire,
  3125. &zone->expiretime);
  3126. else
  3127. DNS_ZONE_TIME_ADD(&now, zone->retry,
  3128. &zone->expiretime);
  3129. delay = isc_random_jitter(zone->retry,
  3130. (zone->retry * 3) / 4);
  3131. DNS_ZONE_TIME_ADD(&now, delay, &zone->refreshtime);
  3132. if (isc_time_compare(&zone->refreshtime,
  3133. &zone->expiretime) >= 0)
  3134. zone->refreshtime = now;
  3135. }
  3136. break;
  3137. case dns_zone_key:
  3138. result = sync_keyzone(zone, db);
  3139. if (result != ISC_R_SUCCESS)
  3140. goto cleanup;
  3141. break;
  3142. default:
  3143. UNEXPECTED_ERROR(__FILE__, __LINE__,
  3144. "unexpected zone type %d", zone->type);
  3145. result = ISC_R_UNEXPECTED;
  3146. goto cleanup;
  3147. }
  3148. /*
  3149. * Check for weak DNSKEY's.
  3150. */
  3151. if (zone->type == dns_zone_master)
  3152. zone_check_dnskeys(zone, db);
  3153. /*
  3154. * Schedule DNSSEC key refresh.
  3155. */
  3156. if (zone->type == dns_zone_master &&
  3157. DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN))
  3158. zone->refreshkeytime = now;
  3159. #if 0
  3160. /* destroy notification example. */
  3161. {
  3162. isc_event_t *e = isc_event_allocate(zone->mctx, NULL,
  3163. DNS_EVENT_DBDESTROYED,
  3164. dns_zonemgr_dbdestroyed,
  3165. zone,
  3166. sizeof(isc_event_t));
  3167. dns_db_ondestroy(db, zone->task, &e);
  3168. }
  3169. #endif
  3170. ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
  3171. if (zone->db != NULL) {
  3172. result = zone_replacedb(zone, db, ISC_FALSE);
  3173. ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
  3174. if (result != ISC_R_SUCCESS)
  3175. goto cleanup;
  3176. } else {
  3177. zone_attachdb(zone, db);
  3178. ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
  3179. DNS_ZONE_SETFLAG(zone,
  3180. DNS_ZONEFLG_LOADED|DNS_ZONEFLG_NEEDNOTIFY);
  3181. }
  3182. result = ISC_R_SUCCESS;
  3183. if (needdump) {
  3184. if (zone->type == dns_zone_key)
  3185. zone_needdump(zone, 30);
  3186. else
  3187. zone_needdump(zone, DNS_DUMP_DELAY);
  3188. }
  3189. if (zone->task != NULL) {
  3190. if (zone->type == dns_zone_master) {
  3191. set_resigntime(zone);
  3192. resume_signingwithkey(zone);
  3193. resume_addnsec3chain(zone);
  3194. }
  3195. if (zone->type == dns_zone_master &&
  3196. zone_isdynamic(zone) &&
  3197. dns_db_issecure(db)) {
  3198. dns_name_t *name;
  3199. dns_fixedname_t fixed;
  3200. dns_rdataset_t next;
  3201. dns_rdataset_init(&next);
  3202. dns_fixedname_init(&fixed);
  3203. name = dns_fixedname_name(&fixed);
  3204. result = dns_db_getsigningtime(db, &next, name);
  3205. if (result == ISC_R_SUCCESS) {
  3206. isc_stdtime_t timenow;
  3207. char namebuf[DNS_NAME_FORMATSIZE];
  3208. char typebuf[DNS_RDATATYPE_FORMATSIZE];
  3209. isc_stdtime_get(&timenow);
  3210. dns_name_format(name, namebuf, sizeof(namebuf));
  3211. dns_rdatatype_format(next.covers,
  3212. typebuf, sizeof(typebuf));
  3213. dns_zone_log(zone, ISC_LOG_DEBUG(3),
  3214. "next resign: %s/%s in %d seconds",
  3215. namebuf, typebuf,
  3216. next.resign - timenow);
  3217. dns_rdataset_disassociate(&next);
  3218. } else
  3219. dns_zone_log(zone, ISC_LOG_WARNING,
  3220. "signed dynamic zone has no "
  3221. "resign event scheduled");
  3222. }
  3223. zone_settimer(zone, &now);
  3224. }
  3225. if (! dns_db_ispersistent(db))
  3226. dns_zone_log(zone, ISC_LOG_INFO, "loaded serial %u%s", serial,
  3227. dns_db_issecure(db) ? " (DNSSEC signed)" : "");
  3228. zone->loadtime = loadtime;
  3229. return (result);
  3230. cleanup:
  3231. if (zone->type == dns_zone_slave ||
  3232. zone->type == dns_zone_stub ||
  3233. zone->type == dns_zone_key) {
  3234. if (zone->journal != NULL)
  3235. zone_saveunique(zone, zone->journal, "jn-XXXXXXXX");
  3236. if (zone->masterfile != NULL)
  3237. zone_saveunique(zone, zone->masterfile, "db-XXXXXXXX");
  3238. /* Mark the zone for immediate refresh. */
  3239. zone->refreshtime = now;
  3240. if (zone->task != NULL)
  3241. zone_settimer(zone, &now);
  3242. result = ISC_R_SUCCESS;
  3243. } else if (zone->type == dns_zone_master)
  3244. dns_zone_log(zone, ISC_LOG_ERROR, "not loaded due to errors.");
  3245. return (result);
  3246. }
  3247. static isc_boolean_t
  3248. exit_check(dns_zone_t *zone) {
  3249. REQUIRE(LOCKED_ZONE(zone));
  3250. if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SHUTDOWN) &&
  3251. zone->irefs == 0)
  3252. {
  3253. /*
  3254. * DNS_ZONEFLG_SHUTDOWN can only be set if erefs == 0.
  3255. */
  3256. INSIST(isc_refcount_current(&zone->erefs) == 0);
  3257. return (ISC_TRUE);
  3258. }
  3259. return (ISC_FALSE);
  3260. }
  3261. static isc_boolean_t
  3262. zone_check_ns(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
  3263. dns_name_t *name, isc_boolean_t logit)
  3264. {
  3265. isc_result_t result;
  3266. char namebuf[DNS_NAME_FORMATSIZE];
  3267. char altbuf[DNS_NAME_FORMATSIZE];
  3268. dns_fixedname_t fixed;
  3269. dns_name_t *foundname;
  3270. int level;
  3271. if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOCHECKNS))
  3272. return (ISC_TRUE);
  3273. if (zone->type == dns_zone_master)
  3274. level = ISC_LOG_ERROR;
  3275. else
  3276. level = ISC_LOG_WARNING;
  3277. dns_fixedname_init(&fixed);
  3278. foundname = dns_fixedname_name(&fixed);
  3279. result = dns_db_find(db, name, version, dns_rdatatype_a,
  3280. 0, 0, NULL, foundname, NULL, NULL);
  3281. if (result == ISC_R_SUCCESS)
  3282. return (ISC_TRUE);
  3283. if (result == DNS_R_NXRRSET) {
  3284. result = dns_db_find(db, name, version, dns_rdatatype_aaaa,
  3285. 0, 0, NULL, foundname, NULL, NULL);
  3286. if (result == ISC_R_SUCCESS)
  3287. return (ISC_TRUE);
  3288. }
  3289. if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
  3290. result == DNS_R_EMPTYNAME) {
  3291. if (logit) {
  3292. dns_name_format(name, namebuf, sizeof namebuf);
  3293. dns_zone_log(zone, level, "NS '%s' has no address "
  3294. "records (A or AAAA)", namebuf);
  3295. }
  3296. return (ISC_FALSE);
  3297. }
  3298. if (result == DNS_R_CNAME) {
  3299. if (logit) {
  3300. dns_name_format(name, namebuf, sizeof namebuf);
  3301. dns_zone_log(zone, level, "NS '%s' is a CNAME "
  3302. "(illegal)", namebuf);
  3303. }
  3304. return (ISC_FALSE);
  3305. }
  3306. if (result == DNS_R_DNAME) {
  3307. if (logit) {
  3308. dns_name_format(name, namebuf, sizeof namebuf);
  3309. dns_name_format(foundname, altbuf, sizeof altbuf);
  3310. dns_zone_log(zone, level, "NS '%s' is below a DNAME "
  3311. "'%s' (illegal)", namebuf, altbuf);
  3312. }
  3313. return (ISC_FALSE);
  3314. }
  3315. return (ISC_TRUE);
  3316. }
  3317. static isc_result_t
  3318. zone_count_ns_rr(dns_zone_t *zone, dns_db_t *db, dns_dbnode_t *node,
  3319. dns_dbversion_t *version, unsigned int *nscount,
  3320. unsigned int *errors, isc_boolean_t logit)
  3321. {
  3322. isc_result_t result;
  3323. unsigned int count = 0;
  3324. unsigned int ecount = 0;
  3325. dns_rdataset_t rdataset;
  3326. dns_rdata_t rdata;
  3327. dns_rdata_ns_t ns;
  3328. dns_rdataset_init(&rdataset);
  3329. result = dns_db_findrdataset(db, node, version, dns_rdatatype_ns,
  3330. dns_rdatatype_none, 0, &rdataset, NULL);
  3331. if (result == ISC_R_NOTFOUND) {
  3332. INSIST(!dns_rdataset_isassociated(&rdataset));
  3333. goto success;
  3334. }
  3335. if (result != ISC_R_SUCCESS) {
  3336. INSIST(!dns_rdataset_isassociated(&rdataset));
  3337. goto invalidate_rdataset;
  3338. }
  3339. result = dns_rdataset_first(&rdataset);
  3340. while (result == ISC_R_SUCCESS) {
  3341. if (errors != NULL && zone->rdclass == dns_rdataclass_in &&
  3342. (zone->type == dns_zone_master ||
  3343. zone->type == dns_zone_slave)) {
  3344. dns_rdata_init(&rdata);
  3345. dns_rdataset_current(&rdataset, &rdata);
  3346. result = dns_rdata_tostruct(&rdata, &ns, NULL);
  3347. RUNTIME_CHECK(result == ISC_R_SUCCESS);
  3348. if (dns_name_issubdomain(&ns.name, &zone->origin) &&
  3349. !zone_check_ns(zone, db, version, &ns.name, logit))
  3350. ecount++;
  3351. }
  3352. count++;
  3353. result = dns_rdataset_next(&rdataset);
  3354. }
  3355. dns_rdataset_disassociate(&rdataset);
  3356. success:
  3357. if (nscount != NULL)
  3358. *nscount = count;
  3359. if (errors != NULL)
  3360. *errors = ecount;
  3361. result = ISC_R_SUCCESS;
  3362. invalidate_rdataset:
  3363. dns_rdataset_invalidate(&rdataset);
  3364. return (result);
  3365. }
  3366. static isc_result_t
  3367. zone_load_soa_rr(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
  3368. unsigned int *soacount,
  3369. isc_uint32_t *serial, isc_uint32_t *refresh,
  3370. isc_uint32_t *retry, isc_uint32_t *expire,
  3371. isc_uint32_t *minimum)
  3372. {
  3373. isc_result_t result;
  3374. unsigned int count;
  3375. dns_rdataset_t rdataset;
  3376. dns_rdata_t rdata = DNS_RDATA_INIT;
  3377. dns_rdata_soa_t soa;
  3378. dns_rdataset_init(&rdataset);
  3379. result = dns_db_findrdataset(db, node, version, dns_rdatatype_soa,
  3380. dns_rdatatype_none, 0, &rdataset, NULL);
  3381. if (result == ISC_R_NOTFOUND) {
  3382. INSIST(!dns_rdataset_isassociated(&rdataset));
  3383. if (soacount != NULL)
  3384. *soacount = 0;
  3385. if (serial != NULL)
  3386. *serial = 0;
  3387. if (refresh != NULL)
  3388. *refresh = 0;
  3389. if (retry != NULL)
  3390. *retry = 0;
  3391. if (expire != NULL)
  3392. *expire = 0;
  3393. if (minimum != NULL)
  3394. *minimum = 0;
  3395. result = ISC_R_SUCCESS;
  3396. goto invalidate_rdataset;
  3397. }
  3398. if (result != ISC_R_SUCCESS) {
  3399. INSIST(!dns_rdataset_isassociated(&rdataset));
  3400. goto invalidate_rdataset;
  3401. }
  3402. count = 0;
  3403. result = dns_rdataset_first(&rdataset);
  3404. while (result == ISC_R_SUCCESS) {
  3405. dns_rdata_init(&rdata);
  3406. dns_rdataset_current(&rdataset, &rdata);
  3407. count++;
  3408. if (count == 1) {
  3409. result = dns_rdata_tostruct(&rdata, &soa, NULL);
  3410. RUNTIME_CHECK(result == ISC_R_SUCCESS);
  3411. }
  3412. result = dns_rdataset_next(&rdataset);
  3413. dns_rdata_reset(&rdata);
  3414. }
  3415. dns_rdataset_disassociate(&rdataset);
  3416. if (soacount != NULL)
  3417. *soacount = count;
  3418. if (count > 0) {
  3419. if (serial != NULL)
  3420. *serial = soa.serial;
  3421. if (refresh != NULL)
  3422. *refresh = soa.refresh;
  3423. if (retry != NULL)
  3424. *retry = soa.retry;
  3425. if (expire != NULL)
  3426. *expire = soa.expire;
  3427. if (minimum != NULL)
  3428. *minimum = soa.minimum;
  3429. }
  3430. result = ISC_R_SUCCESS;
  3431. invalidate_rdataset:
  3432. dns_rdataset_invalidate(&rdataset);
  3433. return (result);
  3434. }
  3435. /*
  3436. * zone must be locked.
  3437. */
  3438. static isc_result_t
  3439. zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount,
  3440. unsigned int *soacount, isc_uint32_t *serial,
  3441. isc_uint32_t *refresh, isc_uint32_t *retry,
  3442. isc_uint32_t *expire, isc_uint32_t *minimum,
  3443. unsigned int *errors)
  3444. {
  3445. isc_result_t result;
  3446. isc_result_t answer = ISC_R_SUCCESS;
  3447. dns_dbversion_t *version = NULL;
  3448. dns_dbnode_t *node;
  3449. REQUIRE(db != NULL);
  3450. REQUIRE(zone != NULL);
  3451. dns_db_currentversion(db, &version);
  3452. node = NULL;
  3453. result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node);
  3454. if (result != ISC_R_SUCCESS) {
  3455. answer = result;
  3456. goto closeversion;
  3457. }
  3458. if (nscount != NULL || errors != NULL) {
  3459. result = zone_count_ns_rr(zone, db, node, version,
  3460. nscount, errors, ISC_TRUE);
  3461. if (result != ISC_R_SUCCESS)
  3462. answer = result;
  3463. }
  3464. if (soacount != NULL || serial != NULL || refresh != NULL
  3465. || retry != NULL || expire != NULL || minimum != NULL) {
  3466. result = zone_load_soa_rr(db, node, version, soacount,
  3467. serial, refresh, retry, expire,
  3468. minimum);
  3469. if (result != ISC_R_SUCCESS)
  3470. answer = result;
  3471. }
  3472. dns_db_detachnode(db, &node);
  3473. closeversion:
  3474. dns_db_closeversion(db, &version, ISC_FALSE);
  3475. return (answer);
  3476. }
  3477. void
  3478. dns_zone_attach(dns_zone_t *source, dns_zone_t **target) {
  3479. REQUIRE(DNS_ZONE_VALID(source));
  3480. REQUIRE(target != NULL && *target == NULL);
  3481. isc_refcount_increment(&source->erefs, NULL);
  3482. *target = source;
  3483. }
  3484. void
  3485. dns_zone_detach(dns_zone_t **zonep) {
  3486. dns_zone_t *zone;
  3487. unsigned int refs;
  3488. isc_boolean_t free_now = ISC_FALSE;
  3489. REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
  3490. zone = *zonep;
  3491. isc_refcount_decrement(&zone->erefs, &refs);
  3492. if (refs == 0) {
  3493. LOCK_ZONE(zone);
  3494. /*
  3495. * We just detached the last external reference.
  3496. */
  3497. if (zone->task != NULL) {
  3498. /*
  3499. * This zone is being managed. Post
  3500. * its control event and let it clean
  3501. * up synchronously in the context of
  3502. * its task.
  3503. */
  3504. isc_event_t *ev = &zone->ctlevent;
  3505. isc_task_send(zone->task, &ev);
  3506. } else {
  3507. /*
  3508. * This zone is not being managed; it has
  3509. * no task and can have no outstanding
  3510. * events. Free it immediately.
  3511. */
  3512. /*
  3513. * Unmanaged zones should not have non-null views;
  3514. * we have no way of detaching from the view here
  3515. * without causing deadlock because this code is called
  3516. * with the view already locked.
  3517. */
  3518. INSIST(zone->view == NULL);
  3519. free_now = ISC_TRUE;
  3520. }
  3521. UNLOCK_ZONE(zone);
  3522. }
  3523. *zonep = NULL;
  3524. if (free_now)
  3525. zone_free(zone);
  3526. }
  3527. void
  3528. dns_zone_iattach(dns_zone_t *source, dns_zone_t **target) {
  3529. REQUIRE(DNS_ZONE_VALID(source));
  3530. REQUIRE(target != NULL && *target == NULL);
  3531. LOCK_ZONE(source);
  3532. zone_iattach(source, target);
  3533. UNLOCK_ZONE(source);
  3534. }
  3535. isc_result_t
  3536. dns_zone_synckeyzone(dns_zone_t *zone) {
  3537. isc_result_t result;
  3538. dns_db_t *db = NULL;
  3539. if (zone->type != dns_zone_key)
  3540. return (DNS_R_BADZONE);
  3541. CHECK(dns_zone_getdb(zone, &db));
  3542. LOCK_ZONE(zone);
  3543. result = sync_keyzone(zone, db);
  3544. UNLOCK_ZONE(zone);
  3545. failure:
  3546. if (db != NULL)
  3547. dns_db_detach(&db);
  3548. return (result);
  3549. }
  3550. static void
  3551. zone_iattach(dns_zone_t *source, dns_zone_t **target) {
  3552. /*
  3553. * 'source' locked by caller.
  3554. */
  3555. REQUIRE(LOCKED_ZONE(source));
  3556. REQUIRE(DNS_ZONE_VALID(source));
  3557. REQUIRE(target != NULL && *target == NULL);
  3558. INSIST(source->irefs + isc_refcount_current(&source->erefs) > 0);
  3559. source->irefs++;
  3560. INSIST(source->irefs != 0);
  3561. *target = source;
  3562. }
  3563. static void
  3564. zone_idetach(dns_zone_t **zonep) {
  3565. dns_zone_t *zone;
  3566. /*
  3567. * 'zone' locked by caller.
  3568. */
  3569. REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
  3570. zone = *zonep;
  3571. REQUIRE(LOCKED_ZONE(*zonep));
  3572. *zonep = NULL;
  3573. INSIST(zone->irefs > 0);
  3574. zone->irefs--;
  3575. INSIST(zone->irefs + isc_refcount_current(&zone->erefs) > 0);
  3576. }
  3577. void
  3578. dns_zone_idetach(dns_zone_t **zonep) {
  3579. dns_zone_t *zone;
  3580. isc_boolean_t free_needed;
  3581. REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
  3582. zone = *zonep;
  3583. *zonep = NULL;
  3584. LOCK_ZONE(zone);
  3585. INSIST(zone->irefs > 0);
  3586. zone->irefs--;
  3587. free_needed = exit_check(zone);
  3588. UNLOCK_ZONE(zone);
  3589. if (free_needed)
  3590. zone_free(zone);
  3591. }
  3592. isc_mem_t *
  3593. dns_zone_getmctx(dns_zone_t *zone) {
  3594. REQUIRE(DNS_ZONE_VALID(zone));
  3595. return (zone->mctx);
  3596. }
  3597. dns_zonemgr_t *
  3598. dns_zone_getmgr(dns_zone_t *zone) {
  3599. REQUIRE(DNS_ZONE_VALID(zone));
  3600. return (zone->zmgr);
  3601. }
  3602. void
  3603. dns_zone_setflag(dns_zone_t *zone, unsigned int flags, isc_boolean_t value) {
  3604. REQUIRE(DNS_ZONE_VALID(zone));
  3605. LOCK_ZONE(zone);
  3606. if (value)
  3607. DNS_ZONE_SETFLAG(zone, flags);
  3608. else
  3609. DNS_ZONE_CLRFLAG(zone, flags);
  3610. UNLOCK_ZONE(zone);
  3611. }
  3612. void
  3613. dns_zone_setoption(dns_zone_t *zone, unsigned int option, isc_boolean_t value)
  3614. {
  3615. REQUIRE(DNS_ZONE_VALID(zone));
  3616. LOCK_ZONE(zone);
  3617. if (value)
  3618. zone->options |= option;
  3619. else
  3620. zone->options &= ~option;
  3621. UNLOCK_ZONE(zone);
  3622. }
  3623. unsigned int
  3624. dns_zone_getoptions(dns_zone_t *zone) {
  3625. REQUIRE(DNS_ZONE_VALID(zone));
  3626. return (zone->options);
  3627. }
  3628. void
  3629. dns_zone_setkeyopt(dns_zone_t *zone, unsigned int keyopt, isc_boolean_t value)
  3630. {
  3631. REQUIRE(DNS_ZONE_VALID(zone));
  3632. LOCK_ZONE(zone);
  3633. if (value)
  3634. zone->keyopts |= keyopt;
  3635. else
  3636. zone->keyopts &= ~keyopt;
  3637. UNLOCK_ZONE(zone);
  3638. }
  3639. unsigned int
  3640. dns_zone_getkeyopts(dns_zone_t *zone) {
  3641. REQUIRE(DNS_ZONE_VALID(zone));
  3642. return (zone->keyopts);
  3643. }
  3644. isc_result_t
  3645. dns_zone_setxfrsource4(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) {
  3646. REQUIRE(DNS_ZONE_VALID(zone));
  3647. LOCK_ZONE(zone);
  3648. zone->xfrsource4 = *xfrsource;
  3649. UNLOCK_ZONE(zone);
  3650. return (ISC_R_SUCCESS);
  3651. }
  3652. isc_sockaddr_t *
  3653. dns_zone_getxfrsource4(dns_zone_t *zone) {
  3654. REQUIRE(DNS_ZONE_VALID(zone));
  3655. return (&zone->xfrsource4);
  3656. }
  3657. isc_result_t
  3658. dns_zone_setxfrsource6(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) {
  3659. REQUIRE(DNS_ZONE_VALID(zone));
  3660. LOCK_ZONE(zone);
  3661. zone->xfrsource6 = *xfrsource;
  3662. UNLOCK_ZONE(zone);
  3663. return (ISC_R_SUCCESS);
  3664. }
  3665. isc_sockaddr_t *
  3666. dns_zone_getxfrsource6(dns_zone_t *zone) {
  3667. REQUIRE(DNS_ZONE_VALID(zone));
  3668. return (&zone->xfrsource6);
  3669. }
  3670. isc_result_t
  3671. dns_zone_setaltxfrsource4(dns_zone_t *zone,
  3672. const isc_sockaddr_t *altxfrsource)
  3673. {
  3674. REQUIRE(DNS_ZONE_VALID(zone));
  3675. LOCK_ZONE(zone);
  3676. zone->altxfrsource4 = *altxfrsource;
  3677. UNLOCK_ZONE(zone);
  3678. return (ISC_R_SUCCESS);
  3679. }
  3680. isc_sockaddr_t *
  3681. dns_zone_getaltxfrsource4(dns_zone_t *zone) {
  3682. REQUIRE(DNS_ZONE_VALID(zone));
  3683. return (&zone->altxfrsource4);
  3684. }
  3685. isc_result_t
  3686. dns_zone_setaltxfrsource6(dns_zone_t *zone,
  3687. const isc_sockaddr_t *altxfrsource)
  3688. {
  3689. REQUIRE(DNS_ZONE_VALID(zone));
  3690. LOCK_ZONE(zone);
  3691. zone->altxfrsource6 = *altxfrsource;
  3692. UNLOCK_ZONE(zone);
  3693. return (ISC_R_SUCCESS);
  3694. }
  3695. isc_sockaddr_t *
  3696. dns_zone_getaltxfrsource6(dns_zone_t *zone) {
  3697. REQUIRE(DNS_ZONE_VALID(zone));
  3698. return (&zone->altxfrsource6);
  3699. }
  3700. isc_result_t
  3701. dns_zone_setnotifysrc4(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) {
  3702. REQUIRE(DNS_ZONE_VALID(zone));
  3703. LOCK_ZONE(zone);
  3704. zone->notifysrc4 = *notifysrc;
  3705. UNLOCK_ZONE(zone);
  3706. return (ISC_R_SUCCESS);
  3707. }
  3708. isc_sockaddr_t *
  3709. dns_zone_getnotifysrc4(dns_zone_t *zone) {
  3710. REQUIRE(DNS_ZONE_VALID(zone));
  3711. return (&zone->notifysrc4);
  3712. }
  3713. isc_result_t
  3714. dns_zone_setnotifysrc6(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) {
  3715. REQUIRE(DNS_ZONE_VALID(zone));
  3716. LOCK_ZONE(zone);
  3717. zone->notifysrc6 = *notifysrc;
  3718. UNLOCK_ZONE(zone);
  3719. return (ISC_R_SUCCESS);
  3720. }
  3721. isc_sockaddr_t *
  3722. dns_zone_getnotifysrc6(dns_zone_t *zone) {
  3723. REQUIRE(DNS_ZONE_VALID(zone));
  3724. return (&zone->notifysrc6);
  3725. }
  3726. isc_result_t
  3727. dns_zone_setalsonotify(dns_zone_t *zone, const isc_sockaddr_t *notify,
  3728. isc_uint32_t count)
  3729. {
  3730. isc_sockaddr_t *new;
  3731. REQUIRE(DNS_ZONE_VALID(zone));
  3732. REQUIRE(count == 0 || notify != NULL);
  3733. LOCK_ZONE(zone);
  3734. if (zone->notify != NULL) {
  3735. isc_mem_put(zone->mctx, zone->notify,
  3736. zone->notifycnt * sizeof(*new));
  3737. zone->notify = NULL;
  3738. zone->notifycnt = 0;
  3739. }
  3740. if (count != 0) {
  3741. new = isc_mem_get(zone->mctx, count * sizeof(*new));
  3742. if (new == NULL) {
  3743. UNLOCK_ZONE(zone);
  3744. return (ISC_R_NOMEMORY);
  3745. }
  3746. memcpy(new, notify, count * sizeof(*new));
  3747. zone->notify = new;
  3748. zone->notifycnt = count;
  3749. }
  3750. UNLOCK_ZONE(zone);
  3751. return (ISC_R_SUCCESS);
  3752. }
  3753. isc_result_t
  3754. dns_zone_setmasters(dns_zone_t *zone, const isc_sockaddr_t *masters,
  3755. isc_uint32_t count)
  3756. {
  3757. isc_result_t result;
  3758. result = dns_zone_setmasterswithkeys(zone, masters, NULL, count);
  3759. return (result);
  3760. }
  3761. static isc_boolean_t
  3762. same_masters(const isc_sockaddr_t *old, const isc_sockaddr_t *new,
  3763. isc_uint32_t count)
  3764. {
  3765. unsigned int i;
  3766. for (i = 0; i < count; i++)
  3767. if (!isc_sockaddr_equal(&old[i], &new[i]))
  3768. return (ISC_FALSE);
  3769. return (ISC_TRUE);
  3770. }
  3771. static isc_boolean_t
  3772. same_keynames(dns_name_t **old, dns_name_t **new, isc_uint32_t count) {
  3773. unsigned int i;
  3774. if (old == NULL && new == NULL)
  3775. return (ISC_TRUE);
  3776. if (old == NULL || new == NULL)
  3777. return (ISC_FALSE);
  3778. for (i = 0; i < count; i++) {
  3779. if (old[i] == NULL && new[i] == NULL)
  3780. continue;
  3781. if (old[i] == NULL || new[i] == NULL ||
  3782. !dns_name_equal(old[i], new[i]))
  3783. return (ISC_FALSE);
  3784. }
  3785. return (ISC_TRUE);
  3786. }
  3787. isc_result_t
  3788. dns_zone_setmasterswithkeys(dns_zone_t *zone,
  3789. const isc_sockaddr_t *masters,
  3790. dns_name_t **keynames,
  3791. isc_uint32_t count)
  3792. {
  3793. isc_sockaddr_t *new;
  3794. isc_result_t result = ISC_R_SUCCESS;
  3795. dns_name_t **newname;
  3796. isc_boolean_t *newok;
  3797. unsigned int i;
  3798. REQUIRE(DNS_ZONE_VALID(zone));
  3799. REQUIRE(count == 0 || masters != NULL);
  3800. if (keynames != NULL) {
  3801. REQUIRE(count != 0);
  3802. }
  3803. LOCK_ZONE(zone);
  3804. /*
  3805. * The refresh code assumes that 'masters' wouldn't change under it.
  3806. * If it will change then kill off any current refresh in progress
  3807. * and update the masters info. If it won't change then we can just
  3808. * unlock and exit.
  3809. */
  3810. if (count != zone->masterscnt ||
  3811. !same_masters(zone->masters, masters, count) ||
  3812. !same_keynames(zone->masterkeynames, keynames, count)) {
  3813. if (zone->request != NULL)
  3814. dns_request_cancel(zone->request);
  3815. } else
  3816. goto unlock;
  3817. if (zone->masters != NULL) {
  3818. isc_mem_put(zone->mctx, zone->masters,
  3819. zone->masterscnt * sizeof(*new));
  3820. zone->masters = NULL;
  3821. }
  3822. if (zone->masterkeynames != NULL) {
  3823. for (i = 0; i < zone->masterscnt; i++) {
  3824. if (zone->masterkeynames[i] != NULL) {
  3825. dns_name_free(zone->masterkeynames[i],
  3826. zone->mctx);
  3827. isc_mem_put(zone->mctx,
  3828. zone->masterkeynames[i],
  3829. sizeof(dns_name_t));
  3830. zone->masterkeynames[i] = NULL;
  3831. }
  3832. }
  3833. isc_mem_put(zone->mctx, zone->masterkeynames,
  3834. zone->masterscnt * sizeof(dns_name_t *));
  3835. zone->masterkeynames = NULL;
  3836. }
  3837. if (zone->mastersok != NULL) {
  3838. isc_mem_put(zone->mctx, zone->mastersok,
  3839. zone->masterscnt * sizeof(isc_boolean_t));
  3840. zone->mastersok = NULL;
  3841. }
  3842. zone->masterscnt = 0;
  3843. /*
  3844. * If count == 0, don't allocate any space for masters, mastersok or
  3845. * keynames so internally, those pointers are NULL if count == 0
  3846. */
  3847. if (count == 0)
  3848. goto unlock;
  3849. /*
  3850. * masters must contain count elements!
  3851. */
  3852. new = isc_mem_get(zone->mctx, count * sizeof(*new));
  3853. if (new == NULL) {
  3854. result = ISC_R_NOMEMORY;
  3855. goto unlock;
  3856. }
  3857. memcpy(new, masters, count * sizeof(*new));
  3858. /*
  3859. * Similarly for mastersok.
  3860. */
  3861. newok = isc_mem_get(zone->mctx, count * sizeof(*newok));
  3862. if (newok == NULL) {
  3863. result = ISC_R_NOMEMORY;
  3864. isc_mem_put(zone->mctx, new, count * sizeof(*new));
  3865. goto unlock;
  3866. };
  3867. for (i = 0; i < count; i++)
  3868. newok[i] = ISC_FALSE;
  3869. /*
  3870. * if keynames is non-NULL, it must contain count elements!
  3871. */
  3872. newname = NULL;
  3873. if (keynames != NULL) {
  3874. newname = isc_mem_get(zone->mctx, count * sizeof(*newname));
  3875. if (newname == NULL) {
  3876. result = ISC_R_NOMEMORY;
  3877. isc_mem_put(zone->mctx, new, count * sizeof(*new));
  3878. isc_mem_put(zone->mctx, newok, count * sizeof(*newok));
  3879. goto unlock;
  3880. }
  3881. for (i = 0; i < count; i++)
  3882. newname[i] = NULL;
  3883. for (i = 0; i < count; i++) {
  3884. if (keynames[i] != NULL) {
  3885. newname[i] = isc_mem_get(zone->mctx,
  3886. sizeof(dns_name_t));
  3887. if (newname[i] == NULL)
  3888. goto allocfail;
  3889. dns_name_init(newname[i], NULL);
  3890. result = dns_name_dup(keynames[i], zone->mctx,
  3891. newname[i]);
  3892. if (result != ISC_R_SUCCESS) {
  3893. allocfail:
  3894. for (i = 0; i < count; i++)
  3895. if (newname[i] != NULL)
  3896. dns_name_free(
  3897. newname[i],
  3898. zone->mctx);
  3899. isc_mem_put(zone->mctx, new,
  3900. count * sizeof(*new));
  3901. isc_mem_put(zone->mctx, newok,
  3902. count * sizeof(*newok));
  3903. isc_mem_put(zone->mctx, newname,
  3904. count * sizeof(*newname));
  3905. goto unlock;
  3906. }
  3907. }
  3908. }
  3909. }
  3910. /*
  3911. * Everything is ok so attach to the zone.
  3912. */
  3913. zone->curmaster = 0;
  3914. zone->masters = new;
  3915. zone->mastersok = newok;
  3916. zone->masterkeynames = newname;
  3917. zone->masterscnt = count;
  3918. DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOMASTERS);
  3919. unlock:
  3920. UNLOCK_ZONE(zone);
  3921. return (result);
  3922. }
  3923. isc_result_t
  3924. dns_zone_getdb(dns_zone_t *zone, dns_db_t **dpb) {
  3925. isc_result_t result = ISC_R_SUCCESS;
  3926. REQUIRE(DNS_ZONE_VALID(zone));
  3927. ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
  3928. if (zone->db == NULL)
  3929. result = DNS_R_NOTLOADED;
  3930. else
  3931. dns_db_attach(zone->db, dpb);
  3932. ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
  3933. return (result);
  3934. }
  3935. void
  3936. dns_zone_setdb(dns_zone_t *zone, dns_db_t *db) {
  3937. REQUIRE(DNS_ZONE_VALID(zone));
  3938. REQUIRE(zone->type == dns_zone_staticstub);
  3939. ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
  3940. REQUIRE(zone->db == NULL);
  3941. dns_db_attach(db, &zone->db);
  3942. ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
  3943. }
  3944. /*
  3945. * Co-ordinates the starting of routine jobs.
  3946. */
  3947. void
  3948. dns_zone_maintenance(dns_zone_t *zone) {
  3949. const char me[] = "dns_zone_maintenance";
  3950. isc_time_t now;
  3951. REQUIRE(DNS_ZONE_VALID(zone));
  3952. ENTER;
  3953. LOCK_ZONE(zone);
  3954. TIME_NOW(&now);
  3955. zone_settimer(zone, &now);
  3956. UNLOCK_ZONE(zone);
  3957. }
  3958. static inline isc_boolean_t
  3959. was_dumping(dns_zone_t *zone) {
  3960. isc_boolean_t dumping;
  3961. REQUIRE(LOCKED_ZONE(zone));
  3962. dumping = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING);
  3963. DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
  3964. if (!dumping) {
  3965. DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
  3966. isc_time_settoepoch(&zone->dumptime);
  3967. }
  3968. return (dumping);
  3969. }
  3970. static isc_result_t
  3971. find_zone_keys(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
  3972. isc_mem_t *mctx, unsigned int maxkeys,
  3973. dst_key_t **keys, unsigned int *nkeys)
  3974. {
  3975. isc_result_t result;
  3976. dns_dbnode_t *node = NULL;
  3977. const char *directory = dns_zone_getkeydirectory(zone);
  3978. CHECK(dns_db_findnode(db, dns_db_origin(db), ISC_FALSE, &node));
  3979. result = dns_dnssec_findzonekeys2(db, ver, node, dns_db_origin(db),
  3980. directory, mctx, maxkeys, keys,
  3981. nkeys);
  3982. if (result == ISC_R_NOTFOUND)
  3983. result = ISC_R_SUCCESS;
  3984. failure:
  3985. if (node != NULL)
  3986. dns_db_detachnode(db, &node);
  3987. return (result);
  3988. }
  3989. static isc_result_t
  3990. offline(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff, dns_name_t *name,
  3991. dns_ttl_t ttl, dns_rdata_t *rdata)
  3992. {
  3993. isc_result_t result;
  3994. if ((rdata->flags & DNS_RDATA_OFFLINE) != 0)
  3995. return (ISC_R_SUCCESS);
  3996. result = update_one_rr(db, ver, diff, DNS_DIFFOP_DELRESIGN,
  3997. name, ttl, rdata);
  3998. if (result != ISC_R_SUCCESS)
  3999. return (result);
  4000. rdata->flags |= DNS_RDATA_OFFLINE;
  4001. result = update_one_rr(db, ver, diff, DNS_DIFFOP_ADDRESIGN,
  4002. name, ttl, rdata);
  4003. return (result);
  4004. }
  4005. static void
  4006. set_key_expiry_warning(dns_zone_t *zone, isc_stdtime_t when, isc_stdtime_t now)
  4007. {
  4008. unsigned int delta;
  4009. char timebuf[80];
  4010. zone->key_expiry = when;
  4011. if (when <= now) {
  4012. dns_zone_log(zone, ISC_LOG_ERROR,
  4013. "DNSKEY RRSIG(s) have expired");
  4014. isc_time_settoepoch(&zone->keywarntime);
  4015. } else if (when < now + 7 * 24 * 3600) {
  4016. isc_time_t t;
  4017. isc_time_set(&t, when, 0);
  4018. isc_time_formattimestamp(&t, timebuf, 80);
  4019. dns_zone_log(zone, ISC_LOG_WARNING,
  4020. "DNSKEY RRSIG(s) will expire within 7 days: %s",
  4021. timebuf);
  4022. delta = when - now;
  4023. delta--; /* loop prevention */
  4024. delta /= 24 * 3600; /* to whole days */
  4025. delta *= 24 * 3600; /* to seconds */
  4026. isc_time_set(&zone->keywarntime, when - delta, 0);
  4027. } else {
  4028. isc_time_set(&zone->keywarntime, when - 7 * 24 * 3600, 0);
  4029. isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
  4030. dns_zone_log(zone, ISC_LOG_NOTICE,
  4031. "setting keywarntime to %s", timebuf);
  4032. }
  4033. }
  4034. /*
  4035. * Helper function to del_sigs(). We don't want to delete RRSIGs that
  4036. * have no new key.
  4037. */
  4038. static isc_boolean_t
  4039. delsig_ok(dns_rdata_rrsig_t *rrsig_ptr, dst_key_t **keys, unsigned int nkeys) {
  4040. unsigned int i = 0;
  4041. /*
  4042. * It's okay to delete a signature if there is an active ZSK
  4043. * with the same algorithm
  4044. */
  4045. for (i = 0; i < nkeys; i++) {
  4046. if (rrsig_ptr->algorithm == dst_key_alg(keys[i]) &&
  4047. (dst_key_isprivate(keys[i])) && !KSK(keys[i]))
  4048. return (ISC_TRUE);
  4049. }
  4050. /*
  4051. * Failing that, it is *not* okay to delete a signature
  4052. * if the associated public key is still in the DNSKEY RRset
  4053. */
  4054. for (i = 0; i < nkeys; i++) {
  4055. if ((rrsig_ptr->algorithm == dst_key_alg(keys[i])) &&
  4056. (rrsig_ptr->keyid == dst_key_id(keys[i])))
  4057. return (ISC_FALSE);
  4058. }
  4059. /*
  4060. * But if the key is gone, then go ahead.
  4061. */
  4062. return (ISC_TRUE);
  4063. }
  4064. /*
  4065. * Delete expired RRsigs and any RRsigs we are about to re-sign.
  4066. * See also update.c:del_keysigs().
  4067. */
  4068. static isc_result_t
  4069. del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
  4070. dns_rdatatype_t type, dns_diff_t *diff, dst_key_t **keys,
  4071. unsigned int nkeys, isc_stdtime_t now, isc_boolean_t incremental)
  4072. {
  4073. isc_result_t result;
  4074. dns_dbnode_t *node = NULL;
  4075. dns_rdataset_t rdataset;
  4076. unsigned int i;
  4077. dns_rdata_rrsig_t rrsig;
  4078. isc_boolean_t found, changed;
  4079. isc_int64_t warn = 0, maybe = 0;
  4080. dns_rdataset_init(&rdataset);
  4081. if (type == dns_rdatatype_nsec3)
  4082. result = dns_db_findnsec3node(db, name, ISC_FALSE, &node);
  4083. else
  4084. result = dns_db_findnode(db, name, ISC_FALSE, &node);
  4085. if (result == ISC_R_NOTFOUND)
  4086. return (ISC_R_SUCCESS);
  4087. if (result != ISC_R_SUCCESS)
  4088. goto failure;
  4089. result = dns_db_findrdataset(db, node, ver, dns_rdatatype_rrsig, type,
  4090. (isc_stdtime_t) 0, &rdataset, NULL);
  4091. dns_db_detachnode(db, &node);
  4092. if (result == ISC_R_NOTFOUND) {
  4093. INSIST(!dns_rdataset_isassociated(&rdataset));
  4094. return (ISC_R_SUCCESS);
  4095. }
  4096. if (result != ISC_R_SUCCESS) {
  4097. INSIST(!dns_rdataset_isassociated(&rdataset));
  4098. goto failure;
  4099. }
  4100. changed = ISC_FALSE;
  4101. for (result = dns_rdataset_first(&rdataset);
  4102. result == ISC_R_SUCCESS;
  4103. result = dns_rdataset_next(&rdataset)) {
  4104. dns_rdata_t rdata = DNS_RDATA_INIT;
  4105. dns_rdataset_current(&rdataset, &rdata);
  4106. result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
  4107. RUNTIME_CHECK(result == ISC_R_SUCCESS);
  4108. if (type != dns_rdatatype_dnskey) {
  4109. if (delsig_ok(&rrsig, keys, nkeys)) {
  4110. result = update_one_rr(db, ver, diff,
  4111. DNS_DIFFOP_DELRESIGN, name,
  4112. rdataset.ttl, &rdata);
  4113. if (incremental)
  4114. changed = ISC_TRUE;
  4115. if (result != ISC_R_SUCCESS)
  4116. break;
  4117. } else {
  4118. /*
  4119. * At this point, we've got an RRSIG,
  4120. * which is signed by an inactive key.
  4121. * An administrator needs to provide a new
  4122. * key/alg, but until that time, we want to
  4123. * keep the old RRSIG. Marking the key as
  4124. * offline will prevent us spinning waiting
  4125. * for the private part.
  4126. */
  4127. if (incremental) {
  4128. result = offline(db, ver, diff, name,
  4129. rdataset.ttl, &rdata);
  4130. changed = ISC_TRUE;
  4131. if (result != ISC_R_SUCCESS)
  4132. break;
  4133. }
  4134. /*
  4135. * Log the key id and algorithm of
  4136. * the inactive key with no replacement
  4137. */
  4138. if (zone->log_key_expired_timer <= now) {
  4139. char origin[DNS_NAME_FORMATSIZE];
  4140. char algbuf[DNS_NAME_FORMATSIZE];
  4141. dns_name_format(&zone->origin, origin,
  4142. sizeof(origin));
  4143. dns_secalg_format(rrsig.algorithm,
  4144. algbuf,
  4145. sizeof(algbuf));
  4146. dns_zone_log(zone, ISC_LOG_WARNING,
  4147. "Key %s/%s/%d "
  4148. "missing or inactive "
  4149. "and has no replacement: "
  4150. "retaining signatures.",
  4151. origin, algbuf,
  4152. rrsig.keyid);
  4153. zone->log_key_expired_timer = now +
  4154. 3600;
  4155. }
  4156. }
  4157. continue;
  4158. }
  4159. /*
  4160. * RRSIG(DNSKEY) requires special processing.
  4161. */
  4162. found = ISC_FALSE;
  4163. for (i = 0; i < nkeys; i++) {
  4164. if (rrsig.algorithm == dst_key_alg(keys[i]) &&
  4165. rrsig.keyid == dst_key_id(keys[i])) {
  4166. found = ISC_TRUE;
  4167. /*
  4168. * Mark offline RRSIG(DNSKEY).
  4169. * We want the earliest offline expire time
  4170. * iff there is a new offline signature.
  4171. */
  4172. if (!dst_key_isprivate(keys[i])) {
  4173. isc_int64_t timeexpire =
  4174. dns_time64_from32(rrsig.timeexpire);
  4175. if (warn != 0 && warn > timeexpire)
  4176. warn = timeexpire;
  4177. if (rdata.flags & DNS_RDATA_OFFLINE) {
  4178. if (maybe == 0 ||
  4179. maybe > timeexpire)
  4180. maybe = timeexpire;
  4181. break;
  4182. }
  4183. if (warn == 0)
  4184. warn = maybe;
  4185. if (warn == 0 || warn > timeexpire)
  4186. warn = timeexpire;
  4187. result = offline(db, ver, diff, name,
  4188. rdataset.ttl, &rdata);
  4189. break;
  4190. }
  4191. result = update_one_rr(db, ver, diff,
  4192. DNS_DIFFOP_DELRESIGN,
  4193. name, rdataset.ttl,
  4194. &rdata);
  4195. break;
  4196. }
  4197. }
  4198. /*
  4199. * If there is not a matching DNSKEY then
  4200. * delete the RRSIG.
  4201. */
  4202. if (!found)
  4203. result = update_one_rr(db, ver, diff,
  4204. DNS_DIFFOP_DELRESIGN, name,
  4205. rdataset.ttl, &rdata);
  4206. if (result != ISC_R_SUCCESS)
  4207. break;
  4208. }
  4209. if (changed && (rdataset.attributes & DNS_RDATASETATTR_RESIGN) != 0)
  4210. dns_db_resigned(db, &rdataset, ver);
  4211. dns_rdataset_disassociate(&rdataset);
  4212. if (result == ISC_R_NOMORE)
  4213. result = ISC_R_SUCCESS;
  4214. if (warn > 0) {
  4215. #if defined(STDTIME_ON_32BITS)
  4216. isc_stdtime_t stdwarn = (isc_stdtime_t)warn;
  4217. if (warn == stdwarn)
  4218. #endif
  4219. set_key_expiry_warning(zone, (isc_stdtime_t)warn, now);
  4220. #if defined(STDTIME_ON_32BITS)
  4221. else
  4222. dns_zone_log(zone, ISC_LOG_ERROR,
  4223. "key expiry warning time out of range");
  4224. #endif
  4225. }
  4226. failure:
  4227. if (node != NULL)
  4228. dns_db_detachnode(db, &node);
  4229. return (result);
  4230. }
  4231. static isc_result_t
  4232. add_sigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
  4233. dns_rdatatype_t type, dns_diff_t *diff, dst_key_t **keys,
  4234. unsigned int nkeys, isc_mem_t *mctx, isc_stdtime_t inception,
  4235. isc_stdtime_t expire, isc_boolean_t check_ksk,
  4236. isc_boolean_t keyset_kskonly)
  4237. {
  4238. isc_result_t result;
  4239. dns_dbnode_t *node = NULL;
  4240. dns_rdataset_t rdataset;
  4241. dns_rdata_t sig_rdata = DNS_RDATA_INIT;
  4242. unsigned char data[1024]; /* XXX */
  4243. isc_buffer_t buffer;
  4244. unsigned int i, j;
  4245. dns_rdataset_init(&rdataset);
  4246. isc_buffer_init(&buffer, data, sizeof(data));
  4247. if (type == dns_rdatatype_nsec3)
  4248. result = dns_db_findnsec3node(db, name, ISC_FALSE, &node);
  4249. else
  4250. result = dns_db_findnode(db, name, ISC_FALSE, &node);
  4251. if (result == ISC_R_NOTFOUND)
  4252. return (ISC_R_SUCCESS);
  4253. if (result != ISC_R_SUCCESS)
  4254. goto failure;
  4255. result = dns_db_findrdataset(db, node, ver, type, 0,
  4256. (isc_stdtime_t) 0, &rdataset, NULL);
  4257. dns_db_detachnode(db, &node);
  4258. if (result == ISC_R_NOTFOUND) {
  4259. INSIST(!dns_rdataset_isassociated(&rdataset));
  4260. return (ISC_R_SUCCESS);
  4261. }
  4262. if (result != ISC_R_SUCCESS) {
  4263. INSIST(!dns_rdataset_isassociated(&rdataset));
  4264. goto failure;
  4265. }
  4266. for (i = 0; i < nkeys; i++) {
  4267. isc_boolean_t both = ISC_FALSE;
  4268. if (!dst_key_isprivate(keys[i]))
  4269. continue;
  4270. if (check_ksk && !REVOKE(keys[i])) {
  4271. isc_boolean_t have_ksk, have_nonksk;
  4272. if (KSK(keys[i])) {
  4273. have_ksk = ISC_TRUE;
  4274. have_nonksk = ISC_FALSE;
  4275. } else {
  4276. have_ksk = ISC_FALSE;
  4277. have_nonksk = ISC_TRUE;
  4278. }
  4279. for (j = 0; j < nkeys; j++) {
  4280. if (j == i || ALG(keys[i]) != ALG(keys[j]))
  4281. continue;
  4282. if (REVOKE(keys[j]))
  4283. continue;
  4284. if (KSK(keys[j]))
  4285. have_ksk = ISC_TRUE;
  4286. else
  4287. have_nonksk = ISC_TRUE;
  4288. both = have_ksk && have_nonksk;
  4289. if (both)
  4290. break;
  4291. }
  4292. }
  4293. if (both) {
  4294. if (type == dns_rdatatype_dnskey) {
  4295. if (!KSK(keys[i]) && keyset_kskonly)
  4296. continue;
  4297. } else if (KSK(keys[i]))
  4298. continue;
  4299. } else if (REVOKE(keys[i]) && type != dns_rdatatype_dnskey)
  4300. continue;
  4301. /* Calculate the signature, creating a RRSIG RDATA. */
  4302. isc_buffer_clear(&buffer);
  4303. CHECK(dns_dnssec_sign(name, &rdataset, keys[i],
  4304. &inception, &expire,
  4305. mctx, &buffer, &sig_rdata));
  4306. /* Update the database and journal with the RRSIG. */
  4307. /* XXX inefficient - will cause dataset merging */
  4308. CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADDRESIGN,
  4309. name, rdataset.ttl, &sig_rdata));
  4310. dns_rdata_reset(&sig_rdata);
  4311. isc_buffer_init(&buffer, data, sizeof(data));
  4312. }
  4313. failure:
  4314. if (dns_rdataset_isassociated(&rdataset))
  4315. dns_rdataset_disassociate(&rdataset);
  4316. if (node != NULL)
  4317. dns_db_detachnode(db, &node);
  4318. return (result);
  4319. }
  4320. static void
  4321. zone_resigninc(dns_zone_t *zone) {
  4322. dns_db_t *db = NULL;
  4323. dns_dbversion_t *version = NULL;
  4324. dns_diff_t sig_diff;
  4325. dns_fixedname_t fixed;
  4326. dns_name_t *name;
  4327. dns_rdataset_t rdataset;
  4328. dns_rdatatype_t covers;
  4329. dst_key_t *zone_keys[DNS_MAXZONEKEYS];
  4330. isc_boolean_t check_ksk, keyset_kskonly = ISC_FALSE;
  4331. isc_result_t result;
  4332. isc_stdtime_t now, inception, soaexpire, expire, stop;
  4333. isc_uint32_t jitter;
  4334. unsigned int i;
  4335. unsigned int nkeys = 0;
  4336. unsigned int resign;
  4337. dns_rdataset_init(&rdataset);
  4338. dns_fixedname_init(&fixed);
  4339. dns_diff_init(zone->mctx, &sig_diff);
  4340. sig_diff.resign = zone->sigresigninginterval;
  4341. /*
  4342. * Updates are disabled. Pause for 5 minutes.
  4343. */
  4344. if (zone->update_disabled) {
  4345. result = ISC_R_FAILURE;
  4346. goto failure;
  4347. }
  4348. ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
  4349. dns_db_attach(zone->db, &db);
  4350. ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
  4351. result = dns_db_newversion(db, &version);
  4352. if (result != ISC_R_SUCCESS) {
  4353. dns_zone_log(zone, ISC_LOG_ERROR,
  4354. "zone_resigninc:dns_db_newversion -> %s\n",
  4355. dns_result_totext(result));
  4356. goto failure;
  4357. }
  4358. result = find_zone_keys(zone, db, version, zone->mctx, DNS_MAXZONEKEYS,
  4359. zone_keys, &nkeys);
  4360. if (result != ISC_R_SUCCESS) {
  4361. dns_zone_log(zone, ISC_LOG_ERROR,
  4362. "zone_resigninc:find_zone_keys -> %s\n",
  4363. dns_result_totext(result));
  4364. goto failure;
  4365. }
  4366. isc_stdtime_get(&now);
  4367. inception = now - 3600; /* Allow for clock skew. */
  4368. soaexpire = now + dns_zone_getsigvalidityinterval(zone);
  4369. /*
  4370. * Spread out signatures over time if they happen to be
  4371. * clumped. We don't do this for each add_sigs() call as
  4372. * we still want some clustering to occur.
  4373. */
  4374. isc_random_get(&jitter);
  4375. expire = soaexpire - jitter % 3600;
  4376. stop = now + 5;
  4377. check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
  4378. keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
  4379. name = dns_fixedname_name(&fixed);
  4380. result = dns_db_getsigningtime(db, &rdataset, name);
  4381. if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
  4382. dns_zone_log(zone, ISC_LOG_ERROR,
  4383. "zone_resigninc:dns_db_getsigningtime -> %s\n",
  4384. dns_result_totext(result));
  4385. }
  4386. i = 0;
  4387. while (result == ISC_R_SUCCESS) {
  4388. resign = rdataset.resign;
  4389. covers = rdataset.covers;
  4390. dns_rdataset_disassociate(&rdataset);
  4391. /*
  4392. * Stop if we hit the SOA as that means we have walked the
  4393. * entire zone. The SOA record should always be the most
  4394. * recent signature.
  4395. */
  4396. /* XXXMPA increase number of RRsets signed pre call */
  4397. if (covers == dns_rdatatype_soa || i++ > zone->signatures ||
  4398. resign > stop)
  4399. break;
  4400. result = del_sigs(zone, db, version, name, covers, &sig_diff,
  4401. zone_keys, nkeys, now, ISC_TRUE);
  4402. if (result != ISC_R_SUCCESS) {
  4403. dns_zone_log(zone, ISC_LOG_ERROR,
  4404. "zone_resigninc:del_sigs -> %s\n",
  4405. dns_result_totext(result));
  4406. break;
  4407. }
  4408. result = add_sigs(db, version, name, covers, &sig_diff,
  4409. zone_keys, nkeys, zone->mctx, inception,
  4410. expire, check_ksk, keyset_kskonly);
  4411. if (result != ISC_R_SUCCESS) {
  4412. dns_zone_log(zone, ISC_LOG_ERROR,
  4413. "zone_resigninc:add_sigs -> %s\n",
  4414. dns_result_totext(result));
  4415. break;
  4416. }
  4417. result = dns_db_getsigningtime(db, &rdataset,
  4418. dns_fixedname_name(&fixed));
  4419. if (nkeys == 0 && result == ISC_R_NOTFOUND) {
  4420. result = ISC_R_SUCCESS;
  4421. break;
  4422. }
  4423. if (result != ISC_R_SUCCESS)
  4424. dns_zone_log(zone, ISC_LOG_ERROR,
  4425. "zone_resigninc:dns_db_getsigningtime -> %s\n",
  4426. dns_result_totext(result));
  4427. }
  4428. if (result != ISC_R_NOMORE && result != ISC_R_SUCCESS)
  4429. goto failure;
  4430. result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
  4431. &sig_diff, zone_keys, nkeys, now, ISC_TRUE);
  4432. if (result != ISC_R_SUCCESS) {
  4433. dns_zone_log(zone, ISC_LOG_ERROR,
  4434. "zone_resigninc:del_sigs -> %s\n",
  4435. dns_result_totext(result));
  4436. goto failure;
  4437. }
  4438. /*
  4439. * Did we change anything in the zone?
  4440. */
  4441. if (ISC_LIST_EMPTY(sig_diff.tuples))
  4442. goto failure;
  4443. /* Increment SOA serial if we have made changes */
  4444. result = increment_soa_serial(db, version, &sig_diff, zone->mctx);
  4445. if (result != ISC_R_SUCCESS) {
  4446. dns_zone_log(zone, ISC_LOG_ERROR,
  4447. "zone_resigninc:increment_soa_serial -> %s\n",
  4448. dns_result_totext(result));
  4449. goto failure;
  4450. }
  4451. /*
  4452. * Generate maximum life time signatures so that the above loop
  4453. * termination is sensible.
  4454. */
  4455. result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa,
  4456. &sig_diff, zone_keys, nkeys, zone->mctx, inception,
  4457. soaexpire, check_ksk, keyset_kskonly);
  4458. if (result != ISC_R_SUCCESS) {
  4459. dns_zone_log(zone, ISC_LOG_ERROR,
  4460. "zone_resigninc:add_sigs -> %s\n",
  4461. dns_result_totext(result));
  4462. goto failure;
  4463. }
  4464. /* Write changes to journal file. */
  4465. CHECK(zone_journal(zone, &sig_diff, "zone_resigninc"));
  4466. /* Everything has succeeded. Commit the changes. */
  4467. dns_db_closeversion(db, &version, ISC_TRUE);
  4468. failure:
  4469. dns_diff_clear(&sig_diff);
  4470. for (i = 0; i < nkeys; i++)
  4471. dst_key_free(&zone_keys[i]);
  4472. if (version != NULL) {
  4473. dns_db_closeversion(zone->db, &version, ISC_FALSE);
  4474. dns_db_detach(&db);
  4475. } else if (db != NULL)
  4476. dns_db_detach(&db);
  4477. if (result == ISC_R_SUCCESS) {
  4478. set_resigntime(zone);
  4479. LOCK_ZONE(zone);
  4480. zone_needdump(zone, DNS_DUMP_DELAY);
  4481. DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
  4482. UNLOCK_ZONE(zone);
  4483. } else {
  4484. /*
  4485. * Something failed. Retry in 5 minutes.
  4486. */
  4487. isc_interval_t ival;
  4488. isc_interval_set(&ival, 300, 0);
  4489. isc_time_nowplusinterval(&zone->resigntime, &ival);
  4490. }
  4491. }
  4492. static isc_result_t
  4493. next_active(dns_db_t *db, dns_dbversion_t *version, dns_name_t *oldname,
  4494. dns_name_t *newname, isc_boolean_t bottom)
  4495. {
  4496. isc_result_t result;
  4497. dns_dbiterator_t *dbit = NULL;
  4498. dns_rdatasetiter_t *rdsit = NULL;
  4499. dns_dbnode_t *node = NULL;
  4500. CHECK(dns_db_createiterator(db, DNS_DB_NONSEC3, &dbit));
  4501. CHECK(dns_dbiterator_seek(dbit, oldname));
  4502. do {
  4503. result = dns_dbiterator_next(dbit);
  4504. if (result == ISC_R_NOMORE)
  4505. CHECK(dns_dbiterator_first(dbit));
  4506. CHECK(dns_dbiterator_current(dbit, &node, newname));
  4507. if (bottom && dns_name_issubdomain(newname, oldname) &&
  4508. !dns_name_equal(newname, oldname)) {
  4509. dns_db_detachnode(db, &node);
  4510. continue;
  4511. }
  4512. /*
  4513. * Is this node empty?
  4514. */
  4515. CHECK(dns_db_allrdatasets(db, node, version, 0, &rdsit));
  4516. result = dns_rdatasetiter_first(rdsit);
  4517. dns_db_detachnode(db, &node);
  4518. dns_rdatasetiter_destroy(&rdsit);
  4519. if (result != ISC_R_NOMORE)
  4520. break;
  4521. } while (1);
  4522. failure:
  4523. if (node != NULL)
  4524. dns_db_detachnode(db, &node);
  4525. if (dbit != NULL)
  4526. dns_dbiterator_destroy(&dbit);
  4527. return (result);
  4528. }
  4529. static isc_boolean_t
  4530. signed_with_key(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
  4531. dns_rdatatype_t type, dst_key_t *key)
  4532. {
  4533. isc_result_t result;
  4534. dns_rdataset_t rdataset;
  4535. dns_rdata_t rdata = DNS_RDATA_INIT;
  4536. dns_rdata_rrsig_t rrsig;
  4537. dns_rdataset_init(&rdataset);
  4538. result = dns_db_findrdataset(db, node, version, dns_rdatatype_rrsig,
  4539. type, 0, &rdataset, NULL);
  4540. if (result != ISC_R_SUCCESS) {
  4541. INSIST(!dns_rdataset_isassociated(&rdataset));
  4542. return (ISC_FALSE);
  4543. }
  4544. for (result = dns_rdataset_first(&rdataset);
  4545. result == ISC_R_SUCCESS;
  4546. result = dns_rdataset_next(&rdataset)) {
  4547. dns_rdataset_current(&rdataset, &rdata);
  4548. result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
  4549. INSIST(result == ISC_R_SUCCESS);
  4550. if (rrsig.algorithm == dst_key_alg(key) &&
  4551. rrsig.keyid == dst_key_id(key)) {
  4552. dns_rdataset_disassociate(&rdataset);
  4553. return (ISC_TRUE);
  4554. }
  4555. dns_rdata_reset(&rdata);
  4556. }
  4557. dns_rdataset_disassociate(&rdataset);
  4558. return (ISC_FALSE);
  4559. }
  4560. static isc_result_t
  4561. add_nsec(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
  4562. dns_dbnode_t *node, dns_ttl_t ttl, isc_boolean_t bottom,
  4563. dns_diff_t *diff)
  4564. {
  4565. dns_fixedname_t fixed;
  4566. dns_name_t *next;
  4567. dns_rdata_t rdata = DNS_RDATA_INIT;
  4568. isc_result_t result;
  4569. unsigned char nsecbuffer[DNS_NSEC_BUFFERSIZE];
  4570. dns_fixedname_init(&fixed);
  4571. next = dns_fixedname_name(&fixed);
  4572. CHECK(next_active(db, version, name, next, bottom));
  4573. CHECK(dns_nsec_buildrdata(db, version, node, next, nsecbuffer,
  4574. &rdata));
  4575. CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADD, name, ttl,
  4576. &rdata));
  4577. failure:
  4578. return (result);
  4579. }
  4580. static isc_result_t
  4581. sign_a_node(dns_db_t *db, dns_name_t *name, dns_dbnode_t *node,
  4582. dns_dbversion_t *version, isc_boolean_t build_nsec3,
  4583. isc_boolean_t build_nsec, dst_key_t *key,
  4584. isc_stdtime_t inception, isc_stdtime_t expire,
  4585. unsigned int minimum, isc_boolean_t is_ksk,
  4586. isc_boolean_t keyset_kskonly, isc_boolean_t *delegation,
  4587. dns_diff_t *diff, isc_int32_t *signatures, isc_mem_t *mctx)
  4588. {
  4589. isc_result_t result;
  4590. dns_rdatasetiter_t *iterator = NULL;
  4591. dns_rdataset_t rdataset;
  4592. dns_rdata_t rdata = DNS_RDATA_INIT;
  4593. isc_buffer_t buffer;
  4594. unsigned char data[1024];
  4595. isc_boolean_t seen_soa, seen_ns, seen_rr, seen_dname, seen_nsec,
  4596. seen_nsec3, seen_ds;
  4597. isc_boolean_t bottom;
  4598. result = dns_db_allrdatasets(db, node, version, 0, &iterator);
  4599. if (result != ISC_R_SUCCESS) {
  4600. if (result == ISC_R_NOTFOUND)
  4601. result = ISC_R_SUCCESS;
  4602. return (result);
  4603. }
  4604. dns_rdataset_init(&rdataset);
  4605. isc_buffer_init(&buffer, data, sizeof(data));
  4606. seen_rr = seen_soa = seen_ns = seen_dname = seen_nsec =
  4607. seen_nsec3 = seen_ds = ISC_FALSE;
  4608. for (result = dns_rdatasetiter_first(iterator);
  4609. result == ISC_R_SUCCESS;
  4610. result = dns_rdatasetiter_next(iterator)) {
  4611. dns_rdatasetiter_current(iterator, &rdataset);
  4612. if (rdataset.type == dns_rdatatype_soa)
  4613. seen_soa = ISC_TRUE;
  4614. else if (rdataset.type == dns_rdatatype_ns)
  4615. seen_ns = ISC_TRUE;
  4616. else if (rdataset.type == dns_rdatatype_ds)
  4617. seen_ds = ISC_TRUE;
  4618. else if (rdataset.type == dns_rdatatype_dname)
  4619. seen_dname = ISC_TRUE;
  4620. else if (rdataset.type == dns_rdatatype_nsec)
  4621. seen_nsec = ISC_TRUE;
  4622. else if (rdataset.type == dns_rdatatype_nsec3)
  4623. seen_nsec3 = ISC_TRUE;
  4624. if (rdataset.type != dns_rdatatype_rrsig)
  4625. seen_rr = ISC_TRUE;
  4626. dns_rdataset_disassociate(&rdataset);
  4627. }
  4628. if (result != ISC_R_NOMORE)
  4629. goto failure;
  4630. if (seen_ns && !seen_soa)
  4631. *delegation = ISC_TRUE;
  4632. /*
  4633. * Going from insecure to NSEC3.
  4634. * Don't generate NSEC3 records for NSEC3 records.
  4635. */
  4636. if (build_nsec3 && !seen_nsec3 && seen_rr) {
  4637. isc_boolean_t unsecure = !seen_ds && seen_ns && !seen_soa;
  4638. CHECK(dns_nsec3_addnsec3s(db, version, name, minimum,
  4639. unsecure, diff));
  4640. (*signatures)--;
  4641. }
  4642. /*
  4643. * Going from insecure to NSEC.
  4644. * Don't generate NSEC records for NSEC3 records.
  4645. */
  4646. if (build_nsec && !seen_nsec3 && !seen_nsec && seen_rr) {
  4647. /* Build and add NSEC. */
  4648. bottom = (seen_ns && !seen_soa) || seen_dname;
  4649. /*
  4650. * Build a NSEC record except at the origin.
  4651. */
  4652. if (!dns_name_equal(name, dns_db_origin(db))) {
  4653. CHECK(add_nsec(db, version, name, node, minimum,
  4654. bottom, diff));
  4655. /* Count a NSEC generation as a signature generation. */
  4656. (*signatures)--;
  4657. }
  4658. }
  4659. result = dns_rdatasetiter_first(iterator);
  4660. while (result == ISC_R_SUCCESS) {
  4661. dns_rdatasetiter_current(iterator, &rdataset);
  4662. if (rdataset.type == dns_rdatatype_soa ||
  4663. rdataset.type == dns_rdatatype_rrsig)
  4664. goto next_rdataset;
  4665. if (rdataset.type == dns_rdatatype_dnskey) {
  4666. if (!is_ksk && keyset_kskonly)
  4667. goto next_rdataset;
  4668. } else if (is_ksk)
  4669. goto next_rdataset;
  4670. if (*delegation &&
  4671. rdataset.type != dns_rdatatype_ds &&
  4672. rdataset.type != dns_rdatatype_nsec)
  4673. goto next_rdataset;
  4674. if (signed_with_key(db, node, version, rdataset.type, key))
  4675. goto next_rdataset;
  4676. /* Calculate the signature, creating a RRSIG RDATA. */
  4677. isc_buffer_clear(&buffer);
  4678. CHECK(dns_dnssec_sign(name, &rdataset, key, &inception,
  4679. &expire, mctx, &buffer, &rdata));
  4680. /* Update the database and journal with the RRSIG. */
  4681. /* XXX inefficient - will cause dataset merging */
  4682. CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADDRESIGN,
  4683. name, rdataset.ttl, &rdata));
  4684. dns_rdata_reset(&rdata);
  4685. (*signatures)--;
  4686. next_rdataset:
  4687. dns_rdataset_disassociate(&rdataset);
  4688. result = dns_rdatasetiter_next(iterator);
  4689. }
  4690. if (result == ISC_R_NOMORE)
  4691. result = ISC_R_SUCCESS;
  4692. if (seen_dname)
  4693. *delegation = ISC_TRUE;
  4694. failure:
  4695. if (dns_rdataset_isassociated(&rdataset))
  4696. dns_rdataset_disassociate(&rdataset);
  4697. if (iterator != NULL)
  4698. dns_rdatasetiter_destroy(&iterator);
  4699. return (result);
  4700. }
  4701. /*
  4702. * If 'update_only' is set then don't create a NSEC RRset if it doesn't exist.
  4703. */
  4704. static isc_result_t
  4705. updatesecure(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
  4706. dns_ttl_t minimum, isc_boolean_t update_only, dns_diff_t *diff)
  4707. {
  4708. isc_result_t result;
  4709. dns_rdataset_t rdataset;
  4710. dns_dbnode_t *node = NULL;
  4711. CHECK(dns_db_getoriginnode(db, &node));
  4712. if (update_only) {
  4713. dns_rdataset_init(&rdataset);
  4714. result = dns_db_findrdataset(db, node, version,
  4715. dns_rdatatype_nsec,
  4716. dns_rdatatype_none,
  4717. 0, &rdataset, NULL);
  4718. if (dns_rdataset_isassociated(&rdataset))
  4719. dns_rdataset_disassociate(&rdataset);
  4720. if (result == ISC_R_NOTFOUND)
  4721. goto success;
  4722. if (result != ISC_R_SUCCESS)
  4723. goto failure;
  4724. }
  4725. CHECK(delete_nsec(db, version, node, name, diff));
  4726. CHECK(add_nsec(db, version, name, node, minimum, ISC_FALSE, diff));
  4727. success:
  4728. result = ISC_R_SUCCESS;
  4729. failure:
  4730. if (node != NULL)
  4731. dns_db_detachnode(db, &node);
  4732. return (result);
  4733. }
  4734. static isc_result_t
  4735. updatesignwithkey(dns_zone_t *zone, dns_signing_t *signing,
  4736. dns_dbversion_t *version, isc_boolean_t build_nsec3,
  4737. dns_ttl_t minimum, dns_diff_t *diff)
  4738. {
  4739. isc_result_t result;
  4740. dns_dbnode_t *node = NULL;
  4741. dns_rdataset_t rdataset;
  4742. dns_rdata_t rdata = DNS_RDATA_INIT;
  4743. unsigned char data[5];
  4744. isc_boolean_t seen_done = ISC_FALSE;
  4745. isc_boolean_t have_rr = ISC_FALSE;
  4746. dns_rdataset_init(&rdataset);
  4747. result = dns_db_getoriginnode(signing->db, &node);
  4748. if (result != ISC_R_SUCCESS)
  4749. goto failure;
  4750. result = dns_db_findrdataset(signing->db, node, version,
  4751. zone->privatetype, dns_rdatatype_none,
  4752. 0, &rdataset, NULL);
  4753. if (result == ISC_R_NOTFOUND) {
  4754. INSIST(!dns_rdataset_isassociated(&rdataset));
  4755. result = ISC_R_SUCCESS;
  4756. goto failure;
  4757. }
  4758. if (result != ISC_R_SUCCESS) {
  4759. INSIST(!dns_rdataset_isassociated(&rdataset));
  4760. goto failure;
  4761. }
  4762. for (result = dns_rdataset_first(&rdataset);
  4763. result == ISC_R_SUCCESS;
  4764. result = dns_rdataset_next(&rdataset)) {
  4765. dns_rdataset_current(&rdataset, &rdata);
  4766. /*
  4767. * If we don't match the algorithm or keyid skip the record.
  4768. */
  4769. if (rdata.length != 5 ||
  4770. rdata.data[0] != signing->algorithm ||
  4771. rdata.data[1] != ((signing->keyid >> 8) & 0xff) ||
  4772. rdata.data[2] != (signing->keyid & 0xff)) {
  4773. have_rr = ISC_TRUE;
  4774. dns_rdata_reset(&rdata);
  4775. continue;
  4776. }
  4777. /*
  4778. * We have a match. If we were signing (!signing->delete)
  4779. * and we already have a record indicating that we have
  4780. * finished signing (rdata.data[4] != 0) then keep it.
  4781. * Otherwise it needs to be deleted as we have removed all
  4782. * the signatures (signing->delete), so any record indicating
  4783. * completion is now out of date, or we have finished signing
  4784. * with the new record so we no longer need to remember that
  4785. * we need to sign the zone with the matching key across a
  4786. * nameserver re-start.
  4787. */
  4788. if (!signing->delete && rdata.data[4] != 0) {
  4789. seen_done = ISC_TRUE;
  4790. have_rr = ISC_TRUE;
  4791. } else
  4792. CHECK(update_one_rr(signing->db, version, diff,
  4793. DNS_DIFFOP_DEL, &zone->origin,
  4794. rdataset.ttl, &rdata));
  4795. dns_rdata_reset(&rdata);
  4796. }
  4797. if (result == ISC_R_NOMORE)
  4798. result = ISC_R_SUCCESS;
  4799. if (!signing->delete && !seen_done) {
  4800. /*
  4801. * If we were signing then we need to indicate that we have
  4802. * finished signing the zone with this key. If it is already
  4803. * there we don't need to add it a second time.
  4804. */
  4805. data[0] = signing->algorithm;
  4806. data[1] = (signing->keyid >> 8) & 0xff;
  4807. data[2] = signing->keyid & 0xff;
  4808. data[3] = 0;
  4809. data[4] = 1;
  4810. rdata.length = sizeof(data);
  4811. rdata.data = data;
  4812. rdata.type = zone->privatetype;
  4813. rdata.rdclass = dns_db_class(signing->db);
  4814. CHECK(update_one_rr(signing->db, version, diff, DNS_DIFFOP_ADD,
  4815. &zone->origin, rdataset.ttl, &rdata));
  4816. } else if (!have_rr) {
  4817. dns_name_t *origin = dns_db_origin(signing->db);
  4818. /*
  4819. * Rebuild the NSEC/NSEC3 record for the origin as we no
  4820. * longer have any private records.
  4821. */
  4822. if (build_nsec3)
  4823. CHECK(dns_nsec3_addnsec3s(signing->db, version, origin,
  4824. minimum, ISC_FALSE, diff));
  4825. CHECK(updatesecure(signing->db, version, origin, minimum,
  4826. ISC_TRUE, diff));
  4827. }
  4828. failure:
  4829. if (dns_rdataset_isassociated(&rdataset))
  4830. dns_rdataset_disassociate(&rdataset);
  4831. if (node != NULL)
  4832. dns_db_detachnode(signing->db, &node);
  4833. return (result);
  4834. }
  4835. /*
  4836. * If 'active' is set then we are not done with the chain yet so only
  4837. * delete the nsec3param record which indicates a full chain exists
  4838. * (flags == 0).
  4839. */
  4840. static isc_result_t
  4841. fixup_nsec3param(dns_db_t *db, dns_dbversion_t *ver, dns_nsec3chain_t *chain,
  4842. isc_boolean_t active, dns_rdatatype_t privatetype,
  4843. dns_diff_t *diff)
  4844. {
  4845. dns_dbnode_t *node = NULL;
  4846. dns_name_t *name = dns_db_origin(db);
  4847. dns_rdata_t rdata = DNS_RDATA_INIT;
  4848. dns_rdataset_t rdataset;
  4849. dns_rdata_nsec3param_t nsec3param;
  4850. isc_result_t result;
  4851. isc_buffer_t buffer;
  4852. unsigned char parambuf[DNS_NSEC3PARAM_BUFFERSIZE];
  4853. dns_ttl_t ttl = 0;
  4854. dns_rdataset_init(&rdataset);
  4855. result = dns_db_getoriginnode(db, &node);
  4856. RUNTIME_CHECK(result == ISC_R_SUCCESS);
  4857. result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param,
  4858. 0, 0, &rdataset, NULL);
  4859. if (result == ISC_R_NOTFOUND)
  4860. goto try_private;
  4861. if (result != ISC_R_SUCCESS)
  4862. goto failure;
  4863. /*
  4864. * Preserve the existing ttl.
  4865. */
  4866. ttl = rdataset.ttl;
  4867. /*
  4868. * Delete all NSEC3PARAM records which match that in nsec3chain.
  4869. */
  4870. for (result = dns_rdataset_first(&rdataset);
  4871. result == ISC_R_SUCCESS;
  4872. result = dns_rdataset_next(&rdataset)) {
  4873. dns_rdataset_current(&rdataset, &rdata);
  4874. CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
  4875. if (nsec3param.hash != chain->nsec3param.hash ||
  4876. (active && nsec3param.flags != 0) ||
  4877. nsec3param.iterations != chain->nsec3param.iterations ||
  4878. nsec3param.salt_length != chain->nsec3param.salt_length ||
  4879. memcmp(nsec3param.salt, chain->nsec3param.salt,
  4880. nsec3param.salt_length)) {
  4881. dns_rdata_reset(&rdata);
  4882. continue;
  4883. }
  4884. CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL,
  4885. name, rdataset.ttl, &rdata));
  4886. dns_rdata_reset(&rdata);
  4887. }
  4888. if (result != ISC_R_NOMORE)
  4889. goto failure;
  4890. dns_rdataset_disassociate(&rdataset);
  4891. try_private:
  4892. if (active)
  4893. goto add;
  4894. /*
  4895. * Delete all private records which match that in nsec3chain.
  4896. */
  4897. result = dns_db_findrdataset(db, node, ver, privatetype,
  4898. 0, 0, &rdataset, NULL);
  4899. if (result == ISC_R_NOTFOUND)
  4900. goto add;
  4901. if (result != ISC_R_SUCCESS)
  4902. goto failure;
  4903. for (result = dns_rdataset_first(&rdataset);
  4904. result == ISC_R_SUCCESS;
  4905. result = dns_rdataset_next(&rdataset)) {
  4906. dns_rdata_t private = DNS_RDATA_INIT;
  4907. unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
  4908. dns_rdataset_current(&rdataset, &private);
  4909. if (!dns_nsec3param_fromprivate(&private, &rdata,
  4910. buf, sizeof(buf)))
  4911. continue;
  4912. CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
  4913. if (nsec3param.hash != chain->nsec3param.hash ||
  4914. nsec3param.iterations != chain->nsec3param.iterations ||
  4915. nsec3param.salt_length != chain->nsec3param.salt_length ||
  4916. memcmp(nsec3param.salt, chain->nsec3param.salt,
  4917. nsec3param.salt_length)) {
  4918. dns_rdata_reset(&rdata);
  4919. continue;
  4920. }
  4921. CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL,
  4922. name, rdataset.ttl, &private));
  4923. dns_rdata_reset(&rdata);
  4924. }
  4925. if (result != ISC_R_NOMORE)
  4926. goto failure;
  4927. add:
  4928. if ((chain->nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) {
  4929. result = ISC_R_SUCCESS;
  4930. goto failure;
  4931. }
  4932. /*
  4933. * Add a NSEC3PARAM record which matches that in nsec3chain but
  4934. * with all flags bits cleared.
  4935. *
  4936. * Note: we do not clear chain->nsec3param.flags as this change
  4937. * may be reversed.
  4938. */
  4939. isc_buffer_init(&buffer, &parambuf, sizeof(parambuf));
  4940. CHECK(dns_rdata_fromstruct(&rdata, dns_db_class(db),
  4941. dns_rdatatype_nsec3param,
  4942. &chain->nsec3param, &buffer));
  4943. rdata.data[1] = 0; /* Clear flag bits. */
  4944. CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD, name, ttl, &rdata));
  4945. failure:
  4946. dns_db_detachnode(db, &node);
  4947. if (dns_rdataset_isassociated(&rdataset))
  4948. dns_rdataset_disassociate(&rdataset);
  4949. return (result);
  4950. }
  4951. static isc_result_t
  4952. delete_nsec(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node,
  4953. dns_name_t *name, dns_diff_t *diff)
  4954. {
  4955. dns_rdataset_t rdataset;
  4956. isc_result_t result;
  4957. dns_rdataset_init(&rdataset);
  4958. result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec,
  4959. 0, 0, &rdataset, NULL);
  4960. if (result == ISC_R_NOTFOUND)
  4961. return (ISC_R_SUCCESS);
  4962. if (result != ISC_R_SUCCESS)
  4963. return (result);
  4964. for (result = dns_rdataset_first(&rdataset);
  4965. result == ISC_R_SUCCESS;
  4966. result = dns_rdataset_next(&rdataset)) {
  4967. dns_rdata_t rdata = DNS_RDATA_INIT;
  4968. dns_rdataset_current(&rdataset, &rdata);
  4969. CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name,
  4970. rdataset.ttl, &rdata));
  4971. }
  4972. if (result == ISC_R_NOMORE)
  4973. result = ISC_R_SUCCESS;
  4974. failure:
  4975. dns_rdataset_disassociate(&rdataset);
  4976. return (result);
  4977. }
  4978. static isc_result_t
  4979. deletematchingnsec3(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node,
  4980. dns_name_t *name, const dns_rdata_nsec3param_t *param,
  4981. dns_diff_t *diff)
  4982. {
  4983. dns_rdataset_t rdataset;
  4984. dns_rdata_nsec3_t nsec3;
  4985. isc_result_t result;
  4986. dns_rdataset_init(&rdataset);
  4987. result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3,
  4988. 0, 0, &rdataset, NULL);
  4989. if (result == ISC_R_NOTFOUND)
  4990. return (ISC_R_SUCCESS);
  4991. if (result != ISC_R_SUCCESS)
  4992. return (result);
  4993. for (result = dns_rdataset_first(&rdataset);
  4994. result == ISC_R_SUCCESS;
  4995. result = dns_rdataset_next(&rdataset)) {
  4996. dns_rdata_t rdata = DNS_RDATA_INIT;
  4997. dns_rdataset_current(&rdataset, &rdata);
  4998. CHECK(dns_rdata_tostruct(&rdata, &nsec3, NULL));
  4999. if (nsec3.hash != param->hash ||
  5000. nsec3.iterations != param->iterations ||
  5001. nsec3.salt_length != param->salt_length ||
  5002. memcmp(nsec3.salt, param->salt, nsec3.salt_length))
  5003. continue;
  5004. CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name,
  5005. rdataset.ttl, &rdata));
  5006. }
  5007. if (result == ISC_R_NOMORE)
  5008. result = ISC_R_SUCCESS;
  5009. failure:
  5010. dns_rdataset_disassociate(&rdataset);
  5011. return (result);
  5012. }
  5013. static isc_result_t
  5014. need_nsec_chain(dns_db_t *db, dns_dbversion_t *ver,
  5015. const dns_rdata_nsec3param_t *param,
  5016. isc_boolean_t *answer)
  5017. {
  5018. dns_dbnode_t *node = NULL;
  5019. dns_rdata_t rdata = DNS_RDATA_INIT;
  5020. dns_rdata_nsec3param_t myparam;
  5021. dns_rdataset_t rdataset;
  5022. isc_result_t result;
  5023. *answer = ISC_FALSE;
  5024. result = dns_db_getoriginnode(db, &node);
  5025. RUNTIME_CHECK(result == ISC_R_SUCCESS);
  5026. dns_rdataset_init(&rdataset);
  5027. result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec,
  5028. 0, 0, &rdataset, NULL);
  5029. if (result == ISC_R_SUCCESS) {
  5030. dns_rdataset_disassociate(&rdataset);
  5031. dns_db_detachnode(db, &node);
  5032. return (result);
  5033. }
  5034. if (result != ISC_R_NOTFOUND) {
  5035. dns_db_detachnode(db, &node);
  5036. return (result);
  5037. }
  5038. result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param,
  5039. 0, 0, &rdataset, NULL);
  5040. if (result == ISC_R_NOTFOUND) {
  5041. *answer = ISC_TRUE;
  5042. dns_db_detachnode(db, &node);
  5043. return (ISC_R_SUCCESS);
  5044. }
  5045. if (result != ISC_R_SUCCESS) {
  5046. dns_db_detachnode(db, &node);
  5047. return (result);
  5048. }
  5049. for (result = dns_rdataset_first(&rdataset);
  5050. result == ISC_R_SUCCESS;
  5051. result = dns_rdataset_next(&rdataset)) {
  5052. dns_rdataset_current(&rdataset, &rdata);
  5053. CHECK(dns_rdata_tostruct(&rdata, &myparam, NULL));
  5054. dns_rdata_reset(&rdata);
  5055. /*
  5056. * Ignore any NSEC3PARAM removals.
  5057. */
  5058. if (NSEC3REMOVE(myparam.flags))
  5059. continue;
  5060. /*
  5061. * Ignore the chain that we are in the process of deleting.
  5062. */
  5063. if (myparam.hash == param->hash &&
  5064. myparam.iterations == param->iterations &&
  5065. myparam.salt_length == param->salt_length &&
  5066. !memcmp(myparam.salt, param->salt, myparam.salt_length))
  5067. continue;
  5068. /*
  5069. * Found an active NSEC3 chain.
  5070. */
  5071. break;
  5072. }
  5073. if (result == ISC_R_NOMORE) {
  5074. *answer = ISC_TRUE;
  5075. result = ISC_R_SUCCESS;
  5076. }
  5077. failure:
  5078. if (dns_rdataset_isassociated(&rdataset))
  5079. dns_rdataset_disassociate(&rdataset);
  5080. dns_db_detachnode(db, &node);
  5081. return (result);
  5082. }
  5083. static isc_result_t
  5084. update_sigs(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *version,
  5085. dst_key_t *zone_keys[], unsigned int nkeys, dns_zone_t *zone,
  5086. isc_stdtime_t inception, isc_stdtime_t expire, isc_stdtime_t now,
  5087. isc_boolean_t check_ksk, isc_boolean_t keyset_kskonly,
  5088. dns_diff_t *sig_diff)
  5089. {
  5090. dns_difftuple_t *tuple;
  5091. isc_result_t result;
  5092. for (tuple = ISC_LIST_HEAD(diff->tuples);
  5093. tuple != NULL;
  5094. tuple = ISC_LIST_HEAD(diff->tuples)) {
  5095. result = del_sigs(zone, db, version, &tuple->name,
  5096. tuple->rdata.type, sig_diff,
  5097. zone_keys, nkeys, now, ISC_FALSE);
  5098. if (result != ISC_R_SUCCESS) {
  5099. dns_zone_log(zone, ISC_LOG_ERROR,
  5100. "update_sigs:del_sigs -> %s\n",
  5101. dns_result_totext(result));
  5102. return (result);
  5103. }
  5104. result = add_sigs(db, version, &tuple->name,
  5105. tuple->rdata.type, sig_diff,
  5106. zone_keys, nkeys, zone->mctx, inception,
  5107. expire, check_ksk, keyset_kskonly);
  5108. if (result != ISC_R_SUCCESS) {
  5109. dns_zone_log(zone, ISC_LOG_ERROR,
  5110. "update_sigs:add_sigs -> %s\n",
  5111. dns_result_totext(result));
  5112. return (result);
  5113. }
  5114. do {
  5115. dns_difftuple_t *next = ISC_LIST_NEXT(tuple, link);
  5116. while (next != NULL &&
  5117. (tuple->rdata.type != next->rdata.type ||
  5118. !dns_name_equal(&tuple->name, &next->name)))
  5119. next = ISC_LIST_NEXT(next, link);
  5120. ISC_LIST_UNLINK(diff->tuples, tuple, link);
  5121. dns_diff_appendminimal(sig_diff, &tuple);
  5122. INSIST(tuple == NULL);
  5123. tuple = next;
  5124. } while (tuple != NULL);
  5125. }
  5126. return (ISC_R_SUCCESS);
  5127. }
  5128. /*
  5129. * Incrementally build and sign a new NSEC3 chain using the parameters
  5130. * requested.
  5131. */
  5132. static void
  5133. zone_nsec3chain(dns_zone_t *zone) {
  5134. dns_db_t *db = NULL;
  5135. dns_dbnode_t *node = NULL;
  5136. dns_dbversion_t *version = NULL;
  5137. dns_diff_t sig_diff;
  5138. dns_diff_t nsec_diff;
  5139. dns_diff_t nsec3_diff;
  5140. dns_diff_t param_diff;
  5141. dns_fixedname_t fixed;
  5142. dns_fixedname_t nextfixed;
  5143. dns_name_t *name, *nextname;
  5144. dns_rdataset_t rdataset;
  5145. dns_nsec3chain_t *nsec3chain = NULL, *nextnsec3chain;
  5146. dns_nsec3chainlist_t cleanup;
  5147. dst_key_t *zone_keys[DNS_MAXZONEKEYS];
  5148. isc_int32_t signatures;
  5149. isc_boolean_t check_ksk, keyset_kskonly;
  5150. isc_boolean_t delegation;
  5151. isc_boolean_t first;
  5152. isc_result_t result;
  5153. isc_stdtime_t now, inception, soaexpire, expire;
  5154. isc_uint32_t jitter;
  5155. unsigned int i;
  5156. unsigned int nkeys = 0;
  5157. isc_uint32_t nodes;
  5158. isc_boolean_t unsecure = ISC_FALSE;
  5159. isc_boolean_t seen_soa, seen_ns, seen_dname, seen_ds;
  5160. isc_boolean_t seen_nsec, seen_nsec3, seen_rr;
  5161. dns_rdatasetiter_t *iterator = NULL;
  5162. isc_boolean_t buildnsecchain;
  5163. isc_boolean_t updatensec = ISC_FALSE;
  5164. dns_rdatatype_t privatetype = zone->privatetype;
  5165. dns_rdataset_init(&rdataset);
  5166. dns_fixedname_init(&fixed);
  5167. name = dns_fixedname_name(&fixed);
  5168. dns_fixedname_init(&nextfixed);
  5169. nextname = dns_fixedname_name(&nextfixed);
  5170. dns_diff_init(zone->mctx, &param_diff);
  5171. dns_diff_init(zone->mctx, &nsec3_diff);
  5172. dns_diff_init(zone->mctx, &nsec_diff);
  5173. dns_diff_init(zone->mctx, &sig_diff);
  5174. sig_diff.resign = zone->sigresigninginterval;
  5175. ISC_LIST_INIT(cleanup);
  5176. /*
  5177. * Updates are disabled. Pause for 5 minutes.
  5178. */
  5179. if (zone->update_disabled) {
  5180. result = ISC_R_FAILURE;
  5181. goto failure;
  5182. }
  5183. ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
  5184. dns_db_attach(zone->db, &db);
  5185. ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
  5186. result = dns_db_newversion(db, &version);
  5187. if (result != ISC_R_SUCCESS) {
  5188. dns_zone_log(zone, ISC_LOG_ERROR,
  5189. "zone_nsec3chain:dns_db_newversion -> %s\n",
  5190. dns_result_totext(result));
  5191. goto failure;
  5192. }
  5193. result = find_zone_keys(zone, db, version, zone->mctx,
  5194. DNS_MAXZONEKEYS, zone_keys, &nkeys);
  5195. if (result != ISC_R_SUCCESS) {
  5196. dns_zone_log(zone, ISC_LOG_ERROR,
  5197. "zone_nsec3chain:find_zone_keys -> %s\n",
  5198. dns_result_totext(result));
  5199. goto failure;
  5200. }
  5201. isc_stdtime_get(&now);
  5202. inception = now - 3600; /* Allow for clock skew. */
  5203. soaexpire = now + dns_zone_getsigvalidityinterval(zone);
  5204. /*
  5205. * Spread out signatures over time if they happen to be
  5206. * clumped. We don't do this for each add_sigs() call as
  5207. * we still want some clustering to occur.
  5208. */
  5209. isc_random_get(&jitter);
  5210. expire = soaexpire - jitter % 3600;
  5211. check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
  5212. keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
  5213. /*
  5214. * We keep pulling nodes off each iterator in turn until
  5215. * we have no more nodes to pull off or we reach the limits
  5216. * for this quantum.
  5217. */
  5218. nodes = zone->nodes;
  5219. signatures = zone->signatures;
  5220. LOCK_ZONE(zone);
  5221. nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
  5222. UNLOCK_ZONE(zone);
  5223. first = ISC_TRUE;
  5224. if (nsec3chain != NULL)
  5225. nsec3chain->save_delete_nsec = nsec3chain->delete_nsec;
  5226. /*
  5227. * Generate new NSEC3 chains first.
  5228. */
  5229. while (nsec3chain != NULL && nodes-- > 0 && signatures > 0) {
  5230. LOCK_ZONE(zone);
  5231. nextnsec3chain = ISC_LIST_NEXT(nsec3chain, link);
  5232. ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
  5233. if (nsec3chain->done || nsec3chain->db != zone->db) {
  5234. ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link);
  5235. ISC_LIST_APPEND(cleanup, nsec3chain, link);
  5236. }
  5237. ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
  5238. UNLOCK_ZONE(zone);
  5239. if (ISC_LIST_TAIL(cleanup) == nsec3chain)
  5240. goto next_addchain;
  5241. /*
  5242. * Possible future db.
  5243. */
  5244. if (nsec3chain->db != db) {
  5245. goto next_addchain;
  5246. }
  5247. if (NSEC3REMOVE(nsec3chain->nsec3param.flags))
  5248. goto next_addchain;
  5249. dns_dbiterator_current(nsec3chain->dbiterator, &node, name);
  5250. if (nsec3chain->delete_nsec) {
  5251. delegation = ISC_FALSE;
  5252. dns_dbiterator_pause(nsec3chain->dbiterator);
  5253. CHECK(delete_nsec(db, version, node, name, &nsec_diff));
  5254. goto next_addnode;
  5255. }
  5256. /*
  5257. * On the first pass we need to check if the current node
  5258. * has not been obscured.
  5259. */
  5260. delegation = ISC_FALSE;
  5261. unsecure = ISC_FALSE;
  5262. if (first) {
  5263. dns_fixedname_t ffound;
  5264. dns_name_t *found;
  5265. dns_fixedname_init(&ffound);
  5266. found = dns_fixedname_name(&ffound);
  5267. result = dns_db_find(db, name, version,
  5268. dns_rdatatype_soa,
  5269. DNS_DBFIND_NOWILD, 0, NULL, found,
  5270. NULL, NULL);
  5271. if ((result == DNS_R_DELEGATION ||
  5272. result == DNS_R_DNAME) &&
  5273. !dns_name_equal(name, found)) {
  5274. /*
  5275. * Remember the obscuring name so that
  5276. * we skip all obscured names.
  5277. */
  5278. dns_name_copy(found, name, NULL);
  5279. delegation = ISC_TRUE;
  5280. goto next_addnode;
  5281. }
  5282. }
  5283. /*
  5284. * Check to see if this is a bottom of zone node.
  5285. */
  5286. result = dns_db_allrdatasets(db, node, version, 0, &iterator);
  5287. if (result == ISC_R_NOTFOUND) /* Empty node? */
  5288. goto next_addnode;
  5289. if (result != ISC_R_SUCCESS)
  5290. goto failure;
  5291. seen_soa = seen_ns = seen_dname = seen_ds = seen_nsec =
  5292. ISC_FALSE;
  5293. for (result = dns_rdatasetiter_first(iterator);
  5294. result == ISC_R_SUCCESS;
  5295. result = dns_rdatasetiter_next(iterator)) {
  5296. dns_rdatasetiter_current(iterator, &rdataset);
  5297. INSIST(rdataset.type != dns_rdatatype_nsec3);
  5298. if (rdataset.type == dns_rdatatype_soa)
  5299. seen_soa = ISC_TRUE;
  5300. else if (rdataset.type == dns_rdatatype_ns)
  5301. seen_ns = ISC_TRUE;
  5302. else if (rdataset.type == dns_rdatatype_dname)
  5303. seen_dname = ISC_TRUE;
  5304. else if (rdataset.type == dns_rdatatype_ds)
  5305. seen_ds = ISC_TRUE;
  5306. else if (rdataset.type == dns_rdatatype_nsec)
  5307. seen_nsec = ISC_TRUE;
  5308. dns_rdataset_disassociate(&rdataset);
  5309. }
  5310. dns_rdatasetiter_destroy(&iterator);
  5311. /*
  5312. * Is there a NSEC chain than needs to be cleaned up?
  5313. */
  5314. if (seen_nsec)
  5315. nsec3chain->seen_nsec = ISC_TRUE;
  5316. if (seen_ns && !seen_soa && !seen_ds)
  5317. unsecure = ISC_TRUE;
  5318. if ((seen_ns && !seen_soa) || seen_dname)
  5319. delegation = ISC_TRUE;
  5320. /*
  5321. * Process one node.
  5322. */
  5323. dns_dbiterator_pause(nsec3chain->dbiterator);
  5324. result = dns_nsec3_addnsec3(db, version, name,
  5325. &nsec3chain->nsec3param,
  5326. zone->minimum, unsecure,
  5327. &nsec3_diff);
  5328. if (result != ISC_R_SUCCESS) {
  5329. dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
  5330. "dns_nsec3_addnsec3 -> %s\n",
  5331. dns_result_totext(result));
  5332. goto failure;
  5333. }
  5334. /*
  5335. * Treat each call to dns_nsec3_addnsec3() as if it's cost is
  5336. * two signatures. Additionally there will, in general, be
  5337. * two signature generated below.
  5338. *
  5339. * If we are only changing the optout flag the cost is half
  5340. * that of the cost of generating a completely new chain.
  5341. */
  5342. signatures -= 4;
  5343. /*
  5344. * Go onto next node.
  5345. */
  5346. next_addnode:
  5347. first = ISC_FALSE;
  5348. dns_db_detachnode(db, &node);
  5349. do {
  5350. result = dns_dbiterator_next(nsec3chain->dbiterator);
  5351. if (result == ISC_R_NOMORE && nsec3chain->delete_nsec) {
  5352. CHECK(fixup_nsec3param(db, version, nsec3chain,
  5353. ISC_FALSE, privatetype,
  5354. &param_diff));
  5355. LOCK_ZONE(zone);
  5356. ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
  5357. link);
  5358. UNLOCK_ZONE(zone);
  5359. ISC_LIST_APPEND(cleanup, nsec3chain, link);
  5360. goto next_addchain;
  5361. }
  5362. if (result == ISC_R_NOMORE) {
  5363. dns_dbiterator_pause(nsec3chain->dbiterator);
  5364. if (nsec3chain->seen_nsec) {
  5365. CHECK(fixup_nsec3param(db, version,
  5366. nsec3chain,
  5367. ISC_TRUE,
  5368. privatetype,
  5369. &param_diff));
  5370. nsec3chain->delete_nsec = ISC_TRUE;
  5371. goto same_addchain;
  5372. }
  5373. CHECK(fixup_nsec3param(db, version, nsec3chain,
  5374. ISC_FALSE, privatetype,
  5375. &param_diff));
  5376. LOCK_ZONE(zone);
  5377. ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
  5378. link);
  5379. UNLOCK_ZONE(zone);
  5380. ISC_LIST_APPEND(cleanup, nsec3chain, link);
  5381. goto next_addchain;
  5382. } else if (result != ISC_R_SUCCESS) {
  5383. dns_zone_log(zone, ISC_LOG_ERROR,
  5384. "zone_nsec3chain:"
  5385. "dns_dbiterator_next -> %s\n",
  5386. dns_result_totext(result));
  5387. goto failure;
  5388. } else if (delegation) {
  5389. dns_dbiterator_current(nsec3chain->dbiterator,
  5390. &node, nextname);
  5391. dns_db_detachnode(db, &node);
  5392. if (!dns_name_issubdomain(nextname, name))
  5393. break;
  5394. } else
  5395. break;
  5396. } while (1);
  5397. continue;
  5398. same_addchain:
  5399. CHECK(dns_dbiterator_first(nsec3chain->dbiterator));
  5400. first = ISC_TRUE;
  5401. continue;
  5402. next_addchain:
  5403. dns_dbiterator_pause(nsec3chain->dbiterator);
  5404. nsec3chain = nextnsec3chain;
  5405. first = ISC_TRUE;
  5406. if (nsec3chain != NULL)
  5407. nsec3chain->save_delete_nsec = nsec3chain->delete_nsec;
  5408. }
  5409. /*
  5410. * Process removals.
  5411. */
  5412. LOCK_ZONE(zone);
  5413. nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
  5414. UNLOCK_ZONE(zone);
  5415. first = ISC_TRUE;
  5416. buildnsecchain = ISC_FALSE;
  5417. while (nsec3chain != NULL && nodes-- > 0 && signatures > 0) {
  5418. LOCK_ZONE(zone);
  5419. nextnsec3chain = ISC_LIST_NEXT(nsec3chain, link);
  5420. UNLOCK_ZONE(zone);
  5421. if (nsec3chain->db != db)
  5422. goto next_removechain;
  5423. if (!NSEC3REMOVE(nsec3chain->nsec3param.flags))
  5424. goto next_removechain;
  5425. /*
  5426. * Work out if we need to build a NSEC chain as a consequence
  5427. * of removing this NSEC3 chain.
  5428. */
  5429. if (first && !updatensec &&
  5430. (nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_NONSEC) == 0) {
  5431. result = need_nsec_chain(db, version,
  5432. &nsec3chain->nsec3param,
  5433. &buildnsecchain);
  5434. if (result != ISC_R_SUCCESS) {
  5435. dns_zone_log(zone, ISC_LOG_ERROR,
  5436. "zone_nsec3chain:"
  5437. "need_nsec_chain -> %s\n",
  5438. dns_result_totext(result));
  5439. goto failure;
  5440. }
  5441. }
  5442. if (first)
  5443. dns_zone_log(zone, ISC_LOG_DEBUG(3), "zone_nsec3chain:"
  5444. "buildnsecchain = %u\n", buildnsecchain);
  5445. dns_dbiterator_current(nsec3chain->dbiterator, &node, name);
  5446. delegation = ISC_FALSE;
  5447. if (!buildnsecchain) {
  5448. /*
  5449. * Delete the NSECPARAM record that matches this chain.
  5450. */
  5451. if (first) {
  5452. result = fixup_nsec3param(db, version,
  5453. nsec3chain,
  5454. ISC_TRUE, privatetype,
  5455. &param_diff);
  5456. if (result != ISC_R_SUCCESS) {
  5457. dns_zone_log(zone, ISC_LOG_ERROR,
  5458. "zone_nsec3chain:"
  5459. "fixup_nsec3param -> %s\n",
  5460. dns_result_totext(result));
  5461. goto failure;
  5462. }
  5463. }
  5464. /*
  5465. * Delete the NSEC3 records.
  5466. */
  5467. result = deletematchingnsec3(db, version, node, name,
  5468. &nsec3chain->nsec3param,
  5469. &nsec3_diff);
  5470. if (result != ISC_R_SUCCESS) {
  5471. dns_zone_log(zone, ISC_LOG_ERROR,
  5472. "zone_nsec3chain:"
  5473. "deletematchingnsec3 -> %s\n",
  5474. dns_result_totext(result));
  5475. goto failure;
  5476. }
  5477. goto next_removenode;
  5478. }
  5479. if (first) {
  5480. dns_fixedname_t ffound;
  5481. dns_name_t *found;
  5482. dns_fixedname_init(&ffound);
  5483. found = dns_fixedname_name(&ffound);
  5484. result = dns_db_find(db, name, version,
  5485. dns_rdatatype_soa,
  5486. DNS_DBFIND_NOWILD, 0, NULL, found,
  5487. NULL, NULL);
  5488. if ((result == DNS_R_DELEGATION ||
  5489. result == DNS_R_DNAME) &&
  5490. !dns_name_equal(name, found)) {
  5491. /*
  5492. * Remember the obscuring name so that
  5493. * we skip all obscured names.
  5494. */
  5495. dns_name_copy(found, name, NULL);
  5496. delegation = ISC_TRUE;
  5497. goto next_removenode;
  5498. }
  5499. }
  5500. /*
  5501. * Check to see if this is a bottom of zone node.
  5502. */
  5503. result = dns_db_allrdatasets(db, node, version, 0, &iterator);
  5504. if (result == ISC_R_NOTFOUND) /* Empty node? */
  5505. goto next_removenode;
  5506. if (result != ISC_R_SUCCESS)
  5507. goto failure;
  5508. seen_soa = seen_ns = seen_dname = seen_nsec3 = seen_nsec =
  5509. seen_rr = ISC_FALSE;
  5510. for (result = dns_rdatasetiter_first(iterator);
  5511. result == ISC_R_SUCCESS;
  5512. result = dns_rdatasetiter_next(iterator)) {
  5513. dns_rdatasetiter_current(iterator, &rdataset);
  5514. if (rdataset.type == dns_rdatatype_soa)
  5515. seen_soa = ISC_TRUE;
  5516. else if (rdataset.type == dns_rdatatype_ns)
  5517. seen_ns = ISC_TRUE;
  5518. else if (rdataset.type == dns_rdatatype_dname)
  5519. seen_dname = ISC_TRUE;
  5520. else if (rdataset.type == dns_rdatatype_nsec)
  5521. seen_nsec = ISC_TRUE;
  5522. else if (rdataset.type == dns_rdatatype_nsec3)
  5523. seen_nsec3 = ISC_TRUE;
  5524. if (rdataset.type != dns_rdatatype_rrsig)
  5525. seen_rr = ISC_TRUE;
  5526. dns_rdataset_disassociate(&rdataset);
  5527. }
  5528. dns_rdatasetiter_destroy(&iterator);
  5529. if (!seen_rr || seen_nsec3 || seen_nsec)
  5530. goto next_removenode;
  5531. if ((seen_ns && !seen_soa) || seen_dname)
  5532. delegation = ISC_TRUE;
  5533. /*
  5534. * Add a NSEC record except at the origin.
  5535. */
  5536. if (!dns_name_equal(name, dns_db_origin(db))) {
  5537. dns_dbiterator_pause(nsec3chain->dbiterator);
  5538. CHECK(add_nsec(db, version, name, node, zone->minimum,
  5539. delegation, &nsec_diff));
  5540. }
  5541. next_removenode:
  5542. first = ISC_FALSE;
  5543. dns_db_detachnode(db, &node);
  5544. do {
  5545. result = dns_dbiterator_next(nsec3chain->dbiterator);
  5546. if (result == ISC_R_NOMORE && buildnsecchain) {
  5547. /*
  5548. * The NSEC chain should now be built.
  5549. * We can now remove the NSEC3 chain.
  5550. */
  5551. updatensec = ISC_TRUE;
  5552. goto same_removechain;
  5553. }
  5554. if (result == ISC_R_NOMORE) {
  5555. LOCK_ZONE(zone);
  5556. ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
  5557. link);
  5558. UNLOCK_ZONE(zone);
  5559. ISC_LIST_APPEND(cleanup, nsec3chain, link);
  5560. dns_dbiterator_pause(nsec3chain->dbiterator);
  5561. result = fixup_nsec3param(db, version,
  5562. nsec3chain, ISC_FALSE,
  5563. privatetype,
  5564. &param_diff);
  5565. if (result != ISC_R_SUCCESS) {
  5566. dns_zone_log(zone, ISC_LOG_ERROR,
  5567. "zone_nsec3chain:"
  5568. "fixup_nsec3param -> %s\n",
  5569. dns_result_totext(result));
  5570. goto failure;
  5571. }
  5572. goto next_removechain;
  5573. } else if (result != ISC_R_SUCCESS) {
  5574. dns_zone_log(zone, ISC_LOG_ERROR,
  5575. "zone_nsec3chain:"
  5576. "dns_dbiterator_next -> %s\n",
  5577. dns_result_totext(result));
  5578. goto failure;
  5579. } else if (delegation) {
  5580. dns_dbiterator_current(nsec3chain->dbiterator,
  5581. &node, nextname);
  5582. dns_db_detachnode(db, &node);
  5583. if (!dns_name_issubdomain(nextname, name))
  5584. break;
  5585. } else
  5586. break;
  5587. } while (1);
  5588. continue;
  5589. same_removechain:
  5590. CHECK(dns_dbiterator_first(nsec3chain->dbiterator));
  5591. buildnsecchain = ISC_FALSE;
  5592. first = ISC_TRUE;
  5593. continue;
  5594. next_removechain:
  5595. dns_dbiterator_pause(nsec3chain->dbiterator);
  5596. nsec3chain = nextnsec3chain;
  5597. first = ISC_TRUE;
  5598. }
  5599. /*
  5600. * We may need to update the NSEC/NSEC3 records for the zone apex.
  5601. */
  5602. if (!ISC_LIST_EMPTY(param_diff.tuples)) {
  5603. isc_boolean_t rebuild_nsec = ISC_FALSE,
  5604. rebuild_nsec3 = ISC_FALSE;
  5605. result = dns_db_getoriginnode(db, &node);
  5606. RUNTIME_CHECK(result == ISC_R_SUCCESS);
  5607. result = dns_db_allrdatasets(db, node, version, 0, &iterator);
  5608. if (result != ISC_R_SUCCESS) {
  5609. dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
  5610. "dns_db_allrdatasets -> %s\n",
  5611. dns_result_totext(result));
  5612. goto failure;
  5613. }
  5614. for (result = dns_rdatasetiter_first(iterator);
  5615. result == ISC_R_SUCCESS;
  5616. result = dns_rdatasetiter_next(iterator)) {
  5617. dns_rdatasetiter_current(iterator, &rdataset);
  5618. if (rdataset.type == dns_rdatatype_nsec)
  5619. rebuild_nsec = ISC_TRUE;
  5620. if (rdataset.type == dns_rdatatype_nsec3param)
  5621. rebuild_nsec3 = ISC_TRUE;
  5622. dns_rdataset_disassociate(&rdataset);
  5623. }
  5624. dns_rdatasetiter_destroy(&iterator);
  5625. dns_db_detachnode(db, &node);
  5626. if (rebuild_nsec) {
  5627. if (nsec3chain != NULL)
  5628. dns_dbiterator_pause(nsec3chain->dbiterator);
  5629. result = updatesecure(db, version, &zone->origin,
  5630. zone->minimum, ISC_TRUE,
  5631. &nsec_diff);
  5632. if (result != ISC_R_SUCCESS) {
  5633. dns_zone_log(zone, ISC_LOG_ERROR,
  5634. "zone_nsec3chain:"
  5635. "updatesecure -> %s\n",
  5636. dns_result_totext(result));
  5637. goto failure;
  5638. }
  5639. }
  5640. if (rebuild_nsec3) {
  5641. result = dns_nsec3_addnsec3s(db, version,
  5642. dns_db_origin(db),
  5643. zone->minimum, ISC_FALSE,
  5644. &nsec3_diff);
  5645. if (result != ISC_R_SUCCESS) {
  5646. dns_zone_log(zone, ISC_LOG_ERROR,
  5647. "zone_nsec3chain:"
  5648. "dns_nsec3_addnsec3s -> %s\n",
  5649. dns_result_totext(result));
  5650. goto failure;
  5651. }
  5652. }
  5653. }
  5654. /*
  5655. * Add / update signatures for the NSEC3 records.
  5656. */
  5657. result = update_sigs(&nsec3_diff, db, version, zone_keys,
  5658. nkeys, zone, inception, expire, now,
  5659. check_ksk, keyset_kskonly, &sig_diff);
  5660. if (result != ISC_R_SUCCESS) {
  5661. dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
  5662. "update_sigs -> %s\n", dns_result_totext(result));
  5663. goto failure;
  5664. }
  5665. /*
  5666. * We have changed the NSEC3PARAM or private RRsets
  5667. * above so we need to update the signatures.
  5668. */
  5669. result = update_sigs(&param_diff, db, version, zone_keys,
  5670. nkeys, zone, inception, expire, now,
  5671. check_ksk, keyset_kskonly, &sig_diff);
  5672. if (result != ISC_R_SUCCESS) {
  5673. dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
  5674. "update_sigs -> %s\n", dns_result_totext(result));
  5675. goto failure;
  5676. }
  5677. if (updatensec) {
  5678. if (nsec3chain != NULL)
  5679. dns_dbiterator_pause(nsec3chain->dbiterator);
  5680. result = updatesecure(db, version, &zone->origin,
  5681. zone->minimum, ISC_FALSE, &nsec_diff);
  5682. if (result != ISC_R_SUCCESS) {
  5683. dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
  5684. "updatesecure -> %s\n",
  5685. dns_result_totext(result));
  5686. goto failure;
  5687. }
  5688. }
  5689. result = update_sigs(&nsec_diff, db, version, zone_keys,
  5690. nkeys, zone, inception, expire, now,
  5691. check_ksk, keyset_kskonly, &sig_diff);
  5692. if (result != ISC_R_SUCCESS) {
  5693. dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
  5694. "update_sigs -> %s\n", dns_result_totext(result));
  5695. goto failure;
  5696. }
  5697. /*
  5698. * If we made no effective changes to the zone then we can just
  5699. * cleanup otherwise we need to increment the serial.
  5700. */
  5701. if (ISC_LIST_HEAD(sig_diff.tuples) == NULL)
  5702. goto done;
  5703. result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
  5704. &sig_diff, zone_keys, nkeys, now, ISC_FALSE);
  5705. if (result != ISC_R_SUCCESS) {
  5706. dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
  5707. "del_sigs -> %s\n", dns_result_totext(result));
  5708. goto failure;
  5709. }
  5710. result = increment_soa_serial(db, version, &sig_diff, zone->mctx);
  5711. if (result != ISC_R_SUCCESS) {
  5712. dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
  5713. "increment_soa_serial -> %s\n",
  5714. dns_result_totext(result));
  5715. goto failure;
  5716. }
  5717. result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa,
  5718. &sig_diff, zone_keys, nkeys, zone->mctx, inception,
  5719. soaexpire, check_ksk, keyset_kskonly);
  5720. if (result != ISC_R_SUCCESS) {
  5721. dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
  5722. "add_sigs -> %s\n", dns_result_totext(result));
  5723. goto failure;
  5724. }
  5725. /* Write changes to journal file. */
  5726. CHECK(zone_journal(zone, &sig_diff, "zone_nsec3chain"));
  5727. LOCK_ZONE(zone);
  5728. zone_needdump(zone, DNS_DUMP_DELAY);
  5729. DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
  5730. UNLOCK_ZONE(zone);
  5731. done:
  5732. /*
  5733. * Pause all iterators so that dns_db_closeversion() can succeed.
  5734. */
  5735. LOCK_ZONE(zone);
  5736. for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
  5737. nsec3chain != NULL;
  5738. nsec3chain = ISC_LIST_NEXT(nsec3chain, link))
  5739. dns_dbiterator_pause(nsec3chain->dbiterator);
  5740. UNLOCK_ZONE(zone);
  5741. /*
  5742. * Everything has succeeded. Commit the changes.
  5743. */
  5744. dns_db_closeversion(db, &version, ISC_TRUE);
  5745. /*
  5746. * Everything succeeded so we can clean these up now.
  5747. */
  5748. nsec3chain = ISC_LIST_HEAD(cleanup);
  5749. while (nsec3chain != NULL) {
  5750. ISC_LIST_UNLINK(cleanup, nsec3chain, link);
  5751. dns_db_detach(&nsec3chain->db);
  5752. dns_dbiterator_destroy(&nsec3chain->dbiterator);
  5753. isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
  5754. nsec3chain = ISC_LIST_HEAD(cleanup);
  5755. }
  5756. set_resigntime(zone);
  5757. failure:
  5758. if (result != ISC_R_SUCCESS)
  5759. dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain: %s\n",
  5760. dns_result_totext(result));
  5761. /*
  5762. * On error roll back the current nsec3chain.
  5763. */
  5764. if (result != ISC_R_SUCCESS && nsec3chain != NULL) {
  5765. if (nsec3chain->done) {
  5766. dns_db_detach(&nsec3chain->db);
  5767. dns_dbiterator_destroy(&nsec3chain->dbiterator);
  5768. isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
  5769. } else {
  5770. result = dns_dbiterator_first(nsec3chain->dbiterator);
  5771. RUNTIME_CHECK(result == ISC_R_SUCCESS);
  5772. dns_dbiterator_pause(nsec3chain->dbiterator);
  5773. nsec3chain->delete_nsec = nsec3chain->save_delete_nsec;
  5774. }
  5775. }
  5776. /*
  5777. * Rollback the cleanup list.
  5778. */
  5779. nsec3chain = ISC_LIST_TAIL(cleanup);
  5780. while (nsec3chain != NULL) {
  5781. ISC_LIST_UNLINK(cleanup, nsec3chain, link);
  5782. if (nsec3chain->done) {
  5783. dns_db_detach(&nsec3chain->db);
  5784. dns_dbiterator_destroy(&nsec3chain->dbiterator);
  5785. isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
  5786. } else {
  5787. LOCK_ZONE(zone);
  5788. ISC_LIST_PREPEND(zone->nsec3chain, nsec3chain, link);
  5789. UNLOCK_ZONE(zone);
  5790. result = dns_dbiterator_first(nsec3chain->dbiterator);
  5791. RUNTIME_CHECK(result == ISC_R_SUCCESS);
  5792. dns_dbiterator_pause(nsec3chain->dbiterator);
  5793. nsec3chain->delete_nsec = nsec3chain->save_delete_nsec;
  5794. }
  5795. nsec3chain = ISC_LIST_TAIL(cleanup);
  5796. }
  5797. LOCK_ZONE(zone);
  5798. for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
  5799. nsec3chain != NULL;
  5800. nsec3chain = ISC_LIST_NEXT(nsec3chain, link))
  5801. dns_dbiterator_pause(nsec3chain->dbiterator);
  5802. UNLOCK_ZONE(zone);
  5803. dns_diff_clear(&param_diff);
  5804. dns_diff_clear(&nsec3_diff);
  5805. dns_diff_clear(&nsec_diff);
  5806. dns_diff_clear(&sig_diff);
  5807. if (iterator != NULL)
  5808. dns_rdatasetiter_destroy(&iterator);
  5809. for (i = 0; i < nkeys; i++)
  5810. dst_key_free(&zone_keys[i]);
  5811. if (node != NULL)
  5812. dns_db_detachnode(db, &node);
  5813. if (version != NULL) {
  5814. dns_db_closeversion(db, &version, ISC_FALSE);
  5815. dns_db_detach(&db);
  5816. } else if (db != NULL)
  5817. dns_db_detach(&db);
  5818. LOCK_ZONE(zone);
  5819. if (ISC_LIST_HEAD(zone->nsec3chain) != NULL) {
  5820. isc_interval_t i;
  5821. if (zone->update_disabled || result != ISC_R_SUCCESS)
  5822. isc_interval_set(&i, 60, 0); /* 1 minute */
  5823. else
  5824. isc_interval_set(&i, 0, 10000000); /* 10 ms */
  5825. isc_time_nowplusinterval(&zone->nsec3chaintime, &i);
  5826. } else
  5827. isc_time_settoepoch(&zone->nsec3chaintime);
  5828. UNLOCK_ZONE(zone);
  5829. }
  5830. static isc_result_t
  5831. del_sig(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
  5832. dns_dbnode_t *node, unsigned int nkeys, dns_secalg_t algorithm,
  5833. isc_uint16_t keyid, dns_diff_t *diff)
  5834. {
  5835. dns_rdata_rrsig_t rrsig;
  5836. dns_rdataset_t rdataset;
  5837. dns_rdatasetiter_t *iterator = NULL;
  5838. isc_result_t result;
  5839. result = dns_db_allrdatasets(db, node, version, 0, &iterator);
  5840. if (result != ISC_R_SUCCESS) {
  5841. if (result == ISC_R_NOTFOUND)
  5842. result = ISC_R_SUCCESS;
  5843. return (result);
  5844. }
  5845. dns_rdataset_init(&rdataset);
  5846. for (result = dns_rdatasetiter_first(iterator);
  5847. result == ISC_R_SUCCESS;
  5848. result = dns_rdatasetiter_next(iterator)) {
  5849. dns_rdatasetiter_current(iterator, &rdataset);
  5850. if (nkeys == 0 && rdataset.type == dns_rdatatype_nsec) {
  5851. for (result = dns_rdataset_first(&rdataset);
  5852. result == ISC_R_SUCCESS;
  5853. result = dns_rdataset_next(&rdataset)) {
  5854. dns_rdata_t rdata = DNS_RDATA_INIT;
  5855. dns_rdataset_current(&rdataset, &rdata);
  5856. CHECK(update_one_rr(db, version, diff,
  5857. DNS_DIFFOP_DEL, name,
  5858. rdataset.ttl, &rdata));
  5859. }
  5860. if (result != ISC_R_NOMORE)
  5861. goto failure;
  5862. dns_rdataset_disassociate(&rdataset);
  5863. continue;
  5864. }
  5865. if (rdataset.type != dns_rdatatype_rrsig) {
  5866. dns_rdataset_disassociate(&rdataset);
  5867. continue;
  5868. }
  5869. for (result = dns_rdataset_first(&rdataset);
  5870. result == ISC_R_SUCCESS;
  5871. result = dns_rdataset_next(&rdataset)) {
  5872. dns_rdata_t rdata = DNS_RDATA_INIT;
  5873. dns_rdataset_current(&rdataset, &rdata);
  5874. CHECK(dns_rdata_tostruct(&rdata, &rrsig, NULL));
  5875. if (rrsig.algorithm != algorithm ||
  5876. rrsig.keyid != keyid)
  5877. continue;
  5878. CHECK(update_one_rr(db, version, diff,
  5879. DNS_DIFFOP_DELRESIGN, name,
  5880. rdataset.ttl, &rdata));
  5881. }
  5882. dns_rdataset_disassociate(&rdataset);
  5883. if (result != ISC_R_NOMORE)
  5884. break;
  5885. }
  5886. if (result == ISC_R_NOMORE)
  5887. result = ISC_R_SUCCESS;
  5888. failure:
  5889. if (dns_rdataset_isassociated(&rdataset))
  5890. dns_rdataset_disassociate(&rdataset);
  5891. dns_rdatasetiter_destroy(&iterator);
  5892. return (result);
  5893. }
  5894. /*
  5895. * Incrementally sign the zone using the keys requested.
  5896. * Builds the NSEC chain if required.
  5897. */
  5898. static void
  5899. zone_sign(dns_zone_t *zone) {
  5900. dns_db_t *db = NULL;
  5901. dns_dbnode_t *node = NULL;
  5902. dns_dbversion_t *version = NULL;
  5903. dns_diff_t sig_diff;
  5904. dns_diff_t post_diff;
  5905. dns_fixedname_t fixed;
  5906. dns_fixedname_t nextfixed;
  5907. dns_name_t *name, *nextname;
  5908. dns_rdataset_t rdataset;
  5909. dns_signing_t *signing, *nextsigning;
  5910. dns_signinglist_t cleanup;
  5911. dst_key_t *zone_keys[DNS_MAXZONEKEYS];
  5912. isc_int32_t signatures;
  5913. isc_boolean_t check_ksk, keyset_kskonly, is_ksk;
  5914. isc_boolean_t commit = ISC_FALSE;
  5915. isc_boolean_t delegation;
  5916. isc_boolean_t build_nsec = ISC_FALSE;
  5917. isc_boolean_t build_nsec3 = ISC_FALSE;
  5918. isc_boolean_t first;
  5919. isc_result_t result;
  5920. isc_stdtime_t now, inception, soaexpire, expire;
  5921. isc_uint32_t jitter;
  5922. unsigned int i, j;
  5923. unsigned int nkeys = 0;
  5924. isc_uint32_t nodes;
  5925. dns_rdataset_init(&rdataset);
  5926. dns_fixedname_init(&fixed);
  5927. name = dns_fixedname_name(&fixed);
  5928. dns_fixedname_init(&nextfixed);
  5929. nextname = dns_fixedname_name(&nextfixed);
  5930. dns_diff_init(zone->mctx, &sig_diff);
  5931. sig_diff.resign = zone->sigresigninginterval;
  5932. dns_diff_init(zone->mctx, &post_diff);
  5933. ISC_LIST_INIT(cleanup);
  5934. /*
  5935. * Updates are disabled. Pause for 5 minutes.
  5936. */
  5937. if (zone->update_disabled) {
  5938. result = ISC_R_FAILURE;
  5939. goto failure;
  5940. }
  5941. ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
  5942. dns_db_attach(zone->db, &db);
  5943. ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
  5944. result = dns_db_newversion(db, &version);
  5945. if (result != ISC_R_SUCCESS) {
  5946. dns_zone_log(zone, ISC_LOG_ERROR,
  5947. "zone_sign:dns_db_newversion -> %s\n",
  5948. dns_result_totext(result));
  5949. goto failure;
  5950. }
  5951. result = find_zone_keys(zone, db, version, zone->mctx,
  5952. DNS_MAXZONEKEYS, zone_keys, &nkeys);
  5953. if (result != ISC_R_SUCCESS) {
  5954. dns_zone_log(zone, ISC_LOG_ERROR,
  5955. "zone_sign:find_zone_keys -> %s\n",
  5956. dns_result_totext(result));
  5957. goto failure;
  5958. }
  5959. isc_stdtime_get(&now);
  5960. inception = now - 3600; /* Allow for clock skew. */
  5961. soaexpire = now + dns_zone_getsigvalidityinterval(zone);
  5962. /*
  5963. * Spread out signatures over time if they happen to be
  5964. * clumped. We don't do this for each add_sigs() call as
  5965. * we still want some clustering to occur.
  5966. */
  5967. isc_random_get(&jitter);
  5968. expire = soaexpire - jitter % 3600;
  5969. /*
  5970. * We keep pulling nodes off each iterator in turn until
  5971. * we have no more nodes to pull off or we reach the limits
  5972. * for this quantum.
  5973. */
  5974. nodes = zone->nodes;
  5975. signatures = zone->signatures;
  5976. signing = ISC_LIST_HEAD(zone->signing);
  5977. first = ISC_TRUE;
  5978. check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
  5979. keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
  5980. /* Determine which type of chain to build */
  5981. CHECK(dns_private_chains(db, version, zone->privatetype,
  5982. &build_nsec, &build_nsec3));
  5983. /* If neither chain is found, default to NSEC */
  5984. if (!build_nsec && !build_nsec3)
  5985. build_nsec = ISC_TRUE;
  5986. while (signing != NULL && nodes-- > 0 && signatures > 0) {
  5987. nextsigning = ISC_LIST_NEXT(signing, link);
  5988. ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
  5989. if (signing->done || signing->db != zone->db) {
  5990. /*
  5991. * The zone has been reloaded. We will have
  5992. * created new signings as part of the reload
  5993. * process so we can destroy this one.
  5994. */
  5995. ISC_LIST_UNLINK(zone->signing, signing, link);
  5996. ISC_LIST_APPEND(cleanup, signing, link);
  5997. ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
  5998. goto next_signing;
  5999. }
  6000. ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
  6001. if (signing->db != db)
  6002. goto next_signing;
  6003. delegation = ISC_FALSE;
  6004. if (first && signing->delete) {
  6005. /*
  6006. * Remove the key we are deleting from consideration.
  6007. */
  6008. for (i = 0, j = 0; i < nkeys; i++) {
  6009. /*
  6010. * Find the key we want to remove.
  6011. */
  6012. if (ALG(zone_keys[i]) == signing->algorithm &&
  6013. dst_key_id(zone_keys[i]) == signing->keyid)
  6014. {
  6015. if (KSK(zone_keys[i]))
  6016. dst_key_free(&zone_keys[i]);
  6017. continue;
  6018. }
  6019. zone_keys[j] = zone_keys[i];
  6020. j++;
  6021. }
  6022. nkeys = j;
  6023. }
  6024. dns_dbiterator_current(signing->dbiterator, &node, name);
  6025. if (signing->delete) {
  6026. dns_dbiterator_pause(signing->dbiterator);
  6027. CHECK(del_sig(db, version, name, node, nkeys,
  6028. signing->algorithm, signing->keyid,
  6029. &sig_diff));
  6030. }
  6031. /*
  6032. * On the first pass we need to check if the current node
  6033. * has not been obscured.
  6034. */
  6035. if (first) {
  6036. dns_fixedname_t ffound;
  6037. dns_name_t *found;
  6038. dns_fixedname_init(&ffound);
  6039. found = dns_fixedname_name(&ffound);
  6040. result = dns_db_find(db, name, version,
  6041. dns_rdatatype_soa,
  6042. DNS_DBFIND_NOWILD, 0, NULL, found,
  6043. NULL, NULL);
  6044. if ((result == DNS_R_DELEGATION ||
  6045. result == DNS_R_DNAME) &&
  6046. !dns_name_equal(name, found)) {
  6047. /*
  6048. * Remember the obscuring name so that
  6049. * we skip all obscured names.
  6050. */
  6051. dns_name_copy(found, name, NULL);
  6052. delegation = ISC_TRUE;
  6053. goto next_node;
  6054. }
  6055. }
  6056. /*
  6057. * Process one node.
  6058. */
  6059. dns_dbiterator_pause(signing->dbiterator);
  6060. for (i = 0; i < nkeys; i++) {
  6061. isc_boolean_t both = ISC_FALSE;
  6062. /*
  6063. * Find the keys we want to sign with.
  6064. */
  6065. if (!dst_key_isprivate(zone_keys[i]))
  6066. continue;
  6067. /*
  6068. * When adding look for the specific key.
  6069. */
  6070. if (!signing->delete &&
  6071. (dst_key_alg(zone_keys[i]) != signing->algorithm ||
  6072. dst_key_id(zone_keys[i]) != signing->keyid))
  6073. continue;
  6074. /*
  6075. * When deleting make sure we are properly signed
  6076. * with the algorithm that was being removed.
  6077. */
  6078. if (signing->delete &&
  6079. ALG(zone_keys[i]) != signing->algorithm)
  6080. continue;
  6081. /*
  6082. * Do we do KSK processing?
  6083. */
  6084. if (check_ksk && !REVOKE(zone_keys[i])) {
  6085. isc_boolean_t have_ksk, have_nonksk;
  6086. if (KSK(zone_keys[i])) {
  6087. have_ksk = ISC_TRUE;
  6088. have_nonksk = ISC_FALSE;
  6089. } else {
  6090. have_ksk = ISC_FALSE;
  6091. have_nonksk = ISC_TRUE;
  6092. }
  6093. for (j = 0; j < nkeys; j++) {
  6094. if (j == i ||
  6095. ALG(zone_keys[i]) !=
  6096. ALG(zone_keys[j]))
  6097. continue;
  6098. if (REVOKE(zone_keys[j]))
  6099. continue;
  6100. if (KSK(zone_keys[j]))
  6101. have_ksk = ISC_TRUE;
  6102. else
  6103. have_nonksk = ISC_TRUE;
  6104. both = have_ksk && have_nonksk;
  6105. if (both)
  6106. break;
  6107. }
  6108. }
  6109. if (both || REVOKE(zone_keys[i]))
  6110. is_ksk = KSK(zone_keys[i]);
  6111. else
  6112. is_ksk = ISC_FALSE;
  6113. CHECK(sign_a_node(db, name, node, version, build_nsec3,
  6114. build_nsec, zone_keys[i], inception,
  6115. expire, zone->minimum, is_ksk,
  6116. ISC_TF(both && keyset_kskonly),
  6117. &delegation, &sig_diff,
  6118. &signatures, zone->mctx));
  6119. /*
  6120. * If we are adding we are done. Look for other keys
  6121. * of the same algorithm if deleting.
  6122. */
  6123. if (!signing->delete)
  6124. break;
  6125. }
  6126. /*
  6127. * Go onto next node.
  6128. */
  6129. next_node:
  6130. first = ISC_FALSE;
  6131. dns_db_detachnode(db, &node);
  6132. do {
  6133. result = dns_dbiterator_next(signing->dbiterator);
  6134. if (result == ISC_R_NOMORE) {
  6135. ISC_LIST_UNLINK(zone->signing, signing, link);
  6136. ISC_LIST_APPEND(cleanup, signing, link);
  6137. dns_dbiterator_pause(signing->dbiterator);
  6138. if (nkeys != 0 && build_nsec) {
  6139. /*
  6140. * We have finished regenerating the
  6141. * zone with a zone signing key.
  6142. * The NSEC chain is now complete and
  6143. * there is a full set of signatures
  6144. * for the zone. We can now clear the
  6145. * OPT bit from the NSEC record.
  6146. */
  6147. result = updatesecure(db, version,
  6148. &zone->origin,
  6149. zone->minimum,
  6150. ISC_FALSE,
  6151. &post_diff);
  6152. if (result != ISC_R_SUCCESS) {
  6153. dns_zone_log(zone,
  6154. ISC_LOG_ERROR,
  6155. "updatesecure -> %s\n",
  6156. dns_result_totext(result));
  6157. goto failure;
  6158. }
  6159. }
  6160. result = updatesignwithkey(zone, signing,
  6161. version,
  6162. build_nsec3,
  6163. zone->minimum,
  6164. &post_diff);
  6165. if (result != ISC_R_SUCCESS) {
  6166. dns_zone_log(zone, ISC_LOG_ERROR,
  6167. "updatesignwithkey "
  6168. "-> %s\n",
  6169. dns_result_totext(result));
  6170. goto failure;
  6171. }
  6172. build_nsec = ISC_FALSE;
  6173. goto next_signing;
  6174. } else if (result != ISC_R_SUCCESS) {
  6175. dns_zone_log(zone, ISC_LOG_ERROR,
  6176. "zone_sign:dns_dbiterator_next -> %s\n",
  6177. dns_result_totext(result));
  6178. goto failure;
  6179. } else if (delegation) {
  6180. dns_dbiterator_current(signing->dbiterator,
  6181. &node, nextname);
  6182. dns_db_detachnode(db, &node);
  6183. if (!dns_name_issubdomain(nextname, name))
  6184. break;
  6185. } else
  6186. break;
  6187. } while (1);
  6188. continue;
  6189. next_signing:
  6190. dns_dbiterator_pause(signing->dbiterator);
  6191. signing = nextsigning;
  6192. first = ISC_TRUE;
  6193. }
  6194. if (ISC_LIST_HEAD(post_diff.tuples) != NULL) {
  6195. result = update_sigs(&post_diff, db, version, zone_keys,
  6196. nkeys, zone, inception, expire, now,
  6197. check_ksk, keyset_kskonly, &sig_diff);
  6198. if (result != ISC_R_SUCCESS) {
  6199. dns_zone_log(zone, ISC_LOG_ERROR, "zone_sign:"
  6200. "update_sigs -> %s\n",
  6201. dns_result_totext(result));
  6202. goto failure;
  6203. }
  6204. }
  6205. /*
  6206. * Have we changed anything?
  6207. */
  6208. if (ISC_LIST_HEAD(sig_diff.tuples) == NULL) {
  6209. result = ISC_R_SUCCESS;
  6210. goto pauseall;
  6211. }
  6212. commit = ISC_TRUE;
  6213. result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
  6214. &sig_diff, zone_keys, nkeys, now, ISC_FALSE);
  6215. if (result != ISC_R_SUCCESS) {
  6216. dns_zone_log(zone, ISC_LOG_ERROR,
  6217. "zone_sign:del_sigs -> %s\n",
  6218. dns_result_totext(result));
  6219. goto failure;
  6220. }
  6221. result = increment_soa_serial(db, version, &sig_diff, zone->mctx);
  6222. if (result != ISC_R_SUCCESS) {
  6223. dns_zone_log(zone, ISC_LOG_ERROR,
  6224. "zone_sign:increment_soa_serial -> %s\n",
  6225. dns_result_totext(result));
  6226. goto failure;
  6227. }
  6228. /*
  6229. * Generate maximum life time signatures so that the above loop
  6230. * termination is sensible.
  6231. */
  6232. result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa,
  6233. &sig_diff, zone_keys, nkeys, zone->mctx, inception,
  6234. soaexpire, check_ksk, keyset_kskonly);
  6235. if (result != ISC_R_SUCCESS) {
  6236. dns_zone_log(zone, ISC_LOG_ERROR,
  6237. "zone_sign:add_sigs -> %s\n",
  6238. dns_result_totext(result));
  6239. goto failure;
  6240. }
  6241. /*
  6242. * Write changes to journal file.
  6243. */
  6244. CHECK(zone_journal(zone, &sig_diff, "zone_sign"));
  6245. pauseall:
  6246. /*
  6247. * Pause all iterators so that dns_db_closeversion() can succeed.
  6248. */
  6249. for (signing = ISC_LIST_HEAD(zone->signing);
  6250. signing != NULL;
  6251. signing = ISC_LIST_NEXT(signing, link))
  6252. dns_dbiterator_pause(signing->dbiterator);
  6253. for (signing = ISC_LIST_HEAD(cleanup);
  6254. signing != NULL;
  6255. signing = ISC_LIST_NEXT(signing, link))
  6256. dns_dbiterator_pause(signing->dbiterator);
  6257. /*
  6258. * Everything has succeeded. Commit the changes.
  6259. */
  6260. dns_db_closeversion(db, &version, commit);
  6261. /*
  6262. * Everything succeeded so we can clean these up now.
  6263. */
  6264. signing = ISC_LIST_HEAD(cleanup);
  6265. while (signing != NULL) {
  6266. ISC_LIST_UNLINK(cleanup, signing, link);
  6267. dns_db_detach(&signing->db);
  6268. dns_dbiterator_destroy(&signing->dbiterator);
  6269. isc_mem_put(zone->mctx, signing, sizeof *signing);
  6270. signing = ISC_LIST_HEAD(cleanup);
  6271. }
  6272. set_resigntime(zone);
  6273. if (commit) {
  6274. LOCK_ZONE(zone);
  6275. DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
  6276. zone_needdump(zone, DNS_DUMP_DELAY);
  6277. UNLOCK_ZONE(zone);
  6278. }
  6279. failure:
  6280. /*
  6281. * Rollback the cleanup list.
  6282. */
  6283. signing = ISC_LIST_HEAD(cleanup);
  6284. while (signing != NULL) {
  6285. ISC_LIST_UNLINK(cleanup, signing, link);
  6286. ISC_LIST_PREPEND(zone->signing, signing, link);
  6287. dns_dbiterator_first(signing->dbiterator);
  6288. dns_dbiterator_pause(signing->dbiterator);
  6289. signing = ISC_LIST_HEAD(cleanup);
  6290. }
  6291. for (signing = ISC_LIST_HEAD(zone->signing);
  6292. signing != NULL;
  6293. signing = ISC_LIST_NEXT(signing, link))
  6294. dns_dbiterator_pause(signing->dbiterator);
  6295. dns_diff_clear(&sig_diff);
  6296. for (i = 0; i < nkeys; i++)
  6297. dst_key_free(&zone_keys[i]);
  6298. if (node != NULL)
  6299. dns_db_detachnode(db, &node);
  6300. if (version != NULL) {
  6301. dns_db_closeversion(db, &version, ISC_FALSE);
  6302. dns_db_detach(&db);
  6303. } else if (db != NULL)
  6304. dns_db_detach(&db);
  6305. if (ISC_LIST_HEAD(zone->signing) != NULL) {
  6306. isc_interval_t i;
  6307. if (zone->update_disabled || result != ISC_R_SUCCESS)
  6308. isc_interval_set(&i, 60, 0); /* 1 minute */
  6309. else
  6310. isc_interval_set(&i, 0, 10000000); /* 10 ms */
  6311. isc_time_nowplusinterval(&zone->signingtime, &i);
  6312. } else
  6313. isc_time_settoepoch(&zone->signingtime);
  6314. }
  6315. static void
  6316. normalize_key(dns_rdata_t *rr, dns_rdata_t *target,
  6317. unsigned char *data, int size) {
  6318. dns_rdata_dnskey_t dnskey;
  6319. dns_rdata_keydata_t keydata;
  6320. isc_buffer_t buf;
  6321. dns_rdata_reset(target);
  6322. isc_buffer_init(&buf, data, size);
  6323. switch (rr->type) {
  6324. case dns_rdatatype_dnskey:
  6325. dns_rdata_tostruct(rr, &dnskey, NULL);
  6326. dnskey.flags &= ~DNS_KEYFLAG_REVOKE;
  6327. dns_rdata_fromstruct(target, rr->rdclass, dns_rdatatype_dnskey,
  6328. &dnskey, &buf);
  6329. break;
  6330. case dns_rdatatype_keydata:
  6331. dns_rdata_tostruct(rr, &keydata, NULL);
  6332. dns_keydata_todnskey(&keydata, &dnskey, NULL);
  6333. dns_rdata_fromstruct(target, rr->rdclass, dns_rdatatype_dnskey,
  6334. &dnskey, &buf);
  6335. break;
  6336. default:
  6337. INSIST(0);
  6338. }
  6339. }
  6340. /*
  6341. * 'rdset' contains either a DNSKEY rdataset from the zone apex, or
  6342. * a KEYDATA rdataset from the key zone.
  6343. *
  6344. * 'rr' contains either a DNSKEY record, or a KEYDATA record
  6345. *
  6346. * After normalizing keys to the same format (DNSKEY, with revoke bit
  6347. * cleared), return ISC_TRUE if a key that matches 'rr' is found in
  6348. * 'rdset', or ISC_FALSE if not.
  6349. */
  6350. static isc_boolean_t
  6351. matchkey(dns_rdataset_t *rdset, dns_rdata_t *rr) {
  6352. unsigned char data1[4096], data2[4096];
  6353. dns_rdata_t rdata, rdata1, rdata2;
  6354. isc_result_t result;
  6355. dns_rdata_init(&rdata);
  6356. dns_rdata_init(&rdata1);
  6357. dns_rdata_init(&rdata2);
  6358. normalize_key(rr, &rdata1, data1, sizeof(data1));
  6359. for (result = dns_rdataset_first(rdset);
  6360. result == ISC_R_SUCCESS;
  6361. result = dns_rdataset_next(rdset)) {
  6362. dns_rdata_reset(&rdata);
  6363. dns_rdataset_current(rdset, &rdata);
  6364. normalize_key(&rdata, &rdata2, data2, sizeof(data2));
  6365. if (dns_rdata_compare(&rdata1, &rdata2) == 0)
  6366. return (ISC_TRUE);
  6367. }
  6368. return (ISC_FALSE);
  6369. }
  6370. /*
  6371. * Calculate the refresh interval for a keydata zone, per
  6372. * RFC5011: MAX(1 hr,
  6373. * MIN(15 days,
  6374. * 1/2 * OrigTTL,
  6375. * 1/2 * RRSigExpirationInterval))
  6376. * or for retries: MAX(1 hr,
  6377. * MIN(1 day,
  6378. * 1/10 * OrigTTL,
  6379. * 1/10 * RRSigExpirationInterval))
  6380. */
  6381. static inline isc_stdtime_t
  6382. refresh_time(dns_keyfetch_t *kfetch, isc_boolean_t retry) {
  6383. isc_result_t result;
  6384. isc_uint32_t t;
  6385. dns_rdataset_t *rdset;
  6386. dns_rdata_t sigrr = DNS_RDATA_INIT;
  6387. dns_rdata_sig_t sig;
  6388. isc_stdtime_t now;
  6389. isc_stdtime_get(&now);
  6390. if (dns_rdataset_isassociated(&kfetch->dnskeysigset))
  6391. rdset = &kfetch->dnskeysigset;
  6392. else
  6393. return (now + HOUR);
  6394. result = dns_rdataset_first(rdset);
  6395. if (result != ISC_R_SUCCESS)
  6396. return (now + HOUR);
  6397. dns_rdataset_current(rdset, &sigrr);
  6398. result = dns_rdata_tostruct(&sigrr, &sig, NULL);
  6399. RUNTIME_CHECK(result == ISC_R_SUCCESS);
  6400. if (!retry) {
  6401. t = sig.originalttl / 2;
  6402. if (isc_serial_gt(sig.timeexpire, now)) {
  6403. isc_uint32_t exp = (sig.timeexpire - now) / 2;
  6404. if (t > exp)
  6405. t = exp;
  6406. }
  6407. if (t > (15*DAY))
  6408. t = (15*DAY);
  6409. if (t < HOUR)
  6410. t = HOUR;
  6411. } else {
  6412. t = sig.originalttl / 10;
  6413. if (isc_serial_gt(sig.timeexpire, now)) {
  6414. isc_uint32_t exp = (sig.timeexpire - now) / 10;
  6415. if (t > exp)
  6416. t = exp;
  6417. }
  6418. if (t > DAY)
  6419. t = DAY;
  6420. if (t < HOUR)
  6421. t = HOUR;
  6422. }
  6423. return (now + t);
  6424. }
  6425. /*
  6426. * This routine is called when no changes are needed in a KEYDATA
  6427. * record except to simply update the refresh timer. Caller should
  6428. * hold zone lock.
  6429. */
  6430. static isc_result_t
  6431. minimal_update(dns_keyfetch_t *kfetch, dns_dbversion_t *ver, dns_diff_t *diff)
  6432. {
  6433. isc_result_t result;
  6434. isc_buffer_t keyb;
  6435. unsigned char key_buf[4096];
  6436. dns_rdata_t rdata = DNS_RDATA_INIT;
  6437. dns_rdata_keydata_t keydata;
  6438. dns_name_t *name;
  6439. dns_zone_t *zone = kfetch->zone;
  6440. isc_stdtime_t now;
  6441. name = dns_fixedname_name(&kfetch->name);
  6442. isc_stdtime_get(&now);
  6443. for (result = dns_rdataset_first(&kfetch->keydataset);
  6444. result == ISC_R_SUCCESS;
  6445. result = dns_rdataset_next(&kfetch->keydataset)) {
  6446. dns_rdata_reset(&rdata);
  6447. dns_rdataset_current(&kfetch->keydataset, &rdata);
  6448. /* Delete old version */
  6449. CHECK(update_one_rr(kfetch->db, ver, diff, DNS_DIFFOP_DEL,
  6450. name, 0, &rdata));
  6451. /* Update refresh timer */
  6452. CHECK(dns_rdata_tostruct(&rdata, &keydata, NULL));
  6453. keydata.refresh = refresh_time(kfetch, ISC_TRUE);
  6454. set_refreshkeytimer(zone, &keydata, now);
  6455. dns_rdata_reset(&rdata);
  6456. isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
  6457. CHECK(dns_rdata_fromstruct(&rdata,
  6458. zone->rdclass, dns_rdatatype_keydata,
  6459. &keydata, &keyb));
  6460. /* Insert updated version */
  6461. CHECK(update_one_rr(kfetch->db, ver, diff, DNS_DIFFOP_ADD,
  6462. name, 0, &rdata));
  6463. }
  6464. result = ISC_R_SUCCESS;
  6465. failure:
  6466. return (result);
  6467. }
  6468. /*
  6469. * Verify that DNSKEY set is signed by the key specified in 'keydata'.
  6470. */
  6471. static isc_boolean_t
  6472. revocable(dns_keyfetch_t *kfetch, dns_rdata_keydata_t *keydata) {
  6473. isc_result_t result;
  6474. dns_name_t *keyname;
  6475. isc_mem_t *mctx;
  6476. dns_rdata_t sigrr = DNS_RDATA_INIT;
  6477. dns_rdata_t rr = DNS_RDATA_INIT;
  6478. dns_rdata_rrsig_t sig;
  6479. dns_rdata_dnskey_t dnskey;
  6480. dst_key_t *dstkey = NULL;
  6481. unsigned char key_buf[4096];
  6482. isc_buffer_t keyb;
  6483. isc_boolean_t answer = ISC_FALSE;
  6484. REQUIRE(kfetch != NULL && keydata != NULL);
  6485. REQUIRE(dns_rdataset_isassociated(&kfetch->dnskeysigset));
  6486. keyname = dns_fixedname_name(&kfetch->name);
  6487. mctx = kfetch->zone->view->mctx;
  6488. /* Generate a key from keydata */
  6489. isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
  6490. dns_keydata_todnskey(keydata, &dnskey, NULL);
  6491. dns_rdata_fromstruct(&rr, keydata->common.rdclass, dns_rdatatype_dnskey,
  6492. &dnskey, &keyb);
  6493. result = dns_dnssec_keyfromrdata(keyname, &rr, mctx, &dstkey);
  6494. if (result != ISC_R_SUCCESS)
  6495. return (ISC_FALSE);
  6496. /* See if that key generated any of the signatures */
  6497. for (result = dns_rdataset_first(&kfetch->dnskeysigset);
  6498. result == ISC_R_SUCCESS;
  6499. result = dns_rdataset_next(&kfetch->dnskeysigset)) {
  6500. dns_fixedname_t fixed;
  6501. dns_fixedname_init(&fixed);
  6502. dns_rdata_reset(&sigrr);
  6503. dns_rdataset_current(&kfetch->dnskeysigset, &sigrr);
  6504. result = dns_rdata_tostruct(&sigrr, &sig, NULL);
  6505. RUNTIME_CHECK(result == ISC_R_SUCCESS);
  6506. if (dst_key_alg(dstkey) == sig.algorithm &&
  6507. (dst_key_id(dstkey) == sig.keyid ||
  6508. dst_key_rid(dstkey) == sig.keyid)) {
  6509. result = dns_dnssec_verify2(keyname,
  6510. &kfetch->dnskeyset,
  6511. dstkey, ISC_FALSE, mctx, &sigrr,
  6512. dns_fixedname_name(&fixed));
  6513. dns_zone_log(kfetch->zone, ISC_LOG_DEBUG(3),
  6514. "Confirm revoked DNSKEY is self-signed: "
  6515. "%s", dns_result_totext(result));
  6516. if (result == ISC_R_SUCCESS) {
  6517. answer = ISC_TRUE;
  6518. break;
  6519. }
  6520. }
  6521. }
  6522. dst_key_free(&dstkey);
  6523. return (answer);
  6524. }
  6525. /*
  6526. * A DNSKEY set has been fetched from the zone apex of a zone whose trust
  6527. * anchors are being managed; scan the keyset, and update the key zone and the
  6528. * local trust anchors according to RFC5011.
  6529. */
  6530. static void
  6531. keyfetch_done(isc_task_t *task, isc_event_t *event) {
  6532. isc_result_t result, eresult;
  6533. dns_fetchevent_t *devent;
  6534. dns_keyfetch_t *kfetch;
  6535. dns_zone_t *zone;
  6536. isc_mem_t *mctx = NULL;
  6537. dns_keytable_t *secroots = NULL;
  6538. dns_dbversion_t *ver = NULL;
  6539. dns_diff_t diff;
  6540. isc_boolean_t alldone = ISC_FALSE;
  6541. isc_boolean_t commit = ISC_FALSE;
  6542. dns_name_t *keyname;
  6543. dns_rdata_t sigrr = DNS_RDATA_INIT;
  6544. dns_rdata_t dnskeyrr = DNS_RDATA_INIT;
  6545. dns_rdata_t keydatarr = DNS_RDATA_INIT;
  6546. dns_rdata_rrsig_t sig;
  6547. dns_rdata_dnskey_t dnskey;
  6548. dns_rdata_keydata_t keydata;
  6549. isc_boolean_t initializing;
  6550. char namebuf[DNS_NAME_FORMATSIZE];
  6551. unsigned char key_buf[4096];
  6552. isc_buffer_t keyb;
  6553. dst_key_t *dstkey;
  6554. isc_stdtime_t now;
  6555. int pending = 0;
  6556. isc_boolean_t secure;
  6557. isc_boolean_t free_needed;
  6558. UNUSED(task);
  6559. INSIST(event != NULL && event->ev_type == DNS_EVENT_FETCHDONE);
  6560. INSIST(event->ev_arg != NULL);
  6561. kfetch = event->ev_arg;
  6562. zone = kfetch->zone;
  6563. isc_mem_attach(zone->mctx, &mctx);
  6564. keyname = dns_fixedname_name(&kfetch->name);
  6565. devent = (dns_fetchevent_t *) event;
  6566. eresult = devent->result;
  6567. /* Free resources which are not of interest */
  6568. if (devent->node != NULL)
  6569. dns_db_detachnode(devent->db, &devent->node);
  6570. if (devent->db != NULL)
  6571. dns_db_detach(&devent->db);
  6572. isc_event_free(&event);
  6573. dns_resolver_destroyfetch(&kfetch->fetch);
  6574. LOCK_ZONE(zone);
  6575. if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) || zone->view == NULL)
  6576. goto cleanup;
  6577. isc_stdtime_get(&now);
  6578. dns_name_format(keyname, namebuf, sizeof(namebuf));
  6579. result = dns_view_getsecroots(zone->view, &secroots);
  6580. INSIST(result == ISC_R_SUCCESS);
  6581. dns_diff_init(mctx, &diff);
  6582. diff.resign = zone->sigresigninginterval;
  6583. CHECK(dns_db_newversion(kfetch->db, &ver));
  6584. zone->refreshkeycount--;
  6585. alldone = ISC_TF(zone->refreshkeycount == 0);
  6586. if (alldone)
  6587. DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESHING);
  6588. /* Fetch failed */
  6589. if (eresult != ISC_R_SUCCESS ||
  6590. !dns_rdataset_isassociated(&kfetch->dnskeyset)) {
  6591. dns_zone_log(zone, ISC_LOG_WARNING,
  6592. "Unable to fetch DNSKEY set "
  6593. "'%s': %s", namebuf, dns_result_totext(eresult));
  6594. CHECK(minimal_update(kfetch, ver, &diff));
  6595. goto done;
  6596. }
  6597. /* No RRSIGs found */
  6598. if (!dns_rdataset_isassociated(&kfetch->dnskeysigset)) {
  6599. dns_zone_log(zone, ISC_LOG_WARNING,
  6600. "No DNSKEY RRSIGs found for "
  6601. "'%s': %s", namebuf, dns_result_totext(eresult));
  6602. CHECK(minimal_update(kfetch, ver, &diff));
  6603. goto done;
  6604. }
  6605. /*
  6606. * Validate the dnskeyset against the current trusted keys.
  6607. */
  6608. for (result = dns_rdataset_first(&kfetch->dnskeysigset);
  6609. result == ISC_R_SUCCESS;
  6610. result = dns_rdataset_next(&kfetch->dnskeysigset)) {
  6611. dns_keynode_t *keynode = NULL;
  6612. dns_rdata_reset(&sigrr);
  6613. dns_rdataset_current(&kfetch->dnskeysigset, &sigrr);
  6614. result = dns_rdata_tostruct(&sigrr, &sig, NULL);
  6615. RUNTIME_CHECK(result == ISC_R_SUCCESS);
  6616. result = dns_keytable_find(secroots, keyname, &keynode);
  6617. while (result == ISC_R_SUCCESS) {
  6618. dns_keynode_t *nextnode = NULL;
  6619. dns_fixedname_t fixed;
  6620. dns_fixedname_init(&fixed);
  6621. dstkey = dns_keynode_key(keynode);
  6622. if (dstkey == NULL) /* fail_secure() was called */
  6623. break;
  6624. if (dst_key_alg(dstkey) == sig.algorithm &&
  6625. dst_key_id(dstkey) == sig.keyid) {
  6626. result = dns_dnssec_verify2(keyname,
  6627. &kfetch->dnskeyset,
  6628. dstkey, ISC_FALSE,
  6629. zone->view->mctx, &sigrr,
  6630. dns_fixedname_name(&fixed));
  6631. dns_zone_log(zone, ISC_LOG_DEBUG(3),
  6632. "Verifying DNSKEY set for zone "
  6633. "'%s': %s", namebuf,
  6634. dns_result_totext(result));
  6635. if (result == ISC_R_SUCCESS) {
  6636. kfetch->dnskeyset.trust =
  6637. dns_trust_secure;
  6638. kfetch->dnskeysigset.trust =
  6639. dns_trust_secure;
  6640. dns_keytable_detachkeynode(secroots,
  6641. &keynode);
  6642. break;
  6643. }
  6644. }
  6645. result = dns_keytable_nextkeynode(secroots,
  6646. keynode, &nextnode);
  6647. dns_keytable_detachkeynode(secroots, &keynode);
  6648. keynode = nextnode;
  6649. }
  6650. if (kfetch->dnskeyset.trust == dns_trust_secure)
  6651. break;
  6652. }
  6653. /*
  6654. * If we were not able to verify the answer using the current
  6655. * trusted keys then all we can do is look at any revoked keys.
  6656. */
  6657. secure = ISC_TF(kfetch->dnskeyset.trust == dns_trust_secure);
  6658. /*
  6659. * First scan keydataset to find keys that are not in dnskeyset
  6660. * - Missing keys which are not scheduled for removal,
  6661. * log a warning
  6662. * - Missing keys which are scheduled for removal and
  6663. * the remove hold-down timer has completed should
  6664. * be removed from the key zone
  6665. * - Missing keys whose acceptance timers have not yet
  6666. * completed, log a warning and reset the acceptance
  6667. * timer to 30 days in the future
  6668. * - All keys not being removed have their refresh timers
  6669. * updated
  6670. */
  6671. initializing = ISC_TRUE;
  6672. for (result = dns_rdataset_first(&kfetch->keydataset);
  6673. result == ISC_R_SUCCESS;
  6674. result = dns_rdataset_next(&kfetch->keydataset)) {
  6675. dns_rdata_reset(&keydatarr);
  6676. dns_rdataset_current(&kfetch->keydataset, &keydatarr);
  6677. dns_rdata_tostruct(&keydatarr, &keydata, NULL);
  6678. /*
  6679. * If any keydata record has a nonzero add holddown, then
  6680. * there was a pre-existing trust anchor for this domain;
  6681. * that means we are *not* initializing it and shouldn't
  6682. * automatically trust all the keys we find at the zone apex.
  6683. */
  6684. initializing = initializing && ISC_TF(keydata.addhd == 0);
  6685. if (! matchkey(&kfetch->dnskeyset, &keydatarr)) {
  6686. isc_boolean_t deletekey = ISC_FALSE;
  6687. if (!secure) {
  6688. if (now > keydata.removehd)
  6689. deletekey = ISC_TRUE;
  6690. } else if (now < keydata.addhd) {
  6691. dns_zone_log(zone, ISC_LOG_WARNING,
  6692. "Pending key unexpectedly missing "
  6693. "from %s; restarting acceptance "
  6694. "timer", namebuf);
  6695. keydata.addhd = now + MONTH;
  6696. keydata.refresh = refresh_time(kfetch,
  6697. ISC_FALSE);
  6698. } else if (keydata.addhd == 0) {
  6699. keydata.addhd = now;
  6700. } else if (keydata.removehd == 0) {
  6701. dns_zone_log(zone, ISC_LOG_WARNING,
  6702. "Active key unexpectedly missing "
  6703. "from %s", namebuf);
  6704. keydata.refresh = now + HOUR;
  6705. } else if (now > keydata.removehd) {
  6706. deletekey = ISC_TRUE;
  6707. } else {
  6708. keydata.refresh = refresh_time(kfetch,
  6709. ISC_FALSE);
  6710. }
  6711. if (secure || deletekey) {
  6712. /* Delete old version */
  6713. CHECK(update_one_rr(kfetch->db, ver, &diff,
  6714. DNS_DIFFOP_DEL, keyname, 0,
  6715. &keydatarr));
  6716. }
  6717. if (!secure || deletekey)
  6718. continue;
  6719. dns_rdata_reset(&keydatarr);
  6720. isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
  6721. dns_rdata_fromstruct(&keydatarr, zone->rdclass,
  6722. dns_rdatatype_keydata,
  6723. &keydata, &keyb);
  6724. /* Insert updated version */
  6725. CHECK(update_one_rr(kfetch->db, ver, &diff,
  6726. DNS_DIFFOP_ADD, keyname, 0,
  6727. &keydatarr));
  6728. set_refreshkeytimer(zone, &keydata, now);
  6729. }
  6730. }
  6731. /*
  6732. * Next scan dnskeyset:
  6733. * - If new keys are found (i.e., lacking a match in keydataset)
  6734. * add them to the key zone and set the acceptance timer
  6735. * to 30 days in the future (or to immediately if we've
  6736. * determined that we're initializing the zone for the
  6737. * first time)
  6738. * - Previously-known keys that have been revoked
  6739. * must be scheduled for removal from the key zone (or,
  6740. * if they hadn't been accepted as trust anchors yet
  6741. * anyway, removed at once)
  6742. * - Previously-known unrevoked keys whose acceptance timers
  6743. * have completed are promoted to trust anchors
  6744. * - All keys not being removed have their refresh
  6745. * timers updated
  6746. */
  6747. for (result = dns_rdataset_first(&kfetch->dnskeyset);
  6748. result == ISC_R_SUCCESS;
  6749. result = dns_rdataset_next(&kfetch->dnskeyset)) {
  6750. isc_boolean_t revoked = ISC_FALSE;
  6751. isc_boolean_t newkey = ISC_FALSE;
  6752. isc_boolean_t updatekey = ISC_FALSE;
  6753. isc_boolean_t deletekey = ISC_FALSE;
  6754. isc_boolean_t trustkey = ISC_FALSE;
  6755. dns_rdata_reset(&dnskeyrr);
  6756. dns_rdataset_current(&kfetch->dnskeyset, &dnskeyrr);
  6757. dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
  6758. /* Skip ZSK's */
  6759. if (!ISC_TF(dnskey.flags & DNS_KEYFLAG_KSK))
  6760. continue;
  6761. revoked = ISC_TF(dnskey.flags & DNS_KEYFLAG_REVOKE);
  6762. if (matchkey(&kfetch->keydataset, &dnskeyrr)) {
  6763. dns_rdata_reset(&keydatarr);
  6764. dns_rdataset_current(&kfetch->keydataset, &keydatarr);
  6765. dns_rdata_tostruct(&keydatarr, &keydata, NULL);
  6766. if (revoked && revocable(kfetch, &keydata)) {
  6767. if (keydata.addhd > now) {
  6768. /*
  6769. * Key wasn't trusted yet, and now
  6770. * it's been revoked? Just remove it
  6771. */
  6772. deletekey = ISC_TRUE;
  6773. } else if (keydata.removehd == 0) {
  6774. /* Remove from secroots */
  6775. dns_view_untrust(zone->view, keyname,
  6776. &dnskey, mctx);
  6777. /* If initializing, delete now */
  6778. if (keydata.addhd == 0)
  6779. deletekey = ISC_TRUE;
  6780. else
  6781. keydata.removehd = now + MONTH;
  6782. } else if (keydata.removehd < now) {
  6783. /* Scheduled for removal */
  6784. deletekey = ISC_TRUE;
  6785. }
  6786. } else if (revoked) {
  6787. if (secure && keydata.removehd == 0) {
  6788. dns_zone_log(zone, ISC_LOG_WARNING,
  6789. "Active key for zone "
  6790. "'%s' is revoked but "
  6791. "did not self-sign; "
  6792. "ignoring.", namebuf);
  6793. continue;
  6794. }
  6795. } else if (secure) {
  6796. if (keydata.removehd != 0) {
  6797. /*
  6798. * Key isn't revoked--but it
  6799. * seems it used to be.
  6800. * Remove it now and add it
  6801. * back as if it were a fresh key.
  6802. */
  6803. deletekey = ISC_TRUE;
  6804. newkey = ISC_TRUE;
  6805. } else if (keydata.addhd > now)
  6806. pending++;
  6807. else if (keydata.addhd == 0)
  6808. keydata.addhd = now;
  6809. if (keydata.addhd <= now)
  6810. trustkey = ISC_TRUE;
  6811. }
  6812. if (!deletekey && !newkey)
  6813. updatekey = ISC_TRUE;
  6814. } else if (secure) {
  6815. /*
  6816. * Key wasn't in the key zone but it's
  6817. * revoked now anyway, so just skip it
  6818. */
  6819. if (revoked)
  6820. continue;
  6821. /* Key wasn't in the key zone: add it */
  6822. newkey = ISC_TRUE;
  6823. if (initializing) {
  6824. dns_keytag_t tag = 0;
  6825. CHECK(compute_tag(keyname, &dnskey,
  6826. mctx, &tag));
  6827. dns_zone_log(zone, ISC_LOG_WARNING,
  6828. "Initializing automatic trust "
  6829. "anchor management for zone '%s'; "
  6830. "DNSKEY ID %d is now trusted, "
  6831. "waiving the normal 30-day "
  6832. "waiting period.",
  6833. namebuf, tag);
  6834. trustkey = ISC_TRUE;
  6835. }
  6836. }
  6837. /* Delete old version */
  6838. if (deletekey || !newkey)
  6839. CHECK(update_one_rr(kfetch->db, ver, &diff,
  6840. DNS_DIFFOP_DEL, keyname, 0,
  6841. &keydatarr));
  6842. if (updatekey) {
  6843. /* Set refresh timer */
  6844. keydata.refresh = refresh_time(kfetch, ISC_FALSE);
  6845. dns_rdata_reset(&keydatarr);
  6846. isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
  6847. dns_rdata_fromstruct(&keydatarr, zone->rdclass,
  6848. dns_rdatatype_keydata,
  6849. &keydata, &keyb);
  6850. /* Insert updated version */
  6851. CHECK(update_one_rr(kfetch->db, ver, &diff,
  6852. DNS_DIFFOP_ADD, keyname, 0,
  6853. &keydatarr));
  6854. } else if (newkey) {
  6855. /* Convert DNSKEY to KEYDATA */
  6856. dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
  6857. dns_keydata_fromdnskey(&keydata, &dnskey, 0, 0, 0,
  6858. NULL);
  6859. keydata.addhd = initializing ? now : now + MONTH;
  6860. keydata.refresh = refresh_time(kfetch, ISC_FALSE);
  6861. dns_rdata_reset(&keydatarr);
  6862. isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
  6863. dns_rdata_fromstruct(&keydatarr, zone->rdclass,
  6864. dns_rdatatype_keydata,
  6865. &keydata, &keyb);
  6866. /* Insert into key zone */
  6867. CHECK(update_one_rr(kfetch->db, ver, &diff,
  6868. DNS_DIFFOP_ADD, keyname, 0,
  6869. &keydatarr));
  6870. }
  6871. if (trustkey) {
  6872. /* Trust this key. */
  6873. dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
  6874. trust_key(zone, keyname, &dnskey, mctx);
  6875. }
  6876. if (!deletekey)
  6877. set_refreshkeytimer(zone, &keydata, now);
  6878. }
  6879. /*
  6880. * RFC5011 says, "A trust point that has all of its trust anchors
  6881. * revoked is considered deleted and is treated as if the trust
  6882. * point was never configured." But if someone revoked their
  6883. * active key before the standby was trusted, that would mean the
  6884. * zone would suddenly be nonsecured. We avoid this by checking to
  6885. * see if there's pending keydata. If so, we put a null key in
  6886. * the security roots; then all queries to the zone will fail.
  6887. */
  6888. if (pending != 0)
  6889. fail_secure(zone, keyname);
  6890. done:
  6891. if (!ISC_LIST_EMPTY(diff.tuples)) {
  6892. /* Write changes to journal file. */
  6893. CHECK(increment_soa_serial(kfetch->db, ver, &diff, mctx));
  6894. CHECK(zone_journal(zone, &diff, "keyfetch_done"));
  6895. commit = ISC_TRUE;
  6896. DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
  6897. zone_needdump(zone, 30);
  6898. }
  6899. failure:
  6900. dns_diff_clear(&diff);
  6901. if (ver != NULL)
  6902. dns_db_closeversion(kfetch->db, &ver, commit);
  6903. cleanup:
  6904. dns_db_detach(&kfetch->db);
  6905. INSIST(zone->irefs > 0);
  6906. zone->irefs--;
  6907. kfetch->zone = NULL;
  6908. if (dns_rdataset_isassociated(&kfetch->keydataset))
  6909. dns_rdataset_disassociate(&kfetch->keydataset);
  6910. if (dns_rdataset_isassociated(&kfetch->dnskeyset))
  6911. dns_rdataset_disassociate(&kfetch->dnskeyset);
  6912. if (dns_rdataset_isassociated(&kfetch->dnskeysigset))
  6913. dns_rdataset_disassociate(&kfetch->dnskeysigset);
  6914. dns_name_free(keyname, mctx);
  6915. isc_mem_put(mctx, kfetch, sizeof(dns_keyfetch_t));
  6916. isc_mem_detach(&mctx);
  6917. if (secroots != NULL)
  6918. dns_keytable_detach(&secroots);
  6919. free_needed = exit_check(zone);
  6920. UNLOCK_ZONE(zone);
  6921. if (free_needed)
  6922. zone_free(zone);
  6923. }
  6924. /*
  6925. * Refresh the data in the key zone. Initiate a fetch to get new DNSKEY
  6926. * records from the zone apex.
  6927. */
  6928. static void
  6929. zone_refreshkeys(dns_zone_t *zone) {
  6930. const char me[] = "zone_refreshkeys";
  6931. isc_result_t result;
  6932. dns_rriterator_t rrit;
  6933. dns_db_t *db = NULL;
  6934. dns_dbversion_t *ver = NULL;
  6935. dns_diff_t diff;
  6936. dns_rdata_t rdata = DNS_RDATA_INIT;
  6937. dns_rdata_keydata_t kd;
  6938. isc_stdtime_t now;
  6939. isc_boolean_t commit = ISC_FALSE;
  6940. isc_boolean_t fetching = ISC_FALSE, fetch_err = ISC_FALSE;
  6941. ENTER;
  6942. REQUIRE(zone->db != NULL);
  6943. isc_stdtime_get(&now);
  6944. LOCK_ZONE(zone);
  6945. if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
  6946. isc_time_settoepoch(&zone->refreshkeytime);
  6947. UNLOCK_ZONE(zone);
  6948. return;
  6949. }
  6950. ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
  6951. dns_db_attach(zone->db, &db);
  6952. ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
  6953. dns_diff_init(zone->mctx, &diff);
  6954. CHECK(dns_db_newversion(db, &ver));
  6955. DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESHING);
  6956. dns_rriterator_init(&rrit, db, ver, 0);
  6957. for (result = dns_rriterator_first(&rrit);
  6958. result == ISC_R_SUCCESS;
  6959. result = dns_rriterator_nextrrset(&rrit)) {
  6960. isc_stdtime_t timer = 0xffffffff;
  6961. dns_name_t *name = NULL, *kname = NULL;
  6962. dns_rdataset_t *kdset = NULL;
  6963. dns_keyfetch_t *kfetch;
  6964. isc_uint32_t ttl;
  6965. dns_rriterator_current(&rrit, &name, &ttl, &kdset, NULL);
  6966. if (kdset == NULL || kdset->type != dns_rdatatype_keydata ||
  6967. !dns_rdataset_isassociated(kdset))
  6968. continue;
  6969. /*
  6970. * Scan the stored keys looking for ones that need
  6971. * removal or refreshing
  6972. */
  6973. for (result = dns_rdataset_first(kdset);
  6974. result == ISC_R_SUCCESS;
  6975. result = dns_rdataset_next(kdset)) {
  6976. dns_rdata_reset(&rdata);
  6977. dns_rdataset_current(kdset, &rdata);
  6978. result = dns_rdata_tostruct(&rdata, &kd, NULL);
  6979. RUNTIME_CHECK(result == ISC_R_SUCCESS);
  6980. /* Removal timer expired? */
  6981. if (kd.removehd != 0 && kd.removehd < now) {
  6982. CHECK(update_one_rr(db, ver, &diff,
  6983. DNS_DIFFOP_DEL, name, ttl,
  6984. &rdata));
  6985. continue;
  6986. }
  6987. /* Acceptance timer expired? */
  6988. if (kd.addhd != 0 && kd.addhd < now)
  6989. timer = kd.addhd;
  6990. /* Or do we just need to refresh the keyset? */
  6991. if (timer > kd.refresh)
  6992. timer = kd.refresh;
  6993. }
  6994. if (timer > now)
  6995. continue;
  6996. kfetch = isc_mem_get(zone->mctx, sizeof(dns_keyfetch_t));
  6997. if (kfetch == NULL) {
  6998. fetch_err = ISC_TRUE;
  6999. goto failure;
  7000. }
  7001. zone->refreshkeycount++;
  7002. kfetch->zone = zone;
  7003. zone->irefs++;
  7004. INSIST(zone->irefs != 0);
  7005. dns_fixedname_init(&kfetch->name);
  7006. kname = dns_fixedname_name(&kfetch->name);
  7007. dns_name_dup(name, zone->mctx, kname);
  7008. dns_rdataset_init(&kfetch->dnskeyset);
  7009. dns_rdataset_init(&kfetch->dnskeysigset);
  7010. dns_rdataset_init(&kfetch->keydataset);
  7011. dns_rdataset_clone(kdset, &kfetch->keydataset);
  7012. kfetch->db = NULL;
  7013. dns_db_attach(db, &kfetch->db);
  7014. kfetch->fetch = NULL;
  7015. result = dns_resolver_createfetch(zone->view->resolver,
  7016. kname, dns_rdatatype_dnskey,
  7017. NULL, NULL, NULL,
  7018. DNS_FETCHOPT_NOVALIDATE,
  7019. zone->task,
  7020. keyfetch_done, kfetch,
  7021. &kfetch->dnskeyset,
  7022. &kfetch->dnskeysigset,
  7023. &kfetch->fetch);
  7024. if (result == ISC_R_SUCCESS)
  7025. fetching = ISC_TRUE;
  7026. else {
  7027. zone->refreshkeycount--;
  7028. zone->irefs--;
  7029. dns_db_detach(&kfetch->db);
  7030. dns_rdataset_disassociate(&kfetch->keydataset);
  7031. dns_name_free(kname, zone->mctx);
  7032. isc_mem_put(zone->mctx, kfetch, sizeof(dns_keyfetch_t));
  7033. dns_zone_log(zone, ISC_LOG_WARNING,
  7034. "Failed to create fetch for "
  7035. "DNSKEY update");
  7036. fetch_err = ISC_TRUE;
  7037. }
  7038. }
  7039. if (!ISC_LIST_EMPTY(diff.tuples)) {
  7040. CHECK(increment_soa_serial(db, ver, &diff, zone->mctx));
  7041. CHECK(zone_journal(zone, &diff, "zone_refreshkeys"));
  7042. commit = ISC_TRUE;
  7043. DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
  7044. zone_needdump(zone, 30);
  7045. }
  7046. failure:
  7047. if (fetch_err) {
  7048. /*
  7049. * Error during a key fetch; retry in an hour.
  7050. */
  7051. isc_time_t timenow, timethen;
  7052. char timebuf[80];
  7053. TIME_NOW(&timenow);
  7054. DNS_ZONE_TIME_ADD(&timenow, HOUR, &timethen);
  7055. zone->refreshkeytime = timethen;
  7056. zone_settimer(zone, &timenow);
  7057. isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
  7058. dns_zone_log(zone, ISC_LOG_DEBUG(1), "retry key refresh: %s",
  7059. timebuf);
  7060. if (!fetching)
  7061. DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESHING);
  7062. }
  7063. UNLOCK_ZONE(zone);
  7064. dns_diff_clear(&diff);
  7065. if (ver != NULL) {
  7066. dns_rriterator_destroy(&rrit);
  7067. dns_db_closeversion(db, &ver, commit);
  7068. }
  7069. dns_db_detach(&db);
  7070. }
  7071. static void
  7072. zone_maintenance(dns_zone_t *zone) {
  7073. const char me[] = "zone_maintenance";
  7074. isc_time_t now;
  7075. isc_result_t result;
  7076. isc_boolean_t dumping;
  7077. REQUIRE(DNS_ZONE_VALID(zone));
  7078. ENTER;
  7079. /*
  7080. * Configuring the view of this zone may have
  7081. * failed, for example because the config file
  7082. * had a syntax error. In that case, the view
  7083. * db or resolver will be NULL, and we had better not try
  7084. * to do maintenance on it.
  7085. */
  7086. if (zone->view == NULL || zone->view->adb == NULL)
  7087. return;
  7088. TIME_NOW(&now);
  7089. /*
  7090. * Expire check.
  7091. */
  7092. switch (zone->type) {
  7093. case dns_zone_slave:
  7094. case dns_zone_stub:
  7095. LOCK_ZONE(zone);
  7096. if (isc_time_compare(&now, &zone->expiretime) >= 0 &&
  7097. DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
  7098. zone_expire(zone);
  7099. zone->refreshtime = now;
  7100. }
  7101. UNLOCK_ZONE(zone);
  7102. break;
  7103. default:
  7104. break;
  7105. }
  7106. /*
  7107. * Up to date check.
  7108. */
  7109. switch (zone->type) {
  7110. case dns_zone_slave:
  7111. case dns_zone_stub:
  7112. if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH) &&
  7113. isc_time_compare(&now, &zone->refreshtime) >= 0)
  7114. dns_zone_refresh(zone);
  7115. break;
  7116. default:
  7117. break;
  7118. }
  7119. /*
  7120. * Do we need to consolidate the backing store?
  7121. */
  7122. switch (zone->type) {
  7123. case dns_zone_master:
  7124. case dns_zone_slave:
  7125. case dns_zone_key:
  7126. case dns_zone_stub:
  7127. LOCK_ZONE(zone);
  7128. if (zone->masterfile != NULL &&
  7129. isc_time_compare(&now, &zone->dumptime) >= 0 &&
  7130. DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
  7131. DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP)) {
  7132. dumping = was_dumping(zone);
  7133. } else
  7134. dumping = ISC_TRUE;
  7135. UNLOCK_ZONE(zone);
  7136. if (!dumping) {
  7137. result = zone_dump(zone, ISC_TRUE); /* task locked */
  7138. if (result != ISC_R_SUCCESS)
  7139. dns_zone_log(zone, ISC_LOG_WARNING,
  7140. "dump failed: %s",
  7141. dns_result_totext(result));
  7142. }
  7143. break;
  7144. default:
  7145. break;
  7146. }
  7147. /*
  7148. * Do we need to refresh keys?
  7149. */
  7150. switch (zone->type) {
  7151. case dns_zone_key:
  7152. if (isc_time_compare(&now, &zone->refreshkeytime) >= 0 &&
  7153. DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
  7154. !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING))
  7155. zone_refreshkeys(zone);
  7156. break;
  7157. case dns_zone_master:
  7158. if (!isc_time_isepoch(&zone->refreshkeytime) &&
  7159. isc_time_compare(&now, &zone->refreshkeytime) >= 0)
  7160. zone_rekey(zone);
  7161. default:
  7162. break;
  7163. }
  7164. switch (zone->type) {
  7165. case dns_zone_master:
  7166. case dns_zone_slave:
  7167. /*
  7168. * Do we need to send out notify messages?
  7169. */
  7170. if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) &&
  7171. isc_time_compare(&now, &zone->notifytime) >= 0)
  7172. zone_notify(zone, &now);
  7173. /*
  7174. * Do we need to sign/resign some RRsets?
  7175. */
  7176. if (!isc_time_isepoch(&zone->signingtime) &&
  7177. isc_time_compare(&now, &zone->signingtime) >= 0)
  7178. zone_sign(zone);
  7179. else if (!isc_time_isepoch(&zone->resigntime) &&
  7180. isc_time_compare(&now, &zone->resigntime) >= 0)
  7181. zone_resigninc(zone);
  7182. else if (!isc_time_isepoch(&zone->nsec3chaintime) &&
  7183. isc_time_compare(&now, &zone->nsec3chaintime) >= 0)
  7184. zone_nsec3chain(zone);
  7185. /*
  7186. * Do we need to issue a key expiry warning.
  7187. */
  7188. if (!isc_time_isepoch(&zone->keywarntime) &&
  7189. isc_time_compare(&now, &zone->keywarntime) >= 0)
  7190. set_key_expiry_warning(zone, zone->key_expiry,
  7191. isc_time_seconds(&now));
  7192. break;
  7193. default:
  7194. break;
  7195. }
  7196. zone_settimer(zone, &now);
  7197. }
  7198. void
  7199. dns_zone_markdirty(dns_zone_t *zone) {
  7200. LOCK_ZONE(zone);
  7201. if (zone->type == dns_zone_master)
  7202. set_resigntime(zone); /* XXXMPA make separate call back */
  7203. zone_needdump(zone, DNS_DUMP_DELAY);
  7204. UNLOCK_ZONE(zone);
  7205. }
  7206. void
  7207. dns_zone_expire(dns_zone_t *zone) {
  7208. REQUIRE(DNS_ZONE_VALID(zone));
  7209. LOCK_ZONE(zone);
  7210. zone_expire(zone);
  7211. UNLOCK_ZONE(zone);
  7212. }
  7213. static void
  7214. zone_expire(dns_zone_t *zone) {
  7215. /*
  7216. * 'zone' locked by caller.
  7217. */
  7218. REQUIRE(LOCKED_ZONE(zone));
  7219. dns_zone_log(zone, ISC_LOG_WARNING, "expired");
  7220. DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXPIRED);
  7221. zone->refresh = DNS_ZONE_DEFAULTREFRESH;
  7222. zone->retry = DNS_ZONE_DEFAULTRETRY;
  7223. DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
  7224. zone_unload(zone);
  7225. }
  7226. void
  7227. dns_zone_refresh(dns_zone_t *zone) {
  7228. isc_interval_t i;
  7229. isc_uint32_t oldflags;
  7230. unsigned int j;
  7231. isc_result_t result;
  7232. REQUIRE(DNS_ZONE_VALID(zone));
  7233. if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
  7234. return;
  7235. /*
  7236. * Set DNS_ZONEFLG_REFRESH so that there is only one refresh operation
  7237. * in progress at a time.
  7238. */
  7239. LOCK_ZONE(zone);
  7240. oldflags = zone->flags;
  7241. if (zone->masterscnt == 0) {
  7242. DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOMASTERS);
  7243. if ((oldflags & DNS_ZONEFLG_NOMASTERS) == 0)
  7244. dns_zone_log(zone, ISC_LOG_ERROR,
  7245. "cannot refresh: no masters");
  7246. goto unlock;
  7247. }
  7248. DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
  7249. DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
  7250. DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
  7251. if ((oldflags & (DNS_ZONEFLG_REFRESH|DNS_ZONEFLG_LOADING)) != 0)
  7252. goto unlock;
  7253. /*
  7254. * Set the next refresh time as if refresh check has failed.
  7255. * Setting this to the retry time will do that. XXXMLG
  7256. * If we are successful it will be reset using zone->refresh.
  7257. */
  7258. isc_interval_set(&i, isc_random_jitter(zone->retry, zone->retry / 4),
  7259. 0);
  7260. result = isc_time_nowplusinterval(&zone->refreshtime, &i);
  7261. if (result != ISC_R_SUCCESS)
  7262. dns_zone_log(zone, ISC_LOG_WARNING,
  7263. "isc_time_nowplusinterval() failed: %s",
  7264. dns_result_totext(result));
  7265. /*
  7266. * When lacking user-specified timer values from the SOA,
  7267. * do exponential backoff of the retry time up to a
  7268. * maximum of six hours.
  7269. */
  7270. if (! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HAVETIMERS))
  7271. zone->retry = ISC_MIN(zone->retry * 2, 6 * 3600);
  7272. zone->curmaster = 0;
  7273. for (j = 0; j < zone->masterscnt; j++)
  7274. zone->mastersok[j] = ISC_FALSE;
  7275. /* initiate soa query */
  7276. queue_soa_query(zone);
  7277. unlock:
  7278. UNLOCK_ZONE(zone);
  7279. }
  7280. isc_result_t
  7281. dns_zone_flush(dns_zone_t *zone) {
  7282. isc_result_t result = ISC_R_SUCCESS;
  7283. isc_boolean_t dumping;
  7284. REQUIRE(DNS_ZONE_VALID(zone));
  7285. LOCK_ZONE(zone);
  7286. DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FLUSH);
  7287. if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
  7288. zone->masterfile != NULL) {
  7289. result = ISC_R_ALREADYRUNNING;
  7290. dumping = was_dumping(zone);
  7291. } else
  7292. dumping = ISC_TRUE;
  7293. UNLOCK_ZONE(zone);
  7294. if (!dumping)
  7295. result = zone_dump(zone, ISC_FALSE); /* Unknown task. */
  7296. return (result);
  7297. }
  7298. isc_result_t
  7299. dns_zone_dump(dns_zone_t *zone) {
  7300. isc_result_t result = ISC_R_ALREADYRUNNING;
  7301. isc_boolean_t dumping;
  7302. REQUIRE(DNS_ZONE_VALID(zone));
  7303. LOCK_ZONE(zone);
  7304. dumping = was_dumping(zone);
  7305. UNLOCK_ZONE(zone);
  7306. if (!dumping)
  7307. result = zone_dump(zone, ISC_FALSE); /* Unknown task. */
  7308. return (result);
  7309. }
  7310. static void
  7311. zone_needdump(dns_zone_t *zone, unsigned int delay) {
  7312. isc_time_t dumptime;
  7313. isc_time_t now;
  7314. /*
  7315. * 'zone' locked by caller
  7316. */
  7317. REQUIRE(DNS_ZONE_VALID(zone));
  7318. REQUIRE(LOCKED_ZONE(zone));
  7319. /*
  7320. * Do we have a place to dump to and are we loaded?
  7321. */
  7322. if (zone->masterfile == NULL ||
  7323. DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0)
  7324. return;
  7325. TIME_NOW(&now);
  7326. /* add some noise */
  7327. DNS_ZONE_JITTER_ADD(&now, delay, &dumptime);
  7328. DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
  7329. if (isc_time_isepoch(&zone->dumptime) ||
  7330. isc_time_compare(&zone->dumptime, &dumptime) > 0)
  7331. zone->dumptime = dumptime;
  7332. if (zone->task != NULL)
  7333. zone_settimer(zone, &now);
  7334. }
  7335. static void
  7336. dump_done(void *arg, isc_result_t result) {
  7337. const char me[] = "dump_done";
  7338. dns_zone_t *zone = arg;
  7339. dns_db_t *db;
  7340. dns_dbversion_t *version;
  7341. isc_boolean_t again = ISC_FALSE;
  7342. isc_boolean_t compact = ISC_FALSE;
  7343. isc_uint32_t serial;
  7344. isc_result_t tresult;
  7345. REQUIRE(DNS_ZONE_VALID(zone));
  7346. ENTER;
  7347. if (result == ISC_R_SUCCESS && zone->journal != NULL &&
  7348. zone->journalsize != -1) {
  7349. /*
  7350. * We don't own these, zone->dctx must stay valid.
  7351. */
  7352. db = dns_dumpctx_db(zone->dctx);
  7353. version = dns_dumpctx_version(zone->dctx);
  7354. tresult = dns_db_getsoaserial(db, version, &serial);
  7355. /*
  7356. * Note: we are task locked here so we can test
  7357. * zone->xfr safely.
  7358. */
  7359. if (tresult == ISC_R_SUCCESS && zone->xfr == NULL) {
  7360. tresult = dns_journal_compact(zone->mctx,
  7361. zone->journal,
  7362. serial,
  7363. zone->journalsize);
  7364. switch (tresult) {
  7365. case ISC_R_SUCCESS:
  7366. case ISC_R_NOSPACE:
  7367. case ISC_R_NOTFOUND:
  7368. dns_zone_log(zone, ISC_LOG_DEBUG(3),
  7369. "dns_journal_compact: %s",
  7370. dns_result_totext(tresult));
  7371. break;
  7372. default:
  7373. dns_zone_log(zone, ISC_LOG_ERROR,
  7374. "dns_journal_compact failed: %s",
  7375. dns_result_totext(tresult));
  7376. break;
  7377. }
  7378. } else if (tresult == ISC_R_SUCCESS) {
  7379. compact = ISC_TRUE;
  7380. zone->compact_serial = serial;
  7381. }
  7382. }
  7383. LOCK_ZONE(zone);
  7384. DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING);
  7385. if (compact)
  7386. DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT);
  7387. if (result != ISC_R_SUCCESS && result != ISC_R_CANCELED) {
  7388. /*
  7389. * Try again in a short while.
  7390. */
  7391. zone_needdump(zone, DNS_DUMP_DELAY);
  7392. } else if (result == ISC_R_SUCCESS &&
  7393. DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) &&
  7394. DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
  7395. DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
  7396. DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
  7397. DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
  7398. isc_time_settoepoch(&zone->dumptime);
  7399. again = ISC_TRUE;
  7400. } else if (result == ISC_R_SUCCESS)
  7401. DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH);
  7402. if (zone->dctx != NULL)
  7403. dns_dumpctx_detach(&zone->dctx);
  7404. zonemgr_putio(&zone->writeio);
  7405. UNLOCK_ZONE(zone);
  7406. if (again)
  7407. (void)zone_dump(zone, ISC_FALSE);
  7408. dns_zone_idetach(&zone);
  7409. }
  7410. static isc_result_t
  7411. zone_dump(dns_zone_t *zone, isc_boolean_t compact) {
  7412. const char me[] = "zone_dump";
  7413. isc_result_t result;
  7414. dns_dbversion_t *version = NULL;
  7415. isc_boolean_t again;
  7416. dns_db_t *db = NULL;
  7417. char *masterfile = NULL;
  7418. dns_masterformat_t masterformat = dns_masterformat_none;
  7419. /*
  7420. * 'compact' MUST only be set if we are task locked.
  7421. */
  7422. REQUIRE(DNS_ZONE_VALID(zone));
  7423. ENTER;
  7424. redo:
  7425. ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
  7426. if (zone->db != NULL)
  7427. dns_db_attach(zone->db, &db);
  7428. ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
  7429. LOCK_ZONE(zone);
  7430. if (zone->masterfile != NULL) {
  7431. masterfile = isc_mem_strdup(zone->mctx, zone->masterfile);
  7432. masterformat = zone->masterformat;
  7433. }
  7434. UNLOCK_ZONE(zone);
  7435. if (db == NULL) {
  7436. result = DNS_R_NOTLOADED;
  7437. goto fail;
  7438. }
  7439. if (masterfile == NULL) {
  7440. result = DNS_R_NOMASTERFILE;
  7441. goto fail;
  7442. }
  7443. if (compact && zone->type != dns_zone_stub) {
  7444. dns_zone_t *dummy = NULL;
  7445. LOCK_ZONE(zone);
  7446. zone_iattach(zone, &dummy);
  7447. result = zonemgr_getio(zone->zmgr, ISC_FALSE, zone->task,
  7448. zone_gotwritehandle, zone,
  7449. &zone->writeio);
  7450. if (result != ISC_R_SUCCESS)
  7451. zone_idetach(&dummy);
  7452. else
  7453. result = DNS_R_CONTINUE;
  7454. UNLOCK_ZONE(zone);
  7455. } else {
  7456. dns_db_currentversion(db, &version);
  7457. result = dns_master_dump2(zone->mctx, db, version,
  7458. &dns_master_style_default,
  7459. masterfile, masterformat);
  7460. dns_db_closeversion(db, &version, ISC_FALSE);
  7461. }
  7462. fail:
  7463. if (db != NULL)
  7464. dns_db_detach(&db);
  7465. if (masterfile != NULL)
  7466. isc_mem_free(zone->mctx, masterfile);
  7467. masterfile = NULL;
  7468. if (result == DNS_R_CONTINUE)
  7469. return (ISC_R_SUCCESS); /* XXXMPA */
  7470. again = ISC_FALSE;
  7471. LOCK_ZONE(zone);
  7472. DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING);
  7473. if (result != ISC_R_SUCCESS) {
  7474. /*
  7475. * Try again in a short while.
  7476. */
  7477. zone_needdump(zone, DNS_DUMP_DELAY);
  7478. } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) &&
  7479. DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
  7480. DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
  7481. DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
  7482. DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
  7483. isc_time_settoepoch(&zone->dumptime);
  7484. again = ISC_TRUE;
  7485. } else
  7486. DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH);
  7487. UNLOCK_ZONE(zone);
  7488. if (again)
  7489. goto redo;
  7490. return (result);
  7491. }
  7492. static isc_result_t
  7493. dumptostream(dns_zone_t *zone, FILE *fd, const dns_master_style_t *style,
  7494. dns_masterformat_t format)
  7495. {
  7496. isc_result_t result;
  7497. dns_dbversion_t *version = NULL;
  7498. dns_db_t *db = NULL;
  7499. REQUIRE(DNS_ZONE_VALID(zone));
  7500. ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
  7501. if (zone->db != NULL)
  7502. dns_db_attach(zone->db, &db);
  7503. ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
  7504. if (db == NULL)
  7505. return (DNS_R_NOTLOADED);
  7506. dns_db_currentversion(db, &version);
  7507. result = dns_master_dumptostream2(zone->mctx, db, version, style,
  7508. format, fd);
  7509. dns_db_closeversion(db, &version, ISC_FALSE);
  7510. dns_db_detach(&db);
  7511. return (result);
  7512. }
  7513. isc_result_t
  7514. dns_zone_dumptostream2(dns_zone_t *zone, FILE *fd, dns_masterformat_t format,
  7515. const dns_master_style_t *style) {
  7516. return dumptostream(zone, fd, style, format);
  7517. }
  7518. isc_result_t
  7519. dns_zone_dumptostream(dns_zone_t *zone, FILE *fd) {
  7520. return dumptostream(zone, fd, &dns_master_style_default,
  7521. dns_masterformat_text);
  7522. }
  7523. isc_result_t
  7524. dns_zone_fulldumptostream(dns_zone_t *zone, FILE *fd) {
  7525. return dumptostream(zone, fd, &dns_master_style_full,
  7526. dns_masterformat_text);
  7527. }
  7528. void
  7529. dns_zone_unload(dns_zone_t *zone) {
  7530. REQUIRE(DNS_ZONE_VALID(zone));
  7531. LOCK_ZONE(zone);
  7532. zone_unload(zone);
  7533. UNLOCK_ZONE(zone);
  7534. }
  7535. static void
  7536. notify_cancel(dns_zone_t *zone) {
  7537. dns_notify_t *notify;
  7538. /*
  7539. * 'zone' locked by caller.
  7540. */
  7541. REQUIRE(LOCKED_ZONE(zone));
  7542. for (notify = ISC_LIST_HEAD(zone->notifies);
  7543. notify != NULL;
  7544. notify = ISC_LIST_NEXT(notify, link)) {
  7545. if (notify->find != NULL)
  7546. dns_adb_cancelfind(notify->find);
  7547. if (notify->request != NULL)
  7548. dns_request_cancel(notify->request);
  7549. }
  7550. }
  7551. static void
  7552. forward_cancel(dns_zone_t *zone) {
  7553. dns_forward_t *forward;
  7554. /*
  7555. * 'zone' locked by caller.
  7556. */
  7557. REQUIRE(LOCKED_ZONE(zone));
  7558. for (forward = ISC_LIST_HEAD(zone->forwards);
  7559. forward != NULL;
  7560. forward = ISC_LIST_NEXT(forward, link)) {
  7561. if (forward->request != NULL)
  7562. dns_request_cancel(forward->request);
  7563. }
  7564. }
  7565. static void
  7566. zone_unload(dns_zone_t *zone) {
  7567. /*
  7568. * 'zone' locked by caller.
  7569. */
  7570. REQUIRE(LOCKED_ZONE(zone));
  7571. if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) ||
  7572. !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
  7573. if (zone->writeio != NULL)
  7574. zonemgr_cancelio(zone->writeio);
  7575. if (zone->dctx != NULL)
  7576. dns_dumpctx_cancel(zone->dctx);
  7577. }
  7578. ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
  7579. zone_detachdb(zone);
  7580. ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
  7581. DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADED);
  7582. DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
  7583. }
  7584. void
  7585. dns_zone_setminrefreshtime(dns_zone_t *zone, isc_uint32_t val) {
  7586. REQUIRE(DNS_ZONE_VALID(zone));
  7587. REQUIRE(val > 0);
  7588. zone->minrefresh = val;
  7589. }
  7590. void
  7591. dns_zone_setmaxrefreshtime(dns_zone_t *zone, isc_uint32_t val) {
  7592. REQUIRE(DNS_ZONE_VALID(zone));
  7593. REQUIRE(val > 0);
  7594. zone->maxrefresh = val;
  7595. }
  7596. void
  7597. dns_zone_setminretrytime(dns_zone_t *zone, isc_uint32_t val) {
  7598. REQUIRE(DNS_ZONE_VALID(zone));
  7599. REQUIRE(val > 0);
  7600. zone->minretry = val;
  7601. }
  7602. void
  7603. dns_zone_setmaxretrytime(dns_zone_t *zone, isc_uint32_t val) {
  7604. REQUIRE(DNS_ZONE_VALID(zone));
  7605. REQUIRE(val > 0);
  7606. zone->maxretry = val;
  7607. }
  7608. static isc_boolean_t
  7609. notify_isqueued(dns_zone_t *zone, dns_name_t *name, isc_sockaddr_t *addr) {
  7610. dns_notify_t *notify;
  7611. for (notify = ISC_LIST_HEAD(zone->notifies);
  7612. notify != NULL;
  7613. notify = ISC_LIST_NEXT(notify, link)) {
  7614. if (notify->request != NULL)
  7615. continue;
  7616. if (name != NULL && dns_name_dynamic(&notify->ns) &&
  7617. dns_name_equal(name, &notify->ns))
  7618. return (ISC_TRUE);
  7619. if (addr != NULL && isc_sockaddr_equal(addr, &notify->dst))
  7620. return (ISC_TRUE);
  7621. }
  7622. return (ISC_FALSE);
  7623. }
  7624. static isc_boolean_t
  7625. notify_isself(dns_zone_t *zone, isc_sockaddr_t *dst) {
  7626. dns_tsigkey_t *key = NULL;
  7627. isc_sockaddr_t src;
  7628. isc_sockaddr_t any;
  7629. isc_boolean_t isself;
  7630. isc_netaddr_t dstaddr;
  7631. isc_result_t result;
  7632. if (zone->view == NULL || zone->isself == NULL)
  7633. return (ISC_FALSE);
  7634. switch (isc_sockaddr_pf(dst)) {
  7635. case PF_INET:
  7636. src = zone->notifysrc4;
  7637. isc_sockaddr_any(&any);
  7638. break;
  7639. case PF_INET6:
  7640. src = zone->notifysrc6;
  7641. isc_sockaddr_any6(&any);
  7642. break;
  7643. default:
  7644. return (ISC_FALSE);
  7645. }
  7646. /*
  7647. * When sending from any the kernel will assign a source address
  7648. * that matches the destination address.
  7649. */
  7650. if (isc_sockaddr_eqaddr(&any, &src))
  7651. src = *dst;
  7652. isc_netaddr_fromsockaddr(&dstaddr, dst);
  7653. result = dns_view_getpeertsig(zone->view, &dstaddr, &key);
  7654. if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
  7655. return (ISC_FALSE);
  7656. isself = (zone->isself)(zone->view, key, &src, dst, zone->rdclass,
  7657. zone->isselfarg);
  7658. if (key != NULL)
  7659. dns_tsigkey_detach(&key);
  7660. return (isself);
  7661. }
  7662. static void
  7663. notify_destroy(dns_notify_t *notify, isc_boolean_t locked) {
  7664. isc_mem_t *mctx;
  7665. /*
  7666. * Caller holds zone lock.
  7667. */
  7668. REQUIRE(DNS_NOTIFY_VALID(notify));
  7669. if (notify->zone != NULL) {
  7670. if (!locked)
  7671. LOCK_ZONE(notify->zone);
  7672. REQUIRE(LOCKED_ZONE(notify->zone));
  7673. if (ISC_LINK_LINKED(notify, link))
  7674. ISC_LIST_UNLINK(notify->zone->notifies, notify, link);
  7675. if (!locked)
  7676. UNLOCK_ZONE(notify->zone);
  7677. if (locked)
  7678. zone_idetach(&notify->zone);
  7679. else
  7680. dns_zone_idetach(&notify->zone);
  7681. }
  7682. if (notify->find != NULL)
  7683. dns_adb_destroyfind(&notify->find);
  7684. if (notify->request != NULL)
  7685. dns_request_destroy(&notify->request);
  7686. if (dns_name_dynamic(&notify->ns))
  7687. dns_name_free(&notify->ns, notify->mctx);
  7688. mctx = notify->mctx;
  7689. isc_mem_put(notify->mctx, notify, sizeof(*notify));
  7690. isc_mem_detach(&mctx);
  7691. }
  7692. static isc_result_t
  7693. notify_create(isc_mem_t *mctx, unsigned int flags, dns_notify_t **notifyp) {
  7694. dns_notify_t *notify;
  7695. REQUIRE(notifyp != NULL && *notifyp == NULL);
  7696. notify = isc_mem_get(mctx, sizeof(*notify));
  7697. if (notify == NULL)
  7698. return (ISC_R_NOMEMORY);
  7699. notify->mctx = NULL;
  7700. isc_mem_attach(mctx, &notify->mctx);
  7701. notify->flags = flags;
  7702. notify->zone = NULL;
  7703. notify->find = NULL;
  7704. notify->request = NULL;
  7705. isc_sockaddr_any(&notify->dst);
  7706. dns_name_init(&notify->ns, NULL);
  7707. ISC_LINK_INIT(notify, link);
  7708. notify->magic = NOTIFY_MAGIC;
  7709. *notifyp = notify;
  7710. return (ISC_R_SUCCESS);
  7711. }
  7712. /*
  7713. * XXXAG should check for DNS_ZONEFLG_EXITING
  7714. */
  7715. static void
  7716. process_adb_event(isc_task_t *task, isc_event_t *ev) {
  7717. dns_notify_t *notify;
  7718. isc_eventtype_t result;
  7719. UNUSED(task);
  7720. notify = ev->ev_arg;
  7721. REQUIRE(DNS_NOTIFY_VALID(notify));
  7722. INSIST(task == notify->zone->task);
  7723. result = ev->ev_type;
  7724. isc_event_free(&ev);
  7725. if (result == DNS_EVENT_ADBMOREADDRESSES) {
  7726. dns_adb_destroyfind(&notify->find);
  7727. notify_find_address(notify);
  7728. return;
  7729. }
  7730. if (result == DNS_EVENT_ADBNOMOREADDRESSES) {
  7731. LOCK_ZONE(notify->zone);
  7732. notify_send(notify);
  7733. UNLOCK_ZONE(notify->zone);
  7734. }
  7735. notify_destroy(notify, ISC_FALSE);
  7736. }
  7737. static void
  7738. notify_find_address(dns_notify_t *notify) {
  7739. isc_result_t result;
  7740. unsigned int options;
  7741. REQUIRE(DNS_NOTIFY_VALID(notify));
  7742. options = DNS_ADBFIND_WANTEVENT | DNS_ADBFIND_INET |
  7743. DNS_ADBFIND_INET6 | DNS_ADBFIND_RETURNLAME;
  7744. if (notify->zone->view->adb == NULL)
  7745. goto destroy;
  7746. result = dns_adb_createfind(notify->zone->view->adb,
  7747. notify->zone->task,
  7748. process_adb_event, notify,
  7749. &notify->ns, dns_rootname, 0,
  7750. options, 0, NULL,
  7751. notify->zone->view->dstport,
  7752. &notify->find);
  7753. /* Something failed? */
  7754. if (result != ISC_R_SUCCESS)
  7755. goto destroy;
  7756. /* More addresses pending? */
  7757. if ((notify->find->options & DNS_ADBFIND_WANTEVENT) != 0)
  7758. return;
  7759. /* We have as many addresses as we can get. */
  7760. LOCK_ZONE(notify->zone);
  7761. notify_send(notify);
  7762. UNLOCK_ZONE(notify->zone);
  7763. destroy:
  7764. notify_destroy(notify, ISC_FALSE);
  7765. }
  7766. static isc_result_t
  7767. notify_send_queue(dns_notify_t *notify) {
  7768. isc_event_t *e;
  7769. isc_result_t result;
  7770. e = isc_event_allocate(notify->mctx, NULL,
  7771. DNS_EVENT_NOTIFYSENDTOADDR,
  7772. notify_send_toaddr,
  7773. notify, sizeof(isc_event_t));
  7774. if (e == NULL)
  7775. return (ISC_R_NOMEMORY);
  7776. e->ev_arg = notify;
  7777. e->ev_sender = NULL;
  7778. result = isc_ratelimiter_enqueue(notify->zone->zmgr->rl,
  7779. notify->zone->task, &e);
  7780. if (result != ISC_R_SUCCESS)
  7781. isc_event_free(&e);
  7782. return (result);
  7783. }
  7784. static void
  7785. notify_send_toaddr(isc_task_t *task, isc_event_t *event) {
  7786. dns_notify_t *notify;
  7787. isc_result_t result;
  7788. dns_message_t *message = NULL;
  7789. isc_netaddr_t dstip;
  7790. dns_tsigkey_t *key = NULL;
  7791. char addrbuf[ISC_SOCKADDR_FORMATSIZE];
  7792. isc_sockaddr_t src;
  7793. int timeout;
  7794. isc_boolean_t have_notifysource = ISC_FALSE;
  7795. notify = event->ev_arg;
  7796. REQUIRE(DNS_NOTIFY_VALID(notify));
  7797. UNUSED(task);
  7798. LOCK_ZONE(notify->zone);
  7799. if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_LOADED) == 0) {
  7800. result = ISC_R_CANCELED;
  7801. goto cleanup;
  7802. }
  7803. if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0 ||
  7804. DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_EXITING) ||
  7805. notify->zone->view->requestmgr == NULL ||
  7806. notify->zone->db == NULL) {
  7807. result = ISC_R_CANCELED;
  7808. goto cleanup;
  7809. }
  7810. /*
  7811. * The raw IPv4 address should also exist. Don't send to the
  7812. * mapped form.
  7813. */
  7814. if (isc_sockaddr_pf(&notify->dst) == PF_INET6 &&
  7815. IN6_IS_ADDR_V4MAPPED(&notify->dst.type.sin6.sin6_addr)) {
  7816. isc_sockaddr_format(&notify->dst, addrbuf, sizeof(addrbuf));
  7817. notify_log(notify->zone, ISC_LOG_DEBUG(3),
  7818. "notify: ignoring IPv6 mapped IPV4 address: %s",
  7819. addrbuf);
  7820. result = ISC_R_CANCELED;
  7821. goto cleanup;
  7822. }
  7823. result = notify_createmessage(notify->zone, notify->flags, &message);
  7824. if (result != ISC_R_SUCCESS)
  7825. goto cleanup;
  7826. isc_netaddr_fromsockaddr(&dstip, &notify->dst);
  7827. isc_sockaddr_format(&notify->dst, addrbuf, sizeof(addrbuf));
  7828. result = dns_view_getpeertsig(notify->zone->view, &dstip, &key);
  7829. if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
  7830. notify_log(notify->zone, ISC_LOG_ERROR, "NOTIFY to %s not "
  7831. "sent. Peer TSIG key lookup failure.", addrbuf);
  7832. goto cleanup_message;
  7833. }
  7834. notify_log(notify->zone, ISC_LOG_DEBUG(3), "sending notify to %s",
  7835. addrbuf);
  7836. if (notify->zone->view->peers != NULL) {
  7837. dns_peer_t *peer = NULL;
  7838. result = dns_peerlist_peerbyaddr(notify->zone->view->peers,
  7839. &dstip, &peer);
  7840. if (result == ISC_R_SUCCESS) {
  7841. result = dns_peer_getnotifysource(peer, &src);
  7842. if (result == ISC_R_SUCCESS)
  7843. have_notifysource = ISC_TRUE;
  7844. }
  7845. }
  7846. switch (isc_sockaddr_pf(&notify->dst)) {
  7847. case PF_INET:
  7848. if (!have_notifysource)
  7849. src = notify->zone->notifysrc4;
  7850. break;
  7851. case PF_INET6:
  7852. if (!have_notifysource)
  7853. src = notify->zone->notifysrc6;
  7854. break;
  7855. default:
  7856. result = ISC_R_NOTIMPLEMENTED;
  7857. goto cleanup_key;
  7858. }
  7859. timeout = 15;
  7860. if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_DIALNOTIFY))
  7861. timeout = 30;
  7862. result = dns_request_createvia2(notify->zone->view->requestmgr,
  7863. message, &src, &notify->dst, 0, key,
  7864. timeout * 3, timeout,
  7865. notify->zone->task, notify_done,
  7866. notify, &notify->request);
  7867. if (result == ISC_R_SUCCESS) {
  7868. if (isc_sockaddr_pf(&notify->dst) == AF_INET) {
  7869. inc_stats(notify->zone,
  7870. dns_zonestatscounter_notifyoutv4);
  7871. } else {
  7872. inc_stats(notify->zone,
  7873. dns_zonestatscounter_notifyoutv6);
  7874. }
  7875. }
  7876. cleanup_key:
  7877. if (key != NULL)
  7878. dns_tsigkey_detach(&key);
  7879. cleanup_message:
  7880. dns_message_destroy(&message);
  7881. cleanup:
  7882. UNLOCK_ZONE(notify->zone);
  7883. if (result != ISC_R_SUCCESS)
  7884. notify_destroy(notify, ISC_FALSE);
  7885. isc_event_free(&event);
  7886. }
  7887. static void
  7888. notify_send(dns_notify_t *notify) {
  7889. dns_adbaddrinfo_t *ai;
  7890. isc_sockaddr_t dst;
  7891. isc_result_t result;
  7892. dns_notify_t *new = NULL;
  7893. /*
  7894. * Zone lock held by caller.
  7895. */
  7896. REQUIRE(DNS_NOTIFY_VALID(notify));
  7897. REQUIRE(LOCKED_ZONE(notify->zone));
  7898. for (ai = ISC_LIST_HEAD(notify->find->list);
  7899. ai != NULL;
  7900. ai = ISC_LIST_NEXT(ai, publink)) {
  7901. dst = ai->sockaddr;
  7902. if (notify_isqueued(notify->zone, NULL, &dst))
  7903. continue;
  7904. if (notify_isself(notify->zone, &dst))
  7905. continue;
  7906. new = NULL;
  7907. result = notify_create(notify->mctx,
  7908. (notify->flags & DNS_NOTIFY_NOSOA),
  7909. &new);
  7910. if (result != ISC_R_SUCCESS)
  7911. goto cleanup;
  7912. zone_iattach(notify->zone, &new->zone);
  7913. ISC_LIST_APPEND(new->zone->notifies, new, link);
  7914. new->dst = dst;
  7915. result = notify_send_queue(new);
  7916. if (result != ISC_R_SUCCESS)
  7917. goto cleanup;
  7918. new = NULL;
  7919. }
  7920. cleanup:
  7921. if (new != NULL)
  7922. notify_destroy(new, ISC_TRUE);
  7923. }
  7924. void
  7925. dns_zone_notify(dns_zone_t *zone) {
  7926. isc_time_t now;
  7927. REQUIRE(DNS_ZONE_VALID(zone));
  7928. LOCK_ZONE(zone);
  7929. DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
  7930. TIME_NOW(&now);
  7931. zone_settimer(zone, &now);
  7932. UNLOCK_ZONE(zone);
  7933. }
  7934. static void
  7935. zone_notify(dns_zone_t *zone, isc_time_t *now) {
  7936. dns_dbnode_t *node = NULL;
  7937. dns_db_t *zonedb = NULL;
  7938. dns_dbversion_t *version = NULL;
  7939. dns_name_t *origin = NULL;
  7940. dns_name_t master;
  7941. dns_rdata_ns_t ns;
  7942. dns_rdata_soa_t soa;
  7943. isc_uint32_t serial;
  7944. dns_rdata_t rdata = DNS_RDATA_INIT;
  7945. dns_rdataset_t nsrdset;
  7946. dns_rdataset_t soardset;
  7947. isc_result_t result;
  7948. dns_notify_t *notify = NULL;
  7949. unsigned int i;
  7950. isc_sockaddr_t dst;
  7951. isc_boolean_t isqueued;
  7952. dns_notifytype_t notifytype;
  7953. unsigned int flags = 0;
  7954. isc_boolean_t loggednotify = ISC_FALSE;
  7955. REQUIRE(DNS_ZONE_VALID(zone));
  7956. LOCK_ZONE(zone);
  7957. DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
  7958. notifytype = zone->notifytype;
  7959. DNS_ZONE_TIME_ADD(now, zone->notifydelay, &zone->notifytime);
  7960. UNLOCK_ZONE(zone);
  7961. if (! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
  7962. return;
  7963. if (notifytype == dns_notifytype_no)
  7964. return;
  7965. if (notifytype == dns_notifytype_masteronly &&
  7966. zone->type != dns_zone_master)
  7967. return;
  7968. origin = &zone->origin;
  7969. /*
  7970. * If the zone is dialup we are done as we don't want to send
  7971. * the current soa so as to force a refresh query.
  7972. */
  7973. if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY))
  7974. flags |= DNS_NOTIFY_NOSOA;
  7975. /*
  7976. * Get SOA RRset.
  7977. */
  7978. ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
  7979. if (zone->db != NULL)
  7980. dns_db_attach(zone->db, &zonedb);
  7981. ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
  7982. if (zonedb == NULL)
  7983. return;
  7984. dns_db_currentversion(zonedb, &version);
  7985. result = dns_db_findnode(zonedb, origin, ISC_FALSE, &node);
  7986. if (result != ISC_R_SUCCESS)
  7987. goto cleanup1;
  7988. dns_rdataset_init(&soardset);
  7989. result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_soa,
  7990. dns_rdatatype_none, 0, &soardset, NULL);
  7991. if (result != ISC_R_SUCCESS)
  7992. goto cleanup2;
  7993. /*
  7994. * Find serial and master server's name.
  7995. */
  7996. dns_name_init(&master, NULL);
  7997. result = dns_rdataset_first(&soardset);
  7998. if (result != ISC_R_SUCCESS)
  7999. goto cleanup3;
  8000. dns_rdataset_current(&soardset, &rdata);
  8001. result = dns_rdata_tostruct(&rdata, &soa, NULL);
  8002. RUNTIME_CHECK(result == ISC_R_SUCCESS);
  8003. dns_rdata_reset(&rdata);
  8004. result = dns_name_dup(&soa.origin, zone->mctx, &master);
  8005. serial = soa.serial;
  8006. dns_rdataset_disassociate(&soardset);
  8007. if (result != ISC_R_SUCCESS)
  8008. goto cleanup3;
  8009. /*
  8010. * Enqueue notify requests for 'also-notify' servers.
  8011. */
  8012. LOCK_ZONE(zone);
  8013. for (i = 0; i < zone->notifycnt; i++) {
  8014. dst = zone->notify[i];
  8015. if (notify_isqueued(zone, NULL, &dst))
  8016. continue;
  8017. result = notify_create(zone->mctx, flags, &notify);
  8018. if (result != ISC_R_SUCCESS)
  8019. continue;
  8020. zone_iattach(zone, &notify->zone);
  8021. notify->dst = dst;
  8022. ISC_LIST_APPEND(zone->notifies, notify, link);
  8023. result = notify_send_queue(notify);
  8024. if (result != ISC_R_SUCCESS)
  8025. notify_destroy(notify, ISC_TRUE);
  8026. if (!loggednotify) {
  8027. notify_log(zone, ISC_LOG_INFO,
  8028. "sending notifies (serial %u)",
  8029. serial);
  8030. loggednotify = ISC_TRUE;
  8031. }
  8032. notify = NULL;
  8033. }
  8034. UNLOCK_ZONE(zone);
  8035. if (notifytype == dns_notifytype_explicit)
  8036. goto cleanup3;
  8037. /*
  8038. * Process NS RRset to generate notifies.
  8039. */
  8040. dns_rdataset_init(&nsrdset);
  8041. result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_ns,
  8042. dns_rdatatype_none, 0, &nsrdset, NULL);
  8043. if (result != ISC_R_SUCCESS)
  8044. goto cleanup3;
  8045. result = dns_rdataset_first(&nsrdset);
  8046. while (result == ISC_R_SUCCESS) {
  8047. dns_rdataset_current(&nsrdset, &rdata);
  8048. result = dns_rdata_tostruct(&rdata, &ns, NULL);
  8049. RUNTIME_CHECK(result == ISC_R_SUCCESS);
  8050. dns_rdata_reset(&rdata);
  8051. /*
  8052. * Don't notify the master server unless explicitly
  8053. * configured to do so.
  8054. */
  8055. if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOTIFYTOSOA) &&
  8056. dns_name_compare(&master, &ns.name) == 0) {
  8057. result = dns_rdataset_next(&nsrdset);
  8058. continue;
  8059. }
  8060. if (!loggednotify) {
  8061. notify_log(zone, ISC_LOG_INFO,
  8062. "sending notifies (serial %u)",
  8063. serial);
  8064. loggednotify = ISC_TRUE;
  8065. }
  8066. LOCK_ZONE(zone);
  8067. isqueued = notify_isqueued(zone, &ns.name, NULL);
  8068. UNLOCK_ZONE(zone);
  8069. if (isqueued) {
  8070. result = dns_rdataset_next(&nsrdset);
  8071. continue;
  8072. }
  8073. result = notify_create(zone->mctx, flags, &notify);
  8074. if (result != ISC_R_SUCCESS)
  8075. continue;
  8076. dns_zone_iattach(zone, &notify->zone);
  8077. result = dns_name_dup(&ns.name, zone->mctx, &notify->ns);
  8078. if (result != ISC_R_SUCCESS) {
  8079. LOCK_ZONE(zone);
  8080. notify_destroy(notify, ISC_TRUE);
  8081. UNLOCK_ZONE(zone);
  8082. continue;
  8083. }
  8084. LOCK_ZONE(zone);
  8085. ISC_LIST_APPEND(zone->notifies, notify, link);
  8086. UNLOCK_ZONE(zone);
  8087. notify_find_address(notify);
  8088. notify = NULL;
  8089. result = dns_rdataset_next(&nsrdset);
  8090. }
  8091. dns_rdataset_disassociate(&nsrdset);
  8092. cleanup3:
  8093. if (dns_name_dynamic(&master))
  8094. dns_name_free(&master, zone->mctx);
  8095. cleanup2:
  8096. dns_db_detachnode(zonedb, &node);
  8097. cleanup1:
  8098. dns_db_closeversion(zonedb, &version, ISC_FALSE);
  8099. dns_db_detach(&zonedb);
  8100. }
  8101. /***
  8102. *** Private
  8103. ***/
  8104. static inline isc_result_t
  8105. save_nsrrset(dns_message_t *message, dns_name_t *name,
  8106. dns_db_t *db, dns_dbversion_t *version)
  8107. {
  8108. dns_rdataset_t *nsrdataset = NULL;
  8109. dns_rdataset_t *rdataset = NULL;
  8110. dns_dbnode_t *node = NULL;
  8111. dns_rdata_ns_t ns;
  8112. isc_result_t result;
  8113. dns_rdata_t rdata = DNS_RDATA_INIT;
  8114. /*
  8115. * Extract NS RRset from message.
  8116. */
  8117. result = dns_message_findname(message, DNS_SECTION_ANSWER, name,
  8118. dns_rdatatype_ns, dns_rdatatype_none,
  8119. NULL, &nsrdataset);
  8120. if (result != ISC_R_SUCCESS)
  8121. goto fail;
  8122. /*
  8123. * Add NS rdataset.
  8124. */
  8125. result = dns_db_findnode(db, name, ISC_TRUE, &node);
  8126. if (result != ISC_R_SUCCESS)
  8127. goto fail;
  8128. result = dns_db_addrdataset(db, node, version, 0,
  8129. nsrdataset, 0, NULL);
  8130. dns_db_detachnode(db, &node);
  8131. if (result != ISC_R_SUCCESS)
  8132. goto fail;
  8133. /*
  8134. * Add glue rdatasets.
  8135. */
  8136. for (result = dns_rdataset_first(nsrdataset);
  8137. result == ISC_R_SUCCESS;
  8138. result = dns_rdataset_next(nsrdataset)) {
  8139. dns_rdataset_current(nsrdataset, &rdata);
  8140. result = dns_rdata_tostruct(&rdata, &ns, NULL);
  8141. RUNTIME_CHECK(result == ISC_R_SUCCESS);
  8142. dns_rdata_reset(&rdata);
  8143. if (!dns_name_issubdomain(&ns.name, name))
  8144. continue;
  8145. rdataset = NULL;
  8146. result = dns_message_findname(message, DNS_SECTION_ADDITIONAL,
  8147. &ns.name, dns_rdatatype_aaaa,
  8148. dns_rdatatype_none, NULL,
  8149. &rdataset);
  8150. if (result == ISC_R_SUCCESS) {
  8151. result = dns_db_findnode(db, &ns.name,
  8152. ISC_TRUE, &node);
  8153. if (result != ISC_R_SUCCESS)
  8154. goto fail;
  8155. result = dns_db_addrdataset(db, node, version, 0,
  8156. rdataset, 0, NULL);
  8157. dns_db_detachnode(db, &node);
  8158. if (result != ISC_R_SUCCESS)
  8159. goto fail;
  8160. }
  8161. rdataset = NULL;
  8162. result = dns_message_findname(message, DNS_SECTION_ADDITIONAL,
  8163. &ns.name, dns_rdatatype_a,
  8164. dns_rdatatype_none, NULL,
  8165. &rdataset);
  8166. if (result == ISC_R_SUCCESS) {
  8167. result = dns_db_findnode(db, &ns.name,
  8168. ISC_TRUE, &node);
  8169. if (result != ISC_R_SUCCESS)
  8170. goto fail;
  8171. result = dns_db_addrdataset(db, node, version, 0,
  8172. rdataset, 0, NULL);
  8173. dns_db_detachnode(db, &node);
  8174. if (result != ISC_R_SUCCESS)
  8175. goto fail;
  8176. }
  8177. }
  8178. if (result != ISC_R_NOMORE)
  8179. goto fail;
  8180. return (ISC_R_SUCCESS);
  8181. fail:
  8182. return (result);
  8183. }
  8184. static void
  8185. stub_callback(isc_task_t *task, isc_event_t *event) {
  8186. const char me[] = "stub_callback";
  8187. dns_requestevent_t *revent = (dns_requestevent_t *)event;
  8188. dns_stub_t *stub = NULL;
  8189. dns_message_t *msg = NULL;
  8190. dns_zone_t *zone = NULL;
  8191. char master[ISC_SOCKADDR_FORMATSIZE];
  8192. char source[ISC_SOCKADDR_FORMATSIZE];
  8193. isc_uint32_t nscnt, cnamecnt, refresh, retry, expire;
  8194. isc_result_t result;
  8195. isc_time_t now;
  8196. isc_boolean_t exiting = ISC_FALSE;
  8197. isc_interval_t i;
  8198. unsigned int j;
  8199. stub = revent->ev_arg;
  8200. INSIST(DNS_STUB_VALID(stub));
  8201. UNUSED(task);
  8202. zone = stub->zone;
  8203. ENTER;
  8204. TIME_NOW(&now);
  8205. LOCK_ZONE(zone);
  8206. if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
  8207. zone_debuglog(zone, me, 1, "exiting");
  8208. exiting = ISC_TRUE;
  8209. goto next_master;
  8210. }
  8211. isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
  8212. isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
  8213. if (revent->result != ISC_R_SUCCESS) {
  8214. if (revent->result == ISC_R_TIMEDOUT &&
  8215. !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
  8216. DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
  8217. dns_zone_log(zone, ISC_LOG_DEBUG(1),
  8218. "refreshing stub: timeout retrying "
  8219. " without EDNS master %s (source %s)",
  8220. master, source);
  8221. goto same_master;
  8222. }
  8223. dns_zonemgr_unreachableadd(zone->zmgr, &zone->masteraddr,
  8224. &zone->sourceaddr, &now);
  8225. dns_zone_log(zone, ISC_LOG_INFO,
  8226. "could not refresh stub from master %s"
  8227. " (source %s): %s", master, source,
  8228. dns_result_totext(revent->result));
  8229. goto next_master;
  8230. }
  8231. result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
  8232. if (result != ISC_R_SUCCESS)
  8233. goto next_master;
  8234. result = dns_request_getresponse(revent->request, msg, 0);
  8235. if (result != ISC_R_SUCCESS)
  8236. goto next_master;
  8237. /*
  8238. * Unexpected rcode.
  8239. */
  8240. if (msg->rcode != dns_rcode_noerror) {
  8241. char rcode[128];
  8242. isc_buffer_t rb;
  8243. isc_buffer_init(&rb, rcode, sizeof(rcode));
  8244. (void)dns_rcode_totext(msg->rcode, &rb);
  8245. if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) &&
  8246. (msg->rcode == dns_rcode_servfail ||
  8247. msg->rcode == dns_rcode_notimp ||
  8248. msg->rcode == dns_rcode_formerr)) {
  8249. dns_zone_log(zone, ISC_LOG_DEBUG(1),
  8250. "refreshing stub: rcode (%.*s) retrying "
  8251. "without EDNS master %s (source %s)",
  8252. (int)rb.used, rcode, master, source);
  8253. DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
  8254. goto same_master;
  8255. }
  8256. dns_zone_log(zone, ISC_LOG_INFO,
  8257. "refreshing stub: "
  8258. "unexpected rcode (%.*s) from %s (source %s)",
  8259. (int)rb.used, rcode, master, source);
  8260. goto next_master;
  8261. }
  8262. /*
  8263. * We need complete messages.
  8264. */
  8265. if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) {
  8266. if (dns_request_usedtcp(revent->request)) {
  8267. dns_zone_log(zone, ISC_LOG_INFO,
  8268. "refreshing stub: truncated TCP "
  8269. "response from master %s (source %s)",
  8270. master, source);
  8271. goto next_master;
  8272. }
  8273. DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC);
  8274. goto same_master;
  8275. }
  8276. /*
  8277. * If non-auth log and next master.
  8278. */
  8279. if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
  8280. dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: "
  8281. "non-authoritative answer from "
  8282. "master %s (source %s)", master, source);
  8283. goto next_master;
  8284. }
  8285. /*
  8286. * Sanity checks.
  8287. */
  8288. cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname);
  8289. nscnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_ns);
  8290. if (cnamecnt != 0) {
  8291. dns_zone_log(zone, ISC_LOG_INFO,
  8292. "refreshing stub: unexpected CNAME response "
  8293. "from master %s (source %s)", master, source);
  8294. goto next_master;
  8295. }
  8296. if (nscnt == 0) {
  8297. dns_zone_log(zone, ISC_LOG_INFO,
  8298. "refreshing stub: no NS records in response "
  8299. "from master %s (source %s)", master, source);
  8300. goto next_master;
  8301. }
  8302. /*
  8303. * Save answer.
  8304. */
  8305. result = save_nsrrset(msg, &zone->origin, stub->db, stub->version);
  8306. if (result != ISC_R_SUCCESS) {
  8307. dns_zone_log(zone, ISC_LOG_INFO,
  8308. "refreshing stub: unable to save NS records "
  8309. "from master %s (source %s)", master, source);
  8310. goto next_master;
  8311. }
  8312. /*
  8313. * Tidy up.
  8314. */
  8315. dns_db_closeversion(stub->db, &stub->version, ISC_TRUE);
  8316. ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
  8317. if (zone->db == NULL)
  8318. zone_attachdb(zone, stub->db);
  8319. result = zone_get_from_db(zone, zone->db, NULL, NULL, NULL, &refresh,
  8320. &retry, &expire, NULL, NULL);
  8321. if (result == ISC_R_SUCCESS) {
  8322. zone->refresh = RANGE(refresh, zone->minrefresh,
  8323. zone->maxrefresh);
  8324. zone->retry = RANGE(retry, zone->minretry, zone->maxretry);
  8325. zone->expire = RANGE(expire, zone->refresh + zone->retry,
  8326. DNS_MAX_EXPIRE);
  8327. DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
  8328. }
  8329. ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
  8330. dns_db_detach(&stub->db);
  8331. dns_message_destroy(&msg);
  8332. isc_event_free(&event);
  8333. dns_request_destroy(&zone->request);
  8334. DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
  8335. DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
  8336. DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime);
  8337. isc_interval_set(&i, zone->expire, 0);
  8338. DNS_ZONE_TIME_ADD(&now, zone->expire, &zone->expiretime);
  8339. if (zone->masterfile != NULL)
  8340. zone_needdump(zone, 0);
  8341. zone_settimer(zone, &now);
  8342. goto free_stub;
  8343. next_master:
  8344. if (stub->version != NULL)
  8345. dns_db_closeversion(stub->db, &stub->version, ISC_FALSE);
  8346. if (stub->db != NULL)
  8347. dns_db_detach(&stub->db);
  8348. if (msg != NULL)
  8349. dns_message_destroy(&msg);
  8350. isc_event_free(&event);
  8351. dns_request_destroy(&zone->request);
  8352. /*
  8353. * Skip to next failed / untried master.
  8354. */
  8355. do {
  8356. zone->curmaster++;
  8357. } while (zone->curmaster < zone->masterscnt &&
  8358. zone->mastersok[zone->curmaster]);
  8359. DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
  8360. if (exiting || zone->curmaster >= zone->masterscnt) {
  8361. isc_boolean_t done = ISC_TRUE;
  8362. if (!exiting &&
  8363. DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
  8364. !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
  8365. /*
  8366. * Did we get a good answer from all the masters?
  8367. */
  8368. for (j = 0; j < zone->masterscnt; j++)
  8369. if (zone->mastersok[j] == ISC_FALSE) {
  8370. done = ISC_FALSE;
  8371. break;
  8372. }
  8373. } else
  8374. done = ISC_TRUE;
  8375. if (!done) {
  8376. zone->curmaster = 0;
  8377. /*
  8378. * Find the next failed master.
  8379. */
  8380. while (zone->curmaster < zone->masterscnt &&
  8381. zone->mastersok[zone->curmaster])
  8382. zone->curmaster++;
  8383. DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
  8384. } else {
  8385. DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
  8386. zone_settimer(zone, &now);
  8387. goto free_stub;
  8388. }
  8389. }
  8390. queue_soa_query(zone);
  8391. goto free_stub;
  8392. same_master:
  8393. if (msg != NULL)
  8394. dns_message_destroy(&msg);
  8395. isc_event_free(&event);
  8396. dns_request_destroy(&zone->request);
  8397. ns_query(zone, NULL, stub);
  8398. UNLOCK_ZONE(zone);
  8399. goto done;
  8400. free_stub:
  8401. UNLOCK_ZONE(zone);
  8402. stub->magic = 0;
  8403. dns_zone_idetach(&stub->zone);
  8404. INSIST(stub->db == NULL);
  8405. INSIST(stub->version == NULL);
  8406. isc_mem_put(stub->mctx, stub, sizeof(*stub));
  8407. done:
  8408. INSIST(event == NULL);
  8409. return;
  8410. }
  8411. /*
  8412. * An SOA query has finished (successfully or not).
  8413. */
  8414. static void
  8415. refresh_callback(isc_task_t *task, isc_event_t *event) {
  8416. const char me[] = "refresh_callback";
  8417. dns_requestevent_t *revent = (dns_requestevent_t *)event;
  8418. dns_zone_t *zone;
  8419. dns_message_t *msg = NULL;
  8420. isc_uint32_t soacnt, cnamecnt, soacount, nscount;
  8421. isc_time_t now;
  8422. char master[ISC_SOCKADDR_FORMATSIZE];
  8423. char source[ISC_SOCKADDR_FORMATSIZE];
  8424. dns_rdataset_t *rdataset = NULL;
  8425. dns_rdata_t rdata = DNS_RDATA_INIT;
  8426. dns_rdata_soa_t soa;
  8427. isc_result_t result;
  8428. isc_uint32_t serial, oldserial = 0;
  8429. unsigned int j;
  8430. isc_boolean_t do_queue_xfrin = ISC_FALSE;
  8431. zone = revent->ev_arg;
  8432. INSIST(DNS_ZONE_VALID(zone));
  8433. UNUSED(task);
  8434. ENTER;
  8435. TIME_NOW(&now);
  8436. LOCK_ZONE(zone);
  8437. /*
  8438. * if timeout log and next master;
  8439. */
  8440. isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
  8441. isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
  8442. if (revent->result != ISC_R_SUCCESS) {
  8443. if (revent->result == ISC_R_TIMEDOUT &&
  8444. !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
  8445. DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
  8446. dns_zone_log(zone, ISC_LOG_DEBUG(1),
  8447. "refresh: timeout retrying without EDNS "
  8448. "master %s (source %s)", master, source);
  8449. goto same_master;
  8450. }
  8451. if (revent->result == ISC_R_TIMEDOUT &&
  8452. !dns_request_usedtcp(revent->request)) {
  8453. dns_zone_log(zone, ISC_LOG_INFO,
  8454. "refresh: retry limit for "
  8455. "master %s exceeded (source %s)",
  8456. master, source);
  8457. /* Try with slave with TCP. */
  8458. if (zone->type == dns_zone_slave &&
  8459. DNS_ZONE_OPTION(zone, DNS_ZONEOPT_TRYTCPREFRESH)) {
  8460. if (!dns_zonemgr_unreachable(zone->zmgr,
  8461. &zone->masteraddr,
  8462. &zone->sourceaddr,
  8463. &now))
  8464. {
  8465. DNS_ZONE_SETFLAG(zone,
  8466. DNS_ZONEFLG_SOABEFOREAXFR);
  8467. goto tcp_transfer;
  8468. }
  8469. dns_zone_log(zone, ISC_LOG_DEBUG(1),
  8470. "refresh: skipped tcp fallback "
  8471. "as master %s (source %s) is "
  8472. "unreachable (cached)",
  8473. master, source);
  8474. }
  8475. } else
  8476. dns_zone_log(zone, ISC_LOG_INFO,
  8477. "refresh: failure trying master "
  8478. "%s (source %s): %s", master, source,
  8479. dns_result_totext(revent->result));
  8480. goto next_master;
  8481. }
  8482. result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
  8483. if (result != ISC_R_SUCCESS)
  8484. goto next_master;
  8485. result = dns_request_getresponse(revent->request, msg, 0);
  8486. if (result != ISC_R_SUCCESS) {
  8487. dns_zone_log(zone, ISC_LOG_INFO,
  8488. "refresh: failure trying master "
  8489. "%s (source %s): %s", master, source,
  8490. dns_result_totext(result));
  8491. goto next_master;
  8492. }
  8493. /*
  8494. * Unexpected rcode.
  8495. */
  8496. if (msg->rcode != dns_rcode_noerror) {
  8497. char rcode[128];
  8498. isc_buffer_t rb;
  8499. isc_buffer_init(&rb, rcode, sizeof(rcode));
  8500. (void)dns_rcode_totext(msg->rcode, &rb);
  8501. if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) &&
  8502. (msg->rcode == dns_rcode_servfail ||
  8503. msg->rcode == dns_rcode_notimp ||
  8504. msg->rcode == dns_rcode_formerr)) {
  8505. dns_zone_log(zone, ISC_LOG_DEBUG(1),
  8506. "refresh: rcode (%.*s) retrying without "
  8507. "EDNS master %s (source %s)",
  8508. (int)rb.used, rcode, master, source);
  8509. DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
  8510. goto same_master;
  8511. }
  8512. dns_zone_log(zone, ISC_LOG_INFO,
  8513. "refresh: unexpected rcode (%.*s) from "
  8514. "master %s (source %s)", (int)rb.used, rcode,
  8515. master, source);
  8516. /*
  8517. * Perhaps AXFR/IXFR is allowed even if SOA queries aren't.
  8518. */
  8519. if (msg->rcode == dns_rcode_refused &&
  8520. zone->type == dns_zone_slave)
  8521. goto tcp_transfer;
  8522. goto next_master;
  8523. }
  8524. /*
  8525. * If truncated punt to zone transfer which will query again.
  8526. */
  8527. if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) {
  8528. if (zone->type == dns_zone_slave) {
  8529. dns_zone_log(zone, ISC_LOG_INFO,
  8530. "refresh: truncated UDP answer, "
  8531. "initiating TCP zone xfer "
  8532. "for master %s (source %s)",
  8533. master, source);
  8534. DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR);
  8535. goto tcp_transfer;
  8536. } else {
  8537. INSIST(zone->type == dns_zone_stub);
  8538. if (dns_request_usedtcp(revent->request)) {
  8539. dns_zone_log(zone, ISC_LOG_INFO,
  8540. "refresh: truncated TCP response "
  8541. "from master %s (source %s)",
  8542. master, source);
  8543. goto next_master;
  8544. }
  8545. DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC);
  8546. goto same_master;
  8547. }
  8548. }
  8549. /*
  8550. * if non-auth log and next master;
  8551. */
  8552. if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
  8553. dns_zone_log(zone, ISC_LOG_INFO,
  8554. "refresh: non-authoritative answer from "
  8555. "master %s (source %s)", master, source);
  8556. goto next_master;
  8557. }
  8558. cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname);
  8559. soacnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_soa);
  8560. nscount = message_count(msg, DNS_SECTION_AUTHORITY, dns_rdatatype_ns);
  8561. soacount = message_count(msg, DNS_SECTION_AUTHORITY,
  8562. dns_rdatatype_soa);
  8563. /*
  8564. * There should not be a CNAME record at top of zone.
  8565. */
  8566. if (cnamecnt != 0) {
  8567. dns_zone_log(zone, ISC_LOG_INFO,
  8568. "refresh: CNAME at top of zone "
  8569. "in master %s (source %s)", master, source);
  8570. goto next_master;
  8571. }
  8572. /*
  8573. * if referral log and next master;
  8574. */
  8575. if (soacnt == 0 && soacount == 0 && nscount != 0) {
  8576. dns_zone_log(zone, ISC_LOG_INFO,
  8577. "refresh: referral response "
  8578. "from master %s (source %s)", master, source);
  8579. goto next_master;
  8580. }
  8581. /*
  8582. * if nodata log and next master;
  8583. */
  8584. if (soacnt == 0 && (nscount == 0 || soacount != 0)) {
  8585. dns_zone_log(zone, ISC_LOG_INFO,
  8586. "refresh: NODATA response "
  8587. "from master %s (source %s)", master, source);
  8588. goto next_master;
  8589. }
  8590. /*
  8591. * Only one soa at top of zone.
  8592. */
  8593. if (soacnt != 1) {
  8594. dns_zone_log(zone, ISC_LOG_INFO,
  8595. "refresh: answer SOA count (%d) != 1 "
  8596. "from master %s (source %s)",
  8597. soacnt, master, source);
  8598. goto next_master;
  8599. }
  8600. /*
  8601. * Extract serial
  8602. */
  8603. rdataset = NULL;
  8604. result = dns_message_findname(msg, DNS_SECTION_ANSWER, &zone->origin,
  8605. dns_rdatatype_soa, dns_rdatatype_none,
  8606. NULL, &rdataset);
  8607. if (result != ISC_R_SUCCESS) {
  8608. dns_zone_log(zone, ISC_LOG_INFO,
  8609. "refresh: unable to get SOA record "
  8610. "from master %s (source %s)", master, source);
  8611. goto next_master;
  8612. }
  8613. result = dns_rdataset_first(rdataset);
  8614. if (result != ISC_R_SUCCESS) {
  8615. dns_zone_log(zone, ISC_LOG_INFO,
  8616. "refresh: dns_rdataset_first() failed");
  8617. goto next_master;
  8618. }
  8619. dns_rdataset_current(rdataset, &rdata);
  8620. result = dns_rdata_tostruct(&rdata, &soa, NULL);
  8621. RUNTIME_CHECK(result == ISC_R_SUCCESS);
  8622. serial = soa.serial;
  8623. if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
  8624. result = zone_get_from_db(zone, zone->db, NULL, NULL,
  8625. &oldserial, NULL, NULL, NULL, NULL,
  8626. NULL);
  8627. RUNTIME_CHECK(result == ISC_R_SUCCESS);
  8628. zone_debuglog(zone, me, 1, "serial: new %u, old %u",
  8629. serial, oldserial);
  8630. } else
  8631. zone_debuglog(zone, me, 1, "serial: new %u, old not loaded",
  8632. serial);
  8633. if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) ||
  8634. DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) ||
  8635. isc_serial_gt(serial, oldserial)) {
  8636. if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr,
  8637. &zone->sourceaddr, &now))
  8638. {
  8639. dns_zone_log(zone, ISC_LOG_INFO,
  8640. "refresh: skipping %s as master %s "
  8641. "(source %s) is unreachable (cached)",
  8642. zone->type == dns_zone_slave ?
  8643. "zone transfer" : "NS query",
  8644. master, source);
  8645. goto next_master;
  8646. }
  8647. tcp_transfer:
  8648. isc_event_free(&event);
  8649. dns_request_destroy(&zone->request);
  8650. if (zone->type == dns_zone_slave) {
  8651. do_queue_xfrin = ISC_TRUE;
  8652. } else {
  8653. INSIST(zone->type == dns_zone_stub);
  8654. ns_query(zone, rdataset, NULL);
  8655. }
  8656. if (msg != NULL)
  8657. dns_message_destroy(&msg);
  8658. } else if (isc_serial_eq(soa.serial, oldserial)) {
  8659. if (zone->masterfile != NULL) {
  8660. result = ISC_R_FAILURE;
  8661. if (zone->journal != NULL)
  8662. result = isc_file_settime(zone->journal, &now);
  8663. if (result == ISC_R_SUCCESS &&
  8664. !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
  8665. !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
  8666. result = isc_file_settime(zone->masterfile,
  8667. &now);
  8668. } else if (result != ISC_R_SUCCESS)
  8669. result = isc_file_settime(zone->masterfile,
  8670. &now);
  8671. /* Someone removed the file from underneath us! */
  8672. if (result == ISC_R_FILENOTFOUND) {
  8673. zone_needdump(zone, DNS_DUMP_DELAY);
  8674. } else if (result != ISC_R_SUCCESS)
  8675. dns_zone_log(zone, ISC_LOG_ERROR,
  8676. "refresh: could not set file "
  8677. "modification time of '%s': %s",
  8678. zone->masterfile,
  8679. dns_result_totext(result));
  8680. }
  8681. DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime);
  8682. DNS_ZONE_TIME_ADD(&now, zone->expire, &zone->expiretime);
  8683. zone->mastersok[zone->curmaster] = ISC_TRUE;
  8684. goto next_master;
  8685. } else {
  8686. if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MULTIMASTER))
  8687. dns_zone_log(zone, ISC_LOG_INFO, "serial number (%u) "
  8688. "received from master %s < ours (%u)",
  8689. soa.serial, master, oldserial);
  8690. else
  8691. zone_debuglog(zone, me, 1, "ahead");
  8692. zone->mastersok[zone->curmaster] = ISC_TRUE;
  8693. goto next_master;
  8694. }
  8695. if (msg != NULL)
  8696. dns_message_destroy(&msg);
  8697. goto detach;
  8698. next_master:
  8699. if (msg != NULL)
  8700. dns_message_destroy(&msg);
  8701. isc_event_free(&event);
  8702. dns_request_destroy(&zone->request);
  8703. /*
  8704. * Skip to next failed / untried master.
  8705. */
  8706. do {
  8707. zone->curmaster++;
  8708. } while (zone->curmaster < zone->masterscnt &&
  8709. zone->mastersok[zone->curmaster]);
  8710. DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
  8711. if (zone->curmaster >= zone->masterscnt) {
  8712. isc_boolean_t done = ISC_TRUE;
  8713. if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
  8714. !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
  8715. /*
  8716. * Did we get a good answer from all the masters?
  8717. */
  8718. for (j = 0; j < zone->masterscnt; j++)
  8719. if (zone->mastersok[j] == ISC_FALSE) {
  8720. done = ISC_FALSE;
  8721. break;
  8722. }
  8723. } else
  8724. done = ISC_TRUE;
  8725. if (!done) {
  8726. DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
  8727. zone->curmaster = 0;
  8728. /*
  8729. * Find the next failed master.
  8730. */
  8731. while (zone->curmaster < zone->masterscnt &&
  8732. zone->mastersok[zone->curmaster])
  8733. zone->curmaster++;
  8734. goto requeue;
  8735. }
  8736. DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
  8737. if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) {
  8738. DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
  8739. zone->refreshtime = now;
  8740. }
  8741. DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
  8742. zone_settimer(zone, &now);
  8743. goto detach;
  8744. }
  8745. requeue:
  8746. queue_soa_query(zone);
  8747. goto detach;
  8748. same_master:
  8749. if (msg != NULL)
  8750. dns_message_destroy(&msg);
  8751. isc_event_free(&event);
  8752. dns_request_destroy(&zone->request);
  8753. queue_soa_query(zone);
  8754. detach:
  8755. UNLOCK_ZONE(zone);
  8756. if (do_queue_xfrin)
  8757. queue_xfrin(zone);
  8758. dns_zone_idetach(&zone);
  8759. return;
  8760. }
  8761. static void
  8762. queue_soa_query(dns_zone_t *zone) {
  8763. const char me[] = "queue_soa_query";
  8764. isc_event_t *e;
  8765. dns_zone_t *dummy = NULL;
  8766. isc_result_t result;
  8767. ENTER;
  8768. /*
  8769. * Locked by caller
  8770. */
  8771. REQUIRE(LOCKED_ZONE(zone));
  8772. if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
  8773. cancel_refresh(zone);
  8774. return;
  8775. }
  8776. e = isc_event_allocate(zone->mctx, NULL, DNS_EVENT_ZONE,
  8777. soa_query, zone, sizeof(isc_event_t));
  8778. if (e == NULL) {
  8779. cancel_refresh(zone);
  8780. return;
  8781. }
  8782. /*
  8783. * Attach so that we won't clean up
  8784. * until the event is delivered.
  8785. */
  8786. zone_iattach(zone, &dummy);
  8787. e->ev_arg = zone;
  8788. e->ev_sender = NULL;
  8789. result = isc_ratelimiter_enqueue(zone->zmgr->rl, zone->task, &e);
  8790. if (result != ISC_R_SUCCESS) {
  8791. zone_idetach(&dummy);
  8792. isc_event_free(&e);
  8793. cancel_refresh(zone);
  8794. }
  8795. }
  8796. static inline isc_result_t
  8797. create_query(dns_zone_t *zone, dns_rdatatype_t rdtype,
  8798. dns_message_t **messagep)
  8799. {
  8800. dns_message_t *message = NULL;
  8801. dns_name_t *qname = NULL;
  8802. dns_rdataset_t *qrdataset = NULL;
  8803. isc_result_t result;
  8804. result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER,
  8805. &message);
  8806. if (result != ISC_R_SUCCESS)
  8807. goto cleanup;
  8808. message->opcode = dns_opcode_query;
  8809. message->rdclass = zone->rdclass;
  8810. result = dns_message_gettempname(message, &qname);
  8811. if (result != ISC_R_SUCCESS)
  8812. goto cleanup;
  8813. result = dns_message_gettemprdataset(message, &qrdataset);
  8814. if (result != ISC_R_SUCCESS)
  8815. goto cleanup;
  8816. /*
  8817. * Make question.
  8818. */
  8819. dns_name_init(qname, NULL);
  8820. dns_name_clone(&zone->origin, qname);
  8821. dns_rdataset_init(qrdataset);
  8822. dns_rdataset_makequestion(qrdataset, zone->rdclass, rdtype);
  8823. ISC_LIST_APPEND(qname->list, qrdataset, link);
  8824. dns_message_addname(message, qname, DNS_SECTION_QUESTION);
  8825. *messagep = message;
  8826. return (ISC_R_SUCCESS);
  8827. cleanup:
  8828. if (qname != NULL)
  8829. dns_message_puttempname(message, &qname);
  8830. if (qrdataset != NULL)
  8831. dns_message_puttemprdataset(message, &qrdataset);
  8832. if (message != NULL)
  8833. dns_message_destroy(&message);
  8834. return (result);
  8835. }
  8836. static isc_result_t
  8837. add_opt(dns_message_t *message, isc_uint16_t udpsize, isc_boolean_t reqnsid) {
  8838. dns_rdataset_t *rdataset = NULL;
  8839. dns_rdatalist_t *rdatalist = NULL;
  8840. dns_rdata_t *rdata = NULL;
  8841. isc_result_t result;
  8842. result = dns_message_gettemprdatalist(message, &rdatalist);
  8843. if (result != ISC_R_SUCCESS)
  8844. goto cleanup;
  8845. result = dns_message_gettemprdata(message, &rdata);
  8846. if (result != ISC_R_SUCCESS)
  8847. goto cleanup;
  8848. result = dns_message_gettemprdataset(message, &rdataset);
  8849. if (result != ISC_R_SUCCESS)
  8850. goto cleanup;
  8851. dns_rdataset_init(rdataset);
  8852. rdatalist->type = dns_rdatatype_opt;
  8853. rdatalist->covers = 0;
  8854. /*
  8855. * Set Maximum UDP buffer size.
  8856. */
  8857. rdatalist->rdclass = udpsize;
  8858. /*
  8859. * Set EXTENDED-RCODE, VERSION, DO and Z to 0.
  8860. */
  8861. rdatalist->ttl = 0;
  8862. /* Set EDNS options if applicable */
  8863. if (reqnsid) {
  8864. unsigned char data[4];
  8865. isc_buffer_t buf;
  8866. isc_buffer_init(&buf, data, sizeof(data));
  8867. isc_buffer_putuint16(&buf, DNS_OPT_NSID);
  8868. isc_buffer_putuint16(&buf, 0);
  8869. rdata->data = data;
  8870. rdata->length = sizeof(data);
  8871. } else {
  8872. rdata->data = NULL;
  8873. rdata->length = 0;
  8874. }
  8875. rdata->rdclass = rdatalist->rdclass;
  8876. rdata->type = rdatalist->type;
  8877. rdata->flags = 0;
  8878. ISC_LIST_INIT(rdatalist->rdata);
  8879. ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
  8880. RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist, rdataset)
  8881. == ISC_R_SUCCESS);
  8882. return (dns_message_setopt(message, rdataset));
  8883. cleanup:
  8884. if (rdatalist != NULL)
  8885. dns_message_puttemprdatalist(message, &rdatalist);
  8886. if (rdataset != NULL)
  8887. dns_message_puttemprdataset(message, &rdataset);
  8888. if (rdata != NULL)
  8889. dns_message_puttemprdata(message, &rdata);
  8890. return (result);
  8891. }
  8892. static void
  8893. soa_query(isc_task_t *task, isc_event_t *event) {
  8894. const char me[] = "soa_query";
  8895. isc_result_t result = ISC_R_FAILURE;
  8896. dns_message_t *message = NULL;
  8897. dns_zone_t *zone = event->ev_arg;
  8898. dns_zone_t *dummy = NULL;
  8899. isc_netaddr_t masterip;
  8900. dns_tsigkey_t *key = NULL;
  8901. isc_uint32_t options;
  8902. isc_boolean_t cancel = ISC_TRUE;
  8903. int timeout;
  8904. isc_boolean_t have_xfrsource, reqnsid;
  8905. isc_uint16_t udpsize = SEND_BUFFER_SIZE;
  8906. REQUIRE(DNS_ZONE_VALID(zone));
  8907. UNUSED(task);
  8908. ENTER;
  8909. LOCK_ZONE(zone);
  8910. if (((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0) ||
  8911. DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) ||
  8912. zone->view->requestmgr == NULL) {
  8913. if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
  8914. cancel = ISC_FALSE;
  8915. goto cleanup;
  8916. }
  8917. /*
  8918. * XXX Optimisation: Create message when zone is setup and reuse.
  8919. */
  8920. result = create_query(zone, dns_rdatatype_soa, &message);
  8921. if (result != ISC_R_SUCCESS)
  8922. goto cleanup;
  8923. again:
  8924. INSIST(zone->masterscnt > 0);
  8925. INSIST(zone->curmaster < zone->masterscnt);
  8926. zone->masteraddr = zone->masters[zone->curmaster];
  8927. isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
  8928. /*
  8929. * First, look for a tsig key in the master statement, then
  8930. * try for a server key.
  8931. */
  8932. if ((zone->masterkeynames != NULL) &&
  8933. (zone->masterkeynames[zone->curmaster] != NULL)) {
  8934. dns_view_t *view = dns_zone_getview(zone);
  8935. dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
  8936. result = dns_view_gettsig(view, keyname, &key);
  8937. if (result != ISC_R_SUCCESS) {
  8938. char namebuf[DNS_NAME_FORMATSIZE];
  8939. dns_name_format(keyname, namebuf, sizeof(namebuf));
  8940. dns_zone_log(zone, ISC_LOG_ERROR,
  8941. "unable to find key: %s", namebuf);
  8942. goto skip_master;
  8943. }
  8944. }
  8945. if (key == NULL) {
  8946. result = dns_view_getpeertsig(zone->view, &masterip, &key);
  8947. if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
  8948. char addrbuf[ISC_NETADDR_FORMATSIZE];
  8949. isc_netaddr_format(&masterip, addrbuf, sizeof(addrbuf));
  8950. dns_zone_log(zone, ISC_LOG_ERROR,
  8951. "unable to find TSIG key for %s", addrbuf);
  8952. goto skip_master;
  8953. }
  8954. }
  8955. have_xfrsource = ISC_FALSE;
  8956. reqnsid = zone->view->requestnsid;
  8957. if (zone->view->peers != NULL) {
  8958. dns_peer_t *peer = NULL;
  8959. isc_boolean_t edns;
  8960. result = dns_peerlist_peerbyaddr(zone->view->peers,
  8961. &masterip, &peer);
  8962. if (result == ISC_R_SUCCESS) {
  8963. result = dns_peer_getsupportedns(peer, &edns);
  8964. if (result == ISC_R_SUCCESS && !edns)
  8965. DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
  8966. result = dns_peer_gettransfersource(peer,
  8967. &zone->sourceaddr);
  8968. if (result == ISC_R_SUCCESS)
  8969. have_xfrsource = ISC_TRUE;
  8970. if (zone->view->resolver != NULL)
  8971. udpsize =
  8972. dns_resolver_getudpsize(zone->view->resolver);
  8973. (void)dns_peer_getudpsize(peer, &udpsize);
  8974. (void)dns_peer_getrequestnsid(peer, &reqnsid);
  8975. }
  8976. }
  8977. switch (isc_sockaddr_pf(&zone->masteraddr)) {
  8978. case PF_INET:
  8979. if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
  8980. if (isc_sockaddr_equal(&zone->altxfrsource4,
  8981. &zone->xfrsource4))
  8982. goto skip_master;
  8983. zone->sourceaddr = zone->altxfrsource4;
  8984. } else if (!have_xfrsource)
  8985. zone->sourceaddr = zone->xfrsource4;
  8986. break;
  8987. case PF_INET6:
  8988. if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
  8989. if (isc_sockaddr_equal(&zone->altxfrsource6,
  8990. &zone->xfrsource6))
  8991. goto skip_master;
  8992. zone->sourceaddr = zone->altxfrsource6;
  8993. } else if (!have_xfrsource)
  8994. zone->sourceaddr = zone->xfrsource6;
  8995. break;
  8996. default:
  8997. result = ISC_R_NOTIMPLEMENTED;
  8998. goto cleanup;
  8999. }
  9000. options = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEVC) ?
  9001. DNS_REQUESTOPT_TCP : 0;
  9002. if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
  9003. result = add_opt(message, udpsize, reqnsid);
  9004. if (result != ISC_R_SUCCESS)
  9005. zone_debuglog(zone, me, 1,
  9006. "unable to add opt record: %s",
  9007. dns_result_totext(result));
  9008. }
  9009. zone_iattach(zone, &dummy);
  9010. timeout = 15;
  9011. if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
  9012. timeout = 30;
  9013. result = dns_request_createvia2(zone->view->requestmgr, message,
  9014. &zone->sourceaddr, &zone->masteraddr,
  9015. options, key, timeout * 3, timeout,
  9016. zone->task, refresh_callback, zone,
  9017. &zone->request);
  9018. if (result != ISC_R_SUCCESS) {
  9019. zone_idetach(&dummy);
  9020. zone_debuglog(zone, me, 1,
  9021. "dns_request_createvia2() failed: %s",
  9022. dns_result_totext(result));
  9023. goto cleanup;
  9024. } else {
  9025. if (isc_sockaddr_pf(&zone->masteraddr) == PF_INET)
  9026. inc_stats(zone, dns_zonestatscounter_soaoutv4);
  9027. else
  9028. inc_stats(zone, dns_zonestatscounter_soaoutv6);
  9029. }
  9030. cancel = ISC_FALSE;
  9031. cleanup:
  9032. if (key != NULL)
  9033. dns_tsigkey_detach(&key);
  9034. if (result != ISC_R_SUCCESS)
  9035. DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
  9036. if (message != NULL)
  9037. dns_message_destroy(&message);
  9038. if (cancel)
  9039. cancel_refresh(zone);
  9040. isc_event_free(&event);
  9041. UNLOCK_ZONE(zone);
  9042. dns_zone_idetach(&zone);
  9043. return;
  9044. skip_master:
  9045. if (key != NULL)
  9046. dns_tsigkey_detach(&key);
  9047. /*
  9048. * Skip to next failed / untried master.
  9049. */
  9050. do {
  9051. zone->curmaster++;
  9052. } while (zone->curmaster < zone->masterscnt &&
  9053. zone->mastersok[zone->curmaster]);
  9054. if (zone->curmaster < zone->masterscnt)
  9055. goto again;
  9056. zone->curmaster = 0;
  9057. goto cleanup;
  9058. }
  9059. static void
  9060. ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) {
  9061. const char me[] = "ns_query";
  9062. isc_result_t result;
  9063. dns_message_t *message = NULL;
  9064. isc_netaddr_t masterip;
  9065. dns_tsigkey_t *key = NULL;
  9066. dns_dbnode_t *node = NULL;
  9067. int timeout;
  9068. isc_boolean_t have_xfrsource = ISC_FALSE, reqnsid;
  9069. isc_uint16_t udpsize = SEND_BUFFER_SIZE;
  9070. REQUIRE(DNS_ZONE_VALID(zone));
  9071. REQUIRE(LOCKED_ZONE(zone));
  9072. REQUIRE((soardataset != NULL && stub == NULL) ||
  9073. (soardataset == NULL && stub != NULL));
  9074. REQUIRE(stub == NULL || DNS_STUB_VALID(stub));
  9075. ENTER;
  9076. if (stub == NULL) {
  9077. stub = isc_mem_get(zone->mctx, sizeof(*stub));
  9078. if (stub == NULL)
  9079. goto cleanup;
  9080. stub->magic = STUB_MAGIC;
  9081. stub->mctx = zone->mctx;
  9082. stub->zone = NULL;
  9083. stub->db = NULL;
  9084. stub->version = NULL;
  9085. /*
  9086. * Attach so that the zone won't disappear from under us.
  9087. */
  9088. zone_iattach(zone, &stub->zone);
  9089. /*
  9090. * If a db exists we will update it, otherwise we create a
  9091. * new one and attach it to the zone once we have the NS
  9092. * RRset and glue.
  9093. */
  9094. ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
  9095. if (zone->db != NULL) {
  9096. dns_db_attach(zone->db, &stub->db);
  9097. ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
  9098. } else {
  9099. ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
  9100. INSIST(zone->db_argc >= 1);
  9101. result = dns_db_create(zone->mctx, zone->db_argv[0],
  9102. &zone->origin, dns_dbtype_stub,
  9103. zone->rdclass,
  9104. zone->db_argc - 1,
  9105. zone->db_argv + 1,
  9106. &stub->db);
  9107. if (result != ISC_R_SUCCESS) {
  9108. dns_zone_log(zone, ISC_LOG_ERROR,
  9109. "refreshing stub: "
  9110. "could not create "
  9111. "database: %s",
  9112. dns_result_totext(result));
  9113. goto cleanup;
  9114. }
  9115. dns_db_settask(stub->db, zone->task);
  9116. }
  9117. result = dns_db_newversion(stub->db, &stub->version);
  9118. if (result != ISC_R_SUCCESS) {
  9119. dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: "
  9120. "dns_db_newversion() failed: %s",
  9121. dns_result_totext(result));
  9122. goto cleanup;
  9123. }
  9124. /*
  9125. * Update SOA record.
  9126. */
  9127. result = dns_db_findnode(stub->db, &zone->origin, ISC_TRUE,
  9128. &node);
  9129. if (result != ISC_R_SUCCESS) {
  9130. dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: "
  9131. "dns_db_findnode() failed: %s",
  9132. dns_result_totext(result));
  9133. goto cleanup;
  9134. }
  9135. result = dns_db_addrdataset(stub->db, node, stub->version, 0,
  9136. soardataset, 0, NULL);
  9137. dns_db_detachnode(stub->db, &node);
  9138. if (result != ISC_R_SUCCESS) {
  9139. dns_zone_log(zone, ISC_LOG_INFO,
  9140. "refreshing stub: "
  9141. "dns_db_addrdataset() failed: %s",
  9142. dns_result_totext(result));
  9143. goto cleanup;
  9144. }
  9145. }
  9146. /*
  9147. * XXX Optimisation: Create message when zone is setup and reuse.
  9148. */
  9149. result = create_query(zone, dns_rdatatype_ns, &message);
  9150. INSIST(result == ISC_R_SUCCESS);
  9151. INSIST(zone->masterscnt > 0);
  9152. INSIST(zone->curmaster < zone->masterscnt);
  9153. zone->masteraddr = zone->masters[zone->curmaster];
  9154. isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
  9155. /*
  9156. * First, look for a tsig key in the master statement, then
  9157. * try for a server key.
  9158. */
  9159. if ((zone->masterkeynames != NULL) &&
  9160. (zone->masterkeynames[zone->curmaster] != NULL)) {
  9161. dns_view_t *view = dns_zone_getview(zone);
  9162. dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
  9163. result = dns_view_gettsig(view, keyname, &key);
  9164. if (result != ISC_R_SUCCESS) {
  9165. char namebuf[DNS_NAME_FORMATSIZE];
  9166. dns_name_format(keyname, namebuf, sizeof(namebuf));
  9167. dns_zone_log(zone, ISC_LOG_ERROR,
  9168. "unable to find key: %s", namebuf);
  9169. }
  9170. }
  9171. if (key == NULL)
  9172. (void)dns_view_getpeertsig(zone->view, &masterip, &key);
  9173. reqnsid = zone->view->requestnsid;
  9174. if (zone->view->peers != NULL) {
  9175. dns_peer_t *peer = NULL;
  9176. isc_boolean_t edns;
  9177. result = dns_peerlist_peerbyaddr(zone->view->peers,
  9178. &masterip, &peer);
  9179. if (result == ISC_R_SUCCESS) {
  9180. result = dns_peer_getsupportedns(peer, &edns);
  9181. if (result == ISC_R_SUCCESS && !edns)
  9182. DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
  9183. result = dns_peer_gettransfersource(peer,
  9184. &zone->sourceaddr);
  9185. if (result == ISC_R_SUCCESS)
  9186. have_xfrsource = ISC_TRUE;
  9187. if (zone->view->resolver != NULL)
  9188. udpsize =
  9189. dns_resolver_getudpsize(zone->view->resolver);
  9190. (void)dns_peer_getudpsize(peer, &udpsize);
  9191. (void)dns_peer_getrequestnsid(peer, &reqnsid);
  9192. }
  9193. }
  9194. if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
  9195. result = add_opt(message, udpsize, reqnsid);
  9196. if (result != ISC_R_SUCCESS)
  9197. zone_debuglog(zone, me, 1,
  9198. "unable to add opt record: %s",
  9199. dns_result_totext(result));
  9200. }
  9201. /*
  9202. * Always use TCP so that we shouldn't truncate in additional section.
  9203. */
  9204. switch (isc_sockaddr_pf(&zone->masteraddr)) {
  9205. case PF_INET:
  9206. if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC))
  9207. zone->sourceaddr = zone->altxfrsource4;
  9208. else if (!have_xfrsource)
  9209. zone->sourceaddr = zone->xfrsource4;
  9210. break;
  9211. case PF_INET6:
  9212. if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC))
  9213. zone->sourceaddr = zone->altxfrsource6;
  9214. else if (!have_xfrsource)
  9215. zone->sourceaddr = zone->xfrsource6;
  9216. break;
  9217. default:
  9218. result = ISC_R_NOTIMPLEMENTED;
  9219. POST(result);
  9220. goto cleanup;
  9221. }
  9222. timeout = 15;
  9223. if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
  9224. timeout = 30;
  9225. result = dns_request_createvia2(zone->view->requestmgr, message,
  9226. &zone->sourceaddr, &zone->masteraddr,
  9227. DNS_REQUESTOPT_TCP, key, timeout * 3,
  9228. timeout, zone->task, stub_callback,
  9229. stub, &zone->request);
  9230. if (result != ISC_R_SUCCESS) {
  9231. zone_debuglog(zone, me, 1,
  9232. "dns_request_createvia() failed: %s",
  9233. dns_result_totext(result));
  9234. goto cleanup;
  9235. }
  9236. dns_message_destroy(&message);
  9237. goto unlock;
  9238. cleanup:
  9239. cancel_refresh(zone);
  9240. if (stub != NULL) {
  9241. stub->magic = 0;
  9242. if (stub->version != NULL)
  9243. dns_db_closeversion(stub->db, &stub->version,
  9244. ISC_FALSE);
  9245. if (stub->db != NULL)
  9246. dns_db_detach(&stub->db);
  9247. if (stub->zone != NULL)
  9248. zone_idetach(&stub->zone);
  9249. isc_mem_put(stub->mctx, stub, sizeof(*stub));
  9250. }
  9251. if (message != NULL)
  9252. dns_message_destroy(&message);
  9253. unlock:
  9254. if (key != NULL)
  9255. dns_tsigkey_detach(&key);
  9256. return;
  9257. }
  9258. /*
  9259. * Handle the control event. Note that although this event causes the zone
  9260. * to shut down, it is not a shutdown event in the sense of the task library.
  9261. */
  9262. static void
  9263. zone_shutdown(isc_task_t *task, isc_event_t *event) {
  9264. dns_zone_t *zone = (dns_zone_t *) event->ev_arg;
  9265. isc_boolean_t free_needed, linked = ISC_FALSE;
  9266. UNUSED(task);
  9267. REQUIRE(DNS_ZONE_VALID(zone));
  9268. INSIST(event->ev_type == DNS_EVENT_ZONECONTROL);
  9269. INSIST(isc_refcount_current(&zone->erefs) == 0);
  9270. zone_debuglog(zone, "zone_shutdown", 3, "shutting down");
  9271. /*
  9272. * Stop things being restarted after we cancel them below.
  9273. */
  9274. LOCK_ZONE(zone);
  9275. DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXITING);
  9276. UNLOCK_ZONE(zone);
  9277. /*
  9278. * If we were waiting for xfrin quota, step out of
  9279. * the queue.
  9280. * If there's no zone manager, we can't be waiting for the
  9281. * xfrin quota
  9282. */
  9283. if (zone->zmgr != NULL) {
  9284. RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
  9285. if (zone->statelist == &zone->zmgr->waiting_for_xfrin) {
  9286. ISC_LIST_UNLINK(zone->zmgr->waiting_for_xfrin, zone,
  9287. statelink);
  9288. linked = ISC_TRUE;
  9289. zone->statelist = NULL;
  9290. }
  9291. RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
  9292. }
  9293. /*
  9294. * In task context, no locking required. See zone_xfrdone().
  9295. */
  9296. if (zone->xfr != NULL)
  9297. dns_xfrin_shutdown(zone->xfr);
  9298. LOCK_ZONE(zone);
  9299. if (linked) {
  9300. INSIST(zone->irefs > 0);
  9301. zone->irefs--;
  9302. }
  9303. if (zone->request != NULL) {
  9304. dns_request_cancel(zone->request);
  9305. }
  9306. if (zone->readio != NULL)
  9307. zonemgr_cancelio(zone->readio);
  9308. if (zone->lctx != NULL)
  9309. dns_loadctx_cancel(zone->lctx);
  9310. if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) ||
  9311. !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
  9312. if (zone->writeio != NULL)
  9313. zonemgr_cancelio(zone->writeio);
  9314. if (zone->dctx != NULL)
  9315. dns_dumpctx_cancel(zone->dctx);
  9316. }
  9317. notify_cancel(zone);
  9318. forward_cancel(zone);
  9319. if (zone->timer != NULL) {
  9320. isc_timer_detach(&zone->timer);
  9321. INSIST(zone->irefs > 0);
  9322. zone->irefs--;
  9323. }
  9324. if (zone->view != NULL)
  9325. dns_view_weakdetach(&zone->view);
  9326. /*
  9327. * We have now canceled everything set the flag to allow exit_check()
  9328. * to succeed. We must not unlock between setting this flag and
  9329. * calling exit_check().
  9330. */
  9331. DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SHUTDOWN);
  9332. free_needed = exit_check(zone);
  9333. UNLOCK_ZONE(zone);
  9334. if (free_needed)
  9335. zone_free(zone);
  9336. }
  9337. static void
  9338. zone_timer(isc_task_t *task, isc_event_t *event) {
  9339. const char me[] = "zone_timer";
  9340. dns_zone_t *zone = (dns_zone_t *)event->ev_arg;
  9341. UNUSED(task);
  9342. REQUIRE(DNS_ZONE_VALID(zone));
  9343. ENTER;
  9344. zone_maintenance(zone);
  9345. isc_event_free(&event);
  9346. }
  9347. static void
  9348. zone_settimer(dns_zone_t *zone, isc_time_t *now) {
  9349. const char me[] = "zone_settimer";
  9350. isc_time_t next;
  9351. isc_result_t result;
  9352. ENTER;
  9353. REQUIRE(DNS_ZONE_VALID(zone));
  9354. if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
  9355. return;
  9356. isc_time_settoepoch(&next);
  9357. switch (zone->type) {
  9358. case dns_zone_master:
  9359. if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY))
  9360. next = zone->notifytime;
  9361. if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
  9362. !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
  9363. INSIST(!isc_time_isepoch(&zone->dumptime));
  9364. if (isc_time_isepoch(&next) ||
  9365. isc_time_compare(&zone->dumptime, &next) < 0)
  9366. next = zone->dumptime;
  9367. }
  9368. if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING) &&
  9369. !isc_time_isepoch(&zone->refreshkeytime)) {
  9370. if (isc_time_isepoch(&next) ||
  9371. isc_time_compare(&zone->refreshkeytime, &next) < 0)
  9372. next = zone->refreshkeytime;
  9373. }
  9374. if (!isc_time_isepoch(&zone->resigntime)) {
  9375. if (isc_time_isepoch(&next) ||
  9376. isc_time_compare(&zone->resigntime, &next) < 0)
  9377. next = zone->resigntime;
  9378. }
  9379. if (!isc_time_isepoch(&zone->keywarntime)) {
  9380. if (isc_time_isepoch(&next) ||
  9381. isc_time_compare(&zone->keywarntime, &next) < 0)
  9382. next = zone->keywarntime;
  9383. }
  9384. if (!isc_time_isepoch(&zone->signingtime)) {
  9385. if (isc_time_isepoch(&next) ||
  9386. isc_time_compare(&zone->signingtime, &next) < 0)
  9387. next = zone->signingtime;
  9388. }
  9389. if (!isc_time_isepoch(&zone->nsec3chaintime)) {
  9390. if (isc_time_isepoch(&next) ||
  9391. isc_time_compare(&zone->nsec3chaintime, &next) < 0)
  9392. next = zone->nsec3chaintime;
  9393. }
  9394. break;
  9395. case dns_zone_slave:
  9396. if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY))
  9397. next = zone->notifytime;
  9398. /*FALLTHROUGH*/
  9399. case dns_zone_stub:
  9400. if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH) &&
  9401. !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOMASTERS) &&
  9402. !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH) &&
  9403. !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING)) {
  9404. INSIST(!isc_time_isepoch(&zone->refreshtime));
  9405. if (isc_time_isepoch(&next) ||
  9406. isc_time_compare(&zone->refreshtime, &next) < 0)
  9407. next = zone->refreshtime;
  9408. }
  9409. if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
  9410. INSIST(!isc_time_isepoch(&zone->expiretime));
  9411. if (isc_time_isepoch(&next) ||
  9412. isc_time_compare(&zone->expiretime, &next) < 0)
  9413. next = zone->expiretime;
  9414. }
  9415. if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
  9416. !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
  9417. INSIST(!isc_time_isepoch(&zone->dumptime));
  9418. if (isc_time_isepoch(&next) ||
  9419. isc_time_compare(&zone->dumptime, &next) < 0)
  9420. next = zone->dumptime;
  9421. }
  9422. break;
  9423. case dns_zone_key:
  9424. if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
  9425. !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
  9426. INSIST(!isc_time_isepoch(&zone->dumptime));
  9427. if (isc_time_isepoch(&next) ||
  9428. isc_time_compare(&zone->dumptime, &next) < 0)
  9429. next = zone->dumptime;
  9430. }
  9431. if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING)) {
  9432. if (isc_time_isepoch(&next) ||
  9433. (!isc_time_isepoch(&zone->refreshkeytime) &&
  9434. isc_time_compare(&zone->refreshkeytime, &next) < 0))
  9435. next = zone->refreshkeytime;
  9436. }
  9437. break;
  9438. default:
  9439. break;
  9440. }
  9441. if (isc_time_isepoch(&next)) {
  9442. zone_debuglog(zone, me, 10, "settimer inactive");
  9443. result = isc_timer_reset(zone->timer, isc_timertype_inactive,
  9444. NULL, NULL, ISC_TRUE);
  9445. if (result != ISC_R_SUCCESS)
  9446. dns_zone_log(zone, ISC_LOG_ERROR,
  9447. "could not deactivate zone timer: %s",
  9448. isc_result_totext(result));
  9449. } else {
  9450. if (isc_time_compare(&next, now) <= 0)
  9451. next = *now;
  9452. result = isc_timer_reset(zone->timer, isc_timertype_once,
  9453. &next, NULL, ISC_TRUE);
  9454. if (result != ISC_R_SUCCESS)
  9455. dns_zone_log(zone, ISC_LOG_ERROR,
  9456. "could not reset zone timer: %s",
  9457. isc_result_totext(result));
  9458. }
  9459. }
  9460. static void
  9461. cancel_refresh(dns_zone_t *zone) {
  9462. const char me[] = "cancel_refresh";
  9463. isc_time_t now;
  9464. /*
  9465. * 'zone' locked by caller.
  9466. */
  9467. REQUIRE(DNS_ZONE_VALID(zone));
  9468. REQUIRE(LOCKED_ZONE(zone));
  9469. ENTER;
  9470. DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
  9471. TIME_NOW(&now);
  9472. zone_settimer(zone, &now);
  9473. }
  9474. static isc_result_t
  9475. notify_createmessage(dns_zone_t *zone, unsigned int flags,
  9476. dns_message_t **messagep)
  9477. {
  9478. dns_db_t *zonedb = NULL;
  9479. dns_dbnode_t *node = NULL;
  9480. dns_dbversion_t *version = NULL;
  9481. dns_message_t *message = NULL;
  9482. dns_rdataset_t rdataset;
  9483. dns_rdata_t rdata = DNS_RDATA_INIT;
  9484. dns_name_t *tempname = NULL;
  9485. dns_rdata_t *temprdata = NULL;
  9486. dns_rdatalist_t *temprdatalist = NULL;
  9487. dns_rdataset_t *temprdataset = NULL;
  9488. isc_result_t result;
  9489. isc_region_t r;
  9490. isc_buffer_t *b = NULL;
  9491. REQUIRE(DNS_ZONE_VALID(zone));
  9492. REQUIRE(messagep != NULL && *messagep == NULL);
  9493. result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER,
  9494. &message);
  9495. if (result != ISC_R_SUCCESS)
  9496. return (result);
  9497. message->opcode = dns_opcode_notify;
  9498. message->flags |= DNS_MESSAGEFLAG_AA;
  9499. message->rdclass = zone->rdclass;
  9500. result = dns_message_gettempname(message, &tempname);
  9501. if (result != ISC_R_SUCCESS)
  9502. goto cleanup;
  9503. result = dns_message_gettemprdataset(message, &temprdataset);
  9504. if (result != ISC_R_SUCCESS)
  9505. goto cleanup;
  9506. /*
  9507. * Make question.
  9508. */
  9509. dns_name_init(tempname, NULL);
  9510. dns_name_clone(&zone->origin, tempname);
  9511. dns_rdataset_init(temprdataset);
  9512. dns_rdataset_makequestion(temprdataset, zone->rdclass,
  9513. dns_rdatatype_soa);
  9514. ISC_LIST_APPEND(tempname->list, temprdataset, link);
  9515. dns_message_addname(message, tempname, DNS_SECTION_QUESTION);
  9516. tempname = NULL;
  9517. temprdataset = NULL;
  9518. if ((flags & DNS_NOTIFY_NOSOA) != 0)
  9519. goto done;
  9520. result = dns_message_gettempname(message, &tempname);
  9521. if (result != ISC_R_SUCCESS)
  9522. goto soa_cleanup;
  9523. result = dns_message_gettemprdata(message, &temprdata);
  9524. if (result != ISC_R_SUCCESS)
  9525. goto soa_cleanup;
  9526. result = dns_message_gettemprdataset(message, &temprdataset);
  9527. if (result != ISC_R_SUCCESS)
  9528. goto soa_cleanup;
  9529. result = dns_message_gettemprdatalist(message, &temprdatalist);
  9530. if (result != ISC_R_SUCCESS)
  9531. goto soa_cleanup;
  9532. ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
  9533. INSIST(zone->db != NULL); /* XXXJT: is this assumption correct? */
  9534. dns_db_attach(zone->db, &zonedb);
  9535. ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
  9536. dns_name_init(tempname, NULL);
  9537. dns_name_clone(&zone->origin, tempname);
  9538. dns_db_currentversion(zonedb, &version);
  9539. result = dns_db_findnode(zonedb, tempname, ISC_FALSE, &node);
  9540. if (result != ISC_R_SUCCESS)
  9541. goto soa_cleanup;
  9542. dns_rdataset_init(&rdataset);
  9543. result = dns_db_findrdataset(zonedb, node, version,
  9544. dns_rdatatype_soa,
  9545. dns_rdatatype_none, 0, &rdataset,
  9546. NULL);
  9547. if (result != ISC_R_SUCCESS)
  9548. goto soa_cleanup;
  9549. result = dns_rdataset_first(&rdataset);
  9550. if (result != ISC_R_SUCCESS)
  9551. goto soa_cleanup;
  9552. dns_rdataset_current(&rdataset, &rdata);
  9553. dns_rdata_toregion(&rdata, &r);
  9554. result = isc_buffer_allocate(zone->mctx, &b, r.length);
  9555. if (result != ISC_R_SUCCESS)
  9556. goto soa_cleanup;
  9557. isc_buffer_putmem(b, r.base, r.length);
  9558. isc_buffer_usedregion(b, &r);
  9559. dns_rdata_init(temprdata);
  9560. dns_rdata_fromregion(temprdata, rdata.rdclass, rdata.type, &r);
  9561. dns_message_takebuffer(message, &b);
  9562. result = dns_rdataset_next(&rdataset);
  9563. dns_rdataset_disassociate(&rdataset);
  9564. if (result != ISC_R_NOMORE)
  9565. goto soa_cleanup;
  9566. temprdatalist->rdclass = rdata.rdclass;
  9567. temprdatalist->type = rdata.type;
  9568. temprdatalist->covers = 0;
  9569. temprdatalist->ttl = rdataset.ttl;
  9570. ISC_LIST_INIT(temprdatalist->rdata);
  9571. ISC_LIST_APPEND(temprdatalist->rdata, temprdata, link);
  9572. dns_rdataset_init(temprdataset);
  9573. result = dns_rdatalist_tordataset(temprdatalist, temprdataset);
  9574. if (result != ISC_R_SUCCESS)
  9575. goto soa_cleanup;
  9576. ISC_LIST_APPEND(tempname->list, temprdataset, link);
  9577. dns_message_addname(message, tempname, DNS_SECTION_ANSWER);
  9578. temprdatalist = NULL;
  9579. temprdataset = NULL;
  9580. temprdata = NULL;
  9581. tempname = NULL;
  9582. soa_cleanup:
  9583. if (node != NULL)
  9584. dns_db_detachnode(zonedb, &node);
  9585. if (version != NULL)
  9586. dns_db_closeversion(zonedb, &version, ISC_FALSE);
  9587. if (zonedb != NULL)
  9588. dns_db_detach(&zonedb);
  9589. if (tempname != NULL)
  9590. dns_message_puttempname(message, &tempname);
  9591. if (temprdata != NULL)
  9592. dns_message_puttemprdata(message, &temprdata);
  9593. if (temprdataset != NULL)
  9594. dns_message_puttemprdataset(message, &temprdataset);
  9595. if (temprdatalist != NULL)
  9596. dns_message_puttemprdatalist(message, &temprdatalist);
  9597. done:
  9598. *messagep = message;
  9599. return (ISC_R_SUCCESS);
  9600. cleanup:
  9601. if (tempname != NULL)
  9602. dns_message_puttempname(message, &tempname);
  9603. if (temprdataset != NULL)
  9604. dns_message_puttemprdataset(message, &temprdataset);
  9605. dns_message_destroy(&message);
  9606. return (result);
  9607. }
  9608. isc_result_t
  9609. dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from,
  9610. dns_message_t *msg)
  9611. {
  9612. unsigned int i;
  9613. dns_rdata_soa_t soa;
  9614. dns_rdataset_t *rdataset = NULL;
  9615. dns_rdata_t rdata = DNS_RDATA_INIT;
  9616. isc_result_t result;
  9617. char fromtext[ISC_SOCKADDR_FORMATSIZE];
  9618. int match = 0;
  9619. isc_netaddr_t netaddr;
  9620. isc_sockaddr_t local, remote;
  9621. REQUIRE(DNS_ZONE_VALID(zone));
  9622. /*
  9623. * If type != T_SOA return DNS_R_NOTIMP. We don't yet support
  9624. * ROLLOVER.
  9625. *
  9626. * SOA: RFC1996
  9627. * Check that 'from' is a valid notify source, (zone->masters).
  9628. * Return DNS_R_REFUSED if not.
  9629. *
  9630. * If the notify message contains a serial number check it
  9631. * against the zones serial and return if <= current serial
  9632. *
  9633. * If a refresh check is progress, if so just record the
  9634. * fact we received a NOTIFY and from where and return.
  9635. * We will perform a new refresh check when the current one
  9636. * completes. Return ISC_R_SUCCESS.
  9637. *
  9638. * Otherwise initiate a refresh check using 'from' as the
  9639. * first address to check. Return ISC_R_SUCCESS.
  9640. */
  9641. isc_sockaddr_format(from, fromtext, sizeof(fromtext));
  9642. /*
  9643. * We only handle NOTIFY (SOA) at the present.
  9644. */
  9645. LOCK_ZONE(zone);
  9646. if (isc_sockaddr_pf(from) == PF_INET)
  9647. inc_stats(zone, dns_zonestatscounter_notifyinv4);
  9648. else
  9649. inc_stats(zone, dns_zonestatscounter_notifyinv6);
  9650. if (msg->counts[DNS_SECTION_QUESTION] == 0 ||
  9651. dns_message_findname(msg, DNS_SECTION_QUESTION, &zone->origin,
  9652. dns_rdatatype_soa, dns_rdatatype_none,
  9653. NULL, NULL) != ISC_R_SUCCESS) {
  9654. UNLOCK_ZONE(zone);
  9655. if (msg->counts[DNS_SECTION_QUESTION] == 0) {
  9656. dns_zone_log(zone, ISC_LOG_NOTICE,
  9657. "NOTIFY with no "
  9658. "question section from: %s", fromtext);
  9659. return (DNS_R_FORMERR);
  9660. }
  9661. dns_zone_log(zone, ISC_LOG_NOTICE,
  9662. "NOTIFY zone does not match");
  9663. return (DNS_R_NOTIMP);
  9664. }
  9665. /*
  9666. * If we are a master zone just succeed.
  9667. */
  9668. if (zone->type == dns_zone_master) {
  9669. UNLOCK_ZONE(zone);
  9670. return (ISC_R_SUCCESS);
  9671. }
  9672. isc_netaddr_fromsockaddr(&netaddr, from);
  9673. for (i = 0; i < zone->masterscnt; i++) {
  9674. if (isc_sockaddr_eqaddr(from, &zone->masters[i]))
  9675. break;
  9676. if (zone->view->aclenv.match_mapped &&
  9677. IN6_IS_ADDR_V4MAPPED(&from->type.sin6.sin6_addr) &&
  9678. isc_sockaddr_pf(&zone->masters[i]) == AF_INET) {
  9679. isc_netaddr_t na1, na2;
  9680. isc_netaddr_fromv4mapped(&na1, &netaddr);
  9681. isc_netaddr_fromsockaddr(&na2, &zone->masters[i]);
  9682. if (isc_netaddr_equal(&na1, &na2))
  9683. break;
  9684. }
  9685. }
  9686. /*
  9687. * Accept notify requests from non masters if they are on
  9688. * 'zone->notify_acl'.
  9689. */
  9690. if (i >= zone->masterscnt && zone->notify_acl != NULL &&
  9691. dns_acl_match(&netaddr, NULL, zone->notify_acl,
  9692. &zone->view->aclenv,
  9693. &match, NULL) == ISC_R_SUCCESS &&
  9694. match > 0)
  9695. {
  9696. /* Accept notify. */
  9697. } else if (i >= zone->masterscnt) {
  9698. UNLOCK_ZONE(zone);
  9699. dns_zone_log(zone, ISC_LOG_INFO,
  9700. "refused notify from non-master: %s", fromtext);
  9701. inc_stats(zone, dns_zonestatscounter_notifyrej);
  9702. return (DNS_R_REFUSED);
  9703. }
  9704. /*
  9705. * If the zone is loaded and there are answers check the serial
  9706. * to see if we need to do a refresh. Do not worry about this
  9707. * check if we are a dialup zone as we use the notify request
  9708. * to trigger a refresh check.
  9709. */
  9710. if (msg->counts[DNS_SECTION_ANSWER] > 0 &&
  9711. DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
  9712. !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH)) {
  9713. result = dns_message_findname(msg, DNS_SECTION_ANSWER,
  9714. &zone->origin,
  9715. dns_rdatatype_soa,
  9716. dns_rdatatype_none, NULL,
  9717. &rdataset);
  9718. if (result == ISC_R_SUCCESS)
  9719. result = dns_rdataset_first(rdataset);
  9720. if (result == ISC_R_SUCCESS) {
  9721. isc_uint32_t serial = 0, oldserial;
  9722. dns_rdataset_current(rdataset, &rdata);
  9723. result = dns_rdata_tostruct(&rdata, &soa, NULL);
  9724. RUNTIME_CHECK(result == ISC_R_SUCCESS);
  9725. serial = soa.serial;
  9726. /*
  9727. * The following should safely be performed without DB
  9728. * lock and succeed in this context.
  9729. */
  9730. result = zone_get_from_db(zone, zone->db, NULL, NULL,
  9731. &oldserial, NULL, NULL, NULL,
  9732. NULL, NULL);
  9733. RUNTIME_CHECK(result == ISC_R_SUCCESS);
  9734. if (isc_serial_le(serial, oldserial)) {
  9735. dns_zone_log(zone,
  9736. ISC_LOG_INFO,
  9737. "notify from %s: "
  9738. "zone is up to date",
  9739. fromtext);
  9740. UNLOCK_ZONE(zone);
  9741. return (ISC_R_SUCCESS);
  9742. }
  9743. }
  9744. }
  9745. /*
  9746. * If we got this far and there was a refresh in progress just
  9747. * let it complete. Record where we got the notify from so we
  9748. * can perform a refresh check when the current one completes
  9749. */
  9750. if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH)) {
  9751. DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
  9752. zone->notifyfrom = *from;
  9753. UNLOCK_ZONE(zone);
  9754. dns_zone_log(zone, ISC_LOG_INFO,
  9755. "notify from %s: refresh in progress, "
  9756. "refresh check queued",
  9757. fromtext);
  9758. return (ISC_R_SUCCESS);
  9759. }
  9760. zone->notifyfrom = *from;
  9761. local = zone->masteraddr;
  9762. remote = zone->sourceaddr;
  9763. UNLOCK_ZONE(zone);
  9764. dns_zonemgr_unreachabledel(zone->zmgr, &local, &remote);
  9765. dns_zone_refresh(zone);
  9766. return (ISC_R_SUCCESS);
  9767. }
  9768. void
  9769. dns_zone_setnotifyacl(dns_zone_t *zone, dns_acl_t *acl) {
  9770. REQUIRE(DNS_ZONE_VALID(zone));
  9771. LOCK_ZONE(zone);
  9772. if (zone->notify_acl != NULL)
  9773. dns_acl_detach(&zone->notify_acl);
  9774. dns_acl_attach(acl, &zone->notify_acl);
  9775. UNLOCK_ZONE(zone);
  9776. }
  9777. void
  9778. dns_zone_setqueryacl(dns_zone_t *zone, dns_acl_t *acl) {
  9779. REQUIRE(DNS_ZONE_VALID(zone));
  9780. LOCK_ZONE(zone);
  9781. if (zone->query_acl != NULL)
  9782. dns_acl_detach(&zone->query_acl);
  9783. dns_acl_attach(acl, &zone->query_acl);
  9784. UNLOCK_ZONE(zone);
  9785. }
  9786. void
  9787. dns_zone_setqueryonacl(dns_zone_t *zone, dns_acl_t *acl) {
  9788. REQUIRE(DNS_ZONE_VALID(zone));
  9789. LOCK_ZONE(zone);
  9790. if (zone->queryon_acl != NULL)
  9791. dns_acl_detach(&zone->queryon_acl);
  9792. dns_acl_attach(acl, &zone->queryon_acl);
  9793. UNLOCK_ZONE(zone);
  9794. }
  9795. void
  9796. dns_zone_setupdateacl(dns_zone_t *zone, dns_acl_t *acl) {
  9797. REQUIRE(DNS_ZONE_VALID(zone));
  9798. LOCK_ZONE(zone);
  9799. if (zone->update_acl != NULL)
  9800. dns_acl_detach(&zone->update_acl);
  9801. dns_acl_attach(acl, &zone->update_acl);
  9802. UNLOCK_ZONE(zone);
  9803. }
  9804. void
  9805. dns_zone_setforwardacl(dns_zone_t *zone, dns_acl_t *acl) {
  9806. REQUIRE(DNS_ZONE_VALID(zone));
  9807. LOCK_ZONE(zone);
  9808. if (zone->forward_acl != NULL)
  9809. dns_acl_detach(&zone->forward_acl);
  9810. dns_acl_attach(acl, &zone->forward_acl);
  9811. UNLOCK_ZONE(zone);
  9812. }
  9813. void
  9814. dns_zone_setxfracl(dns_zone_t *zone, dns_acl_t *acl) {
  9815. REQUIRE(DNS_ZONE_VALID(zone));
  9816. LOCK_ZONE(zone);
  9817. if (zone->xfr_acl != NULL)
  9818. dns_acl_detach(&zone->xfr_acl);
  9819. dns_acl_attach(acl, &zone->xfr_acl);
  9820. UNLOCK_ZONE(zone);
  9821. }
  9822. dns_acl_t *
  9823. dns_zone_getnotifyacl(dns_zone_t *zone) {
  9824. REQUIRE(DNS_ZONE_VALID(zone));
  9825. return (zone->notify_acl);
  9826. }
  9827. dns_acl_t *
  9828. dns_zone_getqueryacl(dns_zone_t *zone) {
  9829. REQUIRE(DNS_ZONE_VALID(zone));
  9830. return (zone->query_acl);
  9831. }
  9832. dns_acl_t *
  9833. dns_zone_getqueryonacl(dns_zone_t *zone) {
  9834. REQUIRE(DNS_ZONE_VALID(zone));
  9835. return (zone->queryon_acl);
  9836. }
  9837. dns_acl_t *
  9838. dns_zone_getupdateacl(dns_zone_t *zone) {
  9839. REQUIRE(DNS_ZONE_VALID(zone));
  9840. return (zone->update_acl);
  9841. }
  9842. dns_acl_t *
  9843. dns_zone_getforwardacl(dns_zone_t *zone) {
  9844. REQUIRE(DNS_ZONE_VALID(zone));
  9845. return (zone->forward_acl);
  9846. }
  9847. dns_acl_t *
  9848. dns_zone_getxfracl(dns_zone_t *zone) {
  9849. REQUIRE(DNS_ZONE_VALID(zone));
  9850. return (zone->xfr_acl);
  9851. }
  9852. void
  9853. dns_zone_clearupdateacl(dns_zone_t *zone) {
  9854. REQUIRE(DNS_ZONE_VALID(zone));
  9855. LOCK_ZONE(zone);
  9856. if (zone->update_acl != NULL)
  9857. dns_acl_detach(&zone->update_acl);
  9858. UNLOCK_ZONE(zone);
  9859. }
  9860. void
  9861. dns_zone_clearforwardacl(dns_zone_t *zone) {
  9862. REQUIRE(DNS_ZONE_VALID(zone));
  9863. LOCK_ZONE(zone);
  9864. if (zone->forward_acl != NULL)
  9865. dns_acl_detach(&zone->forward_acl);
  9866. UNLOCK_ZONE(zone);
  9867. }
  9868. void
  9869. dns_zone_clearnotifyacl(dns_zone_t *zone) {
  9870. REQUIRE(DNS_ZONE_VALID(zone));
  9871. LOCK_ZONE(zone);
  9872. if (zone->notify_acl != NULL)
  9873. dns_acl_detach(&zone->notify_acl);
  9874. UNLOCK_ZONE(zone);
  9875. }
  9876. void
  9877. dns_zone_clearqueryacl(dns_zone_t *zone) {
  9878. REQUIRE(DNS_ZONE_VALID(zone));
  9879. LOCK_ZONE(zone);
  9880. if (zone->query_acl != NULL)
  9881. dns_acl_detach(&zone->query_acl);
  9882. UNLOCK_ZONE(zone);
  9883. }
  9884. void
  9885. dns_zone_clearqueryonacl(dns_zone_t *zone) {
  9886. REQUIRE(DNS_ZONE_VALID(zone));
  9887. LOCK_ZONE(zone);
  9888. if (zone->queryon_acl != NULL)
  9889. dns_acl_detach(&zone->queryon_acl);
  9890. UNLOCK_ZONE(zone);
  9891. }
  9892. void
  9893. dns_zone_clearxfracl(dns_zone_t *zone) {
  9894. REQUIRE(DNS_ZONE_VALID(zone));
  9895. LOCK_ZONE(zone);
  9896. if (zone->xfr_acl != NULL)
  9897. dns_acl_detach(&zone->xfr_acl);
  9898. UNLOCK_ZONE(zone);
  9899. }
  9900. isc_boolean_t
  9901. dns_zone_getupdatedisabled(dns_zone_t *zone) {
  9902. REQUIRE(DNS_ZONE_VALID(zone));
  9903. return (zone->update_disabled);
  9904. }
  9905. void
  9906. dns_zone_setupdatedisabled(dns_zone_t *zone, isc_boolean_t state) {
  9907. REQUIRE(DNS_ZONE_VALID(zone));
  9908. zone->update_disabled = state;
  9909. }
  9910. isc_boolean_t
  9911. dns_zone_getzeronosoattl(dns_zone_t *zone) {
  9912. REQUIRE(DNS_ZONE_VALID(zone));
  9913. return (zone->zero_no_soa_ttl);
  9914. }
  9915. void
  9916. dns_zone_setzeronosoattl(dns_zone_t *zone, isc_boolean_t state) {
  9917. REQUIRE(DNS_ZONE_VALID(zone));
  9918. zone->zero_no_soa_ttl = state;
  9919. }
  9920. void
  9921. dns_zone_setchecknames(dns_zone_t *zone, dns_severity_t severity) {
  9922. REQUIRE(DNS_ZONE_VALID(zone));
  9923. zone->check_names = severity;
  9924. }
  9925. dns_severity_t
  9926. dns_zone_getchecknames(dns_zone_t *zone) {
  9927. REQUIRE(DNS_ZONE_VALID(zone));
  9928. return (zone->check_names);
  9929. }
  9930. void
  9931. dns_zone_setjournalsize(dns_zone_t *zone, isc_int32_t size) {
  9932. REQUIRE(DNS_ZONE_VALID(zone));
  9933. zone->journalsize = size;
  9934. }
  9935. isc_int32_t
  9936. dns_zone_getjournalsize(dns_zone_t *zone) {
  9937. REQUIRE(DNS_ZONE_VALID(zone));
  9938. return (zone->journalsize);
  9939. }
  9940. static void
  9941. zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length) {
  9942. isc_result_t result = ISC_R_FAILURE;
  9943. isc_buffer_t buffer;
  9944. REQUIRE(buf != NULL);
  9945. REQUIRE(length > 1U);
  9946. /*
  9947. * Leave space for terminating '\0'.
  9948. */
  9949. isc_buffer_init(&buffer, buf, length - 1);
  9950. if (dns_name_dynamic(&zone->origin))
  9951. result = dns_name_totext(&zone->origin, ISC_TRUE, &buffer);
  9952. if (result != ISC_R_SUCCESS &&
  9953. isc_buffer_availablelength(&buffer) >= (sizeof("<UNKNOWN>") - 1))
  9954. isc_buffer_putstr(&buffer, "<UNKNOWN>");
  9955. if (isc_buffer_availablelength(&buffer) > 0)
  9956. isc_buffer_putstr(&buffer, "/");
  9957. (void)dns_rdataclass_totext(zone->rdclass, &buffer);
  9958. if (zone->view != NULL && strcmp(zone->view->name, "_bind") != 0 &&
  9959. strcmp(zone->view->name, "_default") != 0 &&
  9960. strlen(zone->view->name) < isc_buffer_availablelength(&buffer)) {
  9961. isc_buffer_putstr(&buffer, "/");
  9962. isc_buffer_putstr(&buffer, zone->view->name);
  9963. }
  9964. buf[isc_buffer_usedlength(&buffer)] = '\0';
  9965. }
  9966. static void
  9967. zone_name_tostr(dns_zone_t *zone, char *buf, size_t length) {
  9968. isc_result_t result = ISC_R_FAILURE;
  9969. isc_buffer_t buffer;
  9970. REQUIRE(buf != NULL);
  9971. REQUIRE(length > 1U);
  9972. /*
  9973. * Leave space for terminating '\0'.
  9974. */
  9975. isc_buffer_init(&buffer, buf, length - 1);
  9976. if (dns_name_dynamic(&zone->origin))
  9977. result = dns_name_totext(&zone->origin, ISC_TRUE, &buffer);
  9978. if (result != ISC_R_SUCCESS &&
  9979. isc_buffer_availablelength(&buffer) >= (sizeof("<UNKNOWN>") - 1))
  9980. isc_buffer_putstr(&buffer, "<UNKNOWN>");
  9981. buf[isc_buffer_usedlength(&buffer)] = '\0';
  9982. }
  9983. static void
  9984. zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length) {
  9985. isc_buffer_t buffer;
  9986. REQUIRE(buf != NULL);
  9987. REQUIRE(length > 1U);
  9988. /*
  9989. * Leave space for terminating '\0'.
  9990. */
  9991. isc_buffer_init(&buffer, buf, length - 1);
  9992. (void)dns_rdataclass_totext(zone->rdclass, &buffer);
  9993. buf[isc_buffer_usedlength(&buffer)] = '\0';
  9994. }
  9995. static void
  9996. zone_viewname_tostr(dns_zone_t *zone, char *buf, size_t length) {
  9997. isc_buffer_t buffer;
  9998. REQUIRE(buf != NULL);
  9999. REQUIRE(length > 1U);
  10000. /*
  10001. * Leave space for terminating '\0'.
  10002. */
  10003. isc_buffer_init(&buffer, buf, length - 1);
  10004. if (zone->view == NULL) {
  10005. isc_buffer_putstr(&buffer, "_none");
  10006. } else if (strlen(zone->view->name)
  10007. < isc_buffer_availablelength(&buffer)) {
  10008. isc_buffer_putstr(&buffer, zone->view->name);
  10009. } else {
  10010. isc_buffer_putstr(&buffer, "_toolong");
  10011. }
  10012. buf[isc_buffer_usedlength(&buffer)] = '\0';
  10013. }
  10014. void
  10015. dns_zone_name(dns_zone_t *zone, char *buf, size_t length) {
  10016. REQUIRE(DNS_ZONE_VALID(zone));
  10017. REQUIRE(buf != NULL);
  10018. zone_namerd_tostr(zone, buf, length);
  10019. }
  10020. static void
  10021. notify_log(dns_zone_t *zone, int level, const char *fmt, ...) {
  10022. va_list ap;
  10023. char message[4096];
  10024. if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
  10025. return;
  10026. va_start(ap, fmt);
  10027. vsnprintf(message, sizeof(message), fmt, ap);
  10028. va_end(ap);
  10029. isc_log_write(dns_lctx, DNS_LOGCATEGORY_NOTIFY, DNS_LOGMODULE_ZONE,
  10030. level, "zone %s: %s", zone->strnamerd, message);
  10031. }
  10032. void
  10033. dns_zone_logc(dns_zone_t *zone, isc_logcategory_t *category,
  10034. int level, const char *fmt, ...) {
  10035. va_list ap;
  10036. char message[4096];
  10037. if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
  10038. return;
  10039. va_start(ap, fmt);
  10040. vsnprintf(message, sizeof(message), fmt, ap);
  10041. va_end(ap);
  10042. isc_log_write(dns_lctx, category, DNS_LOGMODULE_ZONE,
  10043. level, "%s %s: %s", (zone->type == dns_zone_key) ?
  10044. "managed-keys-zone" : "zone", zone->strnamerd, message);
  10045. }
  10046. void
  10047. dns_zone_log(dns_zone_t *zone, int level, const char *fmt, ...) {
  10048. va_list ap;
  10049. char message[4096];
  10050. if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
  10051. return;
  10052. va_start(ap, fmt);
  10053. vsnprintf(message, sizeof(message), fmt, ap);
  10054. va_end(ap);
  10055. isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE,
  10056. level, "%s %s: %s", (zone->type == dns_zone_key) ?
  10057. "managed-keys-zone" : "zone", zone->strnamerd, message);
  10058. }
  10059. static void
  10060. zone_debuglog(dns_zone_t *zone, const char *me, int debuglevel,
  10061. const char *fmt, ...)
  10062. {
  10063. va_list ap;
  10064. char message[4096];
  10065. int level = ISC_LOG_DEBUG(debuglevel);
  10066. if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
  10067. return;
  10068. va_start(ap, fmt);
  10069. vsnprintf(message, sizeof(message), fmt, ap);
  10070. va_end(ap);
  10071. isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE,
  10072. level, "%s: %s %s: %s", me, zone->type != dns_zone_key ?
  10073. "zone" : "managed-keys-zone", zone->strnamerd, message);
  10074. }
  10075. static int
  10076. message_count(dns_message_t *msg, dns_section_t section, dns_rdatatype_t type)
  10077. {
  10078. isc_result_t result;
  10079. dns_name_t *name;
  10080. dns_rdataset_t *curr;
  10081. int count = 0;
  10082. result = dns_message_firstname(msg, section);
  10083. while (result == ISC_R_SUCCESS) {
  10084. name = NULL;
  10085. dns_message_currentname(msg, section, &name);
  10086. for (curr = ISC_LIST_TAIL(name->list); curr != NULL;
  10087. curr = ISC_LIST_PREV(curr, link)) {
  10088. if (curr->type == type)
  10089. count++;
  10090. }
  10091. result = dns_message_nextname(msg, section);
  10092. }
  10093. return (count);
  10094. }
  10095. void
  10096. dns_zone_setmaxxfrin(dns_zone_t *zone, isc_uint32_t maxxfrin) {
  10097. REQUIRE(DNS_ZONE_VALID(zone));
  10098. zone->maxxfrin = maxxfrin;
  10099. }
  10100. isc_uint32_t
  10101. dns_zone_getmaxxfrin(dns_zone_t *zone) {
  10102. REQUIRE(DNS_ZONE_VALID(zone));
  10103. return (zone->maxxfrin);
  10104. }
  10105. void
  10106. dns_zone_setmaxxfrout(dns_zone_t *zone, isc_uint32_t maxxfrout) {
  10107. REQUIRE(DNS_ZONE_VALID(zone));
  10108. zone->maxxfrout = maxxfrout;
  10109. }
  10110. isc_uint32_t
  10111. dns_zone_getmaxxfrout(dns_zone_t *zone) {
  10112. REQUIRE(DNS_ZONE_VALID(zone));
  10113. return (zone->maxxfrout);
  10114. }
  10115. dns_zonetype_t
  10116. dns_zone_gettype(dns_zone_t *zone) {
  10117. REQUIRE(DNS_ZONE_VALID(zone));
  10118. return (zone->type);
  10119. }
  10120. dns_name_t *
  10121. dns_zone_getorigin(dns_zone_t *zone) {
  10122. REQUIRE(DNS_ZONE_VALID(zone));
  10123. return (&zone->origin);
  10124. }
  10125. void
  10126. dns_zone_settask(dns_zone_t *zone, isc_task_t *task) {
  10127. REQUIRE(DNS_ZONE_VALID(zone));
  10128. LOCK_ZONE(zone);
  10129. if (zone->task != NULL)
  10130. isc_task_detach(&zone->task);
  10131. isc_task_attach(task, &zone->task);
  10132. ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
  10133. if (zone->db != NULL)
  10134. dns_db_settask(zone->db, zone->task);
  10135. ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
  10136. UNLOCK_ZONE(zone);
  10137. }
  10138. void
  10139. dns_zone_gettask(dns_zone_t *zone, isc_task_t **target) {
  10140. REQUIRE(DNS_ZONE_VALID(zone));
  10141. isc_task_attach(zone->task, target);
  10142. }
  10143. void
  10144. dns_zone_setidlein(dns_zone_t *zone, isc_uint32_t idlein) {
  10145. REQUIRE(DNS_ZONE_VALID(zone));
  10146. if (idlein == 0)
  10147. idlein = DNS_DEFAULT_IDLEIN;
  10148. zone->idlein = idlein;
  10149. }
  10150. isc_uint32_t
  10151. dns_zone_getidlein(dns_zone_t *zone) {
  10152. REQUIRE(DNS_ZONE_VALID(zone));
  10153. return (zone->idlein);
  10154. }
  10155. void
  10156. dns_zone_setidleout(dns_zone_t *zone, isc_uint32_t idleout) {
  10157. REQUIRE(DNS_ZONE_VALID(zone));
  10158. zone->idleout = idleout;
  10159. }
  10160. isc_uint32_t
  10161. dns_zone_getidleout(dns_zone_t *zone) {
  10162. REQUIRE(DNS_ZONE_VALID(zone));
  10163. return (zone->idleout);
  10164. }
  10165. static void
  10166. notify_done(isc_task_t *task, isc_event_t *event) {
  10167. dns_requestevent_t *revent = (dns_requestevent_t *)event;
  10168. dns_notify_t *notify;
  10169. isc_result_t result;
  10170. dns_message_t *message = NULL;
  10171. isc_buffer_t buf;
  10172. char rcode[128];
  10173. char addrbuf[ISC_SOCKADDR_FORMATSIZE];
  10174. UNUSED(task);
  10175. notify = event->ev_arg;
  10176. REQUIRE(DNS_NOTIFY_VALID(notify));
  10177. INSIST(task == notify->zone->task);
  10178. isc_buffer_init(&buf, rcode, sizeof(rcode));
  10179. isc_sockaddr_format(&notify->dst, addrbuf, sizeof(addrbuf));
  10180. result = revent->result;
  10181. if (result == ISC_R_SUCCESS)
  10182. result = dns_message_create(notify->zone->mctx,
  10183. DNS_MESSAGE_INTENTPARSE, &message);
  10184. if (result == ISC_R_SUCCESS)
  10185. result = dns_request_getresponse(revent->request, message,
  10186. DNS_MESSAGEPARSE_PRESERVEORDER);
  10187. if (result == ISC_R_SUCCESS)
  10188. result = dns_rcode_totext(message->rcode, &buf);
  10189. if (result == ISC_R_SUCCESS)
  10190. notify_log(notify->zone, ISC_LOG_DEBUG(3),
  10191. "notify response from %s: %.*s",
  10192. addrbuf, (int)buf.used, rcode);
  10193. else
  10194. notify_log(notify->zone, ISC_LOG_DEBUG(2),
  10195. "notify to %s failed: %s", addrbuf,
  10196. dns_result_totext(result));
  10197. /*
  10198. * Old bind's return formerr if they see a soa record. Retry w/o
  10199. * the soa if we see a formerr and had sent a SOA.
  10200. */
  10201. isc_event_free(&event);
  10202. if (message != NULL && message->rcode == dns_rcode_formerr &&
  10203. (notify->flags & DNS_NOTIFY_NOSOA) == 0) {
  10204. notify->flags |= DNS_NOTIFY_NOSOA;
  10205. dns_request_destroy(&notify->request);
  10206. result = notify_send_queue(notify);
  10207. if (result != ISC_R_SUCCESS)
  10208. notify_destroy(notify, ISC_FALSE);
  10209. } else {
  10210. if (result == ISC_R_TIMEDOUT)
  10211. notify_log(notify->zone, ISC_LOG_DEBUG(1),
  10212. "notify to %s: retries exceeded", addrbuf);
  10213. notify_destroy(notify, ISC_FALSE);
  10214. }
  10215. if (message != NULL)
  10216. dns_message_destroy(&message);
  10217. }
  10218. isc_result_t
  10219. dns_zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) {
  10220. isc_result_t result;
  10221. REQUIRE(DNS_ZONE_VALID(zone));
  10222. LOCK_ZONE(zone);
  10223. ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
  10224. result = zone_replacedb(zone, db, dump);
  10225. ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
  10226. UNLOCK_ZONE(zone);
  10227. return (result);
  10228. }
  10229. static isc_result_t
  10230. zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) {
  10231. dns_dbversion_t *ver;
  10232. isc_result_t result;
  10233. unsigned int soacount = 0;
  10234. unsigned int nscount = 0;
  10235. /*
  10236. * 'zone' and 'zonedb' locked by caller.
  10237. */
  10238. REQUIRE(DNS_ZONE_VALID(zone));
  10239. REQUIRE(LOCKED_ZONE(zone));
  10240. result = zone_get_from_db(zone, db, &nscount, &soacount,
  10241. NULL, NULL, NULL, NULL, NULL, NULL);
  10242. if (result == ISC_R_SUCCESS) {
  10243. if (soacount != 1) {
  10244. dns_zone_log(zone, ISC_LOG_ERROR,
  10245. "has %d SOA records", soacount);
  10246. result = DNS_R_BADZONE;
  10247. }
  10248. if (nscount == 0 && zone->type != dns_zone_key) {
  10249. dns_zone_log(zone, ISC_LOG_ERROR, "has no NS records");
  10250. result = DNS_R_BADZONE;
  10251. }
  10252. if (result != ISC_R_SUCCESS)
  10253. return (result);
  10254. } else {
  10255. dns_zone_log(zone, ISC_LOG_ERROR,
  10256. "retrieving SOA and NS records failed: %s",
  10257. dns_result_totext(result));
  10258. return (result);
  10259. }
  10260. result = check_nsec3param(zone, db);
  10261. if (result != ISC_R_SUCCESS)
  10262. return (result);
  10263. ver = NULL;
  10264. dns_db_currentversion(db, &ver);
  10265. /*
  10266. * The initial version of a slave zone is always dumped;
  10267. * subsequent versions may be journaled instead if this
  10268. * is enabled in the configuration.
  10269. */
  10270. if (zone->db != NULL && zone->journal != NULL &&
  10271. DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) &&
  10272. !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) {
  10273. isc_uint32_t serial, oldserial;
  10274. dns_zone_log(zone, ISC_LOG_DEBUG(3), "generating diffs");
  10275. result = dns_db_getsoaserial(db, ver, &serial);
  10276. if (result != ISC_R_SUCCESS) {
  10277. dns_zone_log(zone, ISC_LOG_ERROR,
  10278. "ixfr-from-differences: unable to get "
  10279. "new serial");
  10280. goto fail;
  10281. }
  10282. /*
  10283. * This is checked in zone_postload() for master zones.
  10284. */
  10285. result = zone_get_from_db(zone, zone->db, NULL, NULL,
  10286. &oldserial, NULL, NULL, NULL, NULL,
  10287. NULL);
  10288. RUNTIME_CHECK(result == ISC_R_SUCCESS);
  10289. if (zone->type == dns_zone_slave &&
  10290. !isc_serial_gt(serial, oldserial)) {
  10291. isc_uint32_t serialmin, serialmax;
  10292. serialmin = (oldserial + 1) & 0xffffffffU;
  10293. serialmax = (oldserial + 0x7fffffffU) & 0xffffffffU;
  10294. dns_zone_log(zone, ISC_LOG_ERROR,
  10295. "ixfr-from-differences: failed: "
  10296. "new serial (%u) out of range [%u - %u]",
  10297. serial, serialmin, serialmax);
  10298. result = ISC_R_RANGE;
  10299. goto fail;
  10300. }
  10301. result = dns_db_diff(zone->mctx, db, ver, zone->db, NULL,
  10302. zone->journal);
  10303. if (result != ISC_R_SUCCESS)
  10304. goto fail;
  10305. if (dump)
  10306. zone_needdump(zone, DNS_DUMP_DELAY);
  10307. else if (zone->journalsize != -1) {
  10308. result = dns_journal_compact(zone->mctx, zone->journal,
  10309. serial, zone->journalsize);
  10310. switch (result) {
  10311. case ISC_R_SUCCESS:
  10312. case ISC_R_NOSPACE:
  10313. case ISC_R_NOTFOUND:
  10314. dns_zone_log(zone, ISC_LOG_DEBUG(3),
  10315. "dns_journal_compact: %s",
  10316. dns_result_totext(result));
  10317. break;
  10318. default:
  10319. dns_zone_log(zone, ISC_LOG_ERROR,
  10320. "dns_journal_compact failed: %s",
  10321. dns_result_totext(result));
  10322. break;
  10323. }
  10324. }
  10325. } else {
  10326. if (dump && zone->masterfile != NULL) {
  10327. /*
  10328. * If DNS_ZONEFLG_FORCEXFER was set we don't want
  10329. * to keep the old masterfile.
  10330. */
  10331. if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) &&
  10332. remove(zone->masterfile) < 0 && errno != ENOENT) {
  10333. char strbuf[ISC_STRERRORSIZE];
  10334. isc__strerror(errno, strbuf, sizeof(strbuf));
  10335. isc_log_write(dns_lctx,
  10336. DNS_LOGCATEGORY_GENERAL,
  10337. DNS_LOGMODULE_ZONE,
  10338. ISC_LOG_WARNING,
  10339. "unable to remove masterfile "
  10340. "'%s': '%s'",
  10341. zone->masterfile, strbuf);
  10342. }
  10343. if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0)
  10344. DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NODELAY);
  10345. else
  10346. zone_needdump(zone, 0);
  10347. }
  10348. if (dump && zone->journal != NULL) {
  10349. /*
  10350. * The in-memory database just changed, and
  10351. * because 'dump' is set, it didn't change by
  10352. * being loaded from disk. Also, we have not
  10353. * journaled diffs for this change.
  10354. * Therefore, the on-disk journal is missing
  10355. * the deltas for this change. Since it can
  10356. * no longer be used to bring the zone
  10357. * up-to-date, it is useless and should be
  10358. * removed.
  10359. */
  10360. isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
  10361. DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
  10362. "removing journal file");
  10363. if (remove(zone->journal) < 0 && errno != ENOENT) {
  10364. char strbuf[ISC_STRERRORSIZE];
  10365. isc__strerror(errno, strbuf, sizeof(strbuf));
  10366. isc_log_write(dns_lctx,
  10367. DNS_LOGCATEGORY_GENERAL,
  10368. DNS_LOGMODULE_ZONE,
  10369. ISC_LOG_WARNING,
  10370. "unable to remove journal "
  10371. "'%s': '%s'",
  10372. zone->journal, strbuf);
  10373. }
  10374. }
  10375. }
  10376. dns_db_closeversion(db, &ver, ISC_FALSE);
  10377. isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
  10378. DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
  10379. "replacing zone database");
  10380. if (zone->db != NULL)
  10381. zone_detachdb(zone);
  10382. zone_attachdb(zone, db);
  10383. dns_db_settask(zone->db, zone->task);
  10384. DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED|DNS_ZONEFLG_NEEDNOTIFY);
  10385. return (ISC_R_SUCCESS);
  10386. fail:
  10387. dns_db_closeversion(db, &ver, ISC_FALSE);
  10388. return (result);
  10389. }
  10390. /* The caller must hold the dblock as a writer. */
  10391. static inline void
  10392. zone_attachdb(dns_zone_t *zone, dns_db_t *db) {
  10393. REQUIRE(zone->db == NULL && db != NULL);
  10394. dns_db_attach(db, &zone->db);
  10395. if (zone->acache != NULL) {
  10396. isc_result_t result;
  10397. result = dns_acache_setdb(zone->acache, db);
  10398. if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) {
  10399. UNEXPECTED_ERROR(__FILE__, __LINE__,
  10400. "dns_acache_setdb() failed: %s",
  10401. isc_result_totext(result));
  10402. }
  10403. }
  10404. }
  10405. /* The caller must hold the dblock as a writer. */
  10406. static inline void
  10407. zone_detachdb(dns_zone_t *zone) {
  10408. REQUIRE(zone->db != NULL);
  10409. if (zone->acache != NULL)
  10410. (void)dns_acache_putdb(zone->acache, zone->db);
  10411. dns_db_detach(&zone->db);
  10412. }
  10413. static void
  10414. zone_xfrdone(dns_zone_t *zone, isc_result_t result) {
  10415. isc_time_t now;
  10416. isc_boolean_t again = ISC_FALSE;
  10417. unsigned int soacount;
  10418. unsigned int nscount;
  10419. isc_uint32_t serial, refresh, retry, expire, minimum;
  10420. isc_result_t xfrresult = result;
  10421. isc_boolean_t free_needed;
  10422. REQUIRE(DNS_ZONE_VALID(zone));
  10423. dns_zone_log(zone, ISC_LOG_DEBUG(1),
  10424. "zone transfer finished: %s", dns_result_totext(result));
  10425. LOCK_ZONE(zone);
  10426. INSIST((zone->flags & DNS_ZONEFLG_REFRESH) != 0);
  10427. DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
  10428. DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR);
  10429. TIME_NOW(&now);
  10430. switch (result) {
  10431. case ISC_R_SUCCESS:
  10432. DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
  10433. /*FALLTHROUGH*/
  10434. case DNS_R_UPTODATE:
  10435. DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FORCEXFER);
  10436. /*
  10437. * Has the zone expired underneath us?
  10438. */
  10439. ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
  10440. if (zone->db == NULL) {
  10441. ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
  10442. goto same_master;
  10443. }
  10444. /*
  10445. * Update the zone structure's data from the actual
  10446. * SOA received.
  10447. */
  10448. nscount = 0;
  10449. soacount = 0;
  10450. INSIST(zone->db != NULL);
  10451. result = zone_get_from_db(zone, zone->db, &nscount,
  10452. &soacount, &serial, &refresh,
  10453. &retry, &expire, &minimum, NULL);
  10454. ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
  10455. if (result == ISC_R_SUCCESS) {
  10456. if (soacount != 1)
  10457. dns_zone_log(zone, ISC_LOG_ERROR,
  10458. "transferred zone "
  10459. "has %d SOA record%s", soacount,
  10460. (soacount != 0) ? "s" : "");
  10461. if (nscount == 0) {
  10462. dns_zone_log(zone, ISC_LOG_ERROR,
  10463. "transferred zone "
  10464. "has no NS records");
  10465. if (DNS_ZONE_FLAG(zone,
  10466. DNS_ZONEFLG_HAVETIMERS)) {
  10467. zone->refresh = DNS_ZONE_DEFAULTREFRESH;
  10468. zone->retry = DNS_ZONE_DEFAULTRETRY;
  10469. }
  10470. DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
  10471. zone_unload(zone);
  10472. goto next_master;
  10473. }
  10474. zone->refresh = RANGE(refresh, zone->minrefresh,
  10475. zone->maxrefresh);
  10476. zone->retry = RANGE(retry, zone->minretry,
  10477. zone->maxretry);
  10478. zone->expire = RANGE(expire,
  10479. zone->refresh + zone->retry,
  10480. DNS_MAX_EXPIRE);
  10481. zone->minimum = minimum;
  10482. DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
  10483. }
  10484. /*
  10485. * Set our next update/expire times.
  10486. */
  10487. if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) {
  10488. DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
  10489. zone->refreshtime = now;
  10490. DNS_ZONE_TIME_ADD(&now, zone->expire,
  10491. &zone->expiretime);
  10492. } else {
  10493. DNS_ZONE_JITTER_ADD(&now, zone->refresh,
  10494. &zone->refreshtime);
  10495. DNS_ZONE_TIME_ADD(&now, zone->expire,
  10496. &zone->expiretime);
  10497. }
  10498. if (result == ISC_R_SUCCESS && xfrresult == ISC_R_SUCCESS) {
  10499. char buf[DNS_NAME_FORMATSIZE + sizeof(": TSIG ''")];
  10500. if (zone->tsigkey != NULL) {
  10501. char namebuf[DNS_NAME_FORMATSIZE];
  10502. dns_name_format(&zone->tsigkey->name, namebuf,
  10503. sizeof(namebuf));
  10504. snprintf(buf, sizeof(buf), ": TSIG '%s'",
  10505. namebuf);
  10506. } else
  10507. buf[0] = '\0';
  10508. dns_zone_log(zone, ISC_LOG_INFO,
  10509. "transferred serial %u%s",
  10510. serial, buf);
  10511. }
  10512. /*
  10513. * This is not necessary if we just performed a AXFR
  10514. * however it is necessary for an IXFR / UPTODATE and
  10515. * won't hurt with an AXFR.
  10516. */
  10517. if (zone->masterfile != NULL || zone->journal != NULL) {
  10518. result = ISC_R_FAILURE;
  10519. if (zone->journal != NULL)
  10520. result = isc_file_settime(zone->journal, &now);
  10521. if (result != ISC_R_SUCCESS &&
  10522. zone->masterfile != NULL)
  10523. result = isc_file_settime(zone->masterfile,
  10524. &now);
  10525. /* Someone removed the file from underneath us! */
  10526. if (result == ISC_R_FILENOTFOUND &&
  10527. zone->masterfile != NULL) {
  10528. unsigned int delay = DNS_DUMP_DELAY;
  10529. if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NODELAY))
  10530. delay = 0;
  10531. zone_needdump(zone, delay);
  10532. } else if (result != ISC_R_SUCCESS)
  10533. dns_zone_log(zone, ISC_LOG_ERROR,
  10534. "transfer: could not set file "
  10535. "modification time of '%s': %s",
  10536. zone->masterfile,
  10537. dns_result_totext(result));
  10538. }
  10539. DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NODELAY);
  10540. inc_stats(zone, dns_zonestatscounter_xfrsuccess);
  10541. break;
  10542. case DNS_R_BADIXFR:
  10543. /* Force retry with AXFR. */
  10544. DNS_ZONE_SETFLAG(zone, DNS_ZONEFLAG_NOIXFR);
  10545. goto same_master;
  10546. default:
  10547. next_master:
  10548. /*
  10549. * Skip to next failed / untried master.
  10550. */
  10551. do {
  10552. zone->curmaster++;
  10553. } while (zone->curmaster < zone->masterscnt &&
  10554. zone->mastersok[zone->curmaster]);
  10555. /* FALLTHROUGH */
  10556. same_master:
  10557. if (zone->curmaster >= zone->masterscnt) {
  10558. zone->curmaster = 0;
  10559. if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
  10560. !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
  10561. DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
  10562. DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
  10563. while (zone->curmaster < zone->masterscnt &&
  10564. zone->mastersok[zone->curmaster])
  10565. zone->curmaster++;
  10566. again = ISC_TRUE;
  10567. } else
  10568. DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
  10569. } else {
  10570. DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
  10571. again = ISC_TRUE;
  10572. }
  10573. inc_stats(zone, dns_zonestatscounter_xfrfail);
  10574. break;
  10575. }
  10576. zone_settimer(zone, &now);
  10577. /*
  10578. * If creating the transfer object failed, zone->xfr is NULL.
  10579. * Otherwise, we are called as the done callback of a zone
  10580. * transfer object that just entered its shutting-down
  10581. * state. Since we are no longer responsible for shutting
  10582. * it down, we can detach our reference.
  10583. */
  10584. if (zone->xfr != NULL)
  10585. dns_xfrin_detach(&zone->xfr);
  10586. if (zone->tsigkey != NULL)
  10587. dns_tsigkey_detach(&zone->tsigkey);
  10588. /*
  10589. * Handle any deferred journal compaction.
  10590. */
  10591. if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDCOMPACT)) {
  10592. result = dns_journal_compact(zone->mctx, zone->journal,
  10593. zone->compact_serial,
  10594. zone->journalsize);
  10595. switch (result) {
  10596. case ISC_R_SUCCESS:
  10597. case ISC_R_NOSPACE:
  10598. case ISC_R_NOTFOUND:
  10599. dns_zone_log(zone, ISC_LOG_DEBUG(3),
  10600. "dns_journal_compact: %s",
  10601. dns_result_totext(result));
  10602. break;
  10603. default:
  10604. dns_zone_log(zone, ISC_LOG_ERROR,
  10605. "dns_journal_compact failed: %s",
  10606. dns_result_totext(result));
  10607. break;
  10608. }
  10609. DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT);
  10610. }
  10611. /*
  10612. * This transfer finishing freed up a transfer quota slot.
  10613. * Let any other zones waiting for quota have it.
  10614. */
  10615. UNLOCK_ZONE(zone);
  10616. RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
  10617. ISC_LIST_UNLINK(zone->zmgr->xfrin_in_progress, zone, statelink);
  10618. zone->statelist = NULL;
  10619. zmgr_resume_xfrs(zone->zmgr, ISC_FALSE);
  10620. RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
  10621. LOCK_ZONE(zone);
  10622. /*
  10623. * Retry with a different server if necessary.
  10624. */
  10625. if (again && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
  10626. queue_soa_query(zone);
  10627. INSIST(zone->irefs > 0);
  10628. zone->irefs--;
  10629. free_needed = exit_check(zone);
  10630. UNLOCK_ZONE(zone);
  10631. if (free_needed)
  10632. zone_free(zone);
  10633. }
  10634. static void
  10635. zone_loaddone(void *arg, isc_result_t result) {
  10636. static char me[] = "zone_loaddone";
  10637. dns_load_t *load = arg;
  10638. dns_zone_t *zone;
  10639. isc_result_t tresult;
  10640. REQUIRE(DNS_LOAD_VALID(load));
  10641. zone = load->zone;
  10642. ENTER;
  10643. tresult = dns_db_endload(load->db, &load->callbacks.add_private);
  10644. if (tresult != ISC_R_SUCCESS &&
  10645. (result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE))
  10646. result = tresult;
  10647. LOCK_ZONE(load->zone);
  10648. (void)zone_postload(load->zone, load->db, load->loadtime, result);
  10649. zonemgr_putio(&load->zone->readio);
  10650. DNS_ZONE_CLRFLAG(load->zone, DNS_ZONEFLG_LOADING);
  10651. /*
  10652. * Leave the zone frozen if the reload fails.
  10653. */
  10654. if ((result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE) &&
  10655. DNS_ZONE_FLAG(load->zone, DNS_ZONEFLG_THAW))
  10656. zone->update_disabled = ISC_FALSE;
  10657. DNS_ZONE_CLRFLAG(load->zone, DNS_ZONEFLG_THAW);
  10658. UNLOCK_ZONE(load->zone);
  10659. load->magic = 0;
  10660. dns_db_detach(&load->db);
  10661. if (load->zone->lctx != NULL)
  10662. dns_loadctx_detach(&load->zone->lctx);
  10663. dns_zone_idetach(&load->zone);
  10664. isc_mem_putanddetach(&load->mctx, load, sizeof(*load));
  10665. }
  10666. void
  10667. dns_zone_getssutable(dns_zone_t *zone, dns_ssutable_t **table) {
  10668. REQUIRE(DNS_ZONE_VALID(zone));
  10669. REQUIRE(table != NULL);
  10670. REQUIRE(*table == NULL);
  10671. LOCK_ZONE(zone);
  10672. if (zone->ssutable != NULL)
  10673. dns_ssutable_attach(zone->ssutable, table);
  10674. UNLOCK_ZONE(zone);
  10675. }
  10676. void
  10677. dns_zone_setssutable(dns_zone_t *zone, dns_ssutable_t *table) {
  10678. REQUIRE(DNS_ZONE_VALID(zone));
  10679. LOCK_ZONE(zone);
  10680. if (zone->ssutable != NULL)
  10681. dns_ssutable_detach(&zone->ssutable);
  10682. if (table != NULL)
  10683. dns_ssutable_attach(table, &zone->ssutable);
  10684. UNLOCK_ZONE(zone);
  10685. }
  10686. void
  10687. dns_zone_setsigvalidityinterval(dns_zone_t *zone, isc_uint32_t interval) {
  10688. REQUIRE(DNS_ZONE_VALID(zone));
  10689. zone->sigvalidityinterval = interval;
  10690. }
  10691. isc_uint32_t
  10692. dns_zone_getsigvalidityinterval(dns_zone_t *zone) {
  10693. REQUIRE(DNS_ZONE_VALID(zone));
  10694. return (zone->sigvalidityinterval);
  10695. }
  10696. void
  10697. dns_zone_setsigresigninginterval(dns_zone_t *zone, isc_uint32_t interval) {
  10698. REQUIRE(DNS_ZONE_VALID(zone));
  10699. zone->sigresigninginterval = interval;
  10700. }
  10701. isc_uint32_t
  10702. dns_zone_getsigresigninginterval(dns_zone_t *zone) {
  10703. REQUIRE(DNS_ZONE_VALID(zone));
  10704. return (zone->sigresigninginterval);
  10705. }
  10706. static void
  10707. queue_xfrin(dns_zone_t *zone) {
  10708. const char me[] = "queue_xfrin";
  10709. isc_result_t result;
  10710. dns_zonemgr_t *zmgr = zone->zmgr;
  10711. ENTER;
  10712. INSIST(zone->statelist == NULL);
  10713. RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
  10714. ISC_LIST_APPEND(zmgr->waiting_for_xfrin, zone, statelink);
  10715. LOCK_ZONE(zone);
  10716. zone->irefs++;
  10717. UNLOCK_ZONE(zone);
  10718. zone->statelist = &zmgr->waiting_for_xfrin;
  10719. result = zmgr_start_xfrin_ifquota(zmgr, zone);
  10720. RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
  10721. if (result == ISC_R_QUOTA) {
  10722. dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO,
  10723. "zone transfer deferred due to quota");
  10724. } else if (result != ISC_R_SUCCESS) {
  10725. dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_ERROR,
  10726. "starting zone transfer: %s",
  10727. isc_result_totext(result));
  10728. }
  10729. }
  10730. /*
  10731. * This event callback is called when a zone has received
  10732. * any necessary zone transfer quota. This is the time
  10733. * to go ahead and start the transfer.
  10734. */
  10735. static void
  10736. got_transfer_quota(isc_task_t *task, isc_event_t *event) {
  10737. isc_result_t result;
  10738. dns_peer_t *peer = NULL;
  10739. char master[ISC_SOCKADDR_FORMATSIZE];
  10740. char source[ISC_SOCKADDR_FORMATSIZE];
  10741. dns_rdatatype_t xfrtype;
  10742. dns_zone_t *zone = event->ev_arg;
  10743. isc_netaddr_t masterip;
  10744. isc_sockaddr_t sourceaddr;
  10745. isc_sockaddr_t masteraddr;
  10746. isc_time_t now;
  10747. const char *soa_before = "";
  10748. UNUSED(task);
  10749. INSIST(task == zone->task);
  10750. if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
  10751. result = ISC_R_CANCELED;
  10752. goto cleanup;
  10753. }
  10754. TIME_NOW(&now);
  10755. isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
  10756. if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr,
  10757. &zone->sourceaddr, &now))
  10758. {
  10759. isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
  10760. dns_zone_log(zone, ISC_LOG_INFO,
  10761. "got_transfer_quota: skipping zone transfer as "
  10762. "master %s (source %s) is unreachable (cached)",
  10763. master, source);
  10764. result = ISC_R_CANCELED;
  10765. goto cleanup;
  10766. }
  10767. isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
  10768. (void)dns_peerlist_peerbyaddr(zone->view->peers, &masterip, &peer);
  10769. if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR))
  10770. soa_before = "SOA before ";
  10771. /*
  10772. * Decide whether we should request IXFR or AXFR.
  10773. */
  10774. if (zone->db == NULL) {
  10775. dns_zone_log(zone, ISC_LOG_DEBUG(1),
  10776. "no database exists yet, requesting AXFR of "
  10777. "initial version from %s", master);
  10778. xfrtype = dns_rdatatype_axfr;
  10779. } else if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS)) {
  10780. dns_zone_log(zone, ISC_LOG_DEBUG(1), "ixfr-from-differences "
  10781. "set, requesting %sAXFR from %s", soa_before,
  10782. master);
  10783. if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR))
  10784. xfrtype = dns_rdatatype_soa;
  10785. else
  10786. xfrtype = dns_rdatatype_axfr;
  10787. } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) {
  10788. dns_zone_log(zone, ISC_LOG_DEBUG(1),
  10789. "forced reload, requesting AXFR of "
  10790. "initial version from %s", master);
  10791. xfrtype = dns_rdatatype_axfr;
  10792. } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLAG_NOIXFR)) {
  10793. dns_zone_log(zone, ISC_LOG_DEBUG(1),
  10794. "retrying with AXFR from %s due to "
  10795. "previous IXFR failure", master);
  10796. xfrtype = dns_rdatatype_axfr;
  10797. LOCK_ZONE(zone);
  10798. DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLAG_NOIXFR);
  10799. UNLOCK_ZONE(zone);
  10800. } else {
  10801. isc_boolean_t use_ixfr = ISC_TRUE;
  10802. if (peer != NULL &&
  10803. dns_peer_getrequestixfr(peer, &use_ixfr) ==
  10804. ISC_R_SUCCESS) {
  10805. ; /* Using peer setting */
  10806. } else {
  10807. use_ixfr = zone->view->requestixfr;
  10808. }
  10809. if (use_ixfr == ISC_FALSE) {
  10810. dns_zone_log(zone, ISC_LOG_DEBUG(1),
  10811. "IXFR disabled, requesting %sAXFR from %s",
  10812. soa_before, master);
  10813. if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR))
  10814. xfrtype = dns_rdatatype_soa;
  10815. else
  10816. xfrtype = dns_rdatatype_axfr;
  10817. } else {
  10818. dns_zone_log(zone, ISC_LOG_DEBUG(1),
  10819. "requesting IXFR from %s", master);
  10820. xfrtype = dns_rdatatype_ixfr;
  10821. }
  10822. }
  10823. /*
  10824. * Determine if we should attempt to sign the request with TSIG.
  10825. */
  10826. result = ISC_R_NOTFOUND;
  10827. /*
  10828. * First, look for a tsig key in the master statement, then
  10829. * try for a server key.
  10830. */
  10831. if ((zone->masterkeynames != NULL) &&
  10832. (zone->masterkeynames[zone->curmaster] != NULL)) {
  10833. dns_view_t *view = dns_zone_getview(zone);
  10834. dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
  10835. result = dns_view_gettsig(view, keyname, &zone->tsigkey);
  10836. }
  10837. if (zone->tsigkey == NULL)
  10838. result = dns_view_getpeertsig(zone->view, &masterip,
  10839. &zone->tsigkey);
  10840. if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
  10841. dns_zone_log(zone, ISC_LOG_ERROR,
  10842. "could not get TSIG key for zone transfer: %s",
  10843. isc_result_totext(result));
  10844. }
  10845. LOCK_ZONE(zone);
  10846. masteraddr = zone->masteraddr;
  10847. sourceaddr = zone->sourceaddr;
  10848. UNLOCK_ZONE(zone);
  10849. INSIST(isc_sockaddr_pf(&masteraddr) == isc_sockaddr_pf(&sourceaddr));
  10850. result = dns_xfrin_create2(zone, xfrtype, &masteraddr, &sourceaddr,
  10851. zone->tsigkey, zone->mctx,
  10852. zone->zmgr->timermgr, zone->zmgr->socketmgr,
  10853. zone->task, zone_xfrdone, &zone->xfr);
  10854. if (result == ISC_R_SUCCESS) {
  10855. LOCK_ZONE(zone);
  10856. if (xfrtype == dns_rdatatype_axfr) {
  10857. if (isc_sockaddr_pf(&masteraddr) == PF_INET)
  10858. inc_stats(zone, dns_zonestatscounter_axfrreqv4);
  10859. else
  10860. inc_stats(zone, dns_zonestatscounter_axfrreqv6);
  10861. } else if (xfrtype == dns_rdatatype_ixfr) {
  10862. if (isc_sockaddr_pf(&masteraddr) == PF_INET)
  10863. inc_stats(zone, dns_zonestatscounter_ixfrreqv4);
  10864. else
  10865. inc_stats(zone, dns_zonestatscounter_ixfrreqv6);
  10866. }
  10867. UNLOCK_ZONE(zone);
  10868. }
  10869. cleanup:
  10870. /*
  10871. * Any failure in this function is handled like a failed
  10872. * zone transfer. This ensures that we get removed from
  10873. * zmgr->xfrin_in_progress.
  10874. */
  10875. if (result != ISC_R_SUCCESS)
  10876. zone_xfrdone(zone, result);
  10877. isc_event_free(&event);
  10878. }
  10879. /*
  10880. * Update forwarding support.
  10881. */
  10882. static void
  10883. forward_destroy(dns_forward_t *forward) {
  10884. forward->magic = 0;
  10885. if (forward->request != NULL)
  10886. dns_request_destroy(&forward->request);
  10887. if (forward->msgbuf != NULL)
  10888. isc_buffer_free(&forward->msgbuf);
  10889. if (forward->zone != NULL) {
  10890. LOCK(&forward->zone->lock);
  10891. if (ISC_LINK_LINKED(forward, link))
  10892. ISC_LIST_UNLINK(forward->zone->forwards, forward, link);
  10893. UNLOCK(&forward->zone->lock);
  10894. dns_zone_idetach(&forward->zone);
  10895. }
  10896. isc_mem_putanddetach(&forward->mctx, forward, sizeof(*forward));
  10897. }
  10898. static isc_result_t
  10899. sendtomaster(dns_forward_t *forward) {
  10900. isc_result_t result;
  10901. isc_sockaddr_t src;
  10902. LOCK_ZONE(forward->zone);
  10903. if (DNS_ZONE_FLAG(forward->zone, DNS_ZONEFLG_EXITING)) {
  10904. UNLOCK_ZONE(forward->zone);
  10905. return (ISC_R_CANCELED);
  10906. }
  10907. if (forward->which >= forward->zone->masterscnt) {
  10908. UNLOCK_ZONE(forward->zone);
  10909. return (ISC_R_NOMORE);
  10910. }
  10911. forward->addr = forward->zone->masters[forward->which];
  10912. /*
  10913. * Always use TCP regardless of whether the original update
  10914. * used TCP.
  10915. * XXX The timeout may but a bit small if we are far down a
  10916. * transfer graph and the master has to try several masters.
  10917. */
  10918. switch (isc_sockaddr_pf(&forward->addr)) {
  10919. case PF_INET:
  10920. src = forward->zone->xfrsource4;
  10921. break;
  10922. case PF_INET6:
  10923. src = forward->zone->xfrsource6;
  10924. break;
  10925. default:
  10926. result = ISC_R_NOTIMPLEMENTED;
  10927. goto unlock;
  10928. }
  10929. result = dns_request_createraw(forward->zone->view->requestmgr,
  10930. forward->msgbuf,
  10931. &src, &forward->addr,
  10932. DNS_REQUESTOPT_TCP, 15 /* XXX */,
  10933. forward->zone->task,
  10934. forward_callback, forward,
  10935. &forward->request);
  10936. if (result == ISC_R_SUCCESS) {
  10937. if (!ISC_LINK_LINKED(forward, link))
  10938. ISC_LIST_APPEND(forward->zone->forwards, forward, link);
  10939. }
  10940. unlock:
  10941. UNLOCK_ZONE(forward->zone);
  10942. return (result);
  10943. }
  10944. static void
  10945. forward_callback(isc_task_t *task, isc_event_t *event) {
  10946. const char me[] = "forward_callback";
  10947. dns_requestevent_t *revent = (dns_requestevent_t *)event;
  10948. dns_message_t *msg = NULL;
  10949. char master[ISC_SOCKADDR_FORMATSIZE];
  10950. isc_result_t result;
  10951. dns_forward_t *forward;
  10952. dns_zone_t *zone;
  10953. UNUSED(task);
  10954. forward = revent->ev_arg;
  10955. INSIST(DNS_FORWARD_VALID(forward));
  10956. zone = forward->zone;
  10957. INSIST(DNS_ZONE_VALID(zone));
  10958. ENTER;
  10959. isc_sockaddr_format(&forward->addr, master, sizeof(master));
  10960. if (revent->result != ISC_R_SUCCESS) {
  10961. dns_zone_log(zone, ISC_LOG_INFO,
  10962. "could not forward dynamic update to %s: %s",
  10963. master, dns_result_totext(revent->result));
  10964. goto next_master;
  10965. }
  10966. result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
  10967. if (result != ISC_R_SUCCESS)
  10968. goto next_master;
  10969. result = dns_request_getresponse(revent->request, msg,
  10970. DNS_MESSAGEPARSE_PRESERVEORDER |
  10971. DNS_MESSAGEPARSE_CLONEBUFFER);
  10972. if (result != ISC_R_SUCCESS)
  10973. goto next_master;
  10974. switch (msg->rcode) {
  10975. /*
  10976. * Pass these rcodes back to client.
  10977. */
  10978. case dns_rcode_noerror:
  10979. case dns_rcode_yxdomain:
  10980. case dns_rcode_yxrrset:
  10981. case dns_rcode_nxrrset:
  10982. case dns_rcode_refused:
  10983. case dns_rcode_nxdomain:
  10984. break;
  10985. /* These should not occur if the masters/zone are valid. */
  10986. case dns_rcode_notzone:
  10987. case dns_rcode_notauth: {
  10988. char rcode[128];
  10989. isc_buffer_t rb;
  10990. isc_buffer_init(&rb, rcode, sizeof(rcode));
  10991. (void)dns_rcode_totext(msg->rcode, &rb);
  10992. dns_zone_log(zone, ISC_LOG_WARNING,
  10993. "forwarding dynamic update: "
  10994. "unexpected response: master %s returned: %.*s",
  10995. master, (int)rb.used, rcode);
  10996. goto next_master;
  10997. }
  10998. /* Try another server for these rcodes. */
  10999. case dns_rcode_formerr:
  11000. case dns_rcode_servfail:
  11001. case dns_rcode_notimp:
  11002. case dns_rcode_badvers:
  11003. default:
  11004. goto next_master;
  11005. }
  11006. /* call callback */
  11007. (forward->callback)(forward->callback_arg, ISC_R_SUCCESS, msg);
  11008. msg = NULL;
  11009. dns_request_destroy(&forward->request);
  11010. forward_destroy(forward);
  11011. isc_event_free(&event);
  11012. return;
  11013. next_master:
  11014. if (msg != NULL)
  11015. dns_message_destroy(&msg);
  11016. isc_event_free(&event);
  11017. forward->which++;
  11018. dns_request_destroy(&forward->request);
  11019. result = sendtomaster(forward);
  11020. if (result != ISC_R_SUCCESS) {
  11021. /* call callback */
  11022. dns_zone_log(zone, ISC_LOG_DEBUG(3),
  11023. "exhausted dynamic update forwarder list");
  11024. (forward->callback)(forward->callback_arg, result, NULL);
  11025. forward_destroy(forward);
  11026. }
  11027. }
  11028. isc_result_t
  11029. dns_zone_forwardupdate(dns_zone_t *zone, dns_message_t *msg,
  11030. dns_updatecallback_t callback, void *callback_arg)
  11031. {
  11032. dns_forward_t *forward;
  11033. isc_result_t result;
  11034. isc_region_t *mr;
  11035. REQUIRE(DNS_ZONE_VALID(zone));
  11036. REQUIRE(msg != NULL);
  11037. REQUIRE(callback != NULL);
  11038. forward = isc_mem_get(zone->mctx, sizeof(*forward));
  11039. if (forward == NULL)
  11040. return (ISC_R_NOMEMORY);
  11041. forward->request = NULL;
  11042. forward->zone = NULL;
  11043. forward->msgbuf = NULL;
  11044. forward->which = 0;
  11045. forward->mctx = 0;
  11046. forward->callback = callback;
  11047. forward->callback_arg = callback_arg;
  11048. ISC_LINK_INIT(forward, link);
  11049. forward->magic = FORWARD_MAGIC;
  11050. mr = dns_message_getrawmessage(msg);
  11051. if (mr == NULL) {
  11052. result = ISC_R_UNEXPECTEDEND;
  11053. goto cleanup;
  11054. }
  11055. result = isc_buffer_allocate(zone->mctx, &forward->msgbuf, mr->length);
  11056. if (result != ISC_R_SUCCESS)
  11057. goto cleanup;
  11058. result = isc_buffer_copyregion(forward->msgbuf, mr);
  11059. if (result != ISC_R_SUCCESS)
  11060. goto cleanup;
  11061. isc_mem_attach(zone->mctx, &forward->mctx);
  11062. dns_zone_iattach(zone, &forward->zone);
  11063. result = sendtomaster(forward);
  11064. cleanup:
  11065. if (result != ISC_R_SUCCESS) {
  11066. forward_destroy(forward);
  11067. }
  11068. return (result);
  11069. }
  11070. isc_result_t
  11071. dns_zone_next(dns_zone_t *zone, dns_zone_t **next) {
  11072. REQUIRE(DNS_ZONE_VALID(zone));
  11073. REQUIRE(next != NULL && *next == NULL);
  11074. *next = ISC_LIST_NEXT(zone, link);
  11075. if (*next == NULL)
  11076. return (ISC_R_NOMORE);
  11077. else
  11078. return (ISC_R_SUCCESS);
  11079. }
  11080. isc_result_t
  11081. dns_zone_first(dns_zonemgr_t *zmgr, dns_zone_t **first) {
  11082. REQUIRE(DNS_ZONEMGR_VALID(zmgr));
  11083. REQUIRE(first != NULL && *first == NULL);
  11084. *first = ISC_LIST_HEAD(zmgr->zones);
  11085. if (*first == NULL)
  11086. return (ISC_R_NOMORE);
  11087. else
  11088. return (ISC_R_SUCCESS);
  11089. }
  11090. /***
  11091. *** Zone manager.
  11092. ***/
  11093. isc_result_t
  11094. dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
  11095. isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr,
  11096. dns_zonemgr_t **zmgrp)
  11097. {
  11098. dns_zonemgr_t *zmgr;
  11099. isc_result_t result;
  11100. isc_interval_t interval;
  11101. zmgr = isc_mem_get(mctx, sizeof(*zmgr));
  11102. if (zmgr == NULL)
  11103. return (ISC_R_NOMEMORY);
  11104. zmgr->mctx = NULL;
  11105. zmgr->refs = 1;
  11106. isc_mem_attach(mctx, &zmgr->mctx);
  11107. zmgr->taskmgr = taskmgr;
  11108. zmgr->timermgr = timermgr;
  11109. zmgr->socketmgr = socketmgr;
  11110. zmgr->zonetasks = NULL;
  11111. zmgr->task = NULL;
  11112. zmgr->rl = NULL;
  11113. ISC_LIST_INIT(zmgr->zones);
  11114. ISC_LIST_INIT(zmgr->waiting_for_xfrin);
  11115. ISC_LIST_INIT(zmgr->xfrin_in_progress);
  11116. memset(zmgr->unreachable, 0, sizeof(zmgr->unreachable));
  11117. result = isc_rwlock_init(&zmgr->rwlock, 0, 0);
  11118. if (result != ISC_R_SUCCESS)
  11119. goto free_mem;
  11120. zmgr->transfersin = 10;
  11121. zmgr->transfersperns = 2;
  11122. /* Unreachable lock. */
  11123. result = isc_rwlock_init(&zmgr->urlock, 0, 0);
  11124. if (result != ISC_R_SUCCESS)
  11125. goto free_rwlock;
  11126. /* Create a single task for queueing of SOA queries. */
  11127. result = isc_task_create(taskmgr, 1, &zmgr->task);
  11128. if (result != ISC_R_SUCCESS)
  11129. goto free_urlock;
  11130. isc_task_setname(zmgr->task, "zmgr", zmgr);
  11131. result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
  11132. &zmgr->rl);
  11133. if (result != ISC_R_SUCCESS)
  11134. goto free_task;
  11135. /* default to 20 refresh queries / notifies per second. */
  11136. isc_interval_set(&interval, 0, 1000000000/2);
  11137. result = isc_ratelimiter_setinterval(zmgr->rl, &interval);
  11138. RUNTIME_CHECK(result == ISC_R_SUCCESS);
  11139. isc_ratelimiter_setpertic(zmgr->rl, 10);
  11140. zmgr->iolimit = 1;
  11141. zmgr->ioactive = 0;
  11142. ISC_LIST_INIT(zmgr->high);
  11143. ISC_LIST_INIT(zmgr->low);
  11144. result = isc_mutex_init(&zmgr->iolock);
  11145. if (result != ISC_R_SUCCESS)
  11146. goto free_rl;
  11147. zmgr->magic = ZONEMGR_MAGIC;
  11148. *zmgrp = zmgr;
  11149. return (ISC_R_SUCCESS);
  11150. #if 0
  11151. free_iolock:
  11152. DESTROYLOCK(&zmgr->iolock);
  11153. #endif
  11154. free_rl:
  11155. isc_ratelimiter_detach(&zmgr->rl);
  11156. free_task:
  11157. isc_task_detach(&zmgr->task);
  11158. free_urlock:
  11159. isc_rwlock_destroy(&zmgr->urlock);
  11160. free_rwlock:
  11161. isc_rwlock_destroy(&zmgr->rwlock);
  11162. free_mem:
  11163. isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr));
  11164. isc_mem_detach(&mctx);
  11165. return (result);
  11166. }
  11167. isc_result_t
  11168. dns_zonemgr_managezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
  11169. isc_result_t result;
  11170. REQUIRE(DNS_ZONE_VALID(zone));
  11171. REQUIRE(DNS_ZONEMGR_VALID(zmgr));
  11172. if (zmgr->zonetasks == NULL)
  11173. return (ISC_R_FAILURE);
  11174. RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
  11175. LOCK_ZONE(zone);
  11176. REQUIRE(zone->task == NULL);
  11177. REQUIRE(zone->timer == NULL);
  11178. REQUIRE(zone->zmgr == NULL);
  11179. isc_taskpool_gettask(zmgr->zonetasks, &zone->task);
  11180. /*
  11181. * Set the task name. The tag will arbitrarily point to one
  11182. * of the zones sharing the task (in practice, the one
  11183. * to be managed last).
  11184. */
  11185. isc_task_setname(zone->task, "zone", zone);
  11186. result = isc_timer_create(zmgr->timermgr, isc_timertype_inactive,
  11187. NULL, NULL,
  11188. zone->task, zone_timer, zone,
  11189. &zone->timer);
  11190. if (result != ISC_R_SUCCESS)
  11191. goto cleanup_task;
  11192. /*
  11193. * The timer "holds" a iref.
  11194. */
  11195. zone->irefs++;
  11196. INSIST(zone->irefs != 0);
  11197. ISC_LIST_APPEND(zmgr->zones, zone, link);
  11198. zone->zmgr = zmgr;
  11199. zmgr->refs++;
  11200. goto unlock;
  11201. cleanup_task:
  11202. isc_task_detach(&zone->task);
  11203. unlock:
  11204. UNLOCK_ZONE(zone);
  11205. RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
  11206. return (result);
  11207. }
  11208. void
  11209. dns_zonemgr_releasezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
  11210. isc_boolean_t free_now = ISC_FALSE;
  11211. REQUIRE(DNS_ZONE_VALID(zone));
  11212. REQUIRE(DNS_ZONEMGR_VALID(zmgr));
  11213. REQUIRE(zone->zmgr == zmgr);
  11214. RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
  11215. LOCK_ZONE(zone);
  11216. ISC_LIST_UNLINK(zmgr->zones, zone, link);
  11217. zone->zmgr = NULL;
  11218. zmgr->refs--;
  11219. if (zmgr->refs == 0)
  11220. free_now = ISC_TRUE;
  11221. UNLOCK_ZONE(zone);
  11222. RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
  11223. if (free_now)
  11224. zonemgr_free(zmgr);
  11225. ENSURE(zone->zmgr == NULL);
  11226. }
  11227. void
  11228. dns_zonemgr_attach(dns_zonemgr_t *source, dns_zonemgr_t **target) {
  11229. REQUIRE(DNS_ZONEMGR_VALID(source));
  11230. REQUIRE(target != NULL && *target == NULL);
  11231. RWLOCK(&source->rwlock, isc_rwlocktype_write);
  11232. REQUIRE(source->refs > 0);
  11233. source->refs++;
  11234. INSIST(source->refs > 0);
  11235. RWUNLOCK(&source->rwlock, isc_rwlocktype_write);
  11236. *target = source;
  11237. }
  11238. void
  11239. dns_zonemgr_detach(dns_zonemgr_t **zmgrp) {
  11240. dns_zonemgr_t *zmgr;
  11241. isc_boolean_t free_now = ISC_FALSE;
  11242. REQUIRE(zmgrp != NULL);
  11243. zmgr = *zmgrp;
  11244. REQUIRE(DNS_ZONEMGR_VALID(zmgr));
  11245. RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
  11246. zmgr->refs--;
  11247. if (zmgr->refs == 0)
  11248. free_now = ISC_TRUE;
  11249. RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
  11250. if (free_now)
  11251. zonemgr_free(zmgr);
  11252. *zmgrp = NULL;
  11253. }
  11254. isc_result_t
  11255. dns_zonemgr_forcemaint(dns_zonemgr_t *zmgr) {
  11256. dns_zone_t *p;
  11257. REQUIRE(DNS_ZONEMGR_VALID(zmgr));
  11258. RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
  11259. for (p = ISC_LIST_HEAD(zmgr->zones);
  11260. p != NULL;
  11261. p = ISC_LIST_NEXT(p, link))
  11262. {
  11263. dns_zone_maintenance(p);
  11264. }
  11265. RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
  11266. /*
  11267. * Recent configuration changes may have increased the
  11268. * amount of available transfers quota. Make sure any
  11269. * transfers currently blocked on quota get started if
  11270. * possible.
  11271. */
  11272. RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
  11273. zmgr_resume_xfrs(zmgr, ISC_TRUE);
  11274. RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
  11275. return (ISC_R_SUCCESS);
  11276. }
  11277. void
  11278. dns_zonemgr_resumexfrs(dns_zonemgr_t *zmgr) {
  11279. REQUIRE(DNS_ZONEMGR_VALID(zmgr));
  11280. RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
  11281. zmgr_resume_xfrs(zmgr, ISC_TRUE);
  11282. RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
  11283. }
  11284. void
  11285. dns_zonemgr_shutdown(dns_zonemgr_t *zmgr) {
  11286. dns_zone_t *zone;
  11287. REQUIRE(DNS_ZONEMGR_VALID(zmgr));
  11288. isc_ratelimiter_shutdown(zmgr->rl);
  11289. if (zmgr->task != NULL)
  11290. isc_task_destroy(&zmgr->task);
  11291. if (zmgr->zonetasks != NULL)
  11292. isc_taskpool_destroy(&zmgr->zonetasks);
  11293. RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
  11294. for (zone = ISC_LIST_HEAD(zmgr->zones);
  11295. zone != NULL;
  11296. zone = ISC_LIST_NEXT(zone, link))
  11297. {
  11298. LOCK_ZONE(zone);
  11299. forward_cancel(zone);
  11300. UNLOCK_ZONE(zone);
  11301. }
  11302. RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
  11303. }
  11304. isc_result_t
  11305. dns_zonemgr_setsize(dns_zonemgr_t *zmgr, int num_zones) {
  11306. isc_result_t result;
  11307. int ntasks = num_zones / 100;
  11308. isc_taskpool_t *pool = NULL;
  11309. REQUIRE(DNS_ZONEMGR_VALID(zmgr));
  11310. /*
  11311. * For anything fewer than 1000 zones we use 10 tasks in
  11312. * the task pool. More than that, and we'll scale at one
  11313. * task per 100 zones.
  11314. */
  11315. if (ntasks < 10)
  11316. ntasks = 10;
  11317. /* Create or resize the zone task pool. */
  11318. if (zmgr->zonetasks == NULL)
  11319. result = isc_taskpool_create(zmgr->taskmgr, zmgr->mctx,
  11320. ntasks, 2, &pool);
  11321. else
  11322. result = isc_taskpool_expand(&zmgr->zonetasks, ntasks, &pool);
  11323. if (result == ISC_R_SUCCESS)
  11324. zmgr->zonetasks = pool;
  11325. return (result);
  11326. }
  11327. static void
  11328. zonemgr_free(dns_zonemgr_t *zmgr) {
  11329. isc_mem_t *mctx;
  11330. INSIST(zmgr->refs == 0);
  11331. INSIST(ISC_LIST_EMPTY(zmgr->zones));
  11332. zmgr->magic = 0;
  11333. DESTROYLOCK(&zmgr->iolock);
  11334. isc_ratelimiter_detach(&zmgr->rl);
  11335. isc_rwlock_destroy(&zmgr->urlock);
  11336. isc_rwlock_destroy(&zmgr->rwlock);
  11337. mctx = zmgr->mctx;
  11338. isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr));
  11339. isc_mem_detach(&mctx);
  11340. }
  11341. void
  11342. dns_zonemgr_settransfersin(dns_zonemgr_t *zmgr, isc_uint32_t value) {
  11343. REQUIRE(DNS_ZONEMGR_VALID(zmgr));
  11344. zmgr->transfersin = value;
  11345. }
  11346. isc_uint32_t
  11347. dns_zonemgr_getttransfersin(dns_zonemgr_t *zmgr) {
  11348. REQUIRE(DNS_ZONEMGR_VALID(zmgr));
  11349. return (zmgr->transfersin);
  11350. }
  11351. void
  11352. dns_zonemgr_settransfersperns(dns_zonemgr_t *zmgr, isc_uint32_t value) {
  11353. REQUIRE(DNS_ZONEMGR_VALID(zmgr));
  11354. zmgr->transfersperns = value;
  11355. }
  11356. isc_uint32_t
  11357. dns_zonemgr_getttransfersperns(dns_zonemgr_t *zmgr) {
  11358. REQUIRE(DNS_ZONEMGR_VALID(zmgr));
  11359. return (zmgr->transfersperns);
  11360. }
  11361. /*
  11362. * Try to start a new incoming zone transfer to fill a quota
  11363. * slot that was just vacated.
  11364. *
  11365. * Requires:
  11366. * The zone manager is locked by the caller.
  11367. */
  11368. static void
  11369. zmgr_resume_xfrs(dns_zonemgr_t *zmgr, isc_boolean_t multi) {
  11370. dns_zone_t *zone;
  11371. dns_zone_t *next;
  11372. for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin);
  11373. zone != NULL;
  11374. zone = next)
  11375. {
  11376. isc_result_t result;
  11377. next = ISC_LIST_NEXT(zone, statelink);
  11378. result = zmgr_start_xfrin_ifquota(zmgr, zone);
  11379. if (result == ISC_R_SUCCESS) {
  11380. if (multi)
  11381. continue;
  11382. /*
  11383. * We successfully filled the slot. We're done.
  11384. */
  11385. break;
  11386. } else if (result == ISC_R_QUOTA) {
  11387. /*
  11388. * Not enough quota. This is probably the per-server
  11389. * quota, because we usually get called when a unit of
  11390. * global quota has just been freed. Try the next
  11391. * zone, it may succeed if it uses another master.
  11392. */
  11393. continue;
  11394. } else {
  11395. dns_zone_log(zone, ISC_LOG_DEBUG(1),
  11396. "starting zone transfer: %s",
  11397. isc_result_totext(result));
  11398. break;
  11399. }
  11400. }
  11401. }
  11402. /*
  11403. * Try to start an incoming zone transfer for 'zone', quota permitting.
  11404. *
  11405. * Requires:
  11406. * The zone manager is locked by the caller.
  11407. *
  11408. * Returns:
  11409. * ISC_R_SUCCESS There was enough quota and we attempted to
  11410. * start a transfer. zone_xfrdone() has been or will
  11411. * be called.
  11412. * ISC_R_QUOTA Not enough quota.
  11413. * Others Failure.
  11414. */
  11415. static isc_result_t
  11416. zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
  11417. dns_peer_t *peer = NULL;
  11418. isc_netaddr_t masterip;
  11419. isc_uint32_t nxfrsin, nxfrsperns;
  11420. dns_zone_t *x;
  11421. isc_uint32_t maxtransfersin, maxtransfersperns;
  11422. isc_event_t *e;
  11423. /*
  11424. * If we are exiting just pretend we got quota so the zone will
  11425. * be cleaned up in the zone's task context.
  11426. */
  11427. LOCK_ZONE(zone);
  11428. if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
  11429. UNLOCK_ZONE(zone);
  11430. goto gotquota;
  11431. }
  11432. /*
  11433. * Find any configured information about the server we'd
  11434. * like to transfer this zone from.
  11435. */
  11436. isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
  11437. (void)dns_peerlist_peerbyaddr(zone->view->peers, &masterip, &peer);
  11438. UNLOCK_ZONE(zone);
  11439. /*
  11440. * Determine the total maximum number of simultaneous
  11441. * transfers allowed, and the maximum for this specific
  11442. * master.
  11443. */
  11444. maxtransfersin = zmgr->transfersin;
  11445. maxtransfersperns = zmgr->transfersperns;
  11446. if (peer != NULL)
  11447. (void)dns_peer_gettransfers(peer, &maxtransfersperns);
  11448. /*
  11449. * Count the total number of transfers that are in progress,
  11450. * and the number of transfers in progress from this master.
  11451. * We linearly scan a list of all transfers; if this turns
  11452. * out to be too slow, we could hash on the master address.
  11453. */
  11454. nxfrsin = nxfrsperns = 0;
  11455. for (x = ISC_LIST_HEAD(zmgr->xfrin_in_progress);
  11456. x != NULL;
  11457. x = ISC_LIST_NEXT(x, statelink))
  11458. {
  11459. isc_netaddr_t xip;
  11460. LOCK_ZONE(x);
  11461. isc_netaddr_fromsockaddr(&xip, &x->masteraddr);
  11462. UNLOCK_ZONE(x);
  11463. nxfrsin++;
  11464. if (isc_netaddr_equal(&xip, &masterip))
  11465. nxfrsperns++;
  11466. }
  11467. /* Enforce quota. */
  11468. if (nxfrsin >= maxtransfersin)
  11469. return (ISC_R_QUOTA);
  11470. if (nxfrsperns >= maxtransfersperns)
  11471. return (ISC_R_QUOTA);
  11472. gotquota:
  11473. /*
  11474. * We have sufficient quota. Move the zone to the "xfrin_in_progress"
  11475. * list and send it an event to let it start the actual transfer in the
  11476. * context of its own task.
  11477. */
  11478. e = isc_event_allocate(zmgr->mctx, zmgr, DNS_EVENT_ZONESTARTXFRIN,
  11479. got_transfer_quota, zone, sizeof(isc_event_t));
  11480. if (e == NULL)
  11481. return (ISC_R_NOMEMORY);
  11482. LOCK_ZONE(zone);
  11483. INSIST(zone->statelist == &zmgr->waiting_for_xfrin);
  11484. ISC_LIST_UNLINK(zmgr->waiting_for_xfrin, zone, statelink);
  11485. ISC_LIST_APPEND(zmgr->xfrin_in_progress, zone, statelink);
  11486. zone->statelist = &zmgr->xfrin_in_progress;
  11487. isc_task_send(zone->task, &e);
  11488. dns_zone_log(zone, ISC_LOG_INFO, "Transfer started.");
  11489. UNLOCK_ZONE(zone);
  11490. return (ISC_R_SUCCESS);
  11491. }
  11492. void
  11493. dns_zonemgr_setiolimit(dns_zonemgr_t *zmgr, isc_uint32_t iolimit) {
  11494. REQUIRE(DNS_ZONEMGR_VALID(zmgr));
  11495. REQUIRE(iolimit > 0);
  11496. zmgr->iolimit = iolimit;
  11497. }
  11498. isc_uint32_t
  11499. dns_zonemgr_getiolimit(dns_zonemgr_t *zmgr) {
  11500. REQUIRE(DNS_ZONEMGR_VALID(zmgr));
  11501. return (zmgr->iolimit);
  11502. }
  11503. /*
  11504. * Get permission to request a file handle from the OS.
  11505. * An event will be sent to action when one is available.
  11506. * There are two queues available (high and low), the high
  11507. * queue will be serviced before the low one.
  11508. *
  11509. * zonemgr_putio() must be called after the event is delivered to
  11510. * 'action'.
  11511. */
  11512. static isc_result_t
  11513. zonemgr_getio(dns_zonemgr_t *zmgr, isc_boolean_t high,
  11514. isc_task_t *task, isc_taskaction_t action, void *arg,
  11515. dns_io_t **iop)
  11516. {
  11517. dns_io_t *io;
  11518. isc_boolean_t queue;
  11519. REQUIRE(DNS_ZONEMGR_VALID(zmgr));
  11520. REQUIRE(iop != NULL && *iop == NULL);
  11521. io = isc_mem_get(zmgr->mctx, sizeof(*io));
  11522. if (io == NULL)
  11523. return (ISC_R_NOMEMORY);
  11524. io->event = isc_event_allocate(zmgr->mctx, task, DNS_EVENT_IOREADY,
  11525. action, arg, sizeof(*io->event));
  11526. if (io->event == NULL) {
  11527. isc_mem_put(zmgr->mctx, io, sizeof(*io));
  11528. return (ISC_R_NOMEMORY);
  11529. }
  11530. io->zmgr = zmgr;
  11531. io->high = high;
  11532. io->task = NULL;
  11533. isc_task_attach(task, &io->task);
  11534. ISC_LINK_INIT(io, link);
  11535. io->magic = IO_MAGIC;
  11536. LOCK(&zmgr->iolock);
  11537. zmgr->ioactive++;
  11538. queue = ISC_TF(zmgr->ioactive > zmgr->iolimit);
  11539. if (queue) {
  11540. if (io->high)
  11541. ISC_LIST_APPEND(zmgr->high, io, link);
  11542. else
  11543. ISC_LIST_APPEND(zmgr->low, io, link);
  11544. }
  11545. UNLOCK(&zmgr->iolock);
  11546. *iop = io;
  11547. if (!queue) {
  11548. isc_task_send(io->task, &io->event);
  11549. }
  11550. return (ISC_R_SUCCESS);
  11551. }
  11552. static void
  11553. zonemgr_putio(dns_io_t **iop) {
  11554. dns_io_t *io;
  11555. dns_io_t *next;
  11556. dns_zonemgr_t *zmgr;
  11557. REQUIRE(iop != NULL);
  11558. io = *iop;
  11559. REQUIRE(DNS_IO_VALID(io));
  11560. *iop = NULL;
  11561. INSIST(!ISC_LINK_LINKED(io, link));
  11562. INSIST(io->event == NULL);
  11563. zmgr = io->zmgr;
  11564. isc_task_detach(&io->task);
  11565. io->magic = 0;
  11566. isc_mem_put(zmgr->mctx, io, sizeof(*io));
  11567. LOCK(&zmgr->iolock);
  11568. INSIST(zmgr->ioactive > 0);
  11569. zmgr->ioactive--;
  11570. next = HEAD(zmgr->high);
  11571. if (next == NULL)
  11572. next = HEAD(zmgr->low);
  11573. if (next != NULL) {
  11574. if (next->high)
  11575. ISC_LIST_UNLINK(zmgr->high, next, link);
  11576. else
  11577. ISC_LIST_UNLINK(zmgr->low, next, link);
  11578. INSIST(next->event != NULL);
  11579. }
  11580. UNLOCK(&zmgr->iolock);
  11581. if (next != NULL)
  11582. isc_task_send(next->task, &next->event);
  11583. }
  11584. static void
  11585. zonemgr_cancelio(dns_io_t *io) {
  11586. isc_boolean_t send_event = ISC_FALSE;
  11587. REQUIRE(DNS_IO_VALID(io));
  11588. /*
  11589. * If we are queued to be run then dequeue.
  11590. */
  11591. LOCK(&io->zmgr->iolock);
  11592. if (ISC_LINK_LINKED(io, link)) {
  11593. if (io->high)
  11594. ISC_LIST_UNLINK(io->zmgr->high, io, link);
  11595. else
  11596. ISC_LIST_UNLINK(io->zmgr->low, io, link);
  11597. send_event = ISC_TRUE;
  11598. INSIST(io->event != NULL);
  11599. }
  11600. UNLOCK(&io->zmgr->iolock);
  11601. if (send_event) {
  11602. io->event->ev_attributes |= ISC_EVENTATTR_CANCELED;
  11603. isc_task_send(io->task, &io->event);
  11604. }
  11605. }
  11606. static void
  11607. zone_saveunique(dns_zone_t *zone, const char *path, const char *templat) {
  11608. char *buf;
  11609. int buflen;
  11610. isc_result_t result;
  11611. buflen = strlen(path) + strlen(templat) + 2;
  11612. buf = isc_mem_get(zone->mctx, buflen);
  11613. if (buf == NULL)
  11614. return;
  11615. result = isc_file_template(path, templat, buf, buflen);
  11616. if (result != ISC_R_SUCCESS)
  11617. goto cleanup;
  11618. result = isc_file_renameunique(path, buf);
  11619. if (result != ISC_R_SUCCESS)
  11620. goto cleanup;
  11621. dns_zone_log(zone, ISC_LOG_WARNING, "unable to load from '%s'; "
  11622. "renaming file to '%s' for failure analysis and "
  11623. "retransferring.", path, buf);
  11624. cleanup:
  11625. isc_mem_put(zone->mctx, buf, buflen);
  11626. }
  11627. #if 0
  11628. /* Hook for ondestroy notification from a database. */
  11629. static void
  11630. dns_zonemgr_dbdestroyed(isc_task_t *task, isc_event_t *event) {
  11631. dns_db_t *db = event->sender;
  11632. UNUSED(task);
  11633. isc_event_free(&event);
  11634. isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
  11635. DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
  11636. "database (%p) destroyed", (void*) db);
  11637. }
  11638. #endif
  11639. void
  11640. dns_zonemgr_setserialqueryrate(dns_zonemgr_t *zmgr, unsigned int value) {
  11641. isc_interval_t interval;
  11642. isc_uint32_t s, ns;
  11643. isc_uint32_t pertic;
  11644. isc_result_t result;
  11645. REQUIRE(DNS_ZONEMGR_VALID(zmgr));
  11646. if (value == 0)
  11647. value = 1;
  11648. if (value == 1) {
  11649. s = 1;
  11650. ns = 0;
  11651. pertic = 1;
  11652. } else if (value <= 10) {
  11653. s = 0;
  11654. ns = 1000000000 / value;
  11655. pertic = 1;
  11656. } else {
  11657. s = 0;
  11658. ns = (1000000000 / value) * 10;
  11659. pertic = 10;
  11660. }
  11661. isc_interval_set(&interval, s, ns);
  11662. result = isc_ratelimiter_setinterval(zmgr->rl, &interval);
  11663. RUNTIME_CHECK(result == ISC_R_SUCCESS);
  11664. isc_ratelimiter_setpertic(zmgr->rl, pertic);
  11665. zmgr->serialqueryrate = value;
  11666. }
  11667. unsigned int
  11668. dns_zonemgr_getserialqueryrate(dns_zonemgr_t *zmgr) {
  11669. REQUIRE(DNS_ZONEMGR_VALID(zmgr));
  11670. return (zmgr->serialqueryrate);
  11671. }
  11672. isc_boolean_t
  11673. dns_zonemgr_unreachable(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
  11674. isc_sockaddr_t *local, isc_time_t *now)
  11675. {
  11676. unsigned int i;
  11677. isc_rwlocktype_t locktype;
  11678. isc_result_t result;
  11679. isc_uint32_t seconds = isc_time_seconds(now);
  11680. REQUIRE(DNS_ZONEMGR_VALID(zmgr));
  11681. locktype = isc_rwlocktype_read;
  11682. RWLOCK(&zmgr->urlock, locktype);
  11683. for (i = 0; i < UNREACH_CHACHE_SIZE; i++) {
  11684. if (zmgr->unreachable[i].expire >= seconds &&
  11685. isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
  11686. isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) {
  11687. result = isc_rwlock_tryupgrade(&zmgr->urlock);
  11688. if (result == ISC_R_SUCCESS) {
  11689. locktype = isc_rwlocktype_write;
  11690. zmgr->unreachable[i].last = seconds;
  11691. }
  11692. break;
  11693. }
  11694. }
  11695. RWUNLOCK(&zmgr->urlock, locktype);
  11696. return (ISC_TF(i < UNREACH_CHACHE_SIZE));
  11697. }
  11698. void
  11699. dns_zonemgr_unreachabledel(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
  11700. isc_sockaddr_t *local)
  11701. {
  11702. unsigned int i;
  11703. isc_rwlocktype_t locktype;
  11704. isc_result_t result;
  11705. char master[ISC_SOCKADDR_FORMATSIZE];
  11706. char source[ISC_SOCKADDR_FORMATSIZE];
  11707. isc_sockaddr_format(remote, master, sizeof(master));
  11708. isc_sockaddr_format(local, source, sizeof(source));
  11709. REQUIRE(DNS_ZONEMGR_VALID(zmgr));
  11710. locktype = isc_rwlocktype_read;
  11711. RWLOCK(&zmgr->urlock, locktype);
  11712. for (i = 0; i < UNREACH_CHACHE_SIZE; i++) {
  11713. if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
  11714. isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) {
  11715. result = isc_rwlock_tryupgrade(&zmgr->urlock);
  11716. if (result == ISC_R_SUCCESS) {
  11717. locktype = isc_rwlocktype_write;
  11718. zmgr->unreachable[i].expire = 0;
  11719. isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
  11720. DNS_LOGMODULE_ZONE, ISC_LOG_INFO,
  11721. "master %s (source %s) deleted "
  11722. "from unreachable cache",
  11723. master, source);
  11724. }
  11725. break;
  11726. }
  11727. }
  11728. RWUNLOCK(&zmgr->urlock, locktype);
  11729. }
  11730. void
  11731. dns_zonemgr_unreachableadd(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
  11732. isc_sockaddr_t *local, isc_time_t *now)
  11733. {
  11734. isc_uint32_t seconds = isc_time_seconds(now);
  11735. isc_uint32_t last = seconds;
  11736. unsigned int i, slot = UNREACH_CHACHE_SIZE, oldest = 0;
  11737. REQUIRE(DNS_ZONEMGR_VALID(zmgr));
  11738. RWLOCK(&zmgr->urlock, isc_rwlocktype_write);
  11739. for (i = 0; i < UNREACH_CHACHE_SIZE; i++) {
  11740. /* Existing entry? */
  11741. if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
  11742. isc_sockaddr_equal(&zmgr->unreachable[i].local, local))
  11743. break;
  11744. /* Empty slot? */
  11745. if (zmgr->unreachable[i].expire < seconds)
  11746. slot = i;
  11747. /* Least recently used slot? */
  11748. if (zmgr->unreachable[i].last < last) {
  11749. last = zmgr->unreachable[i].last;
  11750. oldest = i;
  11751. }
  11752. }
  11753. if (i < UNREACH_CHACHE_SIZE) {
  11754. /*
  11755. * Found a existing entry. Update the expire timer and
  11756. * last usage timestamps.
  11757. */
  11758. zmgr->unreachable[i].expire = seconds + UNREACH_HOLD_TIME;
  11759. zmgr->unreachable[i].last = seconds;
  11760. } else if (slot != UNREACH_CHACHE_SIZE) {
  11761. /*
  11762. * Found a empty slot. Add a new entry to the cache.
  11763. */
  11764. zmgr->unreachable[slot].expire = seconds + UNREACH_HOLD_TIME;
  11765. zmgr->unreachable[slot].last = seconds;
  11766. zmgr->unreachable[slot].remote = *remote;
  11767. zmgr->unreachable[slot].local = *local;
  11768. } else {
  11769. /*
  11770. * Replace the least recently used entry in the cache.
  11771. */
  11772. zmgr->unreachable[oldest].expire = seconds + UNREACH_HOLD_TIME;
  11773. zmgr->unreachable[oldest].last = seconds;
  11774. zmgr->unreachable[oldest].remote = *remote;
  11775. zmgr->unreachable[oldest].local = *local;
  11776. }
  11777. RWUNLOCK(&zmgr->urlock, isc_rwlocktype_write);
  11778. }
  11779. void
  11780. dns_zone_forcereload(dns_zone_t *zone) {
  11781. REQUIRE(DNS_ZONE_VALID(zone));
  11782. if (zone->type == dns_zone_master)
  11783. return;
  11784. LOCK_ZONE(zone);
  11785. DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FORCEXFER);
  11786. UNLOCK_ZONE(zone);
  11787. dns_zone_refresh(zone);
  11788. }
  11789. isc_boolean_t
  11790. dns_zone_isforced(dns_zone_t *zone) {
  11791. REQUIRE(DNS_ZONE_VALID(zone));
  11792. return (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER));
  11793. }
  11794. isc_result_t
  11795. dns_zone_setstatistics(dns_zone_t *zone, isc_boolean_t on) {
  11796. /*
  11797. * This function is obsoleted.
  11798. */
  11799. UNUSED(zone);
  11800. UNUSED(on);
  11801. return (ISC_R_NOTIMPLEMENTED);
  11802. }
  11803. isc_uint64_t *
  11804. dns_zone_getstatscounters(dns_zone_t *zone) {
  11805. /*
  11806. * This function is obsoleted.
  11807. */
  11808. UNUSED(zone);
  11809. return (NULL);
  11810. }
  11811. void
  11812. dns_zone_setstats(dns_zone_t *zone, isc_stats_t *stats) {
  11813. REQUIRE(DNS_ZONE_VALID(zone));
  11814. REQUIRE(zone->stats == NULL);
  11815. LOCK_ZONE(zone);
  11816. zone->stats = NULL;
  11817. isc_stats_attach(stats, &zone->stats);
  11818. UNLOCK_ZONE(zone);
  11819. }
  11820. void
  11821. dns_zone_setrequeststats(dns_zone_t *zone, isc_stats_t *stats) {
  11822. REQUIRE(DNS_ZONE_VALID(zone));
  11823. LOCK_ZONE(zone);
  11824. if (zone->requeststats_on && stats == NULL)
  11825. zone->requeststats_on = ISC_FALSE;
  11826. else if (!zone->requeststats_on && stats != NULL) {
  11827. if (zone->requeststats == NULL) {
  11828. isc_stats_attach(stats, &zone->requeststats);
  11829. zone->requeststats_on = ISC_TRUE;
  11830. }
  11831. }
  11832. UNLOCK_ZONE(zone);
  11833. return;
  11834. }
  11835. isc_stats_t *
  11836. dns_zone_getrequeststats(dns_zone_t *zone) {
  11837. /*
  11838. * We don't lock zone for efficiency reason. This is not catastrophic
  11839. * because requeststats must always be valid when requeststats_on is
  11840. * true.
  11841. * Some counters may be incremented while requeststats_on is becoming
  11842. * false, or some cannot be incremented just after the statistics are
  11843. * installed, but it shouldn't matter much in practice.
  11844. */
  11845. if (zone->requeststats_on)
  11846. return (zone->requeststats);
  11847. else
  11848. return (NULL);
  11849. }
  11850. void
  11851. dns_zone_dialup(dns_zone_t *zone) {
  11852. REQUIRE(DNS_ZONE_VALID(zone));
  11853. zone_debuglog(zone, "dns_zone_dialup", 3,
  11854. "notify = %d, refresh = %d",
  11855. DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY),
  11856. DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH));
  11857. if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY))
  11858. dns_zone_notify(zone);
  11859. if (zone->type != dns_zone_master &&
  11860. DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
  11861. dns_zone_refresh(zone);
  11862. }
  11863. void
  11864. dns_zone_setdialup(dns_zone_t *zone, dns_dialuptype_t dialup) {
  11865. REQUIRE(DNS_ZONE_VALID(zone));
  11866. LOCK_ZONE(zone);
  11867. DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DIALNOTIFY |
  11868. DNS_ZONEFLG_DIALREFRESH |
  11869. DNS_ZONEFLG_NOREFRESH);
  11870. switch (dialup) {
  11871. case dns_dialuptype_no:
  11872. break;
  11873. case dns_dialuptype_yes:
  11874. DNS_ZONE_SETFLAG(zone, (DNS_ZONEFLG_DIALNOTIFY |
  11875. DNS_ZONEFLG_DIALREFRESH |
  11876. DNS_ZONEFLG_NOREFRESH));
  11877. break;
  11878. case dns_dialuptype_notify:
  11879. DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY);
  11880. break;
  11881. case dns_dialuptype_notifypassive:
  11882. DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY);
  11883. DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
  11884. break;
  11885. case dns_dialuptype_refresh:
  11886. DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALREFRESH);
  11887. DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
  11888. break;
  11889. case dns_dialuptype_passive:
  11890. DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
  11891. break;
  11892. default:
  11893. INSIST(0);
  11894. }
  11895. UNLOCK_ZONE(zone);
  11896. }
  11897. isc_result_t
  11898. dns_zone_setkeydirectory(dns_zone_t *zone, const char *directory) {
  11899. isc_result_t result = ISC_R_SUCCESS;
  11900. REQUIRE(DNS_ZONE_VALID(zone));
  11901. LOCK_ZONE(zone);
  11902. result = dns_zone_setstring(zone, &zone->keydirectory, directory);
  11903. UNLOCK_ZONE(zone);
  11904. return (result);
  11905. }
  11906. const char *
  11907. dns_zone_getkeydirectory(dns_zone_t *zone) {
  11908. REQUIRE(DNS_ZONE_VALID(zone));
  11909. return (zone->keydirectory);
  11910. }
  11911. unsigned int
  11912. dns_zonemgr_getcount(dns_zonemgr_t *zmgr, int state) {
  11913. dns_zone_t *zone;
  11914. unsigned int count = 0;
  11915. REQUIRE(DNS_ZONEMGR_VALID(zmgr));
  11916. RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
  11917. switch (state) {
  11918. case DNS_ZONESTATE_XFERRUNNING:
  11919. for (zone = ISC_LIST_HEAD(zmgr->xfrin_in_progress);
  11920. zone != NULL;
  11921. zone = ISC_LIST_NEXT(zone, statelink))
  11922. count++;
  11923. break;
  11924. case DNS_ZONESTATE_XFERDEFERRED:
  11925. for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin);
  11926. zone != NULL;
  11927. zone = ISC_LIST_NEXT(zone, statelink))
  11928. count++;
  11929. break;
  11930. case DNS_ZONESTATE_SOAQUERY:
  11931. for (zone = ISC_LIST_HEAD(zmgr->zones);
  11932. zone != NULL;
  11933. zone = ISC_LIST_NEXT(zone, link))
  11934. if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH))
  11935. count++;
  11936. break;
  11937. case DNS_ZONESTATE_ANY:
  11938. for (zone = ISC_LIST_HEAD(zmgr->zones);
  11939. zone != NULL;
  11940. zone = ISC_LIST_NEXT(zone, link)) {
  11941. dns_view_t *view = zone->view;
  11942. if (view != NULL && strcmp(view->name, "_bind") == 0)
  11943. continue;
  11944. count++;
  11945. }
  11946. break;
  11947. default:
  11948. INSIST(0);
  11949. }
  11950. RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
  11951. return (count);
  11952. }
  11953. isc_result_t
  11954. dns_zone_checknames(dns_zone_t *zone, dns_name_t *name, dns_rdata_t *rdata) {
  11955. isc_boolean_t ok = ISC_TRUE;
  11956. isc_boolean_t fail = ISC_FALSE;
  11957. char namebuf[DNS_NAME_FORMATSIZE];
  11958. char namebuf2[DNS_NAME_FORMATSIZE];
  11959. char typebuf[DNS_RDATATYPE_FORMATSIZE];
  11960. int level = ISC_LOG_WARNING;
  11961. dns_name_t bad;
  11962. REQUIRE(DNS_ZONE_VALID(zone));
  11963. if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES))
  11964. return (ISC_R_SUCCESS);
  11965. if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL)) {
  11966. level = ISC_LOG_ERROR;
  11967. fail = ISC_TRUE;
  11968. }
  11969. ok = dns_rdata_checkowner(name, rdata->rdclass, rdata->type, ISC_TRUE);
  11970. if (!ok) {
  11971. dns_name_format(name, namebuf, sizeof(namebuf));
  11972. dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf));
  11973. dns_zone_log(zone, level, "%s/%s: %s", namebuf, typebuf,
  11974. dns_result_totext(DNS_R_BADOWNERNAME));
  11975. if (fail)
  11976. return (DNS_R_BADOWNERNAME);
  11977. }
  11978. dns_name_init(&bad, NULL);
  11979. ok = dns_rdata_checknames(rdata, name, &bad);
  11980. if (!ok) {
  11981. dns_name_format(name, namebuf, sizeof(namebuf));
  11982. dns_name_format(&bad, namebuf2, sizeof(namebuf2));
  11983. dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf));
  11984. dns_zone_log(zone, level, "%s/%s: %s: %s ", namebuf, typebuf,
  11985. namebuf2, dns_result_totext(DNS_R_BADNAME));
  11986. if (fail)
  11987. return (DNS_R_BADNAME);
  11988. }
  11989. return (ISC_R_SUCCESS);
  11990. }
  11991. void
  11992. dns_zone_setcheckmx(dns_zone_t *zone, dns_checkmxfunc_t checkmx) {
  11993. REQUIRE(DNS_ZONE_VALID(zone));
  11994. zone->checkmx = checkmx;
  11995. }
  11996. void
  11997. dns_zone_setchecksrv(dns_zone_t *zone, dns_checksrvfunc_t checksrv) {
  11998. REQUIRE(DNS_ZONE_VALID(zone));
  11999. zone->checksrv = checksrv;
  12000. }
  12001. void
  12002. dns_zone_setcheckns(dns_zone_t *zone, dns_checknsfunc_t checkns) {
  12003. REQUIRE(DNS_ZONE_VALID(zone));
  12004. zone->checkns = checkns;
  12005. }
  12006. void
  12007. dns_zone_setisself(dns_zone_t *zone, dns_isselffunc_t isself, void *arg) {
  12008. REQUIRE(DNS_ZONE_VALID(zone));
  12009. LOCK_ZONE(zone);
  12010. zone->isself = isself;
  12011. zone->isselfarg = arg;
  12012. UNLOCK_ZONE(zone);
  12013. }
  12014. void
  12015. dns_zone_setnotifydelay(dns_zone_t *zone, isc_uint32_t delay) {
  12016. REQUIRE(DNS_ZONE_VALID(zone));
  12017. LOCK_ZONE(zone);
  12018. zone->notifydelay = delay;
  12019. UNLOCK_ZONE(zone);
  12020. }
  12021. isc_uint32_t
  12022. dns_zone_getnotifydelay(dns_zone_t *zone) {
  12023. REQUIRE(DNS_ZONE_VALID(zone));
  12024. return (zone->notifydelay);
  12025. }
  12026. isc_result_t
  12027. dns_zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm,
  12028. isc_uint16_t keyid, isc_boolean_t delete)
  12029. {
  12030. isc_result_t result;
  12031. REQUIRE(DNS_ZONE_VALID(zone));
  12032. dns_zone_log(zone, ISC_LOG_NOTICE,
  12033. "dns_zone_signwithkey(algorithm=%u, keyid=%u)",
  12034. algorithm, keyid);
  12035. LOCK_ZONE(zone);
  12036. result = zone_signwithkey(zone, algorithm, keyid, delete);
  12037. UNLOCK_ZONE(zone);
  12038. return (result);
  12039. }
  12040. static const char *hex = "0123456789ABCDEF";
  12041. isc_result_t
  12042. dns_zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) {
  12043. isc_result_t result;
  12044. char salt[255*2+1];
  12045. unsigned int i, j;
  12046. REQUIRE(DNS_ZONE_VALID(zone));
  12047. if (nsec3param->salt_length != 0) {
  12048. INSIST((nsec3param->salt_length * 2U) < sizeof(salt));
  12049. for (i = 0, j = 0; i < nsec3param->salt_length; i++) {
  12050. salt[j++] = hex[(nsec3param->salt[i] >> 4) & 0xf];
  12051. salt[j++] = hex[nsec3param->salt[i] & 0xf];
  12052. }
  12053. salt[j] = '\0';
  12054. } else
  12055. strcpy(salt, "-");
  12056. dns_zone_log(zone, ISC_LOG_NOTICE,
  12057. "dns_zone_addnsec3chain(hash=%u, iterations=%u, salt=%s)",
  12058. nsec3param->hash, nsec3param->iterations,
  12059. salt);
  12060. LOCK_ZONE(zone);
  12061. result = zone_addnsec3chain(zone, nsec3param);
  12062. UNLOCK_ZONE(zone);
  12063. return (result);
  12064. }
  12065. void
  12066. dns_zone_setnodes(dns_zone_t *zone, isc_uint32_t nodes) {
  12067. REQUIRE(DNS_ZONE_VALID(zone));
  12068. if (nodes == 0)
  12069. nodes = 1;
  12070. zone->nodes = nodes;
  12071. }
  12072. void
  12073. dns_zone_setsignatures(dns_zone_t *zone, isc_uint32_t signatures) {
  12074. REQUIRE(DNS_ZONE_VALID(zone));
  12075. /*
  12076. * We treat signatures as a signed value so explicitly
  12077. * limit its range here.
  12078. */
  12079. if (signatures > ISC_INT32_MAX)
  12080. signatures = ISC_INT32_MAX;
  12081. else if (signatures == 0)
  12082. signatures = 1;
  12083. zone->signatures = signatures;
  12084. }
  12085. void
  12086. dns_zone_setprivatetype(dns_zone_t *zone, dns_rdatatype_t type) {
  12087. REQUIRE(DNS_ZONE_VALID(zone));
  12088. zone->privatetype = type;
  12089. }
  12090. dns_rdatatype_t
  12091. dns_zone_getprivatetype(dns_zone_t *zone) {
  12092. REQUIRE(DNS_ZONE_VALID(zone));
  12093. return (zone->privatetype);
  12094. }
  12095. static isc_result_t
  12096. zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, isc_uint16_t keyid,
  12097. isc_boolean_t delete)
  12098. {
  12099. dns_signing_t *signing;
  12100. dns_signing_t *current;
  12101. isc_result_t result = ISC_R_SUCCESS;
  12102. isc_time_t now;
  12103. signing = isc_mem_get(zone->mctx, sizeof *signing);
  12104. if (signing == NULL)
  12105. return (ISC_R_NOMEMORY);
  12106. signing->magic = 0;
  12107. signing->db = NULL;
  12108. signing->dbiterator = NULL;
  12109. signing->algorithm = algorithm;
  12110. signing->keyid = keyid;
  12111. signing->delete = delete;
  12112. signing->done = ISC_FALSE;
  12113. TIME_NOW(&now);
  12114. for (current = ISC_LIST_HEAD(zone->signing);
  12115. current != NULL;
  12116. current = ISC_LIST_NEXT(current, link)) {
  12117. if (current->db == zone->db &&
  12118. current->algorithm == signing->algorithm &&
  12119. current->keyid == signing->keyid) {
  12120. if (current->delete != signing->delete)
  12121. current->done = ISC_TRUE;
  12122. else
  12123. goto cleanup;
  12124. }
  12125. }
  12126. if (zone->db != NULL) {
  12127. dns_db_attach(zone->db, &signing->db);
  12128. result = dns_db_createiterator(signing->db, 0,
  12129. &signing->dbiterator);
  12130. if (result == ISC_R_SUCCESS)
  12131. result = dns_dbiterator_first(signing->dbiterator);
  12132. if (result == ISC_R_SUCCESS) {
  12133. dns_dbiterator_pause(signing->dbiterator);
  12134. ISC_LIST_INITANDAPPEND(zone->signing, signing, link);
  12135. signing = NULL;
  12136. if (isc_time_isepoch(&zone->signingtime)) {
  12137. zone->signingtime = now;
  12138. if (zone->task != NULL)
  12139. zone_settimer(zone, &now);
  12140. }
  12141. }
  12142. } else
  12143. result = ISC_R_NOTFOUND;
  12144. cleanup:
  12145. if (signing != NULL) {
  12146. if (signing->db != NULL)
  12147. dns_db_detach(&signing->db);
  12148. if (signing->dbiterator != NULL)
  12149. dns_dbiterator_destroy(&signing->dbiterator);
  12150. isc_mem_put(zone->mctx, signing, sizeof *signing);
  12151. }
  12152. return (result);
  12153. }
  12154. static void
  12155. logmsg(const char *format, ...) {
  12156. va_list args;
  12157. va_start(args, format);
  12158. isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE,
  12159. ISC_LOG_DEBUG(1), format, args);
  12160. va_end(args);
  12161. }
  12162. static void
  12163. clear_keylist(dns_dnsseckeylist_t *list, isc_mem_t *mctx) {
  12164. dns_dnsseckey_t *key;
  12165. while (!ISC_LIST_EMPTY(*list)) {
  12166. key = ISC_LIST_HEAD(*list);
  12167. ISC_LIST_UNLINK(*list, key, link);
  12168. dns_dnsseckey_destroy(mctx, &key);
  12169. }
  12170. }
  12171. /* Called once; *timep should be set to the current time. */
  12172. static isc_result_t
  12173. next_keyevent(dst_key_t *key, isc_stdtime_t *timep) {
  12174. isc_result_t result;
  12175. isc_stdtime_t now, then = 0, event;
  12176. int i;
  12177. now = *timep;
  12178. for (i = 0; i <= DST_MAX_TIMES; i++) {
  12179. result = dst_key_gettime(key, i, &event);
  12180. if (result == ISC_R_SUCCESS && event > now &&
  12181. (then == 0 || event < then))
  12182. then = event;
  12183. }
  12184. if (then != 0) {
  12185. *timep = then;
  12186. return (ISC_R_SUCCESS);
  12187. }
  12188. return (ISC_R_NOTFOUND);
  12189. }
  12190. static isc_result_t
  12191. rr_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
  12192. const dns_rdata_t *rdata, isc_boolean_t *flag)
  12193. {
  12194. dns_rdataset_t rdataset;
  12195. dns_dbnode_t *node = NULL;
  12196. isc_result_t result;
  12197. dns_rdataset_init(&rdataset);
  12198. if (rdata->type == dns_rdatatype_nsec3)
  12199. CHECK(dns_db_findnsec3node(db, name, ISC_FALSE, &node));
  12200. else
  12201. CHECK(dns_db_findnode(db, name, ISC_FALSE, &node));
  12202. result = dns_db_findrdataset(db, node, ver, rdata->type, 0,
  12203. (isc_stdtime_t) 0, &rdataset, NULL);
  12204. if (result == ISC_R_NOTFOUND) {
  12205. *flag = ISC_FALSE;
  12206. result = ISC_R_SUCCESS;
  12207. goto failure;
  12208. }
  12209. for (result = dns_rdataset_first(&rdataset);
  12210. result == ISC_R_SUCCESS;
  12211. result = dns_rdataset_next(&rdataset)) {
  12212. dns_rdata_t myrdata = DNS_RDATA_INIT;
  12213. dns_rdataset_current(&rdataset, &myrdata);
  12214. if (!dns_rdata_compare(&myrdata, rdata))
  12215. break;
  12216. }
  12217. dns_rdataset_disassociate(&rdataset);
  12218. if (result == ISC_R_SUCCESS) {
  12219. *flag = ISC_TRUE;
  12220. } else if (result == ISC_R_NOMORE) {
  12221. *flag = ISC_FALSE;
  12222. result = ISC_R_SUCCESS;
  12223. }
  12224. failure:
  12225. if (node != NULL)
  12226. dns_db_detachnode(db, &node);
  12227. return (result);
  12228. }
  12229. /*
  12230. * Add records to signal the state of signing or of key removal.
  12231. */
  12232. static isc_result_t
  12233. add_signing_records(dns_db_t *db, dns_rdatatype_t privatetype,
  12234. dns_dbversion_t *ver, dns_diff_t *diff,
  12235. isc_boolean_t sign_all)
  12236. {
  12237. dns_difftuple_t *tuple, *newtuple = NULL;
  12238. dns_rdata_dnskey_t dnskey;
  12239. dns_rdata_t rdata = DNS_RDATA_INIT;
  12240. isc_boolean_t flag;
  12241. isc_region_t r;
  12242. isc_result_t result = ISC_R_SUCCESS;
  12243. isc_uint16_t keyid;
  12244. unsigned char buf[5];
  12245. dns_name_t *name = dns_db_origin(db);
  12246. for (tuple = ISC_LIST_HEAD(diff->tuples);
  12247. tuple != NULL;
  12248. tuple = ISC_LIST_NEXT(tuple, link)) {
  12249. if (tuple->rdata.type != dns_rdatatype_dnskey)
  12250. continue;
  12251. result = dns_rdata_tostruct(&tuple->rdata, &dnskey, NULL);
  12252. RUNTIME_CHECK(result == ISC_R_SUCCESS);
  12253. if ((dnskey.flags &
  12254. (DNS_KEYFLAG_OWNERMASK|DNS_KEYTYPE_NOAUTH))
  12255. != DNS_KEYOWNER_ZONE)
  12256. continue;
  12257. dns_rdata_toregion(&tuple->rdata, &r);
  12258. keyid = dst_region_computeid(&r, dnskey.algorithm);
  12259. buf[0] = dnskey.algorithm;
  12260. buf[1] = (keyid & 0xff00) >> 8;
  12261. buf[2] = (keyid & 0xff);
  12262. buf[3] = (tuple->op == DNS_DIFFOP_ADD) ? 0 : 1;
  12263. buf[4] = 0;
  12264. rdata.data = buf;
  12265. rdata.length = sizeof(buf);
  12266. rdata.type = privatetype;
  12267. rdata.rdclass = tuple->rdata.rdclass;
  12268. if (sign_all || tuple->op == DNS_DIFFOP_DEL) {
  12269. CHECK(rr_exists(db, ver, name, &rdata, &flag));
  12270. if (flag)
  12271. continue;
  12272. CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
  12273. name, 0, &rdata, &newtuple));
  12274. CHECK(do_one_tuple(&newtuple, db, ver, diff));
  12275. INSIST(newtuple == NULL);
  12276. }
  12277. /*
  12278. * Remove any record which says this operation has already
  12279. * completed.
  12280. */
  12281. buf[4] = 1;
  12282. CHECK(rr_exists(db, ver, name, &rdata, &flag));
  12283. if (flag) {
  12284. CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL,
  12285. name, 0, &rdata, &newtuple));
  12286. CHECK(do_one_tuple(&newtuple, db, ver, diff));
  12287. INSIST(newtuple == NULL);
  12288. }
  12289. }
  12290. failure:
  12291. return (result);
  12292. }
  12293. static isc_result_t
  12294. sign_apex(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
  12295. dns_diff_t *diff, dns_diff_t *sig_diff)
  12296. {
  12297. isc_result_t result;
  12298. isc_stdtime_t now, inception, soaexpire;
  12299. isc_boolean_t check_ksk, keyset_kskonly;
  12300. dst_key_t *zone_keys[DNS_MAXZONEKEYS];
  12301. unsigned int nkeys = 0, i;
  12302. dns_difftuple_t *tuple;
  12303. result = find_zone_keys(zone, db, ver, zone->mctx, DNS_MAXZONEKEYS,
  12304. zone_keys, &nkeys);
  12305. if (result != ISC_R_SUCCESS) {
  12306. dns_zone_log(zone, ISC_LOG_ERROR,
  12307. "sign_apex:find_zone_keys -> %s\n",
  12308. dns_result_totext(result));
  12309. return (result);
  12310. }
  12311. isc_stdtime_get(&now);
  12312. inception = now - 3600; /* Allow for clock skew. */
  12313. soaexpire = now + dns_zone_getsigvalidityinterval(zone);
  12314. check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
  12315. keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
  12316. /*
  12317. * See if update_sigs will update DNSKEY signature and if not
  12318. * cause them to sign so that so that newly activated keys
  12319. * are used.
  12320. */
  12321. for (tuple = ISC_LIST_HEAD(diff->tuples);
  12322. tuple != NULL;
  12323. tuple = ISC_LIST_NEXT(tuple, link)) {
  12324. if (tuple->rdata.type == dns_rdatatype_dnskey &&
  12325. dns_name_equal(&tuple->name, &zone->origin))
  12326. break;
  12327. }
  12328. if (tuple == NULL) {
  12329. result = del_sigs(zone, db, ver, &zone->origin,
  12330. dns_rdatatype_dnskey, sig_diff,
  12331. zone_keys, nkeys, now, ISC_FALSE);
  12332. if (result != ISC_R_SUCCESS) {
  12333. dns_zone_log(zone, ISC_LOG_ERROR,
  12334. "sign_apex:del_sigs -> %s\n",
  12335. dns_result_totext(result));
  12336. goto failure;
  12337. }
  12338. result = add_sigs(db, ver, &zone->origin, dns_rdatatype_dnskey,
  12339. sig_diff, zone_keys, nkeys, zone->mctx,
  12340. inception, soaexpire, check_ksk,
  12341. keyset_kskonly);
  12342. if (result != ISC_R_SUCCESS) {
  12343. dns_zone_log(zone, ISC_LOG_ERROR,
  12344. "sign_apex:add_sigs -> %s\n",
  12345. dns_result_totext(result));
  12346. goto failure;
  12347. }
  12348. }
  12349. result = update_sigs(diff, db, ver, zone_keys, nkeys, zone,
  12350. inception, soaexpire, now, check_ksk,
  12351. keyset_kskonly, sig_diff);
  12352. if (result != ISC_R_SUCCESS) {
  12353. dns_zone_log(zone, ISC_LOG_ERROR,
  12354. "sign_apex:update_sigs -> %s\n",
  12355. dns_result_totext(result));
  12356. goto failure;
  12357. }
  12358. failure:
  12359. for (i = 0; i < nkeys; i++)
  12360. dst_key_free(&zone_keys[i]);
  12361. return (result);
  12362. }
  12363. /*
  12364. * Prevent the zone entering a inconsistent state where
  12365. * NSEC only DNSKEYs are present with NSEC3 chains.
  12366. * See update.c:check_dnssec()
  12367. */
  12368. static isc_boolean_t
  12369. dnskey_sane(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
  12370. dns_diff_t *diff)
  12371. {
  12372. isc_result_t result;
  12373. dns_difftuple_t *tuple;
  12374. isc_boolean_t nseconly = ISC_FALSE, nsec3 = ISC_FALSE;
  12375. dns_rdatatype_t privatetype = dns_zone_getprivatetype(zone);
  12376. /* Scan the tuples for an NSEC-only DNSKEY */
  12377. for (tuple = ISC_LIST_HEAD(diff->tuples);
  12378. tuple != NULL;
  12379. tuple = ISC_LIST_NEXT(tuple, link)) {
  12380. isc_uint8_t alg;
  12381. if (tuple->rdata.type != dns_rdatatype_dnskey ||
  12382. tuple->op != DNS_DIFFOP_ADD)
  12383. continue;
  12384. alg = tuple->rdata.data[3];
  12385. if (alg == DST_ALG_RSAMD5 || alg == DST_ALG_RSASHA1 ||
  12386. alg == DST_ALG_DSA || alg == DST_ALG_ECC) {
  12387. nseconly = ISC_TRUE;
  12388. break;
  12389. }
  12390. }
  12391. /* Check existing DB for NSEC-only DNSKEY */
  12392. if (!nseconly)
  12393. CHECK(dns_nsec_nseconly(db, ver, &nseconly));
  12394. /* Check existing DB for NSEC3 */
  12395. if (!nsec3)
  12396. CHECK(dns_nsec3_activex(db, ver, ISC_FALSE,
  12397. privatetype, &nsec3));
  12398. /* Refuse to allow NSEC3 with NSEC-only keys */
  12399. if (nseconly && nsec3) {
  12400. dns_zone_log(zone, ISC_LOG_ERROR,
  12401. "NSEC only DNSKEYs and NSEC3 chains not allowed");
  12402. goto failure;
  12403. }
  12404. return (ISC_TRUE);
  12405. failure:
  12406. return (ISC_FALSE);
  12407. }
  12408. static isc_result_t
  12409. clean_nsec3param(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
  12410. dns_diff_t *diff)
  12411. {
  12412. isc_result_t result;
  12413. dns_dbnode_t *node = NULL;
  12414. dns_rdataset_t rdataset;
  12415. dns_rdataset_init(&rdataset);
  12416. CHECK(dns_db_getoriginnode(db, &node));
  12417. result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey,
  12418. dns_rdatatype_none, 0, &rdataset, NULL);
  12419. if (dns_rdataset_isassociated(&rdataset))
  12420. dns_rdataset_disassociate(&rdataset);
  12421. if (result != ISC_R_NOTFOUND)
  12422. goto failure;
  12423. result = dns_nsec3param_deletechains(db, ver, zone, diff);
  12424. failure:
  12425. if (node != NULL)
  12426. dns_db_detachnode(db, &node);
  12427. return (result);
  12428. }
  12429. /*
  12430. * Given an RRSIG rdataset and an algorithm, determine whether there
  12431. * are any signatures using that algorithm.
  12432. */
  12433. static isc_boolean_t
  12434. signed_with_alg(dns_rdataset_t *rdataset, dns_secalg_t alg) {
  12435. dns_rdata_t rdata = DNS_RDATA_INIT;
  12436. dns_rdata_rrsig_t rrsig;
  12437. isc_result_t result;
  12438. REQUIRE(rdataset == NULL || rdataset->type == dns_rdatatype_rrsig);
  12439. if (rdataset == NULL || !dns_rdataset_isassociated(rdataset)) {
  12440. return (ISC_FALSE);
  12441. }
  12442. for (result = dns_rdataset_first(rdataset);
  12443. result == ISC_R_SUCCESS;
  12444. result = dns_rdataset_next(rdataset))
  12445. {
  12446. dns_rdataset_current(rdataset, &rdata);
  12447. result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
  12448. RUNTIME_CHECK(result == ISC_R_SUCCESS);
  12449. dns_rdata_reset(&rdata);
  12450. if (rrsig.algorithm == alg)
  12451. return (ISC_TRUE);
  12452. }
  12453. return (ISC_FALSE);
  12454. }
  12455. static isc_result_t
  12456. add_chains(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
  12457. dns_diff_t *diff)
  12458. {
  12459. dns_name_t *origin;
  12460. isc_boolean_t build_nsec3;
  12461. isc_result_t result;
  12462. origin = dns_db_origin(db);
  12463. CHECK(dns_private_chains(db, ver, zone->privatetype, NULL,
  12464. &build_nsec3));
  12465. if (build_nsec3)
  12466. CHECK(dns_nsec3_addnsec3sx(db, ver, origin, zone->minimum,
  12467. ISC_FALSE, zone->privatetype, diff));
  12468. CHECK(updatesecure(db, ver, origin, zone->minimum, ISC_TRUE, diff));
  12469. failure:
  12470. return (result);
  12471. }
  12472. static void
  12473. zone_rekey(dns_zone_t *zone) {
  12474. isc_result_t result;
  12475. dns_db_t *db = NULL;
  12476. dns_dbnode_t *node = NULL;
  12477. dns_dbversion_t *ver = NULL;
  12478. dns_rdataset_t soaset, soasigs, keyset, keysigs;
  12479. dns_dnsseckeylist_t dnskeys, keys, rmkeys;
  12480. dns_dnsseckey_t *key;
  12481. dns_diff_t diff, sig_diff;
  12482. isc_boolean_t commit = ISC_FALSE, newactive = ISC_FALSE;
  12483. isc_boolean_t newalg = ISC_FALSE;
  12484. isc_boolean_t fullsign;
  12485. dns_ttl_t ttl = 3600;
  12486. const char *dir;
  12487. isc_mem_t *mctx;
  12488. isc_stdtime_t now;
  12489. isc_time_t timenow;
  12490. isc_interval_t ival;
  12491. char timebuf[80];
  12492. REQUIRE(DNS_ZONE_VALID(zone));
  12493. ISC_LIST_INIT(dnskeys);
  12494. ISC_LIST_INIT(keys);
  12495. ISC_LIST_INIT(rmkeys);
  12496. dns_rdataset_init(&soaset);
  12497. dns_rdataset_init(&soasigs);
  12498. dns_rdataset_init(&keyset);
  12499. dns_rdataset_init(&keysigs);
  12500. dir = dns_zone_getkeydirectory(zone);
  12501. mctx = zone->mctx;
  12502. dns_diff_init(mctx, &diff);
  12503. dns_diff_init(mctx, &sig_diff);
  12504. sig_diff.resign = zone->sigresigninginterval;
  12505. CHECK(dns_zone_getdb(zone, &db));
  12506. CHECK(dns_db_newversion(db, &ver));
  12507. CHECK(dns_db_getoriginnode(db, &node));
  12508. TIME_NOW(&timenow);
  12509. now = isc_time_seconds(&timenow);
  12510. dns_zone_log(zone, ISC_LOG_INFO, "reconfiguring zone keys");
  12511. /* Get the SOA record's TTL */
  12512. CHECK(dns_db_findrdataset(db, node, ver, dns_rdatatype_soa,
  12513. dns_rdatatype_none, 0, &soaset, &soasigs));
  12514. ttl = soaset.ttl;
  12515. dns_rdataset_disassociate(&soaset);
  12516. /* Get the DNSKEY rdataset */
  12517. result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey,
  12518. dns_rdatatype_none, 0, &keyset, &keysigs);
  12519. if (result == ISC_R_SUCCESS) {
  12520. ttl = keyset.ttl;
  12521. result = dns_dnssec_keylistfromrdataset(&zone->origin, dir,
  12522. mctx, &keyset,
  12523. &keysigs, &soasigs,
  12524. ISC_FALSE, ISC_FALSE,
  12525. &dnskeys);
  12526. /* Can't get keys for some reason; try again later. */
  12527. if (result != ISC_R_SUCCESS)
  12528. goto trylater;
  12529. } else if (result != ISC_R_NOTFOUND)
  12530. goto failure;
  12531. /*
  12532. * True when called from "rndc sign". Indicates the zone should be
  12533. * fully signed now.
  12534. */
  12535. fullsign = ISC_TF(DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_FULLSIGN) != 0);
  12536. result = dns_dnssec_findmatchingkeys(&zone->origin, dir, mctx, &keys);
  12537. if (result == ISC_R_SUCCESS) {
  12538. isc_boolean_t check_ksk;
  12539. check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
  12540. result = dns_dnssec_updatekeys(&dnskeys, &keys, &rmkeys,
  12541. &zone->origin, ttl, &diff,
  12542. ISC_TF(!check_ksk),
  12543. mctx, logmsg);
  12544. /* Keys couldn't be updated for some reason;
  12545. * try again later. */
  12546. if (result != ISC_R_SUCCESS) {
  12547. dns_zone_log(zone, ISC_LOG_ERROR, "zone_rekey:"
  12548. "couldn't update zone keys: %s",
  12549. isc_result_totext(result));
  12550. goto trylater;
  12551. }
  12552. /*
  12553. * See if any pre-existing keys have newly become active;
  12554. * also, see if any new key is for a new algorithm, as in that
  12555. * event, we need to sign the zone fully. (If there's a new
  12556. * key, but it's for an already-existing algorithm, then
  12557. * the zone signing can be handled incrementally.)
  12558. */
  12559. for (key = ISC_LIST_HEAD(dnskeys);
  12560. key != NULL;
  12561. key = ISC_LIST_NEXT(key, link)) {
  12562. if (!key->first_sign)
  12563. continue;
  12564. newactive = ISC_TRUE;
  12565. if (!dns_rdataset_isassociated(&keysigs)) {
  12566. newalg = ISC_TRUE;
  12567. break;
  12568. }
  12569. if (signed_with_alg(&keysigs, dst_key_alg(key->key))) {
  12570. /*
  12571. * This isn't a new algorithm; clear
  12572. * first_sign so we won't sign the
  12573. * whole zone with this key later
  12574. */
  12575. key->first_sign = ISC_FALSE;
  12576. } else {
  12577. newalg = ISC_TRUE;
  12578. break;
  12579. }
  12580. }
  12581. if ((newactive || fullsign || !ISC_LIST_EMPTY(diff.tuples)) &&
  12582. dnskey_sane(zone, db, ver, &diff)) {
  12583. CHECK(dns_diff_apply(&diff, db, ver));
  12584. CHECK(clean_nsec3param(zone, db, ver, &diff));
  12585. CHECK(add_signing_records(db, zone->privatetype,
  12586. ver, &diff,
  12587. ISC_TF(newalg || fullsign)));
  12588. CHECK(increment_soa_serial(db, ver, &diff, mctx));
  12589. CHECK(add_chains(zone, db, ver, &diff));
  12590. CHECK(sign_apex(zone, db, ver, &diff, &sig_diff));
  12591. CHECK(zone_journal(zone, &sig_diff, "zone_rekey"));
  12592. commit = ISC_TRUE;
  12593. }
  12594. }
  12595. dns_db_closeversion(db, &ver, commit);
  12596. if (commit) {
  12597. dns_difftuple_t *tuple;
  12598. LOCK_ZONE(zone);
  12599. DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
  12600. zone_needdump(zone, DNS_DUMP_DELAY);
  12601. zone_settimer(zone, &timenow);
  12602. /* Remove any signatures from removed keys. */
  12603. if (!ISC_LIST_EMPTY(rmkeys)) {
  12604. for (key = ISC_LIST_HEAD(rmkeys);
  12605. key != NULL;
  12606. key = ISC_LIST_NEXT(key, link)) {
  12607. result = zone_signwithkey(zone,
  12608. dst_key_alg(key->key),
  12609. dst_key_id(key->key),
  12610. ISC_TRUE);
  12611. if (result != ISC_R_SUCCESS) {
  12612. dns_zone_log(zone, ISC_LOG_ERROR,
  12613. "zone_signwithkey failed: %s",
  12614. dns_result_totext(result));
  12615. }
  12616. }
  12617. }
  12618. if (fullsign) {
  12619. /*
  12620. * "rndc sign" was called, so we now sign the zone
  12621. * with all active keys, whether they're new or not.
  12622. */
  12623. for (key = ISC_LIST_HEAD(dnskeys);
  12624. key != NULL;
  12625. key = ISC_LIST_NEXT(key, link)) {
  12626. if (!key->force_sign && !key->hint_sign)
  12627. continue;
  12628. result = zone_signwithkey(zone,
  12629. dst_key_alg(key->key),
  12630. dst_key_id(key->key),
  12631. ISC_FALSE);
  12632. if (result != ISC_R_SUCCESS) {
  12633. dns_zone_log(zone, ISC_LOG_ERROR,
  12634. "zone_signwithkey failed: %s",
  12635. dns_result_totext(result));
  12636. }
  12637. }
  12638. } else if (newalg) {
  12639. /*
  12640. * We haven't been told to sign fully, but a new
  12641. * algorithm was added to the DNSKEY. We sign
  12642. * the full zone, but only with newly active
  12643. * keys.
  12644. */
  12645. for (key = ISC_LIST_HEAD(dnskeys);
  12646. key != NULL;
  12647. key = ISC_LIST_NEXT(key, link)) {
  12648. if (!key->first_sign)
  12649. continue;
  12650. result = zone_signwithkey(zone,
  12651. dst_key_alg(key->key),
  12652. dst_key_id(key->key),
  12653. ISC_FALSE);
  12654. if (result != ISC_R_SUCCESS) {
  12655. dns_zone_log(zone, ISC_LOG_ERROR,
  12656. "zone_signwithkey failed: %s",
  12657. dns_result_totext(result));
  12658. }
  12659. }
  12660. }
  12661. /*
  12662. * Clear fullsign flag, if it was set, so we don't do
  12663. * another full signing next time
  12664. */
  12665. zone->keyopts &= ~DNS_ZONEKEY_FULLSIGN;
  12666. /*
  12667. * Cause the zone to add/delete NSEC3 chains for the
  12668. * deferred NSEC3PARAM changes.
  12669. */
  12670. for (tuple = ISC_LIST_HEAD(sig_diff.tuples);
  12671. tuple != NULL;
  12672. tuple = ISC_LIST_NEXT(tuple, link)) {
  12673. unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
  12674. dns_rdata_t rdata = DNS_RDATA_INIT;
  12675. dns_rdata_nsec3param_t nsec3param;
  12676. if (tuple->rdata.type != zone->privatetype ||
  12677. tuple->op != DNS_DIFFOP_ADD)
  12678. continue;
  12679. if (!dns_nsec3param_fromprivate(&tuple->rdata, &rdata,
  12680. buf, sizeof(buf)))
  12681. continue;
  12682. result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
  12683. RUNTIME_CHECK(result == ISC_R_SUCCESS);
  12684. if (nsec3param.flags == 0)
  12685. continue;
  12686. result = zone_addnsec3chain(zone, &nsec3param);
  12687. if (result != ISC_R_SUCCESS) {
  12688. dns_zone_log(zone, ISC_LOG_ERROR,
  12689. "zone_addnsec3chain failed: %s",
  12690. dns_result_totext(result));
  12691. }
  12692. }
  12693. /*
  12694. * Schedule the next resigning event
  12695. */
  12696. set_resigntime(zone);
  12697. UNLOCK_ZONE(zone);
  12698. }
  12699. isc_time_settoepoch(&zone->refreshkeytime);
  12700. /*
  12701. * If we're doing key maintenance, set the key refresh timer to
  12702. * the next scheduled key event or to one hour in the future,
  12703. * whichever is sooner.
  12704. */
  12705. if (DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN)) {
  12706. isc_time_t timethen;
  12707. isc_stdtime_t then;
  12708. LOCK_ZONE(zone);
  12709. DNS_ZONE_TIME_ADD(&timenow, HOUR, &timethen);
  12710. zone->refreshkeytime = timethen;
  12711. UNLOCK_ZONE(zone);
  12712. for (key = ISC_LIST_HEAD(dnskeys);
  12713. key != NULL;
  12714. key = ISC_LIST_NEXT(key, link)) {
  12715. then = now;
  12716. result = next_keyevent(key->key, &then);
  12717. if (result != ISC_R_SUCCESS)
  12718. continue;
  12719. DNS_ZONE_TIME_ADD(&timenow, then - now, &timethen);
  12720. LOCK_ZONE(zone);
  12721. if (isc_time_compare(&timethen,
  12722. &zone->refreshkeytime) < 0) {
  12723. zone->refreshkeytime = timethen;
  12724. }
  12725. UNLOCK_ZONE(zone);
  12726. }
  12727. zone_settimer(zone, &timenow);
  12728. isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
  12729. dns_zone_log(zone, ISC_LOG_INFO, "next key event: %s", timebuf);
  12730. }
  12731. failure:
  12732. dns_diff_clear(&diff);
  12733. dns_diff_clear(&sig_diff);
  12734. clear_keylist(&dnskeys, mctx);
  12735. clear_keylist(&keys, mctx);
  12736. clear_keylist(&rmkeys, mctx);
  12737. if (ver != NULL)
  12738. dns_db_closeversion(db, &ver, ISC_FALSE);
  12739. if (dns_rdataset_isassociated(&keyset))
  12740. dns_rdataset_disassociate(&keyset);
  12741. if (dns_rdataset_isassociated(&keysigs))
  12742. dns_rdataset_disassociate(&keysigs);
  12743. if (dns_rdataset_isassociated(&soasigs))
  12744. dns_rdataset_disassociate(&soasigs);
  12745. if (node != NULL)
  12746. dns_db_detachnode(db, &node);
  12747. if (db != NULL)
  12748. dns_db_detach(&db);
  12749. return;
  12750. trylater:
  12751. isc_interval_set(&ival, HOUR, 0);
  12752. isc_time_nowplusinterval(&zone->refreshkeytime, &ival);
  12753. goto failure;
  12754. }
  12755. void
  12756. dns_zone_rekey(dns_zone_t *zone, isc_boolean_t fullsign) {
  12757. isc_time_t now;
  12758. if (zone->type == dns_zone_master && zone->task != NULL) {
  12759. LOCK_ZONE(zone);
  12760. if (fullsign)
  12761. zone->keyopts |= DNS_ZONEKEY_FULLSIGN;
  12762. TIME_NOW(&now);
  12763. zone->refreshkeytime = now;
  12764. zone_settimer(zone, &now);
  12765. UNLOCK_ZONE(zone);
  12766. }
  12767. }
  12768. isc_result_t
  12769. dns_zone_nscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
  12770. unsigned int *errors)
  12771. {
  12772. isc_result_t result;
  12773. dns_dbnode_t *node = NULL;
  12774. REQUIRE(DNS_ZONE_VALID(zone));
  12775. REQUIRE(errors != NULL);
  12776. result = dns_db_getoriginnode(db, &node);
  12777. if (result != ISC_R_SUCCESS)
  12778. return (result);
  12779. result = zone_count_ns_rr(zone, db, node, version, NULL, errors,
  12780. ISC_FALSE);
  12781. dns_db_detachnode(db, &node);
  12782. return (result);
  12783. }
  12784. void
  12785. dns_zone_setadded(dns_zone_t *zone, isc_boolean_t added) {
  12786. REQUIRE(DNS_ZONE_VALID(zone));
  12787. LOCK_ZONE(zone);
  12788. zone->added = added;
  12789. UNLOCK_ZONE(zone);
  12790. }
  12791. isc_boolean_t
  12792. dns_zone_getadded(dns_zone_t *zone) {
  12793. REQUIRE(DNS_ZONE_VALID(zone));
  12794. return (zone->added);
  12795. }
  12796. isc_result_t
  12797. dns_zone_dlzpostload(dns_zone_t *zone, dns_db_t *db)
  12798. {
  12799. isc_time_t loadtime;
  12800. isc_result_t result;
  12801. TIME_NOW(&loadtime);
  12802. LOCK_ZONE(zone);
  12803. result = zone_postload(zone, db, loadtime, ISC_R_SUCCESS);
  12804. UNLOCK_ZONE(zone);
  12805. return result;
  12806. }