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