00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <config.h>
00021 #include <errno.h>
00022
00023 #include <isc/file.h>
00024 #include <isc/hex.h>
00025 #include <isc/mutex.h>
00026 #include <isc/pool.h>
00027 #include <isc/print.h>
00028 #include <isc/random.h>
00029 #include <isc/ratelimiter.h>
00030 #include <isc/refcount.h>
00031 #include <isc/rwlock.h>
00032 #include <isc/serial.h>
00033 #include <isc/stats.h>
00034 #include <isc/stdtime.h>
00035 #include <isc/strerror.h>
00036 #include <isc/string.h>
00037 #include <isc/taskpool.h>
00038 #include <isc/thread.h>
00039 #include <isc/timer.h>
00040 #include <isc/util.h>
00041
00042 #include <dns/acache.h>
00043 #include <dns/acl.h>
00044 #include <dns/adb.h>
00045 #include <dns/callbacks.h>
00046 #include <dns/db.h>
00047 #include <dns/dbiterator.h>
00048 #include <dns/dlz.h>
00049 #include <dns/dnssec.h>
00050 #include <dns/events.h>
00051 #include <dns/journal.h>
00052 #include <dns/keydata.h>
00053 #include <dns/keytable.h>
00054 #include <dns/keyvalues.h>
00055 #include <dns/log.h>
00056 #include <dns/master.h>
00057 #include <dns/masterdump.h>
00058 #include <dns/message.h>
00059 #include <dns/name.h>
00060 #include <dns/nsec.h>
00061 #include <dns/nsec3.h>
00062 #include <dns/peer.h>
00063 #include <dns/private.h>
00064 #include <dns/rbt.h>
00065 #include <dns/rcode.h>
00066 #include <dns/rdata.h>
00067 #include <dns/rdataclass.h>
00068 #include <dns/rdatalist.h>
00069 #include <dns/rdataset.h>
00070 #include <dns/rdatasetiter.h>
00071 #include <dns/rdatastruct.h>
00072 #include <dns/rdatatype.h>
00073 #include <dns/request.h>
00074 #include <dns/resolver.h>
00075 #include <dns/result.h>
00076 #include <dns/rriterator.h>
00077 #include <dns/soa.h>
00078 #include <dns/ssu.h>
00079 #include <dns/stats.h>
00080 #include <dns/time.h>
00081 #include <dns/tsig.h>
00082 #include <dns/update.h>
00083 #include <dns/xfrin.h>
00084 #include <dns/zone.h>
00085 #include <dns/zt.h>
00086
00087 #include <dst/dst.h>
00088
00089 #define ZONE_MAGIC ISC_MAGIC('Z', 'O', 'N', 'E')
00090 #define DNS_ZONE_VALID(zone) ISC_MAGIC_VALID(zone, ZONE_MAGIC)
00091
00092 #define NOTIFY_MAGIC ISC_MAGIC('N', 't', 'f', 'y')
00093 #define DNS_NOTIFY_VALID(notify) ISC_MAGIC_VALID(notify, NOTIFY_MAGIC)
00094
00095 #define STUB_MAGIC ISC_MAGIC('S', 't', 'u', 'b')
00096 #define DNS_STUB_VALID(stub) ISC_MAGIC_VALID(stub, STUB_MAGIC)
00097
00098 #define ZONEMGR_MAGIC ISC_MAGIC('Z', 'm', 'g', 'r')
00099 #define DNS_ZONEMGR_VALID(stub) ISC_MAGIC_VALID(stub, ZONEMGR_MAGIC)
00100
00101 #define LOAD_MAGIC ISC_MAGIC('L', 'o', 'a', 'd')
00102 #define DNS_LOAD_VALID(load) ISC_MAGIC_VALID(load, LOAD_MAGIC)
00103
00104 #define FORWARD_MAGIC ISC_MAGIC('F', 'o', 'r', 'w')
00105 #define DNS_FORWARD_VALID(load) ISC_MAGIC_VALID(load, FORWARD_MAGIC)
00106
00107 #define IO_MAGIC ISC_MAGIC('Z', 'm', 'I', 'O')
00108 #define DNS_IO_VALID(load) ISC_MAGIC_VALID(load, IO_MAGIC)
00109
00110
00111
00112
00113 #define RANGE(a, min, max) \
00114 (((a) < (min)) ? (min) : ((a) < (max) ? (a) : (max)))
00115
00116 #define NSEC3REMOVE(x) (((x) & DNS_NSEC3FLAG_REMOVE) != 0)
00117
00118
00119
00120
00121 #define REVOKE(x) ((dst_key_flags(x) & DNS_KEYFLAG_REVOKE) != 0)
00122 #define KSK(x) ((dst_key_flags(x) & DNS_KEYFLAG_KSK) != 0)
00123 #define ALG(x) dst_key_alg(x)
00124
00125
00126
00127
00128 #define DNS_DEFAULT_IDLEIN 3600
00129 #define DNS_DEFAULT_IDLEOUT 3600
00130 #define MAX_XFER_TIME (2*3600)
00131 #define RESIGN_DELAY 3600
00132
00133 #ifndef DNS_MAX_EXPIRE
00134 #define DNS_MAX_EXPIRE 14515200
00135 #endif
00136
00137 #ifndef DNS_DUMP_DELAY
00138 #define DNS_DUMP_DELAY 900
00139 #endif
00140
00141 typedef struct dns_notify dns_notify_t;
00142 typedef struct dns_stub dns_stub_t;
00143 typedef struct dns_load dns_load_t;
00144 typedef struct dns_forward dns_forward_t;
00145 typedef ISC_LIST(dns_forward_t) dns_forwardlist_t;
00146 typedef struct dns_io dns_io_t;
00147 typedef ISC_LIST(dns_io_t) dns_iolist_t;
00148 typedef struct dns_signing dns_signing_t;
00149 typedef ISC_LIST(dns_signing_t) dns_signinglist_t;
00150 typedef struct dns_nsec3chain dns_nsec3chain_t;
00151 typedef ISC_LIST(dns_nsec3chain_t) dns_nsec3chainlist_t;
00152 typedef struct dns_keyfetch dns_keyfetch_t;
00153 typedef struct dns_asyncload dns_asyncload_t;
00154 typedef struct dns_include dns_include_t;
00155
00156 #define DNS_ZONE_CHECKLOCK
00157 #ifdef DNS_ZONE_CHECKLOCK
00158 #define LOCK_ZONE(z) \
00159 do { LOCK(&(z)->lock); \
00160 INSIST((z)->locked == ISC_FALSE); \
00161 (z)->locked = ISC_TRUE; \
00162 } while (0)
00163 #define UNLOCK_ZONE(z) \
00164 do { (z)->locked = ISC_FALSE; UNLOCK(&(z)->lock); } while (0)
00165 #define LOCKED_ZONE(z) ((z)->locked)
00166 #define TRYLOCK_ZONE(result, z) \
00167 do { \
00168 result = isc_mutex_trylock(&(z)->lock); \
00169 if (result == ISC_R_SUCCESS) { \
00170 INSIST((z)->locked == ISC_FALSE); \
00171 (z)->locked = ISC_TRUE; \
00172 } \
00173 } while (0)
00174 #else
00175 #define LOCK_ZONE(z) LOCK(&(z)->lock)
00176 #define UNLOCK_ZONE(z) UNLOCK(&(z)->lock)
00177 #define LOCKED_ZONE(z) ISC_TRUE
00178 #define TRYLOCK_ZONE(result, z) \
00179 do { result = isc_mutex_trylock(&(z)->lock); } while (0)
00180 #endif
00181
00182 #ifdef ISC_RWLOCK_USEATOMIC
00183 #define ZONEDB_INITLOCK(l) isc_rwlock_init((l), 0, 0)
00184 #define ZONEDB_DESTROYLOCK(l) isc_rwlock_destroy(l)
00185 #define ZONEDB_LOCK(l, t) RWLOCK((l), (t))
00186 #define ZONEDB_UNLOCK(l, t) RWUNLOCK((l), (t))
00187 #else
00188 #define ZONEDB_INITLOCK(l) isc_mutex_init(l)
00189 #define ZONEDB_DESTROYLOCK(l) DESTROYLOCK(l)
00190 #define ZONEDB_LOCK(l, t) LOCK(l)
00191 #define ZONEDB_UNLOCK(l, t) UNLOCK(l)
00192 #endif
00193
00194 struct dns_zone {
00195
00196 unsigned int magic;
00197 isc_mutex_t lock;
00198 #ifdef DNS_ZONE_CHECKLOCK
00199 isc_boolean_t locked;
00200 #endif
00201 isc_mem_t *mctx;
00202 isc_refcount_t erefs;
00203
00204 #ifdef ISC_RWLOCK_USEATOMIC
00205 isc_rwlock_t dblock;
00206 #else
00207 isc_mutex_t dblock;
00208 #endif
00209 dns_db_t *db;
00210
00211
00212 dns_zonemgr_t *zmgr;
00213 ISC_LINK(dns_zone_t) link;
00214 isc_timer_t *timer;
00215 unsigned int irefs;
00216 dns_name_t origin;
00217 char *masterfile;
00218 ISC_LIST(dns_include_t) includes;
00219 ISC_LIST(dns_include_t) newincludes;
00220 unsigned int nincludes;
00221 dns_masterformat_t masterformat;
00222 const dns_master_style_t *masterstyle;
00223 char *journal;
00224 isc_int32_t journalsize;
00225 dns_rdataclass_t rdclass;
00226 dns_zonetype_t type;
00227 unsigned int flags;
00228 unsigned int options;
00229 unsigned int options2;
00230 unsigned int db_argc;
00231 char **db_argv;
00232 isc_time_t expiretime;
00233 isc_time_t refreshtime;
00234 isc_time_t dumptime;
00235 isc_time_t loadtime;
00236 isc_time_t notifytime;
00237 isc_time_t resigntime;
00238 isc_time_t keywarntime;
00239 isc_time_t signingtime;
00240 isc_time_t nsec3chaintime;
00241 isc_time_t refreshkeytime;
00242 isc_uint32_t refreshkeyinterval;
00243 isc_uint32_t refreshkeycount;
00244 isc_uint32_t refresh;
00245 isc_uint32_t retry;
00246 isc_uint32_t expire;
00247 isc_uint32_t minimum;
00248 isc_stdtime_t key_expiry;
00249 isc_stdtime_t log_key_expired_timer;
00250 char *keydirectory;
00251
00252 isc_uint32_t maxrefresh;
00253 isc_uint32_t minrefresh;
00254 isc_uint32_t maxretry;
00255 isc_uint32_t minretry;
00256
00257 isc_sockaddr_t *masters;
00258 isc_dscp_t *masterdscps;
00259 dns_name_t **masterkeynames;
00260 isc_boolean_t *mastersok;
00261 unsigned int masterscnt;
00262 unsigned int curmaster;
00263 isc_sockaddr_t masteraddr;
00264 dns_notifytype_t notifytype;
00265 isc_sockaddr_t *notify;
00266 dns_name_t **notifykeynames;
00267 isc_dscp_t *notifydscp;
00268 unsigned int notifycnt;
00269 isc_sockaddr_t notifyfrom;
00270 isc_task_t *task;
00271 isc_task_t *loadtask;
00272 isc_sockaddr_t notifysrc4;
00273 isc_sockaddr_t notifysrc6;
00274 isc_sockaddr_t xfrsource4;
00275 isc_sockaddr_t xfrsource6;
00276 isc_sockaddr_t altxfrsource4;
00277 isc_sockaddr_t altxfrsource6;
00278 isc_sockaddr_t sourceaddr;
00279 isc_dscp_t notifysrc4dscp;
00280 isc_dscp_t notifysrc6dscp;
00281 isc_dscp_t xfrsource4dscp;
00282 isc_dscp_t xfrsource6dscp;
00283 isc_dscp_t altxfrsource4dscp;
00284 isc_dscp_t altxfrsource6dscp;
00285 dns_xfrin_ctx_t *xfr;
00286 dns_tsigkey_t *tsigkey;
00287
00288 dns_acl_t *update_acl;
00289 dns_acl_t *forward_acl;
00290 dns_acl_t *notify_acl;
00291 dns_acl_t *query_acl;
00292 dns_acl_t *queryon_acl;
00293 dns_acl_t *xfr_acl;
00294 isc_boolean_t update_disabled;
00295 isc_boolean_t zero_no_soa_ttl;
00296 dns_severity_t check_names;
00297 ISC_LIST(dns_notify_t) notifies;
00298 dns_request_t *request;
00299 dns_loadctx_t *lctx;
00300 dns_io_t *readio;
00301 dns_dumpctx_t *dctx;
00302 dns_io_t *writeio;
00303 isc_uint32_t maxxfrin;
00304 isc_uint32_t maxxfrout;
00305 isc_uint32_t idlein;
00306 isc_uint32_t idleout;
00307 isc_event_t ctlevent;
00308 dns_ssutable_t *ssutable;
00309 isc_uint32_t sigvalidityinterval;
00310 isc_uint32_t sigresigninginterval;
00311 dns_view_t *view;
00312 dns_acache_t *acache;
00313 dns_checkmxfunc_t checkmx;
00314 dns_checksrvfunc_t checksrv;
00315 dns_checknsfunc_t checkns;
00316
00317
00318
00319
00320
00321
00322
00323 ISC_LINK(dns_zone_t) statelink;
00324 dns_zonelist_t *statelist;
00325
00326
00327
00328 isc_stats_t *stats;
00329
00330
00331
00332
00333 dns_zonestat_level_t statlevel;
00334 isc_boolean_t requeststats_on;
00335 isc_stats_t *requeststats;
00336 dns_stats_t *rcvquerystats;
00337 isc_uint32_t notifydelay;
00338 dns_isselffunc_t isself;
00339 void *isselfarg;
00340
00341 char * strnamerd;
00342 char * strname;
00343 char * strrdclass;
00344 char * strviewname;
00345
00346
00347
00348
00349 isc_uint32_t compact_serial;
00350
00351
00352
00353 dns_signinglist_t signing;
00354 dns_nsec3chainlist_t nsec3chain;
00355
00356
00357
00358 isc_uint32_t signatures;
00359 isc_uint32_t nodes;
00360 dns_rdatatype_t privatetype;
00361
00362
00363
00364
00365 isc_uint32_t keyopts;
00366
00367
00368
00369
00370 isc_boolean_t added;
00371
00372
00373
00374
00375 isc_boolean_t automatic;
00376
00377
00378
00379
00380 dns_rpz_zones_t *rpzs;
00381 dns_rpz_num_t rpz_num;
00382
00383
00384
00385
00386 dns_updatemethod_t updatemethod;
00387
00388
00389
00390
00391 isc_boolean_t requestixfr;
00392
00393
00394
00395
00396 isc_boolean_t requestexpire;
00397
00398
00399
00400
00401 dns_forwardlist_t forwards;
00402
00403 dns_zone_t *raw;
00404 dns_zone_t *secure;
00405
00406 isc_boolean_t sourceserialset;
00407 isc_uint32_t sourceserial;
00408
00409
00410
00411
00412 dns_ttl_t maxttl;
00413
00414
00415
00416
00417 dns_diff_t rss_diff;
00418 isc_eventlist_t rss_events;
00419 dns_dbversion_t *rss_newver;
00420 dns_dbversion_t *rss_oldver;
00421 dns_db_t *rss_db;
00422 dns_zone_t *rss_raw;
00423 isc_event_t *rss_event;
00424 dns_update_state_t *rss_state;
00425 };
00426
00427 typedef struct {
00428 dns_diff_t *diff;
00429 isc_boolean_t offline;
00430 } zonediff_t;
00431
00432 #define zonediff_init(z, d) \
00433 do { \
00434 zonediff_t *_z = (z); \
00435 (_z)->diff = (d); \
00436 (_z)->offline = ISC_FALSE; \
00437 } while (0)
00438
00439 #define DNS_ZONE_FLAG(z,f) (ISC_TF(((z)->flags & (f)) != 0))
00440 #define DNS_ZONE_SETFLAG(z,f) do { \
00441 INSIST(LOCKED_ZONE(z)); \
00442 (z)->flags |= (f); \
00443 } while (0)
00444 #define DNS_ZONE_CLRFLAG(z,f) do { \
00445 INSIST(LOCKED_ZONE(z)); \
00446 (z)->flags &= ~(f); \
00447 } while (0)
00448
00449 #define DNS_ZONEFLG_REFRESH 0x00000001U
00450 #define DNS_ZONEFLG_NEEDDUMP 0x00000002U
00451 #define DNS_ZONEFLG_USEVC 0x00000004U
00452 #define DNS_ZONEFLG_DUMPING 0x00000008U
00453 #define DNS_ZONEFLG_HASINCLUDE 0x00000010U
00454 #define DNS_ZONEFLG_LOADED 0x00000020U
00455 #define DNS_ZONEFLG_EXITING 0x00000040U
00456 #define DNS_ZONEFLG_EXPIRED 0x00000080U
00457 #define DNS_ZONEFLG_NEEDREFRESH 0x00000100U
00458 #define DNS_ZONEFLG_UPTODATE 0x00000200U
00459
00460 #define DNS_ZONEFLG_NEEDNOTIFY 0x00000400U
00461
00462 #define DNS_ZONEFLG_DIFFONRELOAD 0x00000800U
00463
00464 #define DNS_ZONEFLG_NOMASTERS 0x00001000U
00465
00466
00467 #define DNS_ZONEFLG_LOADING 0x00002000U
00468 #define DNS_ZONEFLG_HAVETIMERS 0x00004000U
00469
00470
00471
00472 #define DNS_ZONEFLG_FORCEXFER 0x00008000U
00473 #define DNS_ZONEFLG_NOREFRESH 0x00010000U
00474 #define DNS_ZONEFLG_DIALNOTIFY 0x00020000U
00475 #define DNS_ZONEFLG_DIALREFRESH 0x00040000U
00476 #define DNS_ZONEFLG_SHUTDOWN 0x00080000U
00477 #define DNS_ZONEFLAG_NOIXFR 0x00100000U
00478 #define DNS_ZONEFLG_FLUSH 0x00200000U
00479 #define DNS_ZONEFLG_NOEDNS 0x00400000U
00480 #define DNS_ZONEFLG_USEALTXFRSRC 0x00800000U
00481 #define DNS_ZONEFLG_SOABEFOREAXFR 0x01000000U
00482 #define DNS_ZONEFLG_NEEDCOMPACT 0x02000000U
00483 #define DNS_ZONEFLG_REFRESHING 0x04000000U
00484 #define DNS_ZONEFLG_THAW 0x08000000U
00485 #define DNS_ZONEFLG_LOADPENDING 0x10000000U
00486 #define DNS_ZONEFLG_NODELAY 0x20000000U
00487 #define DNS_ZONEFLG_SENDSECURE 0x40000000U
00488 #define DNS_ZONEFLG_NEEDSTARTUPNOTIFY 0x80000000U
00489
00490
00491
00492
00493 #define DNS_ZONE_OPTION(z,o) (((z)->options & (o)) != 0)
00494 #define DNS_ZONE_OPTION2(z,o) (((z)->options2 & (o)) != 0)
00495 #define DNS_ZONEKEY_OPTION(z,o) (((z)->keyopts & (o)) != 0)
00496
00497
00498 #define DNS_ZONELOADFLAG_NOSTAT 0x00000001U
00499 #define DNS_ZONELOADFLAG_THAW 0x00000002U
00500
00501
00502 #define UNREACH_CHACHE_SIZE 10U
00503 #define UNREACH_HOLD_TIME 600
00504
00505 #define CHECK(op) \
00506 do { result = (op); \
00507 if (result != ISC_R_SUCCESS) goto failure; \
00508 } while (0)
00509
00510 struct dns_unreachable {
00511 isc_sockaddr_t remote;
00512 isc_sockaddr_t local;
00513 isc_uint32_t expire;
00514 isc_uint32_t last;
00515 isc_uint32_t count;
00516 };
00517
00518 struct dns_zonemgr {
00519 unsigned int magic;
00520 isc_mem_t * mctx;
00521 int refs;
00522 isc_taskmgr_t * taskmgr;
00523 isc_timermgr_t * timermgr;
00524 isc_socketmgr_t * socketmgr;
00525 isc_taskpool_t * zonetasks;
00526 isc_taskpool_t * loadtasks;
00527 isc_task_t * task;
00528 isc_pool_t * mctxpool;
00529 isc_ratelimiter_t * notifyrl;
00530 isc_ratelimiter_t * refreshrl;
00531 isc_ratelimiter_t * startupnotifyrl;
00532 isc_ratelimiter_t * startuprefreshrl;
00533 isc_rwlock_t rwlock;
00534 isc_mutex_t iolock;
00535 isc_rwlock_t urlock;
00536
00537
00538 dns_zonelist_t zones;
00539 dns_zonelist_t waiting_for_xfrin;
00540 dns_zonelist_t xfrin_in_progress;
00541
00542
00543 isc_uint32_t transfersin;
00544 isc_uint32_t transfersperns;
00545 unsigned int notifyrate;
00546 unsigned int startupnotifyrate;
00547 unsigned int serialqueryrate;
00548 unsigned int startupserialqueryrate;
00549
00550
00551 isc_uint32_t iolimit;
00552 isc_uint32_t ioactive;
00553 dns_iolist_t high;
00554 dns_iolist_t low;
00555
00556
00557
00558 struct dns_unreachable unreachable[UNREACH_CHACHE_SIZE];
00559 };
00560
00561
00562
00563
00564 struct dns_notify {
00565 unsigned int magic;
00566 unsigned int flags;
00567 isc_mem_t *mctx;
00568 dns_zone_t *zone;
00569 dns_adbfind_t *find;
00570 dns_request_t *request;
00571 dns_name_t ns;
00572 isc_sockaddr_t dst;
00573 dns_tsigkey_t *key;
00574 isc_dscp_t dscp;
00575 ISC_LINK(dns_notify_t) link;
00576 isc_event_t *event;
00577 };
00578
00579 #define DNS_NOTIFY_NOSOA 0x0001U
00580 #define DNS_NOTIFY_STARTUP 0x0002U
00581
00582
00583
00584
00585
00586
00587
00588 struct dns_stub {
00589 unsigned int magic;
00590 isc_mem_t *mctx;
00591 dns_zone_t *zone;
00592 dns_db_t *db;
00593 dns_dbversion_t *version;
00594 };
00595
00596
00597
00598
00599 struct dns_load {
00600 unsigned int magic;
00601 isc_mem_t *mctx;
00602 dns_zone_t *zone;
00603 dns_db_t *db;
00604 isc_time_t loadtime;
00605 dns_rdatacallbacks_t callbacks;
00606 };
00607
00608
00609
00610
00611 struct dns_forward {
00612 unsigned int magic;
00613 isc_mem_t *mctx;
00614 dns_zone_t *zone;
00615 isc_buffer_t *msgbuf;
00616 dns_request_t *request;
00617 isc_uint32_t which;
00618 isc_sockaddr_t addr;
00619 dns_updatecallback_t callback;
00620 void *callback_arg;
00621 unsigned int options;
00622 ISC_LINK(dns_forward_t) link;
00623 };
00624
00625
00626
00627
00628 struct dns_io {
00629 unsigned int magic;
00630 dns_zonemgr_t *zmgr;
00631 isc_boolean_t high;
00632 isc_task_t *task;
00633 ISC_LINK(dns_io_t) link;
00634 isc_event_t *event;
00635 };
00636
00637
00638
00639
00640
00641 struct dns_signing {
00642 unsigned int magic;
00643 dns_db_t *db;
00644 dns_dbiterator_t *dbiterator;
00645 dns_secalg_t algorithm;
00646 isc_uint16_t keyid;
00647 isc_boolean_t delete;
00648 isc_boolean_t done;
00649 ISC_LINK(dns_signing_t) link;
00650 };
00651
00652 struct dns_nsec3chain {
00653 unsigned int magic;
00654 dns_db_t *db;
00655 dns_dbiterator_t *dbiterator;
00656 dns_rdata_nsec3param_t nsec3param;
00657 unsigned char salt[255];
00658 isc_boolean_t done;
00659 isc_boolean_t seen_nsec;
00660 isc_boolean_t delete_nsec;
00661 isc_boolean_t save_delete_nsec;
00662 ISC_LINK(dns_nsec3chain_t) link;
00663 };
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686 struct dns_keyfetch {
00687 dns_fixedname_t name;
00688 dns_rdataset_t keydataset;
00689 dns_rdataset_t dnskeyset;
00690 dns_rdataset_t dnskeysigset;
00691 dns_zone_t *zone;
00692 dns_db_t *db;
00693 dns_fetch_t *fetch;
00694 };
00695
00696
00697
00698
00699 struct dns_asyncload {
00700 dns_zone_t *zone;
00701 dns_zt_zoneloaded_t loaded;
00702 void *loaded_arg;
00703 };
00704
00705
00706
00707
00708 struct dns_include {
00709 char *name;
00710 isc_time_t filetime;
00711 ISC_LINK(dns_include_t) link;
00712 };
00713
00714
00715
00716
00717
00718
00719 #define HOUR 3600
00720 #define DAY (24*HOUR)
00721 #define MONTH (30*DAY)
00722 unsigned int dns_zone_mkey_hour = HOUR;
00723 unsigned int dns_zone_mkey_day = DAY;
00724 unsigned int dns_zone_mkey_month = MONTH;
00725
00726 #define SEND_BUFFER_SIZE 2048
00727
00728 static void zone_settimer(dns_zone_t *, isc_time_t *);
00729 static void cancel_refresh(dns_zone_t *);
00730 static void zone_debuglog(dns_zone_t *zone, const char *, int debuglevel,
00731 const char *msg, ...) ISC_FORMAT_PRINTF(4, 5);
00732 static void notify_log(dns_zone_t *zone, int level, const char *fmt, ...)
00733 ISC_FORMAT_PRINTF(3, 4);
00734 static void queue_xfrin(dns_zone_t *zone);
00735 static isc_result_t update_one_rr(dns_db_t *db, dns_dbversion_t *ver,
00736 dns_diff_t *diff, dns_diffop_t op,
00737 dns_name_t *name, dns_ttl_t ttl,
00738 dns_rdata_t *rdata);
00739 static void zone_unload(dns_zone_t *zone);
00740 static void zone_expire(dns_zone_t *zone);
00741 static void zone_iattach(dns_zone_t *source, dns_zone_t **target);
00742 static void zone_idetach(dns_zone_t **zonep);
00743 static isc_result_t zone_replacedb(dns_zone_t *zone, dns_db_t *db,
00744 isc_boolean_t dump);
00745 static inline void zone_attachdb(dns_zone_t *zone, dns_db_t *db);
00746 static inline void zone_detachdb(dns_zone_t *zone);
00747 static isc_result_t default_journal(dns_zone_t *zone);
00748 static void zone_xfrdone(dns_zone_t *zone, isc_result_t result);
00749 static isc_result_t zone_postload(dns_zone_t *zone, dns_db_t *db,
00750 isc_time_t loadtime, isc_result_t result);
00751 static void zone_needdump(dns_zone_t *zone, unsigned int delay);
00752 static void zone_shutdown(isc_task_t *, isc_event_t *);
00753 static void zone_loaddone(void *arg, isc_result_t result);
00754 static isc_result_t zone_startload(dns_db_t *db, dns_zone_t *zone,
00755 isc_time_t loadtime);
00756 static void zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length);
00757 static void zone_name_tostr(dns_zone_t *zone, char *buf, size_t length);
00758 static void zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length);
00759 static void zone_viewname_tostr(dns_zone_t *zone, char *buf, size_t length);
00760 static isc_result_t zone_send_secureserial(dns_zone_t *zone,
00761 isc_uint32_t serial);
00762
00763 #if 0
00764
00765 static void dns_zonemgr_dbdestroyed(isc_task_t *task, isc_event_t *event);
00766 #endif
00767
00768 static void refresh_callback(isc_task_t *, isc_event_t *);
00769 static void stub_callback(isc_task_t *, isc_event_t *);
00770 static void queue_soa_query(dns_zone_t *zone);
00771 static void soa_query(isc_task_t *, isc_event_t *);
00772 static void ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset,
00773 dns_stub_t *stub);
00774 static int message_count(dns_message_t *msg, dns_section_t section,
00775 dns_rdatatype_t type);
00776 static void notify_cancel(dns_zone_t *zone);
00777 static void notify_find_address(dns_notify_t *notify);
00778 static void notify_send(dns_notify_t *notify);
00779 static isc_result_t notify_createmessage(dns_zone_t *zone,
00780 unsigned int flags,
00781 dns_message_t **messagep);
00782 static void notify_done(isc_task_t *task, isc_event_t *event);
00783 static void notify_send_toaddr(isc_task_t *task, isc_event_t *event);
00784 static isc_result_t zone_dump(dns_zone_t *, isc_boolean_t);
00785 static void got_transfer_quota(isc_task_t *task, isc_event_t *event);
00786 static isc_result_t zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr,
00787 dns_zone_t *zone);
00788 static void zmgr_resume_xfrs(dns_zonemgr_t *zmgr, isc_boolean_t multi);
00789 static void zonemgr_free(dns_zonemgr_t *zmgr);
00790 static isc_result_t zonemgr_getio(dns_zonemgr_t *zmgr, isc_boolean_t high,
00791 isc_task_t *task, isc_taskaction_t action,
00792 void *arg, dns_io_t **iop);
00793 static void zonemgr_putio(dns_io_t **iop);
00794 static void zonemgr_cancelio(dns_io_t *io);
00795
00796 static isc_result_t
00797 zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount,
00798 unsigned int *soacount, isc_uint32_t *serial,
00799 isc_uint32_t *refresh, isc_uint32_t *retry,
00800 isc_uint32_t *expire, isc_uint32_t *minimum,
00801 unsigned int *errors);
00802
00803 static void zone_freedbargs(dns_zone_t *zone);
00804 static void forward_callback(isc_task_t *task, isc_event_t *event);
00805 static void zone_saveunique(dns_zone_t *zone, const char *path,
00806 const char *templat);
00807 static void zone_maintenance(dns_zone_t *zone);
00808 static void zone_notify(dns_zone_t *zone, isc_time_t *now);
00809 static void dump_done(void *arg, isc_result_t result);
00810 static isc_result_t zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm,
00811 isc_uint16_t keyid, isc_boolean_t delete);
00812 static isc_result_t delete_nsec(dns_db_t *db, dns_dbversion_t *ver,
00813 dns_dbnode_t *node, dns_name_t *name,
00814 dns_diff_t *diff);
00815 static void zone_rekey(dns_zone_t *zone);
00816 static isc_result_t zone_send_securedb(dns_zone_t *zone, dns_db_t *db);
00817 static void setrl(isc_ratelimiter_t *rl, unsigned int *rate,
00818 unsigned int value);
00819
00820 #define ENTER zone_debuglog(zone, me, 1, "enter")
00821
00822 static const unsigned int dbargc_default = 1;
00823 static const char *dbargv_default[] = { "rbt" };
00824
00825 #define DNS_ZONE_JITTER_ADD(a, b, c) \
00826 do { \
00827 isc_interval_t _i; \
00828 isc_uint32_t _j; \
00829 _j = isc_random_jitter((b), (b)/4); \
00830 isc_interval_set(&_i, _j, 0); \
00831 if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \
00832 dns_zone_log(zone, ISC_LOG_WARNING, \
00833 "epoch approaching: upgrade required: " \
00834 "now + %s failed", #b); \
00835 isc_interval_set(&_i, _j/2, 0); \
00836 (void)isc_time_add((a), &_i, (c)); \
00837 } \
00838 } while (0)
00839
00840 #define DNS_ZONE_TIME_ADD(a, b, c) \
00841 do { \
00842 isc_interval_t _i; \
00843 isc_interval_set(&_i, (b), 0); \
00844 if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \
00845 dns_zone_log(zone, ISC_LOG_WARNING, \
00846 "epoch approaching: upgrade required: " \
00847 "now + %s failed", #b); \
00848 isc_interval_set(&_i, (b)/2, 0); \
00849 (void)isc_time_add((a), &_i, (c)); \
00850 } \
00851 } while (0)
00852
00853 typedef struct nsec3param nsec3param_t;
00854 struct nsec3param {
00855 unsigned char data[DNS_NSEC3PARAM_BUFFERSIZE + 1];
00856 unsigned int length;
00857 isc_boolean_t nsec;
00858 isc_boolean_t replace;
00859 ISC_LINK(nsec3param_t) link;
00860 };
00861 typedef ISC_LIST(nsec3param_t) nsec3paramlist_t;
00862 struct np3event {
00863 isc_event_t event;
00864 nsec3param_t params;
00865 };
00866
00867 struct ssevent {
00868 isc_event_t event;
00869 isc_uint32_t serial;
00870 };
00871
00872
00873
00874
00875 static inline void
00876 inc_stats(dns_zone_t *zone, isc_statscounter_t counter) {
00877 if (zone->stats != NULL)
00878 isc_stats_increment(zone->stats, counter);
00879 }
00880
00881
00882
00883
00884
00885 isc_result_t
00886 dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
00887 isc_result_t result;
00888 dns_zone_t *zone;
00889 isc_time_t now;
00890
00891 REQUIRE(zonep != NULL && *zonep == NULL);
00892 REQUIRE(mctx != NULL);
00893
00894 TIME_NOW(&now);
00895 zone = isc_mem_get(mctx, sizeof(*zone));
00896 if (zone == NULL)
00897 return (ISC_R_NOMEMORY);
00898
00899 zone->mctx = NULL;
00900 isc_mem_attach(mctx, &zone->mctx);
00901
00902 result = isc_mutex_init(&zone->lock);
00903 if (result != ISC_R_SUCCESS)
00904 goto free_zone;
00905
00906 result = ZONEDB_INITLOCK(&zone->dblock);
00907 if (result != ISC_R_SUCCESS)
00908 goto free_mutex;
00909
00910
00911 #ifdef DNS_ZONE_CHECKLOCK
00912 zone->locked = ISC_FALSE;
00913 #endif
00914 zone->db = NULL;
00915 zone->zmgr = NULL;
00916 ISC_LINK_INIT(zone, link);
00917 result = isc_refcount_init(&zone->erefs, 1);
00918 if (result != ISC_R_SUCCESS)
00919 goto free_dblock;
00920 zone->irefs = 0;
00921 dns_name_init(&zone->origin, NULL);
00922 zone->strnamerd = NULL;
00923 zone->strname = NULL;
00924 zone->strrdclass = NULL;
00925 zone->strviewname = NULL;
00926 zone->masterfile = NULL;
00927 ISC_LIST_INIT(zone->includes);
00928 ISC_LIST_INIT(zone->newincludes);
00929 zone->nincludes = 0;
00930 zone->masterformat = dns_masterformat_none;
00931 zone->masterstyle = NULL;
00932 zone->keydirectory = NULL;
00933 zone->journalsize = -1;
00934 zone->journal = NULL;
00935 zone->rdclass = dns_rdataclass_none;
00936 zone->type = dns_zone_none;
00937 zone->flags = 0;
00938 zone->options = 0;
00939 zone->options2 = 0;
00940 zone->keyopts = 0;
00941 zone->db_argc = 0;
00942 zone->db_argv = NULL;
00943 isc_time_settoepoch(&zone->expiretime);
00944 isc_time_settoepoch(&zone->refreshtime);
00945 isc_time_settoepoch(&zone->dumptime);
00946 isc_time_settoepoch(&zone->loadtime);
00947 zone->notifytime = now;
00948 isc_time_settoepoch(&zone->resigntime);
00949 isc_time_settoepoch(&zone->keywarntime);
00950 isc_time_settoepoch(&zone->signingtime);
00951 isc_time_settoepoch(&zone->nsec3chaintime);
00952 isc_time_settoepoch(&zone->refreshkeytime);
00953 zone->refreshkeyinterval = 0;
00954 zone->refreshkeycount = 0;
00955 zone->refresh = DNS_ZONE_DEFAULTREFRESH;
00956 zone->retry = DNS_ZONE_DEFAULTRETRY;
00957 zone->expire = 0;
00958 zone->minimum = 0;
00959 zone->maxrefresh = DNS_ZONE_MAXREFRESH;
00960 zone->minrefresh = DNS_ZONE_MINREFRESH;
00961 zone->maxretry = DNS_ZONE_MAXRETRY;
00962 zone->minretry = DNS_ZONE_MINRETRY;
00963 zone->masters = NULL;
00964 zone->masterdscps = NULL;
00965 zone->masterkeynames = NULL;
00966 zone->mastersok = NULL;
00967 zone->masterscnt = 0;
00968 zone->curmaster = 0;
00969 zone->maxttl = 0;
00970 zone->notify = NULL;
00971 zone->notifykeynames = NULL;
00972 zone->notifydscp = NULL;
00973 zone->notifytype = dns_notifytype_yes;
00974 zone->notifycnt = 0;
00975 zone->task = NULL;
00976 zone->loadtask = NULL;
00977 zone->update_acl = NULL;
00978 zone->forward_acl = NULL;
00979 zone->notify_acl = NULL;
00980 zone->query_acl = NULL;
00981 zone->queryon_acl = NULL;
00982 zone->xfr_acl = NULL;
00983 zone->update_disabled = ISC_FALSE;
00984 zone->zero_no_soa_ttl = ISC_TRUE;
00985 zone->check_names = dns_severity_ignore;
00986 zone->request = NULL;
00987 zone->lctx = NULL;
00988 zone->readio = NULL;
00989 zone->dctx = NULL;
00990 zone->writeio = NULL;
00991 zone->timer = NULL;
00992 zone->idlein = DNS_DEFAULT_IDLEIN;
00993 zone->idleout = DNS_DEFAULT_IDLEOUT;
00994 zone->log_key_expired_timer = 0;
00995 ISC_LIST_INIT(zone->notifies);
00996 isc_sockaddr_any(&zone->notifysrc4);
00997 isc_sockaddr_any6(&zone->notifysrc6);
00998 isc_sockaddr_any(&zone->xfrsource4);
00999 isc_sockaddr_any6(&zone->xfrsource6);
01000 isc_sockaddr_any(&zone->altxfrsource4);
01001 isc_sockaddr_any6(&zone->altxfrsource6);
01002 zone->notifysrc4dscp = -1;
01003 zone->notifysrc6dscp = -1;
01004 zone->xfrsource4dscp = -1;
01005 zone->xfrsource6dscp = -1;
01006 zone->altxfrsource4dscp = -1;
01007 zone->altxfrsource6dscp = -1;
01008 zone->xfr = NULL;
01009 zone->tsigkey = NULL;
01010 zone->maxxfrin = MAX_XFER_TIME;
01011 zone->maxxfrout = MAX_XFER_TIME;
01012 zone->ssutable = NULL;
01013 zone->sigvalidityinterval = 30 * 24 * 3600;
01014 zone->sigresigninginterval = 7 * 24 * 3600;
01015 zone->view = NULL;
01016 zone->acache = NULL;
01017 zone->checkmx = NULL;
01018 zone->checksrv = NULL;
01019 zone->checkns = NULL;
01020 ISC_LINK_INIT(zone, statelink);
01021 zone->statelist = NULL;
01022 zone->stats = NULL;
01023 zone->requeststats_on = ISC_FALSE;
01024 zone->statlevel = dns_zonestat_none;
01025 zone->requeststats = NULL;
01026 zone->rcvquerystats = NULL;
01027 zone->notifydelay = 5;
01028 zone->isself = NULL;
01029 zone->isselfarg = NULL;
01030 ISC_LIST_INIT(zone->signing);
01031 ISC_LIST_INIT(zone->nsec3chain);
01032 zone->signatures = 10;
01033 zone->nodes = 100;
01034 zone->privatetype = (dns_rdatatype_t)0xffffU;
01035 zone->added = ISC_FALSE;
01036 zone->automatic = ISC_FALSE;
01037 zone->rpzs = NULL;
01038 zone->rpz_num = DNS_RPZ_INVALID_NUM;
01039 ISC_LIST_INIT(zone->forwards);
01040 zone->raw = NULL;
01041 zone->secure = NULL;
01042 zone->sourceserial = 0;
01043 zone->sourceserialset = ISC_FALSE;
01044 zone->requestixfr = ISC_TRUE;
01045 zone->requestexpire = ISC_TRUE;
01046 ISC_LIST_INIT(zone->rss_events);
01047 zone->rss_db = NULL;
01048 zone->rss_raw = NULL;
01049 zone->rss_newver = NULL;
01050 zone->rss_oldver = NULL;
01051 zone->rss_event = NULL;
01052 zone->rss_state = NULL;
01053 zone->updatemethod = dns_updatemethod_increment;
01054
01055 zone->magic = ZONE_MAGIC;
01056
01057
01058 result = dns_zone_setdbtype(zone, dbargc_default, dbargv_default);
01059 if (result != ISC_R_SUCCESS)
01060 goto free_erefs;
01061
01062 ISC_EVENT_INIT(&zone->ctlevent, sizeof(zone->ctlevent), 0, NULL,
01063 DNS_EVENT_ZONECONTROL, zone_shutdown, zone, zone,
01064 NULL, NULL);
01065 *zonep = zone;
01066 return (ISC_R_SUCCESS);
01067
01068 free_erefs:
01069 isc_refcount_decrement(&zone->erefs, NULL);
01070 isc_refcount_destroy(&zone->erefs);
01071
01072 free_dblock:
01073 ZONEDB_DESTROYLOCK(&zone->dblock);
01074
01075 free_mutex:
01076 DESTROYLOCK(&zone->lock);
01077
01078 free_zone:
01079 isc_mem_putanddetach(&zone->mctx, zone, sizeof(*zone));
01080 return (result);
01081 }
01082
01083
01084
01085
01086
01087 static void
01088 zone_free(dns_zone_t *zone) {
01089 isc_mem_t *mctx = NULL;
01090 dns_signing_t *signing;
01091 dns_nsec3chain_t *nsec3chain;
01092 dns_include_t *include;
01093
01094 REQUIRE(DNS_ZONE_VALID(zone));
01095 REQUIRE(isc_refcount_current(&zone->erefs) == 0);
01096 REQUIRE(zone->irefs == 0);
01097 REQUIRE(!LOCKED_ZONE(zone));
01098 REQUIRE(zone->timer == NULL);
01099 REQUIRE(zone->zmgr == NULL);
01100
01101
01102
01103
01104 if (zone->request != NULL)
01105 dns_request_destroy(&zone->request);
01106 INSIST(zone->readio == NULL);
01107 INSIST(zone->statelist == NULL);
01108 INSIST(zone->writeio == NULL);
01109
01110 if (zone->task != NULL)
01111 isc_task_detach(&zone->task);
01112 if (zone->loadtask != NULL)
01113 isc_task_detach(&zone->loadtask);
01114
01115
01116 for (signing = ISC_LIST_HEAD(zone->signing);
01117 signing != NULL;
01118 signing = ISC_LIST_HEAD(zone->signing)) {
01119 ISC_LIST_UNLINK(zone->signing, signing, link);
01120 dns_db_detach(&signing->db);
01121 dns_dbiterator_destroy(&signing->dbiterator);
01122 isc_mem_put(zone->mctx, signing, sizeof *signing);
01123 }
01124 for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
01125 nsec3chain != NULL;
01126 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain)) {
01127 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link);
01128 dns_db_detach(&nsec3chain->db);
01129 dns_dbiterator_destroy(&nsec3chain->dbiterator);
01130 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
01131 }
01132 for (include = ISC_LIST_HEAD(zone->includes);
01133 include != NULL;
01134 include = ISC_LIST_HEAD(zone->includes)) {
01135 ISC_LIST_UNLINK(zone->includes, include, link);
01136 isc_mem_free(zone->mctx, include->name);
01137 isc_mem_put(zone->mctx, include, sizeof *include);
01138 }
01139 for (include = ISC_LIST_HEAD(zone->newincludes);
01140 include != NULL;
01141 include = ISC_LIST_HEAD(zone->newincludes)) {
01142 ISC_LIST_UNLINK(zone->newincludes, include, link);
01143 isc_mem_free(zone->mctx, include->name);
01144 isc_mem_put(zone->mctx, include, sizeof *include);
01145 }
01146 if (zone->masterfile != NULL)
01147 isc_mem_free(zone->mctx, zone->masterfile);
01148 zone->masterfile = NULL;
01149 if (zone->keydirectory != NULL)
01150 isc_mem_free(zone->mctx, zone->keydirectory);
01151 zone->keydirectory = NULL;
01152 zone->journalsize = -1;
01153 if (zone->journal != NULL)
01154 isc_mem_free(zone->mctx, zone->journal);
01155 zone->journal = NULL;
01156 if (zone->stats != NULL)
01157 isc_stats_detach(&zone->stats);
01158 if (zone->requeststats != NULL)
01159 isc_stats_detach(&zone->requeststats);
01160 if (zone->rcvquerystats != NULL)
01161 dns_stats_detach(&zone->rcvquerystats);
01162 if (zone->db != NULL)
01163 zone_detachdb(zone);
01164 if (zone->acache != NULL)
01165 dns_acache_detach(&zone->acache);
01166 if (zone->rpzs != NULL) {
01167 REQUIRE(zone->rpz_num < zone->rpzs->p.num_zones);
01168 dns_rpz_detach_rpzs(&zone->rpzs);
01169 zone->rpz_num = DNS_RPZ_INVALID_NUM;
01170 }
01171 zone_freedbargs(zone);
01172 RUNTIME_CHECK(dns_zone_setmasterswithkeys(zone, NULL, NULL, 0)
01173 == ISC_R_SUCCESS);
01174 RUNTIME_CHECK(dns_zone_setalsonotify(zone, NULL, 0)
01175 == ISC_R_SUCCESS);
01176 zone->check_names = dns_severity_ignore;
01177 if (zone->update_acl != NULL)
01178 dns_acl_detach(&zone->update_acl);
01179 if (zone->forward_acl != NULL)
01180 dns_acl_detach(&zone->forward_acl);
01181 if (zone->notify_acl != NULL)
01182 dns_acl_detach(&zone->notify_acl);
01183 if (zone->query_acl != NULL)
01184 dns_acl_detach(&zone->query_acl);
01185 if (zone->queryon_acl != NULL)
01186 dns_acl_detach(&zone->queryon_acl);
01187 if (zone->xfr_acl != NULL)
01188 dns_acl_detach(&zone->xfr_acl);
01189 if (dns_name_dynamic(&zone->origin))
01190 dns_name_free(&zone->origin, zone->mctx);
01191 if (zone->strnamerd != NULL)
01192 isc_mem_free(zone->mctx, zone->strnamerd);
01193 if (zone->strname != NULL)
01194 isc_mem_free(zone->mctx, zone->strname);
01195 if (zone->strrdclass != NULL)
01196 isc_mem_free(zone->mctx, zone->strrdclass);
01197 if (zone->strviewname != NULL)
01198 isc_mem_free(zone->mctx, zone->strviewname);
01199 if (zone->ssutable != NULL)
01200 dns_ssutable_detach(&zone->ssutable);
01201
01202
01203 ZONEDB_DESTROYLOCK(&zone->dblock);
01204 DESTROYLOCK(&zone->lock);
01205 isc_refcount_destroy(&zone->erefs);
01206 zone->magic = 0;
01207 mctx = zone->mctx;
01208 isc_mem_put(mctx, zone, sizeof(*zone));
01209 isc_mem_detach(&mctx);
01210 }
01211
01212
01213
01214
01215
01216 static inline isc_boolean_t
01217 inline_secure(dns_zone_t *zone) {
01218 REQUIRE(DNS_ZONE_VALID(zone));
01219 if (zone->raw != NULL)
01220 return (ISC_TRUE);
01221 return (ISC_FALSE);
01222 }
01223
01224
01225
01226
01227
01228 static inline isc_boolean_t
01229 inline_raw(dns_zone_t *zone) {
01230 REQUIRE(DNS_ZONE_VALID(zone));
01231 if (zone->secure != NULL)
01232 return (ISC_TRUE);
01233 return (ISC_FALSE);
01234 }
01235
01236
01237
01238
01239 void
01240 dns_zone_setclass(dns_zone_t *zone, dns_rdataclass_t rdclass) {
01241 char namebuf[1024];
01242
01243 REQUIRE(DNS_ZONE_VALID(zone));
01244 REQUIRE(rdclass != dns_rdataclass_none);
01245
01246
01247
01248
01249 LOCK_ZONE(zone);
01250 INSIST(zone != zone->raw);
01251 REQUIRE(zone->rdclass == dns_rdataclass_none ||
01252 zone->rdclass == rdclass);
01253 zone->rdclass = rdclass;
01254
01255 if (zone->strnamerd != NULL)
01256 isc_mem_free(zone->mctx, zone->strnamerd);
01257 if (zone->strrdclass != NULL)
01258 isc_mem_free(zone->mctx, zone->strrdclass);
01259
01260 zone_namerd_tostr(zone, namebuf, sizeof namebuf);
01261 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
01262 zone_rdclass_tostr(zone, namebuf, sizeof namebuf);
01263 zone->strrdclass = isc_mem_strdup(zone->mctx, namebuf);
01264
01265 if (inline_secure(zone))
01266 dns_zone_setclass(zone->raw, rdclass);
01267 UNLOCK_ZONE(zone);
01268 }
01269
01270 dns_rdataclass_t
01271 dns_zone_getclass(dns_zone_t *zone) {
01272 REQUIRE(DNS_ZONE_VALID(zone));
01273
01274 return (zone->rdclass);
01275 }
01276
01277 void
01278 dns_zone_setnotifytype(dns_zone_t *zone, dns_notifytype_t notifytype) {
01279 REQUIRE(DNS_ZONE_VALID(zone));
01280
01281 LOCK_ZONE(zone);
01282 zone->notifytype = notifytype;
01283 UNLOCK_ZONE(zone);
01284 }
01285
01286 isc_result_t
01287 dns_zone_getserial2(dns_zone_t *zone, isc_uint32_t *serialp) {
01288 isc_result_t result;
01289 unsigned int soacount;
01290
01291 REQUIRE(DNS_ZONE_VALID(zone));
01292 REQUIRE(serialp != NULL);
01293
01294 LOCK_ZONE(zone);
01295 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
01296 if (zone->db != NULL) {
01297 result = zone_get_from_db(zone, zone->db, NULL, &soacount,
01298 serialp, NULL, NULL, NULL, NULL,
01299 NULL);
01300 if (result == ISC_R_SUCCESS && soacount == 0)
01301 result = ISC_R_FAILURE;
01302 } else
01303 result = DNS_R_NOTLOADED;
01304 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
01305 UNLOCK_ZONE(zone);
01306
01307 return (result);
01308 }
01309
01310 isc_uint32_t
01311 dns_zone_getserial(dns_zone_t *zone) {
01312 isc_result_t result;
01313 isc_uint32_t serial;
01314
01315 result = dns_zone_getserial2(zone, &serial);
01316 if (result != ISC_R_SUCCESS)
01317 serial = 0;
01318
01319 return (serial);
01320 }
01321
01322
01323
01324
01325 void
01326 dns_zone_settype(dns_zone_t *zone, dns_zonetype_t type) {
01327 char namebuf[1024];
01328
01329 REQUIRE(DNS_ZONE_VALID(zone));
01330 REQUIRE(type != dns_zone_none);
01331
01332
01333
01334
01335 LOCK_ZONE(zone);
01336 REQUIRE(zone->type == dns_zone_none || zone->type == type);
01337 zone->type = type;
01338
01339 if (zone->strnamerd != NULL)
01340 isc_mem_free(zone->mctx, zone->strnamerd);
01341
01342 zone_namerd_tostr(zone, namebuf, sizeof namebuf);
01343 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
01344 UNLOCK_ZONE(zone);
01345 }
01346
01347 static void
01348 zone_freedbargs(dns_zone_t *zone) {
01349 unsigned int i;
01350
01351
01352 if (zone->db_argv != NULL) {
01353 for (i = 0; i < zone->db_argc; i++)
01354 isc_mem_free(zone->mctx, zone->db_argv[i]);
01355 isc_mem_put(zone->mctx, zone->db_argv,
01356 zone->db_argc * sizeof(*zone->db_argv));
01357 }
01358 zone->db_argc = 0;
01359 zone->db_argv = NULL;
01360 }
01361
01362 isc_result_t
01363 dns_zone_getdbtype(dns_zone_t *zone, char ***argv, isc_mem_t *mctx) {
01364 size_t size = 0;
01365 unsigned int i;
01366 isc_result_t result = ISC_R_SUCCESS;
01367 void *mem;
01368 char **tmp, *tmp2;
01369
01370 REQUIRE(DNS_ZONE_VALID(zone));
01371 REQUIRE(argv != NULL && *argv == NULL);
01372
01373 LOCK_ZONE(zone);
01374 size = (zone->db_argc + 1) * sizeof(char *);
01375 for (i = 0; i < zone->db_argc; i++)
01376 size += strlen(zone->db_argv[i]) + 1;
01377 mem = isc_mem_allocate(mctx, size);
01378 if (mem != NULL) {
01379 tmp = mem;
01380 tmp2 = mem;
01381 tmp2 += (zone->db_argc + 1) * sizeof(char *);
01382 for (i = 0; i < zone->db_argc; i++) {
01383 *tmp++ = tmp2;
01384 strcpy(tmp2, zone->db_argv[i]);
01385 tmp2 += strlen(tmp2) + 1;
01386 }
01387 *tmp = NULL;
01388 } else
01389 result = ISC_R_NOMEMORY;
01390 UNLOCK_ZONE(zone);
01391 *argv = mem;
01392 return (result);
01393 }
01394
01395 isc_result_t
01396 dns_zone_setdbtype(dns_zone_t *zone,
01397 unsigned int dbargc, const char * const *dbargv) {
01398 isc_result_t result = ISC_R_SUCCESS;
01399 char **new = NULL;
01400 unsigned int i;
01401
01402 REQUIRE(DNS_ZONE_VALID(zone));
01403 REQUIRE(dbargc >= 1);
01404 REQUIRE(dbargv != NULL);
01405
01406 LOCK_ZONE(zone);
01407
01408
01409 new = isc_mem_get(zone->mctx, dbargc * sizeof(*new));
01410 if (new == NULL)
01411 goto nomem;
01412 for (i = 0; i < dbargc; i++)
01413 new[i] = NULL;
01414 for (i = 0; i < dbargc; i++) {
01415 new[i] = isc_mem_strdup(zone->mctx, dbargv[i]);
01416 if (new[i] == NULL)
01417 goto nomem;
01418 }
01419
01420
01421 zone_freedbargs(zone);
01422
01423 zone->db_argc = dbargc;
01424 zone->db_argv = new;
01425 result = ISC_R_SUCCESS;
01426 goto unlock;
01427
01428 nomem:
01429 if (new != NULL) {
01430 for (i = 0; i < dbargc; i++)
01431 if (new[i] != NULL)
01432 isc_mem_free(zone->mctx, new[i]);
01433 isc_mem_put(zone->mctx, new, dbargc * sizeof(*new));
01434 }
01435 result = ISC_R_NOMEMORY;
01436
01437 unlock:
01438 UNLOCK_ZONE(zone);
01439 return (result);
01440 }
01441
01442 void
01443 dns_zone_setview(dns_zone_t *zone, dns_view_t *view) {
01444 char namebuf[1024];
01445 REQUIRE(DNS_ZONE_VALID(zone));
01446
01447 LOCK_ZONE(zone);
01448 INSIST(zone != zone->raw);
01449 if (zone->view != NULL)
01450 dns_view_weakdetach(&zone->view);
01451 dns_view_weakattach(view, &zone->view);
01452
01453 if (zone->strviewname != NULL)
01454 isc_mem_free(zone->mctx, zone->strviewname);
01455 if (zone->strnamerd != NULL)
01456 isc_mem_free(zone->mctx, zone->strnamerd);
01457
01458 zone_namerd_tostr(zone, namebuf, sizeof namebuf);
01459 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
01460 zone_viewname_tostr(zone, namebuf, sizeof namebuf);
01461 zone->strviewname = isc_mem_strdup(zone->mctx, namebuf);
01462
01463 if (inline_secure(zone))
01464 dns_zone_setview(zone->raw, view);
01465
01466 UNLOCK_ZONE(zone);
01467 }
01468
01469 dns_view_t *
01470 dns_zone_getview(dns_zone_t *zone) {
01471 REQUIRE(DNS_ZONE_VALID(zone));
01472
01473 return (zone->view);
01474 }
01475
01476
01477 isc_result_t
01478 dns_zone_setorigin(dns_zone_t *zone, const dns_name_t *origin) {
01479 isc_result_t result;
01480 char namebuf[1024];
01481
01482 REQUIRE(DNS_ZONE_VALID(zone));
01483 REQUIRE(origin != NULL);
01484
01485 LOCK_ZONE(zone);
01486 INSIST(zone != zone->raw);
01487 if (dns_name_dynamic(&zone->origin)) {
01488 dns_name_free(&zone->origin, zone->mctx);
01489 dns_name_init(&zone->origin, NULL);
01490 }
01491 result = dns_name_dup(origin, zone->mctx, &zone->origin);
01492
01493 if (zone->strnamerd != NULL)
01494 isc_mem_free(zone->mctx, zone->strnamerd);
01495 if (zone->strname != NULL)
01496 isc_mem_free(zone->mctx, zone->strname);
01497
01498 zone_namerd_tostr(zone, namebuf, sizeof namebuf);
01499 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
01500 zone_name_tostr(zone, namebuf, sizeof namebuf);
01501 zone->strname = isc_mem_strdup(zone->mctx, namebuf);
01502
01503 if (result == ISC_R_SUCCESS && inline_secure(zone))
01504 result = dns_zone_setorigin(zone->raw, origin);
01505 UNLOCK_ZONE(zone);
01506 return (result);
01507 }
01508
01509 void
01510 dns_zone_setacache(dns_zone_t *zone, dns_acache_t *acache) {
01511 REQUIRE(DNS_ZONE_VALID(zone));
01512 REQUIRE(acache != NULL);
01513
01514 LOCK_ZONE(zone);
01515 if (zone->acache != NULL)
01516 dns_acache_detach(&zone->acache);
01517 dns_acache_attach(acache, &zone->acache);
01518 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
01519 if (zone->db != NULL) {
01520 isc_result_t result;
01521
01522
01523
01524
01525
01526
01527
01528 result = dns_acache_setdb(acache, zone->db);
01529 if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) {
01530 UNEXPECTED_ERROR(__FILE__, __LINE__,
01531 "dns_acache_setdb() failed: %s",
01532 isc_result_totext(result));
01533 }
01534 }
01535 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
01536 UNLOCK_ZONE(zone);
01537 }
01538
01539 static isc_result_t
01540 dns_zone_setstring(dns_zone_t *zone, char **field, const char *value) {
01541 char *copy;
01542
01543 if (value != NULL) {
01544 copy = isc_mem_strdup(zone->mctx, value);
01545 if (copy == NULL)
01546 return (ISC_R_NOMEMORY);
01547 } else {
01548 copy = NULL;
01549 }
01550
01551 if (*field != NULL)
01552 isc_mem_free(zone->mctx, *field);
01553
01554 *field = copy;
01555 return (ISC_R_SUCCESS);
01556 }
01557
01558 isc_result_t
01559 dns_zone_setfile(dns_zone_t *zone, const char *file) {
01560 return (dns_zone_setfile3(zone, file, dns_masterformat_text,
01561 &dns_master_style_default));
01562 }
01563
01564 isc_result_t
01565 dns_zone_setfile2(dns_zone_t *zone, const char *file,
01566 dns_masterformat_t format)
01567 {
01568 return (dns_zone_setfile3(zone, file, format,
01569 &dns_master_style_default));
01570 }
01571
01572 isc_result_t
01573 dns_zone_setfile3(dns_zone_t *zone, const char *file,
01574 dns_masterformat_t format,
01575 const dns_master_style_t *style)
01576 {
01577 isc_result_t result = ISC_R_SUCCESS;
01578
01579 REQUIRE(DNS_ZONE_VALID(zone));
01580
01581 LOCK_ZONE(zone);
01582 result = dns_zone_setstring(zone, &zone->masterfile, file);
01583 if (result == ISC_R_SUCCESS) {
01584 zone->masterformat = format;
01585 if (format == dns_masterformat_text)
01586 zone->masterstyle = style;
01587 result = default_journal(zone);
01588 }
01589 UNLOCK_ZONE(zone);
01590
01591 return (result);
01592 }
01593
01594 const char *
01595 dns_zone_getfile(dns_zone_t *zone) {
01596 REQUIRE(DNS_ZONE_VALID(zone));
01597
01598 return (zone->masterfile);
01599 }
01600
01601 dns_ttl_t
01602 dns_zone_getmaxttl(dns_zone_t *zone) {
01603 REQUIRE(DNS_ZONE_VALID(zone));
01604
01605 return (zone->maxttl);
01606 }
01607
01608 void
01609 dns_zone_setmaxttl(dns_zone_t *zone, dns_ttl_t maxttl) {
01610 REQUIRE(DNS_ZONE_VALID(zone));
01611
01612 LOCK_ZONE(zone);
01613 if (maxttl != 0)
01614 zone->options2 |= DNS_ZONEOPT2_CHECKTTL;
01615 else
01616 zone->options2 &= ~DNS_ZONEOPT2_CHECKTTL;
01617 zone->maxttl = maxttl;
01618 UNLOCK_ZONE(zone);
01619
01620 return;
01621 }
01622
01623 static isc_result_t
01624 default_journal(dns_zone_t *zone) {
01625 isc_result_t result;
01626 char *journal;
01627
01628 REQUIRE(DNS_ZONE_VALID(zone));
01629 REQUIRE(LOCKED_ZONE(zone));
01630
01631 if (zone->masterfile != NULL) {
01632
01633 int len = strlen(zone->masterfile) + sizeof(".jnl");
01634 journal = isc_mem_allocate(zone->mctx, len);
01635 if (journal == NULL)
01636 return (ISC_R_NOMEMORY);
01637 strcpy(journal, zone->masterfile);
01638 strcat(journal, ".jnl");
01639 } else {
01640 journal = NULL;
01641 }
01642 result = dns_zone_setstring(zone, &zone->journal, journal);
01643 if (journal != NULL)
01644 isc_mem_free(zone->mctx, journal);
01645 return (result);
01646 }
01647
01648 isc_result_t
01649 dns_zone_setjournal(dns_zone_t *zone, const char *myjournal) {
01650 isc_result_t result = ISC_R_SUCCESS;
01651
01652 REQUIRE(DNS_ZONE_VALID(zone));
01653
01654 LOCK_ZONE(zone);
01655 result = dns_zone_setstring(zone, &zone->journal, myjournal);
01656 UNLOCK_ZONE(zone);
01657
01658 return (result);
01659 }
01660
01661 char *
01662 dns_zone_getjournal(dns_zone_t *zone) {
01663 REQUIRE(DNS_ZONE_VALID(zone));
01664
01665 return (zone->journal);
01666 }
01667
01668
01669
01670
01671
01672
01673
01674
01675
01676
01677 isc_boolean_t
01678 dns_zone_isdynamic(dns_zone_t *zone, isc_boolean_t ignore_freeze) {
01679 REQUIRE(DNS_ZONE_VALID(zone));
01680
01681 if (zone->type == dns_zone_slave || zone->type == dns_zone_stub ||
01682 zone->type == dns_zone_key ||
01683 (zone->type == dns_zone_redirect && zone->masters != NULL))
01684 return (ISC_TRUE);
01685
01686
01687 if (zone->type == dns_zone_master &&
01688 (!zone->update_disabled || ignore_freeze) &&
01689 ((zone->ssutable != NULL) ||
01690 (zone->update_acl != NULL && !dns_acl_isnone(zone->update_acl))))
01691 return (ISC_TRUE);
01692
01693 return (ISC_FALSE);
01694
01695 }
01696
01697
01698
01699
01700 isc_result_t
01701 dns_zone_rpz_enable(dns_zone_t *zone, dns_rpz_zones_t *rpzs,
01702 dns_rpz_num_t rpz_num)
01703 {
01704
01705
01706
01707
01708
01709
01710 if (strcmp(zone->db_argv[0], "rbt") != 0 &&
01711 strcmp(zone->db_argv[0], "rbt64") != 0)
01712 return (ISC_R_NOTIMPLEMENTED);
01713
01714
01715
01716
01717 LOCK_ZONE(zone);
01718 if (zone->rpzs != NULL) {
01719 REQUIRE(zone->rpzs == rpzs && zone->rpz_num == rpz_num);
01720 } else {
01721 REQUIRE(zone->rpz_num == DNS_RPZ_INVALID_NUM);
01722 dns_rpz_attach_rpzs(rpzs, &zone->rpzs);
01723 zone->rpz_num = rpz_num;
01724 }
01725 rpzs->defined |= DNS_RPZ_ZBIT(rpz_num);
01726 UNLOCK_ZONE(zone);
01727
01728 return (ISC_R_SUCCESS);
01729 }
01730
01731 dns_rpz_num_t
01732 dns_zone_get_rpz_num(dns_zone_t *zone) {
01733 return (zone->rpz_num);
01734 }
01735
01736
01737
01738
01739 void
01740 dns_zone_rpz_enable_db(dns_zone_t *zone, dns_db_t *db) {
01741 if (zone->rpz_num != DNS_RPZ_INVALID_NUM) {
01742 REQUIRE(zone->rpzs != NULL);
01743 dns_db_rpz_attach(db, zone->rpzs, zone->rpz_num);
01744 }
01745 }
01746
01747 static isc_boolean_t
01748 zone_touched(dns_zone_t *zone) {
01749 isc_result_t result;
01750 isc_time_t modtime;
01751 dns_include_t *include;
01752
01753 REQUIRE(DNS_ZONE_VALID(zone));
01754
01755 result = isc_file_getmodtime(zone->masterfile, &modtime);
01756 if (result != ISC_R_SUCCESS ||
01757 isc_time_compare(&modtime, &zone->loadtime) > 0)
01758 {
01759 zone->loadtime = modtime;
01760 return (ISC_TRUE);
01761 }
01762
01763 for (include = ISC_LIST_HEAD(zone->includes);
01764 include != NULL;
01765 include = ISC_LIST_NEXT(include, link))
01766 {
01767 result = isc_file_getmodtime(include->name, &modtime);
01768 if (result != ISC_R_SUCCESS ||
01769 isc_time_compare(&modtime, &include->filetime) > 0)
01770 return (ISC_TRUE);
01771 }
01772
01773
01774 return (ISC_FALSE);
01775 }
01776
01777 static isc_result_t
01778 zone_load(dns_zone_t *zone, unsigned int flags, isc_boolean_t locked) {
01779 isc_result_t result;
01780 isc_time_t now;
01781 isc_time_t loadtime;
01782 dns_db_t *db = NULL;
01783 isc_boolean_t rbt, hasraw;
01784
01785 REQUIRE(DNS_ZONE_VALID(zone));
01786
01787 if (!locked)
01788 LOCK_ZONE(zone);
01789
01790 INSIST(zone != zone->raw);
01791 hasraw = inline_secure(zone);
01792 if (hasraw) {
01793 result = zone_load(zone->raw, flags, ISC_FALSE);
01794 if (result != ISC_R_SUCCESS) {
01795 if (!locked)
01796 UNLOCK_ZONE(zone);
01797 return(result);
01798 }
01799 LOCK_ZONE(zone->raw);
01800 }
01801
01802 TIME_NOW(&now);
01803
01804 INSIST(zone->type != dns_zone_none);
01805
01806 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING)) {
01807 if ((flags & DNS_ZONELOADFLAG_THAW) != 0)
01808 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW);
01809 result = DNS_R_CONTINUE;
01810 goto cleanup;
01811 }
01812
01813 INSIST(zone->db_argc >= 1);
01814
01815 rbt = strcmp(zone->db_argv[0], "rbt") == 0 ||
01816 strcmp(zone->db_argv[0], "rbt64") == 0;
01817
01818 if (zone->db != NULL && zone->masterfile == NULL && rbt) {
01819
01820
01821
01822 result = ISC_R_SUCCESS;
01823 goto cleanup;
01824 }
01825
01826 if (zone->db != NULL && dns_zone_isdynamic(zone, ISC_FALSE)) {
01827
01828
01829
01830
01831
01832 if (zone->type == dns_zone_master)
01833 result = DNS_R_DYNAMIC;
01834 else
01835 result = ISC_R_SUCCESS;
01836 goto cleanup;
01837 }
01838
01839
01840
01841
01842
01843
01844
01845 TIME_NOW(&loadtime);
01846
01847
01848
01849
01850
01851
01852 if (zone->masterfile != NULL) {
01853
01854
01855
01856
01857 if (!isc_time_isepoch(&zone->loadtime) &&
01858 (flags & DNS_ZONELOADFLAG_NOSTAT) != 0) {
01859 result = ISC_R_SUCCESS;
01860 goto cleanup;
01861 }
01862
01863 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
01864 !zone_touched(zone))
01865 {
01866 dns_zone_log(zone, ISC_LOG_DEBUG(1),
01867 "skipping load: master file "
01868 "older than last load");
01869 result = DNS_R_UPTODATE;
01870 goto cleanup;
01871 }
01872 }
01873
01874
01875
01876
01877
01878 if (zone->type == dns_zone_master &&
01879 strcmp(zone->db_argv[0], "_builtin") == 0 &&
01880 (zone->db_argc < 2 || strcmp(zone->db_argv[1], "empty") != 0) &&
01881 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
01882 result = ISC_R_SUCCESS;
01883 goto cleanup;
01884 }
01885
01886
01887
01888
01889
01890 if (strcmp(zone->db_argv[0], "dlz") == 0) {
01891 dns_dlzdb_t *dlzdb;
01892 dns_dlzfindzone_t findzone;
01893
01894 for (dlzdb = ISC_LIST_HEAD(zone->view->dlz_unsearched);
01895 dlzdb != NULL;
01896 dlzdb = ISC_LIST_NEXT(dlzdb, link))
01897 {
01898 INSIST(DNS_DLZ_VALID(dlzdb));
01899 if (strcmp(zone->db_argv[1], dlzdb->dlzname) == 0)
01900 break;
01901 }
01902
01903 if (dlzdb == NULL) {
01904 dns_zone_log(zone, ISC_LOG_ERROR,
01905 "DLZ %s does not exist or is set "
01906 "to 'search yes;'", zone->db_argv[1]);
01907 result = ISC_R_NOTFOUND;
01908 goto cleanup;
01909 }
01910
01911 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
01912
01913 findzone = dlzdb->implementation->methods->findzone;
01914 result = (*findzone)(dlzdb->implementation->driverarg,
01915 dlzdb->dbdata, dlzdb->mctx,
01916 zone->view->rdclass, &zone->origin,
01917 NULL, NULL, &db);
01918 if (result != ISC_R_NOTFOUND) {
01919 if (zone->db != NULL)
01920 zone_detachdb(zone);
01921 zone_attachdb(zone, db);
01922 dns_db_detach(&db);
01923 result = ISC_R_SUCCESS;
01924 }
01925 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
01926
01927 if (result == ISC_R_SUCCESS) {
01928 if (dlzdb->configure_callback == NULL)
01929 goto cleanup;
01930
01931 result = (*dlzdb->configure_callback)(zone->view,
01932 dlzdb, zone);
01933 if (result != ISC_R_SUCCESS)
01934 dns_zone_log(zone, ISC_LOG_ERROR,
01935 "DLZ configuration callback: %s",
01936 isc_result_totext(result));
01937 }
01938 goto cleanup;
01939 }
01940
01941 if ((zone->type == dns_zone_slave || zone->type == dns_zone_stub ||
01942 (zone->type == dns_zone_redirect && zone->masters != NULL)) &&
01943 rbt) {
01944 if (zone->masterfile == NULL ||
01945 !isc_file_exists(zone->masterfile)) {
01946 if (zone->masterfile != NULL) {
01947 dns_zone_log(zone, ISC_LOG_DEBUG(1),
01948 "no master file");
01949 }
01950 zone->refreshtime = now;
01951 if (zone->task != NULL)
01952 zone_settimer(zone, &now);
01953 result = ISC_R_SUCCESS;
01954 goto cleanup;
01955 }
01956 }
01957
01958 dns_zone_log(zone, ISC_LOG_DEBUG(1), "starting load");
01959
01960 result = dns_db_create(zone->mctx, zone->db_argv[0],
01961 &zone->origin, (zone->type == dns_zone_stub) ?
01962 dns_dbtype_stub : dns_dbtype_zone,
01963 zone->rdclass,
01964 zone->db_argc - 1, zone->db_argv + 1,
01965 &db);
01966
01967 if (result != ISC_R_SUCCESS) {
01968 dns_zone_log(zone, ISC_LOG_ERROR,
01969 "loading zone: creating database: %s",
01970 isc_result_totext(result));
01971 goto cleanup;
01972 }
01973 dns_db_settask(db, zone->task);
01974
01975 if (! dns_db_ispersistent(db)) {
01976 if (zone->masterfile != NULL) {
01977 result = zone_startload(db, zone, loadtime);
01978 } else {
01979 result = DNS_R_NOMASTERFILE;
01980 if (zone->type == dns_zone_master ||
01981 (zone->type == dns_zone_redirect &&
01982 zone->masters == NULL)) {
01983 dns_zone_log(zone, ISC_LOG_ERROR,
01984 "loading zone: "
01985 "no master file configured");
01986 goto cleanup;
01987 }
01988 dns_zone_log(zone, ISC_LOG_INFO, "loading zone: "
01989 "no master file configured: continuing");
01990 }
01991 }
01992
01993 if (result == DNS_R_CONTINUE) {
01994 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADING);
01995 if ((flags & DNS_ZONELOADFLAG_THAW) != 0)
01996 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW);
01997 goto cleanup;
01998 }
01999
02000 result = zone_postload(zone, db, loadtime, result);
02001
02002 cleanup:
02003 if (hasraw)
02004 UNLOCK_ZONE(zone->raw);
02005 if (!locked)
02006 UNLOCK_ZONE(zone);
02007 if (db != NULL)
02008 dns_db_detach(&db);
02009 return (result);
02010 }
02011
02012 isc_result_t
02013 dns_zone_load(dns_zone_t *zone) {
02014 return (zone_load(zone, 0, ISC_FALSE));
02015 }
02016
02017 isc_result_t
02018 dns_zone_loadnew(dns_zone_t *zone) {
02019 return (zone_load(zone, DNS_ZONELOADFLAG_NOSTAT, ISC_FALSE));
02020 }
02021
02022 static void
02023 zone_asyncload(isc_task_t *task, isc_event_t *event) {
02024 dns_asyncload_t *asl = event->ev_arg;
02025 dns_zone_t *zone = asl->zone;
02026 isc_result_t result = ISC_R_SUCCESS;
02027 isc_boolean_t load_pending;
02028
02029 UNUSED(task);
02030
02031 REQUIRE(DNS_ZONE_VALID(zone));
02032
02033 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0)
02034 result = ISC_R_CANCELED;
02035 isc_event_free(&event);
02036
02037 if (result == ISC_R_CANCELED)
02038 goto cleanup;
02039
02040
02041 LOCK_ZONE(zone);
02042 load_pending = ISC_TF(DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING));
02043
02044 if (!load_pending) {
02045 UNLOCK_ZONE(zone);
02046 goto cleanup;
02047 }
02048
02049 zone_load(zone, 0, ISC_TRUE);
02050
02051 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADPENDING);
02052 UNLOCK_ZONE(zone);
02053
02054
02055 if (asl->loaded != NULL)
02056 (asl->loaded)(asl->loaded_arg, zone, task);
02057
02058 cleanup:
02059 isc_mem_put(zone->mctx, asl, sizeof (*asl));
02060 dns_zone_idetach(&zone);
02061 }
02062
02063 isc_result_t
02064 dns_zone_asyncload(dns_zone_t *zone, dns_zt_zoneloaded_t done, void *arg) {
02065 isc_event_t *e;
02066 dns_asyncload_t *asl = NULL;
02067 isc_result_t result = ISC_R_SUCCESS;
02068
02069 REQUIRE(DNS_ZONE_VALID(zone));
02070
02071 if (zone->zmgr == NULL)
02072 return (ISC_R_FAILURE);
02073
02074
02075 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING))
02076 return (ISC_R_ALREADYRUNNING);
02077
02078 asl = isc_mem_get(zone->mctx, sizeof (*asl));
02079 if (asl == NULL)
02080 CHECK(ISC_R_NOMEMORY);
02081
02082 asl->zone = NULL;
02083 asl->loaded = done;
02084 asl->loaded_arg = arg;
02085
02086 e = isc_event_allocate(zone->zmgr->mctx, zone->zmgr,
02087 DNS_EVENT_ZONELOAD,
02088 zone_asyncload, asl,
02089 sizeof(isc_event_t));
02090 if (e == NULL)
02091 CHECK(ISC_R_NOMEMORY);
02092
02093 LOCK_ZONE(zone);
02094 zone_iattach(zone, &asl->zone);
02095 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADPENDING);
02096 isc_task_send(zone->loadtask, &e);
02097 UNLOCK_ZONE(zone);
02098
02099 return (ISC_R_SUCCESS);
02100
02101 failure:
02102 if (asl != NULL)
02103 isc_mem_put(zone->mctx, asl, sizeof (*asl));
02104 return (result);
02105 }
02106
02107 isc_boolean_t
02108 dns__zone_loadpending(dns_zone_t *zone) {
02109 REQUIRE(DNS_ZONE_VALID(zone));
02110
02111 return (ISC_TF(DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING)));
02112 }
02113
02114 isc_result_t
02115 dns_zone_loadandthaw(dns_zone_t *zone) {
02116 isc_result_t result;
02117
02118 if (inline_raw(zone))
02119 result = zone_load(zone->secure, DNS_ZONELOADFLAG_THAW,
02120 ISC_FALSE);
02121 else
02122 result = zone_load(zone, DNS_ZONELOADFLAG_THAW, ISC_FALSE);
02123
02124 switch (result) {
02125 case DNS_R_CONTINUE:
02126
02127 break;
02128 case DNS_R_UPTODATE:
02129 case ISC_R_SUCCESS:
02130 case DNS_R_SEENINCLUDE:
02131 zone->update_disabled = ISC_FALSE;
02132 break;
02133 case DNS_R_NOMASTERFILE:
02134 zone->update_disabled = ISC_FALSE;
02135 break;
02136 default:
02137
02138 break;
02139 }
02140 return (result);
02141 }
02142
02143 static unsigned int
02144 get_master_options(dns_zone_t *zone) {
02145 unsigned int options;
02146
02147 options = DNS_MASTER_ZONE | DNS_MASTER_RESIGN;
02148 if (zone->type == dns_zone_slave ||
02149 (zone->type == dns_zone_redirect && zone->masters == NULL))
02150 options |= DNS_MASTER_SLAVE;
02151 if (zone->type == dns_zone_key)
02152 options |= DNS_MASTER_KEY;
02153 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNS))
02154 options |= DNS_MASTER_CHECKNS;
02155 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_FATALNS))
02156 options |= DNS_MASTER_FATALNS;
02157 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES))
02158 options |= DNS_MASTER_CHECKNAMES;
02159 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL))
02160 options |= DNS_MASTER_CHECKNAMESFAIL;
02161 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMX))
02162 options |= DNS_MASTER_CHECKMX;
02163 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMXFAIL))
02164 options |= DNS_MASTER_CHECKMXFAIL;
02165 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKWILDCARD))
02166 options |= DNS_MASTER_CHECKWILDCARD;
02167 if (DNS_ZONE_OPTION2(zone, DNS_ZONEOPT2_CHECKTTL))
02168 options |= DNS_MASTER_CHECKTTL;
02169 return (options);
02170 }
02171
02172 static void
02173 zone_registerinclude(const char *filename, void *arg) {
02174 isc_result_t result;
02175 dns_zone_t *zone = (dns_zone_t *) arg;
02176 dns_include_t *inc = NULL;
02177
02178 REQUIRE(DNS_ZONE_VALID(zone));
02179
02180 if (filename == NULL)
02181 return;
02182
02183
02184
02185
02186 for (inc = ISC_LIST_HEAD(zone->newincludes);
02187 inc != NULL;
02188 inc = ISC_LIST_NEXT(inc, link))
02189 if (strcmp(filename, inc->name) == 0)
02190 return;
02191
02192 inc = isc_mem_get(zone->mctx, sizeof(dns_include_t));
02193 if (inc == NULL)
02194 return;
02195 inc->name = isc_mem_strdup(zone->mctx, filename);
02196 if (inc->name == NULL) {
02197 isc_mem_put(zone->mctx, inc, sizeof(dns_include_t));
02198 return;
02199 }
02200 ISC_LINK_INIT(inc, link);
02201
02202 result = isc_file_getmodtime(filename, &inc->filetime);
02203 if (result != ISC_R_SUCCESS)
02204 isc_time_settoepoch(&inc->filetime);
02205
02206 ISC_LIST_APPEND(zone->newincludes, inc, link);
02207 }
02208
02209 static void
02210 zone_gotreadhandle(isc_task_t *task, isc_event_t *event) {
02211 dns_load_t *load = event->ev_arg;
02212 isc_result_t result = ISC_R_SUCCESS;
02213 unsigned int options;
02214
02215 REQUIRE(DNS_LOAD_VALID(load));
02216
02217 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0)
02218 result = ISC_R_CANCELED;
02219 isc_event_free(&event);
02220 if (result == ISC_R_CANCELED)
02221 goto fail;
02222
02223 options = get_master_options(load->zone);
02224
02225 result = dns_master_loadfileinc5(load->zone->masterfile,
02226 dns_db_origin(load->db),
02227 dns_db_origin(load->db),
02228 load->zone->rdclass, options, 0,
02229 &load->callbacks, task,
02230 zone_loaddone, load,
02231 &load->zone->lctx,
02232 zone_registerinclude,
02233 load->zone, load->zone->mctx,
02234 load->zone->masterformat,
02235 load->zone->maxttl);
02236 if (result != ISC_R_SUCCESS && result != DNS_R_CONTINUE &&
02237 result != DNS_R_SEENINCLUDE)
02238 goto fail;
02239 return;
02240
02241 fail:
02242 zone_loaddone(load, result);
02243 }
02244
02245 static void
02246 get_raw_serial(dns_zone_t *raw, dns_masterrawheader_t *rawdata) {
02247 isc_result_t result;
02248 unsigned int soacount;
02249
02250 LOCK(&raw->lock);
02251 if (raw->db != NULL) {
02252 result = zone_get_from_db(raw, raw->db, NULL, &soacount,
02253 &rawdata->sourceserial,
02254 NULL, NULL, NULL, NULL,
02255 NULL);
02256 if (result == ISC_R_SUCCESS && soacount > 0U)
02257 rawdata->flags |= DNS_MASTERRAW_SOURCESERIALSET;
02258 }
02259 UNLOCK(&raw->lock);
02260 }
02261
02262 static void
02263 zone_gotwritehandle(isc_task_t *task, isc_event_t *event) {
02264 const char me[] = "zone_gotwritehandle";
02265 dns_zone_t *zone = event->ev_arg;
02266 isc_result_t result = ISC_R_SUCCESS;
02267 dns_dbversion_t *version = NULL;
02268 dns_masterrawheader_t rawdata;
02269
02270 REQUIRE(DNS_ZONE_VALID(zone));
02271 INSIST(task == zone->task);
02272 ENTER;
02273
02274 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0)
02275 result = ISC_R_CANCELED;
02276 isc_event_free(&event);
02277 if (result == ISC_R_CANCELED)
02278 goto fail;
02279
02280 LOCK_ZONE(zone);
02281 INSIST(zone != zone->raw);
02282 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
02283 if (zone->db != NULL) {
02284 const dns_master_style_t *output_style;
02285
02286 dns_db_currentversion(zone->db, &version);
02287 dns_master_initrawheader(&rawdata);
02288 if (inline_secure(zone))
02289 get_raw_serial(zone->raw, &rawdata);
02290 if (zone->type == dns_zone_key)
02291 output_style = &dns_master_style_keyzone;
02292 else if (zone->masterstyle != NULL)
02293 output_style = zone->masterstyle;
02294 else
02295 output_style = &dns_master_style_default;
02296 result = dns_master_dumpinc3(zone->mctx, zone->db, version,
02297 output_style, zone->masterfile,
02298 zone->task, dump_done, zone, &zone->dctx, zone->masterformat,
02299 &rawdata);
02300 dns_db_closeversion(zone->db, &version, ISC_FALSE);
02301 } else
02302 result = ISC_R_CANCELED;
02303 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
02304 UNLOCK_ZONE(zone);
02305 if (result != DNS_R_CONTINUE)
02306 goto fail;
02307 return;
02308
02309 fail:
02310 dump_done(zone, result);
02311 }
02312
02313
02314
02315
02316
02317
02318
02319 static void
02320 zone_setrawdata(dns_zone_t *zone, dns_masterrawheader_t *header) {
02321 if ((header->flags & DNS_MASTERRAW_SOURCESERIALSET) == 0)
02322 return;
02323
02324 zone->sourceserial = header->sourceserial;
02325 zone->sourceserialset = ISC_TRUE;
02326 }
02327
02328 void
02329 dns_zone_setrawdata(dns_zone_t *zone, dns_masterrawheader_t *header) {
02330 if (zone == NULL)
02331 return;
02332
02333 LOCK_ZONE(zone);
02334 zone_setrawdata(zone, header);
02335 UNLOCK_ZONE(zone);
02336 }
02337
02338 static isc_result_t
02339 zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) {
02340 dns_load_t *load;
02341 isc_result_t result;
02342 isc_result_t tresult;
02343 unsigned int options;
02344
02345 dns_zone_rpz_enable_db(zone, db);
02346 options = get_master_options(zone);
02347 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MANYERRORS))
02348 options |= DNS_MASTER_MANYERRORS;
02349
02350 if (zone->zmgr != NULL && zone->db != NULL && zone->loadtask != NULL) {
02351 load = isc_mem_get(zone->mctx, sizeof(*load));
02352 if (load == NULL)
02353 return (ISC_R_NOMEMORY);
02354
02355 load->mctx = NULL;
02356 load->zone = NULL;
02357 load->db = NULL;
02358 load->loadtime = loadtime;
02359 load->magic = LOAD_MAGIC;
02360
02361 isc_mem_attach(zone->mctx, &load->mctx);
02362 zone_iattach(zone, &load->zone);
02363 dns_db_attach(db, &load->db);
02364 dns_rdatacallbacks_init(&load->callbacks);
02365 load->callbacks.rawdata = zone_setrawdata;
02366 zone_iattach(zone, &load->callbacks.zone);
02367 result = dns_db_beginload(db, &load->callbacks);
02368 if (result != ISC_R_SUCCESS)
02369 goto cleanup;
02370 result = zonemgr_getio(zone->zmgr, ISC_TRUE, zone->loadtask,
02371 zone_gotreadhandle, load,
02372 &zone->readio);
02373 if (result != ISC_R_SUCCESS) {
02374
02375
02376
02377
02378 (void)dns_db_endload(load->db, &load->callbacks);
02379 goto cleanup;
02380 } else
02381 result = DNS_R_CONTINUE;
02382 } else {
02383 dns_rdatacallbacks_t callbacks;
02384
02385 dns_rdatacallbacks_init(&callbacks);
02386 callbacks.rawdata = zone_setrawdata;
02387 zone_iattach(zone, &callbacks.zone);
02388 result = dns_db_beginload(db, &callbacks);
02389 if (result != ISC_R_SUCCESS) {
02390 zone_idetach(&callbacks.zone);
02391 return (result);
02392 }
02393 result = dns_master_loadfile5(zone->masterfile,
02394 &zone->origin, &zone->origin,
02395 zone->rdclass, options, 0,
02396 &callbacks,
02397 zone_registerinclude,
02398 zone, zone->mctx,
02399 zone->masterformat,
02400 zone->maxttl);
02401 tresult = dns_db_endload(db, &callbacks);
02402 if (result == ISC_R_SUCCESS)
02403 result = tresult;
02404 zone_idetach(&callbacks.zone);
02405 }
02406
02407 return (result);
02408
02409 cleanup:
02410 load->magic = 0;
02411 dns_db_detach(&load->db);
02412 zone_idetach(&load->zone);
02413 zone_idetach(&load->callbacks.zone);
02414 isc_mem_detach(&load->mctx);
02415 isc_mem_put(zone->mctx, load, sizeof(*load));
02416 return (result);
02417 }
02418
02419 static isc_boolean_t
02420 zone_check_mx(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
02421 dns_name_t *owner)
02422 {
02423 isc_result_t result;
02424 char ownerbuf[DNS_NAME_FORMATSIZE];
02425 char namebuf[DNS_NAME_FORMATSIZE];
02426 char altbuf[DNS_NAME_FORMATSIZE];
02427 dns_fixedname_t fixed;
02428 dns_name_t *foundname;
02429 int level;
02430
02431
02432
02433
02434 if (dns_name_equal(name, dns_rootname))
02435 return (ISC_TRUE);
02436
02437
02438
02439
02440 if (!dns_name_issubdomain(name, &zone->origin)) {
02441 if (zone->checkmx != NULL)
02442 return ((zone->checkmx)(zone, name, owner));
02443 return (ISC_TRUE);
02444 }
02445
02446 if (zone->type == dns_zone_master)
02447 level = ISC_LOG_ERROR;
02448 else
02449 level = ISC_LOG_WARNING;
02450
02451 dns_fixedname_init(&fixed);
02452 foundname = dns_fixedname_name(&fixed);
02453
02454 result = dns_db_find(db, name, NULL, dns_rdatatype_a,
02455 0, 0, NULL, foundname, NULL, NULL);
02456 if (result == ISC_R_SUCCESS)
02457 return (ISC_TRUE);
02458
02459 if (result == DNS_R_NXRRSET) {
02460 result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
02461 0, 0, NULL, foundname, NULL, NULL);
02462 if (result == ISC_R_SUCCESS)
02463 return (ISC_TRUE);
02464 }
02465
02466 dns_name_format(owner, ownerbuf, sizeof ownerbuf);
02467 dns_name_format(name, namebuf, sizeof namebuf);
02468 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
02469 result == DNS_R_EMPTYNAME) {
02470 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMXFAIL))
02471 level = ISC_LOG_WARNING;
02472 dns_zone_log(zone, level,
02473 "%s/MX '%s' has no address records (A or AAAA)",
02474 ownerbuf, namebuf);
02475 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
02476 }
02477
02478 if (result == DNS_R_CNAME) {
02479 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) ||
02480 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
02481 level = ISC_LOG_WARNING;
02482 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
02483 dns_zone_log(zone, level,
02484 "%s/MX '%s' is a CNAME (illegal)",
02485 ownerbuf, namebuf);
02486 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
02487 }
02488
02489 if (result == DNS_R_DNAME) {
02490 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) ||
02491 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
02492 level = ISC_LOG_WARNING;
02493 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) {
02494 dns_name_format(foundname, altbuf, sizeof altbuf);
02495 dns_zone_log(zone, level, "%s/MX '%s' is below a DNAME"
02496 " '%s' (illegal)", ownerbuf, namebuf,
02497 altbuf);
02498 }
02499 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
02500 }
02501
02502 if (zone->checkmx != NULL && result == DNS_R_DELEGATION)
02503 return ((zone->checkmx)(zone, name, owner));
02504
02505 return (ISC_TRUE);
02506 }
02507
02508 static isc_boolean_t
02509 zone_check_srv(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
02510 dns_name_t *owner)
02511 {
02512 isc_result_t result;
02513 char ownerbuf[DNS_NAME_FORMATSIZE];
02514 char namebuf[DNS_NAME_FORMATSIZE];
02515 char altbuf[DNS_NAME_FORMATSIZE];
02516 dns_fixedname_t fixed;
02517 dns_name_t *foundname;
02518 int level;
02519
02520
02521
02522
02523 if (dns_name_equal(name, dns_rootname))
02524 return (ISC_TRUE);
02525
02526
02527
02528
02529 if (!dns_name_issubdomain(name, &zone->origin)) {
02530 if (zone->checksrv != NULL)
02531 return ((zone->checksrv)(zone, name, owner));
02532 return (ISC_TRUE);
02533 }
02534
02535 if (zone->type == dns_zone_master)
02536 level = ISC_LOG_ERROR;
02537 else
02538 level = ISC_LOG_WARNING;
02539
02540 dns_fixedname_init(&fixed);
02541 foundname = dns_fixedname_name(&fixed);
02542
02543 result = dns_db_find(db, name, NULL, dns_rdatatype_a,
02544 0, 0, NULL, foundname, NULL, NULL);
02545 if (result == ISC_R_SUCCESS)
02546 return (ISC_TRUE);
02547
02548 if (result == DNS_R_NXRRSET) {
02549 result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
02550 0, 0, NULL, foundname, NULL, NULL);
02551 if (result == ISC_R_SUCCESS)
02552 return (ISC_TRUE);
02553 }
02554
02555 dns_name_format(owner, ownerbuf, sizeof ownerbuf);
02556 dns_name_format(name, namebuf, sizeof namebuf);
02557 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
02558 result == DNS_R_EMPTYNAME) {
02559 dns_zone_log(zone, level,
02560 "%s/SRV '%s' has no address records (A or AAAA)",
02561 ownerbuf, namebuf);
02562
02563 return (ISC_TRUE);
02564 }
02565
02566 if (result == DNS_R_CNAME) {
02567 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) ||
02568 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
02569 level = ISC_LOG_WARNING;
02570 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
02571 dns_zone_log(zone, level,
02572 "%s/SRV '%s' is a CNAME (illegal)",
02573 ownerbuf, namebuf);
02574 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
02575 }
02576
02577 if (result == DNS_R_DNAME) {
02578 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) ||
02579 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
02580 level = ISC_LOG_WARNING;
02581 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) {
02582 dns_name_format(foundname, altbuf, sizeof altbuf);
02583 dns_zone_log(zone, level, "%s/SRV '%s' is below a "
02584 "DNAME '%s' (illegal)", ownerbuf, namebuf,
02585 altbuf);
02586 }
02587 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
02588 }
02589
02590 if (zone->checksrv != NULL && result == DNS_R_DELEGATION)
02591 return ((zone->checksrv)(zone, name, owner));
02592
02593 return (ISC_TRUE);
02594 }
02595
02596 static isc_boolean_t
02597 zone_check_glue(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
02598 dns_name_t *owner)
02599 {
02600 isc_boolean_t answer = ISC_TRUE;
02601 isc_result_t result, tresult;
02602 char ownerbuf[DNS_NAME_FORMATSIZE];
02603 char namebuf[DNS_NAME_FORMATSIZE];
02604 char altbuf[DNS_NAME_FORMATSIZE];
02605 dns_fixedname_t fixed;
02606 dns_name_t *foundname;
02607 dns_rdataset_t a;
02608 dns_rdataset_t aaaa;
02609 int level;
02610
02611
02612
02613
02614 if (!dns_name_issubdomain(name, &zone->origin)) {
02615 if (zone->checkns != NULL)
02616 return ((zone->checkns)(zone, name, owner, NULL, NULL));
02617 return (ISC_TRUE);
02618 }
02619
02620 if (zone->type == dns_zone_master)
02621 level = ISC_LOG_ERROR;
02622 else
02623 level = ISC_LOG_WARNING;
02624
02625 dns_fixedname_init(&fixed);
02626 foundname = dns_fixedname_name(&fixed);
02627 dns_rdataset_init(&a);
02628 dns_rdataset_init(&aaaa);
02629
02630 result = dns_db_find(db, name, NULL, dns_rdatatype_a,
02631 DNS_DBFIND_GLUEOK, 0, NULL,
02632 foundname, &a, NULL);
02633
02634 if (result == ISC_R_SUCCESS) {
02635 dns_rdataset_disassociate(&a);
02636 return (ISC_TRUE);
02637 } else if (result == DNS_R_DELEGATION)
02638 dns_rdataset_disassociate(&a);
02639
02640 if (result == DNS_R_NXRRSET || result == DNS_R_DELEGATION ||
02641 result == DNS_R_GLUE) {
02642 tresult = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
02643 DNS_DBFIND_GLUEOK, 0, NULL,
02644 foundname, &aaaa, NULL);
02645 if (tresult == ISC_R_SUCCESS) {
02646 if (dns_rdataset_isassociated(&a))
02647 dns_rdataset_disassociate(&a);
02648 dns_rdataset_disassociate(&aaaa);
02649 return (ISC_TRUE);
02650 }
02651 if (tresult == DNS_R_DELEGATION)
02652 dns_rdataset_disassociate(&aaaa);
02653 if (result == DNS_R_GLUE || tresult == DNS_R_GLUE) {
02654
02655
02656
02657 if (zone->checkns != NULL)
02658 answer = (zone->checkns)(zone, name, owner,
02659 &a, &aaaa);
02660 if (dns_rdataset_isassociated(&a))
02661 dns_rdataset_disassociate(&a);
02662 if (dns_rdataset_isassociated(&aaaa))
02663 dns_rdataset_disassociate(&aaaa);
02664 return (answer);
02665 }
02666 }
02667
02668 dns_name_format(owner, ownerbuf, sizeof ownerbuf);
02669 dns_name_format(name, namebuf, sizeof namebuf);
02670 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
02671 result == DNS_R_EMPTYNAME || result == DNS_R_DELEGATION) {
02672 const char *what;
02673 isc_boolean_t required = ISC_FALSE;
02674 if (dns_name_issubdomain(name, owner)) {
02675 what = "REQUIRED GLUE ";
02676 required = ISC_TRUE;
02677 } else if (result == DNS_R_DELEGATION)
02678 what = "SIBLING GLUE ";
02679 else
02680 what = "";
02681
02682 if (result != DNS_R_DELEGATION || required ||
02683 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKSIBLING)) {
02684 dns_zone_log(zone, level, "%s/NS '%s' has no %s"
02685 "address records (A or AAAA)",
02686 ownerbuf, namebuf, what);
02687
02688
02689
02690 if (result == DNS_R_DELEGATION && zone->checkns != NULL)
02691 (void)(zone->checkns)(zone, name, owner,
02692 &a, &aaaa);
02693
02694
02695 }
02696 } else if (result == DNS_R_CNAME) {
02697 dns_zone_log(zone, level, "%s/NS '%s' is a CNAME (illegal)",
02698 ownerbuf, namebuf);
02699
02700
02701 } else if (result == DNS_R_DNAME) {
02702 dns_name_format(foundname, altbuf, sizeof altbuf);
02703 dns_zone_log(zone, level,
02704 "%s/NS '%s' is below a DNAME '%s' (illegal)",
02705 ownerbuf, namebuf, altbuf);
02706
02707
02708 }
02709
02710 if (dns_rdataset_isassociated(&a))
02711 dns_rdataset_disassociate(&a);
02712 if (dns_rdataset_isassociated(&aaaa))
02713 dns_rdataset_disassociate(&aaaa);
02714 return (answer);
02715 }
02716
02717 static isc_boolean_t
02718 zone_rrset_check_dup(dns_zone_t *zone, dns_name_t *owner,
02719 dns_rdataset_t *rdataset)
02720 {
02721 dns_rdataset_t tmprdataset;
02722 isc_result_t result;
02723 isc_boolean_t answer = ISC_TRUE;
02724 isc_boolean_t format = ISC_TRUE;
02725 int level = ISC_LOG_WARNING;
02726 char ownerbuf[DNS_NAME_FORMATSIZE];
02727 char typebuf[DNS_RDATATYPE_FORMATSIZE];
02728 unsigned int count1 = 0;
02729
02730 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKDUPRRFAIL))
02731 level = ISC_LOG_ERROR;
02732
02733 dns_rdataset_init(&tmprdataset);
02734 for (result = dns_rdataset_first(rdataset);
02735 result == ISC_R_SUCCESS;
02736 result = dns_rdataset_next(rdataset)) {
02737 dns_rdata_t rdata1 = DNS_RDATA_INIT;
02738 unsigned int count2 = 0;
02739
02740 count1++;
02741 dns_rdataset_current(rdataset, &rdata1);
02742 dns_rdataset_clone(rdataset, &tmprdataset);
02743 for (result = dns_rdataset_first(&tmprdataset);
02744 result == ISC_R_SUCCESS;
02745 result = dns_rdataset_next(&tmprdataset)) {
02746 dns_rdata_t rdata2 = DNS_RDATA_INIT;
02747 count2++;
02748 if (count1 >= count2)
02749 continue;
02750 dns_rdataset_current(&tmprdataset, &rdata2);
02751 if (dns_rdata_casecompare(&rdata1, &rdata2) == 0) {
02752 if (format) {
02753 dns_name_format(owner, ownerbuf,
02754 sizeof ownerbuf);
02755 dns_rdatatype_format(rdata1.type,
02756 typebuf,
02757 sizeof(typebuf));
02758 format = ISC_FALSE;
02759 }
02760 dns_zone_log(zone, level, "%s/%s has "
02761 "semantically identical records",
02762 ownerbuf, typebuf);
02763 if (level == ISC_LOG_ERROR)
02764 answer = ISC_FALSE;
02765 break;
02766 }
02767 }
02768 dns_rdataset_disassociate(&tmprdataset);
02769 if (!format)
02770 break;
02771 }
02772 return (answer);
02773 }
02774
02775 static isc_boolean_t
02776 zone_check_dup(dns_zone_t *zone, dns_db_t *db) {
02777 dns_dbiterator_t *dbiterator = NULL;
02778 dns_dbnode_t *node = NULL;
02779 dns_fixedname_t fixed;
02780 dns_name_t *name;
02781 dns_rdataset_t rdataset;
02782 dns_rdatasetiter_t *rdsit = NULL;
02783 isc_boolean_t ok = ISC_TRUE;
02784 isc_result_t result;
02785
02786 dns_fixedname_init(&fixed);
02787 name = dns_fixedname_name(&fixed);
02788 dns_rdataset_init(&rdataset);
02789
02790 result = dns_db_createiterator(db, 0, &dbiterator);
02791 if (result != ISC_R_SUCCESS)
02792 return (ISC_TRUE);
02793
02794 for (result = dns_dbiterator_first(dbiterator);
02795 result == ISC_R_SUCCESS;
02796 result = dns_dbiterator_next(dbiterator)) {
02797 result = dns_dbiterator_current(dbiterator, &node, name);
02798 if (result != ISC_R_SUCCESS)
02799 continue;
02800
02801 result = dns_db_allrdatasets(db, node, NULL, 0, &rdsit);
02802 if (result != ISC_R_SUCCESS)
02803 continue;
02804
02805 for (result = dns_rdatasetiter_first(rdsit);
02806 result == ISC_R_SUCCESS;
02807 result = dns_rdatasetiter_next(rdsit)) {
02808 dns_rdatasetiter_current(rdsit, &rdataset);
02809 if (!zone_rrset_check_dup(zone, name, &rdataset))
02810 ok = ISC_FALSE;
02811 dns_rdataset_disassociate(&rdataset);
02812 }
02813 dns_rdatasetiter_destroy(&rdsit);
02814 dns_db_detachnode(db, &node);
02815 }
02816
02817 if (node != NULL)
02818 dns_db_detachnode(db, &node);
02819 dns_dbiterator_destroy(&dbiterator);
02820
02821 return (ok);
02822 }
02823
02824 static isc_boolean_t
02825 isspf(const dns_rdata_t *rdata) {
02826 char buf[1024];
02827 const unsigned char *data = rdata->data;
02828 unsigned int rdl = rdata->length, i = 0, tl, len;
02829
02830 while (rdl > 0U) {
02831 len = tl = *data;
02832 ++data;
02833 --rdl;
02834 INSIST(tl <= rdl);
02835 if (len > sizeof(buf) - i - 1)
02836 len = sizeof(buf) - i - 1;
02837 memmove(buf + i, data, len);
02838 i += len;
02839 data += tl;
02840 rdl -= tl;
02841 }
02842
02843 if (i < 6U)
02844 return(ISC_FALSE);
02845
02846 buf[i] = 0;
02847 if (strncmp(buf, "v=spf1", 6) == 0 && (buf[6] == 0 || buf[6] == ' '))
02848 return (ISC_TRUE);
02849 return (ISC_FALSE);
02850 }
02851
02852 static isc_boolean_t
02853 integrity_checks(dns_zone_t *zone, dns_db_t *db) {
02854 dns_dbiterator_t *dbiterator = NULL;
02855 dns_dbnode_t *node = NULL;
02856 dns_rdataset_t rdataset;
02857 dns_fixedname_t fixed;
02858 dns_fixedname_t fixedbottom;
02859 dns_rdata_mx_t mx;
02860 dns_rdata_ns_t ns;
02861 dns_rdata_in_srv_t srv;
02862 dns_rdata_t rdata;
02863 dns_name_t *name;
02864 dns_name_t *bottom;
02865 isc_result_t result;
02866 isc_boolean_t ok = ISC_TRUE, have_spf, have_txt;
02867
02868 dns_fixedname_init(&fixed);
02869 name = dns_fixedname_name(&fixed);
02870 dns_fixedname_init(&fixedbottom);
02871 bottom = dns_fixedname_name(&fixedbottom);
02872 dns_rdataset_init(&rdataset);
02873 dns_rdata_init(&rdata);
02874
02875 result = dns_db_createiterator(db, 0, &dbiterator);
02876 if (result != ISC_R_SUCCESS)
02877 return (ISC_TRUE);
02878
02879 result = dns_dbiterator_first(dbiterator);
02880 while (result == ISC_R_SUCCESS) {
02881 result = dns_dbiterator_current(dbiterator, &node, name);
02882 if (result != ISC_R_SUCCESS)
02883 goto cleanup;
02884
02885
02886
02887
02888 if (!dns_name_issubdomain(name, &zone->origin) ||
02889 (dns_name_countlabels(bottom) > 0 &&
02890 dns_name_issubdomain(name, bottom)))
02891 goto next;
02892
02893
02894
02895
02896 if (dns_name_equal(name, &zone->origin))
02897 goto checkmx;
02898
02899 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_ns,
02900 0, 0, &rdataset, NULL);
02901 if (result != ISC_R_SUCCESS)
02902 goto checkmx;
02903
02904
02905
02906 dns_name_copy(name, bottom, NULL);
02907
02908 result = dns_rdataset_first(&rdataset);
02909 while (result == ISC_R_SUCCESS) {
02910 dns_rdataset_current(&rdataset, &rdata);
02911 result = dns_rdata_tostruct(&rdata, &ns, NULL);
02912 RUNTIME_CHECK(result == ISC_R_SUCCESS);
02913 if (!zone_check_glue(zone, db, &ns.name, name))
02914 ok = ISC_FALSE;
02915 dns_rdata_reset(&rdata);
02916 result = dns_rdataset_next(&rdataset);
02917 }
02918 dns_rdataset_disassociate(&rdataset);
02919 goto next;
02920
02921 checkmx:
02922 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_mx,
02923 0, 0, &rdataset, NULL);
02924 if (result != ISC_R_SUCCESS)
02925 goto checksrv;
02926 result = dns_rdataset_first(&rdataset);
02927 while (result == ISC_R_SUCCESS) {
02928 dns_rdataset_current(&rdataset, &rdata);
02929 result = dns_rdata_tostruct(&rdata, &mx, NULL);
02930 RUNTIME_CHECK(result == ISC_R_SUCCESS);
02931 if (!zone_check_mx(zone, db, &mx.mx, name))
02932 ok = ISC_FALSE;
02933 dns_rdata_reset(&rdata);
02934 result = dns_rdataset_next(&rdataset);
02935 }
02936 dns_rdataset_disassociate(&rdataset);
02937
02938 checksrv:
02939 if (zone->rdclass != dns_rdataclass_in)
02940 goto next;
02941 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_srv,
02942 0, 0, &rdataset, NULL);
02943 if (result != ISC_R_SUCCESS)
02944 goto checkspf;
02945 result = dns_rdataset_first(&rdataset);
02946 while (result == ISC_R_SUCCESS) {
02947 dns_rdataset_current(&rdataset, &rdata);
02948 result = dns_rdata_tostruct(&rdata, &srv, NULL);
02949 RUNTIME_CHECK(result == ISC_R_SUCCESS);
02950 if (!zone_check_srv(zone, db, &srv.target, name))
02951 ok = ISC_FALSE;
02952 dns_rdata_reset(&rdata);
02953 result = dns_rdataset_next(&rdataset);
02954 }
02955 dns_rdataset_disassociate(&rdataset);
02956
02957 checkspf:
02958
02959
02960
02961
02962 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKSPF))
02963 goto next;
02964 if (zone->rdclass != dns_rdataclass_in)
02965 goto next;
02966 have_spf = have_txt = ISC_FALSE;
02967 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_spf,
02968 0, 0, &rdataset, NULL);
02969 if (result == ISC_R_SUCCESS) {
02970 dns_rdataset_disassociate(&rdataset);
02971 have_spf = ISC_TRUE;
02972 }
02973 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_txt,
02974 0, 0, &rdataset, NULL);
02975 if (result != ISC_R_SUCCESS)
02976 goto notxt;
02977 result = dns_rdataset_first(&rdataset);
02978 while (result == ISC_R_SUCCESS) {
02979 dns_rdataset_current(&rdataset, &rdata);
02980 have_txt = isspf(&rdata);
02981 dns_rdata_reset(&rdata);
02982 if (have_txt)
02983 break;
02984 result = dns_rdataset_next(&rdataset);
02985 }
02986 dns_rdataset_disassociate(&rdataset);
02987
02988 notxt:
02989 if (have_spf && !have_txt) {
02990 char namebuf[DNS_NAME_FORMATSIZE];
02991
02992 dns_name_format(name, namebuf, sizeof(namebuf));
02993 dns_zone_log(zone, ISC_LOG_WARNING, "'%s' found type "
02994 "SPF record but no SPF TXT record found, "
02995 "add matching type TXT record", namebuf);
02996 }
02997
02998 next:
02999 dns_db_detachnode(db, &node);
03000 result = dns_dbiterator_next(dbiterator);
03001 }
03002
03003 cleanup:
03004 if (node != NULL)
03005 dns_db_detachnode(db, &node);
03006 dns_dbiterator_destroy(&dbiterator);
03007
03008 return (ok);
03009 }
03010
03011
03012
03013
03014
03015
03016 static void
03017 zone_check_dnskeys(dns_zone_t *zone, dns_db_t *db) {
03018 dns_dbnode_t *node = NULL;
03019 dns_dbversion_t *version = NULL;
03020 dns_rdata_dnskey_t dnskey;
03021 dns_rdata_t rdata = DNS_RDATA_INIT;
03022 dns_rdataset_t rdataset;
03023 isc_result_t result;
03024 isc_boolean_t logit, foundrsa = ISC_FALSE, foundmd5 = ISC_FALSE;
03025 const char *algorithm;
03026
03027 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node);
03028 if (result != ISC_R_SUCCESS)
03029 goto cleanup;
03030
03031 dns_db_currentversion(db, &version);
03032 dns_rdataset_init(&rdataset);
03033 result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey,
03034 dns_rdatatype_none, 0, &rdataset, NULL);
03035 if (result != ISC_R_SUCCESS)
03036 goto cleanup;
03037
03038 for (result = dns_rdataset_first(&rdataset);
03039 result == ISC_R_SUCCESS;
03040 result = dns_rdataset_next(&rdataset))
03041 {
03042 dns_rdataset_current(&rdataset, &rdata);
03043 result = dns_rdata_tostruct(&rdata, &dnskey, NULL);
03044 INSIST(result == ISC_R_SUCCESS);
03045
03046 if ((dnskey.algorithm == DST_ALG_RSASHA1 ||
03047 dnskey.algorithm == DST_ALG_RSAMD5) &&
03048 dnskey.datalen > 1 && dnskey.data[0] == 1 &&
03049 dnskey.data[1] == 3)
03050 {
03051 if (dnskey.algorithm == DST_ALG_RSASHA1) {
03052 logit = !foundrsa;
03053 foundrsa = ISC_TRUE;
03054 algorithm = "RSASHA1";
03055 } else {
03056 logit = !foundmd5;
03057 foundmd5 = ISC_TRUE;
03058 algorithm = "RSAMD5";
03059 }
03060 if (logit)
03061 dns_zone_log(zone, ISC_LOG_WARNING,
03062 "weak %s (%u) key found "
03063 "(exponent=3)", algorithm,
03064 dnskey.algorithm);
03065 if (foundrsa && foundmd5)
03066 break;
03067 }
03068 dns_rdata_reset(&rdata);
03069 }
03070 dns_rdataset_disassociate(&rdataset);
03071
03072 cleanup:
03073 if (node != NULL)
03074 dns_db_detachnode(db, &node);
03075 if (version != NULL)
03076 dns_db_closeversion(db, &version, ISC_FALSE);
03077 }
03078
03079 static void
03080 resume_signingwithkey(dns_zone_t *zone) {
03081 dns_dbnode_t *node = NULL;
03082 dns_dbversion_t *version = NULL;
03083 dns_rdata_t rdata = DNS_RDATA_INIT;
03084 dns_rdataset_t rdataset;
03085 isc_result_t result;
03086 dns_db_t *db = NULL;
03087
03088 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
03089 if (zone->db != NULL)
03090 dns_db_attach(zone->db, &db);
03091 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
03092 if (db == NULL)
03093 goto cleanup;
03094
03095 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node);
03096 if (result != ISC_R_SUCCESS)
03097 goto cleanup;
03098
03099 dns_db_currentversion(db, &version);
03100 dns_rdataset_init(&rdataset);
03101 result = dns_db_findrdataset(db, node, version,
03102 zone->privatetype,
03103 dns_rdatatype_none, 0,
03104 &rdataset, NULL);
03105 if (result != ISC_R_SUCCESS) {
03106 INSIST(!dns_rdataset_isassociated(&rdataset));
03107 goto cleanup;
03108 }
03109
03110 for (result = dns_rdataset_first(&rdataset);
03111 result == ISC_R_SUCCESS;
03112 result = dns_rdataset_next(&rdataset))
03113 {
03114 dns_rdataset_current(&rdataset, &rdata);
03115 if (rdata.length != 5 ||
03116 rdata.data[0] == 0 || rdata.data[4] != 0) {
03117 dns_rdata_reset(&rdata);
03118 continue;
03119 }
03120
03121 result = zone_signwithkey(zone, rdata.data[0],
03122 (rdata.data[1] << 8) | rdata.data[2],
03123 ISC_TF(rdata.data[3]));
03124 if (result != ISC_R_SUCCESS) {
03125 dns_zone_log(zone, ISC_LOG_ERROR,
03126 "zone_signwithkey failed: %s",
03127 dns_result_totext(result));
03128 }
03129 dns_rdata_reset(&rdata);
03130 }
03131 dns_rdataset_disassociate(&rdataset);
03132
03133 cleanup:
03134 if (db != NULL) {
03135 if (node != NULL)
03136 dns_db_detachnode(db, &node);
03137 if (version != NULL)
03138 dns_db_closeversion(db, &version, ISC_FALSE);
03139 dns_db_detach(&db);
03140 }
03141 }
03142
03143 static isc_result_t
03144 zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) {
03145 dns_nsec3chain_t *nsec3chain, *current;
03146 dns_dbversion_t *version = NULL;
03147 isc_boolean_t nseconly = ISC_FALSE, nsec3ok = ISC_FALSE;
03148 isc_result_t result;
03149 isc_time_t now;
03150 unsigned int options = 0;
03151 char saltbuf[255*2+1];
03152 char flags[sizeof("INITIAL|REMOVE|CREATE|NONSEC|OPTOUT")];
03153 dns_db_t *db = NULL;
03154 int i;
03155
03156 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
03157 if (zone->db != NULL)
03158 dns_db_attach(zone->db, &db);
03159 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
03160
03161 if (db == NULL) {
03162 result = ISC_R_SUCCESS;
03163 goto cleanup;
03164 }
03165
03166 dns_db_currentversion(db, &version);
03167 result = dns_nsec_nseconly(db, version, &nseconly);
03168 nsec3ok = (result == ISC_R_SUCCESS && !nseconly);
03169 dns_db_closeversion(db, &version, ISC_FALSE);
03170 if (!nsec3ok && (nsec3param->flags & DNS_NSEC3FLAG_REMOVE) == 0) {
03171 result = ISC_R_SUCCESS;
03172 goto cleanup;
03173 }
03174
03175 nsec3chain = isc_mem_get(zone->mctx, sizeof *nsec3chain);
03176 if (nsec3chain == NULL) {
03177 result = ISC_R_NOMEMORY;
03178 goto cleanup;
03179 }
03180
03181 nsec3chain->magic = 0;
03182 nsec3chain->done = ISC_FALSE;
03183 nsec3chain->db = NULL;
03184 nsec3chain->dbiterator = NULL;
03185 nsec3chain->nsec3param.common.rdclass = nsec3param->common.rdclass;
03186 nsec3chain->nsec3param.common.rdtype = nsec3param->common.rdtype;
03187 nsec3chain->nsec3param.hash = nsec3param->hash;
03188 nsec3chain->nsec3param.iterations = nsec3param->iterations;
03189 nsec3chain->nsec3param.flags = nsec3param->flags;
03190 nsec3chain->nsec3param.salt_length = nsec3param->salt_length;
03191 memmove(nsec3chain->salt, nsec3param->salt, nsec3param->salt_length);
03192 nsec3chain->nsec3param.salt = nsec3chain->salt;
03193 nsec3chain->seen_nsec = ISC_FALSE;
03194 nsec3chain->delete_nsec = ISC_FALSE;
03195 nsec3chain->save_delete_nsec = ISC_FALSE;
03196
03197 if (nsec3param->flags == 0)
03198 strlcpy(flags, "NONE", sizeof(flags));
03199 else {
03200 flags[0] = '\0';
03201 if (nsec3param->flags & DNS_NSEC3FLAG_REMOVE)
03202 strlcat(flags, "REMOVE", sizeof(flags));
03203 if (nsec3param->flags & DNS_NSEC3FLAG_INITIAL) {
03204 if (flags[0] == '\0')
03205 strlcpy(flags, "INITIAL", sizeof(flags));
03206 else
03207 strlcat(flags, "|INITIAL", sizeof(flags));
03208 }
03209 if (nsec3param->flags & DNS_NSEC3FLAG_CREATE) {
03210 if (flags[0] == '\0')
03211 strlcpy(flags, "CREATE", sizeof(flags));
03212 else
03213 strlcat(flags, "|CREATE", sizeof(flags));
03214 }
03215 if (nsec3param->flags & DNS_NSEC3FLAG_NONSEC) {
03216 if (flags[0] == '\0')
03217 strlcpy(flags, "NONSEC", sizeof(flags));
03218 else
03219 strlcat(flags, "|NONSEC", sizeof(flags));
03220 }
03221 if (nsec3param->flags & DNS_NSEC3FLAG_OPTOUT) {
03222 if (flags[0] == '\0')
03223 strlcpy(flags, "OPTOUT", sizeof(flags));
03224 else
03225 strlcat(flags, "|OPTOUT", sizeof(flags));
03226 }
03227 }
03228 if (nsec3param->salt_length == 0)
03229 strlcpy(saltbuf, "-", sizeof(saltbuf));
03230 else
03231 for (i = 0; i < nsec3param->salt_length; i++)
03232 sprintf(&saltbuf[i*2], "%02X", nsec3chain->salt[i]);
03233 dns_zone_log(zone, ISC_LOG_INFO,
03234 "zone_addnsec3chain(%u,%s,%u,%s)",
03235 nsec3param->hash, flags, nsec3param->iterations,
03236 saltbuf);
03237
03238 for (current = ISC_LIST_HEAD(zone->nsec3chain);
03239 current != NULL;
03240 current = ISC_LIST_NEXT(current, link)) {
03241 if (current->db == db &&
03242 current->nsec3param.hash == nsec3param->hash &&
03243 current->nsec3param.iterations == nsec3param->iterations &&
03244 current->nsec3param.salt_length == nsec3param->salt_length
03245 && !memcmp(current->nsec3param.salt, nsec3param->salt,
03246 nsec3param->salt_length))
03247 current->done = ISC_TRUE;
03248 }
03249
03250 dns_db_attach(db, &nsec3chain->db);
03251 if ((nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0)
03252 options = DNS_DB_NONSEC3;
03253 result = dns_db_createiterator(nsec3chain->db, options,
03254 &nsec3chain->dbiterator);
03255 if (result == ISC_R_SUCCESS)
03256 dns_dbiterator_first(nsec3chain->dbiterator);
03257 if (result == ISC_R_SUCCESS) {
03258 dns_dbiterator_pause(nsec3chain->dbiterator);
03259 ISC_LIST_INITANDAPPEND(zone->nsec3chain,
03260 nsec3chain, link);
03261 nsec3chain = NULL;
03262 if (isc_time_isepoch(&zone->nsec3chaintime)) {
03263 TIME_NOW(&now);
03264 zone->nsec3chaintime = now;
03265 if (zone->task != NULL)
03266 zone_settimer(zone, &now);
03267 }
03268 }
03269
03270 if (nsec3chain != NULL) {
03271 if (nsec3chain->db != NULL)
03272 dns_db_detach(&nsec3chain->db);
03273 if (nsec3chain->dbiterator != NULL)
03274 dns_dbiterator_destroy(&nsec3chain->dbiterator);
03275 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
03276 }
03277
03278 cleanup:
03279 if (db != NULL)
03280 dns_db_detach(&db);
03281 return (result);
03282 }
03283
03284 static void
03285 resume_addnsec3chain(dns_zone_t *zone) {
03286 dns_dbnode_t *node = NULL;
03287 dns_dbversion_t *version = NULL;
03288 dns_rdataset_t rdataset;
03289 isc_result_t result;
03290 dns_rdata_nsec3param_t nsec3param;
03291 isc_boolean_t nseconly = ISC_FALSE, nsec3ok = ISC_FALSE;
03292 dns_db_t *db = NULL;
03293
03294 if (zone->privatetype == 0)
03295 return;
03296
03297 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
03298 if (zone->db != NULL)
03299 dns_db_attach(zone->db, &db);
03300 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
03301 if (db == NULL)
03302 goto cleanup;
03303
03304 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node);
03305 if (result != ISC_R_SUCCESS)
03306 goto cleanup;
03307
03308 dns_db_currentversion(db, &version);
03309
03310 result = dns_nsec_nseconly(db, version, &nseconly);
03311 nsec3ok = (result == ISC_R_SUCCESS && !nseconly);
03312
03313 dns_rdataset_init(&rdataset);
03314 result = dns_db_findrdataset(db, node, version,
03315 zone->privatetype, dns_rdatatype_none,
03316 0, &rdataset, NULL);
03317 if (result != ISC_R_SUCCESS) {
03318 INSIST(!dns_rdataset_isassociated(&rdataset));
03319 goto cleanup;
03320 }
03321
03322 for (result = dns_rdataset_first(&rdataset);
03323 result == ISC_R_SUCCESS;
03324 result = dns_rdataset_next(&rdataset))
03325 {
03326 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
03327 dns_rdata_t rdata = DNS_RDATA_INIT;
03328 dns_rdata_t private = DNS_RDATA_INIT;
03329
03330 dns_rdataset_current(&rdataset, &private);
03331 if (!dns_nsec3param_fromprivate(&private, &rdata, buf,
03332 sizeof(buf)))
03333 continue;
03334 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
03335 RUNTIME_CHECK(result == ISC_R_SUCCESS);
03336 if (((nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) ||
03337 ((nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0 && nsec3ok))
03338 {
03339 result = zone_addnsec3chain(zone, &nsec3param);
03340 if (result != ISC_R_SUCCESS) {
03341 dns_zone_log(zone, ISC_LOG_ERROR,
03342 "zone_addnsec3chain failed: %s",
03343 dns_result_totext(result));
03344 }
03345 }
03346 }
03347 dns_rdataset_disassociate(&rdataset);
03348 cleanup:
03349 if (db != NULL) {
03350 if (node != NULL)
03351 dns_db_detachnode(db, &node);
03352 if (version != NULL)
03353 dns_db_closeversion(db, &version, ISC_FALSE);
03354 dns_db_detach(&db);
03355 }
03356 }
03357
03358 static void
03359 set_resigntime(dns_zone_t *zone) {
03360 dns_rdataset_t rdataset;
03361 dns_fixedname_t fixed;
03362 unsigned int resign;
03363 isc_result_t result;
03364 isc_uint32_t nanosecs;
03365 dns_db_t *db = NULL;
03366
03367
03368 if (zone->update_disabled)
03369 return;
03370
03371 if (!inline_secure(zone) && (zone->type != dns_zone_master ||
03372 (zone->ssutable == NULL &&
03373 (zone->update_acl == NULL || dns_acl_isnone(zone->update_acl)))))
03374 return;
03375
03376 dns_rdataset_init(&rdataset);
03377 dns_fixedname_init(&fixed);
03378
03379 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
03380 if (zone->db != NULL)
03381 dns_db_attach(zone->db, &db);
03382 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
03383 if (db == NULL) {
03384 isc_time_settoepoch(&zone->resigntime);
03385 return;
03386 }
03387
03388 result = dns_db_getsigningtime(db, &rdataset,
03389 dns_fixedname_name(&fixed));
03390 if (result != ISC_R_SUCCESS) {
03391 isc_time_settoepoch(&zone->resigntime);
03392 goto cleanup;
03393 }
03394
03395 resign = rdataset.resign - zone->sigresigninginterval;
03396 dns_rdataset_disassociate(&rdataset);
03397 isc_random_get(&nanosecs);
03398 nanosecs %= 1000000000;
03399 isc_time_set(&zone->resigntime, resign, nanosecs);
03400 cleanup:
03401 dns_db_detach(&db);
03402 return;
03403 }
03404
03405 static isc_result_t
03406 check_nsec3param(dns_zone_t *zone, dns_db_t *db) {
03407 dns_dbnode_t *node = NULL;
03408 dns_rdataset_t rdataset;
03409 dns_dbversion_t *version = NULL;
03410 dns_rdata_nsec3param_t nsec3param;
03411 isc_boolean_t ok = ISC_FALSE;
03412 isc_result_t result;
03413 dns_rdata_t rdata = DNS_RDATA_INIT;
03414 isc_boolean_t dynamic = (zone->type == dns_zone_master) ?
03415 dns_zone_isdynamic(zone, ISC_FALSE) : ISC_FALSE;
03416
03417 dns_rdataset_init(&rdataset);
03418 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node);
03419 if (result != ISC_R_SUCCESS) {
03420 dns_zone_log(zone, ISC_LOG_ERROR,
03421 "nsec3param lookup failure: %s",
03422 dns_result_totext(result));
03423 return (result);
03424 }
03425 dns_db_currentversion(db, &version);
03426
03427 result = dns_db_findrdataset(db, node, version,
03428 dns_rdatatype_nsec3param,
03429 dns_rdatatype_none, 0, &rdataset, NULL);
03430 if (result == ISC_R_NOTFOUND) {
03431 INSIST(!dns_rdataset_isassociated(&rdataset));
03432 result = ISC_R_SUCCESS;
03433 goto cleanup;
03434 }
03435 if (result != ISC_R_SUCCESS) {
03436 INSIST(!dns_rdataset_isassociated(&rdataset));
03437 dns_zone_log(zone, ISC_LOG_ERROR,
03438 "nsec3param lookup failure: %s",
03439 dns_result_totext(result));
03440 goto cleanup;
03441 }
03442
03443
03444
03445
03446
03447
03448 for (result = dns_rdataset_first(&rdataset);
03449 result == ISC_R_SUCCESS;
03450 result = dns_rdataset_next(&rdataset))
03451 {
03452 dns_rdataset_current(&rdataset, &rdata);
03453 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
03454 dns_rdata_reset(&rdata);
03455 INSIST(result == ISC_R_SUCCESS);
03456 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NSEC3TESTZONE) &&
03457 nsec3param.hash == DNS_NSEC3_UNKNOWNALG && !dynamic)
03458 {
03459 dns_zone_log(zone, ISC_LOG_WARNING,
03460 "nsec3 test \"unknown\" hash algorithm found: %u",
03461 nsec3param.hash);
03462 ok = ISC_TRUE;
03463 } else if (!dns_nsec3_supportedhash(nsec3param.hash)) {
03464 if (dynamic) {
03465 dns_zone_log(zone, ISC_LOG_ERROR,
03466 "unsupported nsec3 hash algorithm"
03467 " in dynamic zone: %u",
03468 nsec3param.hash);
03469 result = DNS_R_BADZONE;
03470
03471 ok = ISC_TRUE;
03472 break;
03473 } else
03474 dns_zone_log(zone, ISC_LOG_WARNING,
03475 "unsupported nsec3 hash algorithm: %u",
03476 nsec3param.hash);
03477 } else
03478 ok = ISC_TRUE;
03479 }
03480 if (result == ISC_R_NOMORE)
03481 result = ISC_R_SUCCESS;
03482
03483 if (!ok) {
03484 result = DNS_R_BADZONE;
03485 dns_zone_log(zone, ISC_LOG_ERROR,
03486 "no supported nsec3 hash algorithm");
03487 }
03488
03489 cleanup:
03490 if (dns_rdataset_isassociated(&rdataset))
03491 dns_rdataset_disassociate(&rdataset);
03492 dns_db_closeversion(db, &version, ISC_FALSE);
03493 dns_db_detachnode(db, &node);
03494 return (result);
03495 }
03496
03497
03498
03499
03500
03501
03502 static void
03503 set_refreshkeytimer(dns_zone_t *zone, dns_rdata_keydata_t *key,
03504 isc_stdtime_t now, isc_boolean_t force)
03505 {
03506 const char me[] = "set_refreshkeytimer";
03507 isc_stdtime_t then;
03508 isc_time_t timenow, timethen;
03509 char timebuf[80];
03510
03511 ENTER;
03512 then = key->refresh;
03513 if (force)
03514 then = now;
03515 if (key->addhd > now && key->addhd < then)
03516 then = key->addhd;
03517 if (key->removehd > now && key->removehd < then)
03518 then = key->removehd;
03519
03520 TIME_NOW(&timenow);
03521 if (then > now)
03522 DNS_ZONE_TIME_ADD(&timenow, then - now, &timethen);
03523 else
03524 timethen = timenow;
03525 if (isc_time_compare(&zone->refreshkeytime, &timenow) < 0 ||
03526 isc_time_compare(&timethen, &zone->refreshkeytime) < 0)
03527 zone->refreshkeytime = timethen;
03528
03529 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
03530 dns_zone_log(zone, ISC_LOG_DEBUG(1), "next key refresh: %s", timebuf);
03531 zone_settimer(zone, &timenow);
03532 }
03533
03534
03535
03536
03537
03538 static isc_result_t
03539 create_keydata(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
03540 dns_diff_t *diff, dns_keytable_t *keytable,
03541 dns_keynode_t **keynodep, isc_boolean_t *changed)
03542 {
03543 const char me[] = "create_keydata";
03544 isc_result_t result = ISC_R_SUCCESS;
03545 isc_buffer_t keyb, dstb;
03546 unsigned char key_buf[4096], dst_buf[DST_KEY_MAXSIZE];
03547 dns_rdata_keydata_t keydata;
03548 dns_rdata_dnskey_t dnskey;
03549 dns_rdata_t rdata = DNS_RDATA_INIT;
03550 dns_keynode_t *keynode;
03551 isc_stdtime_t now;
03552 isc_region_t r;
03553 dst_key_t *key;
03554
03555 REQUIRE(keynodep != NULL);
03556 keynode = *keynodep;
03557
03558 ENTER;
03559 isc_stdtime_get(&now);
03560
03561
03562 while (result == ISC_R_SUCCESS) {
03563 dns_keynode_t *nextnode = NULL;
03564
03565 key = dns_keynode_key(keynode);
03566 if (key == NULL)
03567 goto skip;
03568
03569 isc_buffer_init(&dstb, dst_buf, sizeof(dst_buf));
03570 CHECK(dst_key_todns(key, &dstb));
03571
03572
03573 dns_rdata_reset(&rdata);
03574 isc_buffer_usedregion(&dstb, &r);
03575 dns_rdata_fromregion(&rdata, dst_key_class(key),
03576 dns_rdatatype_dnskey, &r);
03577
03578
03579 CHECK(dns_rdata_tostruct(&rdata, &dnskey, NULL));
03580 CHECK(dns_keydata_fromdnskey(&keydata, &dnskey, now, 0, 0,
03581 NULL));
03582
03583
03584 dns_rdata_reset(&rdata);
03585 isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
03586 CHECK(dns_rdata_fromstruct(&rdata,
03587 zone->rdclass, dns_rdatatype_keydata,
03588 &keydata, &keyb));
03589
03590
03591 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD,
03592 dst_key_name(key), 0, &rdata));
03593 *changed = ISC_TRUE;
03594
03595
03596 set_refreshkeytimer(zone, &keydata, now, ISC_TRUE);
03597
03598 skip:
03599 result = dns_keytable_nextkeynode(keytable, keynode, &nextnode);
03600 if (result != ISC_R_NOTFOUND) {
03601 dns_keytable_detachkeynode(keytable, &keynode);
03602 keynode = nextnode;
03603 }
03604 }
03605
03606 if (keynode != NULL)
03607 dns_keytable_detachkeynode(keytable, &keynode);
03608 *keynodep = NULL;
03609
03610 return (ISC_R_SUCCESS);
03611
03612 failure:
03613 return (result);
03614 }
03615
03616
03617
03618
03619 static isc_result_t
03620 delete_keydata(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff,
03621 dns_name_t *name, dns_rdataset_t *rdataset)
03622 {
03623 dns_rdata_t rdata = DNS_RDATA_INIT;
03624 isc_result_t result, uresult;
03625
03626 for (result = dns_rdataset_first(rdataset);
03627 result == ISC_R_SUCCESS;
03628 result = dns_rdataset_next(rdataset)) {
03629 dns_rdata_reset(&rdata);
03630 dns_rdataset_current(rdataset, &rdata);
03631 uresult = update_one_rr(db, ver, diff, DNS_DIFFOP_DEL,
03632 name, 0, &rdata);
03633 if (uresult != ISC_R_SUCCESS)
03634 return (uresult);
03635 }
03636 if (result == ISC_R_NOMORE)
03637 result = ISC_R_SUCCESS;
03638 return (result);
03639 }
03640
03641
03642
03643
03644 static isc_result_t
03645 compute_tag(dns_name_t *name, dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx,
03646 dns_keytag_t *tag)
03647 {
03648 isc_result_t result;
03649 dns_rdata_t rdata = DNS_RDATA_INIT;
03650 unsigned char data[4096];
03651 isc_buffer_t buffer;
03652 dst_key_t *dstkey = NULL;
03653
03654 isc_buffer_init(&buffer, data, sizeof(data));
03655 dns_rdata_fromstruct(&rdata, dnskey->common.rdclass,
03656 dns_rdatatype_dnskey, dnskey, &buffer);
03657
03658 result = dns_dnssec_keyfromrdata(name, &rdata, mctx, &dstkey);
03659 if (result == ISC_R_SUCCESS)
03660 *tag = dst_key_id(dstkey);
03661 dst_key_free(&dstkey);
03662
03663 return (result);
03664 }
03665
03666
03667
03668
03669 static void
03670 trust_key(dns_zone_t *zone, dns_name_t *keyname,
03671 dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx) {
03672 isc_result_t result;
03673 dns_rdata_t rdata = DNS_RDATA_INIT;
03674 unsigned char data[4096];
03675 isc_buffer_t buffer;
03676 dns_keytable_t *sr = NULL;
03677 dst_key_t *dstkey = NULL;
03678
03679
03680 isc_buffer_init(&buffer, data, sizeof(data));
03681 dns_rdata_fromstruct(&rdata, dnskey->common.rdclass,
03682 dns_rdatatype_dnskey, dnskey, &buffer);
03683
03684 result = dns_view_getsecroots(zone->view, &sr);
03685 if (result != ISC_R_SUCCESS)
03686 goto failure;
03687
03688 CHECK(dns_dnssec_keyfromrdata(keyname, &rdata, mctx, &dstkey));
03689 CHECK(dns_keytable_add(sr, ISC_TRUE, &dstkey));
03690 dns_keytable_detach(&sr);
03691
03692 failure:
03693 if (dstkey != NULL)
03694 dst_key_free(&dstkey);
03695 if (sr != NULL)
03696 dns_keytable_detach(&sr);
03697 return;
03698 }
03699
03700
03701
03702
03703
03704 static void
03705 fail_secure(dns_zone_t *zone, dns_name_t *keyname) {
03706 isc_result_t result;
03707 dns_keytable_t *sr = NULL;
03708
03709 result = dns_view_getsecroots(zone->view, &sr);
03710 if (result == ISC_R_SUCCESS) {
03711 dns_keytable_marksecure(sr, keyname);
03712 dns_keytable_detach(&sr);
03713 }
03714 }
03715
03716
03717
03718
03719
03720 static void
03721 load_secroots(dns_zone_t *zone, dns_name_t *name, dns_rdataset_t *rdataset) {
03722 isc_result_t result;
03723 dns_rdata_t rdata = DNS_RDATA_INIT;
03724 dns_rdata_keydata_t keydata;
03725 dns_rdata_dnskey_t dnskey;
03726 isc_mem_t *mctx = zone->mctx;
03727 int trusted = 0, revoked = 0, pending = 0;
03728 isc_stdtime_t now;
03729 dns_keytable_t *sr = NULL;
03730
03731 isc_stdtime_get(&now);
03732
03733 result = dns_view_getsecroots(zone->view, &sr);
03734 if (result == ISC_R_SUCCESS) {
03735 dns_keytable_delete(sr, name);
03736 dns_keytable_detach(&sr);
03737 }
03738
03739
03740 for (result = dns_rdataset_first(rdataset);
03741 result == ISC_R_SUCCESS;
03742 result = dns_rdataset_next(rdataset)) {
03743 dns_rdata_reset(&rdata);
03744 dns_rdataset_current(rdataset, &rdata);
03745
03746
03747 result = dns_rdata_tostruct(&rdata, &keydata, NULL);
03748 if (result == ISC_R_UNEXPECTEDEND)
03749 continue;
03750 RUNTIME_CHECK(result == ISC_R_SUCCESS);
03751
03752
03753 set_refreshkeytimer(zone, &keydata, now, ISC_TRUE);
03754
03755
03756 if (keydata.removehd != 0) {
03757 revoked++;
03758 continue;
03759 }
03760
03761
03762
03763
03764
03765 if (now < keydata.addhd) {
03766 pending++;
03767 continue;
03768 }
03769
03770
03771 dns_keydata_todnskey(&keydata, &dnskey, NULL);
03772
03773
03774 trusted++;
03775 trust_key(zone, name, &dnskey, mctx);
03776 }
03777
03778 if (trusted == 0 && pending != 0) {
03779 char namebuf[DNS_NAME_FORMATSIZE];
03780 dns_name_format(name, namebuf, sizeof namebuf);
03781 dns_zone_log(zone, ISC_LOG_ERROR,
03782 "No valid trust anchors for '%s'!", namebuf);
03783 dns_zone_log(zone, ISC_LOG_ERROR,
03784 "%d key(s) revoked, %d still pending",
03785 revoked, pending);
03786 dns_zone_log(zone, ISC_LOG_ERROR,
03787 "All queries to '%s' will fail", namebuf);
03788 fail_secure(zone, name);
03789 }
03790 }
03791
03792 static isc_result_t
03793 do_one_tuple(dns_difftuple_t **tuple, dns_db_t *db, dns_dbversion_t *ver,
03794 dns_diff_t *diff)
03795 {
03796 dns_diff_t temp_diff;
03797 isc_result_t result;
03798
03799
03800
03801
03802 dns_diff_init(diff->mctx, &temp_diff);
03803 ISC_LIST_APPEND(temp_diff.tuples, *tuple, link);
03804
03805
03806
03807
03808 result = dns_diff_apply(&temp_diff, db, ver);
03809 ISC_LIST_UNLINK(temp_diff.tuples, *tuple, link);
03810 if (result != ISC_R_SUCCESS) {
03811 dns_difftuple_free(tuple);
03812 return (result);
03813 }
03814
03815
03816
03817
03818 dns_diff_appendminimal(diff, tuple);
03819
03820
03821
03822
03823 return (ISC_R_SUCCESS);
03824 }
03825
03826 static isc_result_t
03827 update_one_rr(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff,
03828 dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl,
03829 dns_rdata_t *rdata)
03830 {
03831 dns_difftuple_t *tuple = NULL;
03832 isc_result_t result;
03833 result = dns_difftuple_create(diff->mctx, op,
03834 name, ttl, rdata, &tuple);
03835 if (result != ISC_R_SUCCESS)
03836 return (result);
03837 return (do_one_tuple(&tuple, db, ver, diff));
03838 }
03839
03840 static isc_result_t
03841 update_soa_serial(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff,
03842 isc_mem_t *mctx, dns_updatemethod_t method) {
03843 dns_difftuple_t *deltuple = NULL;
03844 dns_difftuple_t *addtuple = NULL;
03845 isc_uint32_t serial;
03846 isc_result_t result;
03847
03848 INSIST(method != dns_updatemethod_none);
03849
03850 CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_DEL, &deltuple));
03851 CHECK(dns_difftuple_copy(deltuple, &addtuple));
03852 addtuple->op = DNS_DIFFOP_ADD;
03853
03854 serial = dns_soa_getserial(&addtuple->rdata);
03855 serial = dns_update_soaserial(serial, method);
03856 dns_soa_setserial(serial, &addtuple->rdata);
03857 CHECK(do_one_tuple(&deltuple, db, ver, diff));
03858 CHECK(do_one_tuple(&addtuple, db, ver, diff));
03859 result = ISC_R_SUCCESS;
03860
03861 failure:
03862 if (addtuple != NULL)
03863 dns_difftuple_free(&addtuple);
03864 if (deltuple != NULL)
03865 dns_difftuple_free(&deltuple);
03866 return (result);
03867 }
03868
03869
03870
03871
03872 static isc_result_t
03873 zone_journal(dns_zone_t *zone, dns_diff_t *diff, isc_uint32_t *sourceserial,
03874 const char *caller)
03875 {
03876 const char me[] = "zone_journal";
03877 const char *journalfile;
03878 isc_result_t result = ISC_R_SUCCESS;
03879 dns_journal_t *journal = NULL;
03880 unsigned int mode = DNS_JOURNAL_CREATE|DNS_JOURNAL_WRITE;
03881
03882 ENTER;
03883 journalfile = dns_zone_getjournal(zone);
03884 if (journalfile != NULL) {
03885 result = dns_journal_open(zone->mctx, journalfile, mode,
03886 &journal);
03887 if (result != ISC_R_SUCCESS) {
03888 dns_zone_log(zone, ISC_LOG_ERROR,
03889 "%s:dns_journal_open -> %s",
03890 caller, dns_result_totext(result));
03891 return (result);
03892 }
03893
03894 if (sourceserial != NULL)
03895 dns_journal_set_sourceserial(journal, *sourceserial);
03896
03897 result = dns_journal_write_transaction(journal, diff);
03898 if (result != ISC_R_SUCCESS) {
03899 dns_zone_log(zone, ISC_LOG_ERROR,
03900 "%s:dns_journal_write_transaction -> %s",
03901 caller, dns_result_totext(result));
03902 }
03903 dns_journal_destroy(&journal);
03904 }
03905
03906 return (result);
03907 }
03908
03909
03910
03911
03912 static isc_result_t
03913 add_soa(dns_zone_t *zone, dns_db_t *db) {
03914 isc_result_t result;
03915 dns_rdata_t rdata = DNS_RDATA_INIT;
03916 unsigned char buf[DNS_SOA_BUFFERSIZE];
03917 dns_dbversion_t *ver = NULL;
03918 dns_diff_t diff;
03919
03920 dns_zone_log(zone, ISC_LOG_DEBUG(1), "creating SOA");
03921
03922 dns_diff_init(zone->mctx, &diff);
03923 result = dns_db_newversion(db, &ver);
03924 if (result != ISC_R_SUCCESS) {
03925 dns_zone_log(zone, ISC_LOG_ERROR,
03926 "add_soa:dns_db_newversion -> %s",
03927 dns_result_totext(result));
03928 goto failure;
03929 }
03930
03931
03932 result = dns_soa_buildrdata(&zone->origin, dns_rootname, zone->rdclass,
03933 0, 0, 0, 0, 0, buf, &rdata);
03934 if (result != ISC_R_SUCCESS) {
03935 dns_zone_log(zone, ISC_LOG_ERROR,
03936 "add_soa:dns_soa_buildrdata -> %s",
03937 dns_result_totext(result));
03938 goto failure;
03939 }
03940
03941 result = update_one_rr(db, ver, &diff, DNS_DIFFOP_ADD,
03942 &zone->origin, 0, &rdata);
03943
03944 failure:
03945 dns_diff_clear(&diff);
03946 if (ver != NULL)
03947 dns_db_closeversion(db, &ver, ISC_TF(result == ISC_R_SUCCESS));
03948
03949 INSIST(ver == NULL);
03950
03951 return (result);
03952 }
03953
03954
03955
03956
03957
03958
03959
03960
03961
03962 static isc_result_t
03963 sync_keyzone(dns_zone_t *zone, dns_db_t *db) {
03964 isc_result_t result = ISC_R_SUCCESS;
03965 isc_boolean_t changed = ISC_FALSE;
03966 isc_boolean_t commit = ISC_FALSE;
03967 dns_rbtnodechain_t chain;
03968 dns_fixedname_t fn;
03969 dns_name_t foundname, *origin;
03970 dns_keynode_t *keynode = NULL;
03971 dns_view_t *view = zone->view;
03972 dns_keytable_t *sr = NULL;
03973 dns_dbversion_t *ver = NULL;
03974 dns_diff_t diff;
03975 dns_rriterator_t rrit;
03976
03977 dns_zone_log(zone, ISC_LOG_DEBUG(1), "synchronizing trusted keys");
03978
03979 dns_name_init(&foundname, NULL);
03980 dns_fixedname_init(&fn);
03981 origin = dns_fixedname_name(&fn);
03982
03983 dns_diff_init(zone->mctx, &diff);
03984
03985 CHECK(dns_view_getsecroots(view, &sr));
03986
03987 result = dns_db_newversion(db, &ver);
03988 if (result != ISC_R_SUCCESS) {
03989 dns_zone_log(zone, ISC_LOG_ERROR,
03990 "sync_keyzone:dns_db_newversion -> %s",
03991 dns_result_totext(result));
03992 goto failure;
03993 }
03994
03995
03996
03997
03998
03999
04000
04001
04002 dns_rriterator_init(&rrit, db, ver, 0);
04003 for (result = dns_rriterator_first(&rrit);
04004 result == ISC_R_SUCCESS;
04005 result = dns_rriterator_nextrrset(&rrit)) {
04006 dns_rdataset_t *rdataset = NULL;
04007 dns_name_t *rrname = NULL;
04008 isc_uint32_t ttl;
04009
04010 dns_rriterator_current(&rrit, &rrname, &ttl,
04011 &rdataset, NULL);
04012 if (!dns_rdataset_isassociated(rdataset)) {
04013 dns_rriterator_destroy(&rrit);
04014 goto failure;
04015 }
04016
04017 if (rdataset->type != dns_rdatatype_keydata)
04018 continue;
04019
04020 result = dns_keytable_find(sr, rrname, &keynode);
04021 if ((result != ISC_R_SUCCESS &&
04022 result != DNS_R_PARTIALMATCH) ||
04023 dns_keynode_managed(keynode) == ISC_FALSE)
04024 {
04025 CHECK(delete_keydata(db, ver, &diff,
04026 rrname, rdataset));
04027 changed = ISC_TRUE;
04028 } else {
04029 load_secroots(zone, rrname, rdataset);
04030 }
04031
04032 if (keynode != NULL)
04033 dns_keytable_detachkeynode(sr, &keynode);
04034 }
04035 dns_rriterator_destroy(&rrit);
04036
04037
04038
04039
04040
04041 RWLOCK(&sr->rwlock, isc_rwlocktype_write);
04042 dns_rbtnodechain_init(&chain, zone->mctx);
04043 result = dns_rbtnodechain_first(&chain, sr->table, &foundname, origin);
04044 if (result == ISC_R_NOTFOUND)
04045 result = ISC_R_NOMORE;
04046 while (result == DNS_R_NEWORIGIN || result == ISC_R_SUCCESS) {
04047 dns_rbtnode_t *rbtnode = NULL;
04048
04049 dns_rbtnodechain_current(&chain, &foundname, origin, &rbtnode);
04050 if (rbtnode->data == NULL)
04051 goto skip;
04052
04053 dns_keytable_attachkeynode(sr, rbtnode->data, &keynode);
04054 if (dns_keynode_managed(keynode)) {
04055 dns_fixedname_t fname;
04056 dns_name_t *keyname;
04057 dst_key_t *key;
04058
04059 key = dns_keynode_key(keynode);
04060 dns_fixedname_init(&fname);
04061
04062 if (key == NULL)
04063 goto skip;
04064
04065 keyname = dst_key_name(key);
04066 result = dns_db_find(db, keyname, ver,
04067 dns_rdatatype_keydata,
04068 DNS_DBFIND_NOWILD, 0, NULL,
04069 dns_fixedname_name(&fname),
04070 NULL, NULL);
04071 if (result != ISC_R_SUCCESS)
04072 result = create_keydata(zone, db, ver, &diff,
04073 sr, &keynode, &changed);
04074 if (result != ISC_R_SUCCESS)
04075 break;
04076 }
04077 skip:
04078 result = dns_rbtnodechain_next(&chain, &foundname, origin);
04079 if (keynode != NULL)
04080 dns_keytable_detachkeynode(sr, &keynode);
04081 }
04082 RWUNLOCK(&sr->rwlock, isc_rwlocktype_write);
04083
04084 if (result == ISC_R_NOMORE)
04085 result = ISC_R_SUCCESS;
04086
04087 if (changed) {
04088
04089 CHECK(update_soa_serial(db, ver, &diff, zone->mctx,
04090 zone->updatemethod));
04091 CHECK(zone_journal(zone, &diff, NULL, "sync_keyzone"));
04092
04093 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
04094 zone_needdump(zone, 30);
04095 commit = ISC_TRUE;
04096 }
04097
04098 failure:
04099 if (result != ISC_R_SUCCESS &&
04100 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
04101 dns_zone_log(zone, ISC_LOG_ERROR,
04102 "unable to synchronize managed keys: %s",
04103 dns_result_totext(result));
04104 isc_time_settoepoch(&zone->refreshkeytime);
04105 }
04106 if (keynode != NULL)
04107 dns_keytable_detachkeynode(sr, &keynode);
04108 if (sr != NULL)
04109 dns_keytable_detach(&sr);
04110 if (ver != NULL)
04111 dns_db_closeversion(db, &ver, commit);
04112 dns_diff_clear(&diff);
04113
04114 INSIST(ver == NULL);
04115
04116 return (result);
04117 }
04118
04119 isc_result_t
04120 dns_zone_synckeyzone(dns_zone_t *zone) {
04121 isc_result_t result;
04122 dns_db_t *db = NULL;
04123
04124 if (zone->type != dns_zone_key)
04125 return (DNS_R_BADZONE);
04126
04127 CHECK(dns_zone_getdb(zone, &db));
04128
04129 LOCK_ZONE(zone);
04130 result = sync_keyzone(zone, db);
04131 UNLOCK_ZONE(zone);
04132
04133 failure:
04134 if (db != NULL)
04135 dns_db_detach(&db);
04136 return (result);
04137 }
04138
04139 static void
04140 maybe_send_secure(dns_zone_t *zone) {
04141 isc_result_t result;
04142
04143
04144
04145
04146
04147
04148
04149
04150
04151
04152 if (zone->raw->db != NULL) {
04153 if (zone->db != NULL) {
04154 isc_uint32_t serial;
04155 unsigned int soacount;
04156
04157 result = zone_get_from_db(zone->raw, zone->raw->db,
04158 NULL, &soacount, &serial, NULL,
04159 NULL, NULL, NULL, NULL);
04160 if (result == ISC_R_SUCCESS && soacount > 0U)
04161 zone_send_secureserial(zone->raw, serial);
04162 } else
04163 zone_send_securedb(zone->raw, zone->raw->db);
04164
04165 } else
04166 DNS_ZONE_SETFLAG(zone->raw, DNS_ZONEFLG_SENDSECURE);
04167 }
04168
04169 static isc_boolean_t
04170 zone_unchanged(dns_db_t *db1, dns_db_t *db2, isc_mem_t *mctx) {
04171 isc_result_t result;
04172 isc_boolean_t answer = ISC_FALSE;
04173 dns_diff_t diff;
04174
04175 dns_diff_init(mctx, &diff);
04176 result = dns_db_diffx(&diff, db1, NULL, db2, NULL, NULL);
04177 if (result == ISC_R_SUCCESS && ISC_LIST_EMPTY(diff.tuples))
04178 answer = ISC_TRUE;
04179 dns_diff_clear(&diff);
04180 return (answer);
04181 }
04182
04183
04184
04185
04186
04187 static isc_result_t
04188 zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
04189 isc_result_t result)
04190 {
04191 unsigned int soacount = 0;
04192 unsigned int nscount = 0;
04193 unsigned int errors = 0;
04194 isc_uint32_t serial, oldserial, refresh, retry, expire, minimum;
04195 isc_time_t now;
04196 isc_boolean_t needdump = ISC_FALSE;
04197 isc_boolean_t hasinclude = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE);
04198 isc_boolean_t nomaster = ISC_FALSE;
04199 unsigned int options;
04200 dns_include_t *inc;
04201
04202 INSIST(LOCKED_ZONE(zone));
04203 if (inline_raw(zone))
04204 INSIST(LOCKED_ZONE(zone->secure));
04205
04206 TIME_NOW(&now);
04207
04208
04209
04210
04211
04212
04213 if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE) {
04214 if (zone->type == dns_zone_slave ||
04215 zone->type == dns_zone_stub ||
04216 (zone->type == dns_zone_redirect &&
04217 zone->masters == NULL)) {
04218 if (result == ISC_R_FILENOTFOUND)
04219 dns_zone_log(zone, ISC_LOG_DEBUG(1),
04220 "no master file");
04221 else if (result != DNS_R_NOMASTERFILE)
04222 dns_zone_log(zone, ISC_LOG_ERROR,
04223 "loading from master file %s "
04224 "failed: %s",
04225 zone->masterfile,
04226 dns_result_totext(result));
04227 } else if (zone->type == dns_zone_master &&
04228 inline_secure(zone) && result == ISC_R_FILENOTFOUND)
04229 {
04230 dns_zone_log(zone, ISC_LOG_DEBUG(1),
04231 "no master file, requesting db");
04232 maybe_send_secure(zone);
04233 } else {
04234 int level = ISC_LOG_ERROR;
04235 if (zone->type == dns_zone_key &&
04236 result == ISC_R_FILENOTFOUND)
04237 level = ISC_LOG_DEBUG(1);
04238 dns_zone_log(zone, level,
04239 "loading from master file %s failed: %s",
04240 zone->masterfile,
04241 dns_result_totext(result));
04242 nomaster = ISC_TRUE;
04243 }
04244
04245 if (zone->type != dns_zone_key)
04246 goto cleanup;
04247 }
04248
04249 dns_zone_log(zone, ISC_LOG_DEBUG(2),
04250 "number of nodes in database: %u",
04251 dns_db_nodecount(db));
04252
04253 if (result == DNS_R_SEENINCLUDE)
04254 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HASINCLUDE);
04255 else
04256 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HASINCLUDE);
04257
04258
04259
04260
04261
04262
04263
04264 if (nomaster && zone->type == dns_zone_key) {
04265 result = add_soa(zone, db);
04266 if (result != ISC_R_SUCCESS)
04267 goto cleanup;
04268 }
04269
04270
04271
04272
04273 if (zone->journal != NULL &&
04274 ! DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOMERGE) &&
04275 ! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
04276 {
04277 if (zone->type == dns_zone_master &&
04278 (zone->update_acl != NULL || zone->ssutable != NULL))
04279 options = DNS_JOURNALOPT_RESIGN;
04280 else
04281 options = 0;
04282 result = dns_journal_rollforward(zone->mctx, db, options,
04283 zone->journal);
04284 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND &&
04285 result != DNS_R_UPTODATE && result != DNS_R_NOJOURNAL &&
04286 result != ISC_R_RANGE) {
04287 dns_zone_log(zone, ISC_LOG_ERROR,
04288 "journal rollforward failed: %s",
04289 dns_result_totext(result));
04290 goto cleanup;
04291
04292
04293 }
04294 if (result == ISC_R_NOTFOUND || result == ISC_R_RANGE) {
04295 dns_zone_log(zone, ISC_LOG_ERROR,
04296 "journal rollforward failed: "
04297 "journal out of sync with zone");
04298 goto cleanup;
04299 }
04300 dns_zone_log(zone, ISC_LOG_DEBUG(1),
04301 "journal rollforward completed "
04302 "successfully: %s",
04303 dns_result_totext(result));
04304 if (result == ISC_R_SUCCESS)
04305 needdump = ISC_TRUE;
04306 }
04307
04308
04309
04310
04311 INSIST(db != NULL);
04312 result = zone_get_from_db(zone, db, &nscount, &soacount, &serial,
04313 &refresh, &retry, &expire, &minimum,
04314 &errors);
04315 if (result != ISC_R_SUCCESS && zone->type != dns_zone_key) {
04316 dns_zone_log(zone, ISC_LOG_ERROR,
04317 "could not find NS and/or SOA records");
04318 }
04319
04320
04321
04322
04323
04324
04325 if (zone->journal != NULL && dns_zone_isdynamic(zone, ISC_TRUE) &&
04326 ! DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS)) {
04327 isc_uint32_t jserial;
04328 dns_journal_t *journal = NULL;
04329
04330 result = dns_journal_open(zone->mctx, zone->journal,
04331 DNS_JOURNAL_READ, &journal);
04332 if (result == ISC_R_SUCCESS) {
04333 jserial = dns_journal_last_serial(journal);
04334 dns_journal_destroy(&journal);
04335 } else {
04336 jserial = serial;
04337 result = ISC_R_SUCCESS;
04338 }
04339
04340 if (jserial != serial) {
04341 dns_zone_log(zone, ISC_LOG_INFO,
04342 "journal file is out of date: "
04343 "removing journal file");
04344 if (remove(zone->journal) < 0 && errno != ENOENT) {
04345 char strbuf[ISC_STRERRORSIZE];
04346 isc__strerror(errno, strbuf, sizeof(strbuf));
04347 isc_log_write(dns_lctx,
04348 DNS_LOGCATEGORY_GENERAL,
04349 DNS_LOGMODULE_ZONE,
04350 ISC_LOG_WARNING,
04351 "unable to remove journal "
04352 "'%s': '%s'",
04353 zone->journal, strbuf);
04354 }
04355 }
04356 }
04357
04358 dns_zone_log(zone, ISC_LOG_DEBUG(1), "loaded; checking validity");
04359
04360
04361
04362
04363
04364
04365 switch (zone->type) {
04366 case dns_zone_dlz:
04367 case dns_zone_master:
04368 case dns_zone_slave:
04369 case dns_zone_stub:
04370 case dns_zone_redirect:
04371 if (soacount != 1) {
04372 dns_zone_log(zone, ISC_LOG_ERROR,
04373 "has %d SOA records", soacount);
04374 result = DNS_R_BADZONE;
04375 }
04376 if (nscount == 0) {
04377 dns_zone_log(zone, ISC_LOG_ERROR,
04378 "has no NS records");
04379 result = DNS_R_BADZONE;
04380 }
04381 if (result != ISC_R_SUCCESS)
04382 goto cleanup;
04383 if (zone->type == dns_zone_master && errors != 0) {
04384 result = DNS_R_BADZONE;
04385 goto cleanup;
04386 }
04387 if (zone->type != dns_zone_stub &&
04388 zone->type != dns_zone_redirect) {
04389 result = check_nsec3param(zone, db);
04390 if (result != ISC_R_SUCCESS)
04391 goto cleanup;
04392 }
04393 if (zone->type == dns_zone_master &&
04394 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKINTEGRITY) &&
04395 !integrity_checks(zone, db)) {
04396 result = DNS_R_BADZONE;
04397 goto cleanup;
04398 }
04399 if (zone->type == dns_zone_master &&
04400 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKDUPRR) &&
04401 !zone_check_dup(zone, db)) {
04402 result = DNS_R_BADZONE;
04403 goto cleanup;
04404 }
04405
04406 if (zone->db != NULL) {
04407 unsigned int oldsoacount;
04408
04409
04410
04411
04412
04413 result = zone_get_from_db(zone, zone->db, NULL,
04414 &oldsoacount, &oldserial,
04415 NULL, NULL, NULL, NULL,
04416 NULL);
04417 RUNTIME_CHECK(result == ISC_R_SUCCESS);
04418 RUNTIME_CHECK(soacount > 0U);
04419 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) &&
04420 !isc_serial_gt(serial, oldserial)) {
04421 isc_uint32_t serialmin, serialmax;
04422
04423 INSIST(zone->type == dns_zone_master);
04424
04425 if (serial == oldserial &&
04426 zone_unchanged(zone->db, db, zone->mctx)) {
04427 dns_zone_log(zone, ISC_LOG_INFO,
04428 "ixfr-from-differences: "
04429 "unchanged");
04430 return(ISC_R_SUCCESS);
04431 }
04432
04433 serialmin = (oldserial + 1) & 0xffffffffU;
04434 serialmax = (oldserial + 0x7fffffffU) &
04435 0xffffffffU;
04436 dns_zone_log(zone, ISC_LOG_ERROR,
04437 "ixfr-from-differences: "
04438 "new serial (%u) out of range "
04439 "[%u - %u]", serial, serialmin,
04440 serialmax);
04441 result = DNS_R_BADZONE;
04442 goto cleanup;
04443 } else if (!isc_serial_ge(serial, oldserial))
04444 dns_zone_log(zone, ISC_LOG_ERROR,
04445 "zone serial (%u/%u) has gone "
04446 "backwards", serial, oldserial);
04447 else if (serial == oldserial && !hasinclude &&
04448 strcmp(zone->db_argv[0], "_builtin") != 0)
04449 dns_zone_log(zone, ISC_LOG_ERROR,
04450 "zone serial (%u) unchanged. "
04451 "zone may fail to transfer "
04452 "to slaves.", serial);
04453 }
04454
04455 if (zone->type == dns_zone_master &&
04456 (zone->update_acl != NULL || zone->ssutable != NULL) &&
04457 zone->sigresigninginterval < (3 * refresh) &&
04458 dns_db_issecure(db))
04459 {
04460 dns_zone_log(zone, ISC_LOG_WARNING,
04461 "sig-re-signing-interval less than "
04462 "3 * refresh.");
04463 }
04464
04465 zone->refresh = RANGE(refresh,
04466 zone->minrefresh, zone->maxrefresh);
04467 zone->retry = RANGE(retry,
04468 zone->minretry, zone->maxretry);
04469 zone->expire = RANGE(expire, zone->refresh + zone->retry,
04470 DNS_MAX_EXPIRE);
04471 zone->minimum = minimum;
04472 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
04473
04474 if (zone->type == dns_zone_slave ||
04475 zone->type == dns_zone_stub ||
04476 (zone->type == dns_zone_redirect &&
04477 zone->masters != NULL)) {
04478 isc_time_t t;
04479 isc_uint32_t delay;
04480
04481 result = isc_file_getmodtime(zone->journal, &t);
04482 if (result != ISC_R_SUCCESS)
04483 result = isc_file_getmodtime(zone->masterfile,
04484 &t);
04485 if (result == ISC_R_SUCCESS)
04486 DNS_ZONE_TIME_ADD(&t, zone->expire,
04487 &zone->expiretime);
04488 else
04489 DNS_ZONE_TIME_ADD(&now, zone->retry,
04490 &zone->expiretime);
04491
04492 delay = isc_random_jitter(zone->retry,
04493 (zone->retry * 3) / 4);
04494 DNS_ZONE_TIME_ADD(&now, delay, &zone->refreshtime);
04495 if (isc_time_compare(&zone->refreshtime,
04496 &zone->expiretime) >= 0)
04497 zone->refreshtime = now;
04498 }
04499
04500 break;
04501
04502 case dns_zone_key:
04503 result = sync_keyzone(zone, db);
04504 if (result != ISC_R_SUCCESS)
04505 goto cleanup;
04506 break;
04507
04508 default:
04509 UNEXPECTED_ERROR(__FILE__, __LINE__,
04510 "unexpected zone type %d", zone->type);
04511 result = ISC_R_UNEXPECTED;
04512 goto cleanup;
04513 }
04514
04515
04516
04517
04518 if (zone->type == dns_zone_master)
04519 zone_check_dnskeys(zone, db);
04520
04521
04522
04523
04524 if (zone->type == dns_zone_master &&
04525 DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN))
04526 zone->refreshkeytime = now;
04527
04528 #if 0
04529
04530 {
04531 isc_event_t *e = isc_event_allocate(zone->mctx, NULL,
04532 DNS_EVENT_DBDESTROYED,
04533 dns_zonemgr_dbdestroyed,
04534 zone,
04535 sizeof(isc_event_t));
04536 dns_db_ondestroy(db, zone->task, &e);
04537 }
04538 #endif
04539
04540 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
04541 if (zone->db != NULL) {
04542 result = zone_replacedb(zone, db, ISC_FALSE);
04543 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
04544 if (result != ISC_R_SUCCESS)
04545 goto cleanup;
04546 } else {
04547 result = dns_db_rpz_ready(db);
04548 if (result != ISC_R_SUCCESS)
04549 goto cleanup;
04550 zone_attachdb(zone, db);
04551 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
04552 DNS_ZONE_SETFLAG(zone,
04553 DNS_ZONEFLG_LOADED|
04554 DNS_ZONEFLG_NEEDSTARTUPNOTIFY);
04555 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SENDSECURE) &&
04556 inline_raw(zone))
04557 {
04558 if (zone->secure->db == NULL)
04559 zone_send_securedb(zone, db);
04560 else
04561 zone_send_secureserial(zone, serial);
04562 }
04563 }
04564
04565
04566
04567
04568
04569 if (zone->type == dns_zone_master && inline_secure(zone))
04570 maybe_send_secure(zone);
04571
04572
04573 result = ISC_R_SUCCESS;
04574
04575 if (needdump) {
04576 if (zone->type == dns_zone_key)
04577 zone_needdump(zone, 30);
04578 else
04579 zone_needdump(zone, DNS_DUMP_DELAY);
04580 }
04581
04582 if (zone->task != NULL) {
04583 if (zone->type == dns_zone_master) {
04584 set_resigntime(zone);
04585 resume_signingwithkey(zone);
04586 resume_addnsec3chain(zone);
04587 }
04588
04589 if (zone->type == dns_zone_master &&
04590 !DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_NORESIGN) &&
04591 dns_zone_isdynamic(zone, ISC_FALSE) &&
04592 dns_db_issecure(db)) {
04593 dns_name_t *name;
04594 dns_fixedname_t fixed;
04595 dns_rdataset_t next;
04596
04597 dns_rdataset_init(&next);
04598 dns_fixedname_init(&fixed);
04599 name = dns_fixedname_name(&fixed);
04600
04601 result = dns_db_getsigningtime(db, &next, name);
04602 if (result == ISC_R_SUCCESS) {
04603 isc_stdtime_t timenow;
04604 char namebuf[DNS_NAME_FORMATSIZE];
04605 char typebuf[DNS_RDATATYPE_FORMATSIZE];
04606
04607 isc_stdtime_get(&timenow);
04608 dns_name_format(name, namebuf, sizeof(namebuf));
04609 dns_rdatatype_format(next.covers,
04610 typebuf, sizeof(typebuf));
04611 dns_zone_log(zone, ISC_LOG_DEBUG(3),
04612 "next resign: %s/%s in %d seconds",
04613 namebuf, typebuf,
04614 next.resign - timenow -
04615 zone->sigresigninginterval);
04616 dns_rdataset_disassociate(&next);
04617 } else
04618 dns_zone_log(zone, ISC_LOG_WARNING,
04619 "signed dynamic zone has no "
04620 "resign event scheduled");
04621 }
04622
04623 zone_settimer(zone, &now);
04624 }
04625
04626
04627
04628
04629 for (inc = ISC_LIST_HEAD(zone->includes);
04630 inc != NULL;
04631 inc = ISC_LIST_HEAD(zone->includes)) {
04632 ISC_LIST_UNLINK(zone->includes, inc, link);
04633 isc_mem_free(zone->mctx, inc->name);
04634 isc_mem_put(zone->mctx, inc, sizeof(*inc));
04635 }
04636 zone->nincludes = 0;
04637
04638
04639
04640
04641 for (inc = ISC_LIST_HEAD(zone->newincludes);
04642 inc != NULL;
04643 inc = ISC_LIST_HEAD(zone->newincludes)) {
04644 ISC_LIST_UNLINK(zone->newincludes, inc, link);
04645 ISC_LIST_APPEND(zone->includes, inc, link);
04646 zone->nincludes++;
04647 }
04648
04649 if (! dns_db_ispersistent(db))
04650 dns_zone_log(zone, ISC_LOG_INFO, "loaded serial %u%s", serial,
04651 dns_db_issecure(db) ? " (DNSSEC signed)" : "");
04652
04653 zone->loadtime = loadtime;
04654 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADPENDING);
04655 return (result);
04656
04657 cleanup:
04658 for (inc = ISC_LIST_HEAD(zone->newincludes);
04659 inc != NULL;
04660 inc = ISC_LIST_HEAD(zone->newincludes)) {
04661 ISC_LIST_UNLINK(zone->newincludes, inc, link);
04662 isc_mem_free(zone->mctx, inc->name);
04663 isc_mem_put(zone->mctx, inc, sizeof(*inc));
04664 }
04665 if (zone->type == dns_zone_slave ||
04666 zone->type == dns_zone_stub ||
04667 zone->type == dns_zone_key ||
04668 (zone->type == dns_zone_redirect && zone->masters != NULL)) {
04669 if (zone->journal != NULL)
04670 zone_saveunique(zone, zone->journal, "jn-XXXXXXXX");
04671 if (zone->masterfile != NULL)
04672 zone_saveunique(zone, zone->masterfile, "db-XXXXXXXX");
04673
04674
04675 zone->refreshtime = now;
04676 if (zone->task != NULL)
04677 zone_settimer(zone, &now);
04678 result = ISC_R_SUCCESS;
04679 } else if (zone->type == dns_zone_master ||
04680 zone->type == dns_zone_redirect) {
04681 if (!(inline_secure(zone) && result == ISC_R_FILENOTFOUND))
04682 dns_zone_log(zone, ISC_LOG_ERROR,
04683 "not loaded due to errors.");
04684 else if (zone->type == dns_zone_master)
04685 result = ISC_R_SUCCESS;
04686 }
04687
04688 return (result);
04689 }
04690
04691 static isc_boolean_t
04692 exit_check(dns_zone_t *zone) {
04693 REQUIRE(LOCKED_ZONE(zone));
04694
04695 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SHUTDOWN) && zone->irefs == 0) {
04696
04697
04698
04699 INSIST(isc_refcount_current(&zone->erefs) == 0);
04700 return (ISC_TRUE);
04701 }
04702 return (ISC_FALSE);
04703 }
04704
04705 static isc_boolean_t
04706 zone_check_ns(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
04707 dns_name_t *name, isc_boolean_t logit)
04708 {
04709 isc_result_t result;
04710 char namebuf[DNS_NAME_FORMATSIZE];
04711 char altbuf[DNS_NAME_FORMATSIZE];
04712 dns_fixedname_t fixed;
04713 dns_name_t *foundname;
04714 int level;
04715
04716 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOCHECKNS))
04717 return (ISC_TRUE);
04718
04719 if (zone->type == dns_zone_master)
04720 level = ISC_LOG_ERROR;
04721 else
04722 level = ISC_LOG_WARNING;
04723
04724 dns_fixedname_init(&fixed);
04725 foundname = dns_fixedname_name(&fixed);
04726
04727 result = dns_db_find(db, name, version, dns_rdatatype_a,
04728 0, 0, NULL, foundname, NULL, NULL);
04729 if (result == ISC_R_SUCCESS)
04730 return (ISC_TRUE);
04731
04732 if (result == DNS_R_NXRRSET) {
04733 result = dns_db_find(db, name, version, dns_rdatatype_aaaa,
04734 0, 0, NULL, foundname, NULL, NULL);
04735 if (result == ISC_R_SUCCESS)
04736 return (ISC_TRUE);
04737 }
04738
04739 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
04740 result == DNS_R_EMPTYNAME) {
04741 if (logit) {
04742 dns_name_format(name, namebuf, sizeof namebuf);
04743 dns_zone_log(zone, level, "NS '%s' has no address "
04744 "records (A or AAAA)", namebuf);
04745 }
04746 return (ISC_FALSE);
04747 }
04748
04749 if (result == DNS_R_CNAME) {
04750 if (logit) {
04751 dns_name_format(name, namebuf, sizeof namebuf);
04752 dns_zone_log(zone, level, "NS '%s' is a CNAME "
04753 "(illegal)", namebuf);
04754 }
04755 return (ISC_FALSE);
04756 }
04757
04758 if (result == DNS_R_DNAME) {
04759 if (logit) {
04760 dns_name_format(name, namebuf, sizeof namebuf);
04761 dns_name_format(foundname, altbuf, sizeof altbuf);
04762 dns_zone_log(zone, level, "NS '%s' is below a DNAME "
04763 "'%s' (illegal)", namebuf, altbuf);
04764 }
04765 return (ISC_FALSE);
04766 }
04767
04768 return (ISC_TRUE);
04769 }
04770
04771 static isc_result_t
04772 zone_count_ns_rr(dns_zone_t *zone, dns_db_t *db, dns_dbnode_t *node,
04773 dns_dbversion_t *version, unsigned int *nscount,
04774 unsigned int *errors, isc_boolean_t logit)
04775 {
04776 isc_result_t result;
04777 unsigned int count = 0;
04778 unsigned int ecount = 0;
04779 dns_rdataset_t rdataset;
04780 dns_rdata_t rdata;
04781 dns_rdata_ns_t ns;
04782
04783 dns_rdataset_init(&rdataset);
04784 result = dns_db_findrdataset(db, node, version, dns_rdatatype_ns,
04785 dns_rdatatype_none, 0, &rdataset, NULL);
04786 if (result == ISC_R_NOTFOUND) {
04787 INSIST(!dns_rdataset_isassociated(&rdataset));
04788 goto success;
04789 }
04790 if (result != ISC_R_SUCCESS) {
04791 INSIST(!dns_rdataset_isassociated(&rdataset));
04792 goto invalidate_rdataset;
04793 }
04794
04795 result = dns_rdataset_first(&rdataset);
04796 while (result == ISC_R_SUCCESS) {
04797 if (errors != NULL && zone->rdclass == dns_rdataclass_in &&
04798 (zone->type == dns_zone_master ||
04799 zone->type == dns_zone_slave)) {
04800 dns_rdata_init(&rdata);
04801 dns_rdataset_current(&rdataset, &rdata);
04802 result = dns_rdata_tostruct(&rdata, &ns, NULL);
04803 RUNTIME_CHECK(result == ISC_R_SUCCESS);
04804 if (dns_name_issubdomain(&ns.name, &zone->origin) &&
04805 !zone_check_ns(zone, db, version, &ns.name, logit))
04806 ecount++;
04807 }
04808 count++;
04809 result = dns_rdataset_next(&rdataset);
04810 }
04811 dns_rdataset_disassociate(&rdataset);
04812
04813 success:
04814 if (nscount != NULL)
04815 *nscount = count;
04816 if (errors != NULL)
04817 *errors = ecount;
04818
04819 result = ISC_R_SUCCESS;
04820
04821 invalidate_rdataset:
04822 dns_rdataset_invalidate(&rdataset);
04823
04824 return (result);
04825 }
04826
04827 static isc_result_t
04828 zone_load_soa_rr(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
04829 unsigned int *soacount,
04830 isc_uint32_t *serial, isc_uint32_t *refresh,
04831 isc_uint32_t *retry, isc_uint32_t *expire,
04832 isc_uint32_t *minimum)
04833 {
04834 isc_result_t result;
04835 unsigned int count;
04836 dns_rdataset_t rdataset;
04837 dns_rdata_t rdata = DNS_RDATA_INIT;
04838 dns_rdata_soa_t soa;
04839
04840 dns_rdataset_init(&rdataset);
04841 result = dns_db_findrdataset(db, node, version, dns_rdatatype_soa,
04842 dns_rdatatype_none, 0, &rdataset, NULL);
04843 if (result == ISC_R_NOTFOUND) {
04844 INSIST(!dns_rdataset_isassociated(&rdataset));
04845 if (soacount != NULL)
04846 *soacount = 0;
04847 if (serial != NULL)
04848 *serial = 0;
04849 if (refresh != NULL)
04850 *refresh = 0;
04851 if (retry != NULL)
04852 *retry = 0;
04853 if (expire != NULL)
04854 *expire = 0;
04855 if (minimum != NULL)
04856 *minimum = 0;
04857 result = ISC_R_SUCCESS;
04858 goto invalidate_rdataset;
04859 }
04860 if (result != ISC_R_SUCCESS) {
04861 INSIST(!dns_rdataset_isassociated(&rdataset));
04862 goto invalidate_rdataset;
04863 }
04864
04865 count = 0;
04866 result = dns_rdataset_first(&rdataset);
04867 while (result == ISC_R_SUCCESS) {
04868 dns_rdata_init(&rdata);
04869 dns_rdataset_current(&rdataset, &rdata);
04870 count++;
04871 if (count == 1) {
04872 result = dns_rdata_tostruct(&rdata, &soa, NULL);
04873 RUNTIME_CHECK(result == ISC_R_SUCCESS);
04874 }
04875
04876 result = dns_rdataset_next(&rdataset);
04877 dns_rdata_reset(&rdata);
04878 }
04879 dns_rdataset_disassociate(&rdataset);
04880
04881 if (soacount != NULL)
04882 *soacount = count;
04883
04884 if (count > 0) {
04885 if (serial != NULL)
04886 *serial = soa.serial;
04887 if (refresh != NULL)
04888 *refresh = soa.refresh;
04889 if (retry != NULL)
04890 *retry = soa.retry;
04891 if (expire != NULL)
04892 *expire = soa.expire;
04893 if (minimum != NULL)
04894 *minimum = soa.minimum;
04895 } else {
04896 if (soacount != NULL)
04897 *soacount = 0;
04898 if (serial != NULL)
04899 *serial = 0;
04900 if (refresh != NULL)
04901 *refresh = 0;
04902 if (retry != NULL)
04903 *retry = 0;
04904 if (expire != NULL)
04905 *expire = 0;
04906 if (minimum != NULL)
04907 *minimum = 0;
04908 }
04909
04910 result = ISC_R_SUCCESS;
04911
04912 invalidate_rdataset:
04913 dns_rdataset_invalidate(&rdataset);
04914
04915 return (result);
04916 }
04917
04918
04919
04920
04921 static isc_result_t
04922 zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount,
04923 unsigned int *soacount, isc_uint32_t *serial,
04924 isc_uint32_t *refresh, isc_uint32_t *retry,
04925 isc_uint32_t *expire, isc_uint32_t *minimum,
04926 unsigned int *errors)
04927 {
04928 isc_result_t result;
04929 isc_result_t answer = ISC_R_SUCCESS;
04930 dns_dbversion_t *version = NULL;
04931 dns_dbnode_t *node;
04932
04933 REQUIRE(db != NULL);
04934 REQUIRE(zone != NULL);
04935
04936 dns_db_currentversion(db, &version);
04937
04938 if (nscount != NULL)
04939 *nscount = 0;
04940 if (soacount != NULL)
04941 *soacount = 0;
04942 if (serial != NULL)
04943 *serial = 0;
04944 if (refresh != NULL)
04945 *refresh = 0;
04946 if (retry != NULL)
04947 *retry = 0;
04948 if (expire != NULL)
04949 *expire = 0;
04950 if (errors != NULL)
04951 *errors = 0;
04952
04953 node = NULL;
04954 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node);
04955 if (result != ISC_R_SUCCESS) {
04956 answer = result;
04957 goto closeversion;
04958 }
04959
04960 if (nscount != NULL || errors != NULL) {
04961 result = zone_count_ns_rr(zone, db, node, version,
04962 nscount, errors, ISC_TRUE);
04963 if (result != ISC_R_SUCCESS)
04964 answer = result;
04965 }
04966
04967 if (soacount != NULL || serial != NULL || refresh != NULL
04968 || retry != NULL || expire != NULL || minimum != NULL) {
04969 result = zone_load_soa_rr(db, node, version, soacount,
04970 serial, refresh, retry, expire,
04971 minimum);
04972 if (result != ISC_R_SUCCESS)
04973 answer = result;
04974 }
04975
04976 dns_db_detachnode(db, &node);
04977 closeversion:
04978 dns_db_closeversion(db, &version, ISC_FALSE);
04979
04980 return (answer);
04981 }
04982
04983 void
04984 dns_zone_attach(dns_zone_t *source, dns_zone_t **target) {
04985 REQUIRE(DNS_ZONE_VALID(source));
04986 REQUIRE(target != NULL && *target == NULL);
04987 isc_refcount_increment(&source->erefs, NULL);
04988 *target = source;
04989 }
04990
04991 void
04992 dns_zone_detach(dns_zone_t **zonep) {
04993 dns_zone_t *zone;
04994 dns_zone_t *raw = NULL;
04995 dns_zone_t *secure = NULL;
04996 unsigned int refs;
04997 isc_boolean_t free_now = ISC_FALSE;
04998
04999 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
05000
05001 zone = *zonep;
05002
05003 isc_refcount_decrement(&zone->erefs, &refs);
05004
05005 if (refs == 0) {
05006 LOCK_ZONE(zone);
05007 INSIST(zone != zone->raw);
05008
05009
05010
05011 if (zone->task != NULL) {
05012
05013
05014
05015
05016
05017
05018 isc_event_t *ev = &zone->ctlevent;
05019 isc_task_send(zone->task, &ev);
05020 } else {
05021
05022
05023
05024
05025
05026
05027
05028
05029
05030
05031
05032 INSIST(zone->view == NULL);
05033 free_now = ISC_TRUE;
05034 raw = zone->raw;
05035 zone->raw = NULL;
05036 secure = zone->secure;
05037 zone->secure = NULL;
05038 }
05039 UNLOCK_ZONE(zone);
05040 }
05041 *zonep = NULL;
05042 if (free_now) {
05043 if (raw != NULL)
05044 dns_zone_detach(&raw);
05045 if (secure != NULL)
05046 dns_zone_idetach(&secure);
05047 zone_free(zone);
05048 }
05049 }
05050
05051 void
05052 dns_zone_iattach(dns_zone_t *source, dns_zone_t **target) {
05053 REQUIRE(DNS_ZONE_VALID(source));
05054 REQUIRE(target != NULL && *target == NULL);
05055 LOCK_ZONE(source);
05056 zone_iattach(source, target);
05057 UNLOCK_ZONE(source);
05058 }
05059
05060 static void
05061 zone_iattach(dns_zone_t *source, dns_zone_t **target) {
05062
05063
05064
05065
05066 REQUIRE(LOCKED_ZONE(source));
05067 REQUIRE(DNS_ZONE_VALID(source));
05068 REQUIRE(target != NULL && *target == NULL);
05069 INSIST(source->irefs + isc_refcount_current(&source->erefs) > 0);
05070 source->irefs++;
05071 INSIST(source->irefs != 0);
05072 *target = source;
05073 }
05074
05075 static void
05076 zone_idetach(dns_zone_t **zonep) {
05077 dns_zone_t *zone;
05078
05079
05080
05081
05082 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
05083 zone = *zonep;
05084 REQUIRE(LOCKED_ZONE(*zonep));
05085 *zonep = NULL;
05086
05087 INSIST(zone->irefs > 0);
05088 zone->irefs--;
05089 INSIST(zone->irefs + isc_refcount_current(&zone->erefs) > 0);
05090 }
05091
05092 void
05093 dns_zone_idetach(dns_zone_t **zonep) {
05094 dns_zone_t *zone;
05095 isc_boolean_t free_needed;
05096
05097 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
05098 zone = *zonep;
05099 *zonep = NULL;
05100
05101 LOCK_ZONE(zone);
05102 INSIST(zone->irefs > 0);
05103 zone->irefs--;
05104 free_needed = exit_check(zone);
05105 UNLOCK_ZONE(zone);
05106 if (free_needed)
05107 zone_free(zone);
05108 }
05109
05110 isc_mem_t *
05111 dns_zone_getmctx(dns_zone_t *zone) {
05112 REQUIRE(DNS_ZONE_VALID(zone));
05113
05114 return (zone->mctx);
05115 }
05116
05117 dns_zonemgr_t *
05118 dns_zone_getmgr(dns_zone_t *zone) {
05119 REQUIRE(DNS_ZONE_VALID(zone));
05120
05121 return (zone->zmgr);
05122 }
05123
05124 void
05125 dns_zone_setflag(dns_zone_t *zone, unsigned int flags, isc_boolean_t value) {
05126 REQUIRE(DNS_ZONE_VALID(zone));
05127
05128 LOCK_ZONE(zone);
05129 if (value)
05130 DNS_ZONE_SETFLAG(zone, flags);
05131 else
05132 DNS_ZONE_CLRFLAG(zone, flags);
05133 UNLOCK_ZONE(zone);
05134 }
05135
05136 void
05137 dns_zone_setoption(dns_zone_t *zone, unsigned int option,
05138 isc_boolean_t value)
05139 {
05140 REQUIRE(DNS_ZONE_VALID(zone));
05141
05142 LOCK_ZONE(zone);
05143 if (value)
05144 zone->options |= option;
05145 else
05146 zone->options &= ~option;
05147 UNLOCK_ZONE(zone);
05148 }
05149
05150 void
05151 dns_zone_setoption2(dns_zone_t *zone, unsigned int option,
05152 isc_boolean_t value)
05153 {
05154 REQUIRE(DNS_ZONE_VALID(zone));
05155
05156 LOCK_ZONE(zone);
05157 if (value)
05158 zone->options2 |= option;
05159 else
05160 zone->options2 &= ~option;
05161 UNLOCK_ZONE(zone);
05162 }
05163
05164 unsigned int
05165 dns_zone_getoptions(dns_zone_t *zone) {
05166 REQUIRE(DNS_ZONE_VALID(zone));
05167
05168 return (zone->options);
05169 }
05170
05171 unsigned int
05172 dns_zone_getoptions2(dns_zone_t *zone) {
05173 REQUIRE(DNS_ZONE_VALID(zone));
05174
05175 return (zone->options2);
05176 }
05177
05178 void
05179 dns_zone_setkeyopt(dns_zone_t *zone, unsigned int keyopt, isc_boolean_t value)
05180 {
05181 REQUIRE(DNS_ZONE_VALID(zone));
05182
05183 LOCK_ZONE(zone);
05184 if (value)
05185 zone->keyopts |= keyopt;
05186 else
05187 zone->keyopts &= ~keyopt;
05188 UNLOCK_ZONE(zone);
05189 }
05190
05191 unsigned int
05192 dns_zone_getkeyopts(dns_zone_t *zone) {
05193
05194 REQUIRE(DNS_ZONE_VALID(zone));
05195
05196 return (zone->keyopts);
05197 }
05198
05199 isc_result_t
05200 dns_zone_setxfrsource4(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) {
05201 REQUIRE(DNS_ZONE_VALID(zone));
05202
05203 LOCK_ZONE(zone);
05204 zone->xfrsource4 = *xfrsource;
05205 UNLOCK_ZONE(zone);
05206
05207 return (ISC_R_SUCCESS);
05208 }
05209
05210 isc_sockaddr_t *
05211 dns_zone_getxfrsource4(dns_zone_t *zone) {
05212 REQUIRE(DNS_ZONE_VALID(zone));
05213 return (&zone->xfrsource4);
05214 }
05215
05216 isc_result_t
05217 dns_zone_setxfrsource4dscp(dns_zone_t *zone, isc_dscp_t dscp) {
05218 REQUIRE(DNS_ZONE_VALID(zone));
05219
05220 LOCK_ZONE(zone);
05221 zone->xfrsource4dscp = dscp;
05222 UNLOCK_ZONE(zone);
05223
05224 return (ISC_R_SUCCESS);
05225 }
05226
05227 isc_dscp_t
05228 dns_zone_getxfrsource4dscp(dns_zone_t *zone) {
05229 REQUIRE(DNS_ZONE_VALID(zone));
05230 return (zone->xfrsource4dscp);
05231 }
05232
05233 isc_result_t
05234 dns_zone_setxfrsource6(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) {
05235 REQUIRE(DNS_ZONE_VALID(zone));
05236
05237 LOCK_ZONE(zone);
05238 zone->xfrsource6 = *xfrsource;
05239 UNLOCK_ZONE(zone);
05240
05241 return (ISC_R_SUCCESS);
05242 }
05243
05244 isc_sockaddr_t *
05245 dns_zone_getxfrsource6(dns_zone_t *zone) {
05246 REQUIRE(DNS_ZONE_VALID(zone));
05247 return (&zone->xfrsource6);
05248 }
05249
05250 isc_dscp_t
05251 dns_zone_getxfrsource6dscp(dns_zone_t *zone) {
05252 REQUIRE(DNS_ZONE_VALID(zone));
05253 return (zone->xfrsource6dscp);
05254 }
05255
05256 isc_result_t
05257 dns_zone_setxfrsource6dscp(dns_zone_t *zone, isc_dscp_t dscp) {
05258 REQUIRE(DNS_ZONE_VALID(zone));
05259
05260 LOCK_ZONE(zone);
05261 zone->xfrsource6dscp = dscp;
05262 UNLOCK_ZONE(zone);
05263
05264 return (ISC_R_SUCCESS);
05265 }
05266
05267 isc_result_t
05268 dns_zone_setaltxfrsource4(dns_zone_t *zone,
05269 const isc_sockaddr_t *altxfrsource)
05270 {
05271 REQUIRE(DNS_ZONE_VALID(zone));
05272
05273 LOCK_ZONE(zone);
05274 zone->altxfrsource4 = *altxfrsource;
05275 UNLOCK_ZONE(zone);
05276
05277 return (ISC_R_SUCCESS);
05278 }
05279
05280 isc_sockaddr_t *
05281 dns_zone_getaltxfrsource4(dns_zone_t *zone) {
05282 REQUIRE(DNS_ZONE_VALID(zone));
05283 return (&zone->altxfrsource4);
05284 }
05285
05286 isc_result_t
05287 dns_zone_setaltxfrsource4dscp(dns_zone_t *zone, isc_dscp_t dscp) {
05288 REQUIRE(DNS_ZONE_VALID(zone));
05289
05290 LOCK_ZONE(zone);
05291 zone->altxfrsource4dscp = dscp;
05292 UNLOCK_ZONE(zone);
05293
05294 return (ISC_R_SUCCESS);
05295 }
05296
05297 isc_dscp_t
05298 dns_zone_getaltxfrsource4dscp(dns_zone_t *zone) {
05299 REQUIRE(DNS_ZONE_VALID(zone));
05300 return (zone->altxfrsource4dscp);
05301 }
05302
05303 isc_result_t
05304 dns_zone_setaltxfrsource6(dns_zone_t *zone,
05305 const isc_sockaddr_t *altxfrsource)
05306 {
05307 REQUIRE(DNS_ZONE_VALID(zone));
05308
05309 LOCK_ZONE(zone);
05310 zone->altxfrsource6 = *altxfrsource;
05311 UNLOCK_ZONE(zone);
05312
05313 return (ISC_R_SUCCESS);
05314 }
05315
05316 isc_sockaddr_t *
05317 dns_zone_getaltxfrsource6(dns_zone_t *zone) {
05318 REQUIRE(DNS_ZONE_VALID(zone));
05319 return (&zone->altxfrsource6);
05320 }
05321
05322 isc_result_t
05323 dns_zone_setaltxfrsource6dscp(dns_zone_t *zone, isc_dscp_t dscp) {
05324 REQUIRE(DNS_ZONE_VALID(zone));
05325
05326 LOCK_ZONE(zone);
05327 zone->altxfrsource6dscp = dscp;
05328 UNLOCK_ZONE(zone);
05329
05330 return (ISC_R_SUCCESS);
05331 }
05332
05333 isc_dscp_t
05334 dns_zone_getaltxfrsource6dscp(dns_zone_t *zone) {
05335 REQUIRE(DNS_ZONE_VALID(zone));
05336 return (zone->altxfrsource6dscp);
05337 }
05338
05339 isc_result_t
05340 dns_zone_setnotifysrc4(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) {
05341 REQUIRE(DNS_ZONE_VALID(zone));
05342
05343 LOCK_ZONE(zone);
05344 zone->notifysrc4 = *notifysrc;
05345 UNLOCK_ZONE(zone);
05346
05347 return (ISC_R_SUCCESS);
05348 }
05349
05350 isc_sockaddr_t *
05351 dns_zone_getnotifysrc4(dns_zone_t *zone) {
05352 REQUIRE(DNS_ZONE_VALID(zone));
05353 return (&zone->notifysrc4);
05354 }
05355
05356 isc_result_t
05357 dns_zone_setnotifysrc4dscp(dns_zone_t *zone, isc_dscp_t dscp) {
05358 REQUIRE(DNS_ZONE_VALID(zone));
05359
05360 LOCK_ZONE(zone);
05361 zone->notifysrc4dscp = dscp;
05362 UNLOCK_ZONE(zone);
05363
05364 return (ISC_R_SUCCESS);
05365 }
05366
05367 isc_dscp_t
05368 dns_zone_getnotifysrc4dscp(dns_zone_t *zone) {
05369 REQUIRE(DNS_ZONE_VALID(zone));
05370 return (zone->notifysrc4dscp);
05371 }
05372
05373 isc_result_t
05374 dns_zone_setnotifysrc6(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) {
05375 REQUIRE(DNS_ZONE_VALID(zone));
05376
05377 LOCK_ZONE(zone);
05378 zone->notifysrc6 = *notifysrc;
05379 UNLOCK_ZONE(zone);
05380
05381 return (ISC_R_SUCCESS);
05382 }
05383
05384 isc_sockaddr_t *
05385 dns_zone_getnotifysrc6(dns_zone_t *zone) {
05386 REQUIRE(DNS_ZONE_VALID(zone));
05387 return (&zone->notifysrc6);
05388 }
05389
05390 static isc_boolean_t
05391 same_addrs(const isc_sockaddr_t *old, const isc_sockaddr_t *new,
05392 isc_uint32_t count)
05393 {
05394 unsigned int i;
05395
05396 for (i = 0; i < count; i++)
05397 if (!isc_sockaddr_equal(&old[i], &new[i]))
05398 return (ISC_FALSE);
05399 return (ISC_TRUE);
05400 }
05401
05402 static isc_boolean_t
05403 same_keynames(dns_name_t **old, dns_name_t **new, isc_uint32_t count) {
05404 unsigned int i;
05405
05406 if (old == NULL && new == NULL)
05407 return (ISC_TRUE);
05408 if (old == NULL || new == NULL)
05409 return (ISC_FALSE);
05410
05411 for (i = 0; i < count; i++) {
05412 if (old[i] == NULL && new[i] == NULL)
05413 continue;
05414 if (old[i] == NULL || new[i] == NULL ||
05415 !dns_name_equal(old[i], new[i]))
05416 return (ISC_FALSE);
05417 }
05418 return (ISC_TRUE);
05419 }
05420
05421 static void
05422 clear_addresskeylist(isc_sockaddr_t **addrsp, isc_dscp_t **dscpsp,
05423 dns_name_t ***keynamesp, unsigned int *countp,
05424 isc_mem_t *mctx)
05425 {
05426 unsigned int count;
05427 isc_sockaddr_t *addrs;
05428 isc_dscp_t *dscps;
05429 dns_name_t **keynames;
05430
05431 REQUIRE(countp != NULL && addrsp != NULL && dscpsp != NULL &&
05432 keynamesp != NULL);
05433
05434 count = *countp;
05435 *countp = 0;
05436 addrs = *addrsp;
05437 *addrsp = NULL;
05438 dscps = *dscpsp;
05439 *dscpsp = NULL;
05440 keynames = *keynamesp;
05441 *keynamesp = NULL;
05442
05443 if (addrs != NULL)
05444 isc_mem_put(mctx, addrs, count * sizeof(isc_sockaddr_t));
05445
05446 if (dscps != NULL)
05447 isc_mem_put(mctx, dscps, count * sizeof(isc_dscp_t));
05448
05449 if (keynames != NULL) {
05450 unsigned int i;
05451 for (i = 0; i < count; i++) {
05452 if (keynames[i] != NULL) {
05453 dns_name_free(keynames[i], mctx);
05454 isc_mem_put(mctx, keynames[i],
05455 sizeof(dns_name_t));
05456 keynames[i] = NULL;
05457 }
05458 }
05459 isc_mem_put(mctx, keynames, count * sizeof(dns_name_t *));
05460 }
05461 }
05462
05463 static isc_result_t
05464 set_addrkeylist(unsigned int count,
05465 const isc_sockaddr_t *addrs, isc_sockaddr_t **newaddrsp,
05466 const isc_dscp_t *dscp, isc_dscp_t **newdscpp,
05467 dns_name_t **names, dns_name_t ***newnamesp,
05468 isc_mem_t *mctx)
05469 {
05470 isc_result_t result;
05471 isc_sockaddr_t *newaddrs = NULL;
05472 isc_dscp_t *newdscp = NULL;
05473 dns_name_t **newnames = NULL;
05474 unsigned int i;
05475
05476 REQUIRE(newaddrsp != NULL && *newaddrsp == NULL);
05477 REQUIRE(newdscpp != NULL && *newdscpp == NULL);
05478 REQUIRE(newnamesp != NULL && *newnamesp == NULL);
05479
05480 newaddrs = isc_mem_get(mctx, count * sizeof(*newaddrs));
05481 if (newaddrs == NULL)
05482 return (ISC_R_NOMEMORY);
05483 memmove(newaddrs, addrs, count * sizeof(*newaddrs));
05484
05485 if (dscp != NULL) {
05486 newdscp = isc_mem_get(mctx, count * sizeof(*newdscp));
05487 if (newdscp == NULL) {
05488 isc_mem_put(mctx, newaddrs, count * sizeof(*newaddrs));
05489 return (ISC_R_NOMEMORY);
05490 }
05491 memmove(newdscp, dscp, count * sizeof(*newdscp));
05492 } else
05493 newdscp = NULL;
05494
05495 if (names != NULL) {
05496 newnames = isc_mem_get(mctx, count * sizeof(*newnames));
05497 if (newnames == NULL) {
05498 if (newdscp != NULL)
05499 isc_mem_put(mctx, newdscp,
05500 count * sizeof(*newdscp));
05501 isc_mem_put(mctx, newaddrs, count * sizeof(*newaddrs));
05502 return (ISC_R_NOMEMORY);
05503 }
05504 for (i = 0; i < count; i++)
05505 newnames[i] = NULL;
05506 for (i = 0; i < count; i++) {
05507 if (names[i] != NULL) {
05508 newnames[i] = isc_mem_get(mctx,
05509 sizeof(dns_name_t));
05510 if (newnames[i] == NULL)
05511 goto allocfail;
05512 dns_name_init(newnames[i], NULL);
05513 result = dns_name_dup(names[i], mctx,
05514 newnames[i]);
05515 if (result != ISC_R_SUCCESS) {
05516 allocfail:
05517 for (i = 0; i < count; i++)
05518 if (newnames[i] != NULL)
05519 dns_name_free(
05520 newnames[i],
05521 mctx);
05522 isc_mem_put(mctx, newaddrs,
05523 count * sizeof(*newaddrs));
05524 isc_mem_put(mctx, newdscp,
05525 count * sizeof(*newdscp));
05526 isc_mem_put(mctx, newnames,
05527 count * sizeof(*newnames));
05528 return (ISC_R_NOMEMORY);
05529 }
05530 }
05531 }
05532 } else
05533 newnames = NULL;
05534
05535 *newdscpp = newdscp;
05536 *newaddrsp = newaddrs;
05537 *newnamesp = newnames;
05538 return (ISC_R_SUCCESS);
05539 }
05540
05541 isc_result_t
05542 dns_zone_setnotifysrc6dscp(dns_zone_t *zone, isc_dscp_t dscp) {
05543 REQUIRE(DNS_ZONE_VALID(zone));
05544
05545 LOCK_ZONE(zone);
05546 zone->notifysrc6dscp = dscp;
05547 UNLOCK_ZONE(zone);
05548
05549 return (ISC_R_SUCCESS);
05550 }
05551
05552 isc_dscp_t
05553 dns_zone_getnotifysrc6dscp(dns_zone_t *zone) {
05554 REQUIRE(DNS_ZONE_VALID(zone));
05555 return (zone->notifysrc6dscp);
05556 }
05557
05558 isc_result_t
05559 dns_zone_setalsonotify(dns_zone_t *zone, const isc_sockaddr_t *notify,
05560 isc_uint32_t count)
05561 {
05562 return (dns_zone_setalsonotifydscpkeys(zone, notify, NULL, NULL,
05563 count));
05564 }
05565
05566 isc_result_t
05567 dns_zone_setalsonotifywithkeys(dns_zone_t *zone, const isc_sockaddr_t *notify,
05568 dns_name_t **keynames, isc_uint32_t count)
05569 {
05570 return (dns_zone_setalsonotifydscpkeys(zone, notify, NULL, keynames,
05571 count));
05572 }
05573
05574 isc_result_t
05575 dns_zone_setalsonotifydscpkeys(dns_zone_t *zone, const isc_sockaddr_t *notify,
05576 const isc_dscp_t *dscps, dns_name_t **keynames,
05577 isc_uint32_t count)
05578 {
05579 isc_result_t result;
05580 isc_sockaddr_t *newaddrs = NULL;
05581 isc_dscp_t *newdscps = NULL;
05582 dns_name_t **newnames = NULL;
05583
05584 REQUIRE(DNS_ZONE_VALID(zone));
05585 REQUIRE(count == 0 || notify != NULL);
05586 if (keynames != NULL)
05587 REQUIRE(count != 0);
05588
05589 LOCK_ZONE(zone);
05590
05591 if (count == zone->notifycnt &&
05592 same_addrs(zone->notify, notify, count) &&
05593 same_keynames(zone->notifykeynames, keynames, count))
05594 goto unlock;
05595
05596 clear_addresskeylist(&zone->notify, &zone->notifydscp,
05597 &zone->notifykeynames, &zone->notifycnt,
05598 zone->mctx);
05599
05600 if (count == 0)
05601 goto unlock;
05602
05603
05604
05605
05606 result = set_addrkeylist(count, notify, &newaddrs, dscps, &newdscps,
05607 keynames, &newnames, zone->mctx);
05608 if (result != ISC_R_SUCCESS)
05609 goto unlock;
05610
05611
05612
05613
05614 zone->notify = newaddrs;
05615 zone->notifydscp = newdscps;
05616 zone->notifykeynames = newnames;
05617 zone->notifycnt = count;
05618 unlock:
05619 UNLOCK_ZONE(zone);
05620 return (ISC_R_SUCCESS);
05621 }
05622
05623 isc_result_t
05624 dns_zone_setmasters(dns_zone_t *zone, const isc_sockaddr_t *masters,
05625 isc_uint32_t count)
05626 {
05627 isc_result_t result;
05628
05629 result = dns_zone_setmasterswithkeys(zone, masters, NULL, count);
05630 return (result);
05631 }
05632
05633 isc_result_t
05634 dns_zone_setmasterswithkeys(dns_zone_t *zone,
05635 const isc_sockaddr_t *masters,
05636 dns_name_t **keynames,
05637 isc_uint32_t count)
05638 {
05639 isc_result_t result = ISC_R_SUCCESS;
05640 isc_sockaddr_t *newaddrs = NULL;
05641 isc_dscp_t *newdscps = NULL;
05642 dns_name_t **newnames = NULL;
05643 isc_boolean_t *newok;
05644 unsigned int i;
05645
05646 REQUIRE(DNS_ZONE_VALID(zone));
05647 REQUIRE(count == 0 || masters != NULL);
05648 if (keynames != NULL) {
05649 REQUIRE(count != 0);
05650 }
05651
05652 LOCK_ZONE(zone);
05653
05654
05655
05656
05657
05658
05659 if (count != zone->masterscnt ||
05660 !same_addrs(zone->masters, masters, count) ||
05661 !same_keynames(zone->masterkeynames, keynames, count)) {
05662 if (zone->request != NULL)
05663 dns_request_cancel(zone->request);
05664 } else
05665 goto unlock;
05666
05667
05668
05669
05670
05671 if (zone->mastersok != NULL) {
05672 isc_mem_put(zone->mctx, zone->mastersok,
05673 zone->masterscnt * sizeof(isc_boolean_t));
05674 zone->mastersok = NULL;
05675 }
05676 clear_addresskeylist(&zone->masters, &zone->masterdscps,
05677 &zone->masterkeynames, &zone->masterscnt,
05678 zone->mctx);
05679
05680
05681
05682
05683 if (count == 0)
05684 goto unlock;
05685
05686
05687
05688
05689 newok = isc_mem_get(zone->mctx, count * sizeof(*newok));
05690 if (newok == NULL) {
05691 result = ISC_R_NOMEMORY;
05692 isc_mem_put(zone->mctx, newaddrs, count * sizeof(*newaddrs));
05693 goto unlock;
05694 };
05695 for (i = 0; i < count; i++)
05696 newok[i] = ISC_FALSE;
05697
05698
05699
05700
05701 result = set_addrkeylist(count, masters, &newaddrs, NULL, &newdscps,
05702 keynames, &newnames, zone->mctx);
05703 INSIST(newdscps == NULL);
05704 if (result != ISC_R_SUCCESS) {
05705 isc_mem_put(zone->mctx, newok, count * sizeof(*newok));
05706 goto unlock;
05707 }
05708
05709
05710
05711
05712 zone->curmaster = 0;
05713 zone->mastersok = newok;
05714 zone->masters = newaddrs;
05715 zone->masterdscps = newdscps;
05716 zone->masterkeynames = newnames;
05717 zone->masterscnt = count;
05718 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOMASTERS);
05719
05720 unlock:
05721 UNLOCK_ZONE(zone);
05722 return (result);
05723 }
05724
05725 isc_result_t
05726 dns_zone_getdb(dns_zone_t *zone, dns_db_t **dpb) {
05727 isc_result_t result = ISC_R_SUCCESS;
05728
05729 REQUIRE(DNS_ZONE_VALID(zone));
05730
05731 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
05732 if (zone->db == NULL)
05733 result = DNS_R_NOTLOADED;
05734 else
05735 dns_db_attach(zone->db, dpb);
05736 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
05737
05738 return (result);
05739 }
05740
05741 void
05742 dns_zone_setdb(dns_zone_t *zone, dns_db_t *db) {
05743 REQUIRE(DNS_ZONE_VALID(zone));
05744 REQUIRE(zone->type == dns_zone_staticstub);
05745
05746 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
05747 REQUIRE(zone->db == NULL);
05748 dns_db_attach(db, &zone->db);
05749 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
05750 }
05751
05752
05753
05754
05755
05756 void
05757 dns_zone_maintenance(dns_zone_t *zone) {
05758 const char me[] = "dns_zone_maintenance";
05759 isc_time_t now;
05760
05761 REQUIRE(DNS_ZONE_VALID(zone));
05762 ENTER;
05763
05764 LOCK_ZONE(zone);
05765 TIME_NOW(&now);
05766 zone_settimer(zone, &now);
05767 UNLOCK_ZONE(zone);
05768 }
05769
05770 static inline isc_boolean_t
05771 was_dumping(dns_zone_t *zone) {
05772 isc_boolean_t dumping;
05773
05774 REQUIRE(LOCKED_ZONE(zone));
05775
05776 dumping = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING);
05777 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
05778 if (!dumping) {
05779 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
05780 isc_time_settoepoch(&zone->dumptime);
05781 }
05782 return (dumping);
05783 }
05784
05785 static isc_result_t
05786 find_zone_keys(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
05787 isc_mem_t *mctx, unsigned int maxkeys,
05788 dst_key_t **keys, unsigned int *nkeys)
05789 {
05790 isc_result_t result;
05791 dns_dbnode_t *node = NULL;
05792 const char *directory = dns_zone_getkeydirectory(zone);
05793
05794 CHECK(dns_db_findnode(db, dns_db_origin(db), ISC_FALSE, &node));
05795 memset(keys, 0, sizeof(*keys) * maxkeys);
05796 result = dns_dnssec_findzonekeys2(db, ver, node, dns_db_origin(db),
05797 directory, mctx, maxkeys, keys,
05798 nkeys);
05799 if (result == ISC_R_NOTFOUND)
05800 result = ISC_R_SUCCESS;
05801 failure:
05802 if (node != NULL)
05803 dns_db_detachnode(db, &node);
05804 return (result);
05805 }
05806
05807 static isc_result_t
05808 offline(dns_db_t *db, dns_dbversion_t *ver, zonediff_t *zonediff,
05809 dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata)
05810 {
05811 isc_result_t result;
05812
05813 if ((rdata->flags & DNS_RDATA_OFFLINE) != 0)
05814 return (ISC_R_SUCCESS);
05815 result = update_one_rr(db, ver, zonediff->diff, DNS_DIFFOP_DELRESIGN,
05816 name, ttl, rdata);
05817 if (result != ISC_R_SUCCESS)
05818 return (result);
05819 rdata->flags |= DNS_RDATA_OFFLINE;
05820 result = update_one_rr(db, ver, zonediff->diff, DNS_DIFFOP_ADDRESIGN,
05821 name, ttl, rdata);
05822 zonediff->offline = ISC_TRUE;
05823 return (result);
05824 }
05825
05826 static void
05827 set_key_expiry_warning(dns_zone_t *zone, isc_stdtime_t when, isc_stdtime_t now)
05828 {
05829 unsigned int delta;
05830 char timebuf[80];
05831
05832 zone->key_expiry = when;
05833 if (when <= now) {
05834 dns_zone_log(zone, ISC_LOG_ERROR,
05835 "DNSKEY RRSIG(s) have expired");
05836 isc_time_settoepoch(&zone->keywarntime);
05837 } else if (when < now + 7 * 24 * 3600) {
05838 isc_time_t t;
05839 isc_time_set(&t, when, 0);
05840 isc_time_formattimestamp(&t, timebuf, 80);
05841 dns_zone_log(zone, ISC_LOG_WARNING,
05842 "DNSKEY RRSIG(s) will expire within 7 days: %s",
05843 timebuf);
05844 delta = when - now;
05845 delta--;
05846 delta /= 24 * 3600;
05847 delta *= 24 * 3600;
05848 isc_time_set(&zone->keywarntime, when - delta, 0);
05849 } else {
05850 isc_time_set(&zone->keywarntime, when - 7 * 24 * 3600, 0);
05851 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
05852 dns_zone_log(zone, ISC_LOG_NOTICE,
05853 "setting keywarntime to %s", timebuf);
05854 }
05855 }
05856
05857
05858
05859
05860
05861 static isc_boolean_t
05862 delsig_ok(dns_rdata_rrsig_t *rrsig_ptr, dst_key_t **keys, unsigned int nkeys,
05863 isc_boolean_t *warn)
05864 {
05865 unsigned int i = 0;
05866 isc_boolean_t have_ksk = ISC_FALSE, have_zsk = ISC_FALSE;
05867 isc_boolean_t have_pksk = ISC_FALSE, have_pzsk = ISC_FALSE;
05868
05869 for (i = 0; i < nkeys; i++) {
05870 if (rrsig_ptr->algorithm != dst_key_alg(keys[i]))
05871 continue;
05872 if (dst_key_isprivate(keys[i])) {
05873 if (KSK(keys[i]))
05874 have_ksk = have_pksk = ISC_TRUE;
05875 else
05876 have_zsk = have_pzsk = ISC_TRUE;
05877 } else {
05878 if (KSK(keys[i]))
05879 have_ksk = ISC_TRUE;
05880 else
05881 have_zsk = ISC_TRUE;
05882 }
05883 }
05884
05885 if (have_zsk && have_ksk && !have_pzsk)
05886 *warn = ISC_TRUE;
05887
05888
05889
05890
05891
05892 if (have_pksk || have_pzsk)
05893 return (ISC_TRUE);
05894
05895
05896
05897
05898
05899 for (i = 0; i < nkeys; i++) {
05900 if ((rrsig_ptr->algorithm == dst_key_alg(keys[i])) &&
05901 (rrsig_ptr->keyid == dst_key_id(keys[i])))
05902 return (ISC_FALSE);
05903 }
05904
05905
05906
05907
05908 return (ISC_TRUE);
05909 }
05910
05911
05912
05913
05914
05915 static isc_result_t
05916 del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
05917 dns_rdatatype_t type, zonediff_t *zonediff, dst_key_t **keys,
05918 unsigned int nkeys, isc_stdtime_t now, isc_boolean_t incremental)
05919 {
05920 isc_result_t result;
05921 dns_dbnode_t *node = NULL;
05922 dns_rdataset_t rdataset;
05923 unsigned int i;
05924 dns_rdata_rrsig_t rrsig;
05925 isc_boolean_t found;
05926 isc_int64_t timewarn = 0, timemaybe = 0;
05927
05928 dns_rdataset_init(&rdataset);
05929
05930 if (type == dns_rdatatype_nsec3)
05931 result = dns_db_findnsec3node(db, name, ISC_FALSE, &node);
05932 else
05933 result = dns_db_findnode(db, name, ISC_FALSE, &node);
05934 if (result == ISC_R_NOTFOUND)
05935 return (ISC_R_SUCCESS);
05936 if (result != ISC_R_SUCCESS)
05937 goto failure;
05938 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_rrsig, type,
05939 (isc_stdtime_t) 0, &rdataset, NULL);
05940 dns_db_detachnode(db, &node);
05941
05942 if (result == ISC_R_NOTFOUND) {
05943 INSIST(!dns_rdataset_isassociated(&rdataset));
05944 return (ISC_R_SUCCESS);
05945 }
05946 if (result != ISC_R_SUCCESS) {
05947 INSIST(!dns_rdataset_isassociated(&rdataset));
05948 goto failure;
05949 }
05950
05951 for (result = dns_rdataset_first(&rdataset);
05952 result == ISC_R_SUCCESS;
05953 result = dns_rdataset_next(&rdataset)) {
05954 dns_rdata_t rdata = DNS_RDATA_INIT;
05955
05956 dns_rdataset_current(&rdataset, &rdata);
05957 result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
05958 RUNTIME_CHECK(result == ISC_R_SUCCESS);
05959
05960 if (type != dns_rdatatype_dnskey) {
05961 isc_boolean_t warn = ISC_FALSE, deleted = ISC_FALSE;
05962 if (delsig_ok(&rrsig, keys, nkeys, &warn)) {
05963 result = update_one_rr(db, ver, zonediff->diff,
05964 DNS_DIFFOP_DELRESIGN, name,
05965 rdataset.ttl, &rdata);
05966 if (result != ISC_R_SUCCESS)
05967 break;
05968 deleted = ISC_TRUE;
05969 }
05970 if (warn) {
05971
05972
05973
05974
05975
05976
05977
05978
05979
05980 if (incremental && !deleted) {
05981 result = offline(db, ver, zonediff,
05982 name, rdataset.ttl,
05983 &rdata);
05984 if (result != ISC_R_SUCCESS)
05985 break;
05986 }
05987
05988
05989
05990
05991
05992 if (zone->log_key_expired_timer <= now) {
05993 char origin[DNS_NAME_FORMATSIZE];
05994 char algbuf[DNS_NAME_FORMATSIZE];
05995 dns_name_format(&zone->origin, origin,
05996 sizeof(origin));
05997 dns_secalg_format(rrsig.algorithm,
05998 algbuf,
05999 sizeof(algbuf));
06000 dns_zone_log(zone, ISC_LOG_WARNING,
06001 "Key %s/%s/%d "
06002 "missing or inactive "
06003 "and has no replacement: "
06004 "retaining signatures.",
06005 origin, algbuf,
06006 rrsig.keyid);
06007 zone->log_key_expired_timer = now +
06008 3600;
06009 }
06010 }
06011 continue;
06012 }
06013
06014
06015
06016
06017 found = ISC_FALSE;
06018 for (i = 0; i < nkeys; i++) {
06019 if (rrsig.algorithm == dst_key_alg(keys[i]) &&
06020 rrsig.keyid == dst_key_id(keys[i])) {
06021 found = ISC_TRUE;
06022
06023
06024
06025
06026
06027 if (!dst_key_inactive(keys[i]) &&
06028 !dst_key_isprivate(keys[i]))
06029 {
06030 isc_int64_t timeexpire =
06031 dns_time64_from32(rrsig.timeexpire);
06032 if (timewarn != 0 &&
06033 timewarn > timeexpire)
06034 timewarn = timeexpire;
06035 if (rdata.flags & DNS_RDATA_OFFLINE) {
06036 if (timemaybe == 0 ||
06037 timemaybe > timeexpire)
06038 timemaybe = timeexpire;
06039 break;
06040 }
06041 if (timewarn == 0)
06042 timewarn = timemaybe;
06043 if (timewarn == 0 ||
06044 timewarn > timeexpire)
06045 timewarn = timeexpire;
06046 result = offline(db, ver, zonediff,
06047 name, rdataset.ttl,
06048 &rdata);
06049 break;
06050 }
06051 result = update_one_rr(db, ver, zonediff->diff,
06052 DNS_DIFFOP_DELRESIGN,
06053 name, rdataset.ttl,
06054 &rdata);
06055 break;
06056 }
06057 }
06058
06059
06060
06061
06062
06063 if (!found)
06064 result = update_one_rr(db, ver, zonediff->diff,
06065 DNS_DIFFOP_DELRESIGN, name,
06066 rdataset.ttl, &rdata);
06067 if (result != ISC_R_SUCCESS)
06068 break;
06069 }
06070
06071 dns_rdataset_disassociate(&rdataset);
06072 if (result == ISC_R_NOMORE)
06073 result = ISC_R_SUCCESS;
06074 if (timewarn > 0) {
06075 #if defined(STDTIME_ON_32BITS)
06076 isc_stdtime_t stdwarn = (isc_stdtime_t)timewarn;
06077 if (timewarn == stdwarn)
06078 #endif
06079 set_key_expiry_warning(zone, (isc_stdtime_t)timewarn,
06080 now);
06081 #if defined(STDTIME_ON_32BITS)
06082 else
06083 dns_zone_log(zone, ISC_LOG_ERROR,
06084 "key expiry warning time out of range");
06085 #endif
06086 }
06087 failure:
06088 if (node != NULL)
06089 dns_db_detachnode(db, &node);
06090 return (result);
06091 }
06092
06093 static isc_result_t
06094 add_sigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
06095 dns_rdatatype_t type, dns_diff_t *diff, dst_key_t **keys,
06096 unsigned int nkeys, isc_mem_t *mctx, isc_stdtime_t inception,
06097 isc_stdtime_t expire, isc_boolean_t check_ksk,
06098 isc_boolean_t keyset_kskonly)
06099 {
06100 isc_result_t result;
06101 dns_dbnode_t *node = NULL;
06102 dns_rdataset_t rdataset;
06103 dns_rdata_t sig_rdata = DNS_RDATA_INIT;
06104 unsigned char data[1024];
06105 isc_buffer_t buffer;
06106 unsigned int i, j;
06107
06108 dns_rdataset_init(&rdataset);
06109 isc_buffer_init(&buffer, data, sizeof(data));
06110
06111 if (type == dns_rdatatype_nsec3)
06112 result = dns_db_findnsec3node(db, name, ISC_FALSE, &node);
06113 else
06114 result = dns_db_findnode(db, name, ISC_FALSE, &node);
06115 if (result == ISC_R_NOTFOUND)
06116 return (ISC_R_SUCCESS);
06117 if (result != ISC_R_SUCCESS)
06118 goto failure;
06119 result = dns_db_findrdataset(db, node, ver, type, 0,
06120 (isc_stdtime_t) 0, &rdataset, NULL);
06121 dns_db_detachnode(db, &node);
06122 if (result == ISC_R_NOTFOUND) {
06123 INSIST(!dns_rdataset_isassociated(&rdataset));
06124 return (ISC_R_SUCCESS);
06125 }
06126 if (result != ISC_R_SUCCESS) {
06127 INSIST(!dns_rdataset_isassociated(&rdataset));
06128 goto failure;
06129 }
06130
06131 for (i = 0; i < nkeys; i++) {
06132 isc_boolean_t both = ISC_FALSE;
06133
06134 if (!dst_key_isprivate(keys[i]))
06135 continue;
06136
06137 if (check_ksk && !REVOKE(keys[i])) {
06138 isc_boolean_t have_ksk, have_nonksk;
06139 if (KSK(keys[i])) {
06140 have_ksk = ISC_TRUE;
06141 have_nonksk = ISC_FALSE;
06142 } else {
06143 have_ksk = ISC_FALSE;
06144 have_nonksk = ISC_TRUE;
06145 }
06146 for (j = 0; j < nkeys; j++) {
06147 if (j == i || ALG(keys[i]) != ALG(keys[j]))
06148 continue;
06149 if (REVOKE(keys[j]))
06150 continue;
06151 if (KSK(keys[j]))
06152 have_ksk = ISC_TRUE;
06153 else
06154 have_nonksk = ISC_TRUE;
06155 both = have_ksk && have_nonksk;
06156 if (both)
06157 break;
06158 }
06159 }
06160 if (both) {
06161 if (type == dns_rdatatype_dnskey) {
06162 if (!KSK(keys[i]) && keyset_kskonly)
06163 continue;
06164 } else if (KSK(keys[i]))
06165 continue;
06166 } else if (REVOKE(keys[i]) && type != dns_rdatatype_dnskey)
06167 continue;
06168
06169
06170 isc_buffer_clear(&buffer);
06171 CHECK(dns_dnssec_sign(name, &rdataset, keys[i],
06172 &inception, &expire,
06173 mctx, &buffer, &sig_rdata));
06174
06175
06176 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADDRESIGN,
06177 name, rdataset.ttl, &sig_rdata));
06178 dns_rdata_reset(&sig_rdata);
06179 isc_buffer_init(&buffer, data, sizeof(data));
06180 }
06181
06182 failure:
06183 if (dns_rdataset_isassociated(&rdataset))
06184 dns_rdataset_disassociate(&rdataset);
06185 if (node != NULL)
06186 dns_db_detachnode(db, &node);
06187 return (result);
06188 }
06189
06190 static void
06191 zone_resigninc(dns_zone_t *zone) {
06192 const char *me = "zone_resigninc";
06193 dns_db_t *db = NULL;
06194 dns_dbversion_t *version = NULL;
06195 dns_diff_t _sig_diff;
06196 zonediff_t zonediff;
06197 dns_fixedname_t fixed;
06198 dns_name_t *name;
06199 dns_rdataset_t rdataset;
06200 dns_rdatatype_t covers;
06201 dst_key_t *zone_keys[DNS_MAXZONEKEYS];
06202 isc_boolean_t check_ksk, keyset_kskonly = ISC_FALSE;
06203 isc_result_t result;
06204 isc_stdtime_t now, inception, soaexpire, expire, stop;
06205 isc_uint32_t jitter;
06206 unsigned int i;
06207 unsigned int nkeys = 0;
06208 unsigned int resign;
06209
06210 ENTER;
06211
06212 dns_rdataset_init(&rdataset);
06213 dns_fixedname_init(&fixed);
06214 dns_diff_init(zone->mctx, &_sig_diff);
06215 zonediff_init(&zonediff, &_sig_diff);
06216
06217
06218
06219
06220
06221 if (zone->update_disabled ||
06222 DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_NORESIGN))
06223 {
06224 result = ISC_R_FAILURE;
06225 goto failure;
06226 }
06227
06228 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
06229 dns_db_attach(zone->db, &db);
06230 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
06231
06232 result = dns_db_newversion(db, &version);
06233 if (result != ISC_R_SUCCESS) {
06234 dns_zone_log(zone, ISC_LOG_ERROR,
06235 "zone_resigninc:dns_db_newversion -> %s",
06236 dns_result_totext(result));
06237 goto failure;
06238 }
06239
06240 result = find_zone_keys(zone, db, version, zone->mctx, DNS_MAXZONEKEYS,
06241 zone_keys, &nkeys);
06242 if (result != ISC_R_SUCCESS) {
06243 dns_zone_log(zone, ISC_LOG_ERROR,
06244 "zone_resigninc:find_zone_keys -> %s",
06245 dns_result_totext(result));
06246 goto failure;
06247 }
06248
06249 isc_stdtime_get(&now);
06250 inception = now - 3600;
06251 soaexpire = now + dns_zone_getsigvalidityinterval(zone);
06252
06253
06254
06255
06256
06257 isc_random_get(&jitter);
06258 expire = soaexpire - jitter % 3600;
06259 stop = now + 5;
06260
06261 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
06262 keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
06263
06264 name = dns_fixedname_name(&fixed);
06265 result = dns_db_getsigningtime(db, &rdataset, name);
06266 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
06267 dns_zone_log(zone, ISC_LOG_ERROR,
06268 "zone_resigninc:dns_db_getsigningtime -> %s",
06269 dns_result_totext(result));
06270 }
06271
06272 i = 0;
06273 while (result == ISC_R_SUCCESS) {
06274 resign = rdataset.resign - zone->sigresigninginterval;
06275 covers = rdataset.covers;
06276 dns_rdataset_disassociate(&rdataset);
06277
06278
06279
06280
06281
06282
06283
06284 if (covers == dns_rdatatype_soa || i++ > zone->signatures ||
06285 resign > stop)
06286 break;
06287
06288 result = del_sigs(zone, db, version, name, covers, &zonediff,
06289 zone_keys, nkeys, now, ISC_TRUE);
06290 if (result != ISC_R_SUCCESS) {
06291 dns_zone_log(zone, ISC_LOG_ERROR,
06292 "zone_resigninc:del_sigs -> %s",
06293 dns_result_totext(result));
06294 break;
06295 }
06296
06297 result = add_sigs(db, version, name, covers, zonediff.diff,
06298 zone_keys, nkeys, zone->mctx, inception,
06299 expire, check_ksk, keyset_kskonly);
06300 if (result != ISC_R_SUCCESS) {
06301 dns_zone_log(zone, ISC_LOG_ERROR,
06302 "zone_resigninc:add_sigs -> %s",
06303 dns_result_totext(result));
06304 break;
06305 }
06306 result = dns_db_getsigningtime(db, &rdataset, name);
06307 if (nkeys == 0 && result == ISC_R_NOTFOUND) {
06308 result = ISC_R_SUCCESS;
06309 break;
06310 }
06311 if (result != ISC_R_SUCCESS)
06312 dns_zone_log(zone, ISC_LOG_ERROR,
06313 "zone_resigninc:dns_db_getsigningtime -> %s",
06314 dns_result_totext(result));
06315 }
06316
06317 if (result != ISC_R_NOMORE && result != ISC_R_SUCCESS)
06318 goto failure;
06319
06320 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
06321 &zonediff, zone_keys, nkeys, now, ISC_TRUE);
06322 if (result != ISC_R_SUCCESS) {
06323 dns_zone_log(zone, ISC_LOG_ERROR,
06324 "zone_resigninc:del_sigs -> %s",
06325 dns_result_totext(result));
06326 goto failure;
06327 }
06328
06329
06330
06331
06332 if (ISC_LIST_EMPTY(zonediff.diff->tuples)) {
06333
06334
06335 if (zonediff.offline)
06336 dns_db_closeversion(db, &version, ISC_TRUE);
06337 goto failure;
06338 }
06339
06340
06341 result = update_soa_serial(db, version, zonediff.diff, zone->mctx,
06342 zone->updatemethod);
06343 if (result != ISC_R_SUCCESS) {
06344 dns_zone_log(zone, ISC_LOG_ERROR,
06345 "zone_resigninc:update_soa_serial -> %s",
06346 dns_result_totext(result));
06347 goto failure;
06348 }
06349
06350
06351
06352
06353
06354 result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa,
06355 zonediff.diff, zone_keys, nkeys, zone->mctx,
06356 inception, soaexpire, check_ksk, keyset_kskonly);
06357 if (result != ISC_R_SUCCESS) {
06358 dns_zone_log(zone, ISC_LOG_ERROR,
06359 "zone_resigninc:add_sigs -> %s",
06360 dns_result_totext(result));
06361 goto failure;
06362 }
06363
06364
06365 CHECK(zone_journal(zone, zonediff.diff, NULL, "zone_resigninc"));
06366
06367
06368 dns_db_closeversion(db, &version, ISC_TRUE);
06369
06370 failure:
06371 dns_diff_clear(&_sig_diff);
06372 for (i = 0; i < nkeys; i++)
06373 dst_key_free(&zone_keys[i]);
06374 if (version != NULL) {
06375 dns_db_closeversion(zone->db, &version, ISC_FALSE);
06376 dns_db_detach(&db);
06377 } else if (db != NULL)
06378 dns_db_detach(&db);
06379 if (result == ISC_R_SUCCESS) {
06380 set_resigntime(zone);
06381 LOCK_ZONE(zone);
06382 zone_needdump(zone, DNS_DUMP_DELAY);
06383 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
06384 UNLOCK_ZONE(zone);
06385 } else {
06386
06387
06388
06389 isc_interval_t ival;
06390 isc_interval_set(&ival, 300, 0);
06391 isc_time_nowplusinterval(&zone->resigntime, &ival);
06392 }
06393
06394 INSIST(version == NULL);
06395 }
06396
06397 static isc_result_t
06398 next_active(dns_db_t *db, dns_dbversion_t *version, dns_name_t *oldname,
06399 dns_name_t *newname, isc_boolean_t bottom)
06400 {
06401 isc_result_t result;
06402 dns_dbiterator_t *dbit = NULL;
06403 dns_rdatasetiter_t *rdsit = NULL;
06404 dns_dbnode_t *node = NULL;
06405
06406 CHECK(dns_db_createiterator(db, DNS_DB_NONSEC3, &dbit));
06407 CHECK(dns_dbiterator_seek(dbit, oldname));
06408 do {
06409 result = dns_dbiterator_next(dbit);
06410 if (result == ISC_R_NOMORE)
06411 CHECK(dns_dbiterator_first(dbit));
06412 CHECK(dns_dbiterator_current(dbit, &node, newname));
06413 if (bottom && dns_name_issubdomain(newname, oldname) &&
06414 !dns_name_equal(newname, oldname)) {
06415 dns_db_detachnode(db, &node);
06416 continue;
06417 }
06418
06419
06420
06421 CHECK(dns_db_allrdatasets(db, node, version, 0, &rdsit));
06422 result = dns_rdatasetiter_first(rdsit);
06423 dns_db_detachnode(db, &node);
06424 dns_rdatasetiter_destroy(&rdsit);
06425 if (result != ISC_R_NOMORE)
06426 break;
06427 } while (1);
06428 failure:
06429 if (node != NULL)
06430 dns_db_detachnode(db, &node);
06431 if (dbit != NULL)
06432 dns_dbiterator_destroy(&dbit);
06433 return (result);
06434 }
06435
06436 static isc_boolean_t
06437 signed_with_key(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
06438 dns_rdatatype_t type, dst_key_t *key)
06439 {
06440 isc_result_t result;
06441 dns_rdataset_t rdataset;
06442 dns_rdata_t rdata = DNS_RDATA_INIT;
06443 dns_rdata_rrsig_t rrsig;
06444
06445 dns_rdataset_init(&rdataset);
06446 result = dns_db_findrdataset(db, node, version, dns_rdatatype_rrsig,
06447 type, 0, &rdataset, NULL);
06448 if (result != ISC_R_SUCCESS) {
06449 INSIST(!dns_rdataset_isassociated(&rdataset));
06450 return (ISC_FALSE);
06451 }
06452 for (result = dns_rdataset_first(&rdataset);
06453 result == ISC_R_SUCCESS;
06454 result = dns_rdataset_next(&rdataset)) {
06455 dns_rdataset_current(&rdataset, &rdata);
06456 result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
06457 INSIST(result == ISC_R_SUCCESS);
06458 if (rrsig.algorithm == dst_key_alg(key) &&
06459 rrsig.keyid == dst_key_id(key)) {
06460 dns_rdataset_disassociate(&rdataset);
06461 return (ISC_TRUE);
06462 }
06463 dns_rdata_reset(&rdata);
06464 }
06465 dns_rdataset_disassociate(&rdataset);
06466 return (ISC_FALSE);
06467 }
06468
06469 static isc_result_t
06470 add_nsec(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
06471 dns_dbnode_t *node, dns_ttl_t ttl, isc_boolean_t bottom,
06472 dns_diff_t *diff)
06473 {
06474 dns_fixedname_t fixed;
06475 dns_name_t *next;
06476 dns_rdata_t rdata = DNS_RDATA_INIT;
06477 isc_result_t result;
06478 unsigned char nsecbuffer[DNS_NSEC_BUFFERSIZE];
06479
06480 dns_fixedname_init(&fixed);
06481 next = dns_fixedname_name(&fixed);
06482
06483 CHECK(next_active(db, version, name, next, bottom));
06484 CHECK(dns_nsec_buildrdata(db, version, node, next, nsecbuffer,
06485 &rdata));
06486 CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADD, name, ttl,
06487 &rdata));
06488 failure:
06489 return (result);
06490 }
06491
06492 static isc_result_t
06493 sign_a_node(dns_db_t *db, dns_name_t *name, dns_dbnode_t *node,
06494 dns_dbversion_t *version, isc_boolean_t build_nsec3,
06495 isc_boolean_t build_nsec, dst_key_t *key,
06496 isc_stdtime_t inception, isc_stdtime_t expire,
06497 unsigned int minimum, isc_boolean_t is_ksk,
06498 isc_boolean_t keyset_kskonly, isc_boolean_t *delegation,
06499 dns_diff_t *diff, isc_int32_t *signatures, isc_mem_t *mctx)
06500 {
06501 isc_result_t result;
06502 dns_rdatasetiter_t *iterator = NULL;
06503 dns_rdataset_t rdataset;
06504 dns_rdata_t rdata = DNS_RDATA_INIT;
06505 isc_buffer_t buffer;
06506 unsigned char data[1024];
06507 isc_boolean_t seen_soa, seen_ns, seen_rr, seen_dname, seen_nsec,
06508 seen_nsec3, seen_ds;
06509 isc_boolean_t bottom;
06510
06511 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
06512 if (result != ISC_R_SUCCESS) {
06513 if (result == ISC_R_NOTFOUND)
06514 result = ISC_R_SUCCESS;
06515 return (result);
06516 }
06517
06518 dns_rdataset_init(&rdataset);
06519 isc_buffer_init(&buffer, data, sizeof(data));
06520 seen_rr = seen_soa = seen_ns = seen_dname = seen_nsec =
06521 seen_nsec3 = seen_ds = ISC_FALSE;
06522 for (result = dns_rdatasetiter_first(iterator);
06523 result == ISC_R_SUCCESS;
06524 result = dns_rdatasetiter_next(iterator)) {
06525 dns_rdatasetiter_current(iterator, &rdataset);
06526 if (rdataset.type == dns_rdatatype_soa)
06527 seen_soa = ISC_TRUE;
06528 else if (rdataset.type == dns_rdatatype_ns)
06529 seen_ns = ISC_TRUE;
06530 else if (rdataset.type == dns_rdatatype_ds)
06531 seen_ds = ISC_TRUE;
06532 else if (rdataset.type == dns_rdatatype_dname)
06533 seen_dname = ISC_TRUE;
06534 else if (rdataset.type == dns_rdatatype_nsec)
06535 seen_nsec = ISC_TRUE;
06536 else if (rdataset.type == dns_rdatatype_nsec3)
06537 seen_nsec3 = ISC_TRUE;
06538 if (rdataset.type != dns_rdatatype_rrsig)
06539 seen_rr = ISC_TRUE;
06540 dns_rdataset_disassociate(&rdataset);
06541 }
06542 if (result != ISC_R_NOMORE)
06543 goto failure;
06544 if (seen_ns && !seen_soa)
06545 *delegation = ISC_TRUE;
06546
06547
06548
06549
06550 if (build_nsec3 && !seen_nsec3 && seen_rr) {
06551 isc_boolean_t unsecure = !seen_ds && seen_ns && !seen_soa;
06552 CHECK(dns_nsec3_addnsec3s(db, version, name, minimum,
06553 unsecure, diff));
06554 (*signatures)--;
06555 }
06556
06557
06558
06559
06560 if (build_nsec && !seen_nsec3 && !seen_nsec && seen_rr) {
06561
06562 bottom = (seen_ns && !seen_soa) || seen_dname;
06563
06564
06565
06566 if (!dns_name_equal(name, dns_db_origin(db))) {
06567 CHECK(add_nsec(db, version, name, node, minimum,
06568 bottom, diff));
06569
06570 (*signatures)--;
06571 }
06572 }
06573 result = dns_rdatasetiter_first(iterator);
06574 while (result == ISC_R_SUCCESS) {
06575 dns_rdatasetiter_current(iterator, &rdataset);
06576 if (rdataset.type == dns_rdatatype_soa ||
06577 rdataset.type == dns_rdatatype_rrsig)
06578 goto next_rdataset;
06579 if (rdataset.type == dns_rdatatype_dnskey) {
06580 if (!is_ksk && keyset_kskonly)
06581 goto next_rdataset;
06582 } else if (is_ksk)
06583 goto next_rdataset;
06584 if (*delegation &&
06585 rdataset.type != dns_rdatatype_ds &&
06586 rdataset.type != dns_rdatatype_nsec)
06587 goto next_rdataset;
06588 if (signed_with_key(db, node, version, rdataset.type, key))
06589 goto next_rdataset;
06590
06591 isc_buffer_clear(&buffer);
06592 CHECK(dns_dnssec_sign(name, &rdataset, key, &inception,
06593 &expire, mctx, &buffer, &rdata));
06594
06595
06596 CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADDRESIGN,
06597 name, rdataset.ttl, &rdata));
06598 dns_rdata_reset(&rdata);
06599 (*signatures)--;
06600 next_rdataset:
06601 dns_rdataset_disassociate(&rdataset);
06602 result = dns_rdatasetiter_next(iterator);
06603 }
06604 if (result == ISC_R_NOMORE)
06605 result = ISC_R_SUCCESS;
06606 if (seen_dname)
06607 *delegation = ISC_TRUE;
06608 failure:
06609 if (dns_rdataset_isassociated(&rdataset))
06610 dns_rdataset_disassociate(&rdataset);
06611 if (iterator != NULL)
06612 dns_rdatasetiter_destroy(&iterator);
06613 return (result);
06614 }
06615
06616
06617
06618
06619 static isc_result_t
06620 updatesecure(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
06621 dns_ttl_t minimum, isc_boolean_t update_only, dns_diff_t *diff)
06622 {
06623 isc_result_t result;
06624 dns_rdataset_t rdataset;
06625 dns_dbnode_t *node = NULL;
06626
06627 CHECK(dns_db_getoriginnode(db, &node));
06628 if (update_only) {
06629 dns_rdataset_init(&rdataset);
06630 result = dns_db_findrdataset(db, node, version,
06631 dns_rdatatype_nsec,
06632 dns_rdatatype_none,
06633 0, &rdataset, NULL);
06634 if (dns_rdataset_isassociated(&rdataset))
06635 dns_rdataset_disassociate(&rdataset);
06636 if (result == ISC_R_NOTFOUND)
06637 goto success;
06638 if (result != ISC_R_SUCCESS)
06639 goto failure;
06640 }
06641 CHECK(delete_nsec(db, version, node, name, diff));
06642 CHECK(add_nsec(db, version, name, node, minimum, ISC_FALSE, diff));
06643 success:
06644 result = ISC_R_SUCCESS;
06645 failure:
06646 if (node != NULL)
06647 dns_db_detachnode(db, &node);
06648 return (result);
06649 }
06650
06651 static isc_result_t
06652 updatesignwithkey(dns_zone_t *zone, dns_signing_t *signing,
06653 dns_dbversion_t *version, isc_boolean_t build_nsec3,
06654 dns_ttl_t minimum, dns_diff_t *diff)
06655 {
06656 isc_result_t result;
06657 dns_dbnode_t *node = NULL;
06658 dns_rdataset_t rdataset;
06659 dns_rdata_t rdata = DNS_RDATA_INIT;
06660 unsigned char data[5];
06661 isc_boolean_t seen_done = ISC_FALSE;
06662 isc_boolean_t have_rr = ISC_FALSE;
06663
06664 dns_rdataset_init(&rdataset);
06665 result = dns_db_getoriginnode(signing->db, &node);
06666 if (result != ISC_R_SUCCESS)
06667 goto failure;
06668
06669 result = dns_db_findrdataset(signing->db, node, version,
06670 zone->privatetype, dns_rdatatype_none,
06671 0, &rdataset, NULL);
06672 if (result == ISC_R_NOTFOUND) {
06673 INSIST(!dns_rdataset_isassociated(&rdataset));
06674 result = ISC_R_SUCCESS;
06675 goto failure;
06676 }
06677 if (result != ISC_R_SUCCESS) {
06678 INSIST(!dns_rdataset_isassociated(&rdataset));
06679 goto failure;
06680 }
06681 for (result = dns_rdataset_first(&rdataset);
06682 result == ISC_R_SUCCESS;
06683 result = dns_rdataset_next(&rdataset)) {
06684 dns_rdataset_current(&rdataset, &rdata);
06685
06686
06687
06688 if (rdata.length != 5 ||
06689 rdata.data[0] != signing->algorithm ||
06690 rdata.data[1] != ((signing->keyid >> 8) & 0xff) ||
06691 rdata.data[2] != (signing->keyid & 0xff)) {
06692 have_rr = ISC_TRUE;
06693 dns_rdata_reset(&rdata);
06694 continue;
06695 }
06696
06697
06698
06699
06700
06701
06702
06703
06704
06705
06706
06707 if (!signing->delete && rdata.data[4] != 0) {
06708 seen_done = ISC_TRUE;
06709 have_rr = ISC_TRUE;
06710 } else
06711 CHECK(update_one_rr(signing->db, version, diff,
06712 DNS_DIFFOP_DEL, &zone->origin,
06713 rdataset.ttl, &rdata));
06714 dns_rdata_reset(&rdata);
06715 }
06716 if (result == ISC_R_NOMORE)
06717 result = ISC_R_SUCCESS;
06718 if (!signing->delete && !seen_done) {
06719
06720
06721
06722
06723
06724 data[0] = signing->algorithm;
06725 data[1] = (signing->keyid >> 8) & 0xff;
06726 data[2] = signing->keyid & 0xff;
06727 data[3] = 0;
06728 data[4] = 1;
06729 rdata.length = sizeof(data);
06730 rdata.data = data;
06731 rdata.type = zone->privatetype;
06732 rdata.rdclass = dns_db_class(signing->db);
06733 CHECK(update_one_rr(signing->db, version, diff, DNS_DIFFOP_ADD,
06734 &zone->origin, rdataset.ttl, &rdata));
06735 } else if (!have_rr) {
06736 dns_name_t *origin = dns_db_origin(signing->db);
06737
06738
06739
06740
06741 if (build_nsec3)
06742 CHECK(dns_nsec3_addnsec3s(signing->db, version, origin,
06743 minimum, ISC_FALSE, diff));
06744 CHECK(updatesecure(signing->db, version, origin, minimum,
06745 ISC_TRUE, diff));
06746 }
06747
06748 failure:
06749 if (dns_rdataset_isassociated(&rdataset))
06750 dns_rdataset_disassociate(&rdataset);
06751 if (node != NULL)
06752 dns_db_detachnode(signing->db, &node);
06753 return (result);
06754 }
06755
06756
06757
06758
06759
06760
06761 static isc_result_t
06762 fixup_nsec3param(dns_db_t *db, dns_dbversion_t *ver, dns_nsec3chain_t *chain,
06763 isc_boolean_t active, dns_rdatatype_t privatetype,
06764 dns_diff_t *diff)
06765 {
06766 dns_dbnode_t *node = NULL;
06767 dns_name_t *name = dns_db_origin(db);
06768 dns_rdata_t rdata = DNS_RDATA_INIT;
06769 dns_rdataset_t rdataset;
06770 dns_rdata_nsec3param_t nsec3param;
06771 isc_result_t result;
06772 isc_buffer_t buffer;
06773 unsigned char parambuf[DNS_NSEC3PARAM_BUFFERSIZE];
06774 dns_ttl_t ttl = 0;
06775 isc_boolean_t nseconly = ISC_FALSE, nsec3ok = ISC_FALSE;
06776
06777 dns_rdataset_init(&rdataset);
06778
06779 result = dns_db_getoriginnode(db, &node);
06780 RUNTIME_CHECK(result == ISC_R_SUCCESS);
06781 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param,
06782 0, 0, &rdataset, NULL);
06783 if (result == ISC_R_NOTFOUND)
06784 goto try_private;
06785 if (result != ISC_R_SUCCESS)
06786 goto failure;
06787
06788
06789
06790
06791 ttl = rdataset.ttl;
06792
06793
06794
06795
06796 for (result = dns_rdataset_first(&rdataset);
06797 result == ISC_R_SUCCESS;
06798 result = dns_rdataset_next(&rdataset)) {
06799
06800 dns_rdataset_current(&rdataset, &rdata);
06801 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
06802
06803 if (nsec3param.hash != chain->nsec3param.hash ||
06804 (active && nsec3param.flags != 0) ||
06805 nsec3param.iterations != chain->nsec3param.iterations ||
06806 nsec3param.salt_length != chain->nsec3param.salt_length ||
06807 memcmp(nsec3param.salt, chain->nsec3param.salt,
06808 nsec3param.salt_length)) {
06809 dns_rdata_reset(&rdata);
06810 continue;
06811 }
06812
06813 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL,
06814 name, rdataset.ttl, &rdata));
06815 dns_rdata_reset(&rdata);
06816 }
06817 if (result != ISC_R_NOMORE)
06818 goto failure;
06819
06820 dns_rdataset_disassociate(&rdataset);
06821
06822 try_private:
06823
06824 if (active)
06825 goto add;
06826
06827 result = dns_nsec_nseconly(db, ver, &nseconly);
06828 nsec3ok = (result == ISC_R_SUCCESS && !nseconly);
06829
06830
06831
06832
06833 result = dns_db_findrdataset(db, node, ver, privatetype,
06834 0, 0, &rdataset, NULL);
06835 if (result == ISC_R_NOTFOUND)
06836 goto add;
06837 if (result != ISC_R_SUCCESS)
06838 goto failure;
06839
06840 for (result = dns_rdataset_first(&rdataset);
06841 result == ISC_R_SUCCESS;
06842 result = dns_rdataset_next(&rdataset)) {
06843 dns_rdata_t private = DNS_RDATA_INIT;
06844 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
06845
06846 dns_rdataset_current(&rdataset, &private);
06847 if (!dns_nsec3param_fromprivate(&private, &rdata,
06848 buf, sizeof(buf)))
06849 continue;
06850 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
06851
06852 if ((!nsec3ok &&
06853 (nsec3param.flags & DNS_NSEC3FLAG_INITIAL) != 0) ||
06854 nsec3param.hash != chain->nsec3param.hash ||
06855 nsec3param.iterations != chain->nsec3param.iterations ||
06856 nsec3param.salt_length != chain->nsec3param.salt_length ||
06857 memcmp(nsec3param.salt, chain->nsec3param.salt,
06858 nsec3param.salt_length)) {
06859 dns_rdata_reset(&rdata);
06860 continue;
06861 }
06862
06863 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL,
06864 name, rdataset.ttl, &private));
06865 dns_rdata_reset(&rdata);
06866 }
06867 if (result != ISC_R_NOMORE)
06868 goto failure;
06869
06870 add:
06871 if ((chain->nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) {
06872 result = ISC_R_SUCCESS;
06873 goto failure;
06874 }
06875
06876
06877
06878
06879
06880
06881
06882
06883 isc_buffer_init(&buffer, ¶mbuf, sizeof(parambuf));
06884 CHECK(dns_rdata_fromstruct(&rdata, dns_db_class(db),
06885 dns_rdatatype_nsec3param,
06886 &chain->nsec3param, &buffer));
06887 rdata.data[1] = 0;
06888 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD, name, ttl, &rdata));
06889
06890 failure:
06891 dns_db_detachnode(db, &node);
06892 if (dns_rdataset_isassociated(&rdataset))
06893 dns_rdataset_disassociate(&rdataset);
06894 return (result);
06895 }
06896
06897 static isc_result_t
06898 delete_nsec(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node,
06899 dns_name_t *name, dns_diff_t *diff)
06900 {
06901 dns_rdataset_t rdataset;
06902 isc_result_t result;
06903
06904 dns_rdataset_init(&rdataset);
06905
06906 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec,
06907 0, 0, &rdataset, NULL);
06908 if (result == ISC_R_NOTFOUND)
06909 return (ISC_R_SUCCESS);
06910 if (result != ISC_R_SUCCESS)
06911 return (result);
06912 for (result = dns_rdataset_first(&rdataset);
06913 result == ISC_R_SUCCESS;
06914 result = dns_rdataset_next(&rdataset)) {
06915 dns_rdata_t rdata = DNS_RDATA_INIT;
06916
06917 dns_rdataset_current(&rdataset, &rdata);
06918 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name,
06919 rdataset.ttl, &rdata));
06920 }
06921 if (result == ISC_R_NOMORE)
06922 result = ISC_R_SUCCESS;
06923 failure:
06924 dns_rdataset_disassociate(&rdataset);
06925 return (result);
06926 }
06927
06928 static isc_result_t
06929 deletematchingnsec3(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node,
06930 dns_name_t *name, const dns_rdata_nsec3param_t *param,
06931 dns_diff_t *diff)
06932 {
06933 dns_rdataset_t rdataset;
06934 dns_rdata_nsec3_t nsec3;
06935 isc_result_t result;
06936
06937 dns_rdataset_init(&rdataset);
06938 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3,
06939 0, 0, &rdataset, NULL);
06940 if (result == ISC_R_NOTFOUND)
06941 return (ISC_R_SUCCESS);
06942 if (result != ISC_R_SUCCESS)
06943 return (result);
06944
06945 for (result = dns_rdataset_first(&rdataset);
06946 result == ISC_R_SUCCESS;
06947 result = dns_rdataset_next(&rdataset)) {
06948 dns_rdata_t rdata = DNS_RDATA_INIT;
06949
06950 dns_rdataset_current(&rdataset, &rdata);
06951 CHECK(dns_rdata_tostruct(&rdata, &nsec3, NULL));
06952 if (nsec3.hash != param->hash ||
06953 nsec3.iterations != param->iterations ||
06954 nsec3.salt_length != param->salt_length ||
06955 memcmp(nsec3.salt, param->salt, nsec3.salt_length))
06956 continue;
06957 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name,
06958 rdataset.ttl, &rdata));
06959 }
06960 if (result == ISC_R_NOMORE)
06961 result = ISC_R_SUCCESS;
06962 failure:
06963 dns_rdataset_disassociate(&rdataset);
06964 return (result);
06965 }
06966
06967 static isc_result_t
06968 need_nsec_chain(dns_db_t *db, dns_dbversion_t *ver,
06969 const dns_rdata_nsec3param_t *param,
06970 isc_boolean_t *answer)
06971 {
06972 dns_dbnode_t *node = NULL;
06973 dns_rdata_t rdata = DNS_RDATA_INIT;
06974 dns_rdata_nsec3param_t myparam;
06975 dns_rdataset_t rdataset;
06976 isc_result_t result;
06977
06978 *answer = ISC_FALSE;
06979
06980 result = dns_db_getoriginnode(db, &node);
06981 RUNTIME_CHECK(result == ISC_R_SUCCESS);
06982
06983 dns_rdataset_init(&rdataset);
06984
06985 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec,
06986 0, 0, &rdataset, NULL);
06987 if (result == ISC_R_SUCCESS) {
06988 dns_rdataset_disassociate(&rdataset);
06989 dns_db_detachnode(db, &node);
06990 return (result);
06991 }
06992 if (result != ISC_R_NOTFOUND) {
06993 dns_db_detachnode(db, &node);
06994 return (result);
06995 }
06996
06997 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param,
06998 0, 0, &rdataset, NULL);
06999 if (result == ISC_R_NOTFOUND) {
07000 *answer = ISC_TRUE;
07001 dns_db_detachnode(db, &node);
07002 return (ISC_R_SUCCESS);
07003 }
07004 if (result != ISC_R_SUCCESS) {
07005 dns_db_detachnode(db, &node);
07006 return (result);
07007 }
07008
07009 for (result = dns_rdataset_first(&rdataset);
07010 result == ISC_R_SUCCESS;
07011 result = dns_rdataset_next(&rdataset)) {
07012 dns_rdataset_current(&rdataset, &rdata);
07013 CHECK(dns_rdata_tostruct(&rdata, &myparam, NULL));
07014 dns_rdata_reset(&rdata);
07015
07016
07017
07018 if (NSEC3REMOVE(myparam.flags))
07019 continue;
07020
07021
07022
07023 if (myparam.hash == param->hash &&
07024 myparam.iterations == param->iterations &&
07025 myparam.salt_length == param->salt_length &&
07026 !memcmp(myparam.salt, param->salt, myparam.salt_length))
07027 continue;
07028
07029
07030
07031 break;
07032 }
07033 if (result == ISC_R_NOMORE) {
07034 *answer = ISC_TRUE;
07035 result = ISC_R_SUCCESS;
07036 }
07037
07038 failure:
07039 if (dns_rdataset_isassociated(&rdataset))
07040 dns_rdataset_disassociate(&rdataset);
07041 dns_db_detachnode(db, &node);
07042 return (result);
07043 }
07044
07045 static isc_result_t
07046 update_sigs(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *version,
07047 dst_key_t *zone_keys[], unsigned int nkeys, dns_zone_t *zone,
07048 isc_stdtime_t inception, isc_stdtime_t expire, isc_stdtime_t now,
07049 isc_boolean_t check_ksk, isc_boolean_t keyset_kskonly,
07050 zonediff_t *zonediff)
07051 {
07052 dns_difftuple_t *tuple;
07053 isc_result_t result;
07054
07055 for (tuple = ISC_LIST_HEAD(diff->tuples);
07056 tuple != NULL;
07057 tuple = ISC_LIST_HEAD(diff->tuples)) {
07058 result = del_sigs(zone, db, version, &tuple->name,
07059 tuple->rdata.type, zonediff,
07060 zone_keys, nkeys, now, ISC_FALSE);
07061 if (result != ISC_R_SUCCESS) {
07062 dns_zone_log(zone, ISC_LOG_ERROR,
07063 "update_sigs:del_sigs -> %s",
07064 dns_result_totext(result));
07065 return (result);
07066 }
07067 result = add_sigs(db, version, &tuple->name,
07068 tuple->rdata.type, zonediff->diff,
07069 zone_keys, nkeys, zone->mctx, inception,
07070 expire, check_ksk, keyset_kskonly);
07071 if (result != ISC_R_SUCCESS) {
07072 dns_zone_log(zone, ISC_LOG_ERROR,
07073 "update_sigs:add_sigs -> %s",
07074 dns_result_totext(result));
07075 return (result);
07076 }
07077
07078 do {
07079 dns_difftuple_t *next = ISC_LIST_NEXT(tuple, link);
07080 while (next != NULL &&
07081 (tuple->rdata.type != next->rdata.type ||
07082 !dns_name_equal(&tuple->name, &next->name)))
07083 next = ISC_LIST_NEXT(next, link);
07084 ISC_LIST_UNLINK(diff->tuples, tuple, link);
07085 dns_diff_appendminimal(zonediff->diff, &tuple);
07086 INSIST(tuple == NULL);
07087 tuple = next;
07088 } while (tuple != NULL);
07089 }
07090 return (ISC_R_SUCCESS);
07091 }
07092
07093
07094
07095
07096
07097 static void
07098 zone_nsec3chain(dns_zone_t *zone) {
07099 const char *me = "zone_nsec3chain";
07100 dns_db_t *db = NULL;
07101 dns_dbnode_t *node = NULL;
07102 dns_dbversion_t *version = NULL;
07103 dns_diff_t _sig_diff;
07104 dns_diff_t nsec_diff;
07105 dns_diff_t nsec3_diff;
07106 dns_diff_t param_diff;
07107 zonediff_t zonediff;
07108 dns_fixedname_t fixed;
07109 dns_fixedname_t nextfixed;
07110 dns_name_t *name, *nextname;
07111 dns_rdataset_t rdataset;
07112 dns_nsec3chain_t *nsec3chain = NULL, *nextnsec3chain;
07113 dns_nsec3chainlist_t cleanup;
07114 dst_key_t *zone_keys[DNS_MAXZONEKEYS];
07115 isc_int32_t signatures;
07116 isc_boolean_t check_ksk, keyset_kskonly;
07117 isc_boolean_t delegation;
07118 isc_boolean_t first;
07119 isc_result_t result;
07120 isc_stdtime_t now, inception, soaexpire, expire;
07121 isc_uint32_t jitter;
07122 unsigned int i;
07123 unsigned int nkeys = 0;
07124 isc_uint32_t nodes;
07125 isc_boolean_t unsecure = ISC_FALSE;
07126 isc_boolean_t seen_soa, seen_ns, seen_dname, seen_ds;
07127 isc_boolean_t seen_nsec, seen_nsec3, seen_rr;
07128 dns_rdatasetiter_t *iterator = NULL;
07129 isc_boolean_t buildnsecchain;
07130 isc_boolean_t updatensec = ISC_FALSE;
07131 dns_rdatatype_t privatetype = zone->privatetype;
07132
07133 ENTER;
07134
07135 dns_rdataset_init(&rdataset);
07136 dns_fixedname_init(&fixed);
07137 name = dns_fixedname_name(&fixed);
07138 dns_fixedname_init(&nextfixed);
07139 nextname = dns_fixedname_name(&nextfixed);
07140 dns_diff_init(zone->mctx, ¶m_diff);
07141 dns_diff_init(zone->mctx, &nsec3_diff);
07142 dns_diff_init(zone->mctx, &nsec_diff);
07143 dns_diff_init(zone->mctx, &_sig_diff);
07144 zonediff_init(&zonediff, &_sig_diff);
07145 ISC_LIST_INIT(cleanup);
07146
07147
07148
07149
07150 if (zone->update_disabled) {
07151 result = ISC_R_FAILURE;
07152 goto failure;
07153 }
07154
07155 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
07156 dns_db_attach(zone->db, &db);
07157 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
07158
07159 result = dns_db_newversion(db, &version);
07160 if (result != ISC_R_SUCCESS) {
07161 dns_zone_log(zone, ISC_LOG_ERROR,
07162 "zone_nsec3chain:dns_db_newversion -> %s",
07163 dns_result_totext(result));
07164 goto failure;
07165 }
07166
07167 result = find_zone_keys(zone, db, version, zone->mctx,
07168 DNS_MAXZONEKEYS, zone_keys, &nkeys);
07169 if (result != ISC_R_SUCCESS) {
07170 dns_zone_log(zone, ISC_LOG_ERROR,
07171 "zone_nsec3chain:find_zone_keys -> %s",
07172 dns_result_totext(result));
07173 goto failure;
07174 }
07175
07176 isc_stdtime_get(&now);
07177 inception = now - 3600;
07178 soaexpire = now + dns_zone_getsigvalidityinterval(zone);
07179
07180
07181
07182
07183
07184
07185 isc_random_get(&jitter);
07186 expire = soaexpire - jitter % 3600;
07187
07188 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
07189 keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
07190
07191
07192
07193
07194
07195
07196 nodes = zone->nodes;
07197 signatures = zone->signatures;
07198 LOCK_ZONE(zone);
07199 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
07200 UNLOCK_ZONE(zone);
07201 first = ISC_TRUE;
07202
07203 if (nsec3chain != NULL)
07204 nsec3chain->save_delete_nsec = nsec3chain->delete_nsec;
07205
07206
07207
07208 while (nsec3chain != NULL && nodes-- > 0 && signatures > 0) {
07209 LOCK_ZONE(zone);
07210 nextnsec3chain = ISC_LIST_NEXT(nsec3chain, link);
07211
07212 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
07213 if (nsec3chain->done || nsec3chain->db != zone->db) {
07214 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link);
07215 ISC_LIST_APPEND(cleanup, nsec3chain, link);
07216 }
07217 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
07218 UNLOCK_ZONE(zone);
07219 if (ISC_LIST_TAIL(cleanup) == nsec3chain)
07220 goto next_addchain;
07221
07222
07223
07224
07225 if (nsec3chain->db != db) {
07226 goto next_addchain;
07227 }
07228
07229 if (NSEC3REMOVE(nsec3chain->nsec3param.flags))
07230 goto next_addchain;
07231
07232 dns_dbiterator_current(nsec3chain->dbiterator, &node, name);
07233
07234 if (nsec3chain->delete_nsec) {
07235 delegation = ISC_FALSE;
07236 dns_dbiterator_pause(nsec3chain->dbiterator);
07237 CHECK(delete_nsec(db, version, node, name, &nsec_diff));
07238 goto next_addnode;
07239 }
07240
07241
07242
07243
07244 delegation = ISC_FALSE;
07245 unsecure = ISC_FALSE;
07246 if (first) {
07247 dns_fixedname_t ffound;
07248 dns_name_t *found;
07249 dns_fixedname_init(&ffound);
07250 found = dns_fixedname_name(&ffound);
07251 result = dns_db_find(db, name, version,
07252 dns_rdatatype_soa,
07253 DNS_DBFIND_NOWILD, 0, NULL, found,
07254 NULL, NULL);
07255 if ((result == DNS_R_DELEGATION ||
07256 result == DNS_R_DNAME) &&
07257 !dns_name_equal(name, found)) {
07258
07259
07260
07261
07262 dns_name_copy(found, name, NULL);
07263 delegation = ISC_TRUE;
07264 goto next_addnode;
07265 }
07266 }
07267
07268
07269
07270
07271 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
07272 if (result == ISC_R_NOTFOUND)
07273 goto next_addnode;
07274 if (result != ISC_R_SUCCESS)
07275 goto failure;
07276
07277 seen_soa = seen_ns = seen_dname = seen_ds = seen_nsec =
07278 ISC_FALSE;
07279 for (result = dns_rdatasetiter_first(iterator);
07280 result == ISC_R_SUCCESS;
07281 result = dns_rdatasetiter_next(iterator)) {
07282 dns_rdatasetiter_current(iterator, &rdataset);
07283 INSIST(rdataset.type != dns_rdatatype_nsec3);
07284 if (rdataset.type == dns_rdatatype_soa)
07285 seen_soa = ISC_TRUE;
07286 else if (rdataset.type == dns_rdatatype_ns)
07287 seen_ns = ISC_TRUE;
07288 else if (rdataset.type == dns_rdatatype_dname)
07289 seen_dname = ISC_TRUE;
07290 else if (rdataset.type == dns_rdatatype_ds)
07291 seen_ds = ISC_TRUE;
07292 else if (rdataset.type == dns_rdatatype_nsec)
07293 seen_nsec = ISC_TRUE;
07294 dns_rdataset_disassociate(&rdataset);
07295 }
07296 dns_rdatasetiter_destroy(&iterator);
07297
07298
07299
07300 if (seen_nsec)
07301 nsec3chain->seen_nsec = ISC_TRUE;
07302 if (seen_ns && !seen_soa && !seen_ds)
07303 unsecure = ISC_TRUE;
07304 if ((seen_ns && !seen_soa) || seen_dname)
07305 delegation = ISC_TRUE;
07306
07307
07308
07309
07310 dns_dbiterator_pause(nsec3chain->dbiterator);
07311 result = dns_nsec3_addnsec3(db, version, name,
07312 &nsec3chain->nsec3param,
07313 zone->minimum, unsecure,
07314 &nsec3_diff);
07315 if (result != ISC_R_SUCCESS) {
07316 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
07317 "dns_nsec3_addnsec3 -> %s",
07318 dns_result_totext(result));
07319 goto failure;
07320 }
07321
07322
07323
07324
07325
07326
07327
07328
07329
07330 signatures -= 4;
07331
07332
07333
07334
07335 next_addnode:
07336 first = ISC_FALSE;
07337 dns_db_detachnode(db, &node);
07338 do {
07339 result = dns_dbiterator_next(nsec3chain->dbiterator);
07340
07341 if (result == ISC_R_NOMORE && nsec3chain->delete_nsec) {
07342 dns_dbiterator_pause(nsec3chain->dbiterator);
07343 CHECK(fixup_nsec3param(db, version, nsec3chain,
07344 ISC_FALSE, privatetype,
07345 ¶m_diff));
07346 LOCK_ZONE(zone);
07347 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
07348 link);
07349 UNLOCK_ZONE(zone);
07350 ISC_LIST_APPEND(cleanup, nsec3chain, link);
07351 goto next_addchain;
07352 }
07353 if (result == ISC_R_NOMORE) {
07354 dns_dbiterator_pause(nsec3chain->dbiterator);
07355 if (nsec3chain->seen_nsec) {
07356 CHECK(fixup_nsec3param(db, version,
07357 nsec3chain,
07358 ISC_TRUE,
07359 privatetype,
07360 ¶m_diff));
07361 nsec3chain->delete_nsec = ISC_TRUE;
07362 goto same_addchain;
07363 }
07364 CHECK(fixup_nsec3param(db, version, nsec3chain,
07365 ISC_FALSE, privatetype,
07366 ¶m_diff));
07367 LOCK_ZONE(zone);
07368 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
07369 link);
07370 UNLOCK_ZONE(zone);
07371 ISC_LIST_APPEND(cleanup, nsec3chain, link);
07372 goto next_addchain;
07373 } else if (result != ISC_R_SUCCESS) {
07374 dns_zone_log(zone, ISC_LOG_ERROR,
07375 "zone_nsec3chain:"
07376 "dns_dbiterator_next -> %s",
07377 dns_result_totext(result));
07378 goto failure;
07379 } else if (delegation) {
07380 dns_dbiterator_current(nsec3chain->dbiterator,
07381 &node, nextname);
07382 dns_db_detachnode(db, &node);
07383 if (!dns_name_issubdomain(nextname, name))
07384 break;
07385 } else
07386 break;
07387 } while (1);
07388 continue;
07389
07390 same_addchain:
07391 CHECK(dns_dbiterator_first(nsec3chain->dbiterator));
07392 first = ISC_TRUE;
07393 continue;
07394
07395 next_addchain:
07396 dns_dbiterator_pause(nsec3chain->dbiterator);
07397 nsec3chain = nextnsec3chain;
07398 first = ISC_TRUE;
07399 if (nsec3chain != NULL)
07400 nsec3chain->save_delete_nsec = nsec3chain->delete_nsec;
07401 }
07402
07403
07404
07405
07406 LOCK_ZONE(zone);
07407 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
07408 UNLOCK_ZONE(zone);
07409 first = ISC_TRUE;
07410 buildnsecchain = ISC_FALSE;
07411 while (nsec3chain != NULL && nodes-- > 0 && signatures > 0) {
07412 LOCK_ZONE(zone);
07413 nextnsec3chain = ISC_LIST_NEXT(nsec3chain, link);
07414 UNLOCK_ZONE(zone);
07415
07416 if (nsec3chain->db != db)
07417 goto next_removechain;
07418
07419 if (!NSEC3REMOVE(nsec3chain->nsec3param.flags))
07420 goto next_removechain;
07421
07422
07423
07424
07425
07426 if (first && !updatensec &&
07427 (nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_NONSEC) == 0)
07428 {
07429 result = need_nsec_chain(db, version,
07430 &nsec3chain->nsec3param,
07431 &buildnsecchain);
07432 if (result != ISC_R_SUCCESS) {
07433 dns_zone_log(zone, ISC_LOG_ERROR,
07434 "zone_nsec3chain:"
07435 "need_nsec_chain -> %s",
07436 dns_result_totext(result));
07437 goto failure;
07438 }
07439 }
07440
07441 if (first)
07442 dns_zone_log(zone, ISC_LOG_DEBUG(3), "zone_nsec3chain:"
07443 "buildnsecchain = %u\n", buildnsecchain);
07444
07445 dns_dbiterator_current(nsec3chain->dbiterator, &node, name);
07446 delegation = ISC_FALSE;
07447
07448 if (!buildnsecchain) {
07449
07450
07451
07452 if (first) {
07453 result = fixup_nsec3param(db, version,
07454 nsec3chain,
07455 ISC_TRUE, privatetype,
07456 ¶m_diff);
07457 if (result != ISC_R_SUCCESS) {
07458 dns_zone_log(zone, ISC_LOG_ERROR,
07459 "zone_nsec3chain:"
07460 "fixup_nsec3param -> %s",
07461 dns_result_totext(result));
07462 goto failure;
07463 }
07464 }
07465
07466
07467
07468
07469 result = deletematchingnsec3(db, version, node, name,
07470 &nsec3chain->nsec3param,
07471 &nsec3_diff);
07472 if (result != ISC_R_SUCCESS) {
07473 dns_zone_log(zone, ISC_LOG_ERROR,
07474 "zone_nsec3chain:"
07475 "deletematchingnsec3 -> %s",
07476 dns_result_totext(result));
07477 goto failure;
07478 }
07479 goto next_removenode;
07480 }
07481
07482 if (first) {
07483 dns_fixedname_t ffound;
07484 dns_name_t *found;
07485 dns_fixedname_init(&ffound);
07486 found = dns_fixedname_name(&ffound);
07487 result = dns_db_find(db, name, version,
07488 dns_rdatatype_soa,
07489 DNS_DBFIND_NOWILD, 0, NULL, found,
07490 NULL, NULL);
07491 if ((result == DNS_R_DELEGATION ||
07492 result == DNS_R_DNAME) &&
07493 !dns_name_equal(name, found)) {
07494
07495
07496
07497
07498 dns_name_copy(found, name, NULL);
07499 delegation = ISC_TRUE;
07500 goto next_removenode;
07501 }
07502 }
07503
07504
07505
07506
07507 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
07508 if (result == ISC_R_NOTFOUND)
07509 goto next_removenode;
07510 if (result != ISC_R_SUCCESS)
07511 goto failure;
07512
07513 seen_soa = seen_ns = seen_dname = seen_nsec3 = seen_nsec =
07514 seen_rr = ISC_FALSE;
07515 for (result = dns_rdatasetiter_first(iterator);
07516 result == ISC_R_SUCCESS;
07517 result = dns_rdatasetiter_next(iterator)) {
07518 dns_rdatasetiter_current(iterator, &rdataset);
07519 if (rdataset.type == dns_rdatatype_soa)
07520 seen_soa = ISC_TRUE;
07521 else if (rdataset.type == dns_rdatatype_ns)
07522 seen_ns = ISC_TRUE;
07523 else if (rdataset.type == dns_rdatatype_dname)
07524 seen_dname = ISC_TRUE;
07525 else if (rdataset.type == dns_rdatatype_nsec)
07526 seen_nsec = ISC_TRUE;
07527 else if (rdataset.type == dns_rdatatype_nsec3)
07528 seen_nsec3 = ISC_TRUE;
07529 if (rdataset.type != dns_rdatatype_rrsig)
07530 seen_rr = ISC_TRUE;
07531 dns_rdataset_disassociate(&rdataset);
07532 }
07533 dns_rdatasetiter_destroy(&iterator);
07534
07535 if (!seen_rr || seen_nsec3 || seen_nsec)
07536 goto next_removenode;
07537 if ((seen_ns && !seen_soa) || seen_dname)
07538 delegation = ISC_TRUE;
07539
07540
07541
07542
07543 if (!dns_name_equal(name, dns_db_origin(db))) {
07544 dns_dbiterator_pause(nsec3chain->dbiterator);
07545 CHECK(add_nsec(db, version, name, node, zone->minimum,
07546 delegation, &nsec_diff));
07547 }
07548
07549 next_removenode:
07550 first = ISC_FALSE;
07551 dns_db_detachnode(db, &node);
07552 do {
07553 result = dns_dbiterator_next(nsec3chain->dbiterator);
07554 if (result == ISC_R_NOMORE && buildnsecchain) {
07555
07556
07557
07558
07559 updatensec = ISC_TRUE;
07560 goto same_removechain;
07561 }
07562 if (result == ISC_R_NOMORE) {
07563 LOCK_ZONE(zone);
07564 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
07565 link);
07566 UNLOCK_ZONE(zone);
07567 ISC_LIST_APPEND(cleanup, nsec3chain, link);
07568 dns_dbiterator_pause(nsec3chain->dbiterator);
07569 result = fixup_nsec3param(db, version,
07570 nsec3chain, ISC_FALSE,
07571 privatetype,
07572 ¶m_diff);
07573 if (result != ISC_R_SUCCESS) {
07574 dns_zone_log(zone, ISC_LOG_ERROR,
07575 "zone_nsec3chain:"
07576 "fixup_nsec3param -> %s",
07577 dns_result_totext(result));
07578 goto failure;
07579 }
07580 goto next_removechain;
07581 } else if (result != ISC_R_SUCCESS) {
07582 dns_zone_log(zone, ISC_LOG_ERROR,
07583 "zone_nsec3chain:"
07584 "dns_dbiterator_next -> %s",
07585 dns_result_totext(result));
07586 goto failure;
07587 } else if (delegation) {
07588 dns_dbiterator_current(nsec3chain->dbiterator,
07589 &node, nextname);
07590 dns_db_detachnode(db, &node);
07591 if (!dns_name_issubdomain(nextname, name))
07592 break;
07593 } else
07594 break;
07595 } while (1);
07596 continue;
07597
07598 same_removechain:
07599 CHECK(dns_dbiterator_first(nsec3chain->dbiterator));
07600 buildnsecchain = ISC_FALSE;
07601 first = ISC_TRUE;
07602 continue;
07603
07604 next_removechain:
07605 dns_dbiterator_pause(nsec3chain->dbiterator);
07606 nsec3chain = nextnsec3chain;
07607 first = ISC_TRUE;
07608 }
07609
07610
07611
07612
07613 if (!ISC_LIST_EMPTY(param_diff.tuples)) {
07614 isc_boolean_t rebuild_nsec = ISC_FALSE,
07615 rebuild_nsec3 = ISC_FALSE;
07616 result = dns_db_getoriginnode(db, &node);
07617 RUNTIME_CHECK(result == ISC_R_SUCCESS);
07618 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
07619 if (result != ISC_R_SUCCESS) {
07620 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
07621 "dns_db_allrdatasets -> %s",
07622 dns_result_totext(result));
07623 goto failure;
07624 }
07625 for (result = dns_rdatasetiter_first(iterator);
07626 result == ISC_R_SUCCESS;
07627 result = dns_rdatasetiter_next(iterator)) {
07628 dns_rdatasetiter_current(iterator, &rdataset);
07629 if (rdataset.type == dns_rdatatype_nsec)
07630 rebuild_nsec = ISC_TRUE;
07631 if (rdataset.type == dns_rdatatype_nsec3param)
07632 rebuild_nsec3 = ISC_TRUE;
07633 dns_rdataset_disassociate(&rdataset);
07634 }
07635 dns_rdatasetiter_destroy(&iterator);
07636 dns_db_detachnode(db, &node);
07637
07638 if (rebuild_nsec) {
07639 if (nsec3chain != NULL)
07640 dns_dbiterator_pause(nsec3chain->dbiterator);
07641
07642 result = updatesecure(db, version, &zone->origin,
07643 zone->minimum, ISC_TRUE,
07644 &nsec_diff);
07645 if (result != ISC_R_SUCCESS) {
07646 dns_zone_log(zone, ISC_LOG_ERROR,
07647 "zone_nsec3chain:"
07648 "updatesecure -> %s",
07649 dns_result_totext(result));
07650 goto failure;
07651 }
07652 }
07653
07654 if (rebuild_nsec3) {
07655 if (nsec3chain != NULL)
07656 dns_dbiterator_pause(nsec3chain->dbiterator);
07657
07658 result = dns_nsec3_addnsec3s(db, version,
07659 dns_db_origin(db),
07660 zone->minimum, ISC_FALSE,
07661 &nsec3_diff);
07662 if (result != ISC_R_SUCCESS) {
07663 dns_zone_log(zone, ISC_LOG_ERROR,
07664 "zone_nsec3chain:"
07665 "dns_nsec3_addnsec3s -> %s",
07666 dns_result_totext(result));
07667 goto failure;
07668 }
07669 }
07670 }
07671
07672 if (nsec3chain != NULL)
07673 dns_dbiterator_pause(nsec3chain->dbiterator);
07674
07675
07676
07677
07678 if (nsec3chain != NULL)
07679 dns_dbiterator_pause(nsec3chain->dbiterator);
07680 result = update_sigs(&nsec3_diff, db, version, zone_keys,
07681 nkeys, zone, inception, expire, now,
07682 check_ksk, keyset_kskonly, &zonediff);
07683 if (result != ISC_R_SUCCESS) {
07684 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
07685 "update_sigs -> %s", dns_result_totext(result));
07686 goto failure;
07687 }
07688
07689
07690
07691
07692
07693 result = update_sigs(¶m_diff, db, version, zone_keys,
07694 nkeys, zone, inception, expire, now,
07695 check_ksk, keyset_kskonly, &zonediff);
07696 if (result != ISC_R_SUCCESS) {
07697 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
07698 "update_sigs -> %s", dns_result_totext(result));
07699 goto failure;
07700 }
07701
07702 if (updatensec) {
07703 result = updatesecure(db, version, &zone->origin,
07704 zone->minimum, ISC_FALSE, &nsec_diff);
07705 if (result != ISC_R_SUCCESS) {
07706 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
07707 "updatesecure -> %s",
07708 dns_result_totext(result));
07709 goto failure;
07710 }
07711 }
07712
07713 result = update_sigs(&nsec_diff, db, version, zone_keys,
07714 nkeys, zone, inception, expire, now,
07715 check_ksk, keyset_kskonly, &zonediff);
07716 if (result != ISC_R_SUCCESS) {
07717 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
07718 "update_sigs -> %s", dns_result_totext(result));
07719 goto failure;
07720 }
07721
07722
07723
07724
07725
07726 if (ISC_LIST_EMPTY(zonediff.diff->tuples)) {
07727
07728
07729
07730
07731 goto done;
07732 }
07733
07734 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
07735 &zonediff, zone_keys, nkeys, now, ISC_FALSE);
07736 if (result != ISC_R_SUCCESS) {
07737 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
07738 "del_sigs -> %s", dns_result_totext(result));
07739 goto failure;
07740 }
07741
07742 result = update_soa_serial(db, version, zonediff.diff, zone->mctx,
07743 zone->updatemethod);
07744 if (result != ISC_R_SUCCESS) {
07745 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
07746 "update_soa_serial -> %s",
07747 dns_result_totext(result));
07748 goto failure;
07749 }
07750
07751 result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa,
07752 zonediff.diff, zone_keys, nkeys, zone->mctx,
07753 inception, soaexpire, check_ksk, keyset_kskonly);
07754 if (result != ISC_R_SUCCESS) {
07755 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
07756 "add_sigs -> %s", dns_result_totext(result));
07757 goto failure;
07758 }
07759
07760
07761 CHECK(zone_journal(zone, zonediff.diff, NULL, "zone_nsec3chain"));
07762
07763 LOCK_ZONE(zone);
07764 zone_needdump(zone, DNS_DUMP_DELAY);
07765 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
07766 UNLOCK_ZONE(zone);
07767
07768 done:
07769
07770
07771
07772 LOCK_ZONE(zone);
07773 for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
07774 nsec3chain != NULL;
07775 nsec3chain = ISC_LIST_NEXT(nsec3chain, link))
07776 dns_dbiterator_pause(nsec3chain->dbiterator);
07777 UNLOCK_ZONE(zone);
07778
07779
07780
07781
07782
07783 dns_db_closeversion(db, &version, ISC_TRUE);
07784
07785
07786
07787
07788 nsec3chain = ISC_LIST_HEAD(cleanup);
07789 while (nsec3chain != NULL) {
07790 ISC_LIST_UNLINK(cleanup, nsec3chain, link);
07791 dns_db_detach(&nsec3chain->db);
07792 dns_dbiterator_destroy(&nsec3chain->dbiterator);
07793 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
07794 nsec3chain = ISC_LIST_HEAD(cleanup);
07795 }
07796
07797 set_resigntime(zone);
07798
07799 failure:
07800 if (result != ISC_R_SUCCESS)
07801 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain: %s",
07802 dns_result_totext(result));
07803
07804
07805
07806 if (result != ISC_R_SUCCESS && nsec3chain != NULL) {
07807 if (nsec3chain->done) {
07808 dns_db_detach(&nsec3chain->db);
07809 dns_dbiterator_destroy(&nsec3chain->dbiterator);
07810 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
07811 } else {
07812 result = dns_dbiterator_first(nsec3chain->dbiterator);
07813 RUNTIME_CHECK(result == ISC_R_SUCCESS);
07814 dns_dbiterator_pause(nsec3chain->dbiterator);
07815 nsec3chain->delete_nsec = nsec3chain->save_delete_nsec;
07816 }
07817 }
07818
07819
07820
07821
07822 nsec3chain = ISC_LIST_TAIL(cleanup);
07823 while (nsec3chain != NULL) {
07824 ISC_LIST_UNLINK(cleanup, nsec3chain, link);
07825 if (nsec3chain->done) {
07826 dns_db_detach(&nsec3chain->db);
07827 dns_dbiterator_destroy(&nsec3chain->dbiterator);
07828 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
07829 } else {
07830 LOCK_ZONE(zone);
07831 ISC_LIST_PREPEND(zone->nsec3chain, nsec3chain, link);
07832 UNLOCK_ZONE(zone);
07833 result = dns_dbiterator_first(nsec3chain->dbiterator);
07834 RUNTIME_CHECK(result == ISC_R_SUCCESS);
07835 dns_dbiterator_pause(nsec3chain->dbiterator);
07836 nsec3chain->delete_nsec = nsec3chain->save_delete_nsec;
07837 }
07838 nsec3chain = ISC_LIST_TAIL(cleanup);
07839 }
07840
07841 LOCK_ZONE(zone);
07842 for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
07843 nsec3chain != NULL;
07844 nsec3chain = ISC_LIST_NEXT(nsec3chain, link))
07845 dns_dbiterator_pause(nsec3chain->dbiterator);
07846 UNLOCK_ZONE(zone);
07847
07848 dns_diff_clear(¶m_diff);
07849 dns_diff_clear(&nsec3_diff);
07850 dns_diff_clear(&nsec_diff);
07851 dns_diff_clear(&_sig_diff);
07852
07853 if (iterator != NULL)
07854 dns_rdatasetiter_destroy(&iterator);
07855
07856 for (i = 0; i < nkeys; i++)
07857 dst_key_free(&zone_keys[i]);
07858
07859 if (node != NULL)
07860 dns_db_detachnode(db, &node);
07861 if (version != NULL) {
07862 dns_db_closeversion(db, &version, ISC_FALSE);
07863 dns_db_detach(&db);
07864 } else if (db != NULL)
07865 dns_db_detach(&db);
07866
07867 LOCK_ZONE(zone);
07868 if (ISC_LIST_HEAD(zone->nsec3chain) != NULL) {
07869 isc_interval_t interval;
07870 if (zone->update_disabled || result != ISC_R_SUCCESS)
07871 isc_interval_set(&interval, 60, 0);
07872 else
07873 isc_interval_set(&interval, 0, 10000000);
07874 isc_time_nowplusinterval(&zone->nsec3chaintime, &interval);
07875 } else
07876 isc_time_settoepoch(&zone->nsec3chaintime);
07877 UNLOCK_ZONE(zone);
07878
07879 INSIST(version == NULL);
07880 }
07881
07882 static isc_result_t
07883 del_sig(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
07884 dns_dbnode_t *node, unsigned int nkeys, dns_secalg_t algorithm,
07885 isc_uint16_t keyid, dns_diff_t *diff)
07886 {
07887 dns_rdata_rrsig_t rrsig;
07888 dns_rdataset_t rdataset;
07889 dns_rdatasetiter_t *iterator = NULL;
07890 isc_result_t result;
07891
07892 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
07893 if (result != ISC_R_SUCCESS) {
07894 if (result == ISC_R_NOTFOUND)
07895 result = ISC_R_SUCCESS;
07896 return (result);
07897 }
07898
07899 dns_rdataset_init(&rdataset);
07900 for (result = dns_rdatasetiter_first(iterator);
07901 result == ISC_R_SUCCESS;
07902 result = dns_rdatasetiter_next(iterator)) {
07903 dns_rdatasetiter_current(iterator, &rdataset);
07904 if (nkeys == 0 && rdataset.type == dns_rdatatype_nsec) {
07905 for (result = dns_rdataset_first(&rdataset);
07906 result == ISC_R_SUCCESS;
07907 result = dns_rdataset_next(&rdataset)) {
07908 dns_rdata_t rdata = DNS_RDATA_INIT;
07909 dns_rdataset_current(&rdataset, &rdata);
07910 CHECK(update_one_rr(db, version, diff,
07911 DNS_DIFFOP_DEL, name,
07912 rdataset.ttl, &rdata));
07913 }
07914 if (result != ISC_R_NOMORE)
07915 goto failure;
07916 dns_rdataset_disassociate(&rdataset);
07917 continue;
07918 }
07919 if (rdataset.type != dns_rdatatype_rrsig) {
07920 dns_rdataset_disassociate(&rdataset);
07921 continue;
07922 }
07923 for (result = dns_rdataset_first(&rdataset);
07924 result == ISC_R_SUCCESS;
07925 result = dns_rdataset_next(&rdataset)) {
07926 dns_rdata_t rdata = DNS_RDATA_INIT;
07927 dns_rdataset_current(&rdataset, &rdata);
07928 CHECK(dns_rdata_tostruct(&rdata, &rrsig, NULL));
07929 if (rrsig.algorithm != algorithm ||
07930 rrsig.keyid != keyid)
07931 continue;
07932 CHECK(update_one_rr(db, version, diff,
07933 DNS_DIFFOP_DELRESIGN, name,
07934 rdataset.ttl, &rdata));
07935 }
07936 dns_rdataset_disassociate(&rdataset);
07937 if (result != ISC_R_NOMORE)
07938 break;
07939 }
07940 if (result == ISC_R_NOMORE)
07941 result = ISC_R_SUCCESS;
07942 failure:
07943 if (dns_rdataset_isassociated(&rdataset))
07944 dns_rdataset_disassociate(&rdataset);
07945 dns_rdatasetiter_destroy(&iterator);
07946 return (result);
07947 }
07948
07949
07950
07951
07952
07953 static void
07954 zone_sign(dns_zone_t *zone) {
07955 const char *me = "zone_sign";
07956 dns_db_t *db = NULL;
07957 dns_dbnode_t *node = NULL;
07958 dns_dbversion_t *version = NULL;
07959 dns_diff_t _sig_diff;
07960 dns_diff_t post_diff;
07961 zonediff_t zonediff;
07962 dns_fixedname_t fixed;
07963 dns_fixedname_t nextfixed;
07964 dns_name_t *name, *nextname;
07965 dns_rdataset_t rdataset;
07966 dns_signing_t *signing, *nextsigning;
07967 dns_signinglist_t cleanup;
07968 dst_key_t *zone_keys[DNS_MAXZONEKEYS];
07969 isc_int32_t signatures;
07970 isc_boolean_t check_ksk, keyset_kskonly, is_ksk;
07971 isc_boolean_t commit = ISC_FALSE;
07972 isc_boolean_t delegation;
07973 isc_boolean_t build_nsec = ISC_FALSE;
07974 isc_boolean_t build_nsec3 = ISC_FALSE;
07975 isc_boolean_t first;
07976 isc_result_t result;
07977 isc_stdtime_t now, inception, soaexpire, expire;
07978 isc_uint32_t jitter;
07979 unsigned int i, j;
07980 unsigned int nkeys = 0;
07981 isc_uint32_t nodes;
07982
07983 ENTER;
07984
07985 dns_rdataset_init(&rdataset);
07986 dns_fixedname_init(&fixed);
07987 name = dns_fixedname_name(&fixed);
07988 dns_fixedname_init(&nextfixed);
07989 nextname = dns_fixedname_name(&nextfixed);
07990 dns_diff_init(zone->mctx, &_sig_diff);
07991 dns_diff_init(zone->mctx, &post_diff);
07992 zonediff_init(&zonediff, &_sig_diff);
07993 ISC_LIST_INIT(cleanup);
07994
07995
07996
07997
07998 if (zone->update_disabled) {
07999 result = ISC_R_FAILURE;
08000 goto failure;
08001 }
08002
08003 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
08004 if (zone->db != NULL)
08005 dns_db_attach(zone->db, &db);
08006 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
08007 if (db == NULL) {
08008 result = ISC_R_FAILURE;
08009 goto failure;
08010 }
08011
08012 result = dns_db_newversion(db, &version);
08013 if (result != ISC_R_SUCCESS) {
08014 dns_zone_log(zone, ISC_LOG_ERROR,
08015 "zone_sign:dns_db_newversion -> %s",
08016 dns_result_totext(result));
08017 goto failure;
08018 }
08019
08020 result = find_zone_keys(zone, db, version, zone->mctx,
08021 DNS_MAXZONEKEYS, zone_keys, &nkeys);
08022 if (result != ISC_R_SUCCESS) {
08023 dns_zone_log(zone, ISC_LOG_ERROR,
08024 "zone_sign:find_zone_keys -> %s",
08025 dns_result_totext(result));
08026 goto failure;
08027 }
08028
08029 isc_stdtime_get(&now);
08030 inception = now - 3600;
08031 soaexpire = now + dns_zone_getsigvalidityinterval(zone);
08032
08033
08034
08035
08036
08037
08038 isc_random_get(&jitter);
08039 expire = soaexpire - jitter % 3600;
08040
08041
08042
08043
08044
08045
08046 nodes = zone->nodes;
08047 signatures = zone->signatures;
08048 signing = ISC_LIST_HEAD(zone->signing);
08049 first = ISC_TRUE;
08050
08051 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
08052 keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
08053
08054
08055 CHECK(dns_private_chains(db, version, zone->privatetype,
08056 &build_nsec, &build_nsec3));
08057
08058
08059 if (!build_nsec && !build_nsec3)
08060 build_nsec = ISC_TRUE;
08061
08062 while (signing != NULL && nodes-- > 0 && signatures > 0) {
08063 nextsigning = ISC_LIST_NEXT(signing, link);
08064
08065 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
08066 if (signing->done || signing->db != zone->db) {
08067
08068
08069
08070
08071
08072 ISC_LIST_UNLINK(zone->signing, signing, link);
08073 ISC_LIST_APPEND(cleanup, signing, link);
08074 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
08075 goto next_signing;
08076 }
08077 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
08078
08079 if (signing->db != db)
08080 goto next_signing;
08081
08082 delegation = ISC_FALSE;
08083
08084 if (first && signing->delete) {
08085
08086
08087
08088 for (i = 0, j = 0; i < nkeys; i++) {
08089
08090
08091
08092 if (ALG(zone_keys[i]) == signing->algorithm &&
08093 dst_key_id(zone_keys[i]) == signing->keyid)
08094 {
08095 if (KSK(zone_keys[i]))
08096 dst_key_free(&zone_keys[i]);
08097 continue;
08098 }
08099 zone_keys[j] = zone_keys[i];
08100 j++;
08101 }
08102 nkeys = j;
08103 }
08104
08105 dns_dbiterator_current(signing->dbiterator, &node, name);
08106
08107 if (signing->delete) {
08108 dns_dbiterator_pause(signing->dbiterator);
08109 CHECK(del_sig(db, version, name, node, nkeys,
08110 signing->algorithm, signing->keyid,
08111 zonediff.diff));
08112 }
08113
08114
08115
08116
08117
08118 if (first) {
08119 dns_fixedname_t ffound;
08120 dns_name_t *found;
08121 dns_fixedname_init(&ffound);
08122 found = dns_fixedname_name(&ffound);
08123 result = dns_db_find(db, name, version,
08124 dns_rdatatype_soa,
08125 DNS_DBFIND_NOWILD, 0, NULL, found,
08126 NULL, NULL);
08127 if ((result == DNS_R_DELEGATION ||
08128 result == DNS_R_DNAME) &&
08129 !dns_name_equal(name, found)) {
08130
08131
08132
08133
08134 dns_name_copy(found, name, NULL);
08135 delegation = ISC_TRUE;
08136 goto next_node;
08137 }
08138 }
08139
08140
08141
08142
08143 dns_dbiterator_pause(signing->dbiterator);
08144 for (i = 0; i < nkeys; i++) {
08145 isc_boolean_t both = ISC_FALSE;
08146
08147
08148
08149
08150 if (!dst_key_isprivate(zone_keys[i]))
08151 continue;
08152
08153
08154
08155
08156 if (!signing->delete &&
08157 (dst_key_alg(zone_keys[i]) != signing->algorithm ||
08158 dst_key_id(zone_keys[i]) != signing->keyid))
08159 continue;
08160
08161
08162
08163
08164
08165 if (signing->delete &&
08166 ALG(zone_keys[i]) != signing->algorithm)
08167 continue;
08168
08169
08170
08171
08172 if (check_ksk && !REVOKE(zone_keys[i])) {
08173 isc_boolean_t have_ksk, have_nonksk;
08174 if (KSK(zone_keys[i])) {
08175 have_ksk = ISC_TRUE;
08176 have_nonksk = ISC_FALSE;
08177 } else {
08178 have_ksk = ISC_FALSE;
08179 have_nonksk = ISC_TRUE;
08180 }
08181 for (j = 0; j < nkeys; j++) {
08182 if (j == i ||
08183 ALG(zone_keys[i]) !=
08184 ALG(zone_keys[j]))
08185 continue;
08186 if (REVOKE(zone_keys[j]))
08187 continue;
08188 if (KSK(zone_keys[j]))
08189 have_ksk = ISC_TRUE;
08190 else
08191 have_nonksk = ISC_TRUE;
08192 both = have_ksk && have_nonksk;
08193 if (both)
08194 break;
08195 }
08196 }
08197 if (both || REVOKE(zone_keys[i]))
08198 is_ksk = KSK(zone_keys[i]);
08199 else
08200 is_ksk = ISC_FALSE;
08201
08202 CHECK(sign_a_node(db, name, node, version, build_nsec3,
08203 build_nsec, zone_keys[i], inception,
08204 expire, zone->minimum, is_ksk,
08205 ISC_TF(both && keyset_kskonly),
08206 &delegation, zonediff.diff,
08207 &signatures, zone->mctx));
08208
08209
08210
08211
08212 if (!signing->delete)
08213 break;
08214 }
08215
08216
08217
08218
08219 next_node:
08220 first = ISC_FALSE;
08221 dns_db_detachnode(db, &node);
08222 do {
08223 result = dns_dbiterator_next(signing->dbiterator);
08224 if (result == ISC_R_NOMORE) {
08225 ISC_LIST_UNLINK(zone->signing, signing, link);
08226 ISC_LIST_APPEND(cleanup, signing, link);
08227 dns_dbiterator_pause(signing->dbiterator);
08228 if (nkeys != 0 && build_nsec) {
08229
08230
08231
08232
08233
08234
08235
08236
08237 result = updatesecure(db, version,
08238 &zone->origin,
08239 zone->minimum,
08240 ISC_FALSE,
08241 &post_diff);
08242 if (result != ISC_R_SUCCESS) {
08243 dns_zone_log(zone,
08244 ISC_LOG_ERROR,
08245 "updatesecure -> %s",
08246 dns_result_totext(result));
08247 goto failure;
08248 }
08249 }
08250 result = updatesignwithkey(zone, signing,
08251 version,
08252 build_nsec3,
08253 zone->minimum,
08254 &post_diff);
08255 if (result != ISC_R_SUCCESS) {
08256 dns_zone_log(zone, ISC_LOG_ERROR,
08257 "updatesignwithkey -> %s",
08258 dns_result_totext(result));
08259 goto failure;
08260 }
08261 build_nsec = ISC_FALSE;
08262 goto next_signing;
08263 } else if (result != ISC_R_SUCCESS) {
08264 dns_zone_log(zone, ISC_LOG_ERROR,
08265 "zone_sign:dns_dbiterator_next -> %s",
08266 dns_result_totext(result));
08267 goto failure;
08268 } else if (delegation) {
08269 dns_dbiterator_current(signing->dbiterator,
08270 &node, nextname);
08271 dns_db_detachnode(db, &node);
08272 if (!dns_name_issubdomain(nextname, name))
08273 break;
08274 } else
08275 break;
08276 } while (1);
08277 continue;
08278
08279 next_signing:
08280 dns_dbiterator_pause(signing->dbiterator);
08281 signing = nextsigning;
08282 first = ISC_TRUE;
08283 }
08284
08285 if (ISC_LIST_HEAD(post_diff.tuples) != NULL) {
08286 result = update_sigs(&post_diff, db, version, zone_keys,
08287 nkeys, zone, inception, expire, now,
08288 check_ksk, keyset_kskonly, &zonediff);
08289 if (result != ISC_R_SUCCESS) {
08290 dns_zone_log(zone, ISC_LOG_ERROR, "zone_sign:"
08291 "update_sigs -> %s",
08292 dns_result_totext(result));
08293 goto failure;
08294 }
08295 }
08296
08297
08298
08299
08300 if (ISC_LIST_EMPTY(zonediff.diff->tuples)) {
08301 if (zonediff.offline)
08302 commit = ISC_TRUE;
08303 result = ISC_R_SUCCESS;
08304 goto pauseall;
08305 }
08306
08307 commit = ISC_TRUE;
08308
08309 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
08310 &zonediff, zone_keys, nkeys, now, ISC_FALSE);
08311 if (result != ISC_R_SUCCESS) {
08312 dns_zone_log(zone, ISC_LOG_ERROR,
08313 "zone_sign:del_sigs -> %s",
08314 dns_result_totext(result));
08315 goto failure;
08316 }
08317
08318 result = update_soa_serial(db, version, zonediff.diff, zone->mctx,
08319 zone->updatemethod);
08320 if (result != ISC_R_SUCCESS) {
08321 dns_zone_log(zone, ISC_LOG_ERROR,
08322 "zone_sign:update_soa_serial -> %s",
08323 dns_result_totext(result));
08324 goto failure;
08325 }
08326
08327
08328
08329
08330
08331 result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa,
08332 zonediff.diff, zone_keys, nkeys, zone->mctx,
08333 inception, soaexpire, check_ksk, keyset_kskonly);
08334 if (result != ISC_R_SUCCESS) {
08335 dns_zone_log(zone, ISC_LOG_ERROR,
08336 "zone_sign:add_sigs -> %s",
08337 dns_result_totext(result));
08338 goto failure;
08339 }
08340
08341
08342
08343
08344 CHECK(zone_journal(zone, zonediff.diff, NULL, "zone_sign"));
08345
08346 pauseall:
08347
08348
08349
08350 for (signing = ISC_LIST_HEAD(zone->signing);
08351 signing != NULL;
08352 signing = ISC_LIST_NEXT(signing, link))
08353 dns_dbiterator_pause(signing->dbiterator);
08354
08355 for (signing = ISC_LIST_HEAD(cleanup);
08356 signing != NULL;
08357 signing = ISC_LIST_NEXT(signing, link))
08358 dns_dbiterator_pause(signing->dbiterator);
08359
08360
08361
08362
08363 dns_db_closeversion(db, &version, commit);
08364
08365
08366
08367
08368 signing = ISC_LIST_HEAD(cleanup);
08369 while (signing != NULL) {
08370 ISC_LIST_UNLINK(cleanup, signing, link);
08371 dns_db_detach(&signing->db);
08372 dns_dbiterator_destroy(&signing->dbiterator);
08373 isc_mem_put(zone->mctx, signing, sizeof *signing);
08374 signing = ISC_LIST_HEAD(cleanup);
08375 }
08376
08377 set_resigntime(zone);
08378
08379 if (commit) {
08380 LOCK_ZONE(zone);
08381 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
08382 zone_needdump(zone, DNS_DUMP_DELAY);
08383 UNLOCK_ZONE(zone);
08384 }
08385
08386 failure:
08387
08388
08389
08390 signing = ISC_LIST_HEAD(cleanup);
08391 while (signing != NULL) {
08392 ISC_LIST_UNLINK(cleanup, signing, link);
08393 ISC_LIST_PREPEND(zone->signing, signing, link);
08394 dns_dbiterator_first(signing->dbiterator);
08395 dns_dbiterator_pause(signing->dbiterator);
08396 signing = ISC_LIST_HEAD(cleanup);
08397 }
08398
08399 for (signing = ISC_LIST_HEAD(zone->signing);
08400 signing != NULL;
08401 signing = ISC_LIST_NEXT(signing, link))
08402 dns_dbiterator_pause(signing->dbiterator);
08403
08404 dns_diff_clear(&_sig_diff);
08405
08406 for (i = 0; i < nkeys; i++)
08407 dst_key_free(&zone_keys[i]);
08408
08409 if (node != NULL)
08410 dns_db_detachnode(db, &node);
08411
08412 if (version != NULL) {
08413 dns_db_closeversion(db, &version, ISC_FALSE);
08414 dns_db_detach(&db);
08415 } else if (db != NULL)
08416 dns_db_detach(&db);
08417
08418 if (ISC_LIST_HEAD(zone->signing) != NULL) {
08419 isc_interval_t interval;
08420 if (zone->update_disabled || result != ISC_R_SUCCESS)
08421 isc_interval_set(&interval, 60, 0);
08422 else
08423 isc_interval_set(&interval, 0, 10000000);
08424 isc_time_nowplusinterval(&zone->signingtime, &interval);
08425 } else
08426 isc_time_settoepoch(&zone->signingtime);
08427
08428 INSIST(version == NULL);
08429 }
08430
08431 static isc_result_t
08432 normalize_key(dns_rdata_t *rr, dns_rdata_t *target,
08433 unsigned char *data, int size)
08434 {
08435 dns_rdata_dnskey_t dnskey;
08436 dns_rdata_keydata_t keydata;
08437 isc_buffer_t buf;
08438 isc_result_t result;
08439
08440 dns_rdata_reset(target);
08441 isc_buffer_init(&buf, data, size);
08442
08443 switch (rr->type) {
08444 case dns_rdatatype_dnskey:
08445 result = dns_rdata_tostruct(rr, &dnskey, NULL);
08446 RUNTIME_CHECK(result == ISC_R_SUCCESS);
08447 dnskey.flags &= ~DNS_KEYFLAG_REVOKE;
08448 dns_rdata_fromstruct(target, rr->rdclass, dns_rdatatype_dnskey,
08449 &dnskey, &buf);
08450 break;
08451 case dns_rdatatype_keydata:
08452 result = dns_rdata_tostruct(rr, &keydata, NULL);
08453 if (result == ISC_R_UNEXPECTEDEND)
08454 return (result);
08455 RUNTIME_CHECK(result == ISC_R_SUCCESS);
08456 dns_keydata_todnskey(&keydata, &dnskey, NULL);
08457 dns_rdata_fromstruct(target, rr->rdclass, dns_rdatatype_dnskey,
08458 &dnskey, &buf);
08459 break;
08460 default:
08461 INSIST(0);
08462 }
08463 return (ISC_R_SUCCESS);
08464 }
08465
08466
08467
08468
08469
08470
08471
08472
08473
08474
08475
08476
08477 static isc_boolean_t
08478 matchkey(dns_rdataset_t *rdset, dns_rdata_t *rr) {
08479 unsigned char data1[4096], data2[4096];
08480 dns_rdata_t rdata, rdata1, rdata2;
08481 isc_result_t result;
08482
08483 dns_rdata_init(&rdata);
08484 dns_rdata_init(&rdata1);
08485 dns_rdata_init(&rdata2);
08486
08487 result = normalize_key(rr, &rdata1, data1, sizeof(data1));
08488 if (result != ISC_R_SUCCESS)
08489 return (ISC_FALSE);
08490
08491 for (result = dns_rdataset_first(rdset);
08492 result == ISC_R_SUCCESS;
08493 result = dns_rdataset_next(rdset)) {
08494 dns_rdata_reset(&rdata);
08495 dns_rdataset_current(rdset, &rdata);
08496 result = normalize_key(&rdata, &rdata2, data2, sizeof(data2));
08497 if (result != ISC_R_SUCCESS)
08498 continue;
08499 if (dns_rdata_compare(&rdata1, &rdata2) == 0)
08500 return (ISC_TRUE);
08501 }
08502
08503 return (ISC_FALSE);
08504 }
08505
08506
08507
08508
08509
08510
08511
08512
08513
08514
08515
08516
08517 static inline isc_stdtime_t
08518 refresh_time(dns_keyfetch_t *kfetch, isc_boolean_t retry) {
08519 isc_result_t result;
08520 isc_uint32_t t;
08521 dns_rdataset_t *rdset;
08522 dns_rdata_t sigrr = DNS_RDATA_INIT;
08523 dns_rdata_sig_t sig;
08524 isc_stdtime_t now;
08525
08526 isc_stdtime_get(&now);
08527
08528 if (dns_rdataset_isassociated(&kfetch->dnskeysigset))
08529 rdset = &kfetch->dnskeysigset;
08530 else
08531 return (now + dns_zone_mkey_hour);
08532
08533 result = dns_rdataset_first(rdset);
08534 if (result != ISC_R_SUCCESS)
08535 return (now + dns_zone_mkey_hour);
08536
08537 dns_rdataset_current(rdset, &sigrr);
08538 result = dns_rdata_tostruct(&sigrr, &sig, NULL);
08539 RUNTIME_CHECK(result == ISC_R_SUCCESS);
08540
08541 if (!retry) {
08542 t = sig.originalttl / 2;
08543
08544 if (isc_serial_gt(sig.timeexpire, now)) {
08545 isc_uint32_t exp = (sig.timeexpire - now) / 2;
08546 if (t > exp)
08547 t = exp;
08548 }
08549
08550 if (t > (15 * dns_zone_mkey_day))
08551 t = (15 * dns_zone_mkey_day);
08552
08553 if (t < dns_zone_mkey_hour)
08554 t = dns_zone_mkey_hour;
08555 } else {
08556 t = sig.originalttl / 10;
08557
08558 if (isc_serial_gt(sig.timeexpire, now)) {
08559 isc_uint32_t exp = (sig.timeexpire - now) / 10;
08560 if (t > exp)
08561 t = exp;
08562 }
08563
08564 if (t > dns_zone_mkey_day)
08565 t = dns_zone_mkey_day;
08566
08567 if (t < dns_zone_mkey_hour)
08568 t = dns_zone_mkey_hour;
08569 }
08570
08571 return (now + t);
08572 }
08573
08574
08575
08576
08577
08578
08579 static isc_result_t
08580 minimal_update(dns_keyfetch_t *kfetch, dns_dbversion_t *ver, dns_diff_t *diff)
08581 {
08582 isc_result_t result;
08583 isc_buffer_t keyb;
08584 unsigned char key_buf[4096];
08585 dns_rdata_t rdata = DNS_RDATA_INIT;
08586 dns_rdata_keydata_t keydata;
08587 dns_name_t *name;
08588 dns_zone_t *zone = kfetch->zone;
08589 isc_stdtime_t now;
08590
08591 name = dns_fixedname_name(&kfetch->name);
08592 isc_stdtime_get(&now);
08593
08594 for (result = dns_rdataset_first(&kfetch->keydataset);
08595 result == ISC_R_SUCCESS;
08596 result = dns_rdataset_next(&kfetch->keydataset)) {
08597 dns_rdata_reset(&rdata);
08598 dns_rdataset_current(&kfetch->keydataset, &rdata);
08599
08600
08601 CHECK(update_one_rr(kfetch->db, ver, diff, DNS_DIFFOP_DEL,
08602 name, 0, &rdata));
08603
08604
08605 result = dns_rdata_tostruct(&rdata, &keydata, NULL);
08606 if (result == ISC_R_UNEXPECTEDEND)
08607 continue;
08608 if (result != ISC_R_SUCCESS)
08609 goto failure;
08610 keydata.refresh = refresh_time(kfetch, ISC_TRUE);
08611 set_refreshkeytimer(zone, &keydata, now, ISC_FALSE);
08612
08613 dns_rdata_reset(&rdata);
08614 isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
08615 CHECK(dns_rdata_fromstruct(&rdata,
08616 zone->rdclass, dns_rdatatype_keydata,
08617 &keydata, &keyb));
08618
08619
08620 CHECK(update_one_rr(kfetch->db, ver, diff, DNS_DIFFOP_ADD,
08621 name, 0, &rdata));
08622 }
08623 result = ISC_R_SUCCESS;
08624 failure:
08625 return (result);
08626 }
08627
08628
08629
08630
08631 static isc_boolean_t
08632 revocable(dns_keyfetch_t *kfetch, dns_rdata_keydata_t *keydata) {
08633 isc_result_t result;
08634 dns_name_t *keyname;
08635 isc_mem_t *mctx;
08636 dns_rdata_t sigrr = DNS_RDATA_INIT;
08637 dns_rdata_t rr = DNS_RDATA_INIT;
08638 dns_rdata_rrsig_t sig;
08639 dns_rdata_dnskey_t dnskey;
08640 dst_key_t *dstkey = NULL;
08641 unsigned char key_buf[4096];
08642 isc_buffer_t keyb;
08643 isc_boolean_t answer = ISC_FALSE;
08644
08645 REQUIRE(kfetch != NULL && keydata != NULL);
08646 REQUIRE(dns_rdataset_isassociated(&kfetch->dnskeysigset));
08647
08648 keyname = dns_fixedname_name(&kfetch->name);
08649 mctx = kfetch->zone->view->mctx;
08650
08651
08652 isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
08653 dns_keydata_todnskey(keydata, &dnskey, NULL);
08654 dns_rdata_fromstruct(&rr, keydata->common.rdclass,
08655 dns_rdatatype_dnskey, &dnskey, &keyb);
08656 result = dns_dnssec_keyfromrdata(keyname, &rr, mctx, &dstkey);
08657 if (result != ISC_R_SUCCESS)
08658 return (ISC_FALSE);
08659
08660
08661 for (result = dns_rdataset_first(&kfetch->dnskeysigset);
08662 result == ISC_R_SUCCESS;
08663 result = dns_rdataset_next(&kfetch->dnskeysigset))
08664 {
08665 dns_fixedname_t fixed;
08666 dns_fixedname_init(&fixed);
08667
08668 dns_rdata_reset(&sigrr);
08669 dns_rdataset_current(&kfetch->dnskeysigset, &sigrr);
08670 result = dns_rdata_tostruct(&sigrr, &sig, NULL);
08671 RUNTIME_CHECK(result == ISC_R_SUCCESS);
08672
08673 if (dst_key_alg(dstkey) == sig.algorithm &&
08674 dst_key_rid(dstkey) == sig.keyid)
08675 {
08676 result = dns_dnssec_verify2(keyname,
08677 &kfetch->dnskeyset,
08678 dstkey, ISC_FALSE, mctx, &sigrr,
08679 dns_fixedname_name(&fixed));
08680
08681 dns_zone_log(kfetch->zone, ISC_LOG_DEBUG(3),
08682 "Confirm revoked DNSKEY is self-signed: "
08683 "%s", dns_result_totext(result));
08684
08685 if (result == ISC_R_SUCCESS) {
08686 answer = ISC_TRUE;
08687 break;
08688 }
08689 }
08690 }
08691
08692 dst_key_free(&dstkey);
08693 return (answer);
08694 }
08695
08696
08697
08698
08699
08700
08701 static void
08702 keyfetch_done(isc_task_t *task, isc_event_t *event) {
08703 isc_result_t result, eresult;
08704 dns_fetchevent_t *devent;
08705 dns_keyfetch_t *kfetch;
08706 dns_zone_t *zone;
08707 isc_mem_t *mctx = NULL;
08708 dns_keytable_t *secroots = NULL;
08709 dns_dbversion_t *ver = NULL;
08710 dns_diff_t diff;
08711 isc_boolean_t alldone = ISC_FALSE;
08712 isc_boolean_t commit = ISC_FALSE;
08713 dns_name_t *keyname;
08714 dns_rdata_t sigrr = DNS_RDATA_INIT;
08715 dns_rdata_t dnskeyrr = DNS_RDATA_INIT;
08716 dns_rdata_t keydatarr = DNS_RDATA_INIT;
08717 dns_rdata_rrsig_t sig;
08718 dns_rdata_dnskey_t dnskey;
08719 dns_rdata_keydata_t keydata;
08720 isc_boolean_t initializing;
08721 char namebuf[DNS_NAME_FORMATSIZE];
08722 unsigned char key_buf[4096];
08723 isc_buffer_t keyb;
08724 dst_key_t *dstkey;
08725 isc_stdtime_t now;
08726 int pending = 0;
08727 isc_boolean_t secure;
08728 isc_boolean_t free_needed;
08729
08730 UNUSED(task);
08731 INSIST(event != NULL && event->ev_type == DNS_EVENT_FETCHDONE);
08732 INSIST(event->ev_arg != NULL);
08733
08734 kfetch = event->ev_arg;
08735 zone = kfetch->zone;
08736 isc_mem_attach(zone->mctx, &mctx);
08737 keyname = dns_fixedname_name(&kfetch->name);
08738
08739 devent = (dns_fetchevent_t *) event;
08740 eresult = devent->result;
08741
08742
08743 if (devent->node != NULL)
08744 dns_db_detachnode(devent->db, &devent->node);
08745 if (devent->db != NULL)
08746 dns_db_detach(&devent->db);
08747 isc_event_free(&event);
08748 dns_resolver_destroyfetch(&kfetch->fetch);
08749
08750 LOCK_ZONE(zone);
08751 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) || zone->view == NULL)
08752 goto cleanup;
08753
08754 isc_stdtime_get(&now);
08755 dns_name_format(keyname, namebuf, sizeof(namebuf));
08756
08757 result = dns_view_getsecroots(zone->view, &secroots);
08758 INSIST(result == ISC_R_SUCCESS);
08759
08760 dns_diff_init(mctx, &diff);
08761
08762 CHECK(dns_db_newversion(kfetch->db, &ver));
08763
08764 zone->refreshkeycount--;
08765 alldone = ISC_TF(zone->refreshkeycount == 0);
08766
08767 if (alldone)
08768 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESHING);
08769
08770
08771 if (eresult != ISC_R_SUCCESS ||
08772 !dns_rdataset_isassociated(&kfetch->dnskeyset)) {
08773 dns_zone_log(zone, ISC_LOG_WARNING,
08774 "Unable to fetch DNSKEY set "
08775 "'%s': %s", namebuf, dns_result_totext(eresult));
08776 CHECK(minimal_update(kfetch, ver, &diff));
08777 goto done;
08778 }
08779
08780
08781 if (!dns_rdataset_isassociated(&kfetch->dnskeysigset)) {
08782 dns_zone_log(zone, ISC_LOG_WARNING,
08783 "No DNSKEY RRSIGs found for "
08784 "'%s': %s", namebuf, dns_result_totext(eresult));
08785 CHECK(minimal_update(kfetch, ver, &diff));
08786 goto done;
08787 }
08788
08789
08790
08791
08792
08793 kfetch->dnskeyset.trust = kfetch->dnskeysigset.trust = dns_trust_none;
08794
08795
08796
08797
08798 for (result = dns_rdataset_first(&kfetch->dnskeysigset);
08799 result == ISC_R_SUCCESS;
08800 result = dns_rdataset_next(&kfetch->dnskeysigset)) {
08801 dns_keynode_t *keynode = NULL;
08802
08803 dns_rdata_reset(&sigrr);
08804 dns_rdataset_current(&kfetch->dnskeysigset, &sigrr);
08805 result = dns_rdata_tostruct(&sigrr, &sig, NULL);
08806 RUNTIME_CHECK(result == ISC_R_SUCCESS);
08807
08808 result = dns_keytable_find(secroots, keyname, &keynode);
08809 while (result == ISC_R_SUCCESS) {
08810 dns_keynode_t *nextnode = NULL;
08811 dns_fixedname_t fixed;
08812 dns_fixedname_init(&fixed);
08813
08814 dstkey = dns_keynode_key(keynode);
08815 if (dstkey == NULL)
08816 break;
08817
08818 if (dst_key_alg(dstkey) == sig.algorithm &&
08819 dst_key_id(dstkey) == sig.keyid) {
08820 result = dns_dnssec_verify2(keyname,
08821 &kfetch->dnskeyset,
08822 dstkey, ISC_FALSE,
08823 zone->view->mctx, &sigrr,
08824 dns_fixedname_name(&fixed));
08825
08826 dns_zone_log(zone, ISC_LOG_DEBUG(3),
08827 "Verifying DNSKEY set for zone "
08828 "'%s' using key %d/%d: %s",
08829 namebuf, sig.keyid, sig.algorithm,
08830 dns_result_totext(result));
08831
08832 if (result == ISC_R_SUCCESS) {
08833 kfetch->dnskeyset.trust =
08834 dns_trust_secure;
08835 kfetch->dnskeysigset.trust =
08836 dns_trust_secure;
08837 break;
08838 }
08839 }
08840
08841 result = dns_keytable_nextkeynode(secroots,
08842 keynode, &nextnode);
08843 dns_keytable_detachkeynode(secroots, &keynode);
08844 keynode = nextnode;
08845 }
08846
08847 if (keynode != NULL)
08848 dns_keytable_detachkeynode(secroots, &keynode);
08849
08850 if (kfetch->dnskeyset.trust == dns_trust_secure)
08851 break;
08852 }
08853
08854
08855
08856
08857
08858 secure = ISC_TF(kfetch->dnskeyset.trust == dns_trust_secure);
08859
08860
08861
08862
08863
08864
08865
08866
08867
08868
08869
08870
08871
08872
08873 initializing = ISC_TRUE;
08874 for (result = dns_rdataset_first(&kfetch->keydataset);
08875 result == ISC_R_SUCCESS;
08876 result = dns_rdataset_next(&kfetch->keydataset)) {
08877 dns_rdata_reset(&keydatarr);
08878 dns_rdataset_current(&kfetch->keydataset, &keydatarr);
08879 result = dns_rdata_tostruct(&keydatarr, &keydata, NULL);
08880 RUNTIME_CHECK(result == ISC_R_SUCCESS);
08881
08882
08883
08884
08885
08886
08887
08888 initializing = initializing && ISC_TF(keydata.addhd == 0);
08889
08890 if (! matchkey(&kfetch->dnskeyset, &keydatarr)) {
08891 isc_boolean_t deletekey = ISC_FALSE;
08892
08893 if (!secure) {
08894 if (keydata.removehd != 0 &&
08895 keydata.removehd <= now)
08896 deletekey = ISC_TRUE;
08897 } else if (keydata.addhd == 0) {
08898 deletekey = ISC_TRUE;
08899 } else if (keydata.addhd > now) {
08900 dns_zone_log(zone, ISC_LOG_WARNING,
08901 "Pending key unexpectedly missing "
08902 "from %s; restarting acceptance "
08903 "timer", namebuf);
08904 if (keydata.addhd < now + dns_zone_mkey_month)
08905 keydata.addhd =
08906 now + dns_zone_mkey_month;
08907 keydata.refresh = refresh_time(kfetch,
08908 ISC_FALSE);
08909 } else if (keydata.removehd == 0) {
08910 dns_zone_log(zone, ISC_LOG_WARNING,
08911 "Active key unexpectedly missing "
08912 "from %s", namebuf);
08913 keydata.refresh = now + dns_zone_mkey_hour;
08914 } else if (keydata.removehd <= now) {
08915 deletekey = ISC_TRUE;
08916 } else {
08917 keydata.refresh = refresh_time(kfetch,
08918 ISC_FALSE);
08919 }
08920
08921 if (secure || deletekey) {
08922
08923 CHECK(update_one_rr(kfetch->db, ver, &diff,
08924 DNS_DIFFOP_DEL, keyname, 0,
08925 &keydatarr));
08926 }
08927
08928 if (!secure || deletekey)
08929 continue;
08930
08931 dns_rdata_reset(&keydatarr);
08932 isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
08933 dns_rdata_fromstruct(&keydatarr, zone->rdclass,
08934 dns_rdatatype_keydata,
08935 &keydata, &keyb);
08936
08937
08938 CHECK(update_one_rr(kfetch->db, ver, &diff,
08939 DNS_DIFFOP_ADD, keyname, 0,
08940 &keydatarr));
08941
08942 set_refreshkeytimer(zone, &keydata, now, ISC_FALSE);
08943 }
08944 }
08945
08946
08947
08948
08949
08950
08951
08952
08953
08954
08955
08956
08957
08958
08959
08960
08961
08962 for (result = dns_rdataset_first(&kfetch->dnskeyset);
08963 result == ISC_R_SUCCESS;
08964 result = dns_rdataset_next(&kfetch->dnskeyset))
08965 {
08966 isc_boolean_t revoked = ISC_FALSE;
08967 isc_boolean_t newkey = ISC_FALSE;
08968 isc_boolean_t updatekey = ISC_FALSE;
08969 isc_boolean_t deletekey = ISC_FALSE;
08970 isc_boolean_t trustkey = ISC_FALSE;
08971
08972 dns_rdata_reset(&dnskeyrr);
08973 dns_rdataset_current(&kfetch->dnskeyset, &dnskeyrr);
08974 result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
08975 RUNTIME_CHECK(result == ISC_R_SUCCESS);
08976
08977
08978 if (!ISC_TF(dnskey.flags & DNS_KEYFLAG_KSK))
08979 continue;
08980
08981 revoked = ISC_TF(dnskey.flags & DNS_KEYFLAG_REVOKE);
08982
08983 if (matchkey(&kfetch->keydataset, &dnskeyrr)) {
08984 dns_rdata_reset(&keydatarr);
08985 dns_rdataset_current(&kfetch->keydataset, &keydatarr);
08986 result = dns_rdata_tostruct(&keydatarr, &keydata, NULL);
08987 RUNTIME_CHECK(result == ISC_R_SUCCESS);
08988
08989 if (revoked && revocable(kfetch, &keydata)) {
08990 if (keydata.addhd > now) {
08991
08992
08993
08994
08995 deletekey = ISC_TRUE;
08996 } else if (keydata.removehd == 0) {
08997
08998 dns_view_untrust(zone->view, keyname,
08999 &dnskey, mctx);
09000
09001
09002 fail_secure(zone, keyname);
09003
09004
09005 if (keydata.addhd == 0)
09006 deletekey = ISC_TRUE;
09007 else {
09008 keydata.removehd = now +
09009 dns_zone_mkey_month;
09010 keydata.flags |=
09011 DNS_KEYFLAG_REVOKE;
09012 }
09013 } else if (keydata.removehd < now) {
09014
09015 deletekey = ISC_TRUE;
09016 }
09017 } else if (revoked && keydata.removehd == 0) {
09018 dns_zone_log(zone, ISC_LOG_WARNING,
09019 "Active key for zone "
09020 "'%s' is revoked but "
09021 "did not self-sign; "
09022 "ignoring.", namebuf);
09023 continue;
09024 } else if (secure) {
09025 if (keydata.removehd != 0) {
09026
09027
09028
09029
09030
09031
09032
09033 deletekey = ISC_TRUE;
09034 newkey = ISC_TRUE;
09035 keydata.removehd = 0;
09036 keydata.addhd =
09037 now + dns_zone_mkey_month;
09038 } else if (keydata.addhd > now)
09039 pending++;
09040 else if (keydata.addhd == 0)
09041 keydata.addhd = now;
09042
09043 if (keydata.addhd <= now)
09044 trustkey = ISC_TRUE;
09045 } else if (keydata.addhd > now) {
09046
09047
09048
09049
09050 pending++;
09051 keydata.addhd = now + dns_zone_mkey_month;
09052 }
09053
09054 if (!deletekey && !newkey)
09055 updatekey = ISC_TRUE;
09056 } else if (secure) {
09057
09058
09059
09060
09061 if (revoked)
09062 continue;
09063
09064
09065 newkey = ISC_TRUE;
09066
09067 if (initializing) {
09068 dns_keytag_t tag = 0;
09069 CHECK(compute_tag(keyname, &dnskey,
09070 mctx, &tag));
09071 dns_zone_log(zone, ISC_LOG_WARNING,
09072 "Initializing automatic trust "
09073 "anchor management for zone '%s'; "
09074 "DNSKEY ID %d is now trusted, "
09075 "waiving the normal 30-day "
09076 "waiting period.",
09077 namebuf, tag);
09078 trustkey = ISC_TRUE;
09079 }
09080 } else {
09081
09082
09083
09084
09085 continue;
09086 }
09087
09088
09089 if (deletekey || !newkey)
09090 CHECK(update_one_rr(kfetch->db, ver, &diff,
09091 DNS_DIFFOP_DEL, keyname, 0,
09092 &keydatarr));
09093
09094 if (updatekey) {
09095
09096 keydata.refresh = refresh_time(kfetch, ISC_FALSE);
09097 dns_rdata_reset(&keydatarr);
09098 isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
09099 dns_rdata_fromstruct(&keydatarr, zone->rdclass,
09100 dns_rdatatype_keydata,
09101 &keydata, &keyb);
09102
09103
09104 CHECK(update_one_rr(kfetch->db, ver, &diff,
09105 DNS_DIFFOP_ADD, keyname, 0,
09106 &keydatarr));
09107 } else if (newkey) {
09108
09109 result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
09110 RUNTIME_CHECK(result == ISC_R_SUCCESS);
09111 dns_keydata_fromdnskey(&keydata, &dnskey, 0, 0, 0,
09112 NULL);
09113 keydata.addhd = initializing
09114 ? now : now + dns_zone_mkey_month;
09115 keydata.refresh = refresh_time(kfetch, ISC_FALSE);
09116 dns_rdata_reset(&keydatarr);
09117 isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
09118 dns_rdata_fromstruct(&keydatarr, zone->rdclass,
09119 dns_rdatatype_keydata,
09120 &keydata, &keyb);
09121
09122
09123 CHECK(update_one_rr(kfetch->db, ver, &diff,
09124 DNS_DIFFOP_ADD, keyname, 0,
09125 &keydatarr));
09126 }
09127
09128 if (trustkey) {
09129
09130 result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
09131 RUNTIME_CHECK(result == ISC_R_SUCCESS);
09132 trust_key(zone, keyname, &dnskey, mctx);
09133 }
09134
09135 if (secure && !deletekey) {
09136 INSIST(newkey || updatekey);
09137 set_refreshkeytimer(zone, &keydata, now, ISC_FALSE);
09138 }
09139 }
09140
09141
09142
09143
09144
09145
09146
09147
09148
09149
09150 if (pending != 0)
09151 fail_secure(zone, keyname);
09152
09153 done:
09154
09155 if (!ISC_LIST_EMPTY(diff.tuples)) {
09156
09157 CHECK(update_soa_serial(kfetch->db, ver, &diff, mctx,
09158 zone->updatemethod));
09159 CHECK(zone_journal(zone, &diff, NULL, "keyfetch_done"));
09160 commit = ISC_TRUE;
09161
09162 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
09163 zone_needdump(zone, 30);
09164 }
09165
09166 failure:
09167
09168 dns_diff_clear(&diff);
09169 if (ver != NULL)
09170 dns_db_closeversion(kfetch->db, &ver, commit);
09171
09172 cleanup:
09173 dns_db_detach(&kfetch->db);
09174
09175 INSIST(zone->irefs > 0);
09176 zone->irefs--;
09177 kfetch->zone = NULL;
09178
09179 if (dns_rdataset_isassociated(&kfetch->keydataset))
09180 dns_rdataset_disassociate(&kfetch->keydataset);
09181 if (dns_rdataset_isassociated(&kfetch->dnskeyset))
09182 dns_rdataset_disassociate(&kfetch->dnskeyset);
09183 if (dns_rdataset_isassociated(&kfetch->dnskeysigset))
09184 dns_rdataset_disassociate(&kfetch->dnskeysigset);
09185
09186 dns_name_free(keyname, mctx);
09187 isc_mem_put(mctx, kfetch, sizeof(dns_keyfetch_t));
09188 isc_mem_detach(&mctx);
09189
09190 if (secroots != NULL)
09191 dns_keytable_detach(&secroots);
09192
09193 free_needed = exit_check(zone);
09194 UNLOCK_ZONE(zone);
09195 if (free_needed)
09196 zone_free(zone);
09197
09198 INSIST(ver == NULL);
09199 }
09200
09201
09202
09203
09204
09205 static void
09206 zone_refreshkeys(dns_zone_t *zone) {
09207 const char me[] = "zone_refreshkeys";
09208 isc_result_t result;
09209 dns_rriterator_t rrit;
09210 dns_db_t *db = NULL;
09211 dns_dbversion_t *ver = NULL;
09212 dns_diff_t diff;
09213 dns_rdata_t rdata = DNS_RDATA_INIT;
09214 dns_rdata_keydata_t kd;
09215 isc_stdtime_t now;
09216 isc_boolean_t commit = ISC_FALSE;
09217 isc_boolean_t fetching = ISC_FALSE, fetch_err = ISC_FALSE;
09218
09219 ENTER;
09220 REQUIRE(zone->db != NULL);
09221
09222 isc_stdtime_get(&now);
09223
09224 LOCK_ZONE(zone);
09225 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
09226 isc_time_settoepoch(&zone->refreshkeytime);
09227 UNLOCK_ZONE(zone);
09228 return;
09229 }
09230
09231 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
09232 dns_db_attach(zone->db, &db);
09233 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
09234
09235 dns_diff_init(zone->mctx, &diff);
09236
09237 CHECK(dns_db_newversion(db, &ver));
09238
09239 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESHING);
09240
09241 dns_rriterator_init(&rrit, db, ver, 0);
09242 for (result = dns_rriterator_first(&rrit);
09243 result == ISC_R_SUCCESS;
09244 result = dns_rriterator_nextrrset(&rrit)) {
09245 isc_stdtime_t timer = 0xffffffff;
09246 dns_name_t *name = NULL, *kname = NULL;
09247 dns_rdataset_t *kdset = NULL;
09248 dns_keyfetch_t *kfetch;
09249 isc_uint32_t ttl;
09250
09251 dns_rriterator_current(&rrit, &name, &ttl, &kdset, NULL);
09252 if (kdset == NULL || kdset->type != dns_rdatatype_keydata ||
09253 !dns_rdataset_isassociated(kdset))
09254 continue;
09255
09256
09257
09258
09259
09260 for (result = dns_rdataset_first(kdset);
09261 result == ISC_R_SUCCESS;
09262 result = dns_rdataset_next(kdset)) {
09263 dns_rdata_reset(&rdata);
09264 dns_rdataset_current(kdset, &rdata);
09265 result = dns_rdata_tostruct(&rdata, &kd, NULL);
09266 RUNTIME_CHECK(result == ISC_R_SUCCESS);
09267
09268
09269 if (kd.removehd != 0 && kd.removehd < now) {
09270 CHECK(update_one_rr(db, ver, &diff,
09271 DNS_DIFFOP_DEL, name, ttl,
09272 &rdata));
09273 continue;
09274 }
09275
09276
09277 if (kd.addhd != 0 && kd.addhd < now)
09278 timer = kd.addhd;
09279
09280
09281 if (timer > kd.refresh)
09282 timer = kd.refresh;
09283 }
09284
09285 if (timer > now)
09286 continue;
09287
09288 kfetch = isc_mem_get(zone->mctx, sizeof(dns_keyfetch_t));
09289 if (kfetch == NULL) {
09290 fetch_err = ISC_TRUE;
09291 goto failure;
09292 }
09293
09294 zone->refreshkeycount++;
09295 kfetch->zone = zone;
09296 zone->irefs++;
09297 INSIST(zone->irefs != 0);
09298 dns_fixedname_init(&kfetch->name);
09299 kname = dns_fixedname_name(&kfetch->name);
09300 dns_name_dup(name, zone->mctx, kname);
09301 dns_rdataset_init(&kfetch->dnskeyset);
09302 dns_rdataset_init(&kfetch->dnskeysigset);
09303 dns_rdataset_init(&kfetch->keydataset);
09304 dns_rdataset_clone(kdset, &kfetch->keydataset);
09305 kfetch->db = NULL;
09306 dns_db_attach(db, &kfetch->db);
09307 kfetch->fetch = NULL;
09308
09309 result = dns_resolver_createfetch(zone->view->resolver,
09310 kname, dns_rdatatype_dnskey,
09311 NULL, NULL, NULL,
09312 DNS_FETCHOPT_NOVALIDATE,
09313 zone->task,
09314 keyfetch_done, kfetch,
09315 &kfetch->dnskeyset,
09316 &kfetch->dnskeysigset,
09317 &kfetch->fetch);
09318 if (result == ISC_R_SUCCESS)
09319 fetching = ISC_TRUE;
09320 else {
09321 zone->refreshkeycount--;
09322 zone->irefs--;
09323 dns_db_detach(&kfetch->db);
09324 dns_rdataset_disassociate(&kfetch->keydataset);
09325 dns_name_free(kname, zone->mctx);
09326 isc_mem_put(zone->mctx, kfetch, sizeof(dns_keyfetch_t));
09327 dns_zone_log(zone, ISC_LOG_WARNING,
09328 "Failed to create fetch for "
09329 "DNSKEY update");
09330 fetch_err = ISC_TRUE;
09331 }
09332 }
09333 if (!ISC_LIST_EMPTY(diff.tuples)) {
09334 CHECK(update_soa_serial(db, ver, &diff, zone->mctx,
09335 zone->updatemethod));
09336 CHECK(zone_journal(zone, &diff, NULL, "zone_refreshkeys"));
09337 commit = ISC_TRUE;
09338 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
09339 zone_needdump(zone, 30);
09340 }
09341
09342 failure:
09343 if (fetch_err) {
09344
09345
09346
09347 isc_time_t timenow, timethen;
09348 char timebuf[80];
09349
09350 TIME_NOW(&timenow);
09351 DNS_ZONE_TIME_ADD(&timenow, dns_zone_mkey_hour, &timethen);
09352 zone->refreshkeytime = timethen;
09353 zone_settimer(zone, &timenow);
09354
09355 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
09356 dns_zone_log(zone, ISC_LOG_DEBUG(1), "retry key refresh: %s",
09357 timebuf);
09358
09359 if (!fetching)
09360 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESHING);
09361 }
09362
09363 UNLOCK_ZONE(zone);
09364
09365 dns_diff_clear(&diff);
09366 if (ver != NULL) {
09367 dns_rriterator_destroy(&rrit);
09368 dns_db_closeversion(db, &ver, commit);
09369 }
09370 dns_db_detach(&db);
09371
09372 INSIST(ver == NULL);
09373 }
09374
09375 static void
09376 zone_maintenance(dns_zone_t *zone) {
09377 const char me[] = "zone_maintenance";
09378 isc_time_t now;
09379 isc_result_t result;
09380 isc_boolean_t dumping;
09381
09382 REQUIRE(DNS_ZONE_VALID(zone));
09383 ENTER;
09384
09385
09386
09387
09388 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING))
09389 return;
09390
09391
09392
09393
09394
09395
09396
09397
09398 if (zone->view == NULL || zone->view->adb == NULL)
09399 return;
09400
09401 TIME_NOW(&now);
09402
09403
09404
09405
09406 switch (zone->type) {
09407 case dns_zone_redirect:
09408 if (zone->masters == NULL)
09409 break;
09410 case dns_zone_slave:
09411 case dns_zone_stub:
09412 LOCK_ZONE(zone);
09413 if (isc_time_compare(&now, &zone->expiretime) >= 0 &&
09414 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
09415 zone_expire(zone);
09416 zone->refreshtime = now;
09417 }
09418 UNLOCK_ZONE(zone);
09419 break;
09420 default:
09421 break;
09422 }
09423
09424
09425
09426
09427 switch (zone->type) {
09428 case dns_zone_redirect:
09429 if (zone->masters == NULL)
09430 break;
09431 case dns_zone_slave:
09432 case dns_zone_stub:
09433 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH) &&
09434 isc_time_compare(&now, &zone->refreshtime) >= 0)
09435 dns_zone_refresh(zone);
09436 break;
09437 default:
09438 break;
09439 }
09440
09441
09442
09443
09444 if (zone->type == dns_zone_slave &&
09445 (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) ||
09446 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY)) &&
09447 isc_time_compare(&now, &zone->notifytime) >= 0)
09448 zone_notify(zone, &now);
09449
09450
09451
09452
09453 switch (zone->type) {
09454 case dns_zone_master:
09455 case dns_zone_slave:
09456 case dns_zone_key:
09457 case dns_zone_redirect:
09458 case dns_zone_stub:
09459 LOCK_ZONE(zone);
09460 if (zone->masterfile != NULL &&
09461 isc_time_compare(&now, &zone->dumptime) >= 0 &&
09462 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
09463 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP)) {
09464 dumping = was_dumping(zone);
09465 } else
09466 dumping = ISC_TRUE;
09467 UNLOCK_ZONE(zone);
09468 if (!dumping) {
09469 result = zone_dump(zone, ISC_TRUE);
09470 if (result != ISC_R_SUCCESS)
09471 dns_zone_log(zone, ISC_LOG_WARNING,
09472 "dump failed: %s",
09473 dns_result_totext(result));
09474 }
09475 break;
09476 default:
09477 break;
09478 }
09479
09480
09481
09482
09483 switch (zone->type) {
09484 case dns_zone_master:
09485 case dns_zone_redirect:
09486 if ((DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) ||
09487 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY))&&
09488 isc_time_compare(&now, &zone->notifytime) >= 0)
09489 zone_notify(zone, &now);
09490 default:
09491 break;
09492 }
09493
09494
09495
09496
09497 switch (zone->type) {
09498 case dns_zone_key:
09499 if (isc_time_compare(&now, &zone->refreshkeytime) >= 0) {
09500 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
09501 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING)) {
09502 zone_refreshkeys(zone);
09503 }
09504 }
09505 break;
09506 case dns_zone_master:
09507 if (!isc_time_isepoch(&zone->refreshkeytime) &&
09508 isc_time_compare(&now, &zone->refreshkeytime) >= 0 &&
09509 zone->rss_event == NULL)
09510 zone_rekey(zone);
09511 default:
09512 break;
09513 }
09514
09515 switch (zone->type) {
09516 case dns_zone_master:
09517 case dns_zone_redirect:
09518 case dns_zone_slave:
09519
09520
09521
09522 if (zone->rss_event != NULL)
09523 break;
09524 if (!isc_time_isepoch(&zone->signingtime) &&
09525 isc_time_compare(&now, &zone->signingtime) >= 0)
09526 zone_sign(zone);
09527 else if (!isc_time_isepoch(&zone->resigntime) &&
09528 isc_time_compare(&now, &zone->resigntime) >= 0)
09529 zone_resigninc(zone);
09530 else if (!isc_time_isepoch(&zone->nsec3chaintime) &&
09531 isc_time_compare(&now, &zone->nsec3chaintime) >= 0)
09532 zone_nsec3chain(zone);
09533
09534
09535
09536 if (!isc_time_isepoch(&zone->keywarntime) &&
09537 isc_time_compare(&now, &zone->keywarntime) >= 0)
09538 set_key_expiry_warning(zone, zone->key_expiry,
09539 isc_time_seconds(&now));
09540 break;
09541
09542 default:
09543 break;
09544 }
09545 zone_settimer(zone, &now);
09546 }
09547
09548 void
09549 dns_zone_markdirty(dns_zone_t *zone) {
09550 isc_uint32_t serial;
09551 isc_result_t result = ISC_R_SUCCESS;
09552 dns_zone_t *secure = NULL;
09553
09554
09555
09556
09557
09558
09559 again:
09560 LOCK_ZONE(zone);
09561 if (zone->type == dns_zone_master) {
09562 if (inline_raw(zone)) {
09563 unsigned int soacount;
09564 secure = zone->secure;
09565 INSIST(secure != zone);
09566 TRYLOCK_ZONE(result, secure);
09567 if (result != ISC_R_SUCCESS) {
09568 UNLOCK_ZONE(zone);
09569 secure = NULL;
09570 #ifdef ISC_PLATFORM_USETHREADS
09571 isc_thread_yield();
09572 #endif
09573 goto again;
09574 }
09575
09576 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
09577 if (zone->db != NULL) {
09578 result = zone_get_from_db(zone, zone->db, NULL,
09579 &soacount, &serial,
09580 NULL, NULL, NULL,
09581 NULL, NULL);
09582 } else
09583 result = DNS_R_NOTLOADED;
09584 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
09585 if (result == ISC_R_SUCCESS && soacount > 0U)
09586 zone_send_secureserial(zone, serial);
09587 }
09588
09589
09590 if (result == ISC_R_SUCCESS)
09591 set_resigntime(zone);
09592 }
09593 if (secure != NULL)
09594 UNLOCK_ZONE(secure);
09595 zone_needdump(zone, DNS_DUMP_DELAY);
09596 UNLOCK_ZONE(zone);
09597 }
09598
09599 void
09600 dns_zone_expire(dns_zone_t *zone) {
09601 REQUIRE(DNS_ZONE_VALID(zone));
09602
09603 LOCK_ZONE(zone);
09604 zone_expire(zone);
09605 UNLOCK_ZONE(zone);
09606 }
09607
09608 static void
09609 zone_expire(dns_zone_t *zone) {
09610
09611
09612
09613
09614 REQUIRE(LOCKED_ZONE(zone));
09615
09616 dns_zone_log(zone, ISC_LOG_WARNING, "expired");
09617
09618 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXPIRED);
09619 zone->refresh = DNS_ZONE_DEFAULTREFRESH;
09620 zone->retry = DNS_ZONE_DEFAULTRETRY;
09621 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
09622 zone_unload(zone);
09623 }
09624
09625 void
09626 dns_zone_refresh(dns_zone_t *zone) {
09627 isc_interval_t i;
09628 isc_uint32_t oldflags;
09629 unsigned int j;
09630 isc_result_t result;
09631
09632 REQUIRE(DNS_ZONE_VALID(zone));
09633
09634 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
09635 return;
09636
09637
09638
09639
09640
09641
09642 LOCK_ZONE(zone);
09643 oldflags = zone->flags;
09644 if (zone->masterscnt == 0) {
09645 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOMASTERS);
09646 if ((oldflags & DNS_ZONEFLG_NOMASTERS) == 0)
09647 dns_zone_log(zone, ISC_LOG_ERROR,
09648 "cannot refresh: no masters");
09649 goto unlock;
09650 }
09651 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
09652 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
09653 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
09654 if ((oldflags & (DNS_ZONEFLG_REFRESH|DNS_ZONEFLG_LOADING)) != 0)
09655 goto unlock;
09656
09657
09658
09659
09660
09661
09662 isc_interval_set(&i, isc_random_jitter(zone->retry, zone->retry / 4),
09663 0);
09664 result = isc_time_nowplusinterval(&zone->refreshtime, &i);
09665 if (result != ISC_R_SUCCESS)
09666 dns_zone_log(zone, ISC_LOG_WARNING,
09667 "isc_time_nowplusinterval() failed: %s",
09668 dns_result_totext(result));
09669
09670
09671
09672
09673
09674
09675 if (! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HAVETIMERS))
09676 zone->retry = ISC_MIN(zone->retry * 2, 6 * 3600);
09677
09678 zone->curmaster = 0;
09679 for (j = 0; j < zone->masterscnt; j++)
09680 zone->mastersok[j] = ISC_FALSE;
09681
09682 queue_soa_query(zone);
09683 unlock:
09684 UNLOCK_ZONE(zone);
09685 }
09686
09687 isc_result_t
09688 dns_zone_flush(dns_zone_t *zone) {
09689 isc_result_t result = ISC_R_SUCCESS;
09690 isc_boolean_t dumping;
09691
09692 REQUIRE(DNS_ZONE_VALID(zone));
09693
09694 LOCK_ZONE(zone);
09695 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FLUSH);
09696 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
09697 zone->masterfile != NULL) {
09698 result = ISC_R_ALREADYRUNNING;
09699 dumping = was_dumping(zone);
09700 } else
09701 dumping = ISC_TRUE;
09702 UNLOCK_ZONE(zone);
09703 if (!dumping)
09704 result = zone_dump(zone, ISC_FALSE);
09705 return (result);
09706 }
09707
09708 isc_result_t
09709 dns_zone_dump(dns_zone_t *zone) {
09710 isc_result_t result = ISC_R_ALREADYRUNNING;
09711 isc_boolean_t dumping;
09712
09713 REQUIRE(DNS_ZONE_VALID(zone));
09714
09715 LOCK_ZONE(zone);
09716 dumping = was_dumping(zone);
09717 UNLOCK_ZONE(zone);
09718 if (!dumping)
09719 result = zone_dump(zone, ISC_FALSE);
09720 return (result);
09721 }
09722
09723 static void
09724 zone_needdump(dns_zone_t *zone, unsigned int delay) {
09725 const char me[] = "zone_needdump";
09726 isc_time_t dumptime;
09727 isc_time_t now;
09728
09729
09730
09731
09732
09733 REQUIRE(DNS_ZONE_VALID(zone));
09734 REQUIRE(LOCKED_ZONE(zone));
09735 ENTER;
09736
09737
09738
09739
09740 if (zone->masterfile == NULL ||
09741 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0)
09742 return;
09743
09744 TIME_NOW(&now);
09745
09746 DNS_ZONE_JITTER_ADD(&now, delay, &dumptime);
09747
09748 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
09749 if (isc_time_isepoch(&zone->dumptime) ||
09750 isc_time_compare(&zone->dumptime, &dumptime) > 0)
09751 zone->dumptime = dumptime;
09752 if (zone->task != NULL)
09753 zone_settimer(zone, &now);
09754 }
09755
09756 static void
09757 dump_done(void *arg, isc_result_t result) {
09758 const char me[] = "dump_done";
09759 dns_zone_t *zone = arg;
09760 dns_db_t *db;
09761 dns_dbversion_t *version;
09762 isc_boolean_t again = ISC_FALSE;
09763 isc_boolean_t compact = ISC_FALSE;
09764 isc_uint32_t serial;
09765 isc_result_t tresult;
09766
09767 REQUIRE(DNS_ZONE_VALID(zone));
09768
09769 ENTER;
09770
09771 if (result == ISC_R_SUCCESS && zone->journal != NULL &&
09772 zone->journalsize != -1) {
09773
09774
09775
09776
09777 db = dns_dumpctx_db(zone->dctx);
09778 version = dns_dumpctx_version(zone->dctx);
09779
09780 tresult = dns_db_getsoaserial(db, version, &serial);
09781
09782
09783
09784
09785 if (tresult == ISC_R_SUCCESS && inline_raw(zone) &&
09786 zone->secure->db != NULL)
09787 {
09788 isc_uint32_t sserial;
09789 isc_result_t mresult;
09790
09791 mresult = dns_db_getsoaserial(zone->secure->db,
09792 NULL, &sserial);
09793 if (mresult == ISC_R_SUCCESS &&
09794 isc_serial_lt(sserial, serial))
09795 serial = sserial;
09796 }
09797
09798
09799
09800
09801 if (tresult == ISC_R_SUCCESS && zone->xfr == NULL) {
09802 tresult = dns_journal_compact(zone->mctx,
09803 zone->journal,
09804 serial,
09805 zone->journalsize);
09806 switch (tresult) {
09807 case ISC_R_SUCCESS:
09808 case ISC_R_NOSPACE:
09809 case ISC_R_NOTFOUND:
09810 dns_zone_log(zone, ISC_LOG_DEBUG(3),
09811 "dns_journal_compact: %s",
09812 dns_result_totext(tresult));
09813 break;
09814 default:
09815 dns_zone_log(zone, ISC_LOG_ERROR,
09816 "dns_journal_compact failed: %s",
09817 dns_result_totext(tresult));
09818 break;
09819 }
09820 } else if (tresult == ISC_R_SUCCESS) {
09821 compact = ISC_TRUE;
09822 zone->compact_serial = serial;
09823 }
09824 }
09825
09826 LOCK_ZONE(zone);
09827 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING);
09828 if (compact)
09829 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT);
09830 if (result != ISC_R_SUCCESS && result != ISC_R_CANCELED) {
09831
09832
09833
09834 zone_needdump(zone, DNS_DUMP_DELAY);
09835 } else if (result == ISC_R_SUCCESS &&
09836 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) &&
09837 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
09838 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
09839 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
09840 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
09841 isc_time_settoepoch(&zone->dumptime);
09842 again = ISC_TRUE;
09843 } else if (result == ISC_R_SUCCESS)
09844 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH);
09845
09846 if (zone->dctx != NULL)
09847 dns_dumpctx_detach(&zone->dctx);
09848 zonemgr_putio(&zone->writeio);
09849 UNLOCK_ZONE(zone);
09850 if (again)
09851 (void)zone_dump(zone, ISC_FALSE);
09852 dns_zone_idetach(&zone);
09853 }
09854
09855 static isc_result_t
09856 zone_dump(dns_zone_t *zone, isc_boolean_t compact) {
09857 const char me[] = "zone_dump";
09858 isc_result_t result;
09859 dns_dbversion_t *version = NULL;
09860 isc_boolean_t again;
09861 dns_db_t *db = NULL;
09862 char *masterfile = NULL;
09863 dns_masterformat_t masterformat = dns_masterformat_none;
09864
09865
09866
09867
09868
09869 REQUIRE(DNS_ZONE_VALID(zone));
09870 ENTER;
09871
09872 redo:
09873 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
09874 if (zone->db != NULL)
09875 dns_db_attach(zone->db, &db);
09876 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
09877 LOCK_ZONE(zone);
09878 if (zone->masterfile != NULL) {
09879 masterfile = isc_mem_strdup(zone->mctx, zone->masterfile);
09880 masterformat = zone->masterformat;
09881 }
09882 UNLOCK_ZONE(zone);
09883 if (db == NULL) {
09884 result = DNS_R_NOTLOADED;
09885 goto fail;
09886 }
09887 if (masterfile == NULL) {
09888 result = DNS_R_NOMASTERFILE;
09889 goto fail;
09890 }
09891
09892 if (compact && zone->type != dns_zone_stub) {
09893 dns_zone_t *dummy = NULL;
09894 LOCK_ZONE(zone);
09895 zone_iattach(zone, &dummy);
09896 result = zonemgr_getio(zone->zmgr, ISC_FALSE, zone->task,
09897 zone_gotwritehandle, zone,
09898 &zone->writeio);
09899 if (result != ISC_R_SUCCESS)
09900 zone_idetach(&dummy);
09901 else
09902 result = DNS_R_CONTINUE;
09903 UNLOCK_ZONE(zone);
09904 } else {
09905 const dns_master_style_t *output_style;
09906
09907 dns_masterrawheader_t rawdata;
09908 dns_db_currentversion(db, &version);
09909 dns_master_initrawheader(&rawdata);
09910 if (inline_secure(zone))
09911 get_raw_serial(zone->raw, &rawdata);
09912 if (zone->type == dns_zone_key)
09913 output_style = &dns_master_style_keyzone;
09914 else
09915 output_style = &dns_master_style_default;
09916 result = dns_master_dump3(zone->mctx, db, version,
09917 output_style, masterfile,
09918 masterformat, &rawdata);
09919 dns_db_closeversion(db, &version, ISC_FALSE);
09920 }
09921 fail:
09922 if (db != NULL)
09923 dns_db_detach(&db);
09924 if (masterfile != NULL)
09925 isc_mem_free(zone->mctx, masterfile);
09926 masterfile = NULL;
09927
09928 if (result == DNS_R_CONTINUE)
09929 return (ISC_R_SUCCESS);
09930
09931 again = ISC_FALSE;
09932 LOCK_ZONE(zone);
09933 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING);
09934 if (result != ISC_R_SUCCESS) {
09935
09936
09937
09938 zone_needdump(zone, DNS_DUMP_DELAY);
09939 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) &&
09940 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
09941 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
09942 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
09943 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
09944 isc_time_settoepoch(&zone->dumptime);
09945 again = ISC_TRUE;
09946 } else
09947 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH);
09948 UNLOCK_ZONE(zone);
09949 if (again)
09950 goto redo;
09951
09952 return (result);
09953 }
09954
09955 static isc_result_t
09956 dumptostream(dns_zone_t *zone, FILE *fd, const dns_master_style_t *style,
09957 dns_masterformat_t format, const isc_uint32_t rawversion)
09958 {
09959 isc_result_t result;
09960 dns_dbversion_t *version = NULL;
09961 dns_db_t *db = NULL;
09962 dns_masterrawheader_t rawdata;
09963
09964 REQUIRE(DNS_ZONE_VALID(zone));
09965
09966 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
09967 if (zone->db != NULL)
09968 dns_db_attach(zone->db, &db);
09969 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
09970 if (db == NULL)
09971 return (DNS_R_NOTLOADED);
09972
09973 dns_db_currentversion(db, &version);
09974 dns_master_initrawheader(&rawdata);
09975 if (rawversion == 0)
09976 rawdata.flags |= DNS_MASTERRAW_COMPAT;
09977 else if (inline_secure(zone))
09978 get_raw_serial(zone->raw, &rawdata);
09979 else if (zone->sourceserialset) {
09980 rawdata.flags = DNS_MASTERRAW_SOURCESERIALSET;
09981 rawdata.sourceserial = zone->sourceserial;
09982 }
09983 result = dns_master_dumptostream3(zone->mctx, db, version, style,
09984 format, &rawdata, fd);
09985 dns_db_closeversion(db, &version, ISC_FALSE);
09986 dns_db_detach(&db);
09987 return (result);
09988 }
09989
09990 isc_result_t
09991 dns_zone_dumptostream3(dns_zone_t *zone, FILE *fd, dns_masterformat_t format,
09992 const dns_master_style_t *style,
09993 const isc_uint32_t rawversion)
09994 {
09995 return (dumptostream(zone, fd, style, format, rawversion));
09996 }
09997
09998 isc_result_t
09999 dns_zone_dumptostream2(dns_zone_t *zone, FILE *fd, dns_masterformat_t format,
10000 const dns_master_style_t *style) {
10001 return (dumptostream(zone, fd, style, format, DNS_RAWFORMAT_VERSION));
10002 }
10003
10004 isc_result_t
10005 dns_zone_dumptostream(dns_zone_t *zone, FILE *fd) {
10006 return (dumptostream(zone, fd, &dns_master_style_default,
10007 dns_masterformat_text, 0));
10008 }
10009
10010 isc_result_t
10011 dns_zone_fulldumptostream(dns_zone_t *zone, FILE *fd) {
10012 return (dumptostream(zone, fd, &dns_master_style_full,
10013 dns_masterformat_text, 0));
10014 }
10015
10016 void
10017 dns_zone_unload(dns_zone_t *zone) {
10018 REQUIRE(DNS_ZONE_VALID(zone));
10019
10020 LOCK_ZONE(zone);
10021 zone_unload(zone);
10022 UNLOCK_ZONE(zone);
10023 }
10024
10025 static void
10026 notify_cancel(dns_zone_t *zone) {
10027 dns_notify_t *notify;
10028
10029
10030
10031
10032
10033 REQUIRE(LOCKED_ZONE(zone));
10034
10035 for (notify = ISC_LIST_HEAD(zone->notifies);
10036 notify != NULL;
10037 notify = ISC_LIST_NEXT(notify, link)) {
10038 if (notify->find != NULL)
10039 dns_adb_cancelfind(notify->find);
10040 if (notify->request != NULL)
10041 dns_request_cancel(notify->request);
10042 }
10043 }
10044
10045 static void
10046 forward_cancel(dns_zone_t *zone) {
10047 dns_forward_t *forward;
10048
10049
10050
10051
10052
10053 REQUIRE(LOCKED_ZONE(zone));
10054
10055 for (forward = ISC_LIST_HEAD(zone->forwards);
10056 forward != NULL;
10057 forward = ISC_LIST_NEXT(forward, link)) {
10058 if (forward->request != NULL)
10059 dns_request_cancel(forward->request);
10060 }
10061 }
10062
10063 static void
10064 zone_unload(dns_zone_t *zone) {
10065
10066
10067
10068
10069 REQUIRE(LOCKED_ZONE(zone));
10070
10071 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) ||
10072 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
10073 if (zone->writeio != NULL)
10074 zonemgr_cancelio(zone->writeio);
10075
10076 if (zone->dctx != NULL)
10077 dns_dumpctx_cancel(zone->dctx);
10078 }
10079 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
10080 zone_detachdb(zone);
10081 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
10082 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADED);
10083 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
10084 }
10085
10086 void
10087 dns_zone_setminrefreshtime(dns_zone_t *zone, isc_uint32_t val) {
10088 REQUIRE(DNS_ZONE_VALID(zone));
10089 REQUIRE(val > 0);
10090
10091 zone->minrefresh = val;
10092 }
10093
10094 void
10095 dns_zone_setmaxrefreshtime(dns_zone_t *zone, isc_uint32_t val) {
10096 REQUIRE(DNS_ZONE_VALID(zone));
10097 REQUIRE(val > 0);
10098
10099 zone->maxrefresh = val;
10100 }
10101
10102 void
10103 dns_zone_setminretrytime(dns_zone_t *zone, isc_uint32_t val) {
10104 REQUIRE(DNS_ZONE_VALID(zone));
10105 REQUIRE(val > 0);
10106
10107 zone->minretry = val;
10108 }
10109
10110 void
10111 dns_zone_setmaxretrytime(dns_zone_t *zone, isc_uint32_t val) {
10112 REQUIRE(DNS_ZONE_VALID(zone));
10113 REQUIRE(val > 0);
10114
10115 zone->maxretry = val;
10116 }
10117
10118 static isc_boolean_t
10119 notify_isqueued(dns_zone_t *zone, unsigned int flags, dns_name_t *name,
10120 isc_sockaddr_t *addr, dns_tsigkey_t *key)
10121 {
10122 dns_notify_t *notify;
10123 dns_zonemgr_t *zmgr;
10124 isc_result_t result;
10125
10126 for (notify = ISC_LIST_HEAD(zone->notifies);
10127 notify != NULL;
10128 notify = ISC_LIST_NEXT(notify, link)) {
10129 if (notify->request != NULL)
10130 continue;
10131 if ((flags & DNS_NOTIFY_STARTUP) == 0)
10132 notify->flags &= ~DNS_NOTIFY_STARTUP;
10133 if (name != NULL && dns_name_dynamic(¬ify->ns) &&
10134 dns_name_equal(name, ¬ify->ns))
10135 goto requeue;
10136 if (addr != NULL && isc_sockaddr_equal(addr, ¬ify->dst) &&
10137 notify->key == key)
10138 goto requeue;
10139 }
10140 return (ISC_FALSE);
10141
10142 requeue:
10143
10144
10145
10146
10147
10148 if (notify->event != NULL && (flags & DNS_NOTIFY_STARTUP) == 0) {
10149 zmgr = notify->zone->zmgr;
10150 result = isc_ratelimiter_dequeue(zmgr->startupnotifyrl,
10151 notify->event);
10152 if (result != ISC_R_SUCCESS)
10153 return (ISC_TRUE);
10154 result = isc_ratelimiter_enqueue(notify->zone->zmgr->notifyrl,
10155 notify->zone->task,
10156 ¬ify->event);
10157 if (result != ISC_R_SUCCESS) {
10158 isc_event_free(¬ify->event);
10159 return (ISC_FALSE);
10160 }
10161 }
10162
10163 return (ISC_TRUE);
10164 }
10165
10166 static isc_boolean_t
10167 notify_isself(dns_zone_t *zone, isc_sockaddr_t *dst) {
10168 dns_tsigkey_t *key = NULL;
10169 isc_sockaddr_t src;
10170 isc_sockaddr_t any;
10171 isc_boolean_t isself;
10172 isc_netaddr_t dstaddr;
10173 isc_result_t result;
10174
10175 if (zone->view == NULL || zone->isself == NULL)
10176 return (ISC_FALSE);
10177
10178 switch (isc_sockaddr_pf(dst)) {
10179 case PF_INET:
10180 src = zone->notifysrc4;
10181 isc_sockaddr_any(&any);
10182 break;
10183 case PF_INET6:
10184 src = zone->notifysrc6;
10185 isc_sockaddr_any6(&any);
10186 break;
10187 default:
10188 return (ISC_FALSE);
10189 }
10190
10191
10192
10193
10194
10195 if (isc_sockaddr_eqaddr(&any, &src))
10196 src = *dst;
10197
10198 isc_netaddr_fromsockaddr(&dstaddr, dst);
10199 result = dns_view_getpeertsig(zone->view, &dstaddr, &key);
10200 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
10201 return (ISC_FALSE);
10202 isself = (zone->isself)(zone->view, key, &src, dst, zone->rdclass,
10203 zone->isselfarg);
10204 if (key != NULL)
10205 dns_tsigkey_detach(&key);
10206 return (isself);
10207 }
10208
10209 static void
10210 notify_destroy(dns_notify_t *notify, isc_boolean_t locked) {
10211 isc_mem_t *mctx;
10212
10213 REQUIRE(DNS_NOTIFY_VALID(notify));
10214
10215 if (notify->zone != NULL) {
10216 if (!locked)
10217 LOCK_ZONE(notify->zone);
10218 REQUIRE(LOCKED_ZONE(notify->zone));
10219 if (ISC_LINK_LINKED(notify, link))
10220 ISC_LIST_UNLINK(notify->zone->notifies, notify, link);
10221 if (!locked)
10222 UNLOCK_ZONE(notify->zone);
10223 if (locked)
10224 zone_idetach(¬ify->zone);
10225 else
10226 dns_zone_idetach(¬ify->zone);
10227 }
10228 if (notify->find != NULL)
10229 dns_adb_destroyfind(¬ify->find);
10230 if (notify->request != NULL)
10231 dns_request_destroy(¬ify->request);
10232 if (dns_name_dynamic(¬ify->ns))
10233 dns_name_free(¬ify->ns, notify->mctx);
10234 if (notify->key != NULL)
10235 dns_tsigkey_detach(¬ify->key);
10236 mctx = notify->mctx;
10237 isc_mem_put(notify->mctx, notify, sizeof(*notify));
10238 isc_mem_detach(&mctx);
10239 }
10240
10241 static isc_result_t
10242 notify_create(isc_mem_t *mctx, unsigned int flags, dns_notify_t **notifyp) {
10243 dns_notify_t *notify;
10244
10245 REQUIRE(notifyp != NULL && *notifyp == NULL);
10246
10247 notify = isc_mem_get(mctx, sizeof(*notify));
10248 if (notify == NULL)
10249 return (ISC_R_NOMEMORY);
10250
10251 notify->mctx = NULL;
10252 isc_mem_attach(mctx, ¬ify->mctx);
10253 notify->flags = flags;
10254 notify->zone = NULL;
10255 notify->find = NULL;
10256 notify->request = NULL;
10257 notify->key = NULL;
10258 notify->event = NULL;
10259 isc_sockaddr_any(¬ify->dst);
10260 dns_name_init(¬ify->ns, NULL);
10261 ISC_LINK_INIT(notify, link);
10262 notify->magic = NOTIFY_MAGIC;
10263 *notifyp = notify;
10264 return (ISC_R_SUCCESS);
10265 }
10266
10267
10268
10269
10270 static void
10271 process_adb_event(isc_task_t *task, isc_event_t *ev) {
10272 dns_notify_t *notify;
10273 isc_eventtype_t result;
10274
10275 UNUSED(task);
10276
10277 notify = ev->ev_arg;
10278 REQUIRE(DNS_NOTIFY_VALID(notify));
10279 INSIST(task == notify->zone->task);
10280 result = ev->ev_type;
10281 isc_event_free(&ev);
10282 if (result == DNS_EVENT_ADBMOREADDRESSES) {
10283 dns_adb_destroyfind(¬ify->find);
10284 notify_find_address(notify);
10285 return;
10286 }
10287 if (result == DNS_EVENT_ADBNOMOREADDRESSES) {
10288 LOCK_ZONE(notify->zone);
10289 notify_send(notify);
10290 UNLOCK_ZONE(notify->zone);
10291 }
10292 notify_destroy(notify, ISC_FALSE);
10293 }
10294
10295 static void
10296 notify_find_address(dns_notify_t *notify) {
10297 isc_result_t result;
10298 unsigned int options;
10299
10300 REQUIRE(DNS_NOTIFY_VALID(notify));
10301 options = DNS_ADBFIND_WANTEVENT | DNS_ADBFIND_INET |
10302 DNS_ADBFIND_INET6 | DNS_ADBFIND_RETURNLAME;
10303
10304 if (notify->zone->view->adb == NULL)
10305 goto destroy;
10306
10307 result = dns_adb_createfind(notify->zone->view->adb,
10308 notify->zone->task,
10309 process_adb_event, notify,
10310 ¬ify->ns, dns_rootname, 0,
10311 options, 0, NULL,
10312 notify->zone->view->dstport,
10313 ¬ify->find);
10314
10315
10316 if (result != ISC_R_SUCCESS)
10317 goto destroy;
10318
10319
10320 if ((notify->find->options & DNS_ADBFIND_WANTEVENT) != 0)
10321 return;
10322
10323
10324 LOCK_ZONE(notify->zone);
10325 notify_send(notify);
10326 UNLOCK_ZONE(notify->zone);
10327
10328 destroy:
10329 notify_destroy(notify, ISC_FALSE);
10330 }
10331
10332
10333 static isc_result_t
10334 notify_send_queue(dns_notify_t *notify, isc_boolean_t startup) {
10335 isc_event_t *e;
10336 isc_result_t result;
10337
10338 INSIST(notify->event == NULL);
10339 e = isc_event_allocate(notify->mctx, NULL, DNS_EVENT_NOTIFYSENDTOADDR,
10340 notify_send_toaddr, notify, sizeof(isc_event_t));
10341 if (e == NULL)
10342 return (ISC_R_NOMEMORY);
10343 if (startup)
10344 notify->event = e;
10345 e->ev_arg = notify;
10346 e->ev_sender = NULL;
10347 result = isc_ratelimiter_enqueue(startup
10348 ? notify->zone->zmgr->startupnotifyrl
10349 : notify->zone->zmgr->notifyrl,
10350 notify->zone->task, &e);
10351 if (result != ISC_R_SUCCESS) {
10352 isc_event_free(&e);
10353 notify->event = NULL;
10354 }
10355 return (result);
10356 }
10357
10358 static void
10359 notify_send_toaddr(isc_task_t *task, isc_event_t *event) {
10360 dns_notify_t *notify;
10361 isc_result_t result;
10362 dns_message_t *message = NULL;
10363 isc_netaddr_t dstip;
10364 dns_tsigkey_t *key = NULL;
10365 char addrbuf[ISC_SOCKADDR_FORMATSIZE];
10366 isc_sockaddr_t src;
10367 unsigned int options, timeout;
10368 isc_boolean_t have_notifysource = ISC_FALSE;
10369 isc_boolean_t have_notifydscp = ISC_FALSE;
10370 isc_dscp_t dscp = -1;
10371
10372 notify = event->ev_arg;
10373 REQUIRE(DNS_NOTIFY_VALID(notify));
10374
10375 UNUSED(task);
10376
10377 LOCK_ZONE(notify->zone);
10378
10379 notify->event = NULL;
10380
10381 if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_LOADED) == 0) {
10382 result = ISC_R_CANCELED;
10383 goto cleanup;
10384 }
10385
10386 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0 ||
10387 DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_EXITING) ||
10388 notify->zone->view->requestmgr == NULL ||
10389 notify->zone->db == NULL) {
10390 result = ISC_R_CANCELED;
10391 goto cleanup;
10392 }
10393
10394
10395
10396
10397
10398 if (isc_sockaddr_pf(¬ify->dst) == PF_INET6 &&
10399 IN6_IS_ADDR_V4MAPPED(¬ify->dst.type.sin6.sin6_addr)) {
10400 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf));
10401 notify_log(notify->zone, ISC_LOG_DEBUG(3),
10402 "notify: ignoring IPv6 mapped IPV4 address: %s",
10403 addrbuf);
10404 result = ISC_R_CANCELED;
10405 goto cleanup;
10406 }
10407
10408 result = notify_createmessage(notify->zone, notify->flags, &message);
10409 if (result != ISC_R_SUCCESS)
10410 goto cleanup;
10411
10412 if (notify->key != NULL) {
10413
10414 key = notify->key;
10415 notify->key = NULL;
10416 } else {
10417 isc_netaddr_fromsockaddr(&dstip, ¬ify->dst);
10418 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf));
10419 result = dns_view_getpeertsig(notify->zone->view, &dstip, &key);
10420 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
10421 notify_log(notify->zone, ISC_LOG_ERROR,
10422 "NOTIFY to %s not sent. "
10423 "Peer TSIG key lookup failure.", addrbuf);
10424 goto cleanup_message;
10425 }
10426 }
10427
10428
10429 notify_log(notify->zone, ISC_LOG_DEBUG(3), "sending notify to %s",
10430 addrbuf);
10431 options = 0;
10432 if (notify->zone->view->peers != NULL) {
10433 dns_peer_t *peer = NULL;
10434 isc_boolean_t usetcp = ISC_FALSE;
10435 result = dns_peerlist_peerbyaddr(notify->zone->view->peers,
10436 &dstip, &peer);
10437 if (result == ISC_R_SUCCESS) {
10438 result = dns_peer_getnotifysource(peer, &src);
10439 if (result == ISC_R_SUCCESS)
10440 have_notifysource = ISC_TRUE;
10441 dns_peer_getnotifydscp(peer, &dscp);
10442 if (dscp != -1)
10443 have_notifydscp = ISC_TRUE;
10444 result = dns_peer_getforcetcp(peer, &usetcp);
10445 if (result == ISC_R_SUCCESS && usetcp)
10446 options |= DNS_FETCHOPT_TCP;
10447 }
10448 }
10449 switch (isc_sockaddr_pf(¬ify->dst)) {
10450 case PF_INET:
10451 if (!have_notifysource)
10452 src = notify->zone->notifysrc4;
10453 if (!have_notifydscp)
10454 dscp = notify->zone->notifysrc4dscp;
10455 break;
10456 case PF_INET6:
10457 if (!have_notifysource)
10458 src = notify->zone->notifysrc6;
10459 if (!have_notifydscp)
10460 dscp = notify->zone->notifysrc6dscp;
10461 break;
10462 default:
10463 result = ISC_R_NOTIMPLEMENTED;
10464 goto cleanup_key;
10465 }
10466 timeout = 15;
10467 if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_DIALNOTIFY))
10468 timeout = 30;
10469 result = dns_request_createvia4(notify->zone->view->requestmgr,
10470 message, &src, ¬ify->dst, dscp,
10471 options, key, timeout * 3, timeout,
10472 0, notify->zone->task, notify_done,
10473 notify, ¬ify->request);
10474 if (result == ISC_R_SUCCESS) {
10475 if (isc_sockaddr_pf(¬ify->dst) == AF_INET) {
10476 inc_stats(notify->zone,
10477 dns_zonestatscounter_notifyoutv4);
10478 } else {
10479 inc_stats(notify->zone,
10480 dns_zonestatscounter_notifyoutv6);
10481 }
10482 }
10483
10484 cleanup_key:
10485 if (key != NULL)
10486 dns_tsigkey_detach(&key);
10487 cleanup_message:
10488 dns_message_destroy(&message);
10489 cleanup:
10490 UNLOCK_ZONE(notify->zone);
10491 isc_event_free(&event);
10492 if (result != ISC_R_SUCCESS)
10493 notify_destroy(notify, ISC_FALSE);
10494 }
10495
10496 static void
10497 notify_send(dns_notify_t *notify) {
10498 dns_adbaddrinfo_t *ai;
10499 isc_sockaddr_t dst;
10500 isc_result_t result;
10501 dns_notify_t *new = NULL;
10502 unsigned int flags;
10503 isc_boolean_t startup;
10504
10505
10506
10507
10508 REQUIRE(DNS_NOTIFY_VALID(notify));
10509 REQUIRE(LOCKED_ZONE(notify->zone));
10510
10511 for (ai = ISC_LIST_HEAD(notify->find->list);
10512 ai != NULL;
10513 ai = ISC_LIST_NEXT(ai, publink)) {
10514 dst = ai->sockaddr;
10515 if (notify_isqueued(notify->zone, notify->flags, NULL, &dst,
10516 NULL))
10517 continue;
10518 if (notify_isself(notify->zone, &dst))
10519 continue;
10520 new = NULL;
10521 flags = notify->flags & DNS_NOTIFY_NOSOA;
10522 result = notify_create(notify->mctx, flags, &new);
10523 if (result != ISC_R_SUCCESS)
10524 goto cleanup;
10525 zone_iattach(notify->zone, &new->zone);
10526 ISC_LIST_APPEND(new->zone->notifies, new, link);
10527 new->dst = dst;
10528 startup = ISC_TF((notify->flags & DNS_NOTIFY_STARTUP) != 0);
10529 result = notify_send_queue(new, startup);
10530 if (result != ISC_R_SUCCESS)
10531 goto cleanup;
10532 new = NULL;
10533 }
10534
10535 cleanup:
10536 if (new != NULL)
10537 notify_destroy(new, ISC_TRUE);
10538 }
10539
10540 void
10541 dns_zone_notify(dns_zone_t *zone) {
10542 isc_time_t now;
10543
10544 REQUIRE(DNS_ZONE_VALID(zone));
10545
10546 LOCK_ZONE(zone);
10547 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
10548
10549 TIME_NOW(&now);
10550 zone_settimer(zone, &now);
10551 UNLOCK_ZONE(zone);
10552 }
10553
10554 static void
10555 zone_notify(dns_zone_t *zone, isc_time_t *now) {
10556 dns_dbnode_t *node = NULL;
10557 dns_db_t *zonedb = NULL;
10558 dns_dbversion_t *version = NULL;
10559 dns_name_t *origin = NULL;
10560 dns_name_t master;
10561 dns_rdata_ns_t ns;
10562 dns_rdata_soa_t soa;
10563 isc_uint32_t serial;
10564 dns_rdata_t rdata = DNS_RDATA_INIT;
10565 dns_rdataset_t nsrdset;
10566 dns_rdataset_t soardset;
10567 isc_result_t result;
10568 unsigned int i;
10569 isc_sockaddr_t dst;
10570 isc_boolean_t isqueued;
10571 dns_notifytype_t notifytype;
10572 unsigned int flags = 0;
10573 isc_boolean_t loggednotify = ISC_FALSE;
10574 isc_boolean_t startup;
10575
10576 REQUIRE(DNS_ZONE_VALID(zone));
10577
10578 LOCK_ZONE(zone);
10579 startup = !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
10580 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
10581 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY);
10582 notifytype = zone->notifytype;
10583 DNS_ZONE_TIME_ADD(now, zone->notifydelay, &zone->notifytime);
10584 UNLOCK_ZONE(zone);
10585
10586 if (! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
10587 return;
10588
10589 if (notifytype == dns_notifytype_no)
10590 return;
10591
10592 if (notifytype == dns_notifytype_masteronly &&
10593 zone->type != dns_zone_master)
10594 return;
10595
10596 origin = &zone->origin;
10597
10598
10599
10600
10601
10602 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY))
10603 flags |= DNS_NOTIFY_NOSOA;
10604
10605
10606
10607
10608 if (startup)
10609 flags |= DNS_NOTIFY_STARTUP;
10610
10611
10612
10613
10614 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
10615 if (zone->db != NULL)
10616 dns_db_attach(zone->db, &zonedb);
10617 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
10618 if (zonedb == NULL)
10619 return;
10620 dns_db_currentversion(zonedb, &version);
10621 result = dns_db_findnode(zonedb, origin, ISC_FALSE, &node);
10622 if (result != ISC_R_SUCCESS)
10623 goto cleanup1;
10624
10625 dns_rdataset_init(&soardset);
10626 result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_soa,
10627 dns_rdatatype_none, 0, &soardset, NULL);
10628 if (result != ISC_R_SUCCESS)
10629 goto cleanup2;
10630
10631
10632
10633
10634 dns_name_init(&master, NULL);
10635 result = dns_rdataset_first(&soardset);
10636 if (result != ISC_R_SUCCESS)
10637 goto cleanup3;
10638 dns_rdataset_current(&soardset, &rdata);
10639 result = dns_rdata_tostruct(&rdata, &soa, NULL);
10640 RUNTIME_CHECK(result == ISC_R_SUCCESS);
10641 dns_rdata_reset(&rdata);
10642 result = dns_name_dup(&soa.origin, zone->mctx, &master);
10643 serial = soa.serial;
10644 dns_rdataset_disassociate(&soardset);
10645 if (result != ISC_R_SUCCESS)
10646 goto cleanup3;
10647
10648
10649
10650
10651 LOCK_ZONE(zone);
10652 for (i = 0; i < zone->notifycnt; i++) {
10653 dns_tsigkey_t *key = NULL;
10654 dns_notify_t *notify = NULL;
10655
10656 if ((zone->notifykeynames != NULL) &&
10657 (zone->notifykeynames[i] != NULL)) {
10658 dns_view_t *view = dns_zone_getview(zone);
10659 dns_name_t *keyname = zone->notifykeynames[i];
10660 (void)dns_view_gettsig(view, keyname, &key);
10661 }
10662
10663 dst = zone->notify[i];
10664 if (notify_isqueued(zone, flags, NULL, &dst, key)) {
10665 if (key != NULL)
10666 dns_tsigkey_detach(&key);
10667 continue;
10668 }
10669
10670 result = notify_create(zone->mctx, flags, ¬ify);
10671 if (result != ISC_R_SUCCESS) {
10672 if (key != NULL)
10673 dns_tsigkey_detach(&key);
10674 continue;
10675 }
10676
10677 zone_iattach(zone, ¬ify->zone);
10678 notify->dst = dst;
10679
10680 INSIST(notify->key == NULL);
10681
10682 if (key != NULL) {
10683 notify->key = key;
10684 key = NULL;
10685 }
10686
10687 ISC_LIST_APPEND(zone->notifies, notify, link);
10688 result = notify_send_queue(notify, startup);
10689 if (result != ISC_R_SUCCESS)
10690 notify_destroy(notify, ISC_TRUE);
10691 if (!loggednotify) {
10692 notify_log(zone, ISC_LOG_INFO,
10693 "sending notifies (serial %u)",
10694 serial);
10695 loggednotify = ISC_TRUE;
10696 }
10697 }
10698 UNLOCK_ZONE(zone);
10699
10700 if (notifytype == dns_notifytype_explicit)
10701 goto cleanup3;
10702
10703
10704
10705
10706
10707 dns_rdataset_init(&nsrdset);
10708 result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_ns,
10709 dns_rdatatype_none, 0, &nsrdset, NULL);
10710 if (result != ISC_R_SUCCESS)
10711 goto cleanup3;
10712
10713 result = dns_rdataset_first(&nsrdset);
10714 while (result == ISC_R_SUCCESS) {
10715 dns_notify_t *notify = NULL;
10716
10717 dns_rdataset_current(&nsrdset, &rdata);
10718 result = dns_rdata_tostruct(&rdata, &ns, NULL);
10719 RUNTIME_CHECK(result == ISC_R_SUCCESS);
10720 dns_rdata_reset(&rdata);
10721
10722
10723
10724
10725 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOTIFYTOSOA) &&
10726 dns_name_compare(&master, &ns.name) == 0) {
10727 result = dns_rdataset_next(&nsrdset);
10728 continue;
10729 }
10730
10731 if (!loggednotify) {
10732 notify_log(zone, ISC_LOG_INFO,
10733 "sending notifies (serial %u)",
10734 serial);
10735 loggednotify = ISC_TRUE;
10736 }
10737
10738 LOCK_ZONE(zone);
10739 isqueued = notify_isqueued(zone, flags, &ns.name, NULL, NULL);
10740 UNLOCK_ZONE(zone);
10741 if (isqueued) {
10742 result = dns_rdataset_next(&nsrdset);
10743 continue;
10744 }
10745 result = notify_create(zone->mctx, flags, ¬ify);
10746 if (result != ISC_R_SUCCESS)
10747 continue;
10748 dns_zone_iattach(zone, ¬ify->zone);
10749 result = dns_name_dup(&ns.name, zone->mctx, ¬ify->ns);
10750 if (result != ISC_R_SUCCESS) {
10751 LOCK_ZONE(zone);
10752 notify_destroy(notify, ISC_TRUE);
10753 UNLOCK_ZONE(zone);
10754 continue;
10755 }
10756 LOCK_ZONE(zone);
10757 ISC_LIST_APPEND(zone->notifies, notify, link);
10758 UNLOCK_ZONE(zone);
10759 notify_find_address(notify);
10760 result = dns_rdataset_next(&nsrdset);
10761 }
10762 dns_rdataset_disassociate(&nsrdset);
10763
10764 cleanup3:
10765 if (dns_name_dynamic(&master))
10766 dns_name_free(&master, zone->mctx);
10767 cleanup2:
10768 dns_db_detachnode(zonedb, &node);
10769 cleanup1:
10770 dns_db_closeversion(zonedb, &version, ISC_FALSE);
10771 dns_db_detach(&zonedb);
10772 }
10773
10774
10775
10776
10777
10778 static inline isc_result_t
10779 save_nsrrset(dns_message_t *message, dns_name_t *name,
10780 dns_db_t *db, dns_dbversion_t *version)
10781 {
10782 dns_rdataset_t *nsrdataset = NULL;
10783 dns_rdataset_t *rdataset = NULL;
10784 dns_dbnode_t *node = NULL;
10785 dns_rdata_ns_t ns;
10786 isc_result_t result;
10787 dns_rdata_t rdata = DNS_RDATA_INIT;
10788
10789
10790
10791
10792 result = dns_message_findname(message, DNS_SECTION_ANSWER, name,
10793 dns_rdatatype_ns, dns_rdatatype_none,
10794 NULL, &nsrdataset);
10795 if (result != ISC_R_SUCCESS)
10796 goto fail;
10797
10798
10799
10800
10801 result = dns_db_findnode(db, name, ISC_TRUE, &node);
10802 if (result != ISC_R_SUCCESS)
10803 goto fail;
10804 result = dns_db_addrdataset(db, node, version, 0,
10805 nsrdataset, 0, NULL);
10806 dns_db_detachnode(db, &node);
10807 if (result != ISC_R_SUCCESS)
10808 goto fail;
10809
10810
10811
10812 for (result = dns_rdataset_first(nsrdataset);
10813 result == ISC_R_SUCCESS;
10814 result = dns_rdataset_next(nsrdataset)) {
10815 dns_rdataset_current(nsrdataset, &rdata);
10816 result = dns_rdata_tostruct(&rdata, &ns, NULL);
10817 RUNTIME_CHECK(result == ISC_R_SUCCESS);
10818 dns_rdata_reset(&rdata);
10819 if (!dns_name_issubdomain(&ns.name, name))
10820 continue;
10821 rdataset = NULL;
10822 result = dns_message_findname(message, DNS_SECTION_ADDITIONAL,
10823 &ns.name, dns_rdatatype_aaaa,
10824 dns_rdatatype_none, NULL,
10825 &rdataset);
10826 if (result == ISC_R_SUCCESS) {
10827 result = dns_db_findnode(db, &ns.name,
10828 ISC_TRUE, &node);
10829 if (result != ISC_R_SUCCESS)
10830 goto fail;
10831 result = dns_db_addrdataset(db, node, version, 0,
10832 rdataset, 0, NULL);
10833 dns_db_detachnode(db, &node);
10834 if (result != ISC_R_SUCCESS)
10835 goto fail;
10836 }
10837 rdataset = NULL;
10838 result = dns_message_findname(message, DNS_SECTION_ADDITIONAL,
10839 &ns.name, dns_rdatatype_a,
10840 dns_rdatatype_none, NULL,
10841 &rdataset);
10842 if (result == ISC_R_SUCCESS) {
10843 result = dns_db_findnode(db, &ns.name,
10844 ISC_TRUE, &node);
10845 if (result != ISC_R_SUCCESS)
10846 goto fail;
10847 result = dns_db_addrdataset(db, node, version, 0,
10848 rdataset, 0, NULL);
10849 dns_db_detachnode(db, &node);
10850 if (result != ISC_R_SUCCESS)
10851 goto fail;
10852 }
10853 }
10854 if (result != ISC_R_NOMORE)
10855 goto fail;
10856
10857 return (ISC_R_SUCCESS);
10858
10859 fail:
10860 return (result);
10861 }
10862
10863 static void
10864 stub_callback(isc_task_t *task, isc_event_t *event) {
10865 const char me[] = "stub_callback";
10866 dns_requestevent_t *revent = (dns_requestevent_t *)event;
10867 dns_stub_t *stub = NULL;
10868 dns_message_t *msg = NULL;
10869 dns_zone_t *zone = NULL;
10870 char master[ISC_SOCKADDR_FORMATSIZE];
10871 char source[ISC_SOCKADDR_FORMATSIZE];
10872 isc_uint32_t nscnt, cnamecnt, refresh, retry, expire;
10873 isc_result_t result;
10874 isc_time_t now;
10875 isc_boolean_t exiting = ISC_FALSE;
10876 isc_interval_t i;
10877 unsigned int j, soacount;
10878
10879 stub = revent->ev_arg;
10880 INSIST(DNS_STUB_VALID(stub));
10881
10882 UNUSED(task);
10883
10884 zone = stub->zone;
10885
10886 ENTER;
10887
10888 TIME_NOW(&now);
10889
10890 LOCK_ZONE(zone);
10891
10892 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
10893 zone_debuglog(zone, me, 1, "exiting");
10894 exiting = ISC_TRUE;
10895 goto next_master;
10896 }
10897
10898 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
10899 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
10900
10901 if (revent->result != ISC_R_SUCCESS) {
10902 if (revent->result == ISC_R_TIMEDOUT &&
10903 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
10904 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
10905 dns_zone_log(zone, ISC_LOG_DEBUG(1),
10906 "refreshing stub: timeout retrying "
10907 " without EDNS master %s (source %s)",
10908 master, source);
10909 goto same_master;
10910 }
10911 dns_zonemgr_unreachableadd(zone->zmgr, &zone->masteraddr,
10912 &zone->sourceaddr, &now);
10913 dns_zone_log(zone, ISC_LOG_INFO,
10914 "could not refresh stub from master %s"
10915 " (source %s): %s", master, source,
10916 dns_result_totext(revent->result));
10917 goto next_master;
10918 }
10919
10920 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
10921 if (result != ISC_R_SUCCESS)
10922 goto next_master;
10923
10924 result = dns_request_getresponse(revent->request, msg, 0);
10925 if (result != ISC_R_SUCCESS)
10926 goto next_master;
10927
10928
10929
10930
10931 if (msg->rcode != dns_rcode_noerror) {
10932 char rcode[128];
10933 isc_buffer_t rb;
10934
10935 isc_buffer_init(&rb, rcode, sizeof(rcode));
10936 (void)dns_rcode_totext(msg->rcode, &rb);
10937
10938 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) &&
10939 (msg->rcode == dns_rcode_servfail ||
10940 msg->rcode == dns_rcode_notimp ||
10941 msg->rcode == dns_rcode_formerr)) {
10942 dns_zone_log(zone, ISC_LOG_DEBUG(1),
10943 "refreshing stub: rcode (%.*s) retrying "
10944 "without EDNS master %s (source %s)",
10945 (int)rb.used, rcode, master, source);
10946 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
10947 goto same_master;
10948 }
10949
10950 dns_zone_log(zone, ISC_LOG_INFO,
10951 "refreshing stub: "
10952 "unexpected rcode (%.*s) from %s (source %s)",
10953 (int)rb.used, rcode, master, source);
10954 goto next_master;
10955 }
10956
10957
10958
10959
10960 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) {
10961 if (dns_request_usedtcp(revent->request)) {
10962 dns_zone_log(zone, ISC_LOG_INFO,
10963 "refreshing stub: truncated TCP "
10964 "response from master %s (source %s)",
10965 master, source);
10966 goto next_master;
10967 }
10968 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC);
10969 goto same_master;
10970 }
10971
10972
10973
10974
10975 if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
10976 dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: "
10977 "non-authoritative answer from "
10978 "master %s (source %s)", master, source);
10979 goto next_master;
10980 }
10981
10982
10983
10984
10985 cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname);
10986 nscnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_ns);
10987
10988 if (cnamecnt != 0) {
10989 dns_zone_log(zone, ISC_LOG_INFO,
10990 "refreshing stub: unexpected CNAME response "
10991 "from master %s (source %s)", master, source);
10992 goto next_master;
10993 }
10994
10995 if (nscnt == 0) {
10996 dns_zone_log(zone, ISC_LOG_INFO,
10997 "refreshing stub: no NS records in response "
10998 "from master %s (source %s)", master, source);
10999 goto next_master;
11000 }
11001
11002
11003
11004
11005 result = save_nsrrset(msg, &zone->origin, stub->db, stub->version);
11006 if (result != ISC_R_SUCCESS) {
11007 dns_zone_log(zone, ISC_LOG_INFO,
11008 "refreshing stub: unable to save NS records "
11009 "from master %s (source %s)", master, source);
11010 goto next_master;
11011 }
11012
11013
11014
11015
11016 dns_db_closeversion(stub->db, &stub->version, ISC_TRUE);
11017 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
11018 if (zone->db == NULL)
11019 zone_attachdb(zone, stub->db);
11020 result = zone_get_from_db(zone, zone->db, NULL, &soacount, NULL,
11021 &refresh, &retry, &expire, NULL, NULL);
11022 if (result == ISC_R_SUCCESS && soacount > 0U) {
11023 zone->refresh = RANGE(refresh, zone->minrefresh,
11024 zone->maxrefresh);
11025 zone->retry = RANGE(retry, zone->minretry, zone->maxretry);
11026 zone->expire = RANGE(expire, zone->refresh + zone->retry,
11027 DNS_MAX_EXPIRE);
11028 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
11029 }
11030 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
11031 dns_db_detach(&stub->db);
11032
11033 dns_message_destroy(&msg);
11034 isc_event_free(&event);
11035 dns_request_destroy(&zone->request);
11036
11037 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
11038 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
11039 DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime);
11040 isc_interval_set(&i, zone->expire, 0);
11041 DNS_ZONE_TIME_ADD(&now, zone->expire, &zone->expiretime);
11042
11043 if (zone->masterfile != NULL)
11044 zone_needdump(zone, 0);
11045
11046 zone_settimer(zone, &now);
11047 goto free_stub;
11048
11049 next_master:
11050 if (stub->version != NULL)
11051 dns_db_closeversion(stub->db, &stub->version, ISC_FALSE);
11052 if (stub->db != NULL)
11053 dns_db_detach(&stub->db);
11054 if (msg != NULL)
11055 dns_message_destroy(&msg);
11056 isc_event_free(&event);
11057 dns_request_destroy(&zone->request);
11058
11059
11060
11061 do {
11062 zone->curmaster++;
11063 } while (zone->curmaster < zone->masterscnt &&
11064 zone->mastersok[zone->curmaster]);
11065 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
11066 if (exiting || zone->curmaster >= zone->masterscnt) {
11067 isc_boolean_t done = ISC_TRUE;
11068 if (!exiting &&
11069 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
11070 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
11071
11072
11073
11074 for (j = 0; j < zone->masterscnt; j++)
11075 if (zone->mastersok[j] == ISC_FALSE) {
11076 done = ISC_FALSE;
11077 break;
11078 }
11079 } else
11080 done = ISC_TRUE;
11081 if (!done) {
11082 zone->curmaster = 0;
11083
11084
11085
11086 while (zone->curmaster < zone->masterscnt &&
11087 zone->mastersok[zone->curmaster])
11088 zone->curmaster++;
11089 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
11090 } else {
11091 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
11092
11093 zone_settimer(zone, &now);
11094 goto free_stub;
11095 }
11096 }
11097 queue_soa_query(zone);
11098 goto free_stub;
11099
11100 same_master:
11101 if (msg != NULL)
11102 dns_message_destroy(&msg);
11103 isc_event_free(&event);
11104 dns_request_destroy(&zone->request);
11105 ns_query(zone, NULL, stub);
11106 UNLOCK_ZONE(zone);
11107 goto done;
11108
11109 free_stub:
11110 UNLOCK_ZONE(zone);
11111 stub->magic = 0;
11112 dns_zone_idetach(&stub->zone);
11113 INSIST(stub->db == NULL);
11114 INSIST(stub->version == NULL);
11115 isc_mem_put(stub->mctx, stub, sizeof(*stub));
11116
11117 done:
11118 INSIST(event == NULL);
11119 return;
11120 }
11121
11122
11123
11124
11125
11126 static void
11127 get_edns_expire(dns_zone_t * zone, dns_message_t *message,
11128 isc_uint32_t *expirep)
11129 {
11130 isc_result_t result;
11131 isc_uint32_t expire;
11132 dns_rdata_t rdata = DNS_RDATA_INIT;
11133 isc_buffer_t optbuf;
11134 isc_uint16_t optcode;
11135 isc_uint16_t optlen;
11136
11137 REQUIRE(expirep != NULL);
11138 REQUIRE(message != NULL);
11139
11140 if (message->opt == NULL)
11141 return;
11142
11143 result = dns_rdataset_first(message->opt);
11144 if (result == ISC_R_SUCCESS) {
11145 dns_rdataset_current(message->opt, &rdata);
11146 isc_buffer_init(&optbuf, rdata.data, rdata.length);
11147 isc_buffer_add(&optbuf, rdata.length);
11148 while (isc_buffer_remaininglength(&optbuf) >= 4) {
11149 optcode = isc_buffer_getuint16(&optbuf);
11150 optlen = isc_buffer_getuint16(&optbuf);
11151
11152
11153
11154 if (optcode != DNS_OPT_EXPIRE || optlen != 4) {
11155 isc_buffer_forward(&optbuf, optlen);
11156 continue;
11157 }
11158 expire = isc_buffer_getuint32(&optbuf);
11159 dns_zone_log(zone, ISC_LOG_DEBUG(1),
11160 "got EDNS EXPIRE of %u\n", expire);
11161
11162
11163
11164 if (expire < *expirep)
11165 *expirep = expire;
11166 break;
11167 }
11168 }
11169 }
11170
11171
11172
11173
11174 static void
11175 setmodtime(dns_zone_t *zone, isc_time_t *expiretime) {
11176 isc_result_t result;
11177 isc_time_t when;
11178 isc_interval_t i;
11179
11180 isc_interval_set(&i, zone->expire, 0);
11181 result = isc_time_subtract(expiretime, &i, &when);
11182 if (result != ISC_R_SUCCESS)
11183 return;
11184
11185 result = ISC_R_FAILURE;
11186 if (zone->journal != NULL)
11187 result = isc_file_settime(zone->journal, &when);
11188 if (result == ISC_R_SUCCESS &&
11189 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
11190 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP))
11191 result = isc_file_settime(zone->masterfile, &when);
11192 else if (result != ISC_R_SUCCESS)
11193 result = isc_file_settime(zone->masterfile, &when);
11194
11195
11196
11197
11198 if (result == ISC_R_FILENOTFOUND) {
11199 zone_needdump(zone, DNS_DUMP_DELAY);
11200 } else if (result != ISC_R_SUCCESS)
11201 dns_zone_log(zone, ISC_LOG_ERROR, "refresh: could not set "
11202 "file modification time of '%s': %s",
11203 zone->masterfile, dns_result_totext(result));
11204 }
11205
11206
11207
11208
11209 static void
11210 refresh_callback(isc_task_t *task, isc_event_t *event) {
11211 const char me[] = "refresh_callback";
11212 dns_requestevent_t *revent = (dns_requestevent_t *)event;
11213 dns_zone_t *zone;
11214 dns_message_t *msg = NULL;
11215 isc_uint32_t soacnt, cnamecnt, soacount, nscount;
11216 isc_time_t now;
11217 char master[ISC_SOCKADDR_FORMATSIZE];
11218 char source[ISC_SOCKADDR_FORMATSIZE];
11219 dns_rdataset_t *rdataset = NULL;
11220 dns_rdata_t rdata = DNS_RDATA_INIT;
11221 dns_rdata_soa_t soa;
11222 isc_result_t result;
11223 isc_uint32_t serial, oldserial = 0;
11224 unsigned int j;
11225 isc_boolean_t do_queue_xfrin = ISC_FALSE;
11226
11227 zone = revent->ev_arg;
11228 INSIST(DNS_ZONE_VALID(zone));
11229
11230 UNUSED(task);
11231
11232 ENTER;
11233
11234 TIME_NOW(&now);
11235
11236 LOCK_ZONE(zone);
11237
11238 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
11239 isc_event_free(&event);
11240 dns_request_destroy(&zone->request);
11241 goto detach;
11242 }
11243
11244
11245
11246
11247
11248 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
11249 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
11250
11251 if (revent->result != ISC_R_SUCCESS) {
11252 if (revent->result == ISC_R_TIMEDOUT &&
11253 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
11254 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
11255 dns_zone_log(zone, ISC_LOG_DEBUG(1),
11256 "refresh: timeout retrying without EDNS "
11257 "master %s (source %s)", master, source);
11258 goto same_master;
11259 }
11260 if (revent->result == ISC_R_TIMEDOUT &&
11261 !dns_request_usedtcp(revent->request)) {
11262 dns_zone_log(zone, ISC_LOG_INFO,
11263 "refresh: retry limit for "
11264 "master %s exceeded (source %s)",
11265 master, source);
11266
11267 if ((zone->type == dns_zone_slave ||
11268 zone->type == dns_zone_redirect) &&
11269 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_TRYTCPREFRESH)) {
11270 if (!dns_zonemgr_unreachable(zone->zmgr,
11271 &zone->masteraddr,
11272 &zone->sourceaddr,
11273 &now))
11274 {
11275 DNS_ZONE_SETFLAG(zone,
11276 DNS_ZONEFLG_SOABEFOREAXFR);
11277 goto tcp_transfer;
11278 }
11279 dns_zone_log(zone, ISC_LOG_DEBUG(1),
11280 "refresh: skipped tcp fallback "
11281 "as master %s (source %s) is "
11282 "unreachable (cached)",
11283 master, source);
11284 }
11285 } else
11286 dns_zone_log(zone, ISC_LOG_INFO,
11287 "refresh: failure trying master "
11288 "%s (source %s): %s", master, source,
11289 dns_result_totext(revent->result));
11290 goto next_master;
11291 }
11292
11293 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
11294 if (result != ISC_R_SUCCESS)
11295 goto next_master;
11296 result = dns_request_getresponse(revent->request, msg, 0);
11297 if (result != ISC_R_SUCCESS) {
11298 dns_zone_log(zone, ISC_LOG_INFO,
11299 "refresh: failure trying master "
11300 "%s (source %s): %s", master, source,
11301 dns_result_totext(result));
11302 goto next_master;
11303 }
11304
11305
11306
11307
11308 if (msg->rcode != dns_rcode_noerror) {
11309 char rcode[128];
11310 isc_buffer_t rb;
11311
11312 isc_buffer_init(&rb, rcode, sizeof(rcode));
11313 (void)dns_rcode_totext(msg->rcode, &rb);
11314
11315 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) &&
11316 (msg->rcode == dns_rcode_servfail ||
11317 msg->rcode == dns_rcode_notimp ||
11318 msg->rcode == dns_rcode_formerr)) {
11319 dns_zone_log(zone, ISC_LOG_DEBUG(1),
11320 "refresh: rcode (%.*s) retrying without "
11321 "EDNS master %s (source %s)",
11322 (int)rb.used, rcode, master, source);
11323 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
11324 goto same_master;
11325 }
11326 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) &&
11327 msg->rcode == dns_rcode_badvers) {
11328 dns_zone_log(zone, ISC_LOG_DEBUG(1),
11329 "refresh: rcode (%.*s) retrying without "
11330 "EDNS EXPIRE OPTION master %s (source %s)",
11331 (int)rb.used, rcode, master, source);
11332 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
11333 goto same_master;
11334 }
11335 dns_zone_log(zone, ISC_LOG_INFO,
11336 "refresh: unexpected rcode (%.*s) from "
11337 "master %s (source %s)", (int)rb.used, rcode,
11338 master, source);
11339
11340
11341
11342 if (msg->rcode == dns_rcode_refused &&
11343 (zone->type == dns_zone_slave ||
11344 zone->type == dns_zone_redirect))
11345 goto tcp_transfer;
11346 goto next_master;
11347 }
11348
11349
11350
11351
11352 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) {
11353 if (zone->type == dns_zone_slave ||
11354 zone->type == dns_zone_redirect) {
11355 dns_zone_log(zone, ISC_LOG_INFO,
11356 "refresh: truncated UDP answer, "
11357 "initiating TCP zone xfer "
11358 "for master %s (source %s)",
11359 master, source);
11360 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR);
11361 goto tcp_transfer;
11362 } else {
11363 INSIST(zone->type == dns_zone_stub);
11364 if (dns_request_usedtcp(revent->request)) {
11365 dns_zone_log(zone, ISC_LOG_INFO,
11366 "refresh: truncated TCP response "
11367 "from master %s (source %s)",
11368 master, source);
11369 goto next_master;
11370 }
11371 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC);
11372 goto same_master;
11373 }
11374 }
11375
11376
11377
11378
11379 if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
11380 dns_zone_log(zone, ISC_LOG_INFO,
11381 "refresh: non-authoritative answer from "
11382 "master %s (source %s)", master, source);
11383 goto next_master;
11384 }
11385
11386 cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname);
11387 soacnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_soa);
11388 nscount = message_count(msg, DNS_SECTION_AUTHORITY, dns_rdatatype_ns);
11389 soacount = message_count(msg, DNS_SECTION_AUTHORITY,
11390 dns_rdatatype_soa);
11391
11392
11393
11394
11395 if (cnamecnt != 0) {
11396 dns_zone_log(zone, ISC_LOG_INFO,
11397 "refresh: CNAME at top of zone "
11398 "in master %s (source %s)", master, source);
11399 goto next_master;
11400 }
11401
11402
11403
11404
11405 if (soacnt == 0 && soacount == 0 && nscount != 0) {
11406 dns_zone_log(zone, ISC_LOG_INFO,
11407 "refresh: referral response "
11408 "from master %s (source %s)", master, source);
11409 goto next_master;
11410 }
11411
11412
11413
11414
11415 if (soacnt == 0 && (nscount == 0 || soacount != 0)) {
11416 dns_zone_log(zone, ISC_LOG_INFO,
11417 "refresh: NODATA response "
11418 "from master %s (source %s)", master, source);
11419 goto next_master;
11420 }
11421
11422
11423
11424
11425 if (soacnt != 1) {
11426 dns_zone_log(zone, ISC_LOG_INFO,
11427 "refresh: answer SOA count (%d) != 1 "
11428 "from master %s (source %s)",
11429 soacnt, master, source);
11430 goto next_master;
11431 }
11432
11433
11434
11435
11436 rdataset = NULL;
11437 result = dns_message_findname(msg, DNS_SECTION_ANSWER, &zone->origin,
11438 dns_rdatatype_soa, dns_rdatatype_none,
11439 NULL, &rdataset);
11440 if (result != ISC_R_SUCCESS) {
11441 dns_zone_log(zone, ISC_LOG_INFO,
11442 "refresh: unable to get SOA record "
11443 "from master %s (source %s)", master, source);
11444 goto next_master;
11445 }
11446
11447 result = dns_rdataset_first(rdataset);
11448 if (result != ISC_R_SUCCESS) {
11449 dns_zone_log(zone, ISC_LOG_INFO,
11450 "refresh: dns_rdataset_first() failed");
11451 goto next_master;
11452 }
11453
11454 dns_rdataset_current(rdataset, &rdata);
11455 result = dns_rdata_tostruct(&rdata, &soa, NULL);
11456 RUNTIME_CHECK(result == ISC_R_SUCCESS);
11457
11458 serial = soa.serial;
11459 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
11460 unsigned int dbsoacount;
11461 result = zone_get_from_db(zone, zone->db, NULL, &dbsoacount,
11462 &oldserial, NULL, NULL, NULL, NULL,
11463 NULL);
11464 RUNTIME_CHECK(result == ISC_R_SUCCESS);
11465 RUNTIME_CHECK(dbsoacount > 0U);
11466 zone_debuglog(zone, me, 1, "serial: new %u, old %u",
11467 serial, oldserial);
11468 } else
11469 zone_debuglog(zone, me, 1, "serial: new %u, old not loaded",
11470 serial);
11471
11472 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) ||
11473 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) ||
11474 isc_serial_gt(serial, oldserial)) {
11475 if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr,
11476 &zone->sourceaddr, &now))
11477 {
11478 dns_zone_log(zone, ISC_LOG_INFO,
11479 "refresh: skipping %s as master %s "
11480 "(source %s) is unreachable (cached)",
11481 (zone->type == dns_zone_slave ||
11482 zone->type == dns_zone_redirect) ?
11483 "zone transfer" : "NS query",
11484 master, source);
11485 goto next_master;
11486 }
11487 tcp_transfer:
11488 isc_event_free(&event);
11489 dns_request_destroy(&zone->request);
11490 if (zone->type == dns_zone_slave ||
11491 zone->type == dns_zone_redirect) {
11492 do_queue_xfrin = ISC_TRUE;
11493 } else {
11494 INSIST(zone->type == dns_zone_stub);
11495 ns_query(zone, rdataset, NULL);
11496 }
11497 if (msg != NULL)
11498 dns_message_destroy(&msg);
11499 } else if (isc_serial_eq(soa.serial, oldserial)) {
11500 isc_time_t expiretime;
11501 isc_uint32_t expire;
11502
11503
11504
11505
11506 expire = zone->expire;
11507 get_edns_expire(zone, msg, &expire);
11508 DNS_ZONE_TIME_ADD(&now, expire, &expiretime);
11509
11510
11511
11512
11513 if (isc_time_compare(&expiretime, &zone->expiretime) > 0) {
11514 zone->expiretime = expiretime;
11515 if (zone->masterfile != NULL)
11516 setmodtime(zone, &expiretime);
11517 }
11518
11519 DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime);
11520 zone->mastersok[zone->curmaster] = ISC_TRUE;
11521 goto next_master;
11522 } else {
11523 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MULTIMASTER))
11524 dns_zone_log(zone, ISC_LOG_INFO, "serial number (%u) "
11525 "received from master %s < ours (%u)",
11526 soa.serial, master, oldserial);
11527 else
11528 zone_debuglog(zone, me, 1, "ahead");
11529 zone->mastersok[zone->curmaster] = ISC_TRUE;
11530 goto next_master;
11531 }
11532 if (msg != NULL)
11533 dns_message_destroy(&msg);
11534 goto detach;
11535
11536 next_master:
11537 if (msg != NULL)
11538 dns_message_destroy(&msg);
11539 isc_event_free(&event);
11540 dns_request_destroy(&zone->request);
11541
11542
11543
11544 do {
11545 zone->curmaster++;
11546 } while (zone->curmaster < zone->masterscnt &&
11547 zone->mastersok[zone->curmaster]);
11548 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
11549 if (zone->curmaster >= zone->masterscnt) {
11550 isc_boolean_t done = ISC_TRUE;
11551 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
11552 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
11553
11554
11555
11556 for (j = 0; j < zone->masterscnt; j++)
11557 if (zone->mastersok[j] == ISC_FALSE) {
11558 done = ISC_FALSE;
11559 break;
11560 }
11561 } else
11562 done = ISC_TRUE;
11563 if (!done) {
11564 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
11565 zone->curmaster = 0;
11566
11567
11568
11569 while (zone->curmaster < zone->masterscnt &&
11570 zone->mastersok[zone->curmaster])
11571 zone->curmaster++;
11572 goto requeue;
11573 }
11574 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
11575 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) {
11576 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
11577 zone->refreshtime = now;
11578 }
11579 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
11580 zone_settimer(zone, &now);
11581 goto detach;
11582 }
11583
11584 requeue:
11585 queue_soa_query(zone);
11586 goto detach;
11587
11588 same_master:
11589 if (msg != NULL)
11590 dns_message_destroy(&msg);
11591 isc_event_free(&event);
11592 dns_request_destroy(&zone->request);
11593 queue_soa_query(zone);
11594
11595 detach:
11596 UNLOCK_ZONE(zone);
11597 if (do_queue_xfrin)
11598 queue_xfrin(zone);
11599 dns_zone_idetach(&zone);
11600 return;
11601 }
11602
11603 static void
11604 queue_soa_query(dns_zone_t *zone) {
11605 const char me[] = "queue_soa_query";
11606 isc_event_t *e;
11607 dns_zone_t *dummy = NULL;
11608 isc_result_t result;
11609
11610 ENTER;
11611
11612
11613
11614 REQUIRE(LOCKED_ZONE(zone));
11615
11616 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
11617 cancel_refresh(zone);
11618 return;
11619 }
11620
11621 e = isc_event_allocate(zone->mctx, NULL, DNS_EVENT_ZONE,
11622 soa_query, zone, sizeof(isc_event_t));
11623 if (e == NULL) {
11624 cancel_refresh(zone);
11625 return;
11626 }
11627
11628
11629
11630
11631
11632 zone_iattach(zone, &dummy);
11633
11634 e->ev_arg = zone;
11635 e->ev_sender = NULL;
11636 result = isc_ratelimiter_enqueue(zone->zmgr->refreshrl, zone->task, &e);
11637 if (result != ISC_R_SUCCESS) {
11638 zone_idetach(&dummy);
11639 isc_event_free(&e);
11640 cancel_refresh(zone);
11641 }
11642 }
11643
11644 static inline isc_result_t
11645 create_query(dns_zone_t *zone, dns_rdatatype_t rdtype,
11646 dns_message_t **messagep)
11647 {
11648 dns_message_t *message = NULL;
11649 dns_name_t *qname = NULL;
11650 dns_rdataset_t *qrdataset = NULL;
11651 isc_result_t result;
11652
11653 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER,
11654 &message);
11655 if (result != ISC_R_SUCCESS)
11656 goto cleanup;
11657
11658 message->opcode = dns_opcode_query;
11659 message->rdclass = zone->rdclass;
11660
11661 result = dns_message_gettempname(message, &qname);
11662 if (result != ISC_R_SUCCESS)
11663 goto cleanup;
11664
11665 result = dns_message_gettemprdataset(message, &qrdataset);
11666 if (result != ISC_R_SUCCESS)
11667 goto cleanup;
11668
11669
11670
11671
11672 dns_name_init(qname, NULL);
11673 dns_name_clone(&zone->origin, qname);
11674 dns_rdataset_init(qrdataset);
11675 dns_rdataset_makequestion(qrdataset, zone->rdclass, rdtype);
11676 ISC_LIST_APPEND(qname->list, qrdataset, link);
11677 dns_message_addname(message, qname, DNS_SECTION_QUESTION);
11678
11679 *messagep = message;
11680 return (ISC_R_SUCCESS);
11681
11682 cleanup:
11683 if (qname != NULL)
11684 dns_message_puttempname(message, &qname);
11685 if (qrdataset != NULL)
11686 dns_message_puttemprdataset(message, &qrdataset);
11687 if (message != NULL)
11688 dns_message_destroy(&message);
11689 return (result);
11690 }
11691
11692 static isc_result_t
11693 add_opt(dns_message_t *message, isc_uint16_t udpsize, isc_boolean_t reqnsid,
11694 isc_boolean_t reqexpire)
11695 {
11696 isc_result_t result;
11697 dns_rdataset_t *rdataset = NULL;
11698 dns_ednsopt_t ednsopts[DNS_EDNSOPTIONS];
11699 int count = 0;
11700
11701
11702 if (reqnsid) {
11703 INSIST(count < DNS_EDNSOPTIONS);
11704 ednsopts[count].code = DNS_OPT_NSID;
11705 ednsopts[count].length = 0;
11706 ednsopts[count].value = NULL;
11707 count++;
11708 }
11709 if (reqexpire) {
11710 INSIST(count < DNS_EDNSOPTIONS);
11711 ednsopts[count].code = DNS_OPT_EXPIRE;
11712 ednsopts[count].length = 0;
11713 ednsopts[count].value = NULL;
11714 count++;
11715 }
11716 result = dns_message_buildopt(message, &rdataset, 0, udpsize, 0,
11717 ednsopts, count);
11718 if (result != ISC_R_SUCCESS)
11719 return (result);
11720
11721 return (dns_message_setopt(message, rdataset));
11722 }
11723
11724 static void
11725 soa_query(isc_task_t *task, isc_event_t *event) {
11726 const char me[] = "soa_query";
11727 isc_result_t result = ISC_R_FAILURE;
11728 dns_message_t *message = NULL;
11729 dns_zone_t *zone = event->ev_arg;
11730 dns_zone_t *dummy = NULL;
11731 isc_netaddr_t masterip;
11732 dns_tsigkey_t *key = NULL;
11733 isc_uint32_t options;
11734 isc_boolean_t cancel = ISC_TRUE;
11735 int timeout;
11736 isc_boolean_t have_xfrsource, have_xfrdscp, reqnsid, reqexpire;
11737 isc_uint16_t udpsize = SEND_BUFFER_SIZE;
11738 isc_dscp_t dscp = -1;
11739
11740 REQUIRE(DNS_ZONE_VALID(zone));
11741
11742 UNUSED(task);
11743
11744 ENTER;
11745
11746 LOCK_ZONE(zone);
11747 if (((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0) ||
11748 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) ||
11749 zone->view->requestmgr == NULL) {
11750 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
11751 cancel = ISC_FALSE;
11752 goto cleanup;
11753 }
11754
11755 again:
11756 result = create_query(zone, dns_rdatatype_soa, &message);
11757 if (result != ISC_R_SUCCESS)
11758 goto cleanup;
11759
11760 INSIST(zone->masterscnt > 0);
11761 INSIST(zone->curmaster < zone->masterscnt);
11762
11763 zone->masteraddr = zone->masters[zone->curmaster];
11764
11765 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
11766
11767
11768
11769
11770 if ((zone->masterkeynames != NULL) &&
11771 (zone->masterkeynames[zone->curmaster] != NULL)) {
11772 dns_view_t *view = dns_zone_getview(zone);
11773 dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
11774 result = dns_view_gettsig(view, keyname, &key);
11775 if (result != ISC_R_SUCCESS) {
11776 char namebuf[DNS_NAME_FORMATSIZE];
11777 dns_name_format(keyname, namebuf, sizeof(namebuf));
11778 dns_zone_log(zone, ISC_LOG_ERROR,
11779 "unable to find key: %s", namebuf);
11780 goto skip_master;
11781 }
11782 }
11783 if (key == NULL) {
11784 result = dns_view_getpeertsig(zone->view, &masterip, &key);
11785 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
11786 char addrbuf[ISC_NETADDR_FORMATSIZE];
11787 isc_netaddr_format(&masterip, addrbuf, sizeof(addrbuf));
11788 dns_zone_log(zone, ISC_LOG_ERROR,
11789 "unable to find TSIG key for %s", addrbuf);
11790 goto skip_master;
11791 }
11792 }
11793
11794 options = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEVC) ?
11795 DNS_REQUESTOPT_TCP : 0;
11796 have_xfrsource = have_xfrdscp = ISC_FALSE;
11797 reqnsid = zone->view->requestnsid;
11798 reqexpire = zone->requestexpire;
11799 if (zone->view->peers != NULL) {
11800 dns_peer_t *peer = NULL;
11801 isc_boolean_t edns, usetcp;
11802 result = dns_peerlist_peerbyaddr(zone->view->peers,
11803 &masterip, &peer);
11804 if (result == ISC_R_SUCCESS) {
11805 result = dns_peer_getsupportedns(peer, &edns);
11806 if (result == ISC_R_SUCCESS && !edns)
11807 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
11808 result = dns_peer_gettransfersource(peer,
11809 &zone->sourceaddr);
11810 if (result == ISC_R_SUCCESS)
11811 have_xfrsource = ISC_TRUE;
11812 (void)dns_peer_gettransferdscp(peer, &dscp);
11813 if (dscp != -1)
11814 have_xfrdscp = ISC_TRUE;
11815 if (zone->view->resolver != NULL)
11816 udpsize =
11817 dns_resolver_getudpsize(zone->view->resolver);
11818 (void)dns_peer_getudpsize(peer, &udpsize);
11819 (void)dns_peer_getrequestnsid(peer, &reqnsid);
11820 (void)dns_peer_getrequestexpire(peer, &reqexpire);
11821 result = dns_peer_getforcetcp(peer, &usetcp);
11822 if (result == ISC_R_SUCCESS && usetcp)
11823 options |= DNS_REQUESTOPT_TCP;
11824 }
11825 }
11826
11827 switch (isc_sockaddr_pf(&zone->masteraddr)) {
11828 case PF_INET:
11829 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
11830 if (isc_sockaddr_equal(&zone->altxfrsource4,
11831 &zone->xfrsource4))
11832 goto skip_master;
11833 zone->sourceaddr = zone->altxfrsource4;
11834 if (!have_xfrdscp)
11835 dscp = zone->altxfrsource4dscp;
11836 } else if (!have_xfrsource) {
11837 zone->sourceaddr = zone->xfrsource4;
11838 if (!have_xfrdscp)
11839 dscp = zone->xfrsource4dscp;
11840 }
11841 break;
11842 case PF_INET6:
11843 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
11844 if (isc_sockaddr_equal(&zone->altxfrsource6,
11845 &zone->xfrsource6))
11846 goto skip_master;
11847 zone->sourceaddr = zone->altxfrsource6;
11848 if (!have_xfrdscp)
11849 dscp = zone->altxfrsource6dscp;
11850 } else if (!have_xfrsource) {
11851 zone->sourceaddr = zone->xfrsource6;
11852 if (!have_xfrdscp)
11853 dscp = zone->xfrsource6dscp;
11854 }
11855 break;
11856 default:
11857 result = ISC_R_NOTIMPLEMENTED;
11858 goto cleanup;
11859 }
11860
11861 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
11862 result = add_opt(message, udpsize, reqnsid, reqexpire);
11863 if (result != ISC_R_SUCCESS)
11864 zone_debuglog(zone, me, 1,
11865 "unable to add opt record: %s",
11866 dns_result_totext(result));
11867 }
11868
11869 zone_iattach(zone, &dummy);
11870 timeout = 15;
11871 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
11872 timeout = 30;
11873 result = dns_request_createvia4(zone->view->requestmgr, message,
11874 &zone->sourceaddr, &zone->masteraddr,
11875 dscp, options, key, timeout * 3,
11876 timeout, 0, zone->task,
11877 refresh_callback, zone, &zone->request);
11878 if (result != ISC_R_SUCCESS) {
11879 zone_idetach(&dummy);
11880 zone_debuglog(zone, me, 1,
11881 "dns_request_createvia4() failed: %s",
11882 dns_result_totext(result));
11883 goto skip_master;
11884 } else {
11885 if (isc_sockaddr_pf(&zone->masteraddr) == PF_INET)
11886 inc_stats(zone, dns_zonestatscounter_soaoutv4);
11887 else
11888 inc_stats(zone, dns_zonestatscounter_soaoutv6);
11889 }
11890 cancel = ISC_FALSE;
11891
11892 cleanup:
11893 if (key != NULL)
11894 dns_tsigkey_detach(&key);
11895 if (result != ISC_R_SUCCESS)
11896 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
11897 if (message != NULL)
11898 dns_message_destroy(&message);
11899 if (cancel)
11900 cancel_refresh(zone);
11901 isc_event_free(&event);
11902 UNLOCK_ZONE(zone);
11903 dns_zone_idetach(&zone);
11904 return;
11905
11906 skip_master:
11907 if (key != NULL)
11908 dns_tsigkey_detach(&key);
11909 dns_message_destroy(&message);
11910
11911
11912
11913 do {
11914 zone->curmaster++;
11915 } while (zone->curmaster < zone->masterscnt &&
11916 zone->mastersok[zone->curmaster]);
11917 if (zone->curmaster < zone->masterscnt)
11918 goto again;
11919 zone->curmaster = 0;
11920 goto cleanup;
11921 }
11922
11923 static void
11924 ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) {
11925 const char me[] = "ns_query";
11926 isc_result_t result;
11927 dns_message_t *message = NULL;
11928 isc_netaddr_t masterip;
11929 dns_tsigkey_t *key = NULL;
11930 dns_dbnode_t *node = NULL;
11931 int timeout;
11932 isc_boolean_t have_xfrsource = ISC_FALSE, have_xfrdscp = ISC_FALSE;
11933 isc_boolean_t reqnsid;
11934 isc_uint16_t udpsize = SEND_BUFFER_SIZE;
11935 isc_dscp_t dscp = -1;
11936
11937 REQUIRE(DNS_ZONE_VALID(zone));
11938 REQUIRE(LOCKED_ZONE(zone));
11939 REQUIRE((soardataset != NULL && stub == NULL) ||
11940 (soardataset == NULL && stub != NULL));
11941 REQUIRE(stub == NULL || DNS_STUB_VALID(stub));
11942
11943 ENTER;
11944
11945 if (stub == NULL) {
11946 stub = isc_mem_get(zone->mctx, sizeof(*stub));
11947 if (stub == NULL)
11948 goto cleanup;
11949 stub->magic = STUB_MAGIC;
11950 stub->mctx = zone->mctx;
11951 stub->zone = NULL;
11952 stub->db = NULL;
11953 stub->version = NULL;
11954
11955
11956
11957
11958 zone_iattach(zone, &stub->zone);
11959
11960
11961
11962
11963
11964
11965 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
11966 if (zone->db != NULL) {
11967 dns_db_attach(zone->db, &stub->db);
11968 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
11969 } else {
11970 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
11971
11972 INSIST(zone->db_argc >= 1);
11973 result = dns_db_create(zone->mctx, zone->db_argv[0],
11974 &zone->origin, dns_dbtype_stub,
11975 zone->rdclass,
11976 zone->db_argc - 1,
11977 zone->db_argv + 1,
11978 &stub->db);
11979 if (result != ISC_R_SUCCESS) {
11980 dns_zone_log(zone, ISC_LOG_ERROR,
11981 "refreshing stub: "
11982 "could not create "
11983 "database: %s",
11984 dns_result_totext(result));
11985 goto cleanup;
11986 }
11987 dns_db_settask(stub->db, zone->task);
11988 }
11989
11990 result = dns_db_newversion(stub->db, &stub->version);
11991 if (result != ISC_R_SUCCESS) {
11992 dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: "
11993 "dns_db_newversion() failed: %s",
11994 dns_result_totext(result));
11995 goto cleanup;
11996 }
11997
11998
11999
12000
12001 result = dns_db_findnode(stub->db, &zone->origin, ISC_TRUE,
12002 &node);
12003 if (result != ISC_R_SUCCESS) {
12004 dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: "
12005 "dns_db_findnode() failed: %s",
12006 dns_result_totext(result));
12007 goto cleanup;
12008 }
12009
12010 result = dns_db_addrdataset(stub->db, node, stub->version, 0,
12011 soardataset, 0, NULL);
12012 dns_db_detachnode(stub->db, &node);
12013 if (result != ISC_R_SUCCESS) {
12014 dns_zone_log(zone, ISC_LOG_INFO,
12015 "refreshing stub: "
12016 "dns_db_addrdataset() failed: %s",
12017 dns_result_totext(result));
12018 goto cleanup;
12019 }
12020 }
12021
12022
12023
12024
12025 result = create_query(zone, dns_rdatatype_ns, &message);
12026 INSIST(result == ISC_R_SUCCESS);
12027
12028 INSIST(zone->masterscnt > 0);
12029 INSIST(zone->curmaster < zone->masterscnt);
12030 zone->masteraddr = zone->masters[zone->curmaster];
12031
12032 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
12033
12034
12035
12036
12037 if ((zone->masterkeynames != NULL) &&
12038 (zone->masterkeynames[zone->curmaster] != NULL)) {
12039 dns_view_t *view = dns_zone_getview(zone);
12040 dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
12041 result = dns_view_gettsig(view, keyname, &key);
12042 if (result != ISC_R_SUCCESS) {
12043 char namebuf[DNS_NAME_FORMATSIZE];
12044 dns_name_format(keyname, namebuf, sizeof(namebuf));
12045 dns_zone_log(zone, ISC_LOG_ERROR,
12046 "unable to find key: %s", namebuf);
12047 }
12048 }
12049 if (key == NULL)
12050 (void)dns_view_getpeertsig(zone->view, &masterip, &key);
12051
12052 reqnsid = zone->view->requestnsid;
12053 if (zone->view->peers != NULL) {
12054 dns_peer_t *peer = NULL;
12055 isc_boolean_t edns;
12056 result = dns_peerlist_peerbyaddr(zone->view->peers,
12057 &masterip, &peer);
12058 if (result == ISC_R_SUCCESS) {
12059 result = dns_peer_getsupportedns(peer, &edns);
12060 if (result == ISC_R_SUCCESS && !edns)
12061 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
12062 result = dns_peer_gettransfersource(peer,
12063 &zone->sourceaddr);
12064 if (result == ISC_R_SUCCESS)
12065 have_xfrsource = ISC_TRUE;
12066 result = dns_peer_gettransferdscp(peer, &dscp);
12067 if (result == ISC_R_SUCCESS && dscp != -1)
12068 have_xfrdscp = ISC_TRUE;
12069 if (zone->view->resolver != NULL)
12070 udpsize =
12071 dns_resolver_getudpsize(zone->view->resolver);
12072 (void)dns_peer_getudpsize(peer, &udpsize);
12073 (void)dns_peer_getrequestnsid(peer, &reqnsid);
12074 }
12075
12076 }
12077 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
12078 result = add_opt(message, udpsize, reqnsid, ISC_FALSE);
12079 if (result != ISC_R_SUCCESS)
12080 zone_debuglog(zone, me, 1,
12081 "unable to add opt record: %s",
12082 dns_result_totext(result));
12083 }
12084
12085
12086
12087
12088 switch (isc_sockaddr_pf(&zone->masteraddr)) {
12089 case PF_INET:
12090 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
12091 zone->sourceaddr = zone->altxfrsource4;
12092 if (!have_xfrdscp)
12093 dscp = zone->altxfrsource4dscp;
12094 } else if (!have_xfrsource) {
12095 zone->sourceaddr = zone->xfrsource4;
12096 if (!have_xfrdscp)
12097 dscp = zone->xfrsource4dscp;
12098 }
12099 break;
12100 case PF_INET6:
12101 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
12102 zone->sourceaddr = zone->altxfrsource6;
12103 if (!have_xfrdscp)
12104 dscp = zone->altxfrsource6dscp;
12105 } else if (!have_xfrsource) {
12106 zone->sourceaddr = zone->xfrsource6;
12107 if (!have_xfrdscp)
12108 dscp = zone->xfrsource6dscp;
12109 }
12110 break;
12111 default:
12112 result = ISC_R_NOTIMPLEMENTED;
12113 POST(result);
12114 goto cleanup;
12115 }
12116 timeout = 15;
12117 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
12118 timeout = 30;
12119 result = dns_request_createvia4(zone->view->requestmgr, message,
12120 &zone->sourceaddr, &zone->masteraddr,
12121 dscp, DNS_REQUESTOPT_TCP, key,
12122 timeout * 3, timeout, 0, zone->task,
12123 stub_callback, stub, &zone->request);
12124 if (result != ISC_R_SUCCESS) {
12125 zone_debuglog(zone, me, 1,
12126 "dns_request_createvia() failed: %s",
12127 dns_result_totext(result));
12128 goto cleanup;
12129 }
12130 dns_message_destroy(&message);
12131 goto unlock;
12132
12133 cleanup:
12134 cancel_refresh(zone);
12135 if (stub != NULL) {
12136 stub->magic = 0;
12137 if (stub->version != NULL)
12138 dns_db_closeversion(stub->db, &stub->version,
12139 ISC_FALSE);
12140 if (stub->db != NULL)
12141 dns_db_detach(&stub->db);
12142 if (stub->zone != NULL)
12143 zone_idetach(&stub->zone);
12144 isc_mem_put(stub->mctx, stub, sizeof(*stub));
12145 }
12146 if (message != NULL)
12147 dns_message_destroy(&message);
12148 unlock:
12149 if (key != NULL)
12150 dns_tsigkey_detach(&key);
12151 return;
12152 }
12153
12154
12155
12156
12157
12158 static void
12159 zone_shutdown(isc_task_t *task, isc_event_t *event) {
12160 dns_zone_t *zone = (dns_zone_t *) event->ev_arg;
12161 isc_boolean_t free_needed, linked = ISC_FALSE;
12162 dns_zone_t *raw = NULL, *secure = NULL;
12163
12164 UNUSED(task);
12165 REQUIRE(DNS_ZONE_VALID(zone));
12166 INSIST(event->ev_type == DNS_EVENT_ZONECONTROL);
12167 INSIST(isc_refcount_current(&zone->erefs) == 0);
12168
12169 zone_debuglog(zone, "zone_shutdown", 3, "shutting down");
12170
12171
12172
12173
12174 LOCK_ZONE(zone);
12175 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXITING);
12176 UNLOCK_ZONE(zone);
12177
12178
12179
12180
12181
12182
12183
12184 if (zone->zmgr != NULL) {
12185 RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
12186 if (zone->statelist == &zone->zmgr->waiting_for_xfrin) {
12187 ISC_LIST_UNLINK(zone->zmgr->waiting_for_xfrin, zone,
12188 statelink);
12189 linked = ISC_TRUE;
12190 zone->statelist = NULL;
12191 }
12192 if (zone->statelist == &zone->zmgr->xfrin_in_progress) {
12193 ISC_LIST_UNLINK(zone->zmgr->xfrin_in_progress, zone,
12194 statelink);
12195 zone->statelist = NULL;
12196 zmgr_resume_xfrs(zone->zmgr, ISC_FALSE);
12197 }
12198 RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
12199 }
12200
12201
12202
12203
12204 if (zone->xfr != NULL)
12205 dns_xfrin_shutdown(zone->xfr);
12206
12207
12208 if (zone->zmgr != NULL)
12209 dns_zonemgr_releasezone(zone->zmgr, zone);
12210
12211 LOCK_ZONE(zone);
12212 INSIST(zone != zone->raw);
12213 if (linked) {
12214 INSIST(zone->irefs > 0);
12215 zone->irefs--;
12216 }
12217 if (zone->request != NULL) {
12218 dns_request_cancel(zone->request);
12219 }
12220
12221 if (zone->readio != NULL)
12222 zonemgr_cancelio(zone->readio);
12223
12224 if (zone->lctx != NULL)
12225 dns_loadctx_cancel(zone->lctx);
12226
12227 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) ||
12228 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
12229 if (zone->writeio != NULL)
12230 zonemgr_cancelio(zone->writeio);
12231
12232 if (zone->dctx != NULL)
12233 dns_dumpctx_cancel(zone->dctx);
12234 }
12235
12236 notify_cancel(zone);
12237
12238 forward_cancel(zone);
12239
12240 if (zone->timer != NULL) {
12241 isc_timer_detach(&zone->timer);
12242 INSIST(zone->irefs > 0);
12243 zone->irefs--;
12244 }
12245
12246 if (zone->view != NULL)
12247 dns_view_weakdetach(&zone->view);
12248
12249
12250
12251
12252
12253
12254 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SHUTDOWN);
12255 free_needed = exit_check(zone);
12256 if (inline_secure(zone)) {
12257 raw = zone->raw;
12258 zone->raw = NULL;
12259 }
12260 if (inline_raw(zone)) {
12261 secure = zone->secure;
12262 zone->secure = NULL;
12263 }
12264 UNLOCK_ZONE(zone);
12265 if (raw != NULL)
12266 dns_zone_detach(&raw);
12267 if (secure != NULL)
12268 dns_zone_idetach(&secure);
12269 if (free_needed)
12270 zone_free(zone);
12271 }
12272
12273 static void
12274 zone_timer(isc_task_t *task, isc_event_t *event) {
12275 const char me[] = "zone_timer";
12276 dns_zone_t *zone = (dns_zone_t *)event->ev_arg;
12277
12278 UNUSED(task);
12279 REQUIRE(DNS_ZONE_VALID(zone));
12280
12281 ENTER;
12282
12283 zone_maintenance(zone);
12284
12285 isc_event_free(&event);
12286 }
12287
12288 static void
12289 zone_settimer(dns_zone_t *zone, isc_time_t *now) {
12290 const char me[] = "zone_settimer";
12291 isc_time_t next;
12292 isc_result_t result;
12293
12294 ENTER;
12295 REQUIRE(DNS_ZONE_VALID(zone));
12296 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
12297 return;
12298
12299 isc_time_settoepoch(&next);
12300
12301 switch (zone->type) {
12302 case dns_zone_redirect:
12303 if (zone->masters != NULL)
12304 goto treat_as_slave;
12305
12306
12307 case dns_zone_master:
12308 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) ||
12309 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY))
12310 next = zone->notifytime;
12311 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
12312 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
12313 INSIST(!isc_time_isepoch(&zone->dumptime));
12314 if (isc_time_isepoch(&next) ||
12315 isc_time_compare(&zone->dumptime, &next) < 0)
12316 next = zone->dumptime;
12317 }
12318 if (zone->type == dns_zone_redirect)
12319 break;
12320 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING) &&
12321 !isc_time_isepoch(&zone->refreshkeytime)) {
12322 if (isc_time_isepoch(&next) ||
12323 isc_time_compare(&zone->refreshkeytime, &next) < 0)
12324 next = zone->refreshkeytime;
12325 }
12326 if (!isc_time_isepoch(&zone->resigntime)) {
12327 if (isc_time_isepoch(&next) ||
12328 isc_time_compare(&zone->resigntime, &next) < 0)
12329 next = zone->resigntime;
12330 }
12331 if (!isc_time_isepoch(&zone->keywarntime)) {
12332 if (isc_time_isepoch(&next) ||
12333 isc_time_compare(&zone->keywarntime, &next) < 0)
12334 next = zone->keywarntime;
12335 }
12336 if (!isc_time_isepoch(&zone->signingtime)) {
12337 if (isc_time_isepoch(&next) ||
12338 isc_time_compare(&zone->signingtime, &next) < 0)
12339 next = zone->signingtime;
12340 }
12341 if (!isc_time_isepoch(&zone->nsec3chaintime)) {
12342 if (isc_time_isepoch(&next) ||
12343 isc_time_compare(&zone->nsec3chaintime, &next) < 0)
12344 next = zone->nsec3chaintime;
12345 }
12346 break;
12347
12348 case dns_zone_slave:
12349 treat_as_slave:
12350 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) ||
12351 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY))
12352 next = zone->notifytime;
12353
12354
12355 case dns_zone_stub:
12356 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH) &&
12357 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOMASTERS) &&
12358 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH) &&
12359 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING)) {
12360 INSIST(!isc_time_isepoch(&zone->refreshtime));
12361 if (isc_time_isepoch(&next) ||
12362 isc_time_compare(&zone->refreshtime, &next) < 0)
12363 next = zone->refreshtime;
12364 }
12365 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
12366 !isc_time_isepoch(&zone->expiretime)) {
12367 if (isc_time_isepoch(&next) ||
12368 isc_time_compare(&zone->expiretime, &next) < 0)
12369 next = zone->expiretime;
12370 }
12371 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
12372 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
12373 INSIST(!isc_time_isepoch(&zone->dumptime));
12374 if (isc_time_isepoch(&next) ||
12375 isc_time_compare(&zone->dumptime, &next) < 0)
12376 next = zone->dumptime;
12377 }
12378 break;
12379
12380 case dns_zone_key:
12381 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
12382 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
12383 INSIST(!isc_time_isepoch(&zone->dumptime));
12384 if (isc_time_isepoch(&next) ||
12385 isc_time_compare(&zone->dumptime, &next) < 0)
12386 next = zone->dumptime;
12387 }
12388 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING)) {
12389 if (isc_time_isepoch(&next) ||
12390 (!isc_time_isepoch(&zone->refreshkeytime) &&
12391 isc_time_compare(&zone->refreshkeytime, &next) < 0))
12392 next = zone->refreshkeytime;
12393 }
12394 break;
12395
12396 default:
12397 break;
12398 }
12399
12400 if (isc_time_isepoch(&next)) {
12401 zone_debuglog(zone, me, 10, "settimer inactive");
12402 result = isc_timer_reset(zone->timer, isc_timertype_inactive,
12403 NULL, NULL, ISC_TRUE);
12404 if (result != ISC_R_SUCCESS)
12405 dns_zone_log(zone, ISC_LOG_ERROR,
12406 "could not deactivate zone timer: %s",
12407 isc_result_totext(result));
12408 } else {
12409 if (isc_time_compare(&next, now) <= 0)
12410 next = *now;
12411 result = isc_timer_reset(zone->timer, isc_timertype_once,
12412 &next, NULL, ISC_TRUE);
12413 if (result != ISC_R_SUCCESS)
12414 dns_zone_log(zone, ISC_LOG_ERROR,
12415 "could not reset zone timer: %s",
12416 isc_result_totext(result));
12417 }
12418 }
12419
12420 static void
12421 cancel_refresh(dns_zone_t *zone) {
12422 const char me[] = "cancel_refresh";
12423 isc_time_t now;
12424
12425
12426
12427
12428
12429 REQUIRE(DNS_ZONE_VALID(zone));
12430 REQUIRE(LOCKED_ZONE(zone));
12431
12432 ENTER;
12433
12434 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
12435 TIME_NOW(&now);
12436 zone_settimer(zone, &now);
12437 }
12438
12439 static isc_result_t
12440 notify_createmessage(dns_zone_t *zone, unsigned int flags,
12441 dns_message_t **messagep)
12442 {
12443 dns_db_t *zonedb = NULL;
12444 dns_dbnode_t *node = NULL;
12445 dns_dbversion_t *version = NULL;
12446 dns_message_t *message = NULL;
12447 dns_rdataset_t rdataset;
12448 dns_rdata_t rdata = DNS_RDATA_INIT;
12449
12450 dns_name_t *tempname = NULL;
12451 dns_rdata_t *temprdata = NULL;
12452 dns_rdatalist_t *temprdatalist = NULL;
12453 dns_rdataset_t *temprdataset = NULL;
12454
12455 isc_result_t result;
12456 isc_region_t r;
12457 isc_buffer_t *b = NULL;
12458
12459 REQUIRE(DNS_ZONE_VALID(zone));
12460 REQUIRE(messagep != NULL && *messagep == NULL);
12461
12462 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER,
12463 &message);
12464 if (result != ISC_R_SUCCESS)
12465 return (result);
12466
12467 message->opcode = dns_opcode_notify;
12468 message->flags |= DNS_MESSAGEFLAG_AA;
12469 message->rdclass = zone->rdclass;
12470
12471 result = dns_message_gettempname(message, &tempname);
12472 if (result != ISC_R_SUCCESS)
12473 goto cleanup;
12474
12475 result = dns_message_gettemprdataset(message, &temprdataset);
12476 if (result != ISC_R_SUCCESS)
12477 goto cleanup;
12478
12479
12480
12481
12482 dns_name_init(tempname, NULL);
12483 dns_name_clone(&zone->origin, tempname);
12484 dns_rdataset_init(temprdataset);
12485 dns_rdataset_makequestion(temprdataset, zone->rdclass,
12486 dns_rdatatype_soa);
12487 ISC_LIST_APPEND(tempname->list, temprdataset, link);
12488 dns_message_addname(message, tempname, DNS_SECTION_QUESTION);
12489 tempname = NULL;
12490 temprdataset = NULL;
12491
12492 if ((flags & DNS_NOTIFY_NOSOA) != 0)
12493 goto done;
12494
12495 result = dns_message_gettempname(message, &tempname);
12496 if (result != ISC_R_SUCCESS)
12497 goto soa_cleanup;
12498 result = dns_message_gettemprdata(message, &temprdata);
12499 if (result != ISC_R_SUCCESS)
12500 goto soa_cleanup;
12501 result = dns_message_gettemprdataset(message, &temprdataset);
12502 if (result != ISC_R_SUCCESS)
12503 goto soa_cleanup;
12504 result = dns_message_gettemprdatalist(message, &temprdatalist);
12505 if (result != ISC_R_SUCCESS)
12506 goto soa_cleanup;
12507
12508 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
12509 INSIST(zone->db != NULL);
12510 dns_db_attach(zone->db, &zonedb);
12511 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
12512
12513 dns_name_init(tempname, NULL);
12514 dns_name_clone(&zone->origin, tempname);
12515 dns_db_currentversion(zonedb, &version);
12516 result = dns_db_findnode(zonedb, tempname, ISC_FALSE, &node);
12517 if (result != ISC_R_SUCCESS)
12518 goto soa_cleanup;
12519
12520 dns_rdataset_init(&rdataset);
12521 result = dns_db_findrdataset(zonedb, node, version,
12522 dns_rdatatype_soa,
12523 dns_rdatatype_none, 0, &rdataset,
12524 NULL);
12525 if (result != ISC_R_SUCCESS)
12526 goto soa_cleanup;
12527 result = dns_rdataset_first(&rdataset);
12528 if (result != ISC_R_SUCCESS)
12529 goto soa_cleanup;
12530 dns_rdataset_current(&rdataset, &rdata);
12531 dns_rdata_toregion(&rdata, &r);
12532 result = isc_buffer_allocate(zone->mctx, &b, r.length);
12533 if (result != ISC_R_SUCCESS)
12534 goto soa_cleanup;
12535 isc_buffer_putmem(b, r.base, r.length);
12536 isc_buffer_usedregion(b, &r);
12537 dns_rdata_init(temprdata);
12538 dns_rdata_fromregion(temprdata, rdata.rdclass, rdata.type, &r);
12539 dns_message_takebuffer(message, &b);
12540 result = dns_rdataset_next(&rdataset);
12541 dns_rdataset_disassociate(&rdataset);
12542 if (result != ISC_R_NOMORE)
12543 goto soa_cleanup;
12544 temprdatalist->rdclass = rdata.rdclass;
12545 temprdatalist->type = rdata.type;
12546 temprdatalist->ttl = rdataset.ttl;
12547 ISC_LIST_APPEND(temprdatalist->rdata, temprdata, link);
12548
12549 dns_rdataset_init(temprdataset);
12550 result = dns_rdatalist_tordataset(temprdatalist, temprdataset);
12551 if (result != ISC_R_SUCCESS)
12552 goto soa_cleanup;
12553
12554 ISC_LIST_APPEND(tempname->list, temprdataset, link);
12555 dns_message_addname(message, tempname, DNS_SECTION_ANSWER);
12556 temprdatalist = NULL;
12557 temprdataset = NULL;
12558 temprdata = NULL;
12559 tempname = NULL;
12560
12561 soa_cleanup:
12562 if (node != NULL)
12563 dns_db_detachnode(zonedb, &node);
12564 if (version != NULL)
12565 dns_db_closeversion(zonedb, &version, ISC_FALSE);
12566 if (zonedb != NULL)
12567 dns_db_detach(&zonedb);
12568 if (tempname != NULL)
12569 dns_message_puttempname(message, &tempname);
12570 if (temprdata != NULL)
12571 dns_message_puttemprdata(message, &temprdata);
12572 if (temprdataset != NULL)
12573 dns_message_puttemprdataset(message, &temprdataset);
12574 if (temprdatalist != NULL)
12575 dns_message_puttemprdatalist(message, &temprdatalist);
12576
12577 done:
12578 *messagep = message;
12579 return (ISC_R_SUCCESS);
12580
12581 cleanup:
12582 if (tempname != NULL)
12583 dns_message_puttempname(message, &tempname);
12584 if (temprdataset != NULL)
12585 dns_message_puttemprdataset(message, &temprdataset);
12586 dns_message_destroy(&message);
12587 return (result);
12588 }
12589
12590 isc_result_t
12591 dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from,
12592 dns_message_t *msg)
12593 {
12594 unsigned int i;
12595 dns_rdata_soa_t soa;
12596 dns_rdataset_t *rdataset = NULL;
12597 dns_rdata_t rdata = DNS_RDATA_INIT;
12598 isc_result_t result;
12599 char fromtext[ISC_SOCKADDR_FORMATSIZE];
12600 int match = 0;
12601 isc_netaddr_t netaddr;
12602 isc_sockaddr_t local, remote;
12603 isc_uint32_t serial = 0;
12604 isc_boolean_t have_serial = ISC_FALSE;
12605 dns_tsigkey_t *tsigkey;
12606 dns_name_t *tsig;
12607
12608 REQUIRE(DNS_ZONE_VALID(zone));
12609
12610
12611
12612
12613
12614
12615
12616
12617
12618
12619
12620
12621
12622
12623
12624
12625
12626
12627
12628
12629
12630 isc_sockaddr_format(from, fromtext, sizeof(fromtext));
12631
12632
12633
12634
12635 LOCK_ZONE(zone);
12636 INSIST(zone != zone->raw);
12637 if (inline_secure(zone)) {
12638 result = dns_zone_notifyreceive(zone->raw, from, msg);
12639 UNLOCK_ZONE(zone);
12640 return (result);
12641 }
12642
12643
12644
12645 if (isc_sockaddr_pf(from) == PF_INET)
12646 inc_stats(zone, dns_zonestatscounter_notifyinv4);
12647 else
12648 inc_stats(zone, dns_zonestatscounter_notifyinv6);
12649 if (msg->counts[DNS_SECTION_QUESTION] == 0 ||
12650 dns_message_findname(msg, DNS_SECTION_QUESTION, &zone->origin,
12651 dns_rdatatype_soa, dns_rdatatype_none,
12652 NULL, NULL) != ISC_R_SUCCESS) {
12653 UNLOCK_ZONE(zone);
12654 if (msg->counts[DNS_SECTION_QUESTION] == 0) {
12655 dns_zone_log(zone, ISC_LOG_NOTICE,
12656 "NOTIFY with no "
12657 "question section from: %s", fromtext);
12658 return (DNS_R_FORMERR);
12659 }
12660 dns_zone_log(zone, ISC_LOG_NOTICE,
12661 "NOTIFY zone does not match");
12662 return (DNS_R_NOTIMP);
12663 }
12664
12665
12666
12667
12668 if (zone->type == dns_zone_master) {
12669 UNLOCK_ZONE(zone);
12670 return (ISC_R_SUCCESS);
12671 }
12672
12673 isc_netaddr_fromsockaddr(&netaddr, from);
12674 for (i = 0; i < zone->masterscnt; i++) {
12675 if (isc_sockaddr_eqaddr(from, &zone->masters[i]))
12676 break;
12677 if (zone->view->aclenv.match_mapped &&
12678 IN6_IS_ADDR_V4MAPPED(&from->type.sin6.sin6_addr) &&
12679 isc_sockaddr_pf(&zone->masters[i]) == AF_INET) {
12680 isc_netaddr_t na1, na2;
12681 isc_netaddr_fromv4mapped(&na1, &netaddr);
12682 isc_netaddr_fromsockaddr(&na2, &zone->masters[i]);
12683 if (isc_netaddr_equal(&na1, &na2))
12684 break;
12685 }
12686 }
12687
12688
12689
12690
12691
12692 tsigkey = dns_message_gettsigkey(msg);
12693 tsig = dns_tsigkey_identity(tsigkey);
12694 if (i >= zone->masterscnt && zone->notify_acl != NULL &&
12695 dns_acl_match(&netaddr, tsig, zone->notify_acl,
12696 &zone->view->aclenv,
12697 &match, NULL) == ISC_R_SUCCESS &&
12698 match > 0)
12699 {
12700
12701 } else if (i >= zone->masterscnt) {
12702 UNLOCK_ZONE(zone);
12703 dns_zone_log(zone, ISC_LOG_INFO,
12704 "refused notify from non-master: %s", fromtext);
12705 inc_stats(zone, dns_zonestatscounter_notifyrej);
12706 return (DNS_R_REFUSED);
12707 }
12708
12709
12710
12711
12712
12713
12714
12715 if (msg->counts[DNS_SECTION_ANSWER] > 0 &&
12716 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
12717 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH)) {
12718 result = dns_message_findname(msg, DNS_SECTION_ANSWER,
12719 &zone->origin,
12720 dns_rdatatype_soa,
12721 dns_rdatatype_none, NULL,
12722 &rdataset);
12723 if (result == ISC_R_SUCCESS)
12724 result = dns_rdataset_first(rdataset);
12725 if (result == ISC_R_SUCCESS) {
12726 isc_uint32_t oldserial;
12727 unsigned int soacount;
12728
12729 dns_rdataset_current(rdataset, &rdata);
12730 result = dns_rdata_tostruct(&rdata, &soa, NULL);
12731 RUNTIME_CHECK(result == ISC_R_SUCCESS);
12732 serial = soa.serial;
12733 have_serial = ISC_TRUE;
12734
12735
12736
12737
12738 result = zone_get_from_db(zone, zone->db, NULL,
12739 &soacount, &oldserial, NULL,
12740 NULL, NULL, NULL, NULL);
12741 RUNTIME_CHECK(result == ISC_R_SUCCESS);
12742 RUNTIME_CHECK(soacount > 0U);
12743 if (isc_serial_le(serial, oldserial)) {
12744 dns_zone_log(zone,
12745 ISC_LOG_INFO,
12746 "notify from %s: "
12747 "zone is up to date",
12748 fromtext);
12749 UNLOCK_ZONE(zone);
12750 return (ISC_R_SUCCESS);
12751 }
12752 }
12753 }
12754
12755
12756
12757
12758
12759
12760 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH)) {
12761 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
12762 zone->notifyfrom = *from;
12763 UNLOCK_ZONE(zone);
12764 if (have_serial)
12765 dns_zone_log(zone, ISC_LOG_INFO,
12766 "notify from %s: serial %u: refresh in "
12767 "progress, refresh check queued",
12768 fromtext, serial);
12769 else
12770 dns_zone_log(zone, ISC_LOG_INFO,
12771 "notify from %s: refresh in progress, "
12772 "refresh check queued", fromtext);
12773 return (ISC_R_SUCCESS);
12774 }
12775 if (have_serial)
12776 dns_zone_log(zone, ISC_LOG_INFO, "notify from %s: serial %u",
12777 fromtext, serial);
12778 else
12779 dns_zone_log(zone, ISC_LOG_INFO, "notify from %s: no serial",
12780 fromtext);
12781 zone->notifyfrom = *from;
12782 local = zone->masteraddr;
12783 remote = zone->sourceaddr;
12784 UNLOCK_ZONE(zone);
12785 dns_zonemgr_unreachabledel(zone->zmgr, &local, &remote);
12786 dns_zone_refresh(zone);
12787 return (ISC_R_SUCCESS);
12788 }
12789
12790 void
12791 dns_zone_setnotifyacl(dns_zone_t *zone, dns_acl_t *acl) {
12792
12793 REQUIRE(DNS_ZONE_VALID(zone));
12794
12795 LOCK_ZONE(zone);
12796 if (zone->notify_acl != NULL)
12797 dns_acl_detach(&zone->notify_acl);
12798 dns_acl_attach(acl, &zone->notify_acl);
12799 UNLOCK_ZONE(zone);
12800 }
12801
12802 void
12803 dns_zone_setqueryacl(dns_zone_t *zone, dns_acl_t *acl) {
12804
12805 REQUIRE(DNS_ZONE_VALID(zone));
12806
12807 LOCK_ZONE(zone);
12808 if (zone->query_acl != NULL)
12809 dns_acl_detach(&zone->query_acl);
12810 dns_acl_attach(acl, &zone->query_acl);
12811 UNLOCK_ZONE(zone);
12812 }
12813
12814 void
12815 dns_zone_setqueryonacl(dns_zone_t *zone, dns_acl_t *acl) {
12816
12817 REQUIRE(DNS_ZONE_VALID(zone));
12818
12819 LOCK_ZONE(zone);
12820 if (zone->queryon_acl != NULL)
12821 dns_acl_detach(&zone->queryon_acl);
12822 dns_acl_attach(acl, &zone->queryon_acl);
12823 UNLOCK_ZONE(zone);
12824 }
12825
12826 void
12827 dns_zone_setupdateacl(dns_zone_t *zone, dns_acl_t *acl) {
12828
12829 REQUIRE(DNS_ZONE_VALID(zone));
12830
12831 LOCK_ZONE(zone);
12832 if (zone->update_acl != NULL)
12833 dns_acl_detach(&zone->update_acl);
12834 dns_acl_attach(acl, &zone->update_acl);
12835 UNLOCK_ZONE(zone);
12836 }
12837
12838 void
12839 dns_zone_setforwardacl(dns_zone_t *zone, dns_acl_t *acl) {
12840
12841 REQUIRE(DNS_ZONE_VALID(zone));
12842
12843 LOCK_ZONE(zone);
12844 if (zone->forward_acl != NULL)
12845 dns_acl_detach(&zone->forward_acl);
12846 dns_acl_attach(acl, &zone->forward_acl);
12847 UNLOCK_ZONE(zone);
12848 }
12849
12850 void
12851 dns_zone_setxfracl(dns_zone_t *zone, dns_acl_t *acl) {
12852
12853 REQUIRE(DNS_ZONE_VALID(zone));
12854
12855 LOCK_ZONE(zone);
12856 if (zone->xfr_acl != NULL)
12857 dns_acl_detach(&zone->xfr_acl);
12858 dns_acl_attach(acl, &zone->xfr_acl);
12859 UNLOCK_ZONE(zone);
12860 }
12861
12862 dns_acl_t *
12863 dns_zone_getnotifyacl(dns_zone_t *zone) {
12864
12865 REQUIRE(DNS_ZONE_VALID(zone));
12866
12867 return (zone->notify_acl);
12868 }
12869
12870 dns_acl_t *
12871 dns_zone_getqueryacl(dns_zone_t *zone) {
12872
12873 REQUIRE(DNS_ZONE_VALID(zone));
12874
12875 return (zone->query_acl);
12876 }
12877
12878 dns_acl_t *
12879 dns_zone_getqueryonacl(dns_zone_t *zone) {
12880
12881 REQUIRE(DNS_ZONE_VALID(zone));
12882
12883 return (zone->queryon_acl);
12884 }
12885
12886 dns_acl_t *
12887 dns_zone_getupdateacl(dns_zone_t *zone) {
12888
12889 REQUIRE(DNS_ZONE_VALID(zone));
12890
12891 return (zone->update_acl);
12892 }
12893
12894 dns_acl_t *
12895 dns_zone_getforwardacl(dns_zone_t *zone) {
12896
12897 REQUIRE(DNS_ZONE_VALID(zone));
12898
12899 return (zone->forward_acl);
12900 }
12901
12902 dns_acl_t *
12903 dns_zone_getxfracl(dns_zone_t *zone) {
12904
12905 REQUIRE(DNS_ZONE_VALID(zone));
12906
12907 return (zone->xfr_acl);
12908 }
12909
12910 void
12911 dns_zone_clearupdateacl(dns_zone_t *zone) {
12912
12913 REQUIRE(DNS_ZONE_VALID(zone));
12914
12915 LOCK_ZONE(zone);
12916 if (zone->update_acl != NULL)
12917 dns_acl_detach(&zone->update_acl);
12918 UNLOCK_ZONE(zone);
12919 }
12920
12921 void
12922 dns_zone_clearforwardacl(dns_zone_t *zone) {
12923
12924 REQUIRE(DNS_ZONE_VALID(zone));
12925
12926 LOCK_ZONE(zone);
12927 if (zone->forward_acl != NULL)
12928 dns_acl_detach(&zone->forward_acl);
12929 UNLOCK_ZONE(zone);
12930 }
12931
12932 void
12933 dns_zone_clearnotifyacl(dns_zone_t *zone) {
12934
12935 REQUIRE(DNS_ZONE_VALID(zone));
12936
12937 LOCK_ZONE(zone);
12938 if (zone->notify_acl != NULL)
12939 dns_acl_detach(&zone->notify_acl);
12940 UNLOCK_ZONE(zone);
12941 }
12942
12943 void
12944 dns_zone_clearqueryacl(dns_zone_t *zone) {
12945
12946 REQUIRE(DNS_ZONE_VALID(zone));
12947
12948 LOCK_ZONE(zone);
12949 if (zone->query_acl != NULL)
12950 dns_acl_detach(&zone->query_acl);
12951 UNLOCK_ZONE(zone);
12952 }
12953
12954 void
12955 dns_zone_clearqueryonacl(dns_zone_t *zone) {
12956
12957 REQUIRE(DNS_ZONE_VALID(zone));
12958
12959 LOCK_ZONE(zone);
12960 if (zone->queryon_acl != NULL)
12961 dns_acl_detach(&zone->queryon_acl);
12962 UNLOCK_ZONE(zone);
12963 }
12964
12965 void
12966 dns_zone_clearxfracl(dns_zone_t *zone) {
12967
12968 REQUIRE(DNS_ZONE_VALID(zone));
12969
12970 LOCK_ZONE(zone);
12971 if (zone->xfr_acl != NULL)
12972 dns_acl_detach(&zone->xfr_acl);
12973 UNLOCK_ZONE(zone);
12974 }
12975
12976 isc_boolean_t
12977 dns_zone_getupdatedisabled(dns_zone_t *zone) {
12978 REQUIRE(DNS_ZONE_VALID(zone));
12979 return (zone->update_disabled);
12980
12981 }
12982
12983 void
12984 dns_zone_setupdatedisabled(dns_zone_t *zone, isc_boolean_t state) {
12985 REQUIRE(DNS_ZONE_VALID(zone));
12986 zone->update_disabled = state;
12987 }
12988
12989 isc_boolean_t
12990 dns_zone_getzeronosoattl(dns_zone_t *zone) {
12991 REQUIRE(DNS_ZONE_VALID(zone));
12992 return (zone->zero_no_soa_ttl);
12993
12994 }
12995
12996 void
12997 dns_zone_setzeronosoattl(dns_zone_t *zone, isc_boolean_t state) {
12998 REQUIRE(DNS_ZONE_VALID(zone));
12999 zone->zero_no_soa_ttl = state;
13000 }
13001
13002 void
13003 dns_zone_setchecknames(dns_zone_t *zone, dns_severity_t severity) {
13004
13005 REQUIRE(DNS_ZONE_VALID(zone));
13006
13007 zone->check_names = severity;
13008 }
13009
13010 dns_severity_t
13011 dns_zone_getchecknames(dns_zone_t *zone) {
13012
13013 REQUIRE(DNS_ZONE_VALID(zone));
13014
13015 return (zone->check_names);
13016 }
13017
13018 void
13019 dns_zone_setjournalsize(dns_zone_t *zone, isc_int32_t size) {
13020
13021 REQUIRE(DNS_ZONE_VALID(zone));
13022
13023 zone->journalsize = size;
13024 }
13025
13026 isc_int32_t
13027 dns_zone_getjournalsize(dns_zone_t *zone) {
13028
13029 REQUIRE(DNS_ZONE_VALID(zone));
13030
13031 return (zone->journalsize);
13032 }
13033
13034 static void
13035 zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length) {
13036 isc_result_t result = ISC_R_FAILURE;
13037 isc_buffer_t buffer;
13038
13039 REQUIRE(buf != NULL);
13040 REQUIRE(length > 1U);
13041
13042
13043
13044
13045 isc_buffer_init(&buffer, buf, (unsigned int)length - 1);
13046 if (zone->type != dns_zone_redirect && zone->type != dns_zone_key) {
13047 if (dns_name_dynamic(&zone->origin))
13048 result = dns_name_totext(&zone->origin, ISC_TRUE, &buffer);
13049 if (result != ISC_R_SUCCESS &&
13050 isc_buffer_availablelength(&buffer) >= (sizeof("<UNKNOWN>") - 1))
13051 isc_buffer_putstr(&buffer, "<UNKNOWN>");
13052
13053 if (isc_buffer_availablelength(&buffer) > 0)
13054 isc_buffer_putstr(&buffer, "/");
13055 (void)dns_rdataclass_totext(zone->rdclass, &buffer);
13056 }
13057
13058 if (zone->view != NULL && strcmp(zone->view->name, "_bind") != 0 &&
13059 strcmp(zone->view->name, "_default") != 0 &&
13060 strlen(zone->view->name) < isc_buffer_availablelength(&buffer)) {
13061 isc_buffer_putstr(&buffer, "/");
13062 isc_buffer_putstr(&buffer, zone->view->name);
13063 }
13064 if (inline_secure(zone) && 9U < isc_buffer_availablelength(&buffer))
13065 isc_buffer_putstr(&buffer, " (signed)");
13066 if (inline_raw(zone) && 11U < isc_buffer_availablelength(&buffer))
13067 isc_buffer_putstr(&buffer, " (unsigned)");
13068
13069 buf[isc_buffer_usedlength(&buffer)] = '\0';
13070 }
13071
13072 static void
13073 zone_name_tostr(dns_zone_t *zone, char *buf, size_t length) {
13074 isc_result_t result = ISC_R_FAILURE;
13075 isc_buffer_t buffer;
13076
13077 REQUIRE(buf != NULL);
13078 REQUIRE(length > 1U);
13079
13080
13081
13082
13083 isc_buffer_init(&buffer, buf, (unsigned int)length - 1);
13084 if (dns_name_dynamic(&zone->origin))
13085 result = dns_name_totext(&zone->origin, ISC_TRUE, &buffer);
13086 if (result != ISC_R_SUCCESS &&
13087 isc_buffer_availablelength(&buffer) >= (sizeof("<UNKNOWN>") - 1))
13088 isc_buffer_putstr(&buffer, "<UNKNOWN>");
13089
13090 buf[isc_buffer_usedlength(&buffer)] = '\0';
13091 }
13092
13093 static void
13094 zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length) {
13095 isc_buffer_t buffer;
13096
13097 REQUIRE(buf != NULL);
13098 REQUIRE(length > 1U);
13099
13100
13101
13102
13103 isc_buffer_init(&buffer, buf, (unsigned int)length - 1);
13104 (void)dns_rdataclass_totext(zone->rdclass, &buffer);
13105
13106 buf[isc_buffer_usedlength(&buffer)] = '\0';
13107 }
13108
13109 static void
13110 zone_viewname_tostr(dns_zone_t *zone, char *buf, size_t length) {
13111 isc_buffer_t buffer;
13112
13113 REQUIRE(buf != NULL);
13114 REQUIRE(length > 1U);
13115
13116
13117
13118
13119
13120 isc_buffer_init(&buffer, buf, (unsigned int)length - 1);
13121
13122 if (zone->view == NULL) {
13123 isc_buffer_putstr(&buffer, "_none");
13124 } else if (strlen(zone->view->name)
13125 < isc_buffer_availablelength(&buffer)) {
13126 isc_buffer_putstr(&buffer, zone->view->name);
13127 } else {
13128 isc_buffer_putstr(&buffer, "_toolong");
13129 }
13130
13131 buf[isc_buffer_usedlength(&buffer)] = '\0';
13132 }
13133
13134 void
13135 dns_zone_name(dns_zone_t *zone, char *buf, size_t length) {
13136 REQUIRE(DNS_ZONE_VALID(zone));
13137 REQUIRE(buf != NULL);
13138 zone_namerd_tostr(zone, buf, length);
13139 }
13140
13141 static void
13142 notify_log(dns_zone_t *zone, int level, const char *fmt, ...) {
13143 va_list ap;
13144 char message[4096];
13145
13146 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
13147 return;
13148
13149 va_start(ap, fmt);
13150 vsnprintf(message, sizeof(message), fmt, ap);
13151 va_end(ap);
13152 isc_log_write(dns_lctx, DNS_LOGCATEGORY_NOTIFY, DNS_LOGMODULE_ZONE,
13153 level, "zone %s: %s", zone->strnamerd, message);
13154 }
13155
13156 void
13157 dns_zone_logc(dns_zone_t *zone, isc_logcategory_t *category,
13158 int level, const char *fmt, ...) {
13159 va_list ap;
13160 char message[4096];
13161
13162 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
13163 return;
13164
13165 va_start(ap, fmt);
13166 vsnprintf(message, sizeof(message), fmt, ap);
13167 va_end(ap);
13168 isc_log_write(dns_lctx, category, DNS_LOGMODULE_ZONE,
13169 level, "%s%s: %s", (zone->type == dns_zone_key) ?
13170 "managed-keys-zone" : (zone->type == dns_zone_redirect) ?
13171 "redirect-zone" : "zone ", zone->strnamerd, message);
13172 }
13173
13174 void
13175 dns_zone_log(dns_zone_t *zone, int level, const char *fmt, ...) {
13176 va_list ap;
13177 char message[4096];
13178
13179 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
13180 return;
13181
13182 va_start(ap, fmt);
13183 vsnprintf(message, sizeof(message), fmt, ap);
13184 va_end(ap);
13185 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE,
13186 level, "%s%s: %s", (zone->type == dns_zone_key) ?
13187 "managed-keys-zone" : (zone->type == dns_zone_redirect) ?
13188 "redirect-zone" : "zone ", zone->strnamerd, message);
13189 }
13190
13191 static void
13192 zone_debuglog(dns_zone_t *zone, const char *me, int debuglevel,
13193 const char *fmt, ...)
13194 {
13195 va_list ap;
13196 char message[4096];
13197 int level = ISC_LOG_DEBUG(debuglevel);
13198 const char *zstr;
13199
13200 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
13201 return;
13202
13203 va_start(ap, fmt);
13204 vsnprintf(message, sizeof(message), fmt, ap);
13205 va_end(ap);
13206
13207 switch (zone->type) {
13208 case dns_zone_key:
13209 zstr = "managed-keys-zone";
13210 break;
13211 case dns_zone_redirect:
13212 zstr = "redirect-zone";
13213 break;
13214 default:
13215 zstr = "zone";
13216 }
13217
13218 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE,
13219 level, "%s: %s %s: %s", me, zstr, zone->strnamerd,
13220 message);
13221 }
13222
13223 static int
13224 message_count(dns_message_t *msg, dns_section_t section, dns_rdatatype_t type)
13225 {
13226 isc_result_t result;
13227 dns_name_t *name;
13228 dns_rdataset_t *curr;
13229 int count = 0;
13230
13231 result = dns_message_firstname(msg, section);
13232 while (result == ISC_R_SUCCESS) {
13233 name = NULL;
13234 dns_message_currentname(msg, section, &name);
13235
13236 for (curr = ISC_LIST_TAIL(name->list); curr != NULL;
13237 curr = ISC_LIST_PREV(curr, link)) {
13238 if (curr->type == type)
13239 count++;
13240 }
13241 result = dns_message_nextname(msg, section);
13242 }
13243
13244 return (count);
13245 }
13246
13247 void
13248 dns_zone_setmaxxfrin(dns_zone_t *zone, isc_uint32_t maxxfrin) {
13249 REQUIRE(DNS_ZONE_VALID(zone));
13250
13251 zone->maxxfrin = maxxfrin;
13252 }
13253
13254 isc_uint32_t
13255 dns_zone_getmaxxfrin(dns_zone_t *zone) {
13256 REQUIRE(DNS_ZONE_VALID(zone));
13257
13258 return (zone->maxxfrin);
13259 }
13260
13261 void
13262 dns_zone_setmaxxfrout(dns_zone_t *zone, isc_uint32_t maxxfrout) {
13263 REQUIRE(DNS_ZONE_VALID(zone));
13264 zone->maxxfrout = maxxfrout;
13265 }
13266
13267 isc_uint32_t
13268 dns_zone_getmaxxfrout(dns_zone_t *zone) {
13269 REQUIRE(DNS_ZONE_VALID(zone));
13270
13271 return (zone->maxxfrout);
13272 }
13273
13274 dns_zonetype_t
13275 dns_zone_gettype(dns_zone_t *zone) {
13276 REQUIRE(DNS_ZONE_VALID(zone));
13277
13278 return (zone->type);
13279 }
13280
13281 dns_name_t *
13282 dns_zone_getorigin(dns_zone_t *zone) {
13283 REQUIRE(DNS_ZONE_VALID(zone));
13284
13285 return (&zone->origin);
13286 }
13287
13288 void
13289 dns_zone_settask(dns_zone_t *zone, isc_task_t *task) {
13290 REQUIRE(DNS_ZONE_VALID(zone));
13291
13292 LOCK_ZONE(zone);
13293 if (zone->task != NULL)
13294 isc_task_detach(&zone->task);
13295 isc_task_attach(task, &zone->task);
13296 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
13297 if (zone->db != NULL)
13298 dns_db_settask(zone->db, zone->task);
13299 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
13300 UNLOCK_ZONE(zone);
13301 }
13302
13303 void
13304 dns_zone_gettask(dns_zone_t *zone, isc_task_t **target) {
13305 REQUIRE(DNS_ZONE_VALID(zone));
13306 isc_task_attach(zone->task, target);
13307 }
13308
13309 void
13310 dns_zone_setidlein(dns_zone_t *zone, isc_uint32_t idlein) {
13311 REQUIRE(DNS_ZONE_VALID(zone));
13312
13313 if (idlein == 0)
13314 idlein = DNS_DEFAULT_IDLEIN;
13315 zone->idlein = idlein;
13316 }
13317
13318 isc_uint32_t
13319 dns_zone_getidlein(dns_zone_t *zone) {
13320 REQUIRE(DNS_ZONE_VALID(zone));
13321
13322 return (zone->idlein);
13323 }
13324
13325 void
13326 dns_zone_setidleout(dns_zone_t *zone, isc_uint32_t idleout) {
13327 REQUIRE(DNS_ZONE_VALID(zone));
13328
13329 zone->idleout = idleout;
13330 }
13331
13332 isc_uint32_t
13333 dns_zone_getidleout(dns_zone_t *zone) {
13334 REQUIRE(DNS_ZONE_VALID(zone));
13335
13336 return (zone->idleout);
13337 }
13338
13339 static void
13340 notify_done(isc_task_t *task, isc_event_t *event) {
13341 dns_requestevent_t *revent = (dns_requestevent_t *)event;
13342 dns_notify_t *notify;
13343 isc_result_t result;
13344 dns_message_t *message = NULL;
13345 isc_buffer_t buf;
13346 char rcode[128];
13347 char addrbuf[ISC_SOCKADDR_FORMATSIZE];
13348
13349 UNUSED(task);
13350
13351 notify = event->ev_arg;
13352 REQUIRE(DNS_NOTIFY_VALID(notify));
13353 INSIST(task == notify->zone->task);
13354
13355 isc_buffer_init(&buf, rcode, sizeof(rcode));
13356 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf));
13357
13358 result = revent->result;
13359 if (result == ISC_R_SUCCESS)
13360 result = dns_message_create(notify->zone->mctx,
13361 DNS_MESSAGE_INTENTPARSE, &message);
13362 if (result == ISC_R_SUCCESS)
13363 result = dns_request_getresponse(revent->request, message,
13364 DNS_MESSAGEPARSE_PRESERVEORDER);
13365 if (result == ISC_R_SUCCESS)
13366 result = dns_rcode_totext(message->rcode, &buf);
13367 if (result == ISC_R_SUCCESS)
13368 notify_log(notify->zone, ISC_LOG_DEBUG(3),
13369 "notify response from %s: %.*s",
13370 addrbuf, (int)buf.used, rcode);
13371 else
13372 notify_log(notify->zone, ISC_LOG_DEBUG(2),
13373 "notify to %s failed: %s", addrbuf,
13374 dns_result_totext(result));
13375
13376
13377
13378
13379
13380 isc_event_free(&event);
13381 if (message != NULL && message->rcode == dns_rcode_formerr &&
13382 (notify->flags & DNS_NOTIFY_NOSOA) == 0) {
13383 isc_boolean_t startup;
13384
13385 notify->flags |= DNS_NOTIFY_NOSOA;
13386 dns_request_destroy(¬ify->request);
13387 startup = ISC_TF((notify->flags & DNS_NOTIFY_STARTUP) != 0);
13388 result = notify_send_queue(notify, startup);
13389 if (result != ISC_R_SUCCESS)
13390 notify_destroy(notify, ISC_FALSE);
13391 } else {
13392 if (result == ISC_R_TIMEDOUT)
13393 notify_log(notify->zone, ISC_LOG_DEBUG(1),
13394 "notify to %s: retries exceeded", addrbuf);
13395 notify_destroy(notify, ISC_FALSE);
13396 }
13397 if (message != NULL)
13398 dns_message_destroy(&message);
13399 }
13400
13401 struct secure_event {
13402 isc_event_t e;
13403 dns_db_t *db;
13404 isc_uint32_t serial;
13405 };
13406
13407 static void
13408 update_log_cb(void *arg, dns_zone_t *zone, int level, const char *message) {
13409 UNUSED(arg);
13410 dns_zone_log(zone, level, "%s", message);
13411 }
13412
13413 static isc_result_t
13414 sync_secure_journal(dns_zone_t *zone, dns_zone_t *raw, dns_journal_t *journal,
13415 isc_uint32_t start, isc_uint32_t end,
13416 dns_difftuple_t **soatuplep, dns_diff_t *diff)
13417 {
13418 isc_result_t result;
13419 dns_difftuple_t *tuple = NULL;
13420 dns_diffop_t op = DNS_DIFFOP_ADD;
13421 int n_soa = 0;
13422
13423 REQUIRE(soatuplep != NULL);
13424
13425 if (start == end)
13426 return (DNS_R_UNCHANGED);
13427
13428 CHECK(dns_journal_iter_init(journal, start, end));
13429 for (result = dns_journal_first_rr(journal);
13430 result == ISC_R_SUCCESS;
13431 result = dns_journal_next_rr(journal))
13432 {
13433 dns_name_t *name = NULL;
13434 isc_uint32_t ttl;
13435 dns_rdata_t *rdata = NULL;
13436 dns_journal_current_rr(journal, &name, &ttl, &rdata);
13437
13438 if (rdata->type == dns_rdatatype_soa) {
13439 n_soa++;
13440 if (n_soa == 2) {
13441
13442
13443
13444 if (*soatuplep != NULL)
13445 dns_difftuple_free(soatuplep);
13446 CHECK(dns_difftuple_create(diff->mctx,
13447 DNS_DIFFOP_ADD,
13448 name, ttl, rdata,
13449 soatuplep));
13450 }
13451 if (n_soa == 3)
13452 n_soa = 1;
13453 continue;
13454 }
13455
13456
13457 if (n_soa == 0) {
13458 dns_zone_log(raw, ISC_LOG_ERROR,
13459 "corrupt journal file: '%s'\n",
13460 raw->journal);
13461 return (ISC_R_FAILURE);
13462 }
13463
13464 if (zone->privatetype != 0 &&
13465 rdata->type == zone->privatetype)
13466 continue;
13467
13468 if (rdata->type == dns_rdatatype_nsec ||
13469 rdata->type == dns_rdatatype_rrsig ||
13470 rdata->type == dns_rdatatype_nsec3 ||
13471 rdata->type == dns_rdatatype_dnskey ||
13472 rdata->type == dns_rdatatype_nsec3param)
13473 continue;
13474
13475 op = (n_soa == 1) ? DNS_DIFFOP_DEL : DNS_DIFFOP_ADD;
13476
13477 CHECK(dns_difftuple_create(diff->mctx, op, name, ttl, rdata,
13478 &tuple));
13479 dns_diff_appendminimal(diff, &tuple);
13480 }
13481 if (result == ISC_R_NOMORE)
13482 result = ISC_R_SUCCESS;
13483
13484 failure:
13485 return(result);
13486 }
13487
13488 static isc_result_t
13489 sync_secure_db(dns_zone_t *seczone, dns_zone_t *raw, dns_db_t *secdb,
13490 dns_dbversion_t *secver, dns_difftuple_t **soatuple,
13491 dns_diff_t *diff)
13492 {
13493 isc_result_t result;
13494 dns_db_t *rawdb = NULL;
13495 dns_dbversion_t *rawver = NULL;
13496 dns_difftuple_t *tuple = NULL, *next;
13497 dns_difftuple_t *oldtuple = NULL, *newtuple = NULL;
13498 dns_rdata_soa_t oldsoa, newsoa;
13499
13500 REQUIRE(DNS_ZONE_VALID(seczone));
13501 REQUIRE(soatuple != NULL && *soatuple == NULL);
13502
13503 if (!seczone->sourceserialset)
13504 return (DNS_R_UNCHANGED);
13505
13506 dns_db_attach(raw->db, &rawdb);
13507 dns_db_currentversion(rawdb, &rawver);
13508 result = dns_db_diffx(diff, rawdb, rawver, secdb, secver, NULL);
13509 dns_db_closeversion(rawdb, &rawver, ISC_FALSE);
13510 dns_db_detach(&rawdb);
13511
13512 if (result != ISC_R_SUCCESS)
13513 return (result);
13514
13515 for (tuple = ISC_LIST_HEAD(diff->tuples);
13516 tuple != NULL;
13517 tuple = next)
13518 {
13519 next = ISC_LIST_NEXT(tuple, link);
13520 if (tuple->rdata.type == dns_rdatatype_nsec ||
13521 tuple->rdata.type == dns_rdatatype_rrsig ||
13522 tuple->rdata.type == dns_rdatatype_dnskey ||
13523 tuple->rdata.type == dns_rdatatype_nsec3 ||
13524 tuple->rdata.type == dns_rdatatype_nsec3param)
13525 {
13526 ISC_LIST_UNLINK(diff->tuples, tuple, link);
13527 dns_difftuple_free(&tuple);
13528 continue;
13529 }
13530 if (tuple->rdata.type == dns_rdatatype_soa) {
13531 if (tuple->op == DNS_DIFFOP_DEL) {
13532 INSIST(oldtuple == NULL);
13533 oldtuple = tuple;
13534 }
13535 if (tuple->op == DNS_DIFFOP_ADD) {
13536 INSIST(newtuple == NULL);
13537 newtuple = tuple;
13538 }
13539 }
13540 }
13541
13542 if (oldtuple != NULL && newtuple != NULL) {
13543
13544 result = dns_rdata_tostruct(&oldtuple->rdata, &oldsoa, NULL);
13545 RUNTIME_CHECK(result == ISC_R_SUCCESS);
13546
13547 result = dns_rdata_tostruct(&newtuple->rdata, &newsoa, NULL);
13548 RUNTIME_CHECK(result == ISC_R_SUCCESS);
13549
13550
13551
13552
13553
13554 if (oldsoa.refresh == newsoa.refresh &&
13555 oldsoa.retry == newsoa.retry &&
13556 oldsoa.minimum == newsoa.minimum &&
13557 oldsoa.expire == newsoa.expire &&
13558 dns_name_equal(&oldsoa.origin, &newsoa.origin) &&
13559 dns_name_equal(&oldsoa.contact, &newsoa.contact)) {
13560 ISC_LIST_UNLINK(diff->tuples, oldtuple, link);
13561 dns_difftuple_free(&oldtuple);
13562 ISC_LIST_UNLINK(diff->tuples, newtuple, link);
13563 dns_difftuple_free(&newtuple);
13564 }
13565 }
13566
13567 if (ISC_LIST_EMPTY(diff->tuples))
13568 return (DNS_R_UNCHANGED);
13569
13570
13571
13572
13573
13574 if (oldtuple != NULL) {
13575 ISC_LIST_UNLINK(diff->tuples, oldtuple, link);
13576 dns_difftuple_free(&oldtuple);
13577 }
13578
13579 if (newtuple != NULL) {
13580 ISC_LIST_UNLINK(diff->tuples, newtuple, link);
13581 *soatuple = newtuple;
13582 }
13583
13584 return (ISC_R_SUCCESS);
13585 }
13586
13587 static void
13588 receive_secure_serial(isc_task_t *task, isc_event_t *event) {
13589 static char me[] = "receive_secure_serial";
13590 isc_result_t result = ISC_R_SUCCESS;
13591 dns_journal_t *rjournal = NULL;
13592 dns_journal_t *sjournal = NULL;
13593 isc_uint32_t start, end;
13594 dns_zone_t *zone;
13595 dns_difftuple_t *tuple = NULL, *soatuple = NULL;
13596 dns_update_log_t log = { update_log_cb, NULL };
13597 isc_time_t timenow;
13598
13599 UNUSED(task);
13600
13601 zone = event->ev_arg;
13602 end = ((struct secure_event *)event)->serial;
13603
13604 ENTER;
13605
13606 LOCK_ZONE(zone);
13607
13608
13609
13610
13611
13612 if (zone->rss_event != NULL && zone->rss_event != event) {
13613 ISC_LIST_APPEND(zone->rss_events, event, ev_link);
13614 UNLOCK_ZONE(zone);
13615 return;
13616 }
13617
13618 nextevent:
13619 if (zone->rss_event != NULL) {
13620 INSIST(zone->rss_event == event);
13621 UNLOCK_ZONE(zone);
13622 } else {
13623 zone->rss_event = event;
13624 dns_diff_init(zone->mctx, &zone->rss_diff);
13625
13626
13627
13628
13629 result = ISC_R_SUCCESS;
13630 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
13631 if (zone->db != NULL)
13632 dns_db_attach(zone->db, &zone->rss_db);
13633 else
13634 result = ISC_R_FAILURE;
13635 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
13636
13637 if (result == ISC_R_SUCCESS && zone->raw != NULL)
13638 dns_zone_attach(zone->raw, &zone->rss_raw);
13639 else
13640 result = ISC_R_FAILURE;
13641
13642 UNLOCK_ZONE(zone);
13643
13644 CHECK(result);
13645
13646
13647
13648
13649
13650
13651
13652
13653
13654
13655 CHECK(dns_journal_open(zone->rss_raw->mctx,
13656 zone->rss_raw->journal,
13657 DNS_JOURNAL_WRITE, &rjournal));
13658
13659 result = dns_journal_open(zone->mctx, zone->journal,
13660 DNS_JOURNAL_READ, &sjournal);
13661 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
13662 goto failure;
13663
13664 if (!dns_journal_get_sourceserial(rjournal, &start)) {
13665 start = dns_journal_first_serial(rjournal);
13666 dns_journal_set_sourceserial(rjournal, start);
13667 }
13668 if (sjournal != NULL) {
13669 isc_uint32_t serial;
13670
13671
13672
13673
13674
13675 if (dns_journal_get_sourceserial(sjournal, &serial)) {
13676 if (isc_serial_gt(serial, start))
13677 start = serial;
13678 }
13679 dns_journal_destroy(&sjournal);
13680 }
13681
13682 dns_db_currentversion(zone->rss_db, &zone->rss_oldver);
13683 CHECK(dns_db_newversion(zone->rss_db, &zone->rss_newver));
13684
13685
13686
13687
13688
13689
13690 result = sync_secure_journal(zone, zone->rss_raw, rjournal,
13691 start, end, &soatuple,
13692 &zone->rss_diff);
13693 if (result == DNS_R_UNCHANGED)
13694 goto failure;
13695 else if (result != ISC_R_SUCCESS)
13696 CHECK(sync_secure_db(zone, zone->rss_raw, zone->rss_db,
13697 zone->rss_oldver, &soatuple,
13698 &zone->rss_diff));
13699
13700 CHECK(dns_diff_apply(&zone->rss_diff, zone->rss_db,
13701 zone->rss_newver));
13702
13703 if (soatuple != NULL) {
13704 isc_uint32_t oldserial, newserial, desired;
13705
13706 CHECK(dns_db_createsoatuple(zone->rss_db,
13707 zone->rss_oldver,
13708 zone->rss_diff.mctx,
13709 DNS_DIFFOP_DEL, &tuple));
13710 oldserial = dns_soa_getserial(&tuple->rdata);
13711 newserial = desired =
13712 dns_soa_getserial(&soatuple->rdata);
13713 if (!isc_serial_gt(newserial, oldserial)) {
13714 newserial = oldserial + 1;
13715 if (newserial == 0)
13716 newserial++;
13717 dns_soa_setserial(newserial, &soatuple->rdata);
13718 }
13719 CHECK(do_one_tuple(&tuple, zone->rss_db,
13720 zone->rss_newver, &zone->rss_diff));
13721 CHECK(do_one_tuple(&soatuple, zone->rss_db,
13722 zone->rss_newver, &zone->rss_diff));
13723 dns_zone_log(zone, ISC_LOG_INFO,
13724 "serial %u (unsigned %u)",
13725 newserial, desired);
13726 } else
13727 CHECK(update_soa_serial(zone->rss_db, zone->rss_newver,
13728 &zone->rss_diff, zone->mctx,
13729 zone->updatemethod));
13730
13731 }
13732 result = dns_update_signaturesinc(&log, zone, zone->rss_db,
13733 zone->rss_oldver, zone->rss_newver,
13734 &zone->rss_diff,
13735 zone->sigvalidityinterval,
13736 &zone->rss_state);
13737 if (result == DNS_R_CONTINUE) {
13738 if (rjournal != NULL)
13739 dns_journal_destroy(&rjournal);
13740 isc_task_send(task, &event);
13741 fprintf(stderr, "looping on dns_update_signaturesinc\n");
13742 return;
13743 }
13744 if (result != ISC_R_SUCCESS)
13745 goto failure;
13746
13747 if (rjournal == NULL)
13748 CHECK(dns_journal_open(zone->rss_raw->mctx,
13749 zone->rss_raw->journal,
13750 DNS_JOURNAL_WRITE, &rjournal));
13751 CHECK(zone_journal(zone, &zone->rss_diff, &end,
13752 "receive_secure_serial"));
13753
13754 dns_journal_set_sourceserial(rjournal, end);
13755 dns_journal_commit(rjournal);
13756
13757 LOCK_ZONE(zone);
13758 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
13759
13760 zone->sourceserial = end;
13761 zone->sourceserialset = ISC_TRUE;
13762 zone_needdump(zone, DNS_DUMP_DELAY);
13763
13764 TIME_NOW(&timenow);
13765 zone_settimer(zone, &timenow);
13766 UNLOCK_ZONE(zone);
13767
13768 dns_db_closeversion(zone->rss_db, &zone->rss_oldver, ISC_FALSE);
13769 dns_db_closeversion(zone->rss_db, &zone->rss_newver, ISC_TRUE);
13770
13771 failure:
13772 isc_event_free(&zone->rss_event);
13773 event = ISC_LIST_HEAD(zone->rss_events);
13774
13775 if (zone->rss_raw != NULL)
13776 dns_zone_detach(&zone->rss_raw);
13777 if (result != ISC_R_SUCCESS)
13778 dns_zone_log(zone, ISC_LOG_ERROR, "receive_secure_serial: %s",
13779 dns_result_totext(result));
13780 if (tuple != NULL)
13781 dns_difftuple_free(&tuple);
13782 if (soatuple != NULL)
13783 dns_difftuple_free(&soatuple);
13784 if (zone->rss_db != NULL) {
13785 if (zone->rss_oldver != NULL)
13786 dns_db_closeversion(zone->rss_db, &zone->rss_oldver,
13787 ISC_FALSE);
13788 if (zone->rss_newver != NULL)
13789 dns_db_closeversion(zone->rss_db, &zone->rss_newver,
13790 ISC_FALSE);
13791 dns_db_detach(&zone->rss_db);
13792 }
13793 INSIST(zone->rss_oldver == NULL);
13794 INSIST(zone->rss_newver == NULL);
13795 if (rjournal != NULL)
13796 dns_journal_destroy(&rjournal);
13797 dns_diff_clear(&zone->rss_diff);
13798
13799 if (event != NULL) {
13800 LOCK_ZONE(zone);
13801 INSIST(zone->irefs > 1);
13802 zone->irefs--;
13803 goto nextevent;
13804 }
13805 dns_zone_idetach(&zone);
13806 }
13807
13808 static isc_result_t
13809 zone_send_secureserial(dns_zone_t *zone, isc_uint32_t serial) {
13810 isc_event_t *e;
13811 dns_zone_t *dummy = NULL;
13812
13813 e = isc_event_allocate(zone->secure->mctx, zone,
13814 DNS_EVENT_ZONESECURESERIAL,
13815 receive_secure_serial, zone->secure,
13816 sizeof(struct secure_event));
13817 if (e == NULL)
13818 return (ISC_R_NOMEMORY);
13819 ((struct secure_event *)e)->serial = serial;
13820 INSIST(LOCKED_ZONE(zone->secure));
13821 zone_iattach(zone->secure, &dummy);
13822 isc_task_send(zone->secure->task, &e);
13823
13824 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SENDSECURE);
13825 return (ISC_R_SUCCESS);
13826 }
13827
13828 static isc_result_t
13829 checkandaddsoa(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
13830 dns_rdataset_t *rdataset, isc_uint32_t oldserial)
13831 {
13832 dns_rdata_soa_t soa;
13833 dns_rdata_t rdata = DNS_RDATA_INIT;
13834 dns_rdatalist_t temprdatalist;
13835 dns_rdataset_t temprdataset;
13836 isc_buffer_t b;
13837 isc_result_t result;
13838 unsigned char buf[DNS_SOA_BUFFERSIZE];
13839 dns_fixedname_t fixed;
13840 dns_name_t *name;
13841
13842 result = dns_rdataset_first(rdataset);
13843 RUNTIME_CHECK(result == ISC_R_SUCCESS);
13844 dns_rdataset_current(rdataset, &rdata);
13845 result = dns_rdata_tostruct(&rdata, &soa, NULL);
13846 RUNTIME_CHECK(result == ISC_R_SUCCESS);
13847
13848 if (isc_serial_gt(soa.serial, oldserial))
13849 return (dns_db_addrdataset(db, node, version, 0, rdataset, 0,
13850 NULL));
13851
13852
13853
13854 oldserial++;
13855 if (oldserial == 0)
13856 oldserial++;
13857 soa.serial = oldserial;
13858
13859
13860
13861
13862 dns_rdata_reset(&rdata);
13863 isc_buffer_init(&b, buf, sizeof(buf));
13864 result = dns_rdata_fromstruct(&rdata, rdataset->rdclass,
13865 dns_rdatatype_soa, &soa, &b);
13866 RUNTIME_CHECK(result == ISC_R_SUCCESS);
13867 dns_rdatalist_init(&temprdatalist);
13868 temprdatalist.rdclass = rdata.rdclass;
13869 temprdatalist.type = rdata.type;
13870 temprdatalist.ttl = rdataset->ttl;
13871 ISC_LIST_APPEND(temprdatalist.rdata, &rdata, link);
13872
13873 dns_rdataset_init(&temprdataset);
13874 result = dns_rdatalist_tordataset(&temprdatalist, &temprdataset);
13875 RUNTIME_CHECK(result == ISC_R_SUCCESS);
13876 dns_fixedname_init(&fixed);
13877 name = dns_fixedname_name(&fixed);
13878 dns_rbtnode_nodename(node, name);
13879 dns_rdataset_getownercase(rdataset, name);
13880 dns_rdataset_setownercase(&temprdataset, name);
13881 return (dns_db_addrdataset(db, node, version, 0, &temprdataset,
13882 0, NULL));
13883 }
13884
13885
13886
13887
13888
13889 static isc_result_t
13890 save_nsec3param(dns_zone_t *zone, nsec3paramlist_t *nsec3list) {
13891 isc_result_t result;
13892 dns_dbnode_t *node = NULL;
13893 dns_rdataset_t rdataset, prdataset;
13894 dns_dbversion_t *version = NULL;
13895 nsec3param_t *nsec3param = NULL;
13896 nsec3param_t *nsec3p = NULL;
13897 nsec3param_t *next;
13898 dns_db_t *db = NULL;
13899 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
13900
13901 REQUIRE(DNS_ZONE_VALID(zone));
13902 REQUIRE(nsec3list != NULL);
13903 REQUIRE(ISC_LIST_EMPTY(*nsec3list));
13904
13905 dns_rdataset_init(&rdataset);
13906 dns_rdataset_init(&prdataset);
13907
13908 dns_db_attach(zone->db, &db);
13909 CHECK(dns_db_getoriginnode(db, &node));
13910
13911 dns_db_currentversion(db, &version);
13912 result = dns_db_findrdataset(db, node, version,
13913 dns_rdatatype_nsec3param,
13914 dns_rdatatype_none, 0, &rdataset, NULL);
13915
13916 if (result != ISC_R_SUCCESS)
13917 goto getprivate;
13918
13919
13920
13921
13922
13923
13924
13925 for (result = dns_rdataset_first(&rdataset);
13926 result == ISC_R_SUCCESS;
13927 result = dns_rdataset_next(&rdataset))
13928 {
13929 dns_rdata_t rdata = DNS_RDATA_INIT;
13930 dns_rdata_t private = DNS_RDATA_INIT;
13931
13932 dns_rdataset_current(&rdataset, &rdata);
13933 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
13934 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
13935 "looping through nsec3param data");
13936 nsec3param = isc_mem_get(zone->mctx, sizeof(nsec3param_t));
13937 if (nsec3param == NULL)
13938 CHECK(ISC_R_NOMEMORY);
13939 ISC_LINK_INIT(nsec3param, link);
13940
13941
13942
13943
13944
13945 dns_nsec3param_toprivate(&rdata, &private,
13946 zone->privatetype, nsec3param->data,
13947 sizeof(nsec3param->data));
13948 nsec3param->length = private.length;
13949 ISC_LIST_APPEND(*nsec3list, nsec3param, link);
13950 }
13951
13952 getprivate:
13953 result = dns_db_findrdataset(db, node, version, zone->privatetype,
13954 dns_rdatatype_none, 0, &prdataset, NULL);
13955 if (result != ISC_R_SUCCESS)
13956 goto done;
13957
13958
13959
13960
13961
13962
13963 for (result = dns_rdataset_first(&prdataset);
13964 result == ISC_R_SUCCESS;
13965 result = dns_rdataset_next(&prdataset))
13966 {
13967 dns_rdata_t rdata = DNS_RDATA_INIT;
13968 dns_rdata_t private = DNS_RDATA_INIT;
13969
13970 dns_rdataset_current(&prdataset, &private);
13971 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
13972 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
13973 "looping through nsec3param private data");
13974
13975
13976
13977
13978 if (!dns_nsec3param_fromprivate(&private, &rdata,
13979 buf, sizeof(buf)))
13980 continue;
13981
13982
13983
13984
13985 if (NSEC3REMOVE(rdata.data[1])) {
13986
13987
13988
13989 rdata.data[1] = 0;
13990
13991 for (nsec3p = ISC_LIST_HEAD(*nsec3list);
13992 nsec3p != NULL;
13993 nsec3p = next)
13994 {
13995 next = ISC_LIST_NEXT(nsec3p, link);
13996
13997 if (nsec3p->length == rdata.length + 1 &&
13998 memcmp(rdata.data, nsec3p->data + 1,
13999 nsec3p->length - 1) == 0) {
14000 ISC_LIST_UNLINK(*nsec3list,
14001 nsec3p, link);
14002 isc_mem_put(zone->mctx, nsec3p,
14003 sizeof(nsec3param_t));
14004 }
14005 }
14006 continue;
14007 }
14008
14009 nsec3param = isc_mem_get(zone->mctx, sizeof(nsec3param_t));
14010 if (nsec3param == NULL)
14011 CHECK(ISC_R_NOMEMORY);
14012 ISC_LINK_INIT(nsec3param, link);
14013
14014
14015
14016
14017
14018 INSIST(private.length <= sizeof(nsec3param->data));
14019 memmove(nsec3param->data, private.data, private.length);
14020 nsec3param->length = private.length;
14021 ISC_LIST_APPEND(*nsec3list, nsec3param, link);
14022 }
14023
14024 done:
14025 if (result == ISC_R_NOMORE || result == ISC_R_NOTFOUND)
14026 result = ISC_R_SUCCESS;
14027
14028 failure:
14029 if (node != NULL)
14030 dns_db_detachnode(db, &node);
14031 if (version != NULL)
14032 dns_db_closeversion(db, &version, ISC_FALSE);
14033 if (db != NULL)
14034 dns_db_detach(&db);
14035 if (dns_rdataset_isassociated(&rdataset))
14036 dns_rdataset_disassociate(&rdataset);
14037 if (dns_rdataset_isassociated(&prdataset))
14038 dns_rdataset_disassociate(&prdataset);
14039 return (result);
14040 }
14041
14042
14043
14044
14045
14046
14047 static isc_result_t
14048 restore_nsec3param(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
14049 nsec3paramlist_t *nsec3list)
14050 {
14051 isc_result_t result;
14052 dns_diff_t diff;
14053 dns_rdata_t rdata;
14054 nsec3param_t *nsec3p = NULL;
14055 nsec3param_t *next;
14056
14057 REQUIRE(DNS_ZONE_VALID(zone));
14058 REQUIRE(!ISC_LIST_EMPTY(*nsec3list));
14059
14060 dns_diff_init(zone->mctx, &diff);
14061
14062
14063
14064
14065
14066
14067 for (nsec3p = ISC_LIST_HEAD(*nsec3list);
14068 nsec3p != NULL;
14069 nsec3p = next)
14070 {
14071 next = ISC_LIST_NEXT(nsec3p, link);
14072 dns_rdata_init(&rdata);
14073 nsec3p->data[2] = DNS_NSEC3FLAG_CREATE | DNS_NSEC3FLAG_INITIAL;
14074 rdata.length = nsec3p->length;
14075 rdata.data = nsec3p->data;
14076 rdata.type = zone->privatetype;
14077 rdata.rdclass = zone->rdclass;
14078 CHECK(update_one_rr(db, version, &diff, DNS_DIFFOP_ADD,
14079 &zone->origin, 0, &rdata));
14080 }
14081
14082 result = ISC_R_SUCCESS;
14083
14084 failure:
14085 for (nsec3p = ISC_LIST_HEAD(*nsec3list);
14086 nsec3p != NULL;
14087 nsec3p = next)
14088 {
14089 next = ISC_LIST_NEXT(nsec3p, link);
14090 ISC_LIST_UNLINK(*nsec3list, nsec3p, link);
14091 isc_mem_put(zone->mctx, nsec3p, sizeof(nsec3param_t));
14092 }
14093
14094 dns_diff_clear(&diff);
14095 return (result);
14096 }
14097
14098 static void
14099 receive_secure_db(isc_task_t *task, isc_event_t *event) {
14100 isc_result_t result;
14101 dns_zone_t *zone;
14102 dns_db_t *rawdb, *db = NULL;
14103 dns_dbnode_t *rawnode = NULL, *node = NULL;
14104 dns_fixedname_t fname;
14105 dns_name_t *name;
14106 dns_dbiterator_t *dbiterator = NULL;
14107 dns_rdatasetiter_t *rdsit = NULL;
14108 dns_rdataset_t rdataset;
14109 dns_dbversion_t *version = NULL;
14110 isc_time_t loadtime;
14111 unsigned int oldserial = 0;
14112 isc_boolean_t have_oldserial = ISC_FALSE;
14113 nsec3paramlist_t nsec3list;
14114
14115 UNUSED(task);
14116
14117 ISC_LIST_INIT(nsec3list);
14118
14119 zone = event->ev_arg;
14120 rawdb = ((struct secure_event *)event)->db;
14121 isc_event_free(&event);
14122
14123 dns_fixedname_init(&fname);
14124 name = dns_fixedname_name(&fname);
14125 dns_rdataset_init(&rdataset);
14126
14127 LOCK_ZONE(zone);
14128 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) || !inline_secure(zone)) {
14129 result = ISC_R_SHUTTINGDOWN;
14130 goto failure;
14131 }
14132
14133 TIME_NOW(&loadtime);
14134 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
14135 if (zone->db != NULL) {
14136 result = dns_db_getsoaserial(zone->db, NULL, &oldserial);
14137 if (result == ISC_R_SUCCESS)
14138 have_oldserial = ISC_TRUE;
14139
14140
14141
14142
14143
14144 result = save_nsec3param(zone, &nsec3list);
14145 if (result != ISC_R_SUCCESS) {
14146 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
14147 goto failure;
14148 }
14149 }
14150 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
14151
14152 result = dns_db_create(zone->mctx, zone->db_argv[0],
14153 &zone->origin, dns_dbtype_zone, zone->rdclass,
14154 zone->db_argc - 1, zone->db_argv + 1, &db);
14155 if (result != ISC_R_SUCCESS)
14156 goto failure;
14157
14158 result = dns_db_newversion(db, &version);
14159 if (result != ISC_R_SUCCESS)
14160 goto failure;
14161
14162 result = dns_db_createiterator(rawdb, 0, &dbiterator);
14163 if (result != ISC_R_SUCCESS)
14164 goto failure;
14165
14166 for (result = dns_dbiterator_first(dbiterator);
14167 result == ISC_R_SUCCESS;
14168 result = dns_dbiterator_next(dbiterator)) {
14169 result = dns_dbiterator_current(dbiterator, &rawnode, name);
14170 if (result != ISC_R_SUCCESS)
14171 continue;
14172
14173 result = dns_db_findnode(db, name, ISC_TRUE, &node);
14174 if (result != ISC_R_SUCCESS)
14175 goto failure;
14176
14177 result = dns_db_allrdatasets(rawdb, rawnode, NULL, 0, &rdsit);
14178 if (result != ISC_R_SUCCESS)
14179 goto failure;
14180
14181 for (result = dns_rdatasetiter_first(rdsit);
14182 result == ISC_R_SUCCESS;
14183 result = dns_rdatasetiter_next(rdsit)) {
14184 dns_rdatasetiter_current(rdsit, &rdataset);
14185 if (rdataset.type == dns_rdatatype_nsec ||
14186 rdataset.type == dns_rdatatype_rrsig ||
14187 rdataset.type == dns_rdatatype_nsec3 ||
14188 rdataset.type == dns_rdatatype_dnskey ||
14189 rdataset.type == dns_rdatatype_nsec3param) {
14190 dns_rdataset_disassociate(&rdataset);
14191 continue;
14192 }
14193 if (rdataset.type == dns_rdatatype_soa &&
14194 have_oldserial) {
14195 result = checkandaddsoa(db, node, version,
14196 &rdataset, oldserial);
14197 } else
14198 result = dns_db_addrdataset(db, node, version,
14199 0, &rdataset, 0,
14200 NULL);
14201 if (result != ISC_R_SUCCESS)
14202 goto failure;
14203
14204 dns_rdataset_disassociate(&rdataset);
14205 }
14206 dns_rdatasetiter_destroy(&rdsit);
14207 dns_db_detachnode(rawdb, &rawnode);
14208 dns_db_detachnode(db, &node);
14209 }
14210
14211
14212
14213
14214
14215 if (!ISC_LIST_EMPTY(nsec3list))
14216 restore_nsec3param(zone, db, version, &nsec3list);
14217
14218 dns_db_closeversion(db, &version, ISC_TRUE);
14219
14220
14221
14222
14223 INSIST(zone != zone->raw);
14224 LOCK_ZONE(zone->raw);
14225 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
14226 result = zone_postload(zone, db, loadtime, ISC_R_SUCCESS);
14227 zone_needdump(zone, 0);
14228 UNLOCK_ZONE(zone->raw);
14229
14230 failure:
14231 UNLOCK_ZONE(zone);
14232 if (result != ISC_R_SUCCESS)
14233 dns_zone_log(zone, ISC_LOG_ERROR, "receive_secure_db: %s",
14234 dns_result_totext(result));
14235
14236 while (!ISC_LIST_EMPTY(nsec3list)) {
14237 nsec3param_t *nsec3p;
14238 nsec3p = ISC_LIST_HEAD(nsec3list);
14239 ISC_LIST_UNLINK(nsec3list, nsec3p, link);
14240 isc_mem_put(zone->mctx, nsec3p, sizeof(nsec3param_t));
14241 }
14242 if (dns_rdataset_isassociated(&rdataset))
14243 dns_rdataset_disassociate(&rdataset);
14244 if (db != NULL) {
14245 if (node != NULL)
14246 dns_db_detachnode(db, &node);
14247 if (version != NULL)
14248 dns_db_closeversion(db, &version, ISC_FALSE);
14249 dns_db_detach(&db);
14250 }
14251 if (rawnode != NULL)
14252 dns_db_detachnode(rawdb, &rawnode);
14253 dns_db_detach(&rawdb);
14254 if (dbiterator != NULL)
14255 dns_dbiterator_destroy(&dbiterator);
14256 dns_zone_idetach(&zone);
14257
14258 INSIST(version == NULL);
14259 }
14260
14261 static isc_result_t
14262 zone_send_securedb(dns_zone_t *zone, dns_db_t *db) {
14263 isc_event_t *e;
14264 dns_db_t *dummy = NULL;
14265 dns_zone_t *secure = NULL;
14266
14267 e = isc_event_allocate(zone->secure->mctx, zone,
14268 DNS_EVENT_ZONESECUREDB,
14269 receive_secure_db, zone->secure,
14270 sizeof(struct secure_event));
14271 if (e == NULL)
14272 return (ISC_R_NOMEMORY);
14273 dns_db_attach(db, &dummy);
14274 ((struct secure_event *)e)->db = dummy;
14275 INSIST(LOCKED_ZONE(zone->secure));
14276 zone_iattach(zone->secure, &secure);
14277 isc_task_send(zone->secure->task, &e);
14278 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SENDSECURE);
14279 return (ISC_R_SUCCESS);
14280 }
14281
14282 isc_result_t
14283 dns_zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) {
14284 isc_result_t result;
14285 dns_zone_t *secure = NULL;
14286
14287 REQUIRE(DNS_ZONE_VALID(zone));
14288 again:
14289 LOCK_ZONE(zone);
14290 if (inline_raw(zone)) {
14291 secure = zone->secure;
14292 INSIST(secure != zone);
14293 TRYLOCK_ZONE(result, secure);
14294 if (result != ISC_R_SUCCESS) {
14295 UNLOCK_ZONE(zone);
14296 secure = NULL;
14297 #if ISC_PLATFORM_USETHREADS
14298 isc_thread_yield();
14299 #endif
14300 goto again;
14301 }
14302 }
14303 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
14304 result = zone_replacedb(zone, db, dump);
14305 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
14306 if (secure != NULL)
14307 UNLOCK_ZONE(secure);
14308 UNLOCK_ZONE(zone);
14309 return (result);
14310 }
14311
14312 static isc_result_t
14313 zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) {
14314 dns_dbversion_t *ver;
14315 isc_result_t result;
14316 unsigned int soacount = 0;
14317 unsigned int nscount = 0;
14318
14319
14320
14321
14322 REQUIRE(DNS_ZONE_VALID(zone));
14323 REQUIRE(LOCKED_ZONE(zone));
14324 if (inline_raw(zone))
14325 REQUIRE(LOCKED_ZONE(zone->secure));
14326
14327 result = dns_db_rpz_ready(db);
14328 if (result != ISC_R_SUCCESS)
14329 return (result);
14330
14331 result = zone_get_from_db(zone, db, &nscount, &soacount,
14332 NULL, NULL, NULL, NULL, NULL, NULL);
14333 if (result == ISC_R_SUCCESS) {
14334 if (soacount != 1) {
14335 dns_zone_log(zone, ISC_LOG_ERROR,
14336 "has %d SOA records", soacount);
14337 result = DNS_R_BADZONE;
14338 }
14339 if (nscount == 0 && zone->type != dns_zone_key) {
14340 dns_zone_log(zone, ISC_LOG_ERROR, "has no NS records");
14341 result = DNS_R_BADZONE;
14342 }
14343 if (result != ISC_R_SUCCESS)
14344 return (result);
14345 } else {
14346 dns_zone_log(zone, ISC_LOG_ERROR,
14347 "retrieving SOA and NS records failed: %s",
14348 dns_result_totext(result));
14349 return (result);
14350 }
14351
14352 result = check_nsec3param(zone, db);
14353 if (result != ISC_R_SUCCESS)
14354 return (result);
14355
14356 ver = NULL;
14357 dns_db_currentversion(db, &ver);
14358
14359
14360
14361
14362
14363
14364 if (zone->db != NULL && zone->journal != NULL &&
14365 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) &&
14366 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER))
14367 {
14368 isc_uint32_t serial, oldserial;
14369
14370 dns_zone_log(zone, ISC_LOG_DEBUG(3), "generating diffs");
14371
14372 result = dns_db_getsoaserial(db, ver, &serial);
14373 if (result != ISC_R_SUCCESS) {
14374 dns_zone_log(zone, ISC_LOG_ERROR,
14375 "ixfr-from-differences: unable to get "
14376 "new serial");
14377 goto fail;
14378 }
14379
14380
14381
14382
14383 result = zone_get_from_db(zone, zone->db, NULL, &soacount,
14384 &oldserial, NULL, NULL, NULL, NULL,
14385 NULL);
14386 RUNTIME_CHECK(result == ISC_R_SUCCESS);
14387 RUNTIME_CHECK(soacount > 0U);
14388 if ((zone->type == dns_zone_slave ||
14389 (zone->type == dns_zone_redirect &&
14390 zone->masters != NULL))
14391 && !isc_serial_gt(serial, oldserial)) {
14392 isc_uint32_t serialmin, serialmax;
14393 serialmin = (oldserial + 1) & 0xffffffffU;
14394 serialmax = (oldserial + 0x7fffffffU) & 0xffffffffU;
14395 dns_zone_log(zone, ISC_LOG_ERROR,
14396 "ixfr-from-differences: failed: "
14397 "new serial (%u) out of range [%u - %u]",
14398 serial, serialmin, serialmax);
14399 result = ISC_R_RANGE;
14400 goto fail;
14401 }
14402
14403 result = dns_db_diff(zone->mctx, db, ver, zone->db, NULL,
14404 zone->journal);
14405 if (result != ISC_R_SUCCESS)
14406 goto fail;
14407 if (dump)
14408 zone_needdump(zone, DNS_DUMP_DELAY);
14409 else if (zone->journalsize != -1) {
14410 result = dns_journal_compact(zone->mctx, zone->journal,
14411 serial, zone->journalsize);
14412 switch (result) {
14413 case ISC_R_SUCCESS:
14414 case ISC_R_NOSPACE:
14415 case ISC_R_NOTFOUND:
14416 dns_zone_log(zone, ISC_LOG_DEBUG(3),
14417 "dns_journal_compact: %s",
14418 dns_result_totext(result));
14419 break;
14420 default:
14421 dns_zone_log(zone, ISC_LOG_ERROR,
14422 "dns_journal_compact failed: %s",
14423 dns_result_totext(result));
14424 break;
14425 }
14426 }
14427 if (zone->type == dns_zone_master && inline_raw(zone))
14428 zone_send_secureserial(zone, serial);
14429 } else {
14430 if (dump && zone->masterfile != NULL) {
14431
14432
14433
14434
14435 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) &&
14436 remove(zone->masterfile) < 0 && errno != ENOENT) {
14437 char strbuf[ISC_STRERRORSIZE];
14438 isc__strerror(errno, strbuf, sizeof(strbuf));
14439 isc_log_write(dns_lctx,
14440 DNS_LOGCATEGORY_GENERAL,
14441 DNS_LOGMODULE_ZONE,
14442 ISC_LOG_WARNING,
14443 "unable to remove masterfile "
14444 "'%s': '%s'",
14445 zone->masterfile, strbuf);
14446 }
14447 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0)
14448 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NODELAY);
14449 else
14450 zone_needdump(zone, 0);
14451 }
14452 if (dump && zone->journal != NULL) {
14453
14454
14455
14456
14457
14458
14459
14460
14461
14462
14463
14464 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
14465 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
14466 "removing journal file");
14467 if (remove(zone->journal) < 0 && errno != ENOENT) {
14468 char strbuf[ISC_STRERRORSIZE];
14469 isc__strerror(errno, strbuf, sizeof(strbuf));
14470 isc_log_write(dns_lctx,
14471 DNS_LOGCATEGORY_GENERAL,
14472 DNS_LOGMODULE_ZONE,
14473 ISC_LOG_WARNING,
14474 "unable to remove journal "
14475 "'%s': '%s'",
14476 zone->journal, strbuf);
14477 }
14478 }
14479
14480 if (inline_raw(zone))
14481 zone_send_securedb(zone, db);
14482 }
14483
14484 dns_db_closeversion(db, &ver, ISC_FALSE);
14485
14486 dns_zone_log(zone, ISC_LOG_DEBUG(3), "replacing zone database");
14487
14488 if (zone->db != NULL)
14489 zone_detachdb(zone);
14490 zone_attachdb(zone, db);
14491 dns_db_settask(zone->db, zone->task);
14492 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED|DNS_ZONEFLG_NEEDNOTIFY);
14493 return (ISC_R_SUCCESS);
14494
14495 fail:
14496 dns_db_closeversion(db, &ver, ISC_FALSE);
14497 return (result);
14498 }
14499
14500
14501 static inline void
14502 zone_attachdb(dns_zone_t *zone, dns_db_t *db) {
14503 REQUIRE(zone->db == NULL && db != NULL);
14504
14505 dns_db_attach(db, &zone->db);
14506 if (zone->acache != NULL) {
14507 isc_result_t result;
14508 result = dns_acache_setdb(zone->acache, db);
14509 if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) {
14510 UNEXPECTED_ERROR(__FILE__, __LINE__,
14511 "dns_acache_setdb() failed: %s",
14512 isc_result_totext(result));
14513 }
14514 }
14515 }
14516
14517
14518 static inline void
14519 zone_detachdb(dns_zone_t *zone) {
14520 REQUIRE(zone->db != NULL);
14521
14522 if (zone->acache != NULL)
14523 (void)dns_acache_putdb(zone->acache, zone->db);
14524 dns_db_detach(&zone->db);
14525 }
14526
14527 static void
14528 zone_xfrdone(dns_zone_t *zone, isc_result_t result) {
14529 isc_time_t now;
14530 isc_boolean_t again = ISC_FALSE;
14531 unsigned int soacount;
14532 unsigned int nscount;
14533 isc_uint32_t serial, refresh, retry, expire, minimum;
14534 isc_result_t xfrresult = result;
14535 isc_boolean_t free_needed;
14536 dns_zone_t *secure = NULL;
14537
14538 REQUIRE(DNS_ZONE_VALID(zone));
14539
14540 dns_zone_log(zone, ISC_LOG_DEBUG(1),
14541 "zone transfer finished: %s", dns_result_totext(result));
14542
14543
14544
14545
14546
14547
14548 again:
14549 LOCK_ZONE(zone);
14550 if (inline_raw(zone)) {
14551 secure = zone->secure;
14552 INSIST(secure != zone);
14553 TRYLOCK_ZONE(result, secure);
14554 if (result != ISC_R_SUCCESS) {
14555 UNLOCK_ZONE(zone);
14556 secure = NULL;
14557 #if ISC_PLATFORM_USETHREADS
14558 isc_thread_yield();
14559 #endif
14560 goto again;
14561 }
14562 }
14563
14564 INSIST((zone->flags & DNS_ZONEFLG_REFRESH) != 0);
14565 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
14566 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR);
14567
14568 TIME_NOW(&now);
14569 switch (result) {
14570 case ISC_R_SUCCESS:
14571 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
14572
14573 case DNS_R_UPTODATE:
14574 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FORCEXFER);
14575
14576
14577
14578 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
14579 if (zone->db == NULL) {
14580 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
14581 goto same_master;
14582 }
14583
14584
14585
14586
14587
14588 nscount = 0;
14589 soacount = 0;
14590 INSIST(zone->db != NULL);
14591 result = zone_get_from_db(zone, zone->db, &nscount,
14592 &soacount, &serial, &refresh,
14593 &retry, &expire, &minimum, NULL);
14594 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
14595 if (result == ISC_R_SUCCESS) {
14596 if (soacount != 1)
14597 dns_zone_log(zone, ISC_LOG_ERROR,
14598 "transferred zone "
14599 "has %d SOA record%s", soacount,
14600 (soacount != 0) ? "s" : "");
14601 if (nscount == 0) {
14602 dns_zone_log(zone, ISC_LOG_ERROR,
14603 "transferred zone "
14604 "has no NS records");
14605 if (DNS_ZONE_FLAG(zone,
14606 DNS_ZONEFLG_HAVETIMERS)) {
14607 zone->refresh = DNS_ZONE_DEFAULTREFRESH;
14608 zone->retry = DNS_ZONE_DEFAULTRETRY;
14609 }
14610 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
14611 zone_unload(zone);
14612 goto next_master;
14613 }
14614 zone->refresh = RANGE(refresh, zone->minrefresh,
14615 zone->maxrefresh);
14616 zone->retry = RANGE(retry, zone->minretry,
14617 zone->maxretry);
14618 zone->expire = RANGE(expire,
14619 zone->refresh + zone->retry,
14620 DNS_MAX_EXPIRE);
14621 zone->minimum = minimum;
14622 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
14623 }
14624
14625
14626
14627
14628 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) {
14629 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
14630 zone->refreshtime = now;
14631 DNS_ZONE_TIME_ADD(&now, zone->expire,
14632 &zone->expiretime);
14633 } else {
14634 DNS_ZONE_JITTER_ADD(&now, zone->refresh,
14635 &zone->refreshtime);
14636 DNS_ZONE_TIME_ADD(&now, zone->expire,
14637 &zone->expiretime);
14638 }
14639 if (result == ISC_R_SUCCESS && xfrresult == ISC_R_SUCCESS) {
14640 char buf[DNS_NAME_FORMATSIZE + sizeof(": TSIG ''")];
14641 if (zone->tsigkey != NULL) {
14642 char namebuf[DNS_NAME_FORMATSIZE];
14643 dns_name_format(&zone->tsigkey->name, namebuf,
14644 sizeof(namebuf));
14645 snprintf(buf, sizeof(buf), ": TSIG '%s'",
14646 namebuf);
14647 } else
14648 buf[0] = '\0';
14649 dns_zone_log(zone, ISC_LOG_INFO,
14650 "transferred serial %u%s",
14651 serial, buf);
14652 if (inline_raw(zone))
14653 zone_send_secureserial(zone, serial);
14654 }
14655
14656
14657
14658
14659
14660
14661 if (zone->masterfile != NULL || zone->journal != NULL) {
14662 unsigned int delay = DNS_DUMP_DELAY;
14663
14664 result = ISC_R_FAILURE;
14665 if (zone->journal != NULL)
14666 result = isc_file_settime(zone->journal, &now);
14667 if (result != ISC_R_SUCCESS &&
14668 zone->masterfile != NULL)
14669 result = isc_file_settime(zone->masterfile,
14670 &now);
14671
14672 if ((DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NODELAY) != 0) ||
14673 result == ISC_R_FILENOTFOUND)
14674 delay = 0;
14675
14676 if ((result == ISC_R_SUCCESS ||
14677 result == ISC_R_FILENOTFOUND) &&
14678 zone->masterfile != NULL)
14679 zone_needdump(zone, delay);
14680 else if (result != ISC_R_SUCCESS)
14681 dns_zone_log(zone, ISC_LOG_ERROR,
14682 "transfer: could not set file "
14683 "modification time of '%s': %s",
14684 zone->masterfile,
14685 dns_result_totext(result));
14686 }
14687 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NODELAY);
14688 inc_stats(zone, dns_zonestatscounter_xfrsuccess);
14689 break;
14690
14691 case DNS_R_BADIXFR:
14692
14693 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLAG_NOIXFR);
14694 goto same_master;
14695
14696 default:
14697 next_master:
14698
14699
14700
14701 do {
14702 zone->curmaster++;
14703 } while (zone->curmaster < zone->masterscnt &&
14704 zone->mastersok[zone->curmaster]);
14705
14706 same_master:
14707 if (zone->curmaster >= zone->masterscnt) {
14708 zone->curmaster = 0;
14709 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
14710 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
14711 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
14712 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
14713 while (zone->curmaster < zone->masterscnt &&
14714 zone->mastersok[zone->curmaster])
14715 zone->curmaster++;
14716 again = ISC_TRUE;
14717 } else
14718 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
14719 } else {
14720 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
14721 again = ISC_TRUE;
14722 }
14723 inc_stats(zone, dns_zonestatscounter_xfrfail);
14724 break;
14725 }
14726 zone_settimer(zone, &now);
14727
14728
14729
14730
14731
14732
14733
14734
14735 if (zone->xfr != NULL)
14736 dns_xfrin_detach(&zone->xfr);
14737
14738 if (zone->tsigkey != NULL)
14739 dns_tsigkey_detach(&zone->tsigkey);
14740
14741
14742
14743
14744 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDCOMPACT)) {
14745 result = dns_journal_compact(zone->mctx, zone->journal,
14746 zone->compact_serial,
14747 zone->journalsize);
14748 switch (result) {
14749 case ISC_R_SUCCESS:
14750 case ISC_R_NOSPACE:
14751 case ISC_R_NOTFOUND:
14752 dns_zone_log(zone, ISC_LOG_DEBUG(3),
14753 "dns_journal_compact: %s",
14754 dns_result_totext(result));
14755 break;
14756 default:
14757 dns_zone_log(zone, ISC_LOG_ERROR,
14758 "dns_journal_compact failed: %s",
14759 dns_result_totext(result));
14760 break;
14761 }
14762 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT);
14763 }
14764
14765 if (secure != NULL)
14766 UNLOCK_ZONE(secure);
14767
14768
14769
14770
14771 if (zone->zmgr != NULL &&
14772 zone->statelist == &zone->zmgr->xfrin_in_progress) {
14773 UNLOCK_ZONE(zone);
14774 RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
14775 ISC_LIST_UNLINK(zone->zmgr->xfrin_in_progress, zone, statelink);
14776 zone->statelist = NULL;
14777 zmgr_resume_xfrs(zone->zmgr, ISC_FALSE);
14778 RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
14779 LOCK_ZONE(zone);
14780 }
14781
14782
14783
14784
14785 if (again && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
14786 queue_soa_query(zone);
14787
14788 INSIST(zone->irefs > 0);
14789 zone->irefs--;
14790 free_needed = exit_check(zone);
14791 UNLOCK_ZONE(zone);
14792 if (free_needed)
14793 zone_free(zone);
14794 }
14795
14796 static void
14797 zone_loaddone(void *arg, isc_result_t result) {
14798 static char me[] = "zone_loaddone";
14799 dns_load_t *load = arg;
14800 dns_zone_t *zone;
14801 isc_result_t tresult;
14802 dns_zone_t *secure = NULL;
14803
14804 REQUIRE(DNS_LOAD_VALID(load));
14805 zone = load->zone;
14806
14807 ENTER;
14808
14809 tresult = dns_db_endload(load->db, &load->callbacks);
14810 if (tresult != ISC_R_SUCCESS &&
14811 (result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE))
14812 result = tresult;
14813
14814
14815
14816
14817 again:
14818 LOCK_ZONE(zone);
14819 INSIST(zone != zone->raw);
14820 if (inline_secure(zone))
14821 LOCK_ZONE(zone->raw);
14822 else if (inline_raw(zone)) {
14823 secure = zone->secure;
14824 TRYLOCK_ZONE(result, secure);
14825 if (result != ISC_R_SUCCESS) {
14826 UNLOCK_ZONE(zone);
14827 secure = NULL;
14828 #if ISC_PLATFORM_USETHREADS
14829 isc_thread_yield();
14830 #endif
14831 goto again;
14832 }
14833 }
14834 (void)zone_postload(zone, load->db, load->loadtime, result);
14835 zonemgr_putio(&zone->readio);
14836 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADING);
14837 zone_idetach(&load->callbacks.zone);
14838
14839
14840
14841 if ((result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE) &&
14842 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_THAW))
14843 zone->update_disabled = ISC_FALSE;
14844 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_THAW);
14845 if (inline_secure(zone))
14846 UNLOCK_ZONE(zone->raw);
14847 else if (secure != NULL)
14848 UNLOCK_ZONE(secure);
14849 UNLOCK_ZONE(zone);
14850
14851 load->magic = 0;
14852 dns_db_detach(&load->db);
14853 if (load->zone->lctx != NULL)
14854 dns_loadctx_detach(&load->zone->lctx);
14855 dns_zone_idetach(&load->zone);
14856 isc_mem_putanddetach(&load->mctx, load, sizeof(*load));
14857 }
14858
14859 void
14860 dns_zone_getssutable(dns_zone_t *zone, dns_ssutable_t **table) {
14861 REQUIRE(DNS_ZONE_VALID(zone));
14862 REQUIRE(table != NULL);
14863 REQUIRE(*table == NULL);
14864
14865 LOCK_ZONE(zone);
14866 if (zone->ssutable != NULL)
14867 dns_ssutable_attach(zone->ssutable, table);
14868 UNLOCK_ZONE(zone);
14869 }
14870
14871 void
14872 dns_zone_setssutable(dns_zone_t *zone, dns_ssutable_t *table) {
14873 REQUIRE(DNS_ZONE_VALID(zone));
14874
14875 LOCK_ZONE(zone);
14876 if (zone->ssutable != NULL)
14877 dns_ssutable_detach(&zone->ssutable);
14878 if (table != NULL)
14879 dns_ssutable_attach(table, &zone->ssutable);
14880 UNLOCK_ZONE(zone);
14881 }
14882
14883 void
14884 dns_zone_setsigvalidityinterval(dns_zone_t *zone, isc_uint32_t interval) {
14885 REQUIRE(DNS_ZONE_VALID(zone));
14886
14887 zone->sigvalidityinterval = interval;
14888 }
14889
14890 isc_uint32_t
14891 dns_zone_getsigvalidityinterval(dns_zone_t *zone) {
14892 REQUIRE(DNS_ZONE_VALID(zone));
14893
14894 return (zone->sigvalidityinterval);
14895 }
14896
14897 void
14898 dns_zone_setsigresigninginterval(dns_zone_t *zone, isc_uint32_t interval) {
14899 isc_time_t now;
14900
14901 REQUIRE(DNS_ZONE_VALID(zone));
14902
14903 LOCK_ZONE(zone);
14904 zone->sigresigninginterval = interval;
14905 set_resigntime(zone);
14906 if (zone->task != NULL) {
14907 TIME_NOW(&now);
14908 zone_settimer(zone, &now);
14909 }
14910 UNLOCK_ZONE(zone);
14911 }
14912
14913 isc_uint32_t
14914 dns_zone_getsigresigninginterval(dns_zone_t *zone) {
14915 REQUIRE(DNS_ZONE_VALID(zone));
14916
14917 return (zone->sigresigninginterval);
14918 }
14919
14920 static void
14921 queue_xfrin(dns_zone_t *zone) {
14922 const char me[] = "queue_xfrin";
14923 isc_result_t result;
14924 dns_zonemgr_t *zmgr = zone->zmgr;
14925
14926 ENTER;
14927
14928 INSIST(zone->statelist == NULL);
14929
14930 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
14931 ISC_LIST_APPEND(zmgr->waiting_for_xfrin, zone, statelink);
14932 LOCK_ZONE(zone);
14933 zone->irefs++;
14934 UNLOCK_ZONE(zone);
14935 zone->statelist = &zmgr->waiting_for_xfrin;
14936 result = zmgr_start_xfrin_ifquota(zmgr, zone);
14937 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
14938
14939 if (result == ISC_R_QUOTA) {
14940 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO,
14941 "zone transfer deferred due to quota");
14942 } else if (result != ISC_R_SUCCESS) {
14943 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_ERROR,
14944 "starting zone transfer: %s",
14945 isc_result_totext(result));
14946 }
14947 }
14948
14949
14950
14951
14952
14953
14954 static void
14955 got_transfer_quota(isc_task_t *task, isc_event_t *event) {
14956 isc_result_t result = ISC_R_SUCCESS;
14957 dns_peer_t *peer = NULL;
14958 char master[ISC_SOCKADDR_FORMATSIZE];
14959 char source[ISC_SOCKADDR_FORMATSIZE];
14960 dns_rdatatype_t xfrtype;
14961 dns_zone_t *zone = event->ev_arg;
14962 isc_netaddr_t masterip;
14963 isc_sockaddr_t sourceaddr;
14964 isc_sockaddr_t masteraddr;
14965 isc_time_t now;
14966 const char *soa_before = "";
14967 isc_dscp_t dscp = -1;
14968 isc_boolean_t loaded;
14969
14970 UNUSED(task);
14971
14972 INSIST(task == zone->task);
14973
14974 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
14975 result = ISC_R_CANCELED;
14976 goto cleanup;
14977 }
14978
14979 TIME_NOW(&now);
14980
14981 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
14982 if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr,
14983 &zone->sourceaddr, &now))
14984 {
14985 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
14986 dns_zone_log(zone, ISC_LOG_INFO,
14987 "got_transfer_quota: skipping zone transfer as "
14988 "master %s (source %s) is unreachable (cached)",
14989 master, source);
14990 result = ISC_R_CANCELED;
14991 goto cleanup;
14992 }
14993
14994 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
14995 (void)dns_peerlist_peerbyaddr(zone->view->peers, &masterip, &peer);
14996
14997 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR))
14998 soa_before = "SOA before ";
14999
15000
15001
15002 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
15003 loaded = ISC_TF(zone->db != NULL);
15004 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
15005
15006 if (!loaded) {
15007 dns_zone_log(zone, ISC_LOG_DEBUG(1),
15008 "no database exists yet, requesting AXFR of "
15009 "initial version from %s", master);
15010 xfrtype = dns_rdatatype_axfr;
15011 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) {
15012 dns_zone_log(zone, ISC_LOG_DEBUG(1),
15013 "forced reload, requesting AXFR of "
15014 "initial version from %s", master);
15015 xfrtype = dns_rdatatype_axfr;
15016 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLAG_NOIXFR)) {
15017 dns_zone_log(zone, ISC_LOG_DEBUG(1),
15018 "retrying with AXFR from %s due to "
15019 "previous IXFR failure", master);
15020 xfrtype = dns_rdatatype_axfr;
15021 LOCK_ZONE(zone);
15022 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLAG_NOIXFR);
15023 UNLOCK_ZONE(zone);
15024 } else {
15025 isc_boolean_t use_ixfr = ISC_TRUE;
15026 if (peer != NULL)
15027 result = dns_peer_getrequestixfr(peer, &use_ixfr);
15028 if (peer == NULL || result != ISC_R_SUCCESS)
15029 use_ixfr = zone->requestixfr;
15030 if (use_ixfr == ISC_FALSE) {
15031 dns_zone_log(zone, ISC_LOG_DEBUG(1),
15032 "IXFR disabled, requesting %sAXFR from %s",
15033 soa_before, master);
15034 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR))
15035 xfrtype = dns_rdatatype_soa;
15036 else
15037 xfrtype = dns_rdatatype_axfr;
15038 } else {
15039 dns_zone_log(zone, ISC_LOG_DEBUG(1),
15040 "requesting IXFR from %s", master);
15041 xfrtype = dns_rdatatype_ixfr;
15042 }
15043 }
15044
15045
15046
15047
15048 result = ISC_R_NOTFOUND;
15049
15050
15051
15052
15053
15054 if ((zone->masterkeynames != NULL) &&
15055 (zone->masterkeynames[zone->curmaster] != NULL)) {
15056 dns_view_t *view = dns_zone_getview(zone);
15057 dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
15058 result = dns_view_gettsig(view, keyname, &zone->tsigkey);
15059 }
15060 if (zone->tsigkey == NULL)
15061 result = dns_view_getpeertsig(zone->view, &masterip,
15062 &zone->tsigkey);
15063
15064 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
15065 dns_zone_log(zone, ISC_LOG_ERROR,
15066 "could not get TSIG key for zone transfer: %s",
15067 isc_result_totext(result));
15068 }
15069
15070 if (zone->masterdscps != NULL)
15071 dscp = zone->masterdscps[zone->curmaster];
15072
15073 LOCK_ZONE(zone);
15074 masteraddr = zone->masteraddr;
15075 sourceaddr = zone->sourceaddr;
15076 switch (isc_sockaddr_pf(&masteraddr)) {
15077 case PF_INET:
15078 if (dscp == -1)
15079 dscp = zone->xfrsource4dscp;
15080 break;
15081 case PF_INET6:
15082 if (dscp == -1)
15083 dscp = zone->xfrsource6dscp;
15084 break;
15085 default:
15086 INSIST(0);
15087 };
15088 UNLOCK_ZONE(zone);
15089 INSIST(isc_sockaddr_pf(&masteraddr) == isc_sockaddr_pf(&sourceaddr));
15090 result = dns_xfrin_create3(zone, xfrtype, &masteraddr, &sourceaddr,
15091 dscp, zone->tsigkey, zone->mctx,
15092 zone->zmgr->timermgr, zone->zmgr->socketmgr,
15093 zone->task, zone_xfrdone, &zone->xfr);
15094 if (result == ISC_R_SUCCESS) {
15095 LOCK_ZONE(zone);
15096 if (xfrtype == dns_rdatatype_axfr) {
15097 if (isc_sockaddr_pf(&masteraddr) == PF_INET)
15098 inc_stats(zone, dns_zonestatscounter_axfrreqv4);
15099 else
15100 inc_stats(zone, dns_zonestatscounter_axfrreqv6);
15101 } else if (xfrtype == dns_rdatatype_ixfr) {
15102 if (isc_sockaddr_pf(&masteraddr) == PF_INET)
15103 inc_stats(zone, dns_zonestatscounter_ixfrreqv4);
15104 else
15105 inc_stats(zone, dns_zonestatscounter_ixfrreqv6);
15106 }
15107 UNLOCK_ZONE(zone);
15108 }
15109 cleanup:
15110
15111
15112
15113
15114
15115 if (result != ISC_R_SUCCESS)
15116 zone_xfrdone(zone, result);
15117
15118 isc_event_free(&event);
15119 }
15120
15121
15122
15123
15124
15125 static void
15126 forward_destroy(dns_forward_t *forward) {
15127
15128 forward->magic = 0;
15129 if (forward->request != NULL)
15130 dns_request_destroy(&forward->request);
15131 if (forward->msgbuf != NULL)
15132 isc_buffer_free(&forward->msgbuf);
15133 if (forward->zone != NULL) {
15134 LOCK(&forward->zone->lock);
15135 if (ISC_LINK_LINKED(forward, link))
15136 ISC_LIST_UNLINK(forward->zone->forwards, forward, link);
15137 UNLOCK(&forward->zone->lock);
15138 dns_zone_idetach(&forward->zone);
15139 }
15140 isc_mem_putanddetach(&forward->mctx, forward, sizeof(*forward));
15141 }
15142
15143 static isc_result_t
15144 sendtomaster(dns_forward_t *forward) {
15145 isc_result_t result;
15146 isc_sockaddr_t src;
15147 isc_dscp_t dscp = -1;
15148
15149 LOCK_ZONE(forward->zone);
15150
15151 if (DNS_ZONE_FLAG(forward->zone, DNS_ZONEFLG_EXITING)) {
15152 UNLOCK_ZONE(forward->zone);
15153 return (ISC_R_CANCELED);
15154 }
15155
15156 if (forward->which >= forward->zone->masterscnt) {
15157 UNLOCK_ZONE(forward->zone);
15158 return (ISC_R_NOMORE);
15159 }
15160
15161 forward->addr = forward->zone->masters[forward->which];
15162
15163
15164
15165
15166
15167
15168 switch (isc_sockaddr_pf(&forward->addr)) {
15169 case PF_INET:
15170 src = forward->zone->xfrsource4;
15171 dscp = forward->zone->xfrsource4dscp;
15172 break;
15173 case PF_INET6:
15174 src = forward->zone->xfrsource6;
15175 dscp = forward->zone->xfrsource6dscp;
15176 break;
15177 default:
15178 result = ISC_R_NOTIMPLEMENTED;
15179 goto unlock;
15180 }
15181 result = dns_request_createraw4(forward->zone->view->requestmgr,
15182 forward->msgbuf,
15183 &src, &forward->addr, dscp,
15184 forward->options, 15 ,
15185 0, 0, forward->zone->task,
15186 forward_callback, forward,
15187 &forward->request);
15188 if (result == ISC_R_SUCCESS) {
15189 if (!ISC_LINK_LINKED(forward, link))
15190 ISC_LIST_APPEND(forward->zone->forwards, forward, link);
15191 }
15192
15193 unlock:
15194 UNLOCK_ZONE(forward->zone);
15195 return (result);
15196 }
15197
15198 static void
15199 forward_callback(isc_task_t *task, isc_event_t *event) {
15200 const char me[] = "forward_callback";
15201 dns_requestevent_t *revent = (dns_requestevent_t *)event;
15202 dns_message_t *msg = NULL;
15203 char master[ISC_SOCKADDR_FORMATSIZE];
15204 isc_result_t result;
15205 dns_forward_t *forward;
15206 dns_zone_t *zone;
15207
15208 UNUSED(task);
15209
15210 forward = revent->ev_arg;
15211 INSIST(DNS_FORWARD_VALID(forward));
15212 zone = forward->zone;
15213 INSIST(DNS_ZONE_VALID(zone));
15214
15215 ENTER;
15216
15217 isc_sockaddr_format(&forward->addr, master, sizeof(master));
15218
15219 if (revent->result != ISC_R_SUCCESS) {
15220 dns_zone_log(zone, ISC_LOG_INFO,
15221 "could not forward dynamic update to %s: %s",
15222 master, dns_result_totext(revent->result));
15223 goto next_master;
15224 }
15225
15226 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
15227 if (result != ISC_R_SUCCESS)
15228 goto next_master;
15229
15230 result = dns_request_getresponse(revent->request, msg,
15231 DNS_MESSAGEPARSE_PRESERVEORDER |
15232 DNS_MESSAGEPARSE_CLONEBUFFER);
15233 if (result != ISC_R_SUCCESS)
15234 goto next_master;
15235
15236 switch (msg->rcode) {
15237
15238
15239
15240 case dns_rcode_noerror:
15241 case dns_rcode_yxdomain:
15242 case dns_rcode_yxrrset:
15243 case dns_rcode_nxrrset:
15244 case dns_rcode_refused:
15245 case dns_rcode_nxdomain: {
15246 char rcode[128];
15247 isc_buffer_t rb;
15248
15249 isc_buffer_init(&rb, rcode, sizeof(rcode));
15250 (void)dns_rcode_totext(msg->rcode, &rb);
15251 dns_zone_log(zone, ISC_LOG_INFO,
15252 "forwarded dynamic update: "
15253 "master %s returned: %.*s",
15254 master, (int)rb.used, rcode);
15255 break;
15256 }
15257
15258
15259 case dns_rcode_notzone:
15260 case dns_rcode_notauth: {
15261 char rcode[128];
15262 isc_buffer_t rb;
15263
15264 isc_buffer_init(&rb, rcode, sizeof(rcode));
15265 (void)dns_rcode_totext(msg->rcode, &rb);
15266 dns_zone_log(zone, ISC_LOG_WARNING,
15267 "forwarding dynamic update: "
15268 "unexpected response: master %s returned: %.*s",
15269 master, (int)rb.used, rcode);
15270 goto next_master;
15271 }
15272
15273
15274 case dns_rcode_formerr:
15275 case dns_rcode_servfail:
15276 case dns_rcode_notimp:
15277 case dns_rcode_badvers:
15278 default:
15279 goto next_master;
15280 }
15281
15282
15283 (forward->callback)(forward->callback_arg, ISC_R_SUCCESS, msg);
15284 msg = NULL;
15285 dns_request_destroy(&forward->request);
15286 forward_destroy(forward);
15287 isc_event_free(&event);
15288 return;
15289
15290 next_master:
15291 if (msg != NULL)
15292 dns_message_destroy(&msg);
15293 isc_event_free(&event);
15294 forward->which++;
15295 dns_request_destroy(&forward->request);
15296 result = sendtomaster(forward);
15297 if (result != ISC_R_SUCCESS) {
15298
15299 dns_zone_log(zone, ISC_LOG_DEBUG(3),
15300 "exhausted dynamic update forwarder list");
15301 (forward->callback)(forward->callback_arg, result, NULL);
15302 forward_destroy(forward);
15303 }
15304 }
15305
15306 isc_result_t
15307 dns_zone_forwardupdate(dns_zone_t *zone, dns_message_t *msg,
15308 dns_updatecallback_t callback, void *callback_arg)
15309 {
15310 dns_forward_t *forward;
15311 isc_result_t result;
15312 isc_region_t *mr;
15313
15314 REQUIRE(DNS_ZONE_VALID(zone));
15315 REQUIRE(msg != NULL);
15316 REQUIRE(callback != NULL);
15317
15318 forward = isc_mem_get(zone->mctx, sizeof(*forward));
15319 if (forward == NULL)
15320 return (ISC_R_NOMEMORY);
15321
15322 forward->request = NULL;
15323 forward->zone = NULL;
15324 forward->msgbuf = NULL;
15325 forward->which = 0;
15326 forward->mctx = 0;
15327 forward->callback = callback;
15328 forward->callback_arg = callback_arg;
15329 ISC_LINK_INIT(forward, link);
15330 forward->magic = FORWARD_MAGIC;
15331 forward->options = DNS_REQUESTOPT_TCP;
15332
15333
15334
15335
15336 if (msg->sig0 != NULL)
15337 forward->options |= DNS_REQUESTOPT_FIXEDID;
15338
15339 mr = dns_message_getrawmessage(msg);
15340 if (mr == NULL) {
15341 result = ISC_R_UNEXPECTEDEND;
15342 goto cleanup;
15343 }
15344
15345 result = isc_buffer_allocate(zone->mctx, &forward->msgbuf, mr->length);
15346 if (result != ISC_R_SUCCESS)
15347 goto cleanup;
15348 result = isc_buffer_copyregion(forward->msgbuf, mr);
15349 if (result != ISC_R_SUCCESS)
15350 goto cleanup;
15351
15352 isc_mem_attach(zone->mctx, &forward->mctx);
15353 dns_zone_iattach(zone, &forward->zone);
15354 result = sendtomaster(forward);
15355
15356 cleanup:
15357 if (result != ISC_R_SUCCESS) {
15358 forward_destroy(forward);
15359 }
15360 return (result);
15361 }
15362
15363 isc_result_t
15364 dns_zone_next(dns_zone_t *zone, dns_zone_t **next) {
15365 REQUIRE(DNS_ZONE_VALID(zone));
15366 REQUIRE(next != NULL && *next == NULL);
15367
15368 *next = ISC_LIST_NEXT(zone, link);
15369 if (*next == NULL)
15370 return (ISC_R_NOMORE);
15371 else
15372 return (ISC_R_SUCCESS);
15373 }
15374
15375 isc_result_t
15376 dns_zone_first(dns_zonemgr_t *zmgr, dns_zone_t **first) {
15377 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15378 REQUIRE(first != NULL && *first == NULL);
15379
15380 *first = ISC_LIST_HEAD(zmgr->zones);
15381 if (*first == NULL)
15382 return (ISC_R_NOMORE);
15383 else
15384 return (ISC_R_SUCCESS);
15385 }
15386
15387
15388
15389
15390
15391 isc_result_t
15392 dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
15393 isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr,
15394 dns_zonemgr_t **zmgrp)
15395 {
15396 dns_zonemgr_t *zmgr;
15397 isc_result_t result;
15398
15399 zmgr = isc_mem_get(mctx, sizeof(*zmgr));
15400 if (zmgr == NULL)
15401 return (ISC_R_NOMEMORY);
15402 zmgr->mctx = NULL;
15403 zmgr->refs = 1;
15404 isc_mem_attach(mctx, &zmgr->mctx);
15405 zmgr->taskmgr = taskmgr;
15406 zmgr->timermgr = timermgr;
15407 zmgr->socketmgr = socketmgr;
15408 zmgr->zonetasks = NULL;
15409 zmgr->loadtasks = NULL;
15410 zmgr->mctxpool = NULL;
15411 zmgr->task = NULL;
15412 zmgr->notifyrl = NULL;
15413 zmgr->refreshrl = NULL;
15414 zmgr->startupnotifyrl = NULL;
15415 zmgr->startuprefreshrl = NULL;
15416 ISC_LIST_INIT(zmgr->zones);
15417 ISC_LIST_INIT(zmgr->waiting_for_xfrin);
15418 ISC_LIST_INIT(zmgr->xfrin_in_progress);
15419 memset(zmgr->unreachable, 0, sizeof(zmgr->unreachable));
15420 result = isc_rwlock_init(&zmgr->rwlock, 0, 0);
15421 if (result != ISC_R_SUCCESS)
15422 goto free_mem;
15423
15424 zmgr->transfersin = 10;
15425 zmgr->transfersperns = 2;
15426
15427
15428 result = isc_rwlock_init(&zmgr->urlock, 0, 0);
15429 if (result != ISC_R_SUCCESS)
15430 goto free_rwlock;
15431
15432
15433 result = isc_task_create(taskmgr, 1, &zmgr->task);
15434 if (result != ISC_R_SUCCESS)
15435 goto free_urlock;
15436
15437 isc_task_setname(zmgr->task, "zmgr", zmgr);
15438 result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
15439 &zmgr->notifyrl);
15440 if (result != ISC_R_SUCCESS)
15441 goto free_task;
15442
15443 result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
15444 &zmgr->refreshrl);
15445 if (result != ISC_R_SUCCESS)
15446 goto free_notifyrl;
15447
15448 result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
15449 &zmgr->startupnotifyrl);
15450 if (result != ISC_R_SUCCESS)
15451 goto free_refreshrl;
15452
15453 result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
15454 &zmgr->startuprefreshrl);
15455 if (result != ISC_R_SUCCESS)
15456 goto free_startupnotifyrl;
15457
15458
15459 setrl(zmgr->notifyrl, &zmgr->notifyrate, 20);
15460 setrl(zmgr->startupnotifyrl, &zmgr->startupnotifyrate, 20);
15461 setrl(zmgr->refreshrl, &zmgr->serialqueryrate, 20);
15462 setrl(zmgr->startuprefreshrl, &zmgr->startupserialqueryrate, 20);
15463
15464 zmgr->iolimit = 1;
15465 zmgr->ioactive = 0;
15466 ISC_LIST_INIT(zmgr->high);
15467 ISC_LIST_INIT(zmgr->low);
15468
15469 result = isc_mutex_init(&zmgr->iolock);
15470 if (result != ISC_R_SUCCESS)
15471 goto free_startuprefreshrl;
15472
15473 zmgr->magic = ZONEMGR_MAGIC;
15474
15475 *zmgrp = zmgr;
15476 return (ISC_R_SUCCESS);
15477
15478 #if 0
15479 free_iolock:
15480 DESTROYLOCK(&zmgr->iolock);
15481 #endif
15482 free_startuprefreshrl:
15483 isc_ratelimiter_detach(&zmgr->startuprefreshrl);
15484 free_startupnotifyrl:
15485 isc_ratelimiter_detach(&zmgr->startupnotifyrl);
15486 free_refreshrl:
15487 isc_ratelimiter_detach(&zmgr->refreshrl);
15488 free_notifyrl:
15489 isc_ratelimiter_detach(&zmgr->notifyrl);
15490 free_task:
15491 isc_task_detach(&zmgr->task);
15492 free_urlock:
15493 isc_rwlock_destroy(&zmgr->urlock);
15494 free_rwlock:
15495 isc_rwlock_destroy(&zmgr->rwlock);
15496 free_mem:
15497 isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr));
15498 isc_mem_detach(&mctx);
15499 return (result);
15500 }
15501
15502 isc_result_t
15503 dns_zonemgr_createzone(dns_zonemgr_t *zmgr, dns_zone_t **zonep) {
15504 isc_result_t result;
15505 isc_mem_t *mctx = NULL;
15506 dns_zone_t *zone = NULL;
15507 void *item;
15508
15509 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15510 REQUIRE(zonep != NULL && *zonep == NULL);
15511
15512 if (zmgr->mctxpool == NULL)
15513 return (ISC_R_FAILURE);
15514
15515 item = isc_pool_get(zmgr->mctxpool);
15516 if (item == NULL)
15517 return (ISC_R_FAILURE);
15518
15519 isc_mem_attach((isc_mem_t *) item, &mctx);
15520 result = dns_zone_create(&zone, mctx);
15521 isc_mem_detach(&mctx);
15522
15523 if (result == ISC_R_SUCCESS)
15524 *zonep = zone;
15525
15526 return (result);
15527 }
15528
15529 isc_result_t
15530 dns_zonemgr_managezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
15531 isc_result_t result;
15532
15533 REQUIRE(DNS_ZONE_VALID(zone));
15534 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15535
15536 if (zmgr->zonetasks == NULL)
15537 return (ISC_R_FAILURE);
15538
15539 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
15540 LOCK_ZONE(zone);
15541 REQUIRE(zone->task == NULL);
15542 REQUIRE(zone->timer == NULL);
15543 REQUIRE(zone->zmgr == NULL);
15544
15545 isc_taskpool_gettask(zmgr->zonetasks, &zone->task);
15546 isc_taskpool_gettask(zmgr->loadtasks, &zone->loadtask);
15547
15548
15549
15550
15551
15552
15553 isc_task_setname(zone->task, "zone", zone);
15554 isc_task_setname(zone->loadtask, "loadzone", zone);
15555
15556 result = isc_timer_create(zmgr->timermgr, isc_timertype_inactive,
15557 NULL, NULL,
15558 zone->task, zone_timer, zone,
15559 &zone->timer);
15560
15561 if (result != ISC_R_SUCCESS)
15562 goto cleanup_tasks;
15563
15564
15565
15566
15567 zone->irefs++;
15568 INSIST(zone->irefs != 0);
15569
15570 ISC_LIST_APPEND(zmgr->zones, zone, link);
15571 zone->zmgr = zmgr;
15572 zmgr->refs++;
15573
15574 goto unlock;
15575
15576 cleanup_tasks:
15577 isc_task_detach(&zone->loadtask);
15578 isc_task_detach(&zone->task);
15579
15580 unlock:
15581 UNLOCK_ZONE(zone);
15582 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
15583 return (result);
15584 }
15585
15586 void
15587 dns_zonemgr_releasezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
15588 isc_boolean_t free_now = ISC_FALSE;
15589
15590 REQUIRE(DNS_ZONE_VALID(zone));
15591 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15592 REQUIRE(zone->zmgr == zmgr);
15593
15594 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
15595 LOCK_ZONE(zone);
15596
15597 ISC_LIST_UNLINK(zmgr->zones, zone, link);
15598 zone->zmgr = NULL;
15599 zmgr->refs--;
15600 if (zmgr->refs == 0)
15601 free_now = ISC_TRUE;
15602
15603 UNLOCK_ZONE(zone);
15604 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
15605
15606 if (free_now)
15607 zonemgr_free(zmgr);
15608 ENSURE(zone->zmgr == NULL);
15609 }
15610
15611 void
15612 dns_zonemgr_attach(dns_zonemgr_t *source, dns_zonemgr_t **target) {
15613 REQUIRE(DNS_ZONEMGR_VALID(source));
15614 REQUIRE(target != NULL && *target == NULL);
15615
15616 RWLOCK(&source->rwlock, isc_rwlocktype_write);
15617 REQUIRE(source->refs > 0);
15618 source->refs++;
15619 INSIST(source->refs > 0);
15620 RWUNLOCK(&source->rwlock, isc_rwlocktype_write);
15621 *target = source;
15622 }
15623
15624 void
15625 dns_zonemgr_detach(dns_zonemgr_t **zmgrp) {
15626 dns_zonemgr_t *zmgr;
15627 isc_boolean_t free_now = ISC_FALSE;
15628
15629 REQUIRE(zmgrp != NULL);
15630 zmgr = *zmgrp;
15631 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15632
15633 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
15634 zmgr->refs--;
15635 if (zmgr->refs == 0)
15636 free_now = ISC_TRUE;
15637 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
15638
15639 if (free_now)
15640 zonemgr_free(zmgr);
15641 *zmgrp = NULL;
15642 }
15643
15644 isc_result_t
15645 dns_zonemgr_forcemaint(dns_zonemgr_t *zmgr) {
15646 dns_zone_t *p;
15647
15648 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15649
15650 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
15651 for (p = ISC_LIST_HEAD(zmgr->zones);
15652 p != NULL;
15653 p = ISC_LIST_NEXT(p, link))
15654 {
15655 dns_zone_maintenance(p);
15656 }
15657 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
15658
15659
15660
15661
15662
15663
15664
15665 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
15666 zmgr_resume_xfrs(zmgr, ISC_TRUE);
15667 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
15668 return (ISC_R_SUCCESS);
15669 }
15670
15671 void
15672 dns_zonemgr_resumexfrs(dns_zonemgr_t *zmgr) {
15673
15674 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15675
15676 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
15677 zmgr_resume_xfrs(zmgr, ISC_TRUE);
15678 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
15679 }
15680
15681 void
15682 dns_zonemgr_shutdown(dns_zonemgr_t *zmgr) {
15683 dns_zone_t *zone;
15684
15685 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15686
15687 isc_ratelimiter_shutdown(zmgr->notifyrl);
15688 isc_ratelimiter_shutdown(zmgr->refreshrl);
15689 isc_ratelimiter_shutdown(zmgr->startupnotifyrl);
15690 isc_ratelimiter_shutdown(zmgr->startuprefreshrl);
15691
15692 if (zmgr->task != NULL)
15693 isc_task_destroy(&zmgr->task);
15694 if (zmgr->zonetasks != NULL)
15695 isc_taskpool_destroy(&zmgr->zonetasks);
15696 if (zmgr->loadtasks != NULL)
15697 isc_taskpool_destroy(&zmgr->loadtasks);
15698 if (zmgr->mctxpool != NULL)
15699 isc_pool_destroy(&zmgr->mctxpool);
15700
15701 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
15702 for (zone = ISC_LIST_HEAD(zmgr->zones);
15703 zone != NULL;
15704 zone = ISC_LIST_NEXT(zone, link))
15705 {
15706 LOCK_ZONE(zone);
15707 forward_cancel(zone);
15708 UNLOCK_ZONE(zone);
15709 }
15710 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
15711 }
15712
15713 static isc_result_t
15714 mctxinit(void **target, void *arg) {
15715 isc_result_t result;
15716 isc_mem_t *mctx = NULL;
15717
15718 UNUSED(arg);
15719
15720 REQUIRE(target != NULL && *target == NULL);
15721
15722 result = isc_mem_create(0, 0, &mctx);
15723 if (result != ISC_R_SUCCESS)
15724 return (result);
15725 isc_mem_setname(mctx, "zonemgr-pool", NULL);
15726
15727 *target = mctx;
15728 return (ISC_R_SUCCESS);
15729 }
15730
15731 static void
15732 mctxfree(void **target) {
15733 isc_mem_t *mctx = *(isc_mem_t **) target;
15734 isc_mem_detach(&mctx);
15735 *target = NULL;
15736 }
15737
15738 #define ZONES_PER_TASK 100
15739 #define ZONES_PER_MCTX 1000
15740
15741 isc_result_t
15742 dns_zonemgr_setsize(dns_zonemgr_t *zmgr, int num_zones) {
15743 isc_result_t result;
15744 int ntasks = num_zones / ZONES_PER_TASK;
15745 int nmctx = num_zones / ZONES_PER_MCTX;
15746 isc_taskpool_t *pool = NULL;
15747 isc_pool_t *mctxpool = NULL;
15748
15749 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15750
15751
15752
15753
15754
15755
15756
15757 if (ntasks < 10)
15758 ntasks = 10;
15759 if (nmctx < 2)
15760 nmctx = 2;
15761
15762
15763 if (zmgr->zonetasks == NULL)
15764 result = isc_taskpool_create(zmgr->taskmgr, zmgr->mctx,
15765 ntasks, 2, &pool);
15766 else
15767 result = isc_taskpool_expand(&zmgr->zonetasks, ntasks, &pool);
15768
15769 if (result == ISC_R_SUCCESS)
15770 zmgr->zonetasks = pool;
15771
15772 pool = NULL;
15773 if (zmgr->loadtasks == NULL)
15774 result = isc_taskpool_create(zmgr->taskmgr, zmgr->mctx,
15775 ntasks, 2, &pool);
15776 else
15777 result = isc_taskpool_expand(&zmgr->loadtasks, ntasks, &pool);
15778
15779 if (result == ISC_R_SUCCESS)
15780 zmgr->loadtasks = pool;
15781
15782
15783
15784
15785
15786
15787
15788
15789
15790
15791
15792
15793
15794
15795 isc_taskpool_setprivilege(zmgr->loadtasks, ISC_TRUE);
15796
15797
15798 if (zmgr->mctxpool == NULL)
15799 result = isc_pool_create(zmgr->mctx, nmctx, mctxfree,
15800 mctxinit, NULL, &mctxpool);
15801 else
15802 result = isc_pool_expand(&zmgr->mctxpool, nmctx, &mctxpool);
15803
15804 if (result == ISC_R_SUCCESS)
15805 zmgr->mctxpool = mctxpool;
15806
15807 return (result);
15808 }
15809
15810 static void
15811 zonemgr_free(dns_zonemgr_t *zmgr) {
15812 isc_mem_t *mctx;
15813
15814 INSIST(zmgr->refs == 0);
15815 INSIST(ISC_LIST_EMPTY(zmgr->zones));
15816
15817 zmgr->magic = 0;
15818
15819 DESTROYLOCK(&zmgr->iolock);
15820 isc_ratelimiter_detach(&zmgr->notifyrl);
15821 isc_ratelimiter_detach(&zmgr->refreshrl);
15822 isc_ratelimiter_detach(&zmgr->startupnotifyrl);
15823 isc_ratelimiter_detach(&zmgr->startuprefreshrl);
15824
15825 isc_rwlock_destroy(&zmgr->urlock);
15826 isc_rwlock_destroy(&zmgr->rwlock);
15827 mctx = zmgr->mctx;
15828 isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr));
15829 isc_mem_detach(&mctx);
15830 }
15831
15832 void
15833 dns_zonemgr_settransfersin(dns_zonemgr_t *zmgr, isc_uint32_t value) {
15834 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15835
15836 zmgr->transfersin = value;
15837 }
15838
15839 isc_uint32_t
15840 dns_zonemgr_getttransfersin(dns_zonemgr_t *zmgr) {
15841 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15842
15843 return (zmgr->transfersin);
15844 }
15845
15846 void
15847 dns_zonemgr_settransfersperns(dns_zonemgr_t *zmgr, isc_uint32_t value) {
15848 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15849
15850 zmgr->transfersperns = value;
15851 }
15852
15853 isc_uint32_t
15854 dns_zonemgr_getttransfersperns(dns_zonemgr_t *zmgr) {
15855 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15856
15857 return (zmgr->transfersperns);
15858 }
15859
15860
15861
15862
15863
15864
15865
15866
15867 static void
15868 zmgr_resume_xfrs(dns_zonemgr_t *zmgr, isc_boolean_t multi) {
15869 dns_zone_t *zone;
15870 dns_zone_t *next;
15871
15872 for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin);
15873 zone != NULL;
15874 zone = next)
15875 {
15876 isc_result_t result;
15877 next = ISC_LIST_NEXT(zone, statelink);
15878 result = zmgr_start_xfrin_ifquota(zmgr, zone);
15879 if (result == ISC_R_SUCCESS) {
15880 if (multi)
15881 continue;
15882
15883
15884
15885 break;
15886 } else if (result == ISC_R_QUOTA) {
15887
15888
15889
15890
15891
15892
15893 continue;
15894 } else {
15895 dns_zone_log(zone, ISC_LOG_DEBUG(1),
15896 "starting zone transfer: %s",
15897 isc_result_totext(result));
15898 break;
15899 }
15900 }
15901 }
15902
15903
15904
15905
15906
15907
15908
15909
15910
15911
15912
15913
15914
15915
15916 static isc_result_t
15917 zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
15918 dns_peer_t *peer = NULL;
15919 isc_netaddr_t masterip;
15920 isc_uint32_t nxfrsin, nxfrsperns;
15921 dns_zone_t *x;
15922 isc_uint32_t maxtransfersin, maxtransfersperns;
15923 isc_event_t *e;
15924
15925
15926
15927
15928
15929 LOCK_ZONE(zone);
15930 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
15931 UNLOCK_ZONE(zone);
15932 goto gotquota;
15933 }
15934
15935
15936
15937
15938
15939 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
15940 (void)dns_peerlist_peerbyaddr(zone->view->peers, &masterip, &peer);
15941 UNLOCK_ZONE(zone);
15942
15943
15944
15945
15946
15947
15948 maxtransfersin = zmgr->transfersin;
15949 maxtransfersperns = zmgr->transfersperns;
15950 if (peer != NULL)
15951 (void)dns_peer_gettransfers(peer, &maxtransfersperns);
15952
15953
15954
15955
15956
15957
15958
15959 nxfrsin = nxfrsperns = 0;
15960 for (x = ISC_LIST_HEAD(zmgr->xfrin_in_progress);
15961 x != NULL;
15962 x = ISC_LIST_NEXT(x, statelink))
15963 {
15964 isc_netaddr_t xip;
15965
15966 LOCK_ZONE(x);
15967 isc_netaddr_fromsockaddr(&xip, &x->masteraddr);
15968 UNLOCK_ZONE(x);
15969
15970 nxfrsin++;
15971 if (isc_netaddr_equal(&xip, &masterip))
15972 nxfrsperns++;
15973 }
15974
15975
15976 if (nxfrsin >= maxtransfersin)
15977 return (ISC_R_QUOTA);
15978
15979 if (nxfrsperns >= maxtransfersperns)
15980 return (ISC_R_QUOTA);
15981
15982 gotquota:
15983
15984
15985
15986
15987
15988 e = isc_event_allocate(zmgr->mctx, zmgr, DNS_EVENT_ZONESTARTXFRIN,
15989 got_transfer_quota, zone, sizeof(isc_event_t));
15990 if (e == NULL)
15991 return (ISC_R_NOMEMORY);
15992
15993 LOCK_ZONE(zone);
15994 INSIST(zone->statelist == &zmgr->waiting_for_xfrin);
15995 ISC_LIST_UNLINK(zmgr->waiting_for_xfrin, zone, statelink);
15996 ISC_LIST_APPEND(zmgr->xfrin_in_progress, zone, statelink);
15997 zone->statelist = &zmgr->xfrin_in_progress;
15998 isc_task_send(zone->task, &e);
15999 dns_zone_log(zone, ISC_LOG_INFO, "Transfer started.");
16000 UNLOCK_ZONE(zone);
16001
16002 return (ISC_R_SUCCESS);
16003 }
16004
16005 void
16006 dns_zonemgr_setiolimit(dns_zonemgr_t *zmgr, isc_uint32_t iolimit) {
16007
16008 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
16009 REQUIRE(iolimit > 0);
16010
16011 zmgr->iolimit = iolimit;
16012 }
16013
16014 isc_uint32_t
16015 dns_zonemgr_getiolimit(dns_zonemgr_t *zmgr) {
16016
16017 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
16018
16019 return (zmgr->iolimit);
16020 }
16021
16022
16023
16024
16025
16026
16027
16028
16029
16030
16031
16032 static isc_result_t
16033 zonemgr_getio(dns_zonemgr_t *zmgr, isc_boolean_t high,
16034 isc_task_t *task, isc_taskaction_t action, void *arg,
16035 dns_io_t **iop)
16036 {
16037 dns_io_t *io;
16038 isc_boolean_t queue;
16039
16040 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
16041 REQUIRE(iop != NULL && *iop == NULL);
16042
16043 io = isc_mem_get(zmgr->mctx, sizeof(*io));
16044 if (io == NULL)
16045 return (ISC_R_NOMEMORY);
16046
16047 io->event = isc_event_allocate(zmgr->mctx, task, DNS_EVENT_IOREADY,
16048 action, arg, sizeof(*io->event));
16049 if (io->event == NULL) {
16050 isc_mem_put(zmgr->mctx, io, sizeof(*io));
16051 return (ISC_R_NOMEMORY);
16052 }
16053
16054 io->zmgr = zmgr;
16055 io->high = high;
16056 io->task = NULL;
16057 isc_task_attach(task, &io->task);
16058 ISC_LINK_INIT(io, link);
16059 io->magic = IO_MAGIC;
16060
16061 LOCK(&zmgr->iolock);
16062 zmgr->ioactive++;
16063 queue = ISC_TF(zmgr->ioactive > zmgr->iolimit);
16064 if (queue) {
16065 if (io->high)
16066 ISC_LIST_APPEND(zmgr->high, io, link);
16067 else
16068 ISC_LIST_APPEND(zmgr->low, io, link);
16069 }
16070 UNLOCK(&zmgr->iolock);
16071 *iop = io;
16072
16073 if (!queue)
16074 isc_task_send(io->task, &io->event);
16075 return (ISC_R_SUCCESS);
16076 }
16077
16078 static void
16079 zonemgr_putio(dns_io_t **iop) {
16080 dns_io_t *io;
16081 dns_io_t *next;
16082 dns_zonemgr_t *zmgr;
16083
16084 REQUIRE(iop != NULL);
16085 io = *iop;
16086 REQUIRE(DNS_IO_VALID(io));
16087
16088 *iop = NULL;
16089
16090 INSIST(!ISC_LINK_LINKED(io, link));
16091 INSIST(io->event == NULL);
16092
16093 zmgr = io->zmgr;
16094 isc_task_detach(&io->task);
16095 io->magic = 0;
16096 isc_mem_put(zmgr->mctx, io, sizeof(*io));
16097
16098 LOCK(&zmgr->iolock);
16099 INSIST(zmgr->ioactive > 0);
16100 zmgr->ioactive--;
16101 next = HEAD(zmgr->high);
16102 if (next == NULL)
16103 next = HEAD(zmgr->low);
16104 if (next != NULL) {
16105 if (next->high)
16106 ISC_LIST_UNLINK(zmgr->high, next, link);
16107 else
16108 ISC_LIST_UNLINK(zmgr->low, next, link);
16109 INSIST(next->event != NULL);
16110 }
16111 UNLOCK(&zmgr->iolock);
16112 if (next != NULL)
16113 isc_task_send(next->task, &next->event);
16114 }
16115
16116 static void
16117 zonemgr_cancelio(dns_io_t *io) {
16118 isc_boolean_t send_event = ISC_FALSE;
16119
16120 REQUIRE(DNS_IO_VALID(io));
16121
16122
16123
16124
16125 LOCK(&io->zmgr->iolock);
16126 if (ISC_LINK_LINKED(io, link)) {
16127 if (io->high)
16128 ISC_LIST_UNLINK(io->zmgr->high, io, link);
16129 else
16130 ISC_LIST_UNLINK(io->zmgr->low, io, link);
16131
16132 send_event = ISC_TRUE;
16133 INSIST(io->event != NULL);
16134 }
16135 UNLOCK(&io->zmgr->iolock);
16136 if (send_event) {
16137 io->event->ev_attributes |= ISC_EVENTATTR_CANCELED;
16138 isc_task_send(io->task, &io->event);
16139 }
16140 }
16141
16142 static void
16143 zone_saveunique(dns_zone_t *zone, const char *path, const char *templat) {
16144 char *buf;
16145 int buflen;
16146 isc_result_t result;
16147
16148 buflen = strlen(path) + strlen(templat) + 2;
16149
16150 buf = isc_mem_get(zone->mctx, buflen);
16151 if (buf == NULL)
16152 return;
16153
16154 result = isc_file_template(path, templat, buf, buflen);
16155 if (result != ISC_R_SUCCESS)
16156 goto cleanup;
16157
16158 result = isc_file_renameunique(path, buf);
16159 if (result != ISC_R_SUCCESS)
16160 goto cleanup;
16161
16162 dns_zone_log(zone, ISC_LOG_WARNING, "unable to load from '%s'; "
16163 "renaming file to '%s' for failure analysis and "
16164 "retransferring.", path, buf);
16165
16166 cleanup:
16167 isc_mem_put(zone->mctx, buf, buflen);
16168 }
16169
16170 #if 0
16171
16172
16173 static void
16174 dns_zonemgr_dbdestroyed(isc_task_t *task, isc_event_t *event) {
16175 dns_db_t *db = event->sender;
16176 UNUSED(task);
16177
16178 isc_event_free(&event);
16179
16180 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
16181 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
16182 "database (%p) destroyed", (void*) db);
16183 }
16184 #endif
16185
16186 static void
16187 setrl(isc_ratelimiter_t *rl, unsigned int *rate, unsigned int value) {
16188 isc_interval_t interval;
16189 isc_uint32_t s, ns;
16190 isc_uint32_t pertic;
16191 isc_result_t result;
16192
16193 if (value == 0)
16194 value = 1;
16195
16196 if (value == 1) {
16197 s = 1;
16198 ns = 0;
16199 pertic = 1;
16200 } else if (value <= 10) {
16201 s = 0;
16202 ns = 1000000000 / value;
16203 pertic = 1;
16204 } else {
16205 s = 0;
16206 ns = (1000000000 / value) * 10;
16207 pertic = 10;
16208 }
16209
16210 isc_interval_set(&interval, s, ns);
16211
16212 result = isc_ratelimiter_setinterval(rl, &interval);
16213 RUNTIME_CHECK(result == ISC_R_SUCCESS);
16214 isc_ratelimiter_setpertic(rl, pertic);
16215
16216 *rate = value;
16217 }
16218
16219 void
16220 dns_zonemgr_setnotifyrate(dns_zonemgr_t *zmgr, unsigned int value) {
16221
16222 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
16223
16224 setrl(zmgr->notifyrl, &zmgr->notifyrate, value);
16225 }
16226
16227 void
16228 dns_zonemgr_setstartupnotifyrate(dns_zonemgr_t *zmgr, unsigned int value) {
16229
16230 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
16231
16232 setrl(zmgr->startupnotifyrl, &zmgr->startupnotifyrate, value);
16233 }
16234
16235 void
16236 dns_zonemgr_setserialqueryrate(dns_zonemgr_t *zmgr, unsigned int value) {
16237
16238 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
16239
16240 setrl(zmgr->refreshrl, &zmgr->serialqueryrate, value);
16241
16242 setrl(zmgr->startuprefreshrl, &zmgr->startupserialqueryrate, value);
16243 }
16244
16245 unsigned int
16246 dns_zonemgr_getnotifyrate(dns_zonemgr_t *zmgr) {
16247 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
16248
16249 return (zmgr->notifyrate);
16250 }
16251
16252 unsigned int
16253 dns_zonemgr_getstartupnotifyrate(dns_zonemgr_t *zmgr) {
16254 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
16255
16256 return (zmgr->startupnotifyrate);
16257 }
16258
16259 unsigned int
16260 dns_zonemgr_getserialqueryrate(dns_zonemgr_t *zmgr) {
16261 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
16262
16263 return (zmgr->serialqueryrate);
16264 }
16265
16266 isc_boolean_t
16267 dns_zonemgr_unreachable(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
16268 isc_sockaddr_t *local, isc_time_t *now)
16269 {
16270 unsigned int i;
16271 isc_rwlocktype_t locktype;
16272 isc_result_t result;
16273 isc_uint32_t seconds = isc_time_seconds(now);
16274 isc_uint32_t count = 0;
16275
16276 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
16277
16278 locktype = isc_rwlocktype_read;
16279 RWLOCK(&zmgr->urlock, locktype);
16280 for (i = 0; i < UNREACH_CHACHE_SIZE; i++) {
16281 if (zmgr->unreachable[i].expire >= seconds &&
16282 isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
16283 isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) {
16284 result = isc_rwlock_tryupgrade(&zmgr->urlock);
16285 if (result == ISC_R_SUCCESS) {
16286 locktype = isc_rwlocktype_write;
16287 zmgr->unreachable[i].last = seconds;
16288 count = zmgr->unreachable[i].count;
16289 }
16290 break;
16291 }
16292 }
16293 RWUNLOCK(&zmgr->urlock, locktype);
16294 return (ISC_TF(i < UNREACH_CHACHE_SIZE && count > 1U));
16295 }
16296
16297 void
16298 dns_zonemgr_unreachabledel(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
16299 isc_sockaddr_t *local)
16300 {
16301 unsigned int i;
16302 isc_rwlocktype_t locktype;
16303 isc_result_t result;
16304
16305 char master[ISC_SOCKADDR_FORMATSIZE];
16306 char source[ISC_SOCKADDR_FORMATSIZE];
16307
16308 isc_sockaddr_format(remote, master, sizeof(master));
16309 isc_sockaddr_format(local, source, sizeof(source));
16310
16311 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
16312
16313 locktype = isc_rwlocktype_read;
16314 RWLOCK(&zmgr->urlock, locktype);
16315 for (i = 0; i < UNREACH_CHACHE_SIZE; i++) {
16316 if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
16317 isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) {
16318 if (zmgr->unreachable[i].expire == 0)
16319 break;
16320 result = isc_rwlock_tryupgrade(&zmgr->urlock);
16321 if (result == ISC_R_SUCCESS) {
16322 locktype = isc_rwlocktype_write;
16323 zmgr->unreachable[i].expire = 0;
16324 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
16325 DNS_LOGMODULE_ZONE, ISC_LOG_INFO,
16326 "master %s (source %s) deleted "
16327 "from unreachable cache",
16328 master, source);
16329 }
16330 break;
16331 }
16332 }
16333 RWUNLOCK(&zmgr->urlock, locktype);
16334 }
16335
16336 void
16337 dns_zonemgr_unreachableadd(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
16338 isc_sockaddr_t *local, isc_time_t *now)
16339 {
16340 isc_uint32_t seconds = isc_time_seconds(now);
16341 isc_uint32_t last = seconds;
16342 unsigned int i, slot = UNREACH_CHACHE_SIZE, oldest = 0;
16343
16344 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
16345
16346 RWLOCK(&zmgr->urlock, isc_rwlocktype_write);
16347 for (i = 0; i < UNREACH_CHACHE_SIZE; i++) {
16348
16349 if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
16350 isc_sockaddr_equal(&zmgr->unreachable[i].local, local))
16351 break;
16352
16353 if (zmgr->unreachable[i].expire < seconds)
16354 slot = i;
16355
16356 if (zmgr->unreachable[i].last < last) {
16357 last = zmgr->unreachable[i].last;
16358 oldest = i;
16359 }
16360 }
16361 if (i < UNREACH_CHACHE_SIZE) {
16362
16363
16364
16365
16366 zmgr->unreachable[i].expire = seconds + UNREACH_HOLD_TIME;
16367 zmgr->unreachable[i].last = seconds;
16368 if (zmgr->unreachable[i].expire < seconds)
16369 zmgr->unreachable[i].count = 1;
16370 else
16371 zmgr->unreachable[i].count++;
16372 } else if (slot != UNREACH_CHACHE_SIZE) {
16373
16374
16375
16376 zmgr->unreachable[slot].expire = seconds + UNREACH_HOLD_TIME;
16377 zmgr->unreachable[slot].last = seconds;
16378 zmgr->unreachable[slot].remote = *remote;
16379 zmgr->unreachable[slot].local = *local;
16380 zmgr->unreachable[slot].count = 1;
16381 } else {
16382
16383
16384
16385 zmgr->unreachable[oldest].expire = seconds + UNREACH_HOLD_TIME;
16386 zmgr->unreachable[oldest].last = seconds;
16387 zmgr->unreachable[oldest].remote = *remote;
16388 zmgr->unreachable[oldest].local = *local;
16389 zmgr->unreachable[oldest].count = 1;
16390 }
16391 RWUNLOCK(&zmgr->urlock, isc_rwlocktype_write);
16392 }
16393
16394 void
16395 dns_zone_forcereload(dns_zone_t *zone) {
16396 REQUIRE(DNS_ZONE_VALID(zone));
16397
16398 if (zone->type == dns_zone_master ||
16399 (zone->type == dns_zone_redirect && zone->masters == NULL))
16400 return;
16401
16402 LOCK_ZONE(zone);
16403 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FORCEXFER);
16404 UNLOCK_ZONE(zone);
16405 dns_zone_refresh(zone);
16406 }
16407
16408 isc_boolean_t
16409 dns_zone_isforced(dns_zone_t *zone) {
16410 REQUIRE(DNS_ZONE_VALID(zone));
16411
16412 return (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER));
16413 }
16414
16415 isc_result_t
16416 dns_zone_setstatistics(dns_zone_t *zone, isc_boolean_t on) {
16417
16418
16419
16420 UNUSED(zone);
16421 UNUSED(on);
16422 return (ISC_R_NOTIMPLEMENTED);
16423 }
16424
16425 isc_uint64_t *
16426 dns_zone_getstatscounters(dns_zone_t *zone) {
16427
16428
16429
16430 UNUSED(zone);
16431 return (NULL);
16432 }
16433
16434 void
16435 dns_zone_setstats(dns_zone_t *zone, isc_stats_t *stats) {
16436 REQUIRE(DNS_ZONE_VALID(zone));
16437 REQUIRE(zone->stats == NULL);
16438
16439 LOCK_ZONE(zone);
16440 zone->stats = NULL;
16441 isc_stats_attach(stats, &zone->stats);
16442 UNLOCK_ZONE(zone);
16443 }
16444
16445 void
16446 dns_zone_setrequeststats(dns_zone_t *zone, isc_stats_t *stats) {
16447
16448 REQUIRE(DNS_ZONE_VALID(zone));
16449
16450 LOCK_ZONE(zone);
16451 if (zone->requeststats_on && stats == NULL)
16452 zone->requeststats_on = ISC_FALSE;
16453 else if (!zone->requeststats_on && stats != NULL) {
16454 if (zone->requeststats == NULL) {
16455 isc_stats_attach(stats, &zone->requeststats);
16456 zone->requeststats_on = ISC_TRUE;
16457 }
16458 }
16459 UNLOCK_ZONE(zone);
16460 }
16461
16462 void
16463 dns_zone_setrcvquerystats(dns_zone_t *zone, dns_stats_t *stats) {
16464
16465 REQUIRE(DNS_ZONE_VALID(zone));
16466
16467 LOCK_ZONE(zone);
16468 if (zone->requeststats_on && stats != NULL) {
16469 if (zone->rcvquerystats == NULL) {
16470 dns_stats_attach(stats, &zone->rcvquerystats);
16471 zone->requeststats_on = ISC_TRUE;
16472 }
16473 }
16474 UNLOCK_ZONE(zone);
16475 }
16476
16477 isc_stats_t *
16478 dns_zone_getrequeststats(dns_zone_t *zone) {
16479
16480
16481
16482
16483
16484
16485
16486
16487 if (zone->requeststats_on)
16488 return (zone->requeststats);
16489 else
16490 return (NULL);
16491 }
16492
16493
16494
16495
16496
16497 dns_stats_t *
16498 dns_zone_getrcvquerystats(dns_zone_t *zone) {
16499 if (zone->requeststats_on)
16500 return (zone->rcvquerystats);
16501 else
16502 return (NULL);
16503 }
16504
16505 void
16506 dns_zone_dialup(dns_zone_t *zone) {
16507
16508 REQUIRE(DNS_ZONE_VALID(zone));
16509
16510 zone_debuglog(zone, "dns_zone_dialup", 3,
16511 "notify = %d, refresh = %d",
16512 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY),
16513 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH));
16514
16515 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY))
16516 dns_zone_notify(zone);
16517 if (zone->type != dns_zone_master && zone->masters != NULL &&
16518 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
16519 dns_zone_refresh(zone);
16520 }
16521
16522 void
16523 dns_zone_setdialup(dns_zone_t *zone, dns_dialuptype_t dialup) {
16524 REQUIRE(DNS_ZONE_VALID(zone));
16525
16526 LOCK_ZONE(zone);
16527 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DIALNOTIFY |
16528 DNS_ZONEFLG_DIALREFRESH |
16529 DNS_ZONEFLG_NOREFRESH);
16530 switch (dialup) {
16531 case dns_dialuptype_no:
16532 break;
16533 case dns_dialuptype_yes:
16534 DNS_ZONE_SETFLAG(zone, (DNS_ZONEFLG_DIALNOTIFY |
16535 DNS_ZONEFLG_DIALREFRESH |
16536 DNS_ZONEFLG_NOREFRESH));
16537 break;
16538 case dns_dialuptype_notify:
16539 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY);
16540 break;
16541 case dns_dialuptype_notifypassive:
16542 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY);
16543 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
16544 break;
16545 case dns_dialuptype_refresh:
16546 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALREFRESH);
16547 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
16548 break;
16549 case dns_dialuptype_passive:
16550 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
16551 break;
16552 default:
16553 INSIST(0);
16554 }
16555 UNLOCK_ZONE(zone);
16556 }
16557
16558 isc_result_t
16559 dns_zone_setkeydirectory(dns_zone_t *zone, const char *directory) {
16560 isc_result_t result = ISC_R_SUCCESS;
16561
16562 REQUIRE(DNS_ZONE_VALID(zone));
16563
16564 LOCK_ZONE(zone);
16565 result = dns_zone_setstring(zone, &zone->keydirectory, directory);
16566 UNLOCK_ZONE(zone);
16567
16568 return (result);
16569 }
16570
16571 const char *
16572 dns_zone_getkeydirectory(dns_zone_t *zone) {
16573 REQUIRE(DNS_ZONE_VALID(zone));
16574
16575 return (zone->keydirectory);
16576 }
16577
16578 unsigned int
16579 dns_zonemgr_getcount(dns_zonemgr_t *zmgr, int state) {
16580 dns_zone_t *zone;
16581 unsigned int count = 0;
16582
16583 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
16584
16585 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
16586 switch (state) {
16587 case DNS_ZONESTATE_XFERRUNNING:
16588 for (zone = ISC_LIST_HEAD(zmgr->xfrin_in_progress);
16589 zone != NULL;
16590 zone = ISC_LIST_NEXT(zone, statelink))
16591 count++;
16592 break;
16593 case DNS_ZONESTATE_XFERDEFERRED:
16594 for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin);
16595 zone != NULL;
16596 zone = ISC_LIST_NEXT(zone, statelink))
16597 count++;
16598 break;
16599 case DNS_ZONESTATE_SOAQUERY:
16600 for (zone = ISC_LIST_HEAD(zmgr->zones);
16601 zone != NULL;
16602 zone = ISC_LIST_NEXT(zone, link))
16603 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH))
16604 count++;
16605 break;
16606 case DNS_ZONESTATE_ANY:
16607 for (zone = ISC_LIST_HEAD(zmgr->zones);
16608 zone != NULL;
16609 zone = ISC_LIST_NEXT(zone, link)) {
16610 dns_view_t *view = zone->view;
16611 if (view != NULL && strcmp(view->name, "_bind") == 0)
16612 continue;
16613 count++;
16614 }
16615 break;
16616 case DNS_ZONESTATE_AUTOMATIC:
16617 for (zone = ISC_LIST_HEAD(zmgr->zones);
16618 zone != NULL;
16619 zone = ISC_LIST_NEXT(zone, link)) {
16620 dns_view_t *view = zone->view;
16621 if (view != NULL && strcmp(view->name, "_bind") == 0)
16622 continue;
16623 if (zone->automatic)
16624 count++;
16625 }
16626 break;
16627 default:
16628 INSIST(0);
16629 }
16630
16631 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
16632
16633 return (count);
16634 }
16635
16636 isc_result_t
16637 dns_zone_checknames(dns_zone_t *zone, dns_name_t *name, dns_rdata_t *rdata) {
16638 isc_boolean_t ok = ISC_TRUE;
16639 isc_boolean_t fail = ISC_FALSE;
16640 char namebuf[DNS_NAME_FORMATSIZE];
16641 char namebuf2[DNS_NAME_FORMATSIZE];
16642 char typebuf[DNS_RDATATYPE_FORMATSIZE];
16643 int level = ISC_LOG_WARNING;
16644 dns_name_t bad;
16645
16646 REQUIRE(DNS_ZONE_VALID(zone));
16647
16648 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES) &&
16649 rdata->type != dns_rdatatype_nsec3)
16650 return (ISC_R_SUCCESS);
16651
16652 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL) ||
16653 rdata->type == dns_rdatatype_nsec3) {
16654 level = ISC_LOG_ERROR;
16655 fail = ISC_TRUE;
16656 }
16657
16658 ok = dns_rdata_checkowner(name, rdata->rdclass, rdata->type, ISC_TRUE);
16659 if (!ok) {
16660 dns_name_format(name, namebuf, sizeof(namebuf));
16661 dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf));
16662 dns_zone_log(zone, level, "%s/%s: %s", namebuf, typebuf,
16663 dns_result_totext(DNS_R_BADOWNERNAME));
16664 if (fail)
16665 return (DNS_R_BADOWNERNAME);
16666 }
16667
16668 dns_name_init(&bad, NULL);
16669 ok = dns_rdata_checknames(rdata, name, &bad);
16670 if (!ok) {
16671 dns_name_format(name, namebuf, sizeof(namebuf));
16672 dns_name_format(&bad, namebuf2, sizeof(namebuf2));
16673 dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf));
16674 dns_zone_log(zone, level, "%s/%s: %s: %s ", namebuf, typebuf,
16675 namebuf2, dns_result_totext(DNS_R_BADNAME));
16676 if (fail)
16677 return (DNS_R_BADNAME);
16678 }
16679
16680 return (ISC_R_SUCCESS);
16681 }
16682
16683 void
16684 dns_zone_setcheckmx(dns_zone_t *zone, dns_checkmxfunc_t checkmx) {
16685 REQUIRE(DNS_ZONE_VALID(zone));
16686 zone->checkmx = checkmx;
16687 }
16688
16689 void
16690 dns_zone_setchecksrv(dns_zone_t *zone, dns_checksrvfunc_t checksrv) {
16691 REQUIRE(DNS_ZONE_VALID(zone));
16692 zone->checksrv = checksrv;
16693 }
16694
16695 void
16696 dns_zone_setcheckns(dns_zone_t *zone, dns_checknsfunc_t checkns) {
16697 REQUIRE(DNS_ZONE_VALID(zone));
16698 zone->checkns = checkns;
16699 }
16700
16701 void
16702 dns_zone_setisself(dns_zone_t *zone, dns_isselffunc_t isself, void *arg) {
16703 REQUIRE(DNS_ZONE_VALID(zone));
16704
16705 LOCK_ZONE(zone);
16706 zone->isself = isself;
16707 zone->isselfarg = arg;
16708 UNLOCK_ZONE(zone);
16709 }
16710
16711 void
16712 dns_zone_setnotifydelay(dns_zone_t *zone, isc_uint32_t delay) {
16713 REQUIRE(DNS_ZONE_VALID(zone));
16714
16715 LOCK_ZONE(zone);
16716 zone->notifydelay = delay;
16717 UNLOCK_ZONE(zone);
16718 }
16719
16720 isc_uint32_t
16721 dns_zone_getnotifydelay(dns_zone_t *zone) {
16722 REQUIRE(DNS_ZONE_VALID(zone));
16723
16724 return (zone->notifydelay);
16725 }
16726
16727 isc_result_t
16728 dns_zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm,
16729 isc_uint16_t keyid, isc_boolean_t delete)
16730 {
16731 isc_result_t result;
16732 REQUIRE(DNS_ZONE_VALID(zone));
16733
16734 dns_zone_log(zone, ISC_LOG_NOTICE,
16735 "dns_zone_signwithkey(algorithm=%u, keyid=%u)",
16736 algorithm, keyid);
16737 LOCK_ZONE(zone);
16738 result = zone_signwithkey(zone, algorithm, keyid, delete);
16739 UNLOCK_ZONE(zone);
16740
16741 return (result);
16742 }
16743
16744 static const char *hex = "0123456789ABCDEF";
16745
16746 isc_result_t
16747 dns_zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) {
16748 isc_result_t result;
16749 char salt[255*2+1];
16750 unsigned int i, j;
16751
16752 REQUIRE(DNS_ZONE_VALID(zone));
16753
16754 if (nsec3param->salt_length != 0) {
16755 INSIST((nsec3param->salt_length * 2U) < sizeof(salt));
16756 for (i = 0, j = 0; i < nsec3param->salt_length; i++) {
16757 salt[j++] = hex[(nsec3param->salt[i] >> 4) & 0xf];
16758 salt[j++] = hex[nsec3param->salt[i] & 0xf];
16759 }
16760 salt[j] = '\0';
16761 } else
16762 strcpy(salt, "-");
16763 dns_zone_log(zone, ISC_LOG_NOTICE,
16764 "dns_zone_addnsec3chain(hash=%u, iterations=%u, salt=%s)",
16765 nsec3param->hash, nsec3param->iterations,
16766 salt);
16767 LOCK_ZONE(zone);
16768 result = zone_addnsec3chain(zone, nsec3param);
16769 UNLOCK_ZONE(zone);
16770
16771 return (result);
16772 }
16773
16774 void
16775 dns_zone_setnodes(dns_zone_t *zone, isc_uint32_t nodes) {
16776 REQUIRE(DNS_ZONE_VALID(zone));
16777
16778 if (nodes == 0)
16779 nodes = 1;
16780 zone->nodes = nodes;
16781 }
16782
16783 void
16784 dns_zone_setsignatures(dns_zone_t *zone, isc_uint32_t signatures) {
16785 REQUIRE(DNS_ZONE_VALID(zone));
16786
16787
16788
16789
16790
16791 if (signatures > ISC_INT32_MAX)
16792 signatures = ISC_INT32_MAX;
16793 else if (signatures == 0)
16794 signatures = 1;
16795 zone->signatures = signatures;
16796 }
16797
16798 isc_uint32_t
16799 dns_zone_getsignatures(dns_zone_t *zone) {
16800 REQUIRE(DNS_ZONE_VALID(zone));
16801 return (zone->signatures);
16802 }
16803
16804 void
16805 dns_zone_setprivatetype(dns_zone_t *zone, dns_rdatatype_t type) {
16806 REQUIRE(DNS_ZONE_VALID(zone));
16807 zone->privatetype = type;
16808 }
16809
16810 dns_rdatatype_t
16811 dns_zone_getprivatetype(dns_zone_t *zone) {
16812 REQUIRE(DNS_ZONE_VALID(zone));
16813 return (zone->privatetype);
16814 }
16815
16816 static isc_result_t
16817 zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, isc_uint16_t keyid,
16818 isc_boolean_t delete)
16819 {
16820 dns_signing_t *signing;
16821 dns_signing_t *current;
16822 isc_result_t result = ISC_R_SUCCESS;
16823 isc_time_t now;
16824 dns_db_t *db = NULL;
16825
16826 signing = isc_mem_get(zone->mctx, sizeof *signing);
16827 if (signing == NULL)
16828 return (ISC_R_NOMEMORY);
16829
16830 signing->magic = 0;
16831 signing->db = NULL;
16832 signing->dbiterator = NULL;
16833 signing->algorithm = algorithm;
16834 signing->keyid = keyid;
16835 signing->delete = delete;
16836 signing->done = ISC_FALSE;
16837
16838 TIME_NOW(&now);
16839
16840 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
16841 if (zone->db != NULL)
16842 dns_db_attach(zone->db, &db);
16843 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
16844
16845 if (db == NULL) {
16846 result = ISC_R_NOTFOUND;
16847 goto cleanup;
16848 }
16849
16850 dns_db_attach(db, &signing->db);
16851
16852 for (current = ISC_LIST_HEAD(zone->signing);
16853 current != NULL;
16854 current = ISC_LIST_NEXT(current, link)) {
16855 if (current->db == signing->db &&
16856 current->algorithm == signing->algorithm &&
16857 current->keyid == signing->keyid) {
16858 if (current->delete != signing->delete)
16859 current->done = ISC_TRUE;
16860 else
16861 goto cleanup;
16862 }
16863 }
16864
16865 result = dns_db_createiterator(signing->db, 0,
16866 &signing->dbiterator);
16867
16868 if (result == ISC_R_SUCCESS)
16869 result = dns_dbiterator_first(signing->dbiterator);
16870 if (result == ISC_R_SUCCESS) {
16871 dns_dbiterator_pause(signing->dbiterator);
16872 ISC_LIST_INITANDAPPEND(zone->signing, signing, link);
16873 signing = NULL;
16874 if (isc_time_isepoch(&zone->signingtime)) {
16875 zone->signingtime = now;
16876 if (zone->task != NULL)
16877 zone_settimer(zone, &now);
16878 }
16879 }
16880
16881 cleanup:
16882 if (signing != NULL) {
16883 if (signing->db != NULL)
16884 dns_db_detach(&signing->db);
16885 if (signing->dbiterator != NULL)
16886 dns_dbiterator_destroy(&signing->dbiterator);
16887 isc_mem_put(zone->mctx, signing, sizeof *signing);
16888 }
16889 if (db != NULL)
16890 dns_db_detach(&db);
16891 return (result);
16892 }
16893
16894 static void
16895 logmsg(const char *format, ...) {
16896 va_list args;
16897 va_start(args, format);
16898 isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE,
16899 ISC_LOG_DEBUG(1), format, args);
16900 va_end(args);
16901 }
16902
16903 static void
16904 clear_keylist(dns_dnsseckeylist_t *list, isc_mem_t *mctx) {
16905 dns_dnsseckey_t *key;
16906 while (!ISC_LIST_EMPTY(*list)) {
16907 key = ISC_LIST_HEAD(*list);
16908 ISC_LIST_UNLINK(*list, key, link);
16909 dns_dnsseckey_destroy(mctx, &key);
16910 }
16911 }
16912
16913
16914 static isc_result_t
16915 next_keyevent(dst_key_t *key, isc_stdtime_t *timep) {
16916 isc_result_t result;
16917 isc_stdtime_t now, then = 0, event;
16918 int i;
16919
16920 now = *timep;
16921
16922 for (i = 0; i <= DST_MAX_TIMES; i++) {
16923 result = dst_key_gettime(key, i, &event);
16924 if (result == ISC_R_SUCCESS && event > now &&
16925 (then == 0 || event < then))
16926 then = event;
16927 }
16928
16929 if (then != 0) {
16930 *timep = then;
16931 return (ISC_R_SUCCESS);
16932 }
16933
16934 return (ISC_R_NOTFOUND);
16935 }
16936
16937 static isc_result_t
16938 rr_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
16939 const dns_rdata_t *rdata, isc_boolean_t *flag)
16940 {
16941 dns_rdataset_t rdataset;
16942 dns_dbnode_t *node = NULL;
16943 isc_result_t result;
16944
16945 dns_rdataset_init(&rdataset);
16946 if (rdata->type == dns_rdatatype_nsec3)
16947 CHECK(dns_db_findnsec3node(db, name, ISC_FALSE, &node));
16948 else
16949 CHECK(dns_db_findnode(db, name, ISC_FALSE, &node));
16950 result = dns_db_findrdataset(db, node, ver, rdata->type, 0,
16951 (isc_stdtime_t) 0, &rdataset, NULL);
16952 if (result == ISC_R_NOTFOUND) {
16953 *flag = ISC_FALSE;
16954 result = ISC_R_SUCCESS;
16955 goto failure;
16956 }
16957
16958 for (result = dns_rdataset_first(&rdataset);
16959 result == ISC_R_SUCCESS;
16960 result = dns_rdataset_next(&rdataset)) {
16961 dns_rdata_t myrdata = DNS_RDATA_INIT;
16962 dns_rdataset_current(&rdataset, &myrdata);
16963 if (!dns_rdata_compare(&myrdata, rdata))
16964 break;
16965 }
16966 dns_rdataset_disassociate(&rdataset);
16967 if (result == ISC_R_SUCCESS) {
16968 *flag = ISC_TRUE;
16969 } else if (result == ISC_R_NOMORE) {
16970 *flag = ISC_FALSE;
16971 result = ISC_R_SUCCESS;
16972 }
16973
16974 failure:
16975 if (node != NULL)
16976 dns_db_detachnode(db, &node);
16977 return (result);
16978 }
16979
16980
16981
16982
16983 static isc_result_t
16984 add_signing_records(dns_db_t *db, dns_rdatatype_t privatetype,
16985 dns_dbversion_t *ver, dns_diff_t *diff,
16986 isc_boolean_t sign_all)
16987 {
16988 dns_difftuple_t *tuple, *newtuple = NULL;
16989 dns_rdata_dnskey_t dnskey;
16990 dns_rdata_t rdata = DNS_RDATA_INIT;
16991 isc_boolean_t flag;
16992 isc_region_t r;
16993 isc_result_t result = ISC_R_SUCCESS;
16994 isc_uint16_t keyid;
16995 unsigned char buf[5];
16996 dns_name_t *name = dns_db_origin(db);
16997
16998 for (tuple = ISC_LIST_HEAD(diff->tuples);
16999 tuple != NULL;
17000 tuple = ISC_LIST_NEXT(tuple, link)) {
17001 if (tuple->rdata.type != dns_rdatatype_dnskey)
17002 continue;
17003
17004 result = dns_rdata_tostruct(&tuple->rdata, &dnskey, NULL);
17005 RUNTIME_CHECK(result == ISC_R_SUCCESS);
17006 if ((dnskey.flags &
17007 (DNS_KEYFLAG_OWNERMASK|DNS_KEYTYPE_NOAUTH))
17008 != DNS_KEYOWNER_ZONE)
17009 continue;
17010
17011 dns_rdata_toregion(&tuple->rdata, &r);
17012
17013 keyid = dst_region_computeid(&r, dnskey.algorithm);
17014
17015 buf[0] = dnskey.algorithm;
17016 buf[1] = (keyid & 0xff00) >> 8;
17017 buf[2] = (keyid & 0xff);
17018 buf[3] = (tuple->op == DNS_DIFFOP_ADD) ? 0 : 1;
17019 buf[4] = 0;
17020 rdata.data = buf;
17021 rdata.length = sizeof(buf);
17022 rdata.type = privatetype;
17023 rdata.rdclass = tuple->rdata.rdclass;
17024
17025 if (sign_all || tuple->op == DNS_DIFFOP_DEL) {
17026 CHECK(rr_exists(db, ver, name, &rdata, &flag));
17027 if (flag)
17028 continue;
17029 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
17030 name, 0, &rdata, &newtuple));
17031 CHECK(do_one_tuple(&newtuple, db, ver, diff));
17032 INSIST(newtuple == NULL);
17033 }
17034
17035
17036
17037
17038
17039 buf[4] = 1;
17040 CHECK(rr_exists(db, ver, name, &rdata, &flag));
17041 if (flag) {
17042 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL,
17043 name, 0, &rdata, &newtuple));
17044 CHECK(do_one_tuple(&newtuple, db, ver, diff));
17045 INSIST(newtuple == NULL);
17046 }
17047 }
17048 failure:
17049 return (result);
17050 }
17051
17052 static isc_result_t
17053 sign_apex(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
17054 dns_diff_t *diff, zonediff_t *zonediff)
17055 {
17056 isc_result_t result;
17057 isc_stdtime_t now, inception, soaexpire;
17058 isc_boolean_t check_ksk, keyset_kskonly;
17059 dst_key_t *zone_keys[DNS_MAXZONEKEYS];
17060 unsigned int nkeys = 0, i;
17061 dns_difftuple_t *tuple;
17062
17063 result = find_zone_keys(zone, db, ver, zone->mctx, DNS_MAXZONEKEYS,
17064 zone_keys, &nkeys);
17065 if (result != ISC_R_SUCCESS) {
17066 dns_zone_log(zone, ISC_LOG_ERROR,
17067 "sign_apex:find_zone_keys -> %s",
17068 dns_result_totext(result));
17069 return (result);
17070 }
17071
17072 isc_stdtime_get(&now);
17073 inception = now - 3600;
17074 soaexpire = now + dns_zone_getsigvalidityinterval(zone);
17075
17076 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
17077 keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
17078
17079
17080
17081
17082
17083
17084 for (tuple = ISC_LIST_HEAD(diff->tuples);
17085 tuple != NULL;
17086 tuple = ISC_LIST_NEXT(tuple, link)) {
17087 if (tuple->rdata.type == dns_rdatatype_dnskey &&
17088 dns_name_equal(&tuple->name, &zone->origin))
17089 break;
17090 }
17091
17092 if (tuple == NULL) {
17093 result = del_sigs(zone, db, ver, &zone->origin,
17094 dns_rdatatype_dnskey, zonediff,
17095 zone_keys, nkeys, now, ISC_FALSE);
17096 if (result != ISC_R_SUCCESS) {
17097 dns_zone_log(zone, ISC_LOG_ERROR,
17098 "sign_apex:del_sigs -> %s",
17099 dns_result_totext(result));
17100 goto failure;
17101 }
17102 result = add_sigs(db, ver, &zone->origin, dns_rdatatype_dnskey,
17103 zonediff->diff, zone_keys, nkeys, zone->mctx,
17104 inception, soaexpire, check_ksk,
17105 keyset_kskonly);
17106 if (result != ISC_R_SUCCESS) {
17107 dns_zone_log(zone, ISC_LOG_ERROR,
17108 "sign_apex:add_sigs -> %s",
17109 dns_result_totext(result));
17110 goto failure;
17111 }
17112 }
17113
17114 result = update_sigs(diff, db, ver, zone_keys, nkeys, zone,
17115 inception, soaexpire, now, check_ksk,
17116 keyset_kskonly, zonediff);
17117
17118 if (result != ISC_R_SUCCESS) {
17119 dns_zone_log(zone, ISC_LOG_ERROR,
17120 "sign_apex:update_sigs -> %s",
17121 dns_result_totext(result));
17122 goto failure;
17123 }
17124
17125 failure:
17126 for (i = 0; i < nkeys; i++)
17127 dst_key_free(&zone_keys[i]);
17128 return (result);
17129 }
17130
17131
17132
17133
17134
17135
17136 static isc_boolean_t
17137 dnskey_sane(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
17138 dns_diff_t *diff)
17139 {
17140 isc_result_t result;
17141 dns_difftuple_t *tuple;
17142 isc_boolean_t nseconly = ISC_FALSE, nsec3 = ISC_FALSE;
17143 dns_rdatatype_t privatetype = dns_zone_getprivatetype(zone);
17144
17145
17146 for (tuple = ISC_LIST_HEAD(diff->tuples);
17147 tuple != NULL;
17148 tuple = ISC_LIST_NEXT(tuple, link)) {
17149 isc_uint8_t alg;
17150 if (tuple->rdata.type != dns_rdatatype_dnskey ||
17151 tuple->op != DNS_DIFFOP_ADD)
17152 continue;
17153
17154 alg = tuple->rdata.data[3];
17155 if (alg == DST_ALG_RSAMD5 || alg == DST_ALG_RSASHA1 ||
17156 alg == DST_ALG_DSA || alg == DST_ALG_ECC) {
17157 nseconly = ISC_TRUE;
17158 break;
17159 }
17160 }
17161
17162
17163 if (!nseconly) {
17164 result = dns_nsec_nseconly(db, ver, &nseconly);
17165 if (result == ISC_R_NOTFOUND)
17166 result = ISC_R_SUCCESS;
17167 CHECK(result);
17168 }
17169
17170
17171 if (!nsec3)
17172 CHECK(dns_nsec3_activex(db, ver, ISC_FALSE,
17173 privatetype, &nsec3));
17174
17175
17176 if (nseconly && nsec3) {
17177 dns_zone_log(zone, ISC_LOG_ERROR,
17178 "NSEC only DNSKEYs and NSEC3 chains not allowed");
17179 goto failure;
17180 }
17181
17182 return (ISC_TRUE);
17183
17184 failure:
17185 return (ISC_FALSE);
17186 }
17187
17188 static isc_result_t
17189 clean_nsec3param(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
17190 dns_diff_t *diff)
17191 {
17192 isc_result_t result;
17193 dns_dbnode_t *node = NULL;
17194 dns_rdataset_t rdataset;
17195
17196 dns_rdataset_init(&rdataset);
17197 CHECK(dns_db_getoriginnode(db, &node));
17198
17199 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey,
17200 dns_rdatatype_none, 0, &rdataset, NULL);
17201 if (dns_rdataset_isassociated(&rdataset))
17202 dns_rdataset_disassociate(&rdataset);
17203 if (result != ISC_R_NOTFOUND)
17204 goto failure;
17205
17206 result = dns_nsec3param_deletechains(db, ver, zone, ISC_TRUE, diff);
17207
17208 failure:
17209 if (node != NULL)
17210 dns_db_detachnode(db, &node);
17211 return (result);
17212 }
17213
17214
17215
17216
17217
17218 static isc_boolean_t
17219 signed_with_alg(dns_rdataset_t *rdataset, dns_secalg_t alg) {
17220 dns_rdata_t rdata = DNS_RDATA_INIT;
17221 dns_rdata_rrsig_t rrsig;
17222 isc_result_t result;
17223
17224 REQUIRE(rdataset == NULL || rdataset->type == dns_rdatatype_rrsig);
17225 if (rdataset == NULL || !dns_rdataset_isassociated(rdataset)) {
17226 return (ISC_FALSE);
17227 }
17228
17229 for (result = dns_rdataset_first(rdataset);
17230 result == ISC_R_SUCCESS;
17231 result = dns_rdataset_next(rdataset))
17232 {
17233 dns_rdataset_current(rdataset, &rdata);
17234 result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
17235 RUNTIME_CHECK(result == ISC_R_SUCCESS);
17236 dns_rdata_reset(&rdata);
17237 if (rrsig.algorithm == alg)
17238 return (ISC_TRUE);
17239 }
17240
17241 return (ISC_FALSE);
17242 }
17243
17244 static isc_result_t
17245 add_chains(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
17246 dns_diff_t *diff)
17247 {
17248 dns_name_t *origin;
17249 isc_boolean_t build_nsec3;
17250 isc_result_t result;
17251
17252 origin = dns_db_origin(db);
17253 CHECK(dns_private_chains(db, ver, zone->privatetype, NULL,
17254 &build_nsec3));
17255 if (build_nsec3)
17256 CHECK(dns_nsec3_addnsec3sx(db, ver, origin, zone->minimum,
17257 ISC_FALSE, zone->privatetype, diff));
17258 CHECK(updatesecure(db, ver, origin, zone->minimum, ISC_TRUE, diff));
17259
17260 failure:
17261 return (result);
17262 }
17263
17264 static void
17265 zone_rekey(dns_zone_t *zone) {
17266 isc_result_t result;
17267 dns_db_t *db = NULL;
17268 dns_dbnode_t *node = NULL;
17269 dns_dbversion_t *ver = NULL;
17270 dns_rdataset_t soaset, soasigs, keyset, keysigs;
17271 dns_dnsseckeylist_t dnskeys, keys, rmkeys;
17272 dns_dnsseckey_t *key;
17273 dns_diff_t diff, _sig_diff;
17274 zonediff_t zonediff;
17275 isc_boolean_t commit = ISC_FALSE, newactive = ISC_FALSE;
17276 isc_boolean_t newalg = ISC_FALSE;
17277 isc_boolean_t fullsign;
17278 dns_ttl_t ttl = 3600;
17279 const char *dir;
17280 isc_mem_t *mctx;
17281 isc_stdtime_t now;
17282 isc_time_t timenow;
17283 isc_interval_t ival;
17284 char timebuf[80];
17285
17286 REQUIRE(DNS_ZONE_VALID(zone));
17287
17288 ISC_LIST_INIT(dnskeys);
17289 ISC_LIST_INIT(keys);
17290 ISC_LIST_INIT(rmkeys);
17291 dns_rdataset_init(&soaset);
17292 dns_rdataset_init(&soasigs);
17293 dns_rdataset_init(&keyset);
17294 dns_rdataset_init(&keysigs);
17295 dir = dns_zone_getkeydirectory(zone);
17296 mctx = zone->mctx;
17297 dns_diff_init(mctx, &diff);
17298 dns_diff_init(mctx, &_sig_diff);
17299 zonediff_init(&zonediff, &_sig_diff);
17300
17301 CHECK(dns_zone_getdb(zone, &db));
17302 CHECK(dns_db_newversion(db, &ver));
17303 CHECK(dns_db_getoriginnode(db, &node));
17304
17305 TIME_NOW(&timenow);
17306 now = isc_time_seconds(&timenow);
17307
17308 dns_zone_log(zone, ISC_LOG_INFO, "reconfiguring zone keys");
17309
17310
17311 CHECK(dns_db_findrdataset(db, node, ver, dns_rdatatype_soa,
17312 dns_rdatatype_none, 0, &soaset, &soasigs));
17313 ttl = soaset.ttl;
17314 dns_rdataset_disassociate(&soaset);
17315
17316
17317 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey,
17318 dns_rdatatype_none, 0, &keyset, &keysigs);
17319 if (result == ISC_R_SUCCESS) {
17320 ttl = keyset.ttl;
17321 CHECK(dns_dnssec_keylistfromrdataset(&zone->origin, dir,
17322 mctx, &keyset,
17323 &keysigs, &soasigs,
17324 ISC_FALSE, ISC_FALSE,
17325 &dnskeys));
17326 } else if (result != ISC_R_NOTFOUND)
17327 goto failure;
17328
17329
17330
17331
17332
17333 fullsign = ISC_TF(DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_FULLSIGN) != 0);
17334
17335 result = dns_dnssec_findmatchingkeys(&zone->origin, dir, mctx, &keys);
17336 if (result == ISC_R_SUCCESS) {
17337 isc_boolean_t check_ksk;
17338 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
17339
17340 result = dns_dnssec_updatekeys(&dnskeys, &keys, &rmkeys,
17341 &zone->origin, ttl, &diff,
17342 ISC_TF(!check_ksk),
17343 mctx, logmsg);
17344
17345
17346
17347 if (result != ISC_R_SUCCESS) {
17348 dns_zone_log(zone, ISC_LOG_ERROR, "zone_rekey:"
17349 "couldn't update zone keys: %s",
17350 isc_result_totext(result));
17351 goto failure;
17352 }
17353
17354
17355
17356
17357
17358
17359
17360
17361 for (key = ISC_LIST_HEAD(dnskeys);
17362 key != NULL;
17363 key = ISC_LIST_NEXT(key, link)) {
17364 if (!key->first_sign)
17365 continue;
17366
17367 newactive = ISC_TRUE;
17368
17369 if (!dns_rdataset_isassociated(&keysigs)) {
17370 newalg = ISC_TRUE;
17371 break;
17372 }
17373
17374 if (signed_with_alg(&keysigs, dst_key_alg(key->key))) {
17375
17376
17377
17378
17379
17380 key->first_sign = ISC_FALSE;
17381 } else {
17382 newalg = ISC_TRUE;
17383 break;
17384 }
17385 }
17386
17387 if ((newactive || fullsign || !ISC_LIST_EMPTY(diff.tuples)) &&
17388 dnskey_sane(zone, db, ver, &diff)) {
17389 CHECK(dns_diff_apply(&diff, db, ver));
17390 CHECK(clean_nsec3param(zone, db, ver, &diff));
17391 CHECK(add_signing_records(db, zone->privatetype,
17392 ver, &diff,
17393 ISC_TF(newalg || fullsign)));
17394 CHECK(update_soa_serial(db, ver, &diff, mctx,
17395 zone->updatemethod));
17396 CHECK(add_chains(zone, db, ver, &diff));
17397 CHECK(sign_apex(zone, db, ver, &diff, &zonediff));
17398 CHECK(zone_journal(zone, zonediff.diff, NULL,
17399 "zone_rekey"));
17400 commit = ISC_TRUE;
17401 }
17402 }
17403
17404 dns_db_closeversion(db, &ver, ISC_TRUE);
17405
17406 if (commit) {
17407 dns_difftuple_t *tuple;
17408
17409 LOCK_ZONE(zone);
17410 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
17411
17412 zone_needdump(zone, DNS_DUMP_DELAY);
17413
17414 zone_settimer(zone, &timenow);
17415
17416
17417 if (!ISC_LIST_EMPTY(rmkeys)) {
17418 for (key = ISC_LIST_HEAD(rmkeys);
17419 key != NULL;
17420 key = ISC_LIST_NEXT(key, link)) {
17421 result = zone_signwithkey(zone,
17422 dst_key_alg(key->key),
17423 dst_key_id(key->key),
17424 ISC_TRUE);
17425 if (result != ISC_R_SUCCESS) {
17426 dns_zone_log(zone, ISC_LOG_ERROR,
17427 "zone_signwithkey failed: %s",
17428 dns_result_totext(result));
17429 }
17430 }
17431 }
17432
17433 if (fullsign) {
17434
17435
17436
17437
17438 for (key = ISC_LIST_HEAD(dnskeys);
17439 key != NULL;
17440 key = ISC_LIST_NEXT(key, link)) {
17441 if (!key->force_sign && !key->hint_sign)
17442 continue;
17443
17444 result = zone_signwithkey(zone,
17445 dst_key_alg(key->key),
17446 dst_key_id(key->key),
17447 ISC_FALSE);
17448 if (result != ISC_R_SUCCESS) {
17449 dns_zone_log(zone, ISC_LOG_ERROR,
17450 "zone_signwithkey failed: %s",
17451 dns_result_totext(result));
17452 }
17453 }
17454 } else if (newalg) {
17455
17456
17457
17458
17459
17460
17461 for (key = ISC_LIST_HEAD(dnskeys);
17462 key != NULL;
17463 key = ISC_LIST_NEXT(key, link)) {
17464 if (!key->first_sign)
17465 continue;
17466
17467 result = zone_signwithkey(zone,
17468 dst_key_alg(key->key),
17469 dst_key_id(key->key),
17470 ISC_FALSE);
17471 if (result != ISC_R_SUCCESS) {
17472 dns_zone_log(zone, ISC_LOG_ERROR,
17473 "zone_signwithkey failed: %s",
17474 dns_result_totext(result));
17475 }
17476 }
17477 }
17478
17479
17480
17481
17482
17483 zone->keyopts &= ~DNS_ZONEKEY_FULLSIGN;
17484
17485
17486
17487
17488
17489 for (tuple = ISC_LIST_HEAD(zonediff.diff->tuples);
17490 tuple != NULL;
17491 tuple = ISC_LIST_NEXT(tuple, link)) {
17492 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
17493 dns_rdata_t rdata = DNS_RDATA_INIT;
17494 dns_rdata_nsec3param_t nsec3param;
17495
17496 if (tuple->rdata.type != zone->privatetype ||
17497 tuple->op != DNS_DIFFOP_ADD)
17498 continue;
17499
17500 if (!dns_nsec3param_fromprivate(&tuple->rdata, &rdata,
17501 buf, sizeof(buf)))
17502 continue;
17503 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
17504 RUNTIME_CHECK(result == ISC_R_SUCCESS);
17505 if (nsec3param.flags == 0)
17506 continue;
17507
17508 result = zone_addnsec3chain(zone, &nsec3param);
17509 if (result != ISC_R_SUCCESS) {
17510 dns_zone_log(zone, ISC_LOG_ERROR,
17511 "zone_addnsec3chain failed: %s",
17512 dns_result_totext(result));
17513 }
17514 }
17515
17516
17517
17518
17519
17520 if (fullsign || newalg)
17521 resume_addnsec3chain(zone);
17522
17523
17524
17525
17526 set_resigntime(zone);
17527 UNLOCK_ZONE(zone);
17528 }
17529
17530 isc_time_settoepoch(&zone->refreshkeytime);
17531
17532
17533
17534
17535
17536
17537 if (DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN)) {
17538 isc_time_t timethen;
17539 isc_stdtime_t then;
17540
17541 LOCK_ZONE(zone);
17542 DNS_ZONE_TIME_ADD(&timenow, zone->refreshkeyinterval,
17543 &timethen);
17544 zone->refreshkeytime = timethen;
17545 UNLOCK_ZONE(zone);
17546
17547 for (key = ISC_LIST_HEAD(dnskeys);
17548 key != NULL;
17549 key = ISC_LIST_NEXT(key, link)) {
17550 then = now;
17551 result = next_keyevent(key->key, &then);
17552 if (result != ISC_R_SUCCESS)
17553 continue;
17554
17555 DNS_ZONE_TIME_ADD(&timenow, then - now, &timethen);
17556 LOCK_ZONE(zone);
17557 if (isc_time_compare(&timethen,
17558 &zone->refreshkeytime) < 0) {
17559 zone->refreshkeytime = timethen;
17560 }
17561 UNLOCK_ZONE(zone);
17562 }
17563
17564 zone_settimer(zone, &timenow);
17565
17566 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
17567 dns_zone_log(zone, ISC_LOG_INFO, "next key event: %s", timebuf);
17568 }
17569
17570 done:
17571 dns_diff_clear(&diff);
17572 dns_diff_clear(&_sig_diff);
17573
17574 clear_keylist(&dnskeys, mctx);
17575 clear_keylist(&keys, mctx);
17576 clear_keylist(&rmkeys, mctx);
17577
17578 if (ver != NULL)
17579 dns_db_closeversion(db, &ver, ISC_FALSE);
17580 if (dns_rdataset_isassociated(&keyset))
17581 dns_rdataset_disassociate(&keyset);
17582 if (dns_rdataset_isassociated(&keysigs))
17583 dns_rdataset_disassociate(&keysigs);
17584 if (dns_rdataset_isassociated(&soasigs))
17585 dns_rdataset_disassociate(&soasigs);
17586 if (node != NULL)
17587 dns_db_detachnode(db, &node);
17588 if (db != NULL)
17589 dns_db_detach(&db);
17590
17591 INSIST(ver == NULL);
17592 return;
17593
17594 failure:
17595
17596
17597
17598
17599 isc_interval_set(&ival, ISC_MIN(zone->refreshkeyinterval, 600), 0);
17600 isc_time_nowplusinterval(&zone->refreshkeytime, &ival);
17601 goto done;
17602 }
17603
17604 void
17605 dns_zone_rekey(dns_zone_t *zone, isc_boolean_t fullsign) {
17606 isc_time_t now;
17607
17608 if (zone->type == dns_zone_master && zone->task != NULL) {
17609 LOCK_ZONE(zone);
17610
17611 if (fullsign)
17612 zone->keyopts |= DNS_ZONEKEY_FULLSIGN;
17613
17614 TIME_NOW(&now);
17615 zone->refreshkeytime = now;
17616 zone_settimer(zone, &now);
17617
17618 UNLOCK_ZONE(zone);
17619 }
17620 }
17621
17622 isc_result_t
17623 dns_zone_nscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
17624 unsigned int *errors)
17625 {
17626 isc_result_t result;
17627 dns_dbnode_t *node = NULL;
17628
17629 REQUIRE(DNS_ZONE_VALID(zone));
17630 REQUIRE(errors != NULL);
17631
17632 result = dns_db_getoriginnode(db, &node);
17633 if (result != ISC_R_SUCCESS)
17634 return (result);
17635 result = zone_count_ns_rr(zone, db, node, version, NULL, errors,
17636 ISC_FALSE);
17637 dns_db_detachnode(db, &node);
17638 return (result);
17639 }
17640
17641 void
17642 dns_zone_setautomatic(dns_zone_t *zone, isc_boolean_t automatic) {
17643 REQUIRE(DNS_ZONE_VALID(zone));
17644
17645 LOCK_ZONE(zone);
17646 zone->automatic = automatic;
17647 UNLOCK_ZONE(zone);
17648 }
17649
17650 isc_boolean_t
17651 dns_zone_getautomatic(dns_zone_t *zone) {
17652 REQUIRE(DNS_ZONE_VALID(zone));
17653 return (zone->automatic);
17654 }
17655
17656 void
17657 dns_zone_setadded(dns_zone_t *zone, isc_boolean_t added) {
17658 REQUIRE(DNS_ZONE_VALID(zone));
17659
17660 LOCK_ZONE(zone);
17661 zone->added = added;
17662 UNLOCK_ZONE(zone);
17663 }
17664
17665 isc_boolean_t
17666 dns_zone_getadded(dns_zone_t *zone) {
17667 REQUIRE(DNS_ZONE_VALID(zone));
17668 return (zone->added);
17669 }
17670
17671 isc_result_t
17672 dns_zone_dlzpostload(dns_zone_t *zone, dns_db_t *db)
17673 {
17674 isc_time_t loadtime;
17675 isc_result_t result;
17676 dns_zone_t *secure = NULL;
17677
17678 TIME_NOW(&loadtime);
17679
17680
17681
17682
17683 again:
17684 LOCK_ZONE(zone);
17685 INSIST(zone != zone->raw);
17686 if (inline_secure(zone))
17687 LOCK_ZONE(zone->raw);
17688 else if (inline_raw(zone)) {
17689 secure = zone->secure;
17690 TRYLOCK_ZONE(result, secure);
17691 if (result != ISC_R_SUCCESS) {
17692 UNLOCK_ZONE(zone);
17693 secure = NULL;
17694 #if ISC_PLATFORM_USETHREADS
17695 isc_thread_yield();
17696 #endif
17697 goto again;
17698 }
17699 }
17700 result = zone_postload(zone, db, loadtime, ISC_R_SUCCESS);
17701 if (inline_secure(zone))
17702 UNLOCK_ZONE(zone->raw);
17703 else if (secure != NULL)
17704 UNLOCK_ZONE(secure);
17705 UNLOCK_ZONE(zone);
17706 return result;
17707 }
17708
17709 isc_result_t
17710 dns_zone_setrefreshkeyinterval(dns_zone_t *zone, isc_uint32_t interval) {
17711 REQUIRE(DNS_ZONE_VALID(zone));
17712 if (interval == 0)
17713 return (ISC_R_RANGE);
17714
17715 if (interval > (24 * 60))
17716 interval = (24 * 60);
17717
17718 zone->refreshkeyinterval = interval * 60;
17719 return (ISC_R_SUCCESS);
17720 }
17721
17722 void
17723 dns_zone_setrequestixfr(dns_zone_t *zone, isc_boolean_t flag) {
17724 REQUIRE(DNS_ZONE_VALID(zone));
17725 zone->requestixfr = flag;
17726 }
17727
17728 isc_boolean_t
17729 dns_zone_getrequestixfr(dns_zone_t *zone) {
17730 REQUIRE(DNS_ZONE_VALID(zone));
17731 return (zone->requestixfr);
17732 }
17733
17734 void
17735 dns_zone_setrequestexpire(dns_zone_t *zone, isc_boolean_t flag) {
17736 REQUIRE(DNS_ZONE_VALID(zone));
17737 zone->requestexpire = flag;
17738 }
17739
17740 isc_boolean_t
17741 dns_zone_getrequestexpire(dns_zone_t *zone) {
17742 REQUIRE(DNS_ZONE_VALID(zone));
17743 return (zone->requestexpire);
17744 }
17745
17746 void
17747 dns_zone_setserialupdatemethod(dns_zone_t *zone, dns_updatemethod_t method) {
17748 REQUIRE(DNS_ZONE_VALID(zone));
17749 zone->updatemethod = method;
17750 }
17751
17752 dns_updatemethod_t
17753 dns_zone_getserialupdatemethod(dns_zone_t *zone) {
17754 REQUIRE(DNS_ZONE_VALID(zone));
17755 return(zone->updatemethod);
17756 }
17757
17758
17759
17760
17761 isc_result_t
17762 dns_zone_link(dns_zone_t *zone, dns_zone_t *raw) {
17763 isc_result_t result;
17764 dns_zonemgr_t *zmgr;
17765
17766 REQUIRE(DNS_ZONE_VALID(zone));
17767 REQUIRE(zone->zmgr != NULL);
17768 REQUIRE(zone->task != NULL);
17769 REQUIRE(zone->loadtask != NULL);
17770 REQUIRE(zone->raw == NULL);
17771
17772 REQUIRE(DNS_ZONE_VALID(raw));
17773 REQUIRE(raw->zmgr == NULL);
17774 REQUIRE(raw->task == NULL);
17775 REQUIRE(raw->loadtask == NULL);
17776 REQUIRE(raw->secure == NULL);
17777
17778 REQUIRE(zone != raw);
17779
17780
17781
17782
17783 zmgr = zone->zmgr;
17784 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
17785 LOCK_ZONE(zone);
17786 LOCK_ZONE(raw);
17787
17788 result = isc_timer_create(zmgr->timermgr, isc_timertype_inactive,
17789 NULL, NULL, zone->task, zone_timer, raw,
17790 &raw->timer);
17791 if (result != ISC_R_SUCCESS)
17792 goto unlock;
17793
17794
17795
17796
17797 raw->irefs++;
17798 INSIST(raw->irefs != 0);
17799
17800
17801
17802 isc_refcount_increment(&raw->erefs, NULL);
17803 zone->raw = raw;
17804
17805
17806 zone_iattach(zone, &raw->secure);
17807
17808 isc_task_attach(zone->task, &raw->task);
17809 isc_task_attach(zone->loadtask, &raw->loadtask);
17810
17811 ISC_LIST_APPEND(zmgr->zones, raw, link);
17812 raw->zmgr = zmgr;
17813 zmgr->refs++;
17814
17815 unlock:
17816 UNLOCK_ZONE(raw);
17817 UNLOCK_ZONE(zone);
17818 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
17819 return (result);
17820 }
17821
17822 void
17823 dns_zone_getraw(dns_zone_t *zone, dns_zone_t **raw) {
17824 REQUIRE(DNS_ZONE_VALID(zone));
17825 REQUIRE(raw != NULL && *raw == NULL);
17826
17827 LOCK(&zone->lock);
17828 INSIST(zone != zone->raw);
17829 if (zone->raw != NULL)
17830 dns_zone_attach(zone->raw, raw);
17831 UNLOCK(&zone->lock);
17832 }
17833
17834 struct keydone {
17835 isc_event_t event;
17836 isc_boolean_t all;
17837 unsigned char data[5];
17838 };
17839
17840 #define PENDINGFLAGS (DNS_NSEC3FLAG_CREATE|DNS_NSEC3FLAG_INITIAL)
17841
17842 static void
17843 keydone(isc_task_t *task, isc_event_t *event) {
17844 const char *me = "keydone";
17845 isc_boolean_t commit = ISC_FALSE;
17846 isc_result_t result;
17847 dns_rdata_t rdata = DNS_RDATA_INIT;
17848 dns_dbversion_t *oldver = NULL, *newver = NULL;
17849 dns_zone_t *zone;
17850 dns_db_t *db = NULL;
17851 dns_dbnode_t *node = NULL;
17852 dns_rdataset_t rdataset;
17853 dns_diff_t diff;
17854 struct keydone *kd = (struct keydone *)event;
17855 dns_update_log_t log = { update_log_cb, NULL };
17856 isc_boolean_t clear_pending = ISC_FALSE;
17857
17858 UNUSED(task);
17859
17860 zone = event->ev_arg;
17861 INSIST(DNS_ZONE_VALID(zone));
17862
17863 ENTER;
17864
17865 dns_rdataset_init(&rdataset);
17866 dns_diff_init(zone->mctx, &diff);
17867
17868 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
17869 if (zone->db != NULL)
17870 dns_db_attach(zone->db, &db);
17871 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
17872 if (db == NULL)
17873 goto failure;
17874
17875 dns_db_currentversion(db, &oldver);
17876 result = dns_db_newversion(db, &newver);
17877 if (result != ISC_R_SUCCESS) {
17878 dns_zone_log(zone, ISC_LOG_ERROR,
17879 "keydone:dns_db_newversion -> %s",
17880 dns_result_totext(result));
17881 goto failure;
17882 }
17883
17884 result = dns_db_getoriginnode(db, &node);
17885 if (result != ISC_R_SUCCESS)
17886 goto failure;
17887
17888 result = dns_db_findrdataset(db, node, newver, zone->privatetype,
17889 dns_rdatatype_none, 0, &rdataset, NULL);
17890 if (result == ISC_R_NOTFOUND) {
17891 INSIST(!dns_rdataset_isassociated(&rdataset));
17892 goto failure;
17893 }
17894 if (result != ISC_R_SUCCESS) {
17895 INSIST(!dns_rdataset_isassociated(&rdataset));
17896 goto failure;
17897 }
17898
17899 for (result = dns_rdataset_first(&rdataset);
17900 result == ISC_R_SUCCESS;
17901 result = dns_rdataset_next(&rdataset)) {
17902 isc_boolean_t found = ISC_FALSE;
17903
17904 dns_rdataset_current(&rdataset, &rdata);
17905
17906 if (kd->all) {
17907 if (rdata.length == 5 && rdata.data[0] != 0 &&
17908 rdata.data[3] == 0 && rdata.data[4] == 1)
17909 found = ISC_TRUE;
17910 else if (rdata.data[0] == 0 &&
17911 (rdata.data[2] & PENDINGFLAGS) != 0) {
17912 found = ISC_TRUE;
17913 clear_pending = ISC_TRUE;
17914 }
17915 } else if (rdata.length == 5 &&
17916 memcmp(rdata.data, kd->data, 5) == 0)
17917 found = ISC_TRUE;
17918
17919 if (found)
17920 CHECK(update_one_rr(db, newver, &diff, DNS_DIFFOP_DEL,
17921 &zone->origin, rdataset.ttl,
17922 &rdata));
17923 dns_rdata_reset(&rdata);
17924 }
17925
17926 if (!ISC_LIST_EMPTY(diff.tuples)) {
17927
17928 CHECK(update_soa_serial(db, newver, &diff, zone->mctx,
17929 zone->updatemethod));
17930
17931 result = dns_update_signatures(&log, zone, db,
17932 oldver, newver, &diff,
17933 zone->sigvalidityinterval);
17934 if (!clear_pending)
17935 CHECK(result);
17936
17937 CHECK(zone_journal(zone, &diff, NULL, "keydone"));
17938 commit = ISC_TRUE;
17939
17940 LOCK_ZONE(zone);
17941 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
17942 zone_needdump(zone, 30);
17943 UNLOCK_ZONE(zone);
17944 }
17945
17946 failure:
17947 if (dns_rdataset_isassociated(&rdataset))
17948 dns_rdataset_disassociate(&rdataset);
17949 if (db != NULL) {
17950 if (node != NULL)
17951 dns_db_detachnode(db, &node);
17952 if (oldver != NULL)
17953 dns_db_closeversion(db, &oldver, ISC_FALSE);
17954 if (newver != NULL)
17955 dns_db_closeversion(db, &newver, commit);
17956 dns_db_detach(&db);
17957 }
17958 dns_diff_clear(&diff);
17959 isc_event_free(&event);
17960 dns_zone_idetach(&zone);
17961
17962 INSIST(oldver == NULL);
17963 INSIST(newver == NULL);
17964 }
17965
17966 isc_result_t
17967 dns_zone_keydone(dns_zone_t *zone, const char *keystr) {
17968 isc_result_t result = ISC_R_SUCCESS;
17969 isc_event_t *e;
17970 isc_buffer_t b;
17971 dns_zone_t *dummy = NULL;
17972 struct keydone *kd;
17973
17974 REQUIRE(DNS_ZONE_VALID(zone));
17975
17976 LOCK_ZONE(zone);
17977
17978 e = isc_event_allocate(zone->mctx, zone, DNS_EVENT_KEYDONE, keydone,
17979 zone, sizeof(struct keydone));
17980 if (e == NULL) {
17981 result = ISC_R_NOMEMORY;
17982 goto failure;
17983 }
17984
17985 kd = (struct keydone *) e;
17986 if (strcasecmp(keystr, "all") == 0)
17987 kd->all = ISC_TRUE;
17988 else {
17989 isc_textregion_t r;
17990 char *algstr;
17991 dns_keytag_t keyid;
17992 dns_secalg_t alg;
17993 size_t n;
17994
17995 kd->all = ISC_FALSE;
17996
17997 n = sscanf(keystr, "%hd/", &keyid);
17998 if (n == 0U)
17999 CHECK(ISC_R_FAILURE);
18000
18001 algstr = strchr(keystr, '/');
18002 if (algstr != NULL)
18003 algstr++;
18004 else
18005 CHECK(ISC_R_FAILURE);
18006
18007 n = sscanf(algstr, "%hhd", &alg);
18008 if (n == 0U) {
18009 DE_CONST(algstr, r.base);
18010 r.length = strlen(algstr);
18011 CHECK(dns_secalg_fromtext(&alg, &r));
18012 }
18013
18014
18015 isc_buffer_init(&b, kd->data, sizeof(kd->data));
18016 isc_buffer_putuint8(&b, alg);
18017 isc_buffer_putuint8(&b, (keyid & 0xff00) >> 8);
18018 isc_buffer_putuint8(&b, (keyid & 0xff));
18019 isc_buffer_putuint8(&b, 0);
18020 isc_buffer_putuint8(&b, 1);
18021 }
18022
18023 zone_iattach(zone, &dummy);
18024 isc_task_send(zone->task, &e);
18025
18026 failure:
18027 if (e != NULL)
18028 isc_event_free(&e);
18029 UNLOCK_ZONE(zone);
18030 return (result);
18031 }
18032
18033 static void
18034 setnsec3param(isc_task_t *task, isc_event_t *event) {
18035 const char *me = "setnsec3param";
18036 isc_boolean_t commit = ISC_FALSE;
18037 isc_result_t result;
18038 dns_dbversion_t *oldver = NULL, *newver = NULL;
18039 dns_zone_t *zone;
18040 dns_db_t *db = NULL;
18041 dns_dbnode_t *node = NULL;
18042 dns_rdataset_t prdataset, nrdataset;
18043 dns_diff_t diff;
18044 struct np3event *npe = (struct np3event *)event;
18045 nsec3param_t *np;
18046 dns_update_log_t log = { update_log_cb, NULL };
18047 dns_rdata_t rdata;
18048 isc_boolean_t nseconly;
18049 isc_boolean_t exists = ISC_FALSE;
18050
18051 UNUSED(task);
18052
18053 zone = event->ev_arg;
18054 INSIST(DNS_ZONE_VALID(zone));
18055
18056 ENTER;
18057
18058 np = &npe->params;
18059
18060 dns_rdataset_init(&prdataset);
18061 dns_rdataset_init(&nrdataset);
18062 dns_diff_init(zone->mctx, &diff);
18063
18064 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
18065 if (zone->db != NULL)
18066 dns_db_attach(zone->db, &db);
18067 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
18068 if (db == NULL)
18069 goto failure;
18070
18071 dns_db_currentversion(db, &oldver);
18072 result = dns_db_newversion(db, &newver);
18073 if (result != ISC_R_SUCCESS) {
18074 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
18075 dns_zone_log(zone, ISC_LOG_ERROR,
18076 "setnsec3param:dns_db_newversion -> %s",
18077 dns_result_totext(result));
18078 goto failure;
18079 }
18080
18081 CHECK(dns_db_getoriginnode(db, &node));
18082
18083
18084
18085
18086 result = dns_db_findrdataset(db, node, newver, zone->privatetype,
18087 dns_rdatatype_none, 0, &prdataset, NULL);
18088 if (result == ISC_R_SUCCESS) {
18089 for (result = dns_rdataset_first(&prdataset);
18090 result == ISC_R_SUCCESS;
18091 result = dns_rdataset_next(&prdataset)) {
18092 dns_rdata_init(&rdata);
18093 dns_rdataset_current(&prdataset, &rdata);
18094
18095 if (np->length == rdata.length &&
18096 memcmp(rdata.data, np->data, np->length) == 0) {
18097 exists = ISC_TRUE;
18098 break;
18099 }
18100 }
18101 } else if (result != ISC_R_NOTFOUND) {
18102 INSIST(!dns_rdataset_isassociated(&prdataset));
18103 goto failure;
18104 }
18105
18106
18107
18108
18109 result = dns_db_findrdataset(db, node, newver,
18110 dns_rdatatype_nsec3param,
18111 dns_rdatatype_none, 0, &nrdataset, NULL);
18112 if (result == ISC_R_SUCCESS) {
18113 for (result = dns_rdataset_first(&nrdataset);
18114 result == ISC_R_SUCCESS;
18115 result = dns_rdataset_next(&nrdataset)) {
18116 dns_rdata_init(&rdata);
18117 dns_rdataset_current(&nrdataset, &rdata);
18118
18119 if (np->length == (rdata.length + 1) &&
18120 memcmp(rdata.data, np->data + 1,
18121 np->length - 1) == 0)
18122 {
18123 exists = ISC_TRUE;
18124 break;
18125 }
18126 }
18127 } else if (result != ISC_R_NOTFOUND) {
18128 INSIST(!dns_rdataset_isassociated(&nrdataset));
18129 goto failure;
18130 }
18131
18132
18133
18134
18135
18136 if (!exists && np->replace && (np->length != 0 || np->nsec))
18137 CHECK(dns_nsec3param_deletechains(db, newver, zone,
18138 !np->nsec, &diff));
18139
18140 if (!exists && np->length != 0) {
18141
18142
18143
18144
18145
18146
18147
18148
18149 dns_rdata_init(&rdata);
18150
18151 np->data[2] |= DNS_NSEC3FLAG_CREATE;
18152 result = dns_nsec_nseconly(db, newver, &nseconly);
18153 if (result == ISC_R_NOTFOUND || nseconly)
18154 np->data[2] |= DNS_NSEC3FLAG_INITIAL;
18155
18156 rdata.length = np->length;
18157 rdata.data = np->data;
18158 rdata.type = zone->privatetype;
18159 rdata.rdclass = zone->rdclass;
18160 CHECK(update_one_rr(db, newver, &diff, DNS_DIFFOP_ADD,
18161 &zone->origin, 0, &rdata));
18162 }
18163
18164 if (!ISC_LIST_EMPTY(diff.tuples)) {
18165
18166 CHECK(update_soa_serial(db, newver, &diff, zone->mctx,
18167 zone->updatemethod));
18168 result = dns_update_signatures(&log, zone, db,
18169 oldver, newver, &diff,
18170 zone->sigvalidityinterval);
18171 if (result != ISC_R_NOTFOUND)
18172 CHECK(result);
18173 CHECK(zone_journal(zone, &diff, NULL, "setnsec3param"));
18174 commit = ISC_TRUE;
18175
18176 LOCK_ZONE(zone);
18177 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
18178 zone_needdump(zone, 30);
18179 UNLOCK_ZONE(zone);
18180 }
18181
18182 failure:
18183 if (dns_rdataset_isassociated(&prdataset))
18184 dns_rdataset_disassociate(&prdataset);
18185 if (dns_rdataset_isassociated(&nrdataset))
18186 dns_rdataset_disassociate(&nrdataset);
18187 if (node != NULL)
18188 dns_db_detachnode(db, &node);
18189 if (oldver != NULL)
18190 dns_db_closeversion(db, &oldver, ISC_FALSE);
18191 if (newver != NULL)
18192 dns_db_closeversion(db, &newver, commit);
18193 if (db != NULL)
18194 dns_db_detach(&db);
18195 if (commit)
18196 resume_addnsec3chain(zone);
18197 dns_diff_clear(&diff);
18198 isc_event_free(&event);
18199 dns_zone_idetach(&zone);
18200
18201 INSIST(oldver == NULL);
18202 INSIST(newver == NULL);
18203 }
18204
18205 isc_result_t
18206 dns_zone_setnsec3param(dns_zone_t *zone, isc_uint8_t hash, isc_uint8_t flags,
18207 isc_uint16_t iter, isc_uint8_t saltlen,
18208 unsigned char *salt, isc_boolean_t replace)
18209 {
18210 isc_result_t result = ISC_R_SUCCESS;
18211 dns_rdata_nsec3param_t param;
18212 dns_rdata_t nrdata = DNS_RDATA_INIT;
18213 dns_rdata_t prdata = DNS_RDATA_INIT;
18214 unsigned char nbuf[DNS_NSEC3PARAM_BUFFERSIZE];
18215 struct np3event *npe;
18216 nsec3param_t *np;
18217 dns_zone_t *dummy = NULL;
18218 isc_buffer_t b;
18219 isc_event_t *e;
18220
18221 REQUIRE(DNS_ZONE_VALID(zone));
18222 REQUIRE(salt != NULL);
18223
18224 LOCK_ZONE(zone);
18225
18226 e = isc_event_allocate(zone->mctx, zone, DNS_EVENT_SETNSEC3PARAM,
18227 setnsec3param, zone, sizeof(struct np3event));
18228 if (e == NULL) {
18229 result = ISC_R_NOMEMORY;
18230 goto failure;
18231 }
18232
18233 npe = (struct np3event *) e;
18234 np = &npe->params;
18235
18236 np->replace = replace;
18237 if (hash == 0) {
18238 np->length = 0;
18239 np->nsec = ISC_TRUE;
18240 } else {
18241 param.common.rdclass = zone->rdclass;
18242 param.common.rdtype = dns_rdatatype_nsec3param;
18243 ISC_LINK_INIT(¶m.common, link);
18244 param.mctx = NULL;
18245 param.hash = hash;
18246 param.flags = flags;
18247 param.iterations = iter;
18248 param.salt_length = saltlen;
18249 param.salt = salt;
18250 isc_buffer_init(&b, nbuf, sizeof(nbuf));
18251 CHECK(dns_rdata_fromstruct(&nrdata, zone->rdclass,
18252 dns_rdatatype_nsec3param,
18253 ¶m, &b));
18254 dns_nsec3param_toprivate(&nrdata, &prdata, zone->privatetype,
18255 np->data, sizeof(np->data));
18256 np->length = prdata.length;
18257 }
18258
18259 zone_iattach(zone, &dummy);
18260 isc_task_send(zone->task, &e);
18261
18262 failure:
18263 if (e != NULL)
18264 isc_event_free(&e);
18265 UNLOCK_ZONE(zone);
18266 return (result);
18267 }
18268
18269 isc_result_t
18270 dns_zone_getloadtime(dns_zone_t *zone, isc_time_t *loadtime) {
18271 REQUIRE(DNS_ZONE_VALID(zone));
18272 REQUIRE(loadtime != NULL);
18273
18274 LOCK_ZONE(zone);
18275 *loadtime = zone->loadtime;
18276 UNLOCK_ZONE(zone);
18277 return (ISC_R_SUCCESS);
18278 }
18279
18280 isc_result_t
18281 dns_zone_getexpiretime(dns_zone_t *zone, isc_time_t *expiretime) {
18282 REQUIRE(DNS_ZONE_VALID(zone));
18283 REQUIRE(expiretime != NULL);
18284
18285 LOCK_ZONE(zone);
18286 *expiretime = zone->expiretime;
18287 UNLOCK_ZONE(zone);
18288 return (ISC_R_SUCCESS);
18289 }
18290
18291 isc_result_t
18292 dns_zone_getrefreshtime(dns_zone_t *zone, isc_time_t *refreshtime) {
18293 REQUIRE(DNS_ZONE_VALID(zone));
18294 REQUIRE(refreshtime != NULL);
18295
18296 LOCK_ZONE(zone);
18297 *refreshtime = zone->refreshtime;
18298 UNLOCK_ZONE(zone);
18299 return (ISC_R_SUCCESS);
18300 }
18301
18302 isc_result_t
18303 dns_zone_getrefreshkeytime(dns_zone_t *zone, isc_time_t *refreshkeytime) {
18304 REQUIRE(DNS_ZONE_VALID(zone));
18305 REQUIRE(refreshkeytime != NULL);
18306
18307 LOCK_ZONE(zone);
18308 *refreshkeytime = zone->refreshkeytime;
18309 UNLOCK_ZONE(zone);
18310 return (ISC_R_SUCCESS);
18311 }
18312
18313 unsigned int
18314 dns_zone_getincludes(dns_zone_t *zone, char ***includesp) {
18315 dns_include_t *include;
18316 char **array = NULL;
18317 unsigned int n = 0;
18318
18319 REQUIRE(DNS_ZONE_VALID(zone));
18320 REQUIRE(includesp != NULL && *includesp == NULL);
18321
18322 LOCK_ZONE(zone);
18323 if (zone->nincludes == 0)
18324 goto done;
18325
18326 array = isc_mem_allocate(zone->mctx, sizeof(char *) * zone->nincludes);
18327 if (array == NULL)
18328 goto done;
18329 for (include = ISC_LIST_HEAD(zone->includes);
18330 include != NULL;
18331 include = ISC_LIST_NEXT(include, link)) {
18332 INSIST(n < zone->nincludes);
18333 array[n++] = isc_mem_strdup(zone->mctx, include->name);
18334 }
18335 INSIST(n == zone->nincludes);
18336 *includesp = array;
18337
18338 done:
18339 UNLOCK_ZONE(zone);
18340 return (n);
18341 }
18342
18343 void
18344 dns_zone_setstatlevel(dns_zone_t *zone, dns_zonestat_level_t level) {
18345 REQUIRE(DNS_ZONE_VALID(zone));
18346
18347 zone->statlevel = level;
18348 }
18349
18350 dns_zonestat_level_t
18351 dns_zone_getstatlevel(dns_zone_t *zone) {
18352 REQUIRE(DNS_ZONE_VALID(zone));
18353
18354 return (zone->statlevel);
18355 }
18356
18357 static void
18358 setserial(isc_task_t *task, isc_event_t *event) {
18359 isc_uint32_t oldserial, desired;
18360 const char *me = "setserial";
18361 isc_boolean_t commit = ISC_FALSE;
18362 isc_result_t result;
18363 dns_dbversion_t *oldver = NULL, *newver = NULL;
18364 dns_zone_t *zone;
18365 dns_db_t *db = NULL;
18366 dns_diff_t diff;
18367 struct ssevent *sse = (struct ssevent *)event;
18368 dns_update_log_t log = { update_log_cb, NULL };
18369 dns_difftuple_t *oldtuple = NULL, *newtuple = NULL;
18370
18371 UNUSED(task);
18372
18373 zone = event->ev_arg;
18374 INSIST(DNS_ZONE_VALID(zone));
18375
18376 ENTER;
18377
18378 if (zone->update_disabled)
18379 goto failure;
18380
18381 desired = sse->serial;
18382
18383 dns_diff_init(zone->mctx, &diff);
18384
18385 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
18386 if (zone->db != NULL)
18387 dns_db_attach(zone->db, &db);
18388 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
18389 if (db == NULL)
18390 goto failure;
18391
18392 dns_db_currentversion(db, &oldver);
18393 result = dns_db_newversion(db, &newver);
18394 if (result != ISC_R_SUCCESS) {
18395 dns_zone_log(zone, ISC_LOG_ERROR,
18396 "setserial:dns_db_newversion -> %s",
18397 dns_result_totext(result));
18398 goto failure;
18399 }
18400
18401 CHECK(dns_db_createsoatuple(db, oldver, diff.mctx,
18402 DNS_DIFFOP_DEL, &oldtuple));
18403 CHECK(dns_difftuple_copy(oldtuple, &newtuple));
18404 newtuple->op = DNS_DIFFOP_ADD;
18405
18406 oldserial = dns_soa_getserial(&oldtuple->rdata);
18407 if (desired == 0U)
18408 desired = 1;
18409 if (!isc_serial_gt(desired, oldserial)) {
18410 if (desired != oldserial)
18411 dns_zone_log(zone, ISC_LOG_INFO,
18412 "setserial: desired serial (%u) "
18413 "out of range (%u-%u)", desired,
18414 oldserial + 1, (oldserial + 0x7fffffff));
18415 goto failure;
18416 }
18417
18418 dns_soa_setserial(desired, &newtuple->rdata);
18419 CHECK(do_one_tuple(&oldtuple, db, newver, &diff));
18420 CHECK(do_one_tuple(&newtuple, db, newver, &diff));
18421 result = dns_update_signatures(&log, zone, db,
18422 oldver, newver, &diff,
18423 zone->sigvalidityinterval);
18424 if (result != ISC_R_NOTFOUND)
18425 CHECK(result);
18426
18427
18428 CHECK(zone_journal(zone, &diff, NULL, "setserial"));
18429 commit = ISC_TRUE;
18430
18431 LOCK_ZONE(zone);
18432 zone_needdump(zone, 30);
18433 UNLOCK_ZONE(zone);
18434
18435 failure:
18436 if (oldtuple != NULL)
18437 dns_difftuple_free(&oldtuple);
18438 if (newtuple != NULL)
18439 dns_difftuple_free(&newtuple);
18440 if (oldver != NULL)
18441 dns_db_closeversion(db, &oldver, ISC_FALSE);
18442 if (newver != NULL)
18443 dns_db_closeversion(db, &newver, commit);
18444 if (db != NULL)
18445 dns_db_detach(&db);
18446 dns_diff_clear(&diff);
18447 isc_event_free(&event);
18448 dns_zone_idetach(&zone);
18449
18450 INSIST(oldver == NULL);
18451 INSIST(newver == NULL);
18452 }
18453
18454 isc_result_t
18455 dns_zone_setserial(dns_zone_t *zone, isc_uint32_t serial) {
18456 isc_result_t result = ISC_R_SUCCESS;
18457 dns_zone_t *dummy = NULL;
18458 isc_event_t *e = NULL;
18459 struct ssevent *sse;
18460
18461 REQUIRE(DNS_ZONE_VALID(zone));
18462
18463 LOCK_ZONE(zone);
18464
18465 if (!inline_secure(zone)) {
18466 if (!dns_zone_isdynamic(zone, ISC_TRUE)) {
18467 result = DNS_R_NOTDYNAMIC;
18468 goto failure;
18469 }
18470 }
18471
18472 if (zone->update_disabled) {
18473 result = DNS_R_FROZEN;
18474 goto failure;
18475 }
18476
18477 e = isc_event_allocate(zone->mctx, zone, DNS_EVENT_SETSERIAL,
18478 setserial, zone, sizeof(struct ssevent));
18479 if (e == NULL) {
18480 result = ISC_R_NOMEMORY;
18481 goto failure;
18482 }
18483
18484 sse = (struct ssevent *)e;
18485 sse->serial = serial;
18486
18487 zone_iattach(zone, &dummy);
18488 isc_task_send(zone->task, &e);
18489
18490 failure:
18491 if (e != NULL)
18492 isc_event_free(&e);
18493 UNLOCK_ZONE(zone);
18494 return (result);
18495 }