00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <config.h>
00021
00022 #include <stdlib.h>
00023 #include <unistd.h>
00024 #include <limits.h>
00025 #include <ctype.h>
00026 #include <sys/types.h>
00027 #include <sys/stat.h>
00028
00029 #include <isc/app.h>
00030 #include <isc/base64.h>
00031 #include <isc/dir.h>
00032 #include <isc/entropy.h>
00033 #include <isc/file.h>
00034 #include <isc/hash.h>
00035 #include <isc/hex.h>
00036 #include <isc/httpd.h>
00037 #include <isc/lex.h>
00038 #include <isc/parseint.h>
00039 #include <isc/portset.h>
00040 #include <isc/print.h>
00041 #include <isc/random.h>
00042 #include <isc/refcount.h>
00043 #include <isc/resource.h>
00044 #include <isc/sha2.h>
00045 #include <isc/socket.h>
00046 #include <isc/stat.h>
00047 #include <isc/stats.h>
00048 #include <isc/stdio.h>
00049 #include <isc/string.h>
00050 #include <isc/task.h>
00051 #include <isc/timer.h>
00052 #include <isc/util.h>
00053 #include <isc/xml.h>
00054
00055 #ifdef AES_SIT
00056 #include <isc/aes.h>
00057 #else
00058 #include <isc/hmacsha.h>
00059 #endif
00060
00061 #include <isccfg/grammar.h>
00062 #include <isccfg/namedconf.h>
00063
00064 #include <bind9/check.h>
00065
00066 #include <dns/acache.h>
00067 #include <dns/adb.h>
00068 #include <dns/badcache.h>
00069 #include <dns/cache.h>
00070 #include <dns/db.h>
00071 #include <dns/dispatch.h>
00072 #include <dns/dlz.h>
00073 #include <dns/dns64.h>
00074 #include <dns/forward.h>
00075 #include <dns/journal.h>
00076 #include <dns/keytable.h>
00077 #include <dns/keyvalues.h>
00078 #include <dns/lib.h>
00079 #include <dns/master.h>
00080 #include <dns/masterdump.h>
00081 #include <dns/nta.h>
00082 #include <dns/order.h>
00083 #include <dns/peer.h>
00084 #include <dns/portlist.h>
00085 #include <dns/private.h>
00086 #include <dns/rbt.h>
00087 #include <dns/rdataclass.h>
00088 #include <dns/rdatalist.h>
00089 #include <dns/rdataset.h>
00090 #include <dns/rdatastruct.h>
00091 #include <dns/resolver.h>
00092 #include <dns/rootns.h>
00093 #include <dns/rriterator.h>
00094 #include <dns/secalg.h>
00095 #include <dns/soa.h>
00096 #include <dns/stats.h>
00097 #include <dns/tkey.h>
00098 #include <dns/tsig.h>
00099 #include <dns/ttl.h>
00100 #include <dns/view.h>
00101 #include <dns/zone.h>
00102 #include <dns/zt.h>
00103
00104 #include <dst/dst.h>
00105 #include <dst/result.h>
00106
00107 #include <named/client.h>
00108 #include <named/config.h>
00109 #include <named/control.h>
00110 #include <named/geoip.h>
00111 #include <named/interfacemgr.h>
00112 #include <named/log.h>
00113 #include <named/logconf.h>
00114 #include <named/lwresd.h>
00115 #include <named/main.h>
00116 #include <named/os.h>
00117 #include <named/server.h>
00118 #include <named/statschannel.h>
00119 #include <named/tkeyconf.h>
00120 #include <named/tsigconf.h>
00121 #include <named/zoneconf.h>
00122 #ifdef HAVE_LIBSCF
00123 #include <named/ns_smf_globals.h>
00124 #include <stdlib.h>
00125 #endif
00126 #ifdef HAVE_GEOIP
00127 #include <named/geoip.h>
00128 #endif
00129
00130 #ifndef PATH_MAX
00131 #define PATH_MAX 1024
00132 #endif
00133
00134 #ifndef SIZE_MAX
00135 #define SIZE_MAX ((size_t)-1)
00136 #endif
00137
00138 #ifdef TUNE_LARGE
00139 #define RESOLVER_NTASKS 523
00140 #define UDPBUFFERS 32768
00141 #define EXCLBUFFERS 32768
00142 #else
00143 #define RESOLVER_NTASKS 31
00144 #define UDPBUFFERS 1000
00145 #define EXCLBUFFERS 4096
00146 #endif
00147
00148
00149
00150
00151
00152 #define CHECK(op) \
00153 do { result = (op); \
00154 if (result != ISC_R_SUCCESS) goto cleanup; \
00155 } while (0)
00156
00157 #define TCHECK(op) \
00158 do { tresult = (op); \
00159 if (tresult != ISC_R_SUCCESS) { \
00160 isc_buffer_clear(*text); \
00161 goto cleanup; \
00162 } \
00163 } while (0)
00164
00165 #define CHECKM(op, msg) \
00166 do { result = (op); \
00167 if (result != ISC_R_SUCCESS) { \
00168 isc_log_write(ns_g_lctx, \
00169 NS_LOGCATEGORY_GENERAL, \
00170 NS_LOGMODULE_SERVER, \
00171 ISC_LOG_ERROR, \
00172 "%s: %s", msg, \
00173 isc_result_totext(result)); \
00174 goto cleanup; \
00175 } \
00176 } while (0) \
00177
00178 #define CHECKMF(op, msg, file) \
00179 do { result = (op); \
00180 if (result != ISC_R_SUCCESS) { \
00181 isc_log_write(ns_g_lctx, \
00182 NS_LOGCATEGORY_GENERAL, \
00183 NS_LOGMODULE_SERVER, \
00184 ISC_LOG_ERROR, \
00185 "%s '%s': %s", msg, file, \
00186 isc_result_totext(result)); \
00187 goto cleanup; \
00188 } \
00189 } while (0) \
00190
00191 #define CHECKFATAL(op, msg) \
00192 do { result = (op); \
00193 if (result != ISC_R_SUCCESS) \
00194 fatal(msg, result); \
00195 } while (0) \
00196
00197
00198
00199
00200
00201
00202
00203 #define MAX_ADB_SIZE_FOR_CACHESHARE 8388608U
00204
00205 struct ns_dispatch {
00206 isc_sockaddr_t addr;
00207 unsigned int dispatchgen;
00208 dns_dispatch_t *dispatch;
00209 ISC_LINK(struct ns_dispatch) link;
00210 };
00211
00212 struct ns_cache {
00213 dns_cache_t *cache;
00214 dns_view_t *primaryview;
00215 isc_boolean_t needflush;
00216 isc_boolean_t adbsizeadjusted;
00217 ISC_LINK(ns_cache_t) link;
00218 };
00219
00220 struct dumpcontext {
00221 isc_mem_t *mctx;
00222 isc_boolean_t dumpcache;
00223 isc_boolean_t dumpzones;
00224 FILE *fp;
00225 ISC_LIST(struct viewlistentry) viewlist;
00226 struct viewlistentry *view;
00227 struct zonelistentry *zone;
00228 dns_dumpctx_t *mdctx;
00229 dns_db_t *db;
00230 dns_db_t *cache;
00231 isc_task_t *task;
00232 dns_dbversion_t *version;
00233 };
00234
00235 struct viewlistentry {
00236 dns_view_t *view;
00237 ISC_LINK(struct viewlistentry) link;
00238 ISC_LIST(struct zonelistentry) zonelist;
00239 };
00240
00241 struct zonelistentry {
00242 dns_zone_t *zone;
00243 ISC_LINK(struct zonelistentry) link;
00244 };
00245
00246
00247
00248
00249
00250 typedef struct ns_cfgctx {
00251 isc_mem_t * mctx;
00252 cfg_parser_t * conf_parser;
00253 cfg_parser_t * add_parser;
00254 cfg_obj_t * config;
00255 cfg_obj_t * vconfig;
00256 cfg_obj_t * nzconfig;
00257 cfg_aclconfctx_t * actx;
00258 } ns_cfgctx_t;
00259
00260
00261
00262
00263
00264
00265 typedef struct {
00266 ns_server_t *server;
00267 isc_refcount_t refs;
00268 } ns_zoneload_t;
00269
00270
00271
00272
00273 const char *empty_zones[] = {
00274
00275 "10.IN-ADDR.ARPA",
00276 "16.172.IN-ADDR.ARPA",
00277 "17.172.IN-ADDR.ARPA",
00278 "18.172.IN-ADDR.ARPA",
00279 "19.172.IN-ADDR.ARPA",
00280 "20.172.IN-ADDR.ARPA",
00281 "21.172.IN-ADDR.ARPA",
00282 "22.172.IN-ADDR.ARPA",
00283 "23.172.IN-ADDR.ARPA",
00284 "24.172.IN-ADDR.ARPA",
00285 "25.172.IN-ADDR.ARPA",
00286 "26.172.IN-ADDR.ARPA",
00287 "27.172.IN-ADDR.ARPA",
00288 "28.172.IN-ADDR.ARPA",
00289 "29.172.IN-ADDR.ARPA",
00290 "30.172.IN-ADDR.ARPA",
00291 "31.172.IN-ADDR.ARPA",
00292 "168.192.IN-ADDR.ARPA",
00293
00294
00295 "64.100.IN-ADDR.ARPA",
00296 "65.100.IN-ADDR.ARPA",
00297 "66.100.IN-ADDR.ARPA",
00298 "67.100.IN-ADDR.ARPA",
00299 "68.100.IN-ADDR.ARPA",
00300 "69.100.IN-ADDR.ARPA",
00301 "70.100.IN-ADDR.ARPA",
00302 "71.100.IN-ADDR.ARPA",
00303 "72.100.IN-ADDR.ARPA",
00304 "73.100.IN-ADDR.ARPA",
00305 "74.100.IN-ADDR.ARPA",
00306 "75.100.IN-ADDR.ARPA",
00307 "76.100.IN-ADDR.ARPA",
00308 "77.100.IN-ADDR.ARPA",
00309 "78.100.IN-ADDR.ARPA",
00310 "79.100.IN-ADDR.ARPA",
00311 "80.100.IN-ADDR.ARPA",
00312 "81.100.IN-ADDR.ARPA",
00313 "82.100.IN-ADDR.ARPA",
00314 "83.100.IN-ADDR.ARPA",
00315 "84.100.IN-ADDR.ARPA",
00316 "85.100.IN-ADDR.ARPA",
00317 "86.100.IN-ADDR.ARPA",
00318 "87.100.IN-ADDR.ARPA",
00319 "88.100.IN-ADDR.ARPA",
00320 "89.100.IN-ADDR.ARPA",
00321 "90.100.IN-ADDR.ARPA",
00322 "91.100.IN-ADDR.ARPA",
00323 "92.100.IN-ADDR.ARPA",
00324 "93.100.IN-ADDR.ARPA",
00325 "94.100.IN-ADDR.ARPA",
00326 "95.100.IN-ADDR.ARPA",
00327 "96.100.IN-ADDR.ARPA",
00328 "97.100.IN-ADDR.ARPA",
00329 "98.100.IN-ADDR.ARPA",
00330 "99.100.IN-ADDR.ARPA",
00331 "100.100.IN-ADDR.ARPA",
00332 "101.100.IN-ADDR.ARPA",
00333 "102.100.IN-ADDR.ARPA",
00334 "103.100.IN-ADDR.ARPA",
00335 "104.100.IN-ADDR.ARPA",
00336 "105.100.IN-ADDR.ARPA",
00337 "106.100.IN-ADDR.ARPA",
00338 "107.100.IN-ADDR.ARPA",
00339 "108.100.IN-ADDR.ARPA",
00340 "109.100.IN-ADDR.ARPA",
00341 "110.100.IN-ADDR.ARPA",
00342 "111.100.IN-ADDR.ARPA",
00343 "112.100.IN-ADDR.ARPA",
00344 "113.100.IN-ADDR.ARPA",
00345 "114.100.IN-ADDR.ARPA",
00346 "115.100.IN-ADDR.ARPA",
00347 "116.100.IN-ADDR.ARPA",
00348 "117.100.IN-ADDR.ARPA",
00349 "118.100.IN-ADDR.ARPA",
00350 "119.100.IN-ADDR.ARPA",
00351 "120.100.IN-ADDR.ARPA",
00352 "121.100.IN-ADDR.ARPA",
00353 "122.100.IN-ADDR.ARPA",
00354 "123.100.IN-ADDR.ARPA",
00355 "124.100.IN-ADDR.ARPA",
00356 "125.100.IN-ADDR.ARPA",
00357 "126.100.IN-ADDR.ARPA",
00358 "127.100.IN-ADDR.ARPA",
00359
00360
00361 "0.IN-ADDR.ARPA",
00362 "127.IN-ADDR.ARPA",
00363 "254.169.IN-ADDR.ARPA",
00364 "2.0.192.IN-ADDR.ARPA",
00365 "100.51.198.IN-ADDR.ARPA",
00366 "113.0.203.IN-ADDR.ARPA",
00367 "255.255.255.255.IN-ADDR.ARPA",
00368
00369
00370 "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.IP6.ARPA",
00371 "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.IP6.ARPA",
00372
00373 "D.F.IP6.ARPA",
00374 "8.E.F.IP6.ARPA",
00375 "9.E.F.IP6.ARPA",
00376 "A.E.F.IP6.ARPA",
00377 "B.E.F.IP6.ARPA",
00378
00379
00380 "8.B.D.0.1.0.0.2.IP6.ARPA",
00381
00382 NULL
00383 };
00384
00385 ISC_PLATFORM_NORETURN_PRE static void
00386 fatal(const char *msg, isc_result_t result) ISC_PLATFORM_NORETURN_POST;
00387
00388 static void
00389 ns_server_reload(isc_task_t *task, isc_event_t *event);
00390
00391 static isc_result_t
00392 ns_listenelt_fromconfig(const cfg_obj_t *listener, const cfg_obj_t *config,
00393 cfg_aclconfctx_t *actx, isc_mem_t *mctx,
00394 isc_uint16_t family, ns_listenelt_t **target);
00395 static isc_result_t
00396 ns_listenlist_fromconfig(const cfg_obj_t *listenlist, const cfg_obj_t *config,
00397 cfg_aclconfctx_t *actx, isc_mem_t *mctx,
00398 isc_uint16_t family, ns_listenlist_t **target);
00399
00400 static isc_result_t
00401 configure_forward(const cfg_obj_t *config, dns_view_t *view, dns_name_t *origin,
00402 const cfg_obj_t *forwarders, const cfg_obj_t *forwardtype);
00403
00404 static isc_result_t
00405 configure_alternates(const cfg_obj_t *config, dns_view_t *view,
00406 const cfg_obj_t *alternates);
00407
00408 static isc_result_t
00409 configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig,
00410 const cfg_obj_t *vconfig, isc_mem_t *mctx, dns_view_t *view,
00411 dns_viewlist_t *viewlist, cfg_aclconfctx_t *aclconf,
00412 isc_boolean_t added, isc_boolean_t old_rpz_ok,
00413 isc_boolean_t modify);
00414
00415 static isc_result_t
00416 add_keydata_zone(dns_view_t *view, const char *directory, isc_mem_t *mctx);
00417
00418 static void
00419 end_reserved_dispatches(ns_server_t *server, isc_boolean_t all);
00420
00421 static void
00422 newzone_cfgctx_destroy(void **cfgp);
00423
00424 static inline isc_result_t
00425 putstr(isc_buffer_t **b, const char *str);
00426
00427 static isc_result_t
00428 putmem(isc_buffer_t **b, const char *str, size_t len);
00429
00430 static isc_result_t
00431 putuint8(isc_buffer_t **b, isc_uint8_t val);
00432
00433 static inline isc_result_t
00434 putnull(isc_buffer_t **b);
00435
00436 static isc_result_t
00437 add_comment(FILE *fp, const char *viewname);
00438
00439
00440
00441
00442
00443 static isc_result_t
00444 configure_view_acl(const cfg_obj_t *vconfig, const cfg_obj_t *config,
00445 const char *aclname, const char *acltuplename,
00446 cfg_aclconfctx_t *actx, isc_mem_t *mctx, dns_acl_t **aclp)
00447 {
00448 isc_result_t result;
00449 const cfg_obj_t *maps[3];
00450 const cfg_obj_t *aclobj = NULL;
00451 int i = 0;
00452
00453 if (*aclp != NULL)
00454 dns_acl_detach(aclp);
00455 if (vconfig != NULL)
00456 maps[i++] = cfg_tuple_get(vconfig, "options");
00457 if (config != NULL) {
00458 const cfg_obj_t *options = NULL;
00459 (void)cfg_map_get(config, "options", &options);
00460 if (options != NULL)
00461 maps[i++] = options;
00462 }
00463 maps[i] = NULL;
00464
00465 (void)ns_config_get(maps, aclname, &aclobj);
00466 if (aclobj == NULL)
00467
00468
00469
00470 return (ISC_R_SUCCESS);
00471
00472 if (acltuplename != NULL) {
00473
00474
00475
00476
00477
00478 aclobj = cfg_tuple_get(aclobj, acltuplename);
00479 }
00480
00481 result = cfg_acl_fromconfig(aclobj, config, ns_g_lctx,
00482 actx, mctx, 0, aclp);
00483
00484 return (result);
00485 }
00486
00487
00488
00489
00490
00491
00492 static isc_result_t
00493 configure_view_sortlist(const cfg_obj_t *vconfig, const cfg_obj_t *config,
00494 cfg_aclconfctx_t *actx, isc_mem_t *mctx,
00495 dns_acl_t **aclp)
00496 {
00497 isc_result_t result;
00498 const cfg_obj_t *maps[3];
00499 const cfg_obj_t *aclobj = NULL;
00500 int i = 0;
00501
00502 if (*aclp != NULL)
00503 dns_acl_detach(aclp);
00504 if (vconfig != NULL)
00505 maps[i++] = cfg_tuple_get(vconfig, "options");
00506 if (config != NULL) {
00507 const cfg_obj_t *options = NULL;
00508 (void)cfg_map_get(config, "options", &options);
00509 if (options != NULL)
00510 maps[i++] = options;
00511 }
00512 maps[i] = NULL;
00513
00514 (void)ns_config_get(maps, "sortlist", &aclobj);
00515 if (aclobj == NULL)
00516 return (ISC_R_SUCCESS);
00517
00518
00519
00520
00521
00522
00523
00524 result = cfg_acl_fromconfig(aclobj, config, ns_g_lctx,
00525 actx, mctx, 3, aclp);
00526
00527 return (result);
00528 }
00529
00530 static isc_result_t
00531 configure_view_nametable(const cfg_obj_t *vconfig, const cfg_obj_t *config,
00532 const char *confname, const char *conftuplename,
00533 isc_mem_t *mctx, dns_rbt_t **rbtp)
00534 {
00535 isc_result_t result;
00536 const cfg_obj_t *maps[3];
00537 const cfg_obj_t *obj = NULL;
00538 const cfg_listelt_t *element;
00539 int i = 0;
00540 dns_fixedname_t fixed;
00541 dns_name_t *name;
00542 isc_buffer_t b;
00543 const char *str;
00544 const cfg_obj_t *nameobj;
00545
00546 if (*rbtp != NULL)
00547 dns_rbt_destroy(rbtp);
00548 if (vconfig != NULL)
00549 maps[i++] = cfg_tuple_get(vconfig, "options");
00550 if (config != NULL) {
00551 const cfg_obj_t *options = NULL;
00552 (void)cfg_map_get(config, "options", &options);
00553 if (options != NULL)
00554 maps[i++] = options;
00555 }
00556 maps[i] = NULL;
00557
00558 (void)ns_config_get(maps, confname, &obj);
00559 if (obj == NULL)
00560
00561
00562
00563 return (ISC_R_SUCCESS);
00564
00565 if (conftuplename != NULL) {
00566 obj = cfg_tuple_get(obj, conftuplename);
00567 if (cfg_obj_isvoid(obj))
00568 return (ISC_R_SUCCESS);
00569 }
00570
00571 result = dns_rbt_create(mctx, NULL, NULL, rbtp);
00572 if (result != ISC_R_SUCCESS)
00573 return (result);
00574
00575 dns_fixedname_init(&fixed);
00576 name = dns_fixedname_name(&fixed);
00577 for (element = cfg_list_first(obj);
00578 element != NULL;
00579 element = cfg_list_next(element)) {
00580 nameobj = cfg_listelt_value(element);
00581 str = cfg_obj_asstring(nameobj);
00582 isc_buffer_constinit(&b, str, strlen(str));
00583 isc_buffer_add(&b, strlen(str));
00584 CHECK(dns_name_fromtext(name, &b, dns_rootname, 0, NULL));
00585
00586
00587
00588
00589
00590
00591
00592 result = dns_rbt_addname(*rbtp, name, (void *)1);
00593 if (result != ISC_R_SUCCESS) {
00594 cfg_obj_log(nameobj, ns_g_lctx, ISC_LOG_ERROR,
00595 "failed to add %s for %s: %s",
00596 str, confname, isc_result_totext(result));
00597 goto cleanup;
00598 }
00599
00600 }
00601
00602 return (result);
00603
00604 cleanup:
00605 dns_rbt_destroy(rbtp);
00606 return (result);
00607
00608 }
00609
00610 static isc_result_t
00611 dstkey_fromconfig(const cfg_obj_t *vconfig, const cfg_obj_t *key,
00612 isc_boolean_t managed, dst_key_t **target, isc_mem_t *mctx)
00613 {
00614 dns_rdataclass_t viewclass;
00615 dns_rdata_dnskey_t keystruct;
00616 isc_uint32_t flags, proto, alg;
00617 const char *keystr, *keynamestr;
00618 unsigned char keydata[4096];
00619 isc_buffer_t keydatabuf;
00620 unsigned char rrdata[4096];
00621 isc_buffer_t rrdatabuf;
00622 isc_region_t r;
00623 dns_fixedname_t fkeyname;
00624 dns_name_t *keyname;
00625 isc_buffer_t namebuf;
00626 isc_result_t result;
00627 dst_key_t *dstkey = NULL;
00628
00629 INSIST(target != NULL && *target == NULL);
00630
00631 flags = cfg_obj_asuint32(cfg_tuple_get(key, "flags"));
00632 proto = cfg_obj_asuint32(cfg_tuple_get(key, "protocol"));
00633 alg = cfg_obj_asuint32(cfg_tuple_get(key, "algorithm"));
00634 keyname = dns_fixedname_name(&fkeyname);
00635 keynamestr = cfg_obj_asstring(cfg_tuple_get(key, "name"));
00636
00637 if (managed) {
00638 const char *initmethod;
00639 initmethod = cfg_obj_asstring(cfg_tuple_get(key, "init"));
00640
00641 if (strcasecmp(initmethod, "initial-key") != 0) {
00642 cfg_obj_log(key, ns_g_lctx, ISC_LOG_ERROR,
00643 "managed key '%s': "
00644 "invalid initialization method '%s'",
00645 keynamestr, initmethod);
00646 result = ISC_R_FAILURE;
00647 goto cleanup;
00648 }
00649 }
00650
00651 if (vconfig == NULL)
00652 viewclass = dns_rdataclass_in;
00653 else {
00654 const cfg_obj_t *classobj = cfg_tuple_get(vconfig, "class");
00655 CHECK(ns_config_getclass(classobj, dns_rdataclass_in,
00656 &viewclass));
00657 }
00658 keystruct.common.rdclass = viewclass;
00659 keystruct.common.rdtype = dns_rdatatype_dnskey;
00660
00661
00662
00663 keystruct.mctx = NULL;
00664
00665 ISC_LINK_INIT(&keystruct.common, link);
00666
00667 if (flags > 0xffff)
00668 CHECKM(ISC_R_RANGE, "key flags");
00669 if (proto > 0xff)
00670 CHECKM(ISC_R_RANGE, "key protocol");
00671 if (alg > 0xff)
00672 CHECKM(ISC_R_RANGE, "key algorithm");
00673 keystruct.flags = (isc_uint16_t)flags;
00674 keystruct.protocol = (isc_uint8_t)proto;
00675 keystruct.algorithm = (isc_uint8_t)alg;
00676
00677 isc_buffer_init(&keydatabuf, keydata, sizeof(keydata));
00678 isc_buffer_init(&rrdatabuf, rrdata, sizeof(rrdata));
00679
00680 keystr = cfg_obj_asstring(cfg_tuple_get(key, "key"));
00681 CHECK(isc_base64_decodestring(keystr, &keydatabuf));
00682 isc_buffer_usedregion(&keydatabuf, &r);
00683 keystruct.datalen = r.length;
00684 keystruct.data = r.base;
00685
00686 if ((keystruct.algorithm == DST_ALG_RSASHA1 ||
00687 keystruct.algorithm == DST_ALG_RSAMD5) &&
00688 r.length > 1 && r.base[0] == 1 && r.base[1] == 3)
00689 cfg_obj_log(key, ns_g_lctx, ISC_LOG_WARNING,
00690 "%s key '%s' has a weak exponent",
00691 managed ? "managed" : "trusted",
00692 keynamestr);
00693
00694 CHECK(dns_rdata_fromstruct(NULL,
00695 keystruct.common.rdclass,
00696 keystruct.common.rdtype,
00697 &keystruct, &rrdatabuf));
00698 dns_fixedname_init(&fkeyname);
00699 isc_buffer_constinit(&namebuf, keynamestr, strlen(keynamestr));
00700 isc_buffer_add(&namebuf, strlen(keynamestr));
00701 CHECK(dns_name_fromtext(keyname, &namebuf, dns_rootname, 0, NULL));
00702 CHECK(dst_key_fromdns(keyname, viewclass, &rrdatabuf,
00703 mctx, &dstkey));
00704
00705 *target = dstkey;
00706 return (ISC_R_SUCCESS);
00707
00708 cleanup:
00709 if (result == DST_R_NOCRYPTO) {
00710 cfg_obj_log(key, ns_g_lctx, ISC_LOG_ERROR,
00711 "ignoring %s key for '%s': no crypto support",
00712 managed ? "managed" : "trusted",
00713 keynamestr);
00714 } else if (result == DST_R_UNSUPPORTEDALG) {
00715 cfg_obj_log(key, ns_g_lctx, ISC_LOG_WARNING,
00716 "skipping %s key for '%s': %s",
00717 managed ? "managed" : "trusted",
00718 keynamestr, isc_result_totext(result));
00719 } else {
00720 cfg_obj_log(key, ns_g_lctx, ISC_LOG_ERROR,
00721 "configuring %s key for '%s': %s",
00722 managed ? "managed" : "trusted",
00723 keynamestr, isc_result_totext(result));
00724 result = ISC_R_FAILURE;
00725 }
00726
00727 if (dstkey != NULL)
00728 dst_key_free(&dstkey);
00729
00730 return (result);
00731 }
00732
00733 static isc_result_t
00734 load_view_keys(const cfg_obj_t *keys, const cfg_obj_t *vconfig,
00735 dns_view_t *view, isc_boolean_t managed,
00736 dns_name_t *keyname, isc_mem_t *mctx)
00737 {
00738 const cfg_listelt_t *elt, *elt2;
00739 const cfg_obj_t *key, *keylist;
00740 dst_key_t *dstkey = NULL;
00741 isc_result_t result;
00742 dns_keytable_t *secroots = NULL;
00743
00744 CHECK(dns_view_getsecroots(view, &secroots));
00745
00746 for (elt = cfg_list_first(keys);
00747 elt != NULL;
00748 elt = cfg_list_next(elt)) {
00749 keylist = cfg_listelt_value(elt);
00750
00751 for (elt2 = cfg_list_first(keylist);
00752 elt2 != NULL;
00753 elt2 = cfg_list_next(elt2)) {
00754 key = cfg_listelt_value(elt2);
00755 result = dstkey_fromconfig(vconfig, key, managed,
00756 &dstkey, mctx);
00757 if (result == DST_R_UNSUPPORTEDALG) {
00758 result = ISC_R_SUCCESS;
00759 continue;
00760 }
00761 if (result != ISC_R_SUCCESS)
00762 goto cleanup;
00763
00764
00765
00766
00767 if (keyname != NULL &&
00768 !dns_name_equal(keyname, dst_key_name(dstkey)))
00769 {
00770 dst_key_free(&dstkey);
00771 continue;
00772 }
00773
00774 CHECK(dns_keytable_add(secroots, managed, &dstkey));
00775 }
00776 }
00777
00778 cleanup:
00779 if (dstkey != NULL)
00780 dst_key_free(&dstkey);
00781 if (secroots != NULL)
00782 dns_keytable_detach(&secroots);
00783 if (result == DST_R_NOCRYPTO)
00784 result = ISC_R_SUCCESS;
00785 return (result);
00786 }
00787
00788
00789
00790
00791
00792
00793
00794 static isc_result_t
00795 configure_view_dnsseckeys(dns_view_t *view, const cfg_obj_t *vconfig,
00796 const cfg_obj_t *config, const cfg_obj_t *bindkeys,
00797 isc_boolean_t auto_dlv, isc_boolean_t auto_root,
00798 isc_mem_t *mctx)
00799 {
00800 isc_result_t result = ISC_R_SUCCESS;
00801 const cfg_obj_t *view_keys = NULL;
00802 const cfg_obj_t *global_keys = NULL;
00803 const cfg_obj_t *view_managed_keys = NULL;
00804 const cfg_obj_t *global_managed_keys = NULL;
00805 const cfg_obj_t *maps[4];
00806 const cfg_obj_t *voptions = NULL;
00807 const cfg_obj_t *options = NULL;
00808 const cfg_obj_t *obj = NULL;
00809 const char *directory;
00810 int i = 0;
00811
00812
00813 if (strcmp(view->name, "_bind") == 0 &&
00814 view->rdclass == dns_rdataclass_chaos) {
00815 return (ISC_R_SUCCESS);
00816 }
00817
00818 if (vconfig != NULL) {
00819 voptions = cfg_tuple_get(vconfig, "options");
00820 if (voptions != NULL) {
00821 (void) cfg_map_get(voptions, "trusted-keys",
00822 &view_keys);
00823 (void) cfg_map_get(voptions, "managed-keys",
00824 &view_managed_keys);
00825 maps[i++] = voptions;
00826 }
00827 }
00828
00829 if (config != NULL) {
00830 (void)cfg_map_get(config, "trusted-keys", &global_keys);
00831 (void)cfg_map_get(config, "managed-keys", &global_managed_keys);
00832 (void)cfg_map_get(config, "options", &options);
00833 if (options != NULL) {
00834 maps[i++] = options;
00835 }
00836 }
00837
00838 maps[i++] = ns_g_defaults;
00839 maps[i] = NULL;
00840
00841 result = dns_view_initsecroots(view, mctx);
00842 if (result != ISC_R_SUCCESS) {
00843 isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
00844 NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
00845 "couldn't create keytable");
00846 return (ISC_R_UNEXPECTED);
00847 }
00848
00849 result = dns_view_initntatable(view, ns_g_taskmgr, ns_g_timermgr);
00850 if (result != ISC_R_SUCCESS) {
00851 isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
00852 NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
00853 "couldn't create NTA table");
00854 return (ISC_R_UNEXPECTED);
00855 }
00856
00857 if (auto_dlv && view->rdclass == dns_rdataclass_in) {
00858 const cfg_obj_t *builtin_keys = NULL;
00859 const cfg_obj_t *builtin_managed_keys = NULL;
00860
00861 isc_log_write(ns_g_lctx, DNS_LOGCATEGORY_SECURITY,
00862 NS_LOGMODULE_SERVER, ISC_LOG_INFO,
00863 "using built-in DLV key for view %s",
00864 view->name);
00865
00866
00867
00868
00869
00870 if (bindkeys != NULL) {
00871 (void)cfg_map_get(bindkeys, "trusted-keys",
00872 &builtin_keys);
00873 (void)cfg_map_get(bindkeys, "managed-keys",
00874 &builtin_managed_keys);
00875 } else {
00876 (void)cfg_map_get(ns_g_config, "trusted-keys",
00877 &builtin_keys);
00878 (void)cfg_map_get(ns_g_config, "managed-keys",
00879 &builtin_managed_keys);
00880 }
00881
00882 if (builtin_keys != NULL)
00883 CHECK(load_view_keys(builtin_keys, vconfig, view,
00884 ISC_FALSE, view->dlv, mctx));
00885 if (builtin_managed_keys != NULL)
00886 CHECK(load_view_keys(builtin_managed_keys, vconfig,
00887 view, ISC_TRUE, view->dlv, mctx));
00888 }
00889
00890 if (auto_root && view->rdclass == dns_rdataclass_in) {
00891 const cfg_obj_t *builtin_keys = NULL;
00892 const cfg_obj_t *builtin_managed_keys = NULL;
00893
00894 isc_log_write(ns_g_lctx, DNS_LOGCATEGORY_SECURITY,
00895 NS_LOGMODULE_SERVER, ISC_LOG_INFO,
00896 "using built-in root key for view %s",
00897 view->name);
00898
00899
00900
00901
00902
00903 if (bindkeys != NULL) {
00904 (void)cfg_map_get(bindkeys, "trusted-keys",
00905 &builtin_keys);
00906 (void)cfg_map_get(bindkeys, "managed-keys",
00907 &builtin_managed_keys);
00908 } else {
00909 (void)cfg_map_get(ns_g_config, "trusted-keys",
00910 &builtin_keys);
00911 (void)cfg_map_get(ns_g_config, "managed-keys",
00912 &builtin_managed_keys);
00913 }
00914
00915 if (builtin_keys != NULL)
00916 CHECK(load_view_keys(builtin_keys, vconfig, view,
00917 ISC_FALSE, dns_rootname, mctx));
00918 if (builtin_managed_keys != NULL)
00919 CHECK(load_view_keys(builtin_managed_keys, vconfig,
00920 view, ISC_TRUE, dns_rootname,
00921 mctx));
00922 }
00923
00924 CHECK(load_view_keys(view_keys, vconfig, view, ISC_FALSE,
00925 NULL, mctx));
00926 CHECK(load_view_keys(view_managed_keys, vconfig, view, ISC_TRUE,
00927 NULL, mctx));
00928
00929 if (view->rdclass == dns_rdataclass_in) {
00930 CHECK(load_view_keys(global_keys, vconfig, view, ISC_FALSE,
00931 NULL, mctx));
00932 CHECK(load_view_keys(global_managed_keys, vconfig, view,
00933 ISC_TRUE, NULL, mctx));
00934 }
00935
00936
00937
00938
00939 obj = NULL;
00940 (void)ns_config_get(maps, "managed-keys-directory", &obj);
00941 directory = (obj != NULL ? cfg_obj_asstring(obj) : NULL);
00942 if (directory != NULL)
00943 result = isc_file_isdirectory(directory);
00944 if (result != ISC_R_SUCCESS) {
00945 isc_log_write(ns_g_lctx, DNS_LOGCATEGORY_SECURITY,
00946 NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
00947 "invalid managed-keys-directory %s: %s",
00948 directory, isc_result_totext(result));
00949 goto cleanup;
00950
00951 }
00952 CHECK(add_keydata_zone(view, directory, ns_g_mctx));
00953
00954 cleanup:
00955 return (result);
00956 }
00957
00958 static isc_result_t
00959 mustbesecure(const cfg_obj_t *mbs, dns_resolver_t *resolver) {
00960 const cfg_listelt_t *element;
00961 const cfg_obj_t *obj;
00962 const char *str;
00963 dns_fixedname_t fixed;
00964 dns_name_t *name;
00965 isc_boolean_t value;
00966 isc_result_t result;
00967 isc_buffer_t b;
00968
00969 dns_fixedname_init(&fixed);
00970 name = dns_fixedname_name(&fixed);
00971 for (element = cfg_list_first(mbs);
00972 element != NULL;
00973 element = cfg_list_next(element))
00974 {
00975 obj = cfg_listelt_value(element);
00976 str = cfg_obj_asstring(cfg_tuple_get(obj, "name"));
00977 isc_buffer_constinit(&b, str, strlen(str));
00978 isc_buffer_add(&b, strlen(str));
00979 CHECK(dns_name_fromtext(name, &b, dns_rootname, 0, NULL));
00980 value = cfg_obj_asboolean(cfg_tuple_get(obj, "value"));
00981 CHECK(dns_resolver_setmustbesecure(resolver, name, value));
00982 }
00983
00984 result = ISC_R_SUCCESS;
00985
00986 cleanup:
00987 return (result);
00988 }
00989
00990
00991
00992
00993 static isc_result_t
00994 get_view_querysource_dispatch(const cfg_obj_t **maps, int af,
00995 dns_dispatch_t **dispatchp, isc_dscp_t *dscpp,
00996 isc_boolean_t is_firstview)
00997 {
00998 isc_result_t result = ISC_R_FAILURE;
00999 dns_dispatch_t *disp;
01000 isc_sockaddr_t sa;
01001 unsigned int attrs, attrmask;
01002 const cfg_obj_t *obj = NULL;
01003 unsigned int maxdispatchbuffers = UDPBUFFERS;
01004 isc_dscp_t dscp = -1;
01005
01006 switch (af) {
01007 case AF_INET:
01008 result = ns_config_get(maps, "query-source", &obj);
01009 INSIST(result == ISC_R_SUCCESS);
01010 break;
01011 case AF_INET6:
01012 result = ns_config_get(maps, "query-source-v6", &obj);
01013 INSIST(result == ISC_R_SUCCESS);
01014 break;
01015 default:
01016 INSIST(0);
01017 }
01018
01019 sa = *(cfg_obj_assockaddr(obj));
01020 INSIST(isc_sockaddr_pf(&sa) == af);
01021
01022 dscp = cfg_obj_getdscp(obj);
01023 if (dscp != -1 && dscpp != NULL)
01024 *dscpp = dscp;
01025
01026
01027
01028
01029 switch (af) {
01030 case AF_INET:
01031 result = isc_net_probeipv4();
01032 break;
01033 case AF_INET6:
01034 result = isc_net_probeipv6();
01035 break;
01036 default:
01037 INSIST(0);
01038 }
01039 if (result != ISC_R_SUCCESS)
01040 return (ISC_R_SUCCESS);
01041
01042
01043
01044
01045 attrs = 0;
01046 attrs |= DNS_DISPATCHATTR_UDP;
01047 switch (af) {
01048 case AF_INET:
01049 attrs |= DNS_DISPATCHATTR_IPV4;
01050 break;
01051 case AF_INET6:
01052 attrs |= DNS_DISPATCHATTR_IPV6;
01053 break;
01054 }
01055 if (isc_sockaddr_getport(&sa) == 0) {
01056 attrs |= DNS_DISPATCHATTR_EXCLUSIVE;
01057 maxdispatchbuffers = EXCLBUFFERS;
01058 } else {
01059 INSIST(obj != NULL);
01060 if (is_firstview) {
01061 cfg_obj_log(obj, ns_g_lctx, ISC_LOG_INFO,
01062 "using specific query-source port "
01063 "suppresses port randomization and can be "
01064 "insecure.");
01065 }
01066 }
01067
01068 attrmask = 0;
01069 attrmask |= DNS_DISPATCHATTR_UDP;
01070 attrmask |= DNS_DISPATCHATTR_TCP;
01071 attrmask |= DNS_DISPATCHATTR_IPV4;
01072 attrmask |= DNS_DISPATCHATTR_IPV6;
01073
01074 disp = NULL;
01075 result = dns_dispatch_getudp(ns_g_dispatchmgr, ns_g_socketmgr,
01076 ns_g_taskmgr, &sa, 4096,
01077 maxdispatchbuffers, 32768, 16411, 16433,
01078 attrs, attrmask, &disp);
01079 if (result != ISC_R_SUCCESS) {
01080 isc_sockaddr_t any;
01081 char buf[ISC_SOCKADDR_FORMATSIZE];
01082
01083 switch (af) {
01084 case AF_INET:
01085 isc_sockaddr_any(&any);
01086 break;
01087 case AF_INET6:
01088 isc_sockaddr_any6(&any);
01089 break;
01090 }
01091 if (isc_sockaddr_equal(&sa, &any))
01092 return (ISC_R_SUCCESS);
01093 isc_sockaddr_format(&sa, buf, sizeof(buf));
01094 isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
01095 NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
01096 "could not get query source dispatcher (%s)",
01097 buf);
01098 return (result);
01099 }
01100
01101 *dispatchp = disp;
01102
01103 return (ISC_R_SUCCESS);
01104 }
01105
01106 static isc_result_t
01107 configure_order(dns_order_t *order, const cfg_obj_t *ent) {
01108 dns_rdataclass_t rdclass;
01109 dns_rdatatype_t rdtype;
01110 const cfg_obj_t *obj;
01111 dns_fixedname_t fixed;
01112 unsigned int mode = 0;
01113 const char *str;
01114 isc_buffer_t b;
01115 isc_result_t result;
01116 isc_boolean_t addroot;
01117
01118 result = ns_config_getclass(cfg_tuple_get(ent, "class"),
01119 dns_rdataclass_any, &rdclass);
01120 if (result != ISC_R_SUCCESS)
01121 return (result);
01122
01123 result = ns_config_gettype(cfg_tuple_get(ent, "type"),
01124 dns_rdatatype_any, &rdtype);
01125 if (result != ISC_R_SUCCESS)
01126 return (result);
01127
01128 obj = cfg_tuple_get(ent, "name");
01129 if (cfg_obj_isstring(obj))
01130 str = cfg_obj_asstring(obj);
01131 else
01132 str = "*";
01133 addroot = ISC_TF(strcmp(str, "*") == 0);
01134 isc_buffer_constinit(&b, str, strlen(str));
01135 isc_buffer_add(&b, strlen(str));
01136 dns_fixedname_init(&fixed);
01137 result = dns_name_fromtext(dns_fixedname_name(&fixed), &b,
01138 dns_rootname, 0, NULL);
01139 if (result != ISC_R_SUCCESS)
01140 return (result);
01141
01142 obj = cfg_tuple_get(ent, "ordering");
01143 INSIST(cfg_obj_isstring(obj));
01144 str = cfg_obj_asstring(obj);
01145 if (!strcasecmp(str, "fixed"))
01146 #if DNS_RDATASET_FIXED
01147 mode = DNS_RDATASETATTR_FIXEDORDER;
01148 #else
01149 mode = 0;
01150 #endif
01151 else if (!strcasecmp(str, "random"))
01152 mode = DNS_RDATASETATTR_RANDOMIZE;
01153 else if (!strcasecmp(str, "cyclic"))
01154 mode = 0;
01155 else
01156 INSIST(0);
01157
01158
01159
01160
01161
01162
01163 if (addroot) {
01164 result = dns_order_add(order, dns_rootname,
01165 rdtype, rdclass, mode);
01166 if (result != ISC_R_SUCCESS)
01167 return (result);
01168 }
01169
01170 return (dns_order_add(order, dns_fixedname_name(&fixed),
01171 rdtype, rdclass, mode));
01172 }
01173
01174 static isc_result_t
01175 configure_peer(const cfg_obj_t *cpeer, isc_mem_t *mctx, dns_peer_t **peerp) {
01176 isc_netaddr_t na;
01177 dns_peer_t *peer;
01178 const cfg_obj_t *obj;
01179 const char *str;
01180 isc_result_t result;
01181 unsigned int prefixlen;
01182
01183 cfg_obj_asnetprefix(cfg_map_getname(cpeer), &na, &prefixlen);
01184
01185 peer = NULL;
01186 result = dns_peer_newprefix(mctx, &na, prefixlen, &peer);
01187 if (result != ISC_R_SUCCESS)
01188 return (result);
01189
01190 obj = NULL;
01191 (void)cfg_map_get(cpeer, "bogus", &obj);
01192 if (obj != NULL)
01193 CHECK(dns_peer_setbogus(peer, cfg_obj_asboolean(obj)));
01194
01195 obj = NULL;
01196 (void)cfg_map_get(cpeer, "provide-ixfr", &obj);
01197 if (obj != NULL)
01198 CHECK(dns_peer_setprovideixfr(peer, cfg_obj_asboolean(obj)));
01199
01200 obj = NULL;
01201 (void)cfg_map_get(cpeer, "request-expire", &obj);
01202 if (obj != NULL)
01203 CHECK(dns_peer_setrequestexpire(peer, cfg_obj_asboolean(obj)));
01204
01205 obj = NULL;
01206 (void)cfg_map_get(cpeer, "request-ixfr", &obj);
01207 if (obj != NULL)
01208 CHECK(dns_peer_setrequestixfr(peer, cfg_obj_asboolean(obj)));
01209
01210 obj = NULL;
01211 (void)cfg_map_get(cpeer, "request-nsid", &obj);
01212 if (obj != NULL)
01213 CHECK(dns_peer_setrequestnsid(peer, cfg_obj_asboolean(obj)));
01214
01215 #ifdef ISC_PLATFORM_USESIT
01216 obj = NULL;
01217 (void)cfg_map_get(cpeer, "request-sit", &obj);
01218 if (obj != NULL)
01219 CHECK(dns_peer_setrequestsit(peer, cfg_obj_asboolean(obj)));
01220 #endif
01221
01222 obj = NULL;
01223 (void)cfg_map_get(cpeer, "edns", &obj);
01224 if (obj != NULL)
01225 CHECK(dns_peer_setsupportedns(peer, cfg_obj_asboolean(obj)));
01226
01227 obj = NULL;
01228 (void)cfg_map_get(cpeer, "edns-udp-size", &obj);
01229 if (obj != NULL) {
01230 isc_uint32_t udpsize = cfg_obj_asuint32(obj);
01231 if (udpsize < 512)
01232 udpsize = 512;
01233 if (udpsize > 4096)
01234 udpsize = 4096;
01235 CHECK(dns_peer_setudpsize(peer, (isc_uint16_t)udpsize));
01236 }
01237
01238 obj = NULL;
01239 (void)cfg_map_get(cpeer, "edns-version", &obj);
01240 if (obj != NULL) {
01241 isc_uint32_t ednsversion = cfg_obj_asuint32(obj);
01242 if (ednsversion > 255)
01243 ednsversion = 255;
01244 CHECK(dns_peer_setednsversion(peer, (isc_uint8_t)ednsversion));
01245 }
01246
01247 obj = NULL;
01248 (void)cfg_map_get(cpeer, "max-udp-size", &obj);
01249 if (obj != NULL) {
01250 isc_uint32_t udpsize = cfg_obj_asuint32(obj);
01251 if (udpsize < 512)
01252 udpsize = 512;
01253 if (udpsize > 4096)
01254 udpsize = 4096;
01255 CHECK(dns_peer_setmaxudp(peer, (isc_uint16_t)udpsize));
01256 }
01257
01258 obj = NULL;
01259 (void)cfg_map_get(cpeer, "tcp-only", &obj);
01260 if (obj != NULL)
01261 CHECK(dns_peer_setforcetcp(peer, cfg_obj_asboolean(obj)));
01262
01263 obj = NULL;
01264 (void)cfg_map_get(cpeer, "transfers", &obj);
01265 if (obj != NULL)
01266 CHECK(dns_peer_settransfers(peer, cfg_obj_asuint32(obj)));
01267
01268 obj = NULL;
01269 (void)cfg_map_get(cpeer, "transfer-format", &obj);
01270 if (obj != NULL) {
01271 str = cfg_obj_asstring(obj);
01272 if (strcasecmp(str, "many-answers") == 0)
01273 CHECK(dns_peer_settransferformat(peer,
01274 dns_many_answers));
01275 else if (strcasecmp(str, "one-answer") == 0)
01276 CHECK(dns_peer_settransferformat(peer,
01277 dns_one_answer));
01278 else
01279 INSIST(0);
01280 }
01281
01282 obj = NULL;
01283 (void)cfg_map_get(cpeer, "keys", &obj);
01284 if (obj != NULL) {
01285 result = dns_peer_setkeybycharp(peer, cfg_obj_asstring(obj));
01286 if (result != ISC_R_SUCCESS)
01287 goto cleanup;
01288 }
01289
01290 obj = NULL;
01291 if (na.family == AF_INET)
01292 (void)cfg_map_get(cpeer, "transfer-source", &obj);
01293 else
01294 (void)cfg_map_get(cpeer, "transfer-source-v6", &obj);
01295 if (obj != NULL) {
01296 result = dns_peer_settransfersource(peer,
01297 cfg_obj_assockaddr(obj));
01298 if (result != ISC_R_SUCCESS)
01299 goto cleanup;
01300 result = dns_peer_settransferdscp(peer, cfg_obj_getdscp(obj));
01301 if (result != ISC_R_SUCCESS)
01302 goto cleanup;
01303 ns_add_reserved_dispatch(ns_g_server, cfg_obj_assockaddr(obj));
01304 }
01305
01306 obj = NULL;
01307 if (na.family == AF_INET)
01308 (void)cfg_map_get(cpeer, "notify-source", &obj);
01309 else
01310 (void)cfg_map_get(cpeer, "notify-source-v6", &obj);
01311 if (obj != NULL) {
01312 result = dns_peer_setnotifysource(peer,
01313 cfg_obj_assockaddr(obj));
01314 if (result != ISC_R_SUCCESS)
01315 goto cleanup;
01316 result = dns_peer_setnotifydscp(peer, cfg_obj_getdscp(obj));
01317 if (result != ISC_R_SUCCESS)
01318 goto cleanup;
01319 ns_add_reserved_dispatch(ns_g_server, cfg_obj_assockaddr(obj));
01320 }
01321
01322 obj = NULL;
01323 if (na.family == AF_INET)
01324 (void)cfg_map_get(cpeer, "query-source", &obj);
01325 else
01326 (void)cfg_map_get(cpeer, "query-source-v6", &obj);
01327 if (obj != NULL) {
01328 result = dns_peer_setquerysource(peer,
01329 cfg_obj_assockaddr(obj));
01330 if (result != ISC_R_SUCCESS)
01331 goto cleanup;
01332 result = dns_peer_setquerydscp(peer, cfg_obj_getdscp(obj));
01333 if (result != ISC_R_SUCCESS)
01334 goto cleanup;
01335 ns_add_reserved_dispatch(ns_g_server, cfg_obj_assockaddr(obj));
01336 }
01337
01338 *peerp = peer;
01339 return (ISC_R_SUCCESS);
01340
01341 cleanup:
01342 dns_peer_detach(&peer);
01343 return (result);
01344 }
01345
01346 static isc_result_t
01347 disable_algorithms(const cfg_obj_t *disabled, dns_resolver_t *resolver) {
01348 isc_result_t result;
01349 const cfg_obj_t *algorithms;
01350 const cfg_listelt_t *element;
01351 const char *str;
01352 dns_fixedname_t fixed;
01353 dns_name_t *name;
01354 isc_buffer_t b;
01355
01356 dns_fixedname_init(&fixed);
01357 name = dns_fixedname_name(&fixed);
01358 str = cfg_obj_asstring(cfg_tuple_get(disabled, "name"));
01359 isc_buffer_constinit(&b, str, strlen(str));
01360 isc_buffer_add(&b, strlen(str));
01361 CHECK(dns_name_fromtext(name, &b, dns_rootname, 0, NULL));
01362
01363 algorithms = cfg_tuple_get(disabled, "algorithms");
01364 for (element = cfg_list_first(algorithms);
01365 element != NULL;
01366 element = cfg_list_next(element))
01367 {
01368 isc_textregion_t r;
01369 dns_secalg_t alg;
01370
01371 DE_CONST(cfg_obj_asstring(cfg_listelt_value(element)), r.base);
01372 r.length = strlen(r.base);
01373
01374 result = dns_secalg_fromtext(&alg, &r);
01375 if (result != ISC_R_SUCCESS) {
01376 isc_uint8_t ui;
01377 result = isc_parse_uint8(&ui, r.base, 10);
01378 alg = ui;
01379 }
01380 if (result != ISC_R_SUCCESS) {
01381 cfg_obj_log(cfg_listelt_value(element),
01382 ns_g_lctx, ISC_LOG_ERROR,
01383 "invalid algorithm");
01384 CHECK(result);
01385 }
01386 CHECK(dns_resolver_disable_algorithm(resolver, name, alg));
01387 }
01388 cleanup:
01389 return (result);
01390 }
01391
01392 static isc_result_t
01393 disable_ds_digests(const cfg_obj_t *disabled, dns_resolver_t *resolver) {
01394 isc_result_t result;
01395 const cfg_obj_t *digests;
01396 const cfg_listelt_t *element;
01397 const char *str;
01398 dns_fixedname_t fixed;
01399 dns_name_t *name;
01400 isc_buffer_t b;
01401
01402 dns_fixedname_init(&fixed);
01403 name = dns_fixedname_name(&fixed);
01404 str = cfg_obj_asstring(cfg_tuple_get(disabled, "name"));
01405 isc_buffer_constinit(&b, str, strlen(str));
01406 isc_buffer_add(&b, strlen(str));
01407 CHECK(dns_name_fromtext(name, &b, dns_rootname, 0, NULL));
01408
01409 digests = cfg_tuple_get(disabled, "digests");
01410 for (element = cfg_list_first(digests);
01411 element != NULL;
01412 element = cfg_list_next(element))
01413 {
01414 isc_textregion_t r;
01415 dns_dsdigest_t digest;
01416
01417 DE_CONST(cfg_obj_asstring(cfg_listelt_value(element)), r.base);
01418 r.length = strlen(r.base);
01419
01420
01421 result = dns_dsdigest_fromtext(&digest, &r);
01422 if (result != ISC_R_SUCCESS) {
01423 cfg_obj_log(cfg_listelt_value(element),
01424 ns_g_lctx, ISC_LOG_ERROR,
01425 "invalid algorithm");
01426 CHECK(result);
01427 }
01428 CHECK(dns_resolver_disable_ds_digest(resolver, name, digest));
01429 }
01430 cleanup:
01431 return (result);
01432 }
01433
01434 static isc_boolean_t
01435 on_disable_list(const cfg_obj_t *disablelist, dns_name_t *zonename) {
01436 const cfg_listelt_t *element;
01437 dns_fixedname_t fixed;
01438 dns_name_t *name;
01439 isc_result_t result;
01440 const cfg_obj_t *value;
01441 const char *str;
01442 isc_buffer_t b;
01443
01444 dns_fixedname_init(&fixed);
01445 name = dns_fixedname_name(&fixed);
01446
01447 for (element = cfg_list_first(disablelist);
01448 element != NULL;
01449 element = cfg_list_next(element))
01450 {
01451 value = cfg_listelt_value(element);
01452 str = cfg_obj_asstring(value);
01453 isc_buffer_constinit(&b, str, strlen(str));
01454 isc_buffer_add(&b, strlen(str));
01455 result = dns_name_fromtext(name, &b, dns_rootname,
01456 0, NULL);
01457 RUNTIME_CHECK(result == ISC_R_SUCCESS);
01458 if (dns_name_equal(name, zonename))
01459 return (ISC_TRUE);
01460 }
01461 return (ISC_FALSE);
01462 }
01463
01464 static isc_result_t
01465 check_dbtype(dns_zone_t *zone, unsigned int dbtypec, const char **dbargv,
01466 isc_mem_t *mctx)
01467 {
01468 char **argv = NULL;
01469 unsigned int i;
01470 isc_result_t result = ISC_R_SUCCESS;
01471
01472 CHECK(dns_zone_getdbtype(zone, &argv, mctx));
01473
01474
01475
01476
01477 for (i = 0; i < dbtypec; i++)
01478 if (argv[i] == NULL || strcmp(argv[i], dbargv[i]) != 0)
01479 CHECK(ISC_R_FAILURE);
01480
01481
01482
01483
01484 if (i == dbtypec && argv[i] != NULL)
01485 result = ISC_R_FAILURE;
01486
01487 cleanup:
01488 isc_mem_free(mctx, argv);
01489 return (result);
01490 }
01491
01492 static isc_result_t
01493 setquerystats(dns_zone_t *zone, isc_mem_t *mctx, dns_zonestat_level_t level) {
01494 isc_result_t result;
01495 isc_stats_t *zoneqrystats;
01496
01497 dns_zone_setstatlevel(zone, level);
01498
01499 zoneqrystats = NULL;
01500 if (level == dns_zonestat_full) {
01501 result = isc_stats_create(mctx, &zoneqrystats,
01502 dns_nsstatscounter_max);
01503 if (result != ISC_R_SUCCESS)
01504 return (result);
01505 }
01506 dns_zone_setrequeststats(zone, zoneqrystats);
01507 if (zoneqrystats != NULL)
01508 isc_stats_detach(&zoneqrystats);
01509
01510 return (ISC_R_SUCCESS);
01511 }
01512
01513 static ns_cache_t *
01514 cachelist_find(ns_cachelist_t *cachelist, const char *cachename) {
01515 ns_cache_t *nsc;
01516
01517 for (nsc = ISC_LIST_HEAD(*cachelist);
01518 nsc != NULL;
01519 nsc = ISC_LIST_NEXT(nsc, link)) {
01520 if (strcmp(dns_cache_getname(nsc->cache), cachename) == 0)
01521 return (nsc);
01522 }
01523
01524 return (NULL);
01525 }
01526
01527 static isc_boolean_t
01528 cache_reusable(dns_view_t *originview, dns_view_t *view,
01529 isc_boolean_t new_zero_no_soattl)
01530 {
01531 if (originview->checknames != view->checknames ||
01532 dns_resolver_getzeronosoattl(originview->resolver) !=
01533 new_zero_no_soattl ||
01534 originview->acceptexpired != view->acceptexpired ||
01535 originview->enablevalidation != view->enablevalidation ||
01536 originview->maxcachettl != view->maxcachettl ||
01537 originview->maxncachettl != view->maxncachettl) {
01538 return (ISC_FALSE);
01539 }
01540
01541 return (ISC_TRUE);
01542 }
01543
01544 static isc_boolean_t
01545 cache_sharable(dns_view_t *originview, dns_view_t *view,
01546 isc_boolean_t new_zero_no_soattl,
01547 unsigned int new_cleaning_interval,
01548 isc_uint64_t new_max_cache_size)
01549 {
01550
01551
01552
01553
01554 if (!cache_reusable(originview, view, new_zero_no_soattl))
01555 return (ISC_FALSE);
01556
01557
01558
01559
01560
01561 if (dns_cache_getcleaninginterval(originview->cache) !=
01562 new_cleaning_interval ||
01563 dns_cache_getcachesize(originview->cache) != new_max_cache_size) {
01564 return (ISC_FALSE);
01565 }
01566
01567 return (ISC_TRUE);
01568 }
01569
01570
01571
01572
01573 static isc_result_t
01574 dlzconfigure_callback(dns_view_t *view, dns_dlzdb_t *dlzdb, dns_zone_t *zone) {
01575 dns_name_t *origin = dns_zone_getorigin(zone);
01576 dns_rdataclass_t zclass = view->rdclass;
01577 isc_result_t result;
01578
01579 result = dns_zonemgr_managezone(ns_g_server->zonemgr, zone);
01580 if (result != ISC_R_SUCCESS)
01581 return (result);
01582 dns_zone_setstats(zone, ns_g_server->zonestats);
01583
01584 return (ns_zone_configure_writeable_dlz(dlzdb, zone, zclass, origin));
01585 }
01586
01587 static isc_result_t
01588 dns64_reverse(dns_view_t *view, isc_mem_t *mctx, isc_netaddr_t *na,
01589 unsigned int prefixlen, const char *server,
01590 const char *contact)
01591 {
01592 char *cp;
01593 char reverse[48+sizeof("ip6.arpa.")];
01594 const char *dns64_dbtype[4] = { "_dns64", "dns64", ".", "." };
01595 const char *sep = ": view ";
01596 const char *viewname = view->name;
01597 const unsigned char *s6;
01598 dns_fixedname_t fixed;
01599 dns_name_t *name;
01600 dns_zone_t *zone = NULL;
01601 int dns64_dbtypec = 4;
01602 isc_buffer_t b;
01603 isc_result_t result;
01604
01605 REQUIRE(prefixlen == 32 || prefixlen == 40 || prefixlen == 48 ||
01606 prefixlen == 56 || prefixlen == 64 || prefixlen == 96);
01607
01608 if (!strcmp(viewname, "_default")) {
01609 sep = "";
01610 viewname = "";
01611 }
01612
01613
01614
01615
01616 cp = reverse;
01617 s6 = na->type.in6.s6_addr;
01618 while (prefixlen > 0) {
01619 prefixlen -= 8;
01620 sprintf(cp, "%x.%x.", s6[prefixlen/8] & 0xf,
01621 (s6[prefixlen/8] >> 4) & 0xf);
01622 cp += 4;
01623 }
01624 strcat(cp, "ip6.arpa.");
01625
01626
01627
01628
01629 if (server != NULL)
01630 dns64_dbtype[2] = server;
01631 if (contact != NULL)
01632 dns64_dbtype[3] = contact;
01633 dns_fixedname_init(&fixed);
01634 name = dns_fixedname_name(&fixed);
01635 isc_buffer_constinit(&b, reverse, strlen(reverse));
01636 isc_buffer_add(&b, strlen(reverse));
01637 CHECK(dns_name_fromtext(name, &b, dns_rootname, 0, NULL));
01638 CHECK(dns_zone_create(&zone, mctx));
01639 CHECK(dns_zone_setorigin(zone, name));
01640 dns_zone_setview(zone, view);
01641 CHECK(dns_zonemgr_managezone(ns_g_server->zonemgr, zone));
01642 dns_zone_setclass(zone, view->rdclass);
01643 dns_zone_settype(zone, dns_zone_master);
01644 dns_zone_setstats(zone, ns_g_server->zonestats);
01645 CHECK(dns_zone_setdbtype(zone, dns64_dbtypec, dns64_dbtype));
01646 if (view->queryacl != NULL)
01647 dns_zone_setqueryacl(zone, view->queryacl);
01648 if (view->queryonacl != NULL)
01649 dns_zone_setqueryonacl(zone, view->queryonacl);
01650 dns_zone_setdialup(zone, dns_dialuptype_no);
01651 dns_zone_setnotifytype(zone, dns_notifytype_no);
01652 dns_zone_setoption(zone, DNS_ZONEOPT_NOCHECKNS, ISC_TRUE);
01653 CHECK(setquerystats(zone, mctx, dns_zonestat_none));
01654 CHECK(dns_view_addzone(view, zone));
01655 isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER,
01656 ISC_LOG_INFO, "dns64 reverse zone%s%s: %s", sep,
01657 viewname, reverse);
01658
01659 cleanup:
01660 if (zone != NULL)
01661 dns_zone_detach(&zone);
01662 return (result);
01663 }
01664
01665 static isc_result_t
01666 configure_rpz_name(dns_view_t *view, const cfg_obj_t *obj, dns_name_t *name,
01667 const char *str, const char *msg)
01668 {
01669 isc_result_t result;
01670
01671 result = dns_name_fromstring(name, str, DNS_NAME_DOWNCASE, view->mctx);
01672 if (result != ISC_R_SUCCESS)
01673 cfg_obj_log(obj, ns_g_lctx, DNS_RPZ_ERROR_LEVEL,
01674 "invalid %s '%s'", msg, str);
01675 return (result);
01676 }
01677
01678 static isc_result_t
01679 configure_rpz_name2(dns_view_t *view, const cfg_obj_t *obj, dns_name_t *name,
01680 const char *str, const dns_name_t *origin)
01681 {
01682 isc_result_t result;
01683
01684 result = dns_name_fromstring2(name, str, origin, DNS_NAME_DOWNCASE,
01685 view->mctx);
01686 if (result != ISC_R_SUCCESS)
01687 cfg_obj_log(obj, ns_g_lctx, DNS_RPZ_ERROR_LEVEL,
01688 "invalid zone '%s'", str);
01689 return (result);
01690 }
01691
01692 static isc_result_t
01693 configure_rpz_zone(dns_view_t *view, const cfg_listelt_t *element,
01694 isc_boolean_t recursive_only_def, dns_ttl_t ttl_def,
01695 const dns_rpz_zone_t *old, isc_boolean_t *old_rpz_okp)
01696 {
01697 const cfg_obj_t *rpz_obj, *obj;
01698 const char *str;
01699 dns_rpz_zone_t *new;
01700 isc_result_t result;
01701 dns_rpz_num_t rpz_num;
01702
01703 REQUIRE(old != NULL || !*old_rpz_okp);
01704
01705 rpz_obj = cfg_listelt_value(element);
01706
01707 if (view->rpzs->p.num_zones >= DNS_RPZ_MAX_ZONES) {
01708 cfg_obj_log(rpz_obj, ns_g_lctx, DNS_RPZ_ERROR_LEVEL,
01709 "limit of %d response policy zones exceeded",
01710 DNS_RPZ_MAX_ZONES);
01711 return (ISC_R_FAILURE);
01712 }
01713
01714 new = isc_mem_get(view->rpzs->mctx, sizeof(*new));
01715 if (new == NULL) {
01716 cfg_obj_log(rpz_obj, ns_g_lctx, DNS_RPZ_ERROR_LEVEL,
01717 "no memory for response policy zones");
01718 return (ISC_R_NOMEMORY);
01719 }
01720
01721 memset(new, 0, sizeof(*new));
01722 result = isc_refcount_init(&new->refs, 1);
01723 if (result != ISC_R_SUCCESS) {
01724 isc_mem_put(view->rpzs->mctx, new, sizeof(*new));
01725 return (result);
01726 }
01727 dns_name_init(&new->origin, NULL);
01728 dns_name_init(&new->client_ip, NULL);
01729 dns_name_init(&new->ip, NULL);
01730 dns_name_init(&new->nsdname, NULL);
01731 dns_name_init(&new->nsip, NULL);
01732 dns_name_init(&new->passthru, NULL);
01733 dns_name_init(&new->drop, NULL);
01734 dns_name_init(&new->tcp_only, NULL);
01735 dns_name_init(&new->cname, NULL);
01736 new->num = view->rpzs->p.num_zones++;
01737 view->rpzs->zones[new->num] = new;
01738
01739 obj = cfg_tuple_get(rpz_obj, "recursive-only");
01740 if (cfg_obj_isvoid(obj) ? recursive_only_def : cfg_obj_asboolean(obj)) {
01741 view->rpzs->p.no_rd_ok &= ~DNS_RPZ_ZBIT(new->num);
01742 } else {
01743 view->rpzs->p.no_rd_ok |= DNS_RPZ_ZBIT(new->num);
01744 }
01745
01746 obj = cfg_tuple_get(rpz_obj, "max-policy-ttl");
01747 if (cfg_obj_isuint32(obj)) {
01748 new->max_policy_ttl = cfg_obj_asuint32(obj);
01749 } else {
01750 new->max_policy_ttl = ttl_def;
01751 }
01752 if (*old_rpz_okp && new->max_policy_ttl != old->max_policy_ttl)
01753 *old_rpz_okp = ISC_FALSE;
01754
01755 str = cfg_obj_asstring(cfg_tuple_get(rpz_obj, "zone name"));
01756 result = configure_rpz_name(view, rpz_obj, &new->origin, str, "zone");
01757 if (result != ISC_R_SUCCESS)
01758 return (result);
01759 if (dns_name_equal(&new->origin, dns_rootname)) {
01760 cfg_obj_log(rpz_obj, ns_g_lctx, DNS_RPZ_ERROR_LEVEL,
01761 "invalid zone name '%s'", str);
01762 return (DNS_R_EMPTYLABEL);
01763 }
01764 for (rpz_num = 0; rpz_num < view->rpzs->p.num_zones-1; ++rpz_num) {
01765 if (dns_name_equal(&view->rpzs->zones[rpz_num]->origin,
01766 &new->origin)) {
01767 cfg_obj_log(rpz_obj, ns_g_lctx, DNS_RPZ_ERROR_LEVEL,
01768 "duplicate '%s'", str);
01769 result = DNS_R_DUPLICATE;
01770 return (result);
01771 }
01772 }
01773 if (*old_rpz_okp && !dns_name_equal(&old->origin, &new->origin))
01774 *old_rpz_okp = ISC_FALSE;
01775
01776 result = configure_rpz_name2(view, rpz_obj, &new->client_ip,
01777 DNS_RPZ_CLIENT_IP_ZONE, &new->origin);
01778 if (result != ISC_R_SUCCESS)
01779 return (result);
01780
01781 result = configure_rpz_name2(view, rpz_obj, &new->ip,
01782 DNS_RPZ_IP_ZONE, &new->origin);
01783 if (result != ISC_R_SUCCESS)
01784 return (result);
01785
01786 result = configure_rpz_name2(view, rpz_obj, &new->nsdname,
01787 DNS_RPZ_NSDNAME_ZONE, &new->origin);
01788 if (result != ISC_R_SUCCESS)
01789 return (result);
01790
01791 result = configure_rpz_name2(view, rpz_obj, &new->nsip,
01792 DNS_RPZ_NSIP_ZONE, &new->origin);
01793 if (result != ISC_R_SUCCESS)
01794 return (result);
01795
01796 result = configure_rpz_name(view, rpz_obj, &new->passthru,
01797 DNS_RPZ_PASSTHRU_NAME, "name");
01798 if (result != ISC_R_SUCCESS)
01799 return (result);
01800
01801 result = configure_rpz_name(view, rpz_obj, &new->drop,
01802 DNS_RPZ_DROP_NAME, "name");
01803 if (result != ISC_R_SUCCESS)
01804 return (result);
01805
01806 result = configure_rpz_name(view, rpz_obj, &new->tcp_only,
01807 DNS_RPZ_TCP_ONLY_NAME, "name");
01808 if (result != ISC_R_SUCCESS)
01809 return (result);
01810
01811 obj = cfg_tuple_get(rpz_obj, "policy");
01812 if (cfg_obj_isvoid(obj)) {
01813 new->policy = DNS_RPZ_POLICY_GIVEN;
01814 } else {
01815 str = cfg_obj_asstring(cfg_tuple_get(obj, "policy name"));
01816 new->policy = dns_rpz_str2policy(str);
01817 INSIST(new->policy != DNS_RPZ_POLICY_ERROR);
01818 if (new->policy == DNS_RPZ_POLICY_CNAME) {
01819 str = cfg_obj_asstring(cfg_tuple_get(obj, "cname"));
01820 result = configure_rpz_name(view, rpz_obj, &new->cname,
01821 str, "cname");
01822 if (result != ISC_R_SUCCESS)
01823 return (result);
01824 }
01825 }
01826 if (*old_rpz_okp && (new->policy != old->policy ||
01827 !dns_name_equal(&old->cname, &new->cname)))
01828 *old_rpz_okp = ISC_FALSE;
01829
01830 return (ISC_R_SUCCESS);
01831 }
01832
01833 static isc_result_t
01834 configure_rpz(dns_view_t *view, const cfg_obj_t *rpz_obj,
01835 isc_boolean_t *old_rpz_okp)
01836 {
01837 const cfg_listelt_t *zone_element;
01838 const cfg_obj_t *sub_obj;
01839 isc_boolean_t recursive_only_def;
01840 dns_ttl_t ttl_def;
01841 dns_rpz_zones_t *new;
01842 const dns_rpz_zones_t *old;
01843 dns_view_t *pview;
01844 const dns_rpz_zone_t *old_zone;
01845 isc_result_t result;
01846 int i;
01847
01848 *old_rpz_okp = ISC_FALSE;
01849
01850 zone_element = cfg_list_first(cfg_tuple_get(rpz_obj, "zone list"));
01851 if (zone_element == NULL)
01852 return (ISC_R_SUCCESS);
01853
01854 result = dns_rpz_new_zones(&view->rpzs, view->mctx);
01855 if (result != ISC_R_SUCCESS)
01856 return (result);
01857 new = view->rpzs;
01858
01859 sub_obj = cfg_tuple_get(rpz_obj, "recursive-only");
01860 if (!cfg_obj_isvoid(sub_obj) &&
01861 !cfg_obj_asboolean(sub_obj))
01862 recursive_only_def = ISC_FALSE;
01863 else
01864 recursive_only_def = ISC_TRUE;
01865
01866 sub_obj = cfg_tuple_get(rpz_obj, "break-dnssec");
01867 if (!cfg_obj_isvoid(sub_obj) &&
01868 cfg_obj_asboolean(sub_obj))
01869 new->p.break_dnssec = ISC_TRUE;
01870 else
01871 new->p.break_dnssec = ISC_FALSE;
01872
01873 sub_obj = cfg_tuple_get(rpz_obj, "max-policy-ttl");
01874 if (cfg_obj_isuint32(sub_obj))
01875 ttl_def = cfg_obj_asuint32(sub_obj);
01876 else
01877 ttl_def = DNS_RPZ_MAX_TTL_DEFAULT;
01878
01879 sub_obj = cfg_tuple_get(rpz_obj, "min-ns-dots");
01880 if (cfg_obj_isuint32(sub_obj))
01881 new->p.min_ns_labels = cfg_obj_asuint32(sub_obj) + 1;
01882 else
01883 new->p.min_ns_labels = 2;
01884
01885 sub_obj = cfg_tuple_get(rpz_obj, "qname-wait-recurse");
01886 if (cfg_obj_isvoid(sub_obj) || cfg_obj_asboolean(sub_obj))
01887 new->p.qname_wait_recurse = ISC_TRUE;
01888 else
01889 new->p.qname_wait_recurse = ISC_FALSE;
01890
01891 pview = NULL;
01892 result = dns_viewlist_find(&ns_g_server->viewlist,
01893 view->name, view->rdclass, &pview);
01894 if (result == ISC_R_SUCCESS) {
01895 old = pview->rpzs;
01896 } else {
01897 old = NULL;
01898 }
01899 if (old == NULL)
01900 *old_rpz_okp = ISC_FALSE;
01901 else
01902 *old_rpz_okp = ISC_TRUE;
01903
01904 for (i = 0;
01905 zone_element != NULL;
01906 ++i, zone_element = cfg_list_next(zone_element)) {
01907 INSIST(old != NULL || !*old_rpz_okp);
01908 if (*old_rpz_okp && i < old->p.num_zones) {
01909 old_zone = old->zones[i];
01910 } else {
01911 *old_rpz_okp = ISC_FALSE;
01912 old_zone = NULL;
01913 }
01914 result = configure_rpz_zone(view, zone_element,
01915 recursive_only_def, ttl_def,
01916 old_zone, old_rpz_okp);
01917 if (result != ISC_R_SUCCESS) {
01918 if (pview != NULL)
01919 dns_view_detach(&pview);
01920 return (result);
01921 }
01922 }
01923
01924
01925
01926
01927
01928
01929 if (old != NULL && memcmp(&old->p, &new->p, sizeof(new->p)) != 0)
01930 *old_rpz_okp = ISC_FALSE;
01931 if (*old_rpz_okp) {
01932 dns_rpz_detach_rpzs(&view->rpzs);
01933 dns_rpz_attach_rpzs(pview->rpzs, &view->rpzs);
01934 }
01935 if (pview != NULL)
01936 dns_view_detach(&pview);
01937
01938 return (ISC_R_SUCCESS);
01939 }
01940
01941 #define CHECK_RRL(cond, pat, val1, val2) \
01942 do { \
01943 if (!(cond)) { \
01944 cfg_obj_log(obj, ns_g_lctx, ISC_LOG_ERROR, \
01945 pat, val1, val2); \
01946 result = ISC_R_RANGE; \
01947 goto cleanup; \
01948 } \
01949 } while (0)
01950
01951 #define CHECK_RRL_RATE(rate, def, max_rate, name) \
01952 do { \
01953 obj = NULL; \
01954 rrl->rate.str = name; \
01955 result = cfg_map_get(map, name, &obj); \
01956 if (result == ISC_R_SUCCESS) { \
01957 rrl->rate.r = cfg_obj_asuint32(obj); \
01958 CHECK_RRL(rrl->rate.r <= max_rate, \
01959 name" %d > %d", \
01960 rrl->rate.r, max_rate); \
01961 } else { \
01962 rrl->rate.r = def; \
01963 } \
01964 rrl->rate.scaled = rrl->rate.r; \
01965 } while (0)
01966
01967 static isc_result_t
01968 configure_rrl(dns_view_t *view, const cfg_obj_t *config, const cfg_obj_t *map) {
01969 const cfg_obj_t *obj;
01970 dns_rrl_t *rrl;
01971 isc_result_t result;
01972 int min_entries, i, j;
01973
01974
01975
01976
01977
01978
01979
01980 min_entries = 500;
01981 obj = NULL;
01982 result = cfg_map_get(map, "min-table-size", &obj);
01983 if (result == ISC_R_SUCCESS) {
01984 min_entries = cfg_obj_asuint32(obj);
01985 if (min_entries < 1)
01986 min_entries = 1;
01987 }
01988 result = dns_rrl_init(&rrl, view, min_entries);
01989 if (result != ISC_R_SUCCESS)
01990 return (result);
01991
01992 i = ISC_MAX(20000, min_entries);
01993 obj = NULL;
01994 result = cfg_map_get(map, "max-table-size", &obj);
01995 if (result == ISC_R_SUCCESS) {
01996 i = cfg_obj_asuint32(obj);
01997 CHECK_RRL(i >= min_entries,
01998 "max-table-size %d < min-table-size %d",
01999 i, min_entries);
02000 }
02001 rrl->max_entries = i;
02002
02003 CHECK_RRL_RATE(responses_per_second, 0, DNS_RRL_MAX_RATE,
02004 "responses-per-second");
02005 CHECK_RRL_RATE(referrals_per_second,
02006 rrl->responses_per_second.r, DNS_RRL_MAX_RATE,
02007 "referrals-per-second");
02008 CHECK_RRL_RATE(nodata_per_second,
02009 rrl->responses_per_second.r, DNS_RRL_MAX_RATE,
02010 "nodata-per-second");
02011 CHECK_RRL_RATE(nxdomains_per_second,
02012 rrl->responses_per_second.r, DNS_RRL_MAX_RATE,
02013 "nxdomains-per-second");
02014 CHECK_RRL_RATE(errors_per_second,
02015 rrl->responses_per_second.r, DNS_RRL_MAX_RATE,
02016 "errors-per-second");
02017
02018 CHECK_RRL_RATE(all_per_second, 0, DNS_RRL_MAX_RATE,
02019 "all-per-second");
02020
02021 CHECK_RRL_RATE(slip, 2, DNS_RRL_MAX_SLIP,
02022 "slip");
02023
02024 i = 15;
02025 obj = NULL;
02026 result = cfg_map_get(map, "window", &obj);
02027 if (result == ISC_R_SUCCESS) {
02028 i = cfg_obj_asuint32(obj);
02029 CHECK_RRL(i >= 1 && i <= DNS_RRL_MAX_WINDOW,
02030 "window %d < 1 or > %d", i, DNS_RRL_MAX_WINDOW);
02031 }
02032 rrl->window = i;
02033
02034 i = 0;
02035 obj = NULL;
02036 result = cfg_map_get(map, "qps-scale", &obj);
02037 if (result == ISC_R_SUCCESS) {
02038 i = cfg_obj_asuint32(obj);
02039 CHECK_RRL(i >= 1, "invalid 'qps-scale %d'%s", i, "");
02040 }
02041 rrl->qps_scale = i;
02042 rrl->qps = 1.0;
02043
02044 i = 24;
02045 obj = NULL;
02046 result = cfg_map_get(map, "ipv4-prefix-length", &obj);
02047 if (result == ISC_R_SUCCESS) {
02048 i = cfg_obj_asuint32(obj);
02049 CHECK_RRL(i >= 8 && i <= 32,
02050 "invalid 'ipv4-prefix-length %d'%s", i, "");
02051 }
02052 rrl->ipv4_prefixlen = i;
02053 if (i == 32)
02054 rrl->ipv4_mask = 0xffffffff;
02055 else
02056 rrl->ipv4_mask = htonl(0xffffffff << (32-i));
02057
02058 i = 56;
02059 obj = NULL;
02060 result = cfg_map_get(map, "ipv6-prefix-length", &obj);
02061 if (result == ISC_R_SUCCESS) {
02062 i = cfg_obj_asuint32(obj);
02063 CHECK_RRL(i >= 16 && i <= DNS_RRL_MAX_PREFIX,
02064 "ipv6-prefix-length %d < 16 or > %d",
02065 i, DNS_RRL_MAX_PREFIX);
02066 }
02067 rrl->ipv6_prefixlen = i;
02068 for (j = 0; j < 4; ++j) {
02069 if (i <= 0) {
02070 rrl->ipv6_mask[j] = 0;
02071 } else if (i < 32) {
02072 rrl->ipv6_mask[j] = htonl(0xffffffff << (32-i));
02073 } else {
02074 rrl->ipv6_mask[j] = 0xffffffff;
02075 }
02076 i -= 32;
02077 }
02078
02079 obj = NULL;
02080 result = cfg_map_get(map, "exempt-clients", &obj);
02081 if (result == ISC_R_SUCCESS) {
02082 result = cfg_acl_fromconfig(obj, config, ns_g_lctx,
02083 ns_g_aclconfctx, ns_g_mctx,
02084 0, &rrl->exempt);
02085 CHECK_RRL(result == ISC_R_SUCCESS,
02086 "invalid %s%s", "address match list", "");
02087 }
02088
02089 obj = NULL;
02090 result = cfg_map_get(map, "log-only", &obj);
02091 if (result == ISC_R_SUCCESS && cfg_obj_asboolean(obj))
02092 rrl->log_only = ISC_TRUE;
02093 else
02094 rrl->log_only = ISC_FALSE;
02095
02096 return (ISC_R_SUCCESS);
02097
02098 cleanup:
02099 dns_rrl_view_destroy(view);
02100 return (result);
02101 }
02102
02103 static isc_result_t
02104 add_soa(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
02105 dns_name_t *origin, dns_name_t *contact)
02106 {
02107 dns_dbnode_t *node = NULL;
02108 dns_rdata_t rdata = DNS_RDATA_INIT;
02109 dns_rdatalist_t rdatalist;
02110 dns_rdataset_t rdataset;
02111 isc_result_t result;
02112 unsigned char buf[DNS_SOA_BUFFERSIZE];
02113
02114 CHECK(dns_soa_buildrdata(origin, contact, dns_db_class(db),
02115 0, 28800, 7200, 604800, 86400, buf, &rdata));
02116
02117 dns_rdatalist_init(&rdatalist);
02118 rdatalist.type = rdata.type;
02119 rdatalist.rdclass = rdata.rdclass;
02120 rdatalist.ttl = 86400;
02121 ISC_LIST_APPEND(rdatalist.rdata, &rdata, link);
02122
02123 dns_rdataset_init(&rdataset);
02124 CHECK(dns_rdatalist_tordataset(&rdatalist, &rdataset));
02125 CHECK(dns_db_findnode(db, name, ISC_TRUE, &node));
02126 CHECK(dns_db_addrdataset(db, node, version, 0, &rdataset, 0, NULL));
02127
02128 cleanup:
02129 if (node != NULL)
02130 dns_db_detachnode(db, &node);
02131 return (result);
02132 }
02133
02134 static isc_result_t
02135 add_ns(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
02136 dns_name_t *nsname)
02137 {
02138 dns_dbnode_t *node = NULL;
02139 dns_rdata_ns_t ns;
02140 dns_rdata_t rdata = DNS_RDATA_INIT;
02141 dns_rdatalist_t rdatalist;
02142 dns_rdataset_t rdataset;
02143 isc_result_t result;
02144 isc_buffer_t b;
02145 unsigned char buf[DNS_NAME_MAXWIRE];
02146
02147 isc_buffer_init(&b, buf, sizeof(buf));
02148
02149 ns.common.rdtype = dns_rdatatype_ns;
02150 ns.common.rdclass = dns_db_class(db);
02151 ns.mctx = NULL;
02152 dns_name_init(&ns.name, NULL);
02153 dns_name_clone(nsname, &ns.name);
02154 CHECK(dns_rdata_fromstruct(&rdata, dns_db_class(db), dns_rdatatype_ns,
02155 &ns, &b));
02156
02157 dns_rdatalist_init(&rdatalist);
02158 rdatalist.type = rdata.type;
02159 rdatalist.rdclass = rdata.rdclass;
02160 rdatalist.ttl = 86400;
02161 ISC_LIST_APPEND(rdatalist.rdata, &rdata, link);
02162
02163 dns_rdataset_init(&rdataset);
02164 CHECK(dns_rdatalist_tordataset(&rdatalist, &rdataset));
02165 CHECK(dns_db_findnode(db, name, ISC_TRUE, &node));
02166 CHECK(dns_db_addrdataset(db, node, version, 0, &rdataset, 0, NULL));
02167
02168 cleanup:
02169 if (node != NULL)
02170 dns_db_detachnode(db, &node);
02171 return (result);
02172 }
02173
02174 static isc_result_t
02175 create_empty_zone(dns_zone_t *zone, dns_name_t *name, dns_view_t *view,
02176 const cfg_obj_t *zonelist, const char **empty_dbtype,
02177 int empty_dbtypec, dns_zonestat_level_t statlevel)
02178 {
02179 char namebuf[DNS_NAME_FORMATSIZE];
02180 const cfg_listelt_t *element;
02181 const cfg_obj_t *obj;
02182 const cfg_obj_t *zconfig;
02183 const cfg_obj_t *zoptions;
02184 const char *rbt_dbtype[4] = { "rbt" };
02185 const char *sep = ": view ";
02186 const char *str;
02187 const char *viewname = view->name;
02188 dns_db_t *db = NULL;
02189 dns_dbversion_t *version = NULL;
02190 dns_fixedname_t cfixed;
02191 dns_fixedname_t fixed;
02192 dns_fixedname_t nsfixed;
02193 dns_name_t *contact;
02194 dns_name_t *ns;
02195 dns_name_t *zname;
02196 dns_zone_t *myzone = NULL;
02197 int rbt_dbtypec = 1;
02198 isc_result_t result;
02199 dns_namereln_t namereln;
02200 int order;
02201 unsigned int nlabels;
02202
02203 dns_fixedname_init(&fixed);
02204 zname = dns_fixedname_name(&fixed);
02205 dns_fixedname_init(&nsfixed);
02206 ns = dns_fixedname_name(&nsfixed);
02207 dns_fixedname_init(&cfixed);
02208 contact = dns_fixedname_name(&cfixed);
02209
02210
02211
02212
02213
02214 for (element = cfg_list_first(zonelist);
02215 element != NULL;
02216 element = cfg_list_next(element)) {
02217
02218 zconfig = cfg_listelt_value(element);
02219 str = cfg_obj_asstring(cfg_tuple_get(zconfig, "name"));
02220 CHECK(dns_name_fromstring(zname, str, 0, NULL));
02221 namereln = dns_name_fullcompare(zname, name, &order, &nlabels);
02222 if (namereln != dns_namereln_subdomain)
02223 continue;
02224
02225 zoptions = cfg_tuple_get(zconfig, "options");
02226
02227 obj = NULL;
02228 (void)cfg_map_get(zoptions, "type", &obj);
02229 if (obj != NULL &&
02230 strcasecmp(cfg_obj_asstring(obj), "forward") == 0) {
02231 obj = NULL;
02232 (void)cfg_map_get(zoptions, "forward", &obj);
02233 if (obj == NULL)
02234 continue;
02235 if (strcasecmp(cfg_obj_asstring(obj), "only") != 0)
02236 continue;
02237 }
02238 if (db == NULL) {
02239 CHECK(dns_db_create(view->mctx, "rbt", name,
02240 dns_dbtype_zone, view->rdclass,
02241 0, NULL, &db));
02242 CHECK(dns_db_newversion(db, &version));
02243 if (strcmp(empty_dbtype[2], "@") == 0)
02244 dns_name_clone(name, ns);
02245 else
02246 CHECK(dns_name_fromstring(ns, empty_dbtype[2],
02247 0, NULL));
02248 CHECK(dns_name_fromstring(contact, empty_dbtype[3],
02249 0, NULL));
02250 CHECK(add_soa(db, version, name, ns, contact));
02251 CHECK(add_ns(db, version, name, ns));
02252 }
02253 CHECK(add_ns(db, version, zname, dns_rootname));
02254 }
02255
02256
02257
02258
02259 if (zone != NULL) {
02260 unsigned int typec;
02261 const char **dbargv;
02262
02263 if (db != NULL) {
02264 typec = rbt_dbtypec;
02265 dbargv = rbt_dbtype;
02266 } else {
02267 typec = empty_dbtypec;
02268 dbargv = empty_dbtype;
02269 }
02270
02271 result = check_dbtype(zone, typec, dbargv, view->mctx);
02272 if (result != ISC_R_SUCCESS)
02273 zone = NULL;
02274
02275 if (zone != NULL && dns_zone_gettype(zone) != dns_zone_master)
02276 zone = NULL;
02277 if (zone != NULL && dns_zone_getfile(zone) != NULL)
02278 zone = NULL;
02279 if (zone != NULL) {
02280 dns_zone_getraw(zone, &myzone);
02281 if (myzone != NULL) {
02282 dns_zone_detach(&myzone);
02283 zone = NULL;
02284 }
02285 }
02286 }
02287
02288 if (zone == NULL) {
02289 CHECK(dns_zonemgr_createzone(ns_g_server->zonemgr, &myzone));
02290 zone = myzone;
02291 CHECK(dns_zone_setorigin(zone, name));
02292 CHECK(dns_zonemgr_managezone(ns_g_server->zonemgr, zone));
02293 if (db == NULL)
02294 CHECK(dns_zone_setdbtype(zone, empty_dbtypec,
02295 empty_dbtype));
02296 dns_zone_setclass(zone, view->rdclass);
02297 dns_zone_settype(zone, dns_zone_master);
02298 dns_zone_setstats(zone, ns_g_server->zonestats);
02299 }
02300
02301 dns_zone_setoption(zone, ~DNS_ZONEOPT_NOCHECKNS, ISC_FALSE);
02302 dns_zone_setoption(zone, DNS_ZONEOPT_NOCHECKNS, ISC_TRUE);
02303 dns_zone_setnotifytype(zone, dns_notifytype_no);
02304 dns_zone_setdialup(zone, dns_dialuptype_no);
02305 dns_zone_setautomatic(zone, ISC_TRUE);
02306 if (view->queryacl != NULL)
02307 dns_zone_setqueryacl(zone, view->queryacl);
02308 else
02309 dns_zone_clearqueryacl(zone);
02310 if (view->queryonacl != NULL)
02311 dns_zone_setqueryonacl(zone, view->queryonacl);
02312 else
02313 dns_zone_clearqueryonacl(zone);
02314 dns_zone_clearupdateacl(zone);
02315 if (view->transferacl != NULL)
02316 dns_zone_setxfracl(zone, view->transferacl);
02317 else
02318 dns_zone_clearxfracl(zone);
02319
02320 CHECK(setquerystats(zone, view->mctx, statlevel));
02321 if (db != NULL) {
02322 dns_db_closeversion(db, &version, ISC_TRUE);
02323 CHECK(dns_zone_replacedb(zone, db, ISC_FALSE));
02324 }
02325 dns_zone_setview(zone, view);
02326 CHECK(dns_view_addzone(view, zone));
02327
02328 if (!strcmp(viewname, "_default")) {
02329 sep = "";
02330 viewname = "";
02331 }
02332 dns_name_format(name, namebuf, sizeof(namebuf));
02333 isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER,
02334 ISC_LOG_INFO, "automatic empty zone%s%s: %s",
02335 sep, viewname, namebuf);
02336
02337 cleanup:
02338 if (myzone != NULL)
02339 dns_zone_detach(&myzone);
02340 if (version != NULL)
02341 dns_db_closeversion(db, &version, ISC_FALSE);
02342 if (db != NULL)
02343 dns_db_detach(&db);
02344
02345 INSIST(version == NULL);
02346
02347 return (result);
02348 }
02349
02350
02351
02352
02353
02354
02355
02356
02357 static isc_result_t
02358 configure_view(dns_view_t *view, dns_viewlist_t *viewlist,
02359 cfg_obj_t *config, cfg_obj_t *vconfig,
02360 ns_cachelist_t *cachelist, const cfg_obj_t *bindkeys,
02361 isc_mem_t *mctx, cfg_aclconfctx_t *actx,
02362 isc_boolean_t need_hints)
02363 {
02364 const cfg_obj_t *maps[4];
02365 const cfg_obj_t *cfgmaps[3];
02366 const cfg_obj_t *optionmaps[3];
02367 const cfg_obj_t *options = NULL;
02368 const cfg_obj_t *voptions = NULL;
02369 const cfg_obj_t *forwardtype;
02370 const cfg_obj_t *forwarders;
02371 const cfg_obj_t *alternates;
02372 const cfg_obj_t *zonelist;
02373 const cfg_obj_t *dlzlist;
02374 const cfg_obj_t *dlz;
02375 unsigned int dlzargc;
02376 char **dlzargv;
02377 const cfg_obj_t *disabled;
02378 const cfg_obj_t *obj;
02379 const cfg_listelt_t *element;
02380 in_port_t port;
02381 dns_cache_t *cache = NULL;
02382 isc_result_t result;
02383 unsigned int cleaning_interval;
02384 size_t max_cache_size;
02385 size_t max_acache_size;
02386 size_t max_adb_size;
02387 isc_uint32_t lame_ttl, fail_ttl;
02388 dns_tsig_keyring_t *ring = NULL;
02389 dns_view_t *pview = NULL;
02390 isc_mem_t *cmctx = NULL, *hmctx = NULL;
02391 dns_dispatch_t *dispatch4 = NULL;
02392 dns_dispatch_t *dispatch6 = NULL;
02393 isc_boolean_t reused_cache = ISC_FALSE;
02394 isc_boolean_t shared_cache = ISC_FALSE;
02395 int i = 0, j = 0, k = 0;
02396 const char *str;
02397 const char *cachename = NULL;
02398 dns_order_t *order = NULL;
02399 isc_uint32_t udpsize;
02400 isc_uint32_t maxbits;
02401 unsigned int resopts = 0;
02402 dns_zone_t *zone = NULL;
02403 isc_uint32_t max_clients_per_query;
02404 isc_boolean_t empty_zones_enable;
02405 const cfg_obj_t *disablelist = NULL;
02406 isc_stats_t *resstats = NULL;
02407 dns_stats_t *resquerystats = NULL;
02408 isc_boolean_t auto_dlv = ISC_FALSE;
02409 isc_boolean_t auto_root = ISC_FALSE;
02410 ns_cache_t *nsc;
02411 isc_boolean_t zero_no_soattl;
02412 dns_acl_t *clients = NULL, *mapped = NULL, *excluded = NULL;
02413 unsigned int query_timeout, ndisp;
02414 ns_cfgctx_t *nzctx;
02415 isc_boolean_t old_rpz_ok = ISC_FALSE;
02416 isc_dscp_t dscp4 = -1, dscp6 = -1;
02417
02418 REQUIRE(DNS_VIEW_VALID(view));
02419
02420 if (config != NULL)
02421 (void)cfg_map_get(config, "options", &options);
02422
02423
02424
02425
02426
02427
02428 if (vconfig != NULL) {
02429 voptions = cfg_tuple_get(vconfig, "options");
02430 maps[i++] = voptions;
02431 optionmaps[j++] = voptions;
02432 cfgmaps[k++] = voptions;
02433 }
02434 if (options != NULL) {
02435 maps[i++] = options;
02436 optionmaps[j++] = options;
02437 }
02438
02439 maps[i++] = ns_g_defaults;
02440 maps[i] = NULL;
02441 optionmaps[j] = NULL;
02442 if (config != NULL)
02443 cfgmaps[k++] = config;
02444 cfgmaps[k] = NULL;
02445
02446
02447
02448
02449 CHECKM(ns_config_getport(config, &port), "port");
02450 dns_view_setdstport(view, port);
02451
02452
02453
02454
02455
02456
02457 obj = NULL;
02458 (void)ns_config_get(maps, "acache-enable", &obj);
02459 if (obj != NULL && cfg_obj_asboolean(obj)) {
02460 cmctx = NULL;
02461 CHECK(isc_mem_create(0, 0, &cmctx));
02462 CHECK(dns_acache_create(&view->acache, cmctx, ns_g_taskmgr,
02463 ns_g_timermgr));
02464 isc_mem_setname(cmctx, "acache", NULL);
02465 isc_mem_detach(&cmctx);
02466 }
02467 if (view->acache != NULL) {
02468 obj = NULL;
02469 result = ns_config_get(maps, "acache-cleaning-interval", &obj);
02470 INSIST(result == ISC_R_SUCCESS);
02471 dns_acache_setcleaninginterval(view->acache,
02472 cfg_obj_asuint32(obj) * 60);
02473
02474 obj = NULL;
02475 result = ns_config_get(maps, "max-acache-size", &obj);
02476 INSIST(result == ISC_R_SUCCESS);
02477 if (cfg_obj_isstring(obj)) {
02478 str = cfg_obj_asstring(obj);
02479 INSIST(strcasecmp(str, "unlimited") == 0);
02480 max_acache_size = 0;
02481 } else {
02482 isc_resourcevalue_t value;
02483 value = cfg_obj_asuint64(obj);
02484 if (value > SIZE_MAX) {
02485 cfg_obj_log(obj, ns_g_lctx,
02486 ISC_LOG_WARNING,
02487 "'max-acache-size "
02488 "%" ISC_PRINT_QUADFORMAT "u' "
02489 "is too large for this "
02490 "system; reducing to %lu",
02491 value, (unsigned long)SIZE_MAX);
02492 value = SIZE_MAX;
02493 }
02494 max_acache_size = (size_t) value;
02495 }
02496 dns_acache_setcachesize(view->acache, max_acache_size);
02497 }
02498
02499 CHECK(configure_view_acl(vconfig, config, "allow-query", NULL, actx,
02500 ns_g_mctx, &view->queryacl));
02501 if (view->queryacl == NULL) {
02502 CHECK(configure_view_acl(NULL, ns_g_config, "allow-query",
02503 NULL, actx, ns_g_mctx,
02504 &view->queryacl));
02505 }
02506
02507
02508
02509
02510
02511 obj = NULL;
02512 if (view->rdclass == dns_rdataclass_in && need_hints &&
02513 ns_config_get(maps, "response-policy", &obj) == ISC_R_SUCCESS) {
02514 CHECK(configure_rpz(view, obj, &old_rpz_ok));
02515 }
02516
02517
02518
02519
02520 zonelist = NULL;
02521 if (voptions != NULL)
02522 (void)cfg_map_get(voptions, "zone", &zonelist);
02523 else
02524 (void)cfg_map_get(config, "zone", &zonelist);
02525
02526
02527
02528
02529 for (element = cfg_list_first(zonelist);
02530 element != NULL;
02531 element = cfg_list_next(element))
02532 {
02533 const cfg_obj_t *zconfig = cfg_listelt_value(element);
02534 CHECK(configure_zone(config, zconfig, vconfig, mctx, view,
02535 viewlist, actx, ISC_FALSE, old_rpz_ok,
02536 ISC_FALSE));
02537 }
02538
02539
02540
02541
02542
02543 if (view->rpzs != NULL) {
02544 dns_rpz_num_t n;
02545
02546 for (n = 0; n < view->rpzs->p.num_zones; ++n)
02547 {
02548 if ((view->rpzs->defined & DNS_RPZ_ZBIT(n)) == 0) {
02549 char namebuf[DNS_NAME_FORMATSIZE];
02550
02551 dns_name_format(&view->rpzs->zones[n]->origin,
02552 namebuf, sizeof(namebuf));
02553 cfg_obj_log(obj, ns_g_lctx, DNS_RPZ_ERROR_LEVEL,
02554 "'%s' is not a master or slave zone",
02555 namebuf);
02556 result = ISC_R_NOTFOUND;
02557 goto cleanup;
02558 }
02559 }
02560 }
02561
02562
02563
02564
02565
02566
02567 nzctx = view->new_zone_config;
02568 if (nzctx != NULL && nzctx->nzconfig != NULL) {
02569 isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
02570 NS_LOGMODULE_SERVER, ISC_LOG_INFO,
02571 "loading additional zones for view '%s'",
02572 view->name);
02573
02574 zonelist = NULL;
02575 cfg_map_get(nzctx->nzconfig, "zone", &zonelist);
02576
02577 for (element = cfg_list_first(zonelist);
02578 element != NULL;
02579 element = cfg_list_next(element))
02580 {
02581 const cfg_obj_t *zconfig = cfg_listelt_value(element);
02582 CHECK(configure_zone(config, zconfig, vconfig,
02583 mctx, view, NULL, actx,
02584 ISC_TRUE, ISC_FALSE, ISC_FALSE));
02585 }
02586 }
02587
02588
02589
02590
02591 dlzlist = NULL;
02592 if (voptions != NULL)
02593 (void)cfg_map_get(voptions, "dlz", &dlzlist);
02594 else
02595 (void)cfg_map_get(config, "dlz", &dlzlist);
02596
02597 for (element = cfg_list_first(dlzlist);
02598 element != NULL;
02599 element = cfg_list_next(element))
02600 {
02601 dlz = cfg_listelt_value(element);
02602
02603 obj = NULL;
02604 (void)cfg_map_get(dlz, "database", &obj);
02605 if (obj != NULL) {
02606 dns_dlzdb_t *dlzdb = NULL;
02607 const cfg_obj_t *name, *search = NULL;
02608 char *s = isc_mem_strdup(mctx, cfg_obj_asstring(obj));
02609
02610 if (s == NULL) {
02611 result = ISC_R_NOMEMORY;
02612 goto cleanup;
02613 }
02614
02615 result = dns_dlzstrtoargv(mctx, s, &dlzargc, &dlzargv);
02616 if (result != ISC_R_SUCCESS) {
02617 isc_mem_free(mctx, s);
02618 goto cleanup;
02619 }
02620
02621 name = cfg_map_getname(dlz);
02622 result = dns_dlzcreate(mctx, cfg_obj_asstring(name),
02623 dlzargv[0], dlzargc, dlzargv,
02624 &dlzdb);
02625 isc_mem_free(mctx, s);
02626 isc_mem_put(mctx, dlzargv, dlzargc * sizeof(*dlzargv));
02627 if (result != ISC_R_SUCCESS)
02628 goto cleanup;
02629
02630
02631
02632
02633
02634
02635
02636 (void)cfg_map_get(dlz, "search", &search);
02637 if (search == NULL || cfg_obj_asboolean(search)) {
02638 dlzdb->search = ISC_TRUE;
02639 result = dns_dlzconfigure(view, dlzdb,
02640 dlzconfigure_callback);
02641 if (result != ISC_R_SUCCESS)
02642 goto cleanup;
02643 ISC_LIST_APPEND(view->dlz_searched,
02644 dlzdb, link);
02645 } else {
02646 dlzdb->search = ISC_FALSE;
02647 ISC_LIST_APPEND(view->dlz_unsearched,
02648 dlzdb, link);
02649 }
02650
02651 }
02652 }
02653
02654
02655
02656
02657
02658 obj = NULL;
02659 result = ns_config_get(maps, "cleaning-interval", &obj);
02660 INSIST(result == ISC_R_SUCCESS);
02661 cleaning_interval = cfg_obj_asuint32(obj) * 60;
02662
02663 obj = NULL;
02664 result = ns_config_get(maps, "max-cache-size", &obj);
02665 INSIST(result == ISC_R_SUCCESS);
02666 if (cfg_obj_isstring(obj)) {
02667 str = cfg_obj_asstring(obj);
02668 INSIST(strcasecmp(str, "unlimited") == 0);
02669 max_cache_size = 0;
02670 } else {
02671 isc_resourcevalue_t value;
02672 value = cfg_obj_asuint64(obj);
02673 if (value > SIZE_MAX) {
02674 cfg_obj_log(obj, ns_g_lctx,
02675 ISC_LOG_WARNING,
02676 "'max-cache-size "
02677 "%" ISC_PRINT_QUADFORMAT "u' "
02678 "is too large for this "
02679 "system; reducing to %lu",
02680 value, (unsigned long)SIZE_MAX);
02681 value = SIZE_MAX;
02682 }
02683 max_cache_size = (size_t) value;
02684 }
02685
02686
02687 obj = NULL;
02688 result = ns_checknames_get(maps, "response", &obj);
02689 INSIST(result == ISC_R_SUCCESS);
02690
02691 str = cfg_obj_asstring(obj);
02692 if (strcasecmp(str, "fail") == 0) {
02693 resopts |= DNS_RESOLVER_CHECKNAMES |
02694 DNS_RESOLVER_CHECKNAMESFAIL;
02695 view->checknames = ISC_TRUE;
02696 } else if (strcasecmp(str, "warn") == 0) {
02697 resopts |= DNS_RESOLVER_CHECKNAMES;
02698 view->checknames = ISC_FALSE;
02699 } else if (strcasecmp(str, "ignore") == 0) {
02700 view->checknames = ISC_FALSE;
02701 } else
02702 INSIST(0);
02703
02704 obj = NULL;
02705 result = ns_config_get(maps, "zero-no-soa-ttl-cache", &obj);
02706 INSIST(result == ISC_R_SUCCESS);
02707 zero_no_soattl = cfg_obj_asboolean(obj);
02708
02709 obj = NULL;
02710 result = ns_config_get(maps, "dns64", &obj);
02711 if (result == ISC_R_SUCCESS && strcmp(view->name, "_bind") &&
02712 strcmp(view->name, "_meta")) {
02713 isc_netaddr_t na, suffix, *sp;
02714 unsigned int prefixlen;
02715 const char *server, *contact;
02716 const cfg_obj_t *myobj;
02717
02718 myobj = NULL;
02719 result = ns_config_get(maps, "dns64-server", &myobj);
02720 if (result == ISC_R_SUCCESS)
02721 server = cfg_obj_asstring(myobj);
02722 else
02723 server = NULL;
02724
02725 myobj = NULL;
02726 result = ns_config_get(maps, "dns64-contact", &myobj);
02727 if (result == ISC_R_SUCCESS)
02728 contact = cfg_obj_asstring(myobj);
02729 else
02730 contact = NULL;
02731
02732 for (element = cfg_list_first(obj);
02733 element != NULL;
02734 element = cfg_list_next(element))
02735 {
02736 const cfg_obj_t *map = cfg_listelt_value(element);
02737 dns_dns64_t *dns64 = NULL;
02738 unsigned int dns64options = 0;
02739
02740 cfg_obj_asnetprefix(cfg_map_getname(map), &na,
02741 &prefixlen);
02742
02743 obj = NULL;
02744 (void)cfg_map_get(map, "suffix", &obj);
02745 if (obj != NULL) {
02746 sp = &suffix;
02747 isc_netaddr_fromsockaddr(sp,
02748 cfg_obj_assockaddr(obj));
02749 } else
02750 sp = NULL;
02751
02752 clients = mapped = excluded = NULL;
02753 obj = NULL;
02754 (void)cfg_map_get(map, "clients", &obj);
02755 if (obj != NULL) {
02756 result = cfg_acl_fromconfig(obj, config,
02757 ns_g_lctx, actx,
02758 mctx, 0, &clients);
02759 if (result != ISC_R_SUCCESS)
02760 goto cleanup;
02761 }
02762 obj = NULL;
02763 (void)cfg_map_get(map, "mapped", &obj);
02764 if (obj != NULL) {
02765 result = cfg_acl_fromconfig(obj, config,
02766 ns_g_lctx, actx,
02767 mctx, 0, &mapped);
02768 if (result != ISC_R_SUCCESS)
02769 goto cleanup;
02770 }
02771 obj = NULL;
02772 (void)cfg_map_get(map, "exclude", &obj);
02773 if (obj != NULL) {
02774 result = cfg_acl_fromconfig(obj, config,
02775 ns_g_lctx, actx,
02776 mctx, 0, &excluded);
02777 if (result != ISC_R_SUCCESS)
02778 goto cleanup;
02779 }
02780
02781 obj = NULL;
02782 (void)cfg_map_get(map, "recursive-only", &obj);
02783 if (obj != NULL && cfg_obj_asboolean(obj))
02784 dns64options |= DNS_DNS64_RECURSIVE_ONLY;
02785
02786 obj = NULL;
02787 (void)cfg_map_get(map, "break-dnssec", &obj);
02788 if (obj != NULL && cfg_obj_asboolean(obj))
02789 dns64options |= DNS_DNS64_BREAK_DNSSEC;
02790
02791 result = dns_dns64_create(mctx, &na, prefixlen, sp,
02792 clients, mapped, excluded,
02793 dns64options, &dns64);
02794 if (result != ISC_R_SUCCESS)
02795 goto cleanup;
02796 dns_dns64_append(&view->dns64, dns64);
02797 view->dns64cnt++;
02798 result = dns64_reverse(view, mctx, &na, prefixlen,
02799 server, contact);
02800 if (result != ISC_R_SUCCESS)
02801 goto cleanup;
02802 if (clients != NULL)
02803 dns_acl_detach(&clients);
02804 if (mapped != NULL)
02805 dns_acl_detach(&mapped);
02806 if (excluded != NULL)
02807 dns_acl_detach(&excluded);
02808 }
02809 }
02810
02811 obj = NULL;
02812 result = ns_config_get(maps, "dnssec-accept-expired", &obj);
02813 INSIST(result == ISC_R_SUCCESS);
02814 view->acceptexpired = cfg_obj_asboolean(obj);
02815
02816 obj = NULL;
02817 result = ns_config_get(maps, "dnssec-validation", &obj);
02818 INSIST(result == ISC_R_SUCCESS);
02819 if (cfg_obj_isboolean(obj)) {
02820 view->enablevalidation = cfg_obj_asboolean(obj);
02821 } else {
02822
02823 view->enablevalidation = ISC_TRUE;
02824 auto_root = ISC_TRUE;
02825 }
02826
02827 obj = NULL;
02828 result = ns_config_get(maps, "max-cache-ttl", &obj);
02829 INSIST(result == ISC_R_SUCCESS);
02830 view->maxcachettl = cfg_obj_asuint32(obj);
02831
02832 obj = NULL;
02833 result = ns_config_get(maps, "max-ncache-ttl", &obj);
02834 INSIST(result == ISC_R_SUCCESS);
02835 view->maxncachettl = cfg_obj_asuint32(obj);
02836 if (view->maxncachettl > 7 * 24 * 3600)
02837 view->maxncachettl = 7 * 24 * 3600;
02838
02839
02840
02841
02842
02843
02844
02845
02846
02847
02848
02849
02850
02851
02852
02853
02854
02855
02856
02857
02858
02859
02860
02861
02862 obj = NULL;
02863 result = ns_config_get(maps, "attach-cache", &obj);
02864 if (result == ISC_R_SUCCESS)
02865 cachename = cfg_obj_asstring(obj);
02866 else
02867 cachename = view->name;
02868 cache = NULL;
02869 nsc = cachelist_find(cachelist, cachename);
02870 if (nsc != NULL) {
02871 if (!cache_sharable(nsc->primaryview, view, zero_no_soattl,
02872 cleaning_interval, max_cache_size)) {
02873 isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
02874 NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
02875 "views %s and %s can't share the cache "
02876 "due to configuration parameter mismatch",
02877 nsc->primaryview->name, view->name);
02878 result = ISC_R_FAILURE;
02879 goto cleanup;
02880 }
02881 dns_cache_attach(nsc->cache, &cache);
02882 shared_cache = ISC_TRUE;
02883 } else {
02884 if (strcmp(cachename, view->name) == 0) {
02885 result = dns_viewlist_find(&ns_g_server->viewlist,
02886 cachename, view->rdclass,
02887 &pview);
02888 if (result != ISC_R_NOTFOUND && result != ISC_R_SUCCESS)
02889 goto cleanup;
02890 if (pview != NULL) {
02891 if (!cache_reusable(pview, view,
02892 zero_no_soattl)) {
02893 isc_log_write(ns_g_lctx,
02894 NS_LOGCATEGORY_GENERAL,
02895 NS_LOGMODULE_SERVER,
02896 ISC_LOG_DEBUG(1),
02897 "cache cannot be reused "
02898 "for view %s due to "
02899 "configuration parameter "
02900 "mismatch", view->name);
02901 } else {
02902 INSIST(pview->cache != NULL);
02903 isc_log_write(ns_g_lctx,
02904 NS_LOGCATEGORY_GENERAL,
02905 NS_LOGMODULE_SERVER,
02906 ISC_LOG_DEBUG(3),
02907 "reusing existing cache");
02908 reused_cache = ISC_TRUE;
02909 dns_cache_attach(pview->cache, &cache);
02910 }
02911 dns_view_getresstats(pview, &resstats);
02912 dns_view_getresquerystats(pview,
02913 &resquerystats);
02914 dns_view_detach(&pview);
02915 }
02916 }
02917 if (cache == NULL) {
02918
02919
02920
02921
02922
02923
02924
02925
02926
02927
02928
02929
02930 CHECK(isc_mem_create(0, 0, &cmctx));
02931 isc_mem_setname(cmctx, "cache", NULL);
02932 CHECK(isc_mem_create(0, 0, &hmctx));
02933 isc_mem_setname(hmctx, "cache_heap", NULL);
02934 CHECK(dns_cache_create3(cmctx, hmctx, ns_g_taskmgr,
02935 ns_g_timermgr, view->rdclass,
02936 cachename, "rbt", 0, NULL,
02937 &cache));
02938 isc_mem_detach(&cmctx);
02939 isc_mem_detach(&hmctx);
02940 }
02941 nsc = isc_mem_get(mctx, sizeof(*nsc));
02942 if (nsc == NULL) {
02943 result = ISC_R_NOMEMORY;
02944 goto cleanup;
02945 }
02946 nsc->cache = NULL;
02947 dns_cache_attach(cache, &nsc->cache);
02948 nsc->primaryview = view;
02949 nsc->needflush = ISC_FALSE;
02950 nsc->adbsizeadjusted = ISC_FALSE;
02951 ISC_LINK_INIT(nsc, link);
02952 ISC_LIST_APPEND(*cachelist, nsc, link);
02953 }
02954 dns_view_setcache2(view, cache, shared_cache);
02955
02956
02957
02958
02959
02960 obj = NULL;
02961 result = ns_config_get(maps, "cache-file", &obj);
02962 if (result == ISC_R_SUCCESS && strcmp(view->name, "_bind") != 0) {
02963 CHECK(dns_cache_setfilename(cache, cfg_obj_asstring(obj)));
02964 if (!reused_cache && !shared_cache)
02965 CHECK(dns_cache_load(cache));
02966 }
02967
02968 dns_cache_setcleaninginterval(cache, cleaning_interval);
02969 dns_cache_setcachesize(cache, max_cache_size);
02970
02971 dns_cache_detach(&cache);
02972
02973
02974
02975
02976
02977
02978 CHECK(get_view_querysource_dispatch(maps, AF_INET, &dispatch4, &dscp4,
02979 ISC_TF(ISC_LIST_PREV(view, link)
02980 == NULL)));
02981 CHECK(get_view_querysource_dispatch(maps, AF_INET6, &dispatch6, &dscp6,
02982 ISC_TF(ISC_LIST_PREV(view, link)
02983 == NULL)));
02984 if (dispatch4 == NULL && dispatch6 == NULL) {
02985 UNEXPECTED_ERROR(__FILE__, __LINE__,
02986 "unable to obtain neither an IPv4 nor"
02987 " an IPv6 dispatch");
02988 result = ISC_R_UNEXPECTED;
02989 goto cleanup;
02990 }
02991
02992 if (resstats == NULL) {
02993 CHECK(isc_stats_create(mctx, &resstats,
02994 dns_resstatscounter_max));
02995 }
02996 dns_view_setresstats(view, resstats);
02997 if (resquerystats == NULL)
02998 CHECK(dns_rdatatypestats_create(mctx, &resquerystats));
02999 dns_view_setresquerystats(view, resquerystats);
03000
03001 ndisp = 4 * ISC_MIN(ns_g_udpdisp, MAX_UDP_DISPATCH);
03002 CHECK(dns_view_createresolver(view, ns_g_taskmgr, RESOLVER_NTASKS,
03003 ndisp, ns_g_socketmgr, ns_g_timermgr,
03004 resopts, ns_g_dispatchmgr,
03005 dispatch4, dispatch6));
03006
03007 if (dscp4 == -1)
03008 dscp4 = ns_g_dscp;
03009 if (dscp6 == -1)
03010 dscp6 = ns_g_dscp;
03011 if (dscp4 != -1)
03012 dns_resolver_setquerydscp4(view->resolver, dscp4);
03013 if (dscp6 != -1)
03014 dns_resolver_setquerydscp6(view->resolver, dscp6);
03015
03016
03017
03018
03019
03020 max_adb_size = 0;
03021 if (max_cache_size != 0U) {
03022 max_adb_size = max_cache_size / 8;
03023 if (max_adb_size == 0U)
03024 max_adb_size = 1;
03025 if (view != nsc->primaryview &&
03026 max_adb_size > MAX_ADB_SIZE_FOR_CACHESHARE) {
03027 max_adb_size = MAX_ADB_SIZE_FOR_CACHESHARE;
03028 if (!nsc->adbsizeadjusted) {
03029 dns_adb_setadbsize(nsc->primaryview->adb,
03030 MAX_ADB_SIZE_FOR_CACHESHARE);
03031 nsc->adbsizeadjusted = ISC_TRUE;
03032 }
03033 }
03034 }
03035 dns_adb_setadbsize(view->adb, max_adb_size);
03036
03037
03038
03039
03040 obj = NULL;
03041 result = ns_config_get(maps, "lame-ttl", &obj);
03042 INSIST(result == ISC_R_SUCCESS);
03043 lame_ttl = cfg_obj_asuint32(obj);
03044 if (lame_ttl > 1800)
03045 lame_ttl = 1800;
03046 dns_resolver_setlamettl(view->resolver, lame_ttl);
03047
03048
03049
03050
03051 obj = NULL;
03052 result = ns_config_get(maps, "resolver-query-timeout", &obj);
03053 INSIST(result == ISC_R_SUCCESS);
03054 query_timeout = cfg_obj_asuint32(obj);
03055 dns_resolver_settimeout(view->resolver, query_timeout);
03056
03057
03058 dns_resolver_setzeronosoattl(view->resolver, zero_no_soattl);
03059
03060
03061
03062
03063 obj = NULL;
03064 result = ns_config_get(maps, "edns-udp-size", &obj);
03065 INSIST(result == ISC_R_SUCCESS);
03066 udpsize = cfg_obj_asuint32(obj);
03067 if (udpsize < 512)
03068 udpsize = 512;
03069 if (udpsize > 4096)
03070 udpsize = 4096;
03071 dns_resolver_setudpsize(view->resolver, (isc_uint16_t)udpsize);
03072
03073
03074
03075
03076 obj = NULL;
03077 result = ns_config_get(maps, "max-udp-size", &obj);
03078 INSIST(result == ISC_R_SUCCESS);
03079 udpsize = cfg_obj_asuint32(obj);
03080 if (udpsize < 512)
03081 udpsize = 512;
03082 if (udpsize > 4096)
03083 udpsize = 4096;
03084 view->maxudp = udpsize;
03085
03086 #ifdef ISC_PLATFORM_USESIT
03087
03088
03089
03090 obj = NULL;
03091 result = ns_config_get(maps, "nosit-udp-size", &obj);
03092 INSIST(result == ISC_R_SUCCESS);
03093 udpsize = cfg_obj_asuint32(obj);
03094 if (udpsize < 128)
03095 udpsize = 128;
03096 if (udpsize > view->maxudp)
03097 udpsize = view->maxudp;
03098 view->situdp = udpsize;
03099 #endif
03100
03101
03102
03103
03104 obj = NULL;
03105 result = ns_config_get(maps, "max-rsa-exponent-size", &obj);
03106 INSIST(result == ISC_R_SUCCESS);
03107 maxbits = cfg_obj_asuint32(obj);
03108 if (maxbits != 0 && maxbits < 35)
03109 maxbits = 35;
03110 if (maxbits > 4096)
03111 maxbits = 4096;
03112 view->maxbits = maxbits;
03113
03114
03115
03116
03117 dns_resolver_reset_algorithms(view->resolver);
03118 disabled = NULL;
03119 (void)ns_config_get(maps, "disable-algorithms", &disabled);
03120 if (disabled != NULL) {
03121 for (element = cfg_list_first(disabled);
03122 element != NULL;
03123 element = cfg_list_next(element))
03124 CHECK(disable_algorithms(cfg_listelt_value(element),
03125 view->resolver));
03126 }
03127
03128
03129
03130
03131 dns_resolver_reset_ds_digests(view->resolver);
03132 disabled = NULL;
03133 (void)ns_config_get(maps, "disable-ds-digests", &disabled);
03134 if (disabled != NULL) {
03135 for (element = cfg_list_first(disabled);
03136 element != NULL;
03137 element = cfg_list_next(element))
03138 CHECK(disable_ds_digests(cfg_listelt_value(element),
03139 view->resolver));
03140 }
03141
03142
03143
03144
03145
03146 forwardtype = NULL;
03147 forwarders = NULL;
03148 (void)ns_config_get(maps, "forward", &forwardtype);
03149 (void)ns_config_get(maps, "forwarders", &forwarders);
03150 if (forwarders != NULL)
03151 CHECK(configure_forward(config, view, dns_rootname,
03152 forwarders, forwardtype));
03153
03154
03155
03156
03157 alternates = NULL;
03158 (void)ns_config_get(maps, "dual-stack-servers", &alternates);
03159 if (alternates != NULL)
03160 CHECK(configure_alternates(config, view, alternates));
03161
03162
03163
03164
03165 if (view->rdclass == dns_rdataclass_in && view->hints == NULL)
03166 dns_view_sethints(view, ns_g_server->in_roothints);
03167
03168
03169
03170
03171
03172
03173
03174
03175 if (view->hints == NULL) {
03176 dns_zone_t *rootzone = NULL;
03177 (void)dns_view_findzone(view, dns_rootname, &rootzone);
03178 if (rootzone != NULL) {
03179 dns_zone_detach(&rootzone);
03180 need_hints = ISC_FALSE;
03181 }
03182 if (need_hints)
03183 isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
03184 NS_LOGMODULE_SERVER, ISC_LOG_WARNING,
03185 "no root hints for view '%s'",
03186 view->name);
03187 }
03188
03189
03190
03191
03192 CHECK(ns_tsigkeyring_fromconfig(config, vconfig, view->mctx, &ring));
03193 if (ns_g_server->sessionkey != NULL) {
03194 CHECK(dns_tsigkeyring_add(ring, ns_g_server->session_keyname,
03195 ns_g_server->sessionkey));
03196 }
03197 dns_view_setkeyring(view, ring);
03198 dns_tsigkeyring_detach(&ring);
03199
03200
03201
03202
03203 result = dns_viewlist_find(&ns_g_server->viewlist, view->name,
03204 view->rdclass, &pview);
03205 if (result != ISC_R_NOTFOUND && result != ISC_R_SUCCESS)
03206 goto cleanup;
03207 if (pview != NULL) {
03208 dns_view_getdynamickeyring(pview, &ring);
03209 if (ring != NULL)
03210 dns_view_setdynamickeyring(view, ring);
03211 dns_tsigkeyring_detach(&ring);
03212 dns_view_detach(&pview);
03213 } else
03214 dns_view_restorekeyring(view);
03215
03216
03217
03218
03219 {
03220 const cfg_obj_t *peers = NULL;
03221 dns_peerlist_t *newpeers = NULL;
03222
03223 (void)ns_config_get(cfgmaps, "server", &peers);
03224 CHECK(dns_peerlist_new(mctx, &newpeers));
03225 for (element = cfg_list_first(peers);
03226 element != NULL;
03227 element = cfg_list_next(element))
03228 {
03229 const cfg_obj_t *cpeer = cfg_listelt_value(element);
03230 dns_peer_t *peer;
03231
03232 CHECK(configure_peer(cpeer, mctx, &peer));
03233 dns_peerlist_addpeer(newpeers, peer);
03234 dns_peer_detach(&peer);
03235 }
03236 dns_peerlist_detach(&view->peers);
03237 view->peers = newpeers;
03238 }
03239
03240
03241
03242
03243 {
03244 const cfg_obj_t *rrsetorder = NULL;
03245
03246 (void)ns_config_get(maps, "rrset-order", &rrsetorder);
03247 CHECK(dns_order_create(mctx, &order));
03248 for (element = cfg_list_first(rrsetorder);
03249 element != NULL;
03250 element = cfg_list_next(element))
03251 {
03252 const cfg_obj_t *ent = cfg_listelt_value(element);
03253
03254 CHECK(configure_order(order, ent));
03255 }
03256 if (view->order != NULL)
03257 dns_order_detach(&view->order);
03258 dns_order_attach(order, &view->order);
03259 dns_order_detach(&order);
03260 }
03261
03262
03263
03264 dns_aclenv_copy(&view->aclenv, &ns_g_server->aclenv);
03265
03266
03267
03268
03269 CHECK(configure_view_acl(vconfig, config, "match-clients", NULL, actx,
03270 ns_g_mctx, &view->matchclients));
03271 CHECK(configure_view_acl(vconfig, config, "match-destinations", NULL,
03272 actx, ns_g_mctx, &view->matchdestinations));
03273
03274
03275
03276
03277 obj = NULL;
03278 (void)ns_config_get(maps, "match-recursive-only", &obj);
03279 if (obj != NULL && cfg_obj_asboolean(obj))
03280 view->matchrecursiveonly = ISC_TRUE;
03281 else
03282 view->matchrecursiveonly = ISC_FALSE;
03283
03284
03285
03286
03287 obj = NULL;
03288 result = ns_config_get(maps, "recursion", &obj);
03289 INSIST(result == ISC_R_SUCCESS);
03290 view->recursion = cfg_obj_asboolean(obj);
03291
03292 obj = NULL;
03293 result = ns_config_get(maps, "auth-nxdomain", &obj);
03294 INSIST(result == ISC_R_SUCCESS);
03295 view->auth_nxdomain = cfg_obj_asboolean(obj);
03296
03297 obj = NULL;
03298 result = ns_config_get(maps, "minimal-responses", &obj);
03299 INSIST(result == ISC_R_SUCCESS);
03300 view->minimalresponses = cfg_obj_asboolean(obj);
03301
03302 obj = NULL;
03303 result = ns_config_get(maps, "transfer-format", &obj);
03304 INSIST(result == ISC_R_SUCCESS);
03305 str = cfg_obj_asstring(obj);
03306 if (strcasecmp(str, "many-answers") == 0)
03307 view->transfer_format = dns_many_answers;
03308 else if (strcasecmp(str, "one-answer") == 0)
03309 view->transfer_format = dns_one_answer;
03310 else
03311 INSIST(0);
03312
03313
03314
03315
03316
03317 obj = NULL;
03318 result = ns_config_get(maps, "additional-from-auth", &obj);
03319 INSIST(result == ISC_R_SUCCESS);
03320 view->additionalfromauth = cfg_obj_asboolean(obj);
03321 if (view->recursion && ! view->additionalfromauth) {
03322 cfg_obj_log(obj, ns_g_lctx, ISC_LOG_WARNING,
03323 "'additional-from-auth no' is only supported "
03324 "with 'recursion no'");
03325 view->additionalfromauth = ISC_TRUE;
03326 }
03327
03328 obj = NULL;
03329 result = ns_config_get(maps, "additional-from-cache", &obj);
03330 INSIST(result == ISC_R_SUCCESS);
03331 view->additionalfromcache = cfg_obj_asboolean(obj);
03332 if (view->recursion && ! view->additionalfromcache) {
03333 cfg_obj_log(obj, ns_g_lctx, ISC_LOG_WARNING,
03334 "'additional-from-cache no' is only supported "
03335 "with 'recursion no'");
03336 view->additionalfromcache = ISC_TRUE;
03337 }
03338
03339
03340
03341
03342
03343
03344 CHECK(configure_view_acl(vconfig, config, "allow-query-cache", NULL,
03345 actx, ns_g_mctx, &view->cacheacl));
03346 CHECK(configure_view_acl(vconfig, config, "allow-query-cache-on", NULL,
03347 actx, ns_g_mctx, &view->cacheonacl));
03348 if (view->cacheonacl == NULL)
03349 CHECK(configure_view_acl(NULL, ns_g_config,
03350 "allow-query-cache-on", NULL, actx,
03351 ns_g_mctx, &view->cacheonacl));
03352 if (strcmp(view->name, "_bind") != 0) {
03353 CHECK(configure_view_acl(vconfig, config, "allow-recursion",
03354 NULL, actx, ns_g_mctx,
03355 &view->recursionacl));
03356 CHECK(configure_view_acl(vconfig, config, "allow-recursion-on",
03357 NULL, actx, ns_g_mctx,
03358 &view->recursiononacl));
03359 }
03360
03361
03362
03363
03364
03365
03366
03367 if (view->cacheacl == NULL && view->recursionacl != NULL)
03368 dns_acl_attach(view->recursionacl, &view->cacheacl);
03369
03370
03371
03372
03373
03374
03375 if (view->cacheacl == NULL && view->recursion)
03376 CHECK(configure_view_acl(vconfig, config, "allow-query", NULL,
03377 actx, ns_g_mctx, &view->cacheacl));
03378 if (view->recursion &&
03379 view->recursionacl == NULL && view->cacheacl != NULL)
03380 dns_acl_attach(view->cacheacl, &view->recursionacl);
03381
03382
03383
03384
03385
03386 if (view->recursionacl == NULL && view->recursion)
03387 CHECK(configure_view_acl(NULL, ns_g_config,
03388 "allow-recursion", NULL,
03389 actx, ns_g_mctx,
03390 &view->recursionacl));
03391 if (view->recursiononacl == NULL && view->recursion)
03392 CHECK(configure_view_acl(NULL, ns_g_config,
03393 "allow-recursion-on", NULL,
03394 actx, ns_g_mctx,
03395 &view->recursiononacl));
03396 if (view->cacheacl == NULL) {
03397 if (view->recursion)
03398 CHECK(configure_view_acl(NULL, ns_g_config,
03399 "allow-query-cache", NULL,
03400 actx, ns_g_mctx,
03401 &view->cacheacl));
03402 else
03403 CHECK(dns_acl_none(mctx, &view->cacheacl));
03404 }
03405
03406
03407
03408
03409
03410
03411 CHECK(configure_view_acl(vconfig, config, "no-case-compress", NULL,
03412 actx, ns_g_mctx, &view->nocasecompress));
03413
03414
03415
03416
03417 CHECK(configure_view_acl(vconfig, config, "deny-answer-addresses",
03418 "acl", actx, ns_g_mctx, &view->denyansweracl));
03419 CHECK(configure_view_nametable(vconfig, config, "deny-answer-addresses",
03420 "except-from", ns_g_mctx,
03421 &view->answeracl_exclude));
03422
03423
03424
03425
03426 CHECK(configure_view_nametable(vconfig, config, "deny-answer-aliases",
03427 "name", ns_g_mctx,
03428 &view->denyanswernames));
03429 CHECK(configure_view_nametable(vconfig, config, "deny-answer-aliases",
03430 "except-from", ns_g_mctx,
03431 &view->answernames_exclude));
03432
03433
03434
03435
03436 CHECK(configure_view_sortlist(vconfig, config, actx, ns_g_mctx,
03437 &view->sortlist));
03438
03439
03440
03441
03442
03443
03444 if (view->notifyacl == NULL)
03445 CHECK(configure_view_acl(NULL, ns_g_config,
03446 "allow-notify", NULL, actx,
03447 ns_g_mctx, &view->notifyacl));
03448 if (view->transferacl == NULL)
03449 CHECK(configure_view_acl(NULL, ns_g_config,
03450 "allow-transfer", NULL, actx,
03451 ns_g_mctx, &view->transferacl));
03452 if (view->updateacl == NULL)
03453 CHECK(configure_view_acl(NULL, ns_g_config,
03454 "allow-update", NULL, actx,
03455 ns_g_mctx, &view->updateacl));
03456 if (view->upfwdacl == NULL)
03457 CHECK(configure_view_acl(NULL, ns_g_config,
03458 "allow-update-forwarding", NULL, actx,
03459 ns_g_mctx, &view->upfwdacl));
03460
03461 obj = NULL;
03462 result = ns_config_get(maps, "provide-ixfr", &obj);
03463 INSIST(result == ISC_R_SUCCESS);
03464 view->provideixfr = cfg_obj_asboolean(obj);
03465
03466 obj = NULL;
03467 result = ns_config_get(maps, "request-nsid", &obj);
03468 INSIST(result == ISC_R_SUCCESS);
03469 view->requestnsid = cfg_obj_asboolean(obj);
03470
03471 #ifdef ISC_PLATFORM_USESIT
03472 obj = NULL;
03473 result = ns_config_get(maps, "request-sit", &obj);
03474 INSIST(result == ISC_R_SUCCESS);
03475 view->requestsit = cfg_obj_asboolean(obj);
03476 #endif
03477
03478 obj = NULL;
03479 result = ns_config_get(maps, "max-clients-per-query", &obj);
03480 INSIST(result == ISC_R_SUCCESS);
03481 max_clients_per_query = cfg_obj_asuint32(obj);
03482
03483 obj = NULL;
03484 result = ns_config_get(maps, "clients-per-query", &obj);
03485 INSIST(result == ISC_R_SUCCESS);
03486 dns_resolver_setclientsperquery(view->resolver,
03487 cfg_obj_asuint32(obj),
03488 max_clients_per_query);
03489
03490 obj = NULL;
03491 result = ns_config_get(maps, "max-recursion-depth", &obj);
03492 INSIST(result == ISC_R_SUCCESS);
03493 dns_resolver_setmaxdepth(view->resolver, cfg_obj_asuint32(obj));
03494
03495 obj = NULL;
03496 result = ns_config_get(maps, "max-recursion-queries", &obj);
03497 INSIST(result == ISC_R_SUCCESS);
03498 dns_resolver_setmaxqueries(view->resolver, cfg_obj_asuint32(obj));
03499
03500 #ifdef ALLOW_FILTER_AAAA
03501 obj = NULL;
03502 result = ns_config_get(maps, "filter-aaaa-on-v4", &obj);
03503 INSIST(result == ISC_R_SUCCESS);
03504 if (cfg_obj_isboolean(obj)) {
03505 if (cfg_obj_asboolean(obj))
03506 view->v4_aaaa = dns_aaaa_filter;
03507 else
03508 view->v4_aaaa = dns_aaaa_ok;
03509 } else {
03510 const char *v4_aaaastr = cfg_obj_asstring(obj);
03511 if (strcasecmp(v4_aaaastr, "break-dnssec") == 0)
03512 view->v4_aaaa = dns_aaaa_break_dnssec;
03513 else
03514 INSIST(0);
03515 }
03516
03517 obj = NULL;
03518 result = ns_config_get(maps, "filter-aaaa-on-v6", &obj);
03519 INSIST(result == ISC_R_SUCCESS);
03520 if (cfg_obj_isboolean(obj)) {
03521 if (cfg_obj_asboolean(obj))
03522 view->v6_aaaa = dns_aaaa_filter;
03523 else
03524 view->v6_aaaa = dns_aaaa_ok;
03525 } else {
03526 const char *v6_aaaastr = cfg_obj_asstring(obj);
03527 if (strcasecmp(v6_aaaastr, "break-dnssec") == 0)
03528 view->v6_aaaa = dns_aaaa_break_dnssec;
03529 else
03530 INSIST(0);
03531 }
03532
03533 CHECK(configure_view_acl(vconfig, config, "filter-aaaa", NULL,
03534 actx, ns_g_mctx, &view->aaaa_acl));
03535 #endif
03536 obj = NULL;
03537 result = ns_config_get(maps, "prefetch", &obj);
03538 if (result == ISC_R_SUCCESS) {
03539 const cfg_obj_t *trigger, *eligible;
03540
03541 trigger = cfg_tuple_get(obj, "trigger");
03542 view->prefetch_trigger = cfg_obj_asuint32(trigger);
03543 if (view->prefetch_trigger > 10)
03544 view->prefetch_trigger = 10;
03545 eligible = cfg_tuple_get(obj, "eligible");
03546 if (cfg_obj_isvoid(eligible)) {
03547 int m;
03548 for (m = 1; maps[m] != NULL; m++) {
03549 obj = NULL;
03550 result = ns_config_get(&maps[m],
03551 "prefetch", &obj);
03552 INSIST(result == ISC_R_SUCCESS);
03553 eligible = cfg_tuple_get(obj, "eligible");
03554 if (cfg_obj_isuint32(eligible))
03555 break;
03556 }
03557 INSIST(cfg_obj_isuint32(eligible));
03558 }
03559 view->prefetch_eligible = cfg_obj_asuint32(eligible);
03560 if (view->prefetch_eligible < view->prefetch_trigger + 6)
03561 view->prefetch_eligible = view->prefetch_trigger + 6;
03562 }
03563
03564 obj = NULL;
03565 result = ns_config_get(maps, "dnssec-enable", &obj);
03566 INSIST(result == ISC_R_SUCCESS);
03567 view->enablednssec = cfg_obj_asboolean(obj);
03568
03569 obj = NULL;
03570 result = ns_config_get(optionmaps, "dnssec-lookaside", &obj);
03571 if (result == ISC_R_SUCCESS) {
03572
03573 const cfg_obj_t *dlvobj;
03574 const char *dom;
03575 dlvobj = cfg_listelt_value(cfg_list_first(obj));
03576 dom = cfg_obj_asstring(cfg_tuple_get(dlvobj, "domain"));
03577 if (cfg_obj_isvoid(cfg_tuple_get(dlvobj, "trust-anchor"))) {
03578
03579 if (!strcasecmp(dom, "no"))
03580 result = ISC_R_NOTFOUND;
03581 else if (!strcasecmp(dom, "auto")) {
03582 auto_dlv = ISC_TRUE;
03583 obj = NULL;
03584 result = cfg_map_get(ns_g_defaults,
03585 "dnssec-lookaside", &obj);
03586 }
03587 }
03588 }
03589
03590 if (result == ISC_R_SUCCESS) {
03591 for (element = cfg_list_first(obj);
03592 element != NULL;
03593 element = cfg_list_next(element))
03594 {
03595 dns_name_t *dlv;
03596
03597 obj = cfg_listelt_value(element);
03598 obj = cfg_tuple_get(obj, "trust-anchor");
03599 dlv = dns_fixedname_name(&view->dlv_fixed);
03600 CHECK(dns_name_fromstring(dlv, cfg_obj_asstring(obj),
03601 DNS_NAME_DOWNCASE, NULL));
03602 view->dlv = dns_fixedname_name(&view->dlv_fixed);
03603 }
03604 } else
03605 view->dlv = NULL;
03606
03607
03608
03609
03610
03611 CHECK(configure_view_dnsseckeys(view, vconfig, config, bindkeys,
03612 auto_dlv, auto_root, mctx));
03613 dns_resolver_resetmustbesecure(view->resolver);
03614 obj = NULL;
03615 result = ns_config_get(maps, "dnssec-must-be-secure", &obj);
03616 if (result == ISC_R_SUCCESS)
03617 CHECK(mustbesecure(obj, view->resolver));
03618
03619 obj = NULL;
03620 result = ns_config_get(maps, "nta-recheck", &obj);
03621 INSIST(result == ISC_R_SUCCESS);
03622 view->nta_recheck = cfg_obj_asuint32(obj);
03623
03624 obj = NULL;
03625 result = ns_config_get(maps, "nta-lifetime", &obj);
03626 INSIST(result == ISC_R_SUCCESS);
03627 view->nta_lifetime = cfg_obj_asuint32(obj);
03628
03629 obj = NULL;
03630 result = ns_config_get(maps, "preferred-glue", &obj);
03631 if (result == ISC_R_SUCCESS) {
03632 str = cfg_obj_asstring(obj);
03633 if (strcasecmp(str, "a") == 0)
03634 view->preferred_glue = dns_rdatatype_a;
03635 else if (strcasecmp(str, "aaaa") == 0)
03636 view->preferred_glue = dns_rdatatype_aaaa;
03637 else
03638 view->preferred_glue = 0;
03639 } else
03640 view->preferred_glue = 0;
03641
03642 obj = NULL;
03643 result = ns_config_get(maps, "root-delegation-only", &obj);
03644 if (result == ISC_R_SUCCESS) {
03645 dns_fixedname_t fixed;
03646 dns_name_t *name;
03647 const cfg_obj_t *exclude;
03648
03649 dns_view_setrootdelonly(view, ISC_TRUE);
03650
03651 dns_fixedname_init(&fixed);
03652 name = dns_fixedname_name(&fixed);
03653 for (element = cfg_list_first(obj);
03654 element != NULL;
03655 element = cfg_list_next(element)) {
03656 exclude = cfg_listelt_value(element);
03657 CHECK(dns_name_fromstring(name,
03658 cfg_obj_asstring(exclude),
03659 0, NULL));
03660 CHECK(dns_view_excludedelegationonly(view, name));
03661 }
03662 } else
03663 dns_view_setrootdelonly(view, ISC_FALSE);
03664
03665
03666
03667
03668
03669 obj = NULL;
03670 (void)ns_config_get(maps, "empty-zones-enable", &obj);
03671 (void)ns_config_get(maps, "disable-empty-zone", &disablelist);
03672 if (obj == NULL && disablelist == NULL &&
03673 view->rdclass == dns_rdataclass_in) {
03674 empty_zones_enable = view->recursion;
03675 } else if (view->rdclass == dns_rdataclass_in) {
03676 if (obj != NULL)
03677 empty_zones_enable = cfg_obj_asboolean(obj);
03678 else
03679 empty_zones_enable = view->recursion;
03680 } else {
03681 empty_zones_enable = ISC_FALSE;
03682 }
03683
03684 if (empty_zones_enable && !lwresd_g_useresolvconf) {
03685 const char *empty;
03686 int empty_zone = 0;
03687 dns_fixedname_t fixed;
03688 dns_name_t *name;
03689 isc_buffer_t buffer;
03690 char server[DNS_NAME_FORMATSIZE + 1];
03691 char contact[DNS_NAME_FORMATSIZE + 1];
03692 const char *empty_dbtype[4] =
03693 { "_builtin", "empty", NULL, NULL };
03694 int empty_dbtypec = 4;
03695 dns_zonestat_level_t statlevel;
03696
03697 dns_fixedname_init(&fixed);
03698 name = dns_fixedname_name(&fixed);
03699
03700 obj = NULL;
03701 result = ns_config_get(maps, "empty-server", &obj);
03702 if (result == ISC_R_SUCCESS) {
03703 CHECK(dns_name_fromstring(name, cfg_obj_asstring(obj),
03704 0, NULL));
03705 isc_buffer_init(&buffer, server, sizeof(server) - 1);
03706 CHECK(dns_name_totext(name, ISC_FALSE, &buffer));
03707 server[isc_buffer_usedlength(&buffer)] = 0;
03708 empty_dbtype[2] = server;
03709 } else
03710 empty_dbtype[2] = "@";
03711
03712 obj = NULL;
03713 result = ns_config_get(maps, "empty-contact", &obj);
03714 if (result == ISC_R_SUCCESS) {
03715 CHECK(dns_name_fromstring(name, cfg_obj_asstring(obj),
03716 0, NULL));
03717 isc_buffer_init(&buffer, contact, sizeof(contact) - 1);
03718 CHECK(dns_name_totext(name, ISC_FALSE, &buffer));
03719 contact[isc_buffer_usedlength(&buffer)] = 0;
03720 empty_dbtype[3] = contact;
03721 } else
03722 empty_dbtype[3] = ".";
03723
03724 obj = NULL;
03725 result = ns_config_get(maps, "zone-statistics", &obj);
03726 INSIST(result == ISC_R_SUCCESS);
03727 if (cfg_obj_isboolean(obj)) {
03728 if (cfg_obj_asboolean(obj))
03729 statlevel = dns_zonestat_full;
03730 else
03731 statlevel = dns_zonestat_none;
03732 } else {
03733 const char *levelstr = cfg_obj_asstring(obj);
03734 if (strcasecmp(levelstr, "full") == 0)
03735 statlevel = dns_zonestat_full;
03736 else if (strcasecmp(levelstr, "terse") == 0)
03737 statlevel = dns_zonestat_terse;
03738 else if (strcasecmp(levelstr, "none") == 0)
03739 statlevel = dns_zonestat_none;
03740 else
03741 INSIST(0);
03742 }
03743
03744 for (empty = empty_zones[empty_zone];
03745 empty != NULL;
03746 empty = empty_zones[++empty_zone])
03747 {
03748 dns_forwarders_t *dnsforwarders = NULL;
03749
03750
03751
03752
03753 CHECK(dns_name_fromstring(name, empty, 0, NULL));
03754 if (disablelist != NULL &&
03755 on_disable_list(disablelist, name))
03756 continue;
03757
03758
03759
03760
03761 (void)dns_view_findzone(view, name, &zone);
03762 if (zone != NULL) {
03763 dns_zone_detach(&zone);
03764 continue;
03765 }
03766
03767
03768
03769
03770
03771 result = dns_fwdtable_find(view->fwdtable, name,
03772 &dnsforwarders);
03773 if (result == ISC_R_SUCCESS &&
03774 dnsforwarders->fwdpolicy == dns_fwdpolicy_only)
03775 continue;
03776
03777
03778
03779
03780 result = dns_viewlist_find(&ns_g_server->viewlist,
03781 view->name, view->rdclass,
03782 &pview);
03783 if (result != ISC_R_NOTFOUND &&
03784 result != ISC_R_SUCCESS)
03785 goto cleanup;
03786
03787 if (pview != NULL) {
03788 (void)dns_view_findzone(pview, name, &zone);
03789 dns_view_detach(&pview);
03790 }
03791
03792 CHECK(create_empty_zone(zone, name, view, zonelist,
03793 empty_dbtype, empty_dbtypec,
03794 statlevel));
03795 if (zone != NULL)
03796 dns_zone_detach(&zone);
03797 }
03798 }
03799
03800 obj = NULL;
03801 result = ns_config_get(maps, "rate-limit", &obj);
03802 if (result == ISC_R_SUCCESS) {
03803 result = configure_rrl(view, config, obj);
03804 if (result != ISC_R_SUCCESS)
03805 goto cleanup;
03806 }
03807
03808
03809
03810
03811 obj = NULL;
03812 result = ns_config_get(maps, "servfail-ttl", &obj);
03813 INSIST(result == ISC_R_SUCCESS);
03814 fail_ttl = cfg_obj_asuint32(obj);
03815 if (fail_ttl > 300)
03816 fail_ttl = 300;
03817 dns_view_setfailttl(view, fail_ttl);
03818
03819
03820
03821
03822 obj = NULL;
03823 result = ns_config_get(maps, "nxdomain-redirect", &obj);
03824 if (result == ISC_R_SUCCESS) {
03825 dns_name_t *name = dns_fixedname_name(&view->redirectfixed);
03826 CHECK(dns_name_fromstring(name, cfg_obj_asstring(obj), 0,
03827 NULL));
03828 view->redirectzone = name;
03829 } else
03830 view->redirectzone = NULL;
03831
03832
03833 result = ISC_R_SUCCESS;
03834
03835 cleanup:
03836 if (clients != NULL)
03837 dns_acl_detach(&clients);
03838 if (mapped != NULL)
03839 dns_acl_detach(&mapped);
03840 if (excluded != NULL)
03841 dns_acl_detach(&excluded);
03842 if (ring != NULL)
03843 dns_tsigkeyring_detach(&ring);
03844 if (zone != NULL)
03845 dns_zone_detach(&zone);
03846 if (dispatch4 != NULL)
03847 dns_dispatch_detach(&dispatch4);
03848 if (dispatch6 != NULL)
03849 dns_dispatch_detach(&dispatch6);
03850 if (resstats != NULL)
03851 isc_stats_detach(&resstats);
03852 if (resquerystats != NULL)
03853 dns_stats_detach(&resquerystats);
03854 if (order != NULL)
03855 dns_order_detach(&order);
03856 if (cmctx != NULL)
03857 isc_mem_detach(&cmctx);
03858 if (hmctx != NULL)
03859 isc_mem_detach(&hmctx);
03860
03861 if (cache != NULL)
03862 dns_cache_detach(&cache);
03863
03864 return (result);
03865 }
03866
03867 static isc_result_t
03868 configure_hints(dns_view_t *view, const char *filename) {
03869 isc_result_t result;
03870 dns_db_t *db;
03871
03872 db = NULL;
03873 result = dns_rootns_create(view->mctx, view->rdclass, filename, &db);
03874 if (result == ISC_R_SUCCESS) {
03875 dns_view_sethints(view, db);
03876 dns_db_detach(&db);
03877 }
03878
03879 return (result);
03880 }
03881
03882 static isc_result_t
03883 configure_alternates(const cfg_obj_t *config, dns_view_t *view,
03884 const cfg_obj_t *alternates)
03885 {
03886 const cfg_obj_t *portobj;
03887 const cfg_obj_t *addresses;
03888 const cfg_listelt_t *element;
03889 isc_result_t result = ISC_R_SUCCESS;
03890 in_port_t port;
03891
03892
03893
03894
03895 if (ns_g_lwresdonly && ns_g_port != 0)
03896 port = ns_g_port;
03897 else
03898 CHECKM(ns_config_getport(config, &port), "port");
03899
03900 if (alternates != NULL) {
03901 portobj = cfg_tuple_get(alternates, "port");
03902 if (cfg_obj_isuint32(portobj)) {
03903 isc_uint32_t val = cfg_obj_asuint32(portobj);
03904 if (val > ISC_UINT16_MAX) {
03905 cfg_obj_log(portobj, ns_g_lctx, ISC_LOG_ERROR,
03906 "port '%u' out of range", val);
03907 return (ISC_R_RANGE);
03908 }
03909 port = (in_port_t) val;
03910 }
03911 }
03912
03913 addresses = NULL;
03914 if (alternates != NULL)
03915 addresses = cfg_tuple_get(alternates, "addresses");
03916
03917 for (element = cfg_list_first(addresses);
03918 element != NULL;
03919 element = cfg_list_next(element))
03920 {
03921 const cfg_obj_t *alternate = cfg_listelt_value(element);
03922 isc_sockaddr_t sa;
03923
03924 if (!cfg_obj_issockaddr(alternate)) {
03925 dns_fixedname_t fixed;
03926 dns_name_t *name;
03927 const char *str = cfg_obj_asstring(cfg_tuple_get(
03928 alternate, "name"));
03929 isc_buffer_t buffer;
03930 in_port_t myport = port;
03931
03932 isc_buffer_constinit(&buffer, str, strlen(str));
03933 isc_buffer_add(&buffer, strlen(str));
03934 dns_fixedname_init(&fixed);
03935 name = dns_fixedname_name(&fixed);
03936 CHECK(dns_name_fromtext(name, &buffer, dns_rootname, 0,
03937 NULL));
03938
03939 portobj = cfg_tuple_get(alternate, "port");
03940 if (cfg_obj_isuint32(portobj)) {
03941 isc_uint32_t val = cfg_obj_asuint32(portobj);
03942 if (val > ISC_UINT16_MAX) {
03943 cfg_obj_log(portobj, ns_g_lctx,
03944 ISC_LOG_ERROR,
03945 "port '%u' out of range",
03946 val);
03947 return (ISC_R_RANGE);
03948 }
03949 myport = (in_port_t) val;
03950 }
03951 CHECK(dns_resolver_addalternate(view->resolver, NULL,
03952 name, myport));
03953 continue;
03954 }
03955
03956 sa = *cfg_obj_assockaddr(alternate);
03957 if (isc_sockaddr_getport(&sa) == 0)
03958 isc_sockaddr_setport(&sa, port);
03959 CHECK(dns_resolver_addalternate(view->resolver, &sa,
03960 NULL, 0));
03961 }
03962
03963 cleanup:
03964 return (result);
03965 }
03966
03967 static isc_result_t
03968 configure_forward(const cfg_obj_t *config, dns_view_t *view, dns_name_t *origin,
03969 const cfg_obj_t *forwarders, const cfg_obj_t *forwardtype)
03970 {
03971 const cfg_obj_t *portobj, *dscpobj;
03972 const cfg_obj_t *faddresses;
03973 const cfg_listelt_t *element;
03974 dns_fwdpolicy_t fwdpolicy = dns_fwdpolicy_none;
03975 dns_forwarderlist_t fwdlist;
03976 dns_forwarder_t *fwd;
03977 isc_result_t result;
03978 in_port_t port;
03979 isc_dscp_t dscp = -1;
03980
03981 ISC_LIST_INIT(fwdlist);
03982
03983
03984
03985
03986 if (ns_g_lwresdonly && ns_g_port != 0)
03987 port = ns_g_port;
03988 else
03989 CHECKM(ns_config_getport(config, &port), "port");
03990
03991 if (forwarders != NULL) {
03992 portobj = cfg_tuple_get(forwarders, "port");
03993 if (cfg_obj_isuint32(portobj)) {
03994 isc_uint32_t val = cfg_obj_asuint32(portobj);
03995 if (val > ISC_UINT16_MAX) {
03996 cfg_obj_log(portobj, ns_g_lctx, ISC_LOG_ERROR,
03997 "port '%u' out of range", val);
03998 return (ISC_R_RANGE);
03999 }
04000 port = (in_port_t) val;
04001 }
04002 }
04003
04004
04005
04006
04007 dscp = ns_g_dscp;
04008 if (forwarders != NULL) {
04009 dscpobj = cfg_tuple_get(forwarders, "dscp");
04010 if (cfg_obj_isuint32(dscpobj)) {
04011 if (cfg_obj_asuint32(dscpobj) > 63) {
04012 cfg_obj_log(dscpobj, ns_g_lctx, ISC_LOG_ERROR,
04013 "dscp value '%u' is out of range",
04014 cfg_obj_asuint32(dscpobj));
04015 return (ISC_R_RANGE);
04016 }
04017 dscp = (isc_dscp_t)cfg_obj_asuint32(dscpobj);
04018 }
04019 }
04020
04021 faddresses = NULL;
04022 if (forwarders != NULL)
04023 faddresses = cfg_tuple_get(forwarders, "addresses");
04024
04025 for (element = cfg_list_first(faddresses);
04026 element != NULL;
04027 element = cfg_list_next(element))
04028 {
04029 const cfg_obj_t *forwarder = cfg_listelt_value(element);
04030 fwd = isc_mem_get(view->mctx, sizeof(dns_forwarder_t));
04031 if (fwd == NULL) {
04032 result = ISC_R_NOMEMORY;
04033 goto cleanup;
04034 }
04035 fwd->addr = *cfg_obj_assockaddr(forwarder);
04036 if (isc_sockaddr_getport(&fwd->addr) == 0)
04037 isc_sockaddr_setport(&fwd->addr, port);
04038 fwd->dscp = cfg_obj_getdscp(forwarder);
04039 if (fwd->dscp == -1)
04040 fwd->dscp = dscp;
04041 ISC_LINK_INIT(fwd, link);
04042 ISC_LIST_APPEND(fwdlist, fwd, link);
04043 }
04044
04045 if (ISC_LIST_EMPTY(fwdlist)) {
04046 if (forwardtype != NULL)
04047 cfg_obj_log(forwarders, ns_g_lctx, ISC_LOG_WARNING,
04048 "no forwarders seen; disabling "
04049 "forwarding");
04050 fwdpolicy = dns_fwdpolicy_none;
04051 } else {
04052 if (forwardtype == NULL)
04053 fwdpolicy = dns_fwdpolicy_first;
04054 else {
04055 const char *forwardstr = cfg_obj_asstring(forwardtype);
04056 if (strcasecmp(forwardstr, "first") == 0)
04057 fwdpolicy = dns_fwdpolicy_first;
04058 else if (strcasecmp(forwardstr, "only") == 0)
04059 fwdpolicy = dns_fwdpolicy_only;
04060 else
04061 INSIST(0);
04062 }
04063 }
04064
04065 result = dns_fwdtable_addfwd(view->fwdtable, origin, &fwdlist,
04066 fwdpolicy);
04067 if (result != ISC_R_SUCCESS) {
04068 char namebuf[DNS_NAME_FORMATSIZE];
04069 dns_name_format(origin, namebuf, sizeof(namebuf));
04070 cfg_obj_log(forwarders, ns_g_lctx, ISC_LOG_WARNING,
04071 "could not set up forwarding for domain '%s': %s",
04072 namebuf, isc_result_totext(result));
04073 goto cleanup;
04074 }
04075
04076 result = ISC_R_SUCCESS;
04077
04078 cleanup:
04079
04080 while (!ISC_LIST_EMPTY(fwdlist)) {
04081 fwd = ISC_LIST_HEAD(fwdlist);
04082 ISC_LIST_UNLINK(fwdlist, fwd, link);
04083 isc_mem_put(view->mctx, fwd, sizeof(dns_forwarder_t));
04084 }
04085
04086 return (result);
04087 }
04088
04089 static isc_result_t
04090 get_viewinfo(const cfg_obj_t *vconfig, const char **namep,
04091 dns_rdataclass_t *classp)
04092 {
04093 isc_result_t result = ISC_R_SUCCESS;
04094 const char *viewname;
04095 dns_rdataclass_t viewclass;
04096
04097 REQUIRE(namep != NULL && *namep == NULL);
04098 REQUIRE(classp != NULL);
04099
04100 if (vconfig != NULL) {
04101 const cfg_obj_t *classobj = NULL;
04102
04103 viewname = cfg_obj_asstring(cfg_tuple_get(vconfig, "name"));
04104 classobj = cfg_tuple_get(vconfig, "class");
04105 result = ns_config_getclass(classobj, dns_rdataclass_in,
04106 &viewclass);
04107 } else {
04108 viewname = "_default";
04109 viewclass = dns_rdataclass_in;
04110 }
04111
04112 *namep = viewname;
04113 *classp = viewclass;
04114
04115 return (result);
04116 }
04117
04118
04119
04120
04121
04122
04123 static isc_result_t
04124 find_view(const cfg_obj_t *vconfig, dns_viewlist_t *viewlist,
04125 dns_view_t **viewp)
04126 {
04127 isc_result_t result;
04128 const char *viewname = NULL;
04129 dns_rdataclass_t viewclass;
04130 dns_view_t *view = NULL;
04131
04132 result = get_viewinfo(vconfig, &viewname, &viewclass);
04133 if (result != ISC_R_SUCCESS)
04134 return (result);
04135
04136 result = dns_viewlist_find(viewlist, viewname, viewclass, &view);
04137 if (result != ISC_R_SUCCESS)
04138 return (result);
04139
04140 *viewp = view;
04141 return (ISC_R_SUCCESS);
04142 }
04143
04144
04145
04146
04147
04148
04149
04150
04151 static isc_result_t
04152 create_view(const cfg_obj_t *vconfig, dns_viewlist_t *viewlist,
04153 dns_view_t **viewp)
04154 {
04155 isc_result_t result;
04156 const char *viewname = NULL;
04157 dns_rdataclass_t viewclass;
04158 dns_view_t *view = NULL;
04159
04160 result = get_viewinfo(vconfig, &viewname, &viewclass);
04161 if (result != ISC_R_SUCCESS)
04162 return (result);
04163
04164 result = dns_viewlist_find(viewlist, viewname, viewclass, &view);
04165 if (result == ISC_R_SUCCESS)
04166 return (ISC_R_EXISTS);
04167 if (result != ISC_R_NOTFOUND)
04168 return (result);
04169 INSIST(view == NULL);
04170
04171 result = dns_view_create(ns_g_mctx, viewclass, viewname, &view);
04172 if (result != ISC_R_SUCCESS)
04173 return (result);
04174
04175 result = isc_entropy_getdata(ns_g_entropy, view->secret,
04176 sizeof(view->secret), NULL, 0);
04177 if (result != ISC_R_SUCCESS) {
04178 dns_view_detach(&view);
04179 return (result);
04180 }
04181
04182 #ifdef HAVE_GEOIP
04183 view->aclenv.geoip = ns_g_geoip;
04184 #endif
04185
04186 ISC_LIST_APPEND(*viewlist, view, link);
04187 dns_view_attach(view, viewp);
04188 return (ISC_R_SUCCESS);
04189 }
04190
04191
04192
04193
04194 static isc_result_t
04195 configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig,
04196 const cfg_obj_t *vconfig, isc_mem_t *mctx, dns_view_t *view,
04197 dns_viewlist_t *viewlist, cfg_aclconfctx_t *aclconf,
04198 isc_boolean_t added, isc_boolean_t old_rpz_ok,
04199 isc_boolean_t modify)
04200 {
04201 dns_view_t *pview = NULL;
04202 dns_zone_t *zone = NULL;
04203 dns_zone_t *raw = NULL;
04204 dns_zone_t *dupzone = NULL;
04205 const cfg_obj_t *options = NULL;
04206 const cfg_obj_t *zoptions = NULL;
04207 const cfg_obj_t *typeobj = NULL;
04208 const cfg_obj_t *forwarders = NULL;
04209 const cfg_obj_t *forwardtype = NULL;
04210 const cfg_obj_t *only = NULL;
04211 const cfg_obj_t *signing = NULL;
04212 const cfg_obj_t *viewobj = NULL;
04213 isc_result_t result;
04214 isc_result_t tresult;
04215 isc_buffer_t buffer;
04216 dns_fixedname_t fixorigin;
04217 dns_name_t *origin;
04218 const char *zname;
04219 dns_rdataclass_t zclass;
04220 const char *ztypestr;
04221 dns_rpz_num_t rpz_num;
04222
04223 options = NULL;
04224 (void)cfg_map_get(config, "options", &options);
04225
04226 zoptions = cfg_tuple_get(zconfig, "options");
04227
04228
04229
04230
04231 zname = cfg_obj_asstring(cfg_tuple_get(zconfig, "name"));
04232 isc_buffer_constinit(&buffer, zname, strlen(zname));
04233 isc_buffer_add(&buffer, strlen(zname));
04234 dns_fixedname_init(&fixorigin);
04235 CHECK(dns_name_fromtext(dns_fixedname_name(&fixorigin),
04236 &buffer, dns_rootname, 0, NULL));
04237 origin = dns_fixedname_name(&fixorigin);
04238
04239 CHECK(ns_config_getclass(cfg_tuple_get(zconfig, "class"),
04240 view->rdclass, &zclass));
04241 if (zclass != view->rdclass) {
04242 const char *vname = NULL;
04243 if (vconfig != NULL)
04244 vname = cfg_obj_asstring(cfg_tuple_get(vconfig,
04245 "name"));
04246 else
04247 vname = "<default view>";
04248
04249 isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
04250 NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
04251 "zone '%s': wrong class for view '%s'",
04252 zname, vname);
04253 result = ISC_R_FAILURE;
04254 goto cleanup;
04255 }
04256
04257 (void)cfg_map_get(zoptions, "in-view", &viewobj);
04258 if (viewobj != NULL) {
04259 const char *inview = cfg_obj_asstring(viewobj);
04260 dns_view_t *otherview = NULL;
04261
04262 if (viewlist == NULL) {
04263 cfg_obj_log(zconfig, ns_g_lctx, ISC_LOG_ERROR,
04264 "'in-view' option is not permitted in "
04265 "dynamically added zones");
04266 result = ISC_R_FAILURE;
04267 goto cleanup;
04268 }
04269
04270 result = dns_viewlist_find(viewlist, inview, view->rdclass,
04271 &otherview);
04272 if (result != ISC_R_SUCCESS) {
04273 cfg_obj_log(zconfig, ns_g_lctx, ISC_LOG_ERROR,
04274 "view '%s' is not yet defined.", inview);
04275 result = ISC_R_FAILURE;
04276 goto cleanup;
04277 }
04278
04279 result = dns_view_findzone(otherview, origin, &zone);
04280 dns_view_detach(&otherview);
04281 if (result != ISC_R_SUCCESS) {
04282 cfg_obj_log(zconfig, ns_g_lctx, ISC_LOG_ERROR,
04283 "zone '%s' not defined in view '%s'",
04284 zname, inview);
04285 result = ISC_R_FAILURE;
04286 goto cleanup;
04287 }
04288
04289 CHECK(dns_view_addzone(view, zone));
04290 dns_zone_detach(&zone);
04291
04292
04293
04294
04295
04296
04297 forwarders = NULL;
04298 result = cfg_map_get(zoptions, "forwarders", &forwarders);
04299 if (result == ISC_R_SUCCESS) {
04300 forwardtype = NULL;
04301 (void)cfg_map_get(zoptions, "forward", &forwardtype);
04302 CHECK(configure_forward(config, view, origin,
04303 forwarders, forwardtype));
04304 }
04305 result = ISC_R_SUCCESS;
04306 goto cleanup;
04307 }
04308
04309 (void)cfg_map_get(zoptions, "type", &typeobj);
04310 if (typeobj == NULL) {
04311 cfg_obj_log(zconfig, ns_g_lctx, ISC_LOG_ERROR,
04312 "zone '%s' 'type' not specified", zname);
04313 result = ISC_R_FAILURE;
04314 goto cleanup;
04315 }
04316 ztypestr = cfg_obj_asstring(typeobj);
04317
04318
04319
04320
04321
04322 if (strcasecmp(ztypestr, "hint") == 0) {
04323 const cfg_obj_t *fileobj = NULL;
04324 if (cfg_map_get(zoptions, "file", &fileobj) != ISC_R_SUCCESS) {
04325 isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
04326 NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
04327 "zone '%s': 'file' not specified",
04328 zname);
04329 result = ISC_R_FAILURE;
04330 goto cleanup;
04331 }
04332 if (dns_name_equal(origin, dns_rootname)) {
04333 const char *hintsfile = cfg_obj_asstring(fileobj);
04334
04335 CHECK(configure_hints(view, hintsfile));
04336
04337
04338
04339
04340 only = NULL;
04341 tresult = cfg_map_get(zoptions, "delegation-only",
04342 &only);
04343 if (tresult == ISC_R_SUCCESS && cfg_obj_asboolean(only))
04344 CHECK(dns_view_adddelegationonly(view, origin));
04345 } else {
04346 isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
04347 NS_LOGMODULE_SERVER, ISC_LOG_WARNING,
04348 "ignoring non-root hint zone '%s'",
04349 zname);
04350 result = ISC_R_SUCCESS;
04351 }
04352
04353 goto cleanup;
04354 }
04355
04356
04357
04358
04359
04360 if (strcasecmp(ztypestr, "forward") == 0) {
04361 forwardtype = NULL;
04362 forwarders = NULL;
04363
04364 (void)cfg_map_get(zoptions, "forward", &forwardtype);
04365 (void)cfg_map_get(zoptions, "forwarders", &forwarders);
04366 CHECK(configure_forward(config, view, origin, forwarders,
04367 forwardtype));
04368
04369
04370
04371
04372 only = NULL;
04373 tresult = cfg_map_get(zoptions, "delegation-only", &only);
04374 if (tresult == ISC_R_SUCCESS && cfg_obj_asboolean(only))
04375 CHECK(dns_view_adddelegationonly(view, origin));
04376 goto cleanup;
04377 }
04378
04379
04380
04381
04382 if (strcasecmp(ztypestr, "delegation-only") == 0) {
04383 result = dns_view_adddelegationonly(view, origin);
04384 goto cleanup;
04385 }
04386
04387
04388
04389
04390 if (strcasecmp(ztypestr, "redirect") == 0) {
04391 if (view->redirect != NULL) {
04392 cfg_obj_log(zconfig, ns_g_lctx, ISC_LOG_ERROR,
04393 "redirect zone already exists");
04394 result = ISC_R_EXISTS;
04395 goto cleanup;
04396 }
04397 result = dns_viewlist_find(viewlist, view->name,
04398 view->rdclass, &pview);
04399 if (result != ISC_R_NOTFOUND && result != ISC_R_SUCCESS)
04400 goto cleanup;
04401 if (pview != NULL && pview->redirect != NULL) {
04402 dns_zone_attach(pview->redirect, &zone);
04403 dns_zone_setview(zone, view);
04404 } else {
04405 CHECK(dns_zonemgr_createzone(ns_g_server->zonemgr,
04406 &zone));
04407 CHECK(dns_zone_setorigin(zone, origin));
04408 dns_zone_setview(zone, view);
04409 CHECK(dns_zonemgr_managezone(ns_g_server->zonemgr,
04410 zone));
04411 dns_zone_setstats(zone, ns_g_server->zonestats);
04412 }
04413 CHECK(ns_zone_configure(config, vconfig, zconfig, aclconf,
04414 zone, NULL));
04415 dns_zone_attach(zone, &view->redirect);
04416 goto cleanup;
04417 }
04418
04419 if (!modify) {
04420
04421
04422
04423 result = dns_view_findzone(view, origin, &dupzone);
04424 if (result == ISC_R_SUCCESS) {
04425
04426
04427
04428 cfg_obj_log(zconfig, ns_g_lctx, ISC_LOG_ERROR,
04429 "zone '%s' already exists", zname);
04430 dns_zone_detach(&dupzone);
04431 result = ISC_R_EXISTS;
04432 goto cleanup;
04433 }
04434 INSIST(dupzone == NULL);
04435 }
04436
04437
04438
04439
04440 for (rpz_num = 0; ; ++rpz_num) {
04441 if (view->rpzs == NULL || rpz_num >= view->rpzs->p.num_zones) {
04442 rpz_num = DNS_RPZ_INVALID_NUM;
04443 break;
04444 }
04445 if (dns_name_equal(&view->rpzs->zones[rpz_num]->origin, origin))
04446 break;
04447 }
04448
04449
04450
04451
04452
04453
04454
04455
04456
04457
04458
04459
04460
04461 result = dns_viewlist_find(&ns_g_server->viewlist, view->name,
04462 view->rdclass, &pview);
04463 if (result != ISC_R_NOTFOUND && result != ISC_R_SUCCESS)
04464 goto cleanup;
04465 if (pview != NULL)
04466 result = dns_view_findzone(pview, origin, &zone);
04467 if (result != ISC_R_NOTFOUND && result != ISC_R_SUCCESS)
04468 goto cleanup;
04469
04470 if (zone != NULL && !ns_zone_reusable(zone, zconfig))
04471 dns_zone_detach(&zone);
04472
04473 if (zone != NULL && (rpz_num != dns_zone_get_rpz_num(zone) ||
04474 (rpz_num != DNS_RPZ_INVALID_NUM && !old_rpz_ok)))
04475 dns_zone_detach(&zone);
04476
04477 if (zone != NULL) {
04478
04479
04480
04481
04482 dns_zone_setview(zone, view);
04483 if (view->acache != NULL)
04484 dns_zone_setacache(zone, view->acache);
04485 } else {
04486
04487
04488
04489
04490 CHECK(dns_zonemgr_createzone(ns_g_server->zonemgr, &zone));
04491 CHECK(dns_zone_setorigin(zone, origin));
04492 dns_zone_setview(zone, view);
04493 if (view->acache != NULL)
04494 dns_zone_setacache(zone, view->acache);
04495 CHECK(dns_zonemgr_managezone(ns_g_server->zonemgr, zone));
04496 dns_zone_setstats(zone, ns_g_server->zonestats);
04497 }
04498
04499 if (rpz_num != DNS_RPZ_INVALID_NUM) {
04500 result = dns_zone_rpz_enable(zone, view->rpzs, rpz_num);
04501 if (result != ISC_R_SUCCESS) {
04502 isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
04503 NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
04504 "zone '%s': incompatible"
04505 " masterfile-format or database"
04506 " for a response policy zone",
04507 zname);
04508 goto cleanup;
04509 }
04510 }
04511
04512
04513
04514
04515
04516 forwarders = NULL;
04517 if (cfg_map_get(zoptions, "forwarders", &forwarders) == ISC_R_SUCCESS)
04518 {
04519 forwardtype = NULL;
04520 (void)cfg_map_get(zoptions, "forward", &forwardtype);
04521 CHECK(configure_forward(config, view, origin, forwarders,
04522 forwardtype));
04523 }
04524
04525
04526
04527
04528 only = NULL;
04529 if (cfg_map_get(zoptions, "delegation-only", &only) == ISC_R_SUCCESS)
04530 {
04531 if (cfg_obj_asboolean(only))
04532 CHECK(dns_view_adddelegationonly(view, origin));
04533 }
04534
04535
04536
04537
04538 dns_zone_setadded(zone, added);
04539
04540 signing = NULL;
04541 if ((strcasecmp(ztypestr, "master") == 0 ||
04542 strcasecmp(ztypestr, "slave") == 0) &&
04543 cfg_map_get(zoptions, "inline-signing", &signing) == ISC_R_SUCCESS &&
04544 cfg_obj_asboolean(signing))
04545 {
04546 dns_zone_getraw(zone, &raw);
04547 if (raw == NULL) {
04548 CHECK(dns_zone_create(&raw, mctx));
04549 CHECK(dns_zone_setorigin(raw, origin));
04550 dns_zone_setview(raw, view);
04551 if (view->acache != NULL)
04552 dns_zone_setacache(raw, view->acache);
04553 dns_zone_setstats(raw, ns_g_server->zonestats);
04554 CHECK(dns_zone_link(zone, raw));
04555 }
04556 }
04557
04558
04559
04560
04561 CHECK(ns_zone_configure(config, vconfig, zconfig, aclconf, zone, raw));
04562
04563
04564
04565
04566 if (!modify)
04567 CHECK(dns_view_addzone(view, zone));
04568
04569
04570
04571
04572 if ((dns_zone_getkeyopts(zone) & DNS_ZONEKEY_MAINTAIN) != 0)
04573 dns_zone_rekey(zone, ISC_FALSE);
04574
04575 cleanup:
04576 if (zone != NULL)
04577 dns_zone_detach(&zone);
04578 if (raw != NULL)
04579 dns_zone_detach(&raw);
04580 if (pview != NULL)
04581 dns_view_detach(&pview);
04582
04583 return (result);
04584 }
04585
04586
04587
04588
04589
04590 static isc_result_t
04591 add_keydata_zone(dns_view_t *view, const char *directory, isc_mem_t *mctx) {
04592 isc_result_t result;
04593 dns_view_t *pview = NULL;
04594 dns_zone_t *zone = NULL;
04595 dns_acl_t *none = NULL;
04596 char filename[PATH_MAX];
04597 isc_boolean_t defaultview;
04598
04599 REQUIRE(view != NULL);
04600
04601
04602 result = dns_viewlist_find(&ns_g_server->viewlist,
04603 view->name, view->rdclass,
04604 &pview);
04605 if (result != ISC_R_NOTFOUND &&
04606 result != ISC_R_SUCCESS)
04607 return (result);
04608
04609 if (pview != NULL && pview->managed_keys != NULL) {
04610 dns_zone_attach(pview->managed_keys, &view->managed_keys);
04611 dns_zone_setview(pview->managed_keys, view);
04612 dns_view_detach(&pview);
04613 dns_zone_synckeyzone(view->managed_keys);
04614 return (ISC_R_SUCCESS);
04615 }
04616
04617
04618 CHECK(dns_zonemgr_createzone(ns_g_server->zonemgr, &zone));
04619 CHECK(dns_zone_setorigin(zone, dns_rootname));
04620
04621 defaultview = ISC_TF(strcmp(view->name, "_default") == 0);
04622 CHECK(isc_file_sanitize(directory,
04623 defaultview ? "managed-keys" : view->name,
04624 defaultview ? "bind" : "mkeys",
04625 filename, sizeof(filename)));
04626 CHECK(dns_zone_setfile(zone, filename));
04627
04628 dns_zone_setview(zone, view);
04629 dns_zone_settype(zone, dns_zone_key);
04630 dns_zone_setclass(zone, view->rdclass);
04631
04632 CHECK(dns_zonemgr_managezone(ns_g_server->zonemgr, zone));
04633
04634 if (view->acache != NULL)
04635 dns_zone_setacache(zone, view->acache);
04636
04637 CHECK(dns_acl_none(mctx, &none));
04638 dns_zone_setqueryacl(zone, none);
04639 dns_zone_setqueryonacl(zone, none);
04640 dns_acl_detach(&none);
04641
04642 dns_zone_setdialup(zone, dns_dialuptype_no);
04643 dns_zone_setnotifytype(zone, dns_notifytype_no);
04644 dns_zone_setoption(zone, DNS_ZONEOPT_NOCHECKNS, ISC_TRUE);
04645 dns_zone_setjournalsize(zone, 0);
04646
04647 dns_zone_setstats(zone, ns_g_server->zonestats);
04648 CHECK(setquerystats(zone, mctx, dns_zonestat_none));
04649
04650 if (view->managed_keys != NULL)
04651 dns_zone_detach(&view->managed_keys);
04652 dns_zone_attach(zone, &view->managed_keys);
04653
04654 isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
04655 NS_LOGMODULE_SERVER, ISC_LOG_INFO,
04656 "set up managed keys zone for view %s, file '%s'",
04657 view->name, filename);
04658
04659 cleanup:
04660 if (zone != NULL)
04661 dns_zone_detach(&zone);
04662 if (none != NULL)
04663 dns_acl_detach(&none);
04664
04665 return (result);
04666 }
04667
04668
04669
04670
04671 static void
04672 configure_server_quota(const cfg_obj_t **maps, const char *name,
04673 isc_quota_t *quota)
04674 {
04675 const cfg_obj_t *obj = NULL;
04676 isc_result_t result;
04677
04678 result = ns_config_get(maps, name, &obj);
04679 INSIST(result == ISC_R_SUCCESS);
04680 isc_quota_max(quota, cfg_obj_asuint32(obj));
04681 }
04682
04683
04684
04685
04686
04687 static isc_result_t
04688 directory_callback(const char *clausename, const cfg_obj_t *obj, void *arg) {
04689 isc_result_t result;
04690 const char *directory;
04691
04692 REQUIRE(strcasecmp("directory", clausename) == 0);
04693
04694 UNUSED(arg);
04695 UNUSED(clausename);
04696
04697
04698
04699
04700 directory = cfg_obj_asstring(obj);
04701
04702 if (! isc_file_ischdiridempotent(directory))
04703 cfg_obj_log(obj, ns_g_lctx, ISC_LOG_WARNING,
04704 "option 'directory' contains relative path '%s'",
04705 directory);
04706
04707 result = isc_dir_chdir(directory);
04708 if (result != ISC_R_SUCCESS) {
04709 cfg_obj_log(obj, ns_g_lctx, ISC_LOG_ERROR,
04710 "change directory to '%s' failed: %s",
04711 directory, isc_result_totext(result));
04712 return (result);
04713 }
04714
04715 return (ISC_R_SUCCESS);
04716 }
04717
04718 static isc_result_t
04719 scan_interfaces(ns_server_t *server, isc_boolean_t verbose) {
04720 isc_result_t result;
04721 isc_boolean_t match_mapped = server->aclenv.match_mapped;
04722 #ifdef HAVE_GEOIP
04723 isc_boolean_t use_ecs = server->aclenv.geoip_use_ecs;
04724 #endif
04725
04726 result = ns_interfacemgr_scan(server->interfacemgr, verbose);
04727
04728
04729
04730
04731 dns_aclenv_copy(&server->aclenv,
04732 ns_interfacemgr_getaclenv(server->interfacemgr));
04733
04734 server->aclenv.match_mapped = match_mapped;
04735 #ifdef HAVE_GEOIP
04736 server->aclenv.geoip_use_ecs = use_ecs;
04737 #endif
04738
04739 return (result);
04740 }
04741
04742 static isc_result_t
04743 add_listenelt(isc_mem_t *mctx, ns_listenlist_t *list, isc_sockaddr_t *addr,
04744 isc_dscp_t dscp, isc_boolean_t wcardport_ok)
04745 {
04746 ns_listenelt_t *lelt = NULL;
04747 dns_acl_t *src_acl = NULL;
04748 isc_result_t result;
04749 isc_sockaddr_t any_sa6;
04750 isc_netaddr_t netaddr;
04751
04752 REQUIRE(isc_sockaddr_pf(addr) == AF_INET6);
04753
04754 isc_sockaddr_any6(&any_sa6);
04755 if (!isc_sockaddr_equal(&any_sa6, addr) &&
04756 (wcardport_ok || isc_sockaddr_getport(addr) != 0)) {
04757 isc_netaddr_fromin6(&netaddr, &addr->type.sin6.sin6_addr);
04758
04759 result = dns_acl_create(mctx, 0, &src_acl);
04760 if (result != ISC_R_SUCCESS)
04761 return (result);
04762
04763 result = dns_iptable_addprefix(src_acl->iptable,
04764 &netaddr, 128, ISC_TRUE);
04765 if (result != ISC_R_SUCCESS)
04766 goto clean;
04767
04768 result = ns_listenelt_create(mctx, isc_sockaddr_getport(addr),
04769 dscp, src_acl, &lelt);
04770 if (result != ISC_R_SUCCESS)
04771 goto clean;
04772 ISC_LIST_APPEND(list->elts, lelt, link);
04773 }
04774
04775 return (ISC_R_SUCCESS);
04776
04777 clean:
04778 INSIST(lelt == NULL);
04779 dns_acl_detach(&src_acl);
04780
04781 return (result);
04782 }
04783
04784
04785
04786
04787
04788
04789
04790 static void
04791 adjust_interfaces(ns_server_t *server, isc_mem_t *mctx) {
04792 isc_result_t result;
04793 ns_listenlist_t *list = NULL;
04794 dns_view_t *view;
04795 dns_zone_t *zone, *next;
04796 isc_sockaddr_t addr, *addrp;
04797 isc_dscp_t dscp = -1;
04798
04799 result = ns_listenlist_create(mctx, &list);
04800 if (result != ISC_R_SUCCESS)
04801 return;
04802
04803 for (view = ISC_LIST_HEAD(server->viewlist);
04804 view != NULL;
04805 view = ISC_LIST_NEXT(view, link)) {
04806 dns_dispatch_t *dispatch6;
04807
04808 dispatch6 = dns_resolver_dispatchv6(view->resolver);
04809 if (dispatch6 == NULL)
04810 continue;
04811 result = dns_dispatch_getlocaladdress(dispatch6, &addr);
04812 if (result != ISC_R_SUCCESS)
04813 goto fail;
04814
04815
04816
04817
04818
04819
04820
04821
04822
04823
04824 result = add_listenelt(mctx, list, &addr, dscp, ISC_TRUE);
04825 if (result != ISC_R_SUCCESS)
04826 goto fail;
04827 }
04828
04829 zone = NULL;
04830 for (result = dns_zone_first(server->zonemgr, &zone);
04831 result == ISC_R_SUCCESS;
04832 next = NULL, result = dns_zone_next(zone, &next), zone = next) {
04833 dns_view_t *zoneview;
04834
04835
04836
04837
04838
04839
04840
04841
04842
04843 zoneview = dns_zone_getview(zone);
04844 if (zoneview == NULL)
04845 continue;
04846 for (view = ISC_LIST_HEAD(server->viewlist);
04847 view != NULL && view != zoneview;
04848 view = ISC_LIST_NEXT(view, link))
04849 ;
04850 if (view == NULL)
04851 continue;
04852
04853 addrp = dns_zone_getnotifysrc6(zone);
04854 dscp = dns_zone_getnotifysrc6dscp(zone);
04855 result = add_listenelt(mctx, list, addrp, dscp, ISC_FALSE);
04856 if (result != ISC_R_SUCCESS)
04857 goto fail;
04858
04859 addrp = dns_zone_getxfrsource6(zone);
04860 dscp = dns_zone_getxfrsource6dscp(zone);
04861 result = add_listenelt(mctx, list, addrp, dscp, ISC_FALSE);
04862 if (result != ISC_R_SUCCESS)
04863 goto fail;
04864 }
04865
04866 ns_interfacemgr_adjust(server->interfacemgr, list, ISC_TRUE);
04867
04868 clean:
04869 ns_listenlist_detach(&list);
04870 return;
04871
04872 fail:
04873
04874
04875
04876
04877 isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
04878 NS_LOGMODULE_SERVER, ISC_LOG_WARNING,
04879 "could not adjust the listen-on list; "
04880 "some interfaces may not work");
04881 goto clean;
04882 }
04883
04884
04885
04886
04887
04888
04889
04890 static void
04891 interface_timer_tick(isc_task_t *task, isc_event_t *event) {
04892 isc_result_t result;
04893 ns_server_t *server = (ns_server_t *) event->ev_arg;
04894 INSIST(task == server->task);
04895 UNUSED(task);
04896
04897 isc_event_free(&event);
04898
04899
04900
04901
04902
04903 result = isc_task_beginexclusive(server->task);
04904 RUNTIME_CHECK(result == ISC_R_SUCCESS);
04905 scan_interfaces(server, ISC_FALSE);
04906 isc_task_endexclusive(server->task);
04907 }
04908
04909 static void
04910 heartbeat_timer_tick(isc_task_t *task, isc_event_t *event) {
04911 ns_server_t *server = (ns_server_t *) event->ev_arg;
04912 dns_view_t *view;
04913
04914 UNUSED(task);
04915 isc_event_free(&event);
04916 view = ISC_LIST_HEAD(server->viewlist);
04917 while (view != NULL) {
04918 dns_view_dialup(view);
04919 view = ISC_LIST_NEXT(view, link);
04920 }
04921 }
04922
04923 static void
04924 pps_timer_tick(isc_task_t *task, isc_event_t *event) {
04925 static unsigned int oldrequests = 0;
04926 unsigned int requests = ns_client_requests;
04927
04928 UNUSED(task);
04929 isc_event_free(&event);
04930
04931
04932
04933
04934 dns_pps = (requests - oldrequests) / 1200;
04935 oldrequests = requests;
04936 }
04937
04938
04939
04940
04941
04942
04943 static isc_result_t
04944 setstring(ns_server_t *server, char **field, const char *value) {
04945 char *copy;
04946
04947 if (value != NULL) {
04948 copy = isc_mem_strdup(server->mctx, value);
04949 if (copy == NULL)
04950 return (ISC_R_NOMEMORY);
04951 } else {
04952 copy = NULL;
04953 }
04954
04955 if (*field != NULL)
04956 isc_mem_free(server->mctx, *field);
04957
04958 *field = copy;
04959 return (ISC_R_SUCCESS);
04960 }
04961
04962
04963
04964
04965
04966
04967 static isc_result_t
04968 setoptstring(ns_server_t *server, char **field, const cfg_obj_t *obj) {
04969 if (cfg_obj_isvoid(obj))
04970 return (setstring(server, field, NULL));
04971 else
04972 return (setstring(server, field, cfg_obj_asstring(obj)));
04973 }
04974
04975 static void
04976 set_limit(const cfg_obj_t **maps, const char *configname,
04977 const char *description, isc_resource_t resourceid,
04978 isc_resourcevalue_t defaultvalue)
04979 {
04980 const cfg_obj_t *obj = NULL;
04981 const char *resource;
04982 isc_resourcevalue_t value;
04983 isc_result_t result;
04984
04985 if (ns_config_get(maps, configname, &obj) != ISC_R_SUCCESS)
04986 return;
04987
04988 if (cfg_obj_isstring(obj)) {
04989 resource = cfg_obj_asstring(obj);
04990 if (strcasecmp(resource, "unlimited") == 0)
04991 value = ISC_RESOURCE_UNLIMITED;
04992 else {
04993 INSIST(strcasecmp(resource, "default") == 0);
04994 value = defaultvalue;
04995 }
04996 } else
04997 value = cfg_obj_asuint64(obj);
04998
04999 result = isc_resource_setlimit(resourceid, value);
05000 isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER,
05001 result == ISC_R_SUCCESS ?
05002 ISC_LOG_DEBUG(3) : ISC_LOG_WARNING,
05003 "set maximum %s to %" ISC_PRINT_QUADFORMAT "u: %s",
05004 description, value, isc_result_totext(result));
05005 }
05006
05007 #define SETLIMIT(cfgvar, resource, description) \
05008 set_limit(maps, cfgvar, description, isc_resource_ ## resource, \
05009 ns_g_init ## resource)
05010
05011 static void
05012 set_limits(const cfg_obj_t **maps) {
05013 SETLIMIT("stacksize", stacksize, "stack size");
05014 SETLIMIT("datasize", datasize, "data size");
05015 SETLIMIT("coresize", coresize, "core size");
05016 SETLIMIT("files", openfiles, "open files");
05017 }
05018
05019 static void
05020 portset_fromconf(isc_portset_t *portset, const cfg_obj_t *ports,
05021 isc_boolean_t positive)
05022 {
05023 const cfg_listelt_t *element;
05024
05025 for (element = cfg_list_first(ports);
05026 element != NULL;
05027 element = cfg_list_next(element)) {
05028 const cfg_obj_t *obj = cfg_listelt_value(element);
05029
05030 if (cfg_obj_isuint32(obj)) {
05031 in_port_t port = (in_port_t)cfg_obj_asuint32(obj);
05032
05033 if (positive)
05034 isc_portset_add(portset, port);
05035 else
05036 isc_portset_remove(portset, port);
05037 } else {
05038 const cfg_obj_t *obj_loport, *obj_hiport;
05039 in_port_t loport, hiport;
05040
05041 obj_loport = cfg_tuple_get(obj, "loport");
05042 loport = (in_port_t)cfg_obj_asuint32(obj_loport);
05043 obj_hiport = cfg_tuple_get(obj, "hiport");
05044 hiport = (in_port_t)cfg_obj_asuint32(obj_hiport);
05045
05046 if (positive)
05047 isc_portset_addrange(portset, loport, hiport);
05048 else {
05049 isc_portset_removerange(portset, loport,
05050 hiport);
05051 }
05052 }
05053 }
05054 }
05055
05056 static isc_result_t
05057 removed(dns_zone_t *zone, void *uap) {
05058 const char *type;
05059
05060 if (dns_zone_getview(zone) != uap)
05061 return (ISC_R_SUCCESS);
05062
05063 switch (dns_zone_gettype(zone)) {
05064 case dns_zone_master:
05065 type = "master";
05066 break;
05067 case dns_zone_slave:
05068 type = "slave";
05069 break;
05070 case dns_zone_stub:
05071 type = "stub";
05072 break;
05073 case dns_zone_staticstub:
05074 type = "static-stub";
05075 break;
05076 case dns_zone_redirect:
05077 type = "redirect";
05078 break;
05079 default:
05080 type = "other";
05081 break;
05082 }
05083 dns_zone_log(zone, ISC_LOG_INFO, "(%s) removed", type);
05084 return (ISC_R_SUCCESS);
05085 }
05086
05087 static void
05088 cleanup_session_key(ns_server_t *server, isc_mem_t *mctx) {
05089 if (server->session_keyfile != NULL) {
05090 isc_file_remove(server->session_keyfile);
05091 isc_mem_free(mctx, server->session_keyfile);
05092 server->session_keyfile = NULL;
05093 }
05094
05095 if (server->session_keyname != NULL) {
05096 if (dns_name_dynamic(server->session_keyname))
05097 dns_name_free(server->session_keyname, mctx);
05098 isc_mem_put(mctx, server->session_keyname, sizeof(dns_name_t));
05099 server->session_keyname = NULL;
05100 }
05101
05102 if (server->sessionkey != NULL)
05103 dns_tsigkey_detach(&server->sessionkey);
05104
05105 server->session_keyalg = DST_ALG_UNKNOWN;
05106 server->session_keybits = 0;
05107 }
05108
05109 static isc_result_t
05110 generate_session_key(const char *filename, const char *keynamestr,
05111 dns_name_t *keyname, const char *algstr,
05112 dns_name_t *algname, unsigned int algtype,
05113 isc_uint16_t bits, isc_mem_t *mctx,
05114 dns_tsigkey_t **tsigkeyp)
05115 {
05116 isc_result_t result = ISC_R_SUCCESS;
05117 dst_key_t *key = NULL;
05118 isc_buffer_t key_txtbuffer;
05119 isc_buffer_t key_rawbuffer;
05120 char key_txtsecret[256];
05121 char key_rawsecret[64];
05122 isc_region_t key_rawregion;
05123 isc_stdtime_t now;
05124 dns_tsigkey_t *tsigkey = NULL;
05125 FILE *fp = NULL;
05126
05127 isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
05128 NS_LOGMODULE_SERVER, ISC_LOG_INFO,
05129 "generating session key for dynamic DNS");
05130
05131
05132 result = dst_key_generate(keyname, algtype, bits, 1, 0,
05133 DNS_KEYPROTO_ANY, dns_rdataclass_in,
05134 mctx, &key);
05135 if (result != ISC_R_SUCCESS)
05136 return (result);
05137
05138
05139
05140
05141
05142 isc_buffer_init(&key_rawbuffer, &key_rawsecret, sizeof(key_rawsecret));
05143 CHECK(dst_key_tobuffer(key, &key_rawbuffer));
05144
05145 isc_buffer_usedregion(&key_rawbuffer, &key_rawregion);
05146 isc_buffer_init(&key_txtbuffer, &key_txtsecret, sizeof(key_txtsecret));
05147 CHECK(isc_base64_totext(&key_rawregion, -1, "", &key_txtbuffer));
05148
05149
05150 isc_stdtime_get(&now);
05151 CHECK(dns_tsigkey_createfromkey(dst_key_name(key), algname, key,
05152 ISC_FALSE, NULL, now, now, mctx, NULL,
05153 &tsigkey));
05154
05155
05156 fp = ns_os_openfile(filename, S_IRUSR|S_IWUSR, ISC_TRUE);
05157 if (fp == NULL) {
05158 isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
05159 NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
05160 "could not create %s", filename);
05161 result = ISC_R_NOPERM;
05162 goto cleanup;
05163 }
05164
05165 fprintf(fp, "key \"%s\" {\n"
05166 "\talgorithm %s;\n"
05167 "\tsecret \"%.*s\";\n};\n", keynamestr, algstr,
05168 (int) isc_buffer_usedlength(&key_txtbuffer),
05169 (char*) isc_buffer_base(&key_txtbuffer));
05170
05171 CHECK(isc_stdio_flush(fp));
05172 CHECK(isc_stdio_close(fp));
05173
05174 dst_key_free(&key);
05175
05176 *tsigkeyp = tsigkey;
05177
05178 return (ISC_R_SUCCESS);
05179
05180 cleanup:
05181 isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
05182 NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
05183 "failed to generate session key "
05184 "for dynamic DNS: %s", isc_result_totext(result));
05185 if (fp != NULL) {
05186 (void)isc_stdio_close(fp);
05187 (void)isc_file_remove(filename);
05188 }
05189 if (tsigkey != NULL)
05190 dns_tsigkey_detach(&tsigkey);
05191 if (key != NULL)
05192 dst_key_free(&key);
05193
05194 return (result);
05195 }
05196
05197 static isc_result_t
05198 configure_session_key(const cfg_obj_t **maps, ns_server_t *server,
05199 isc_mem_t *mctx)
05200 {
05201 const char *keyfile, *keynamestr, *algstr;
05202 unsigned int algtype;
05203 dns_fixedname_t fname;
05204 dns_name_t *keyname, *algname;
05205 isc_buffer_t buffer;
05206 isc_uint16_t bits;
05207 const cfg_obj_t *obj;
05208 isc_boolean_t need_deleteold = ISC_FALSE;
05209 isc_boolean_t need_createnew = ISC_FALSE;
05210 isc_result_t result;
05211
05212 obj = NULL;
05213 result = ns_config_get(maps, "session-keyfile", &obj);
05214 if (result == ISC_R_SUCCESS) {
05215 if (cfg_obj_isvoid(obj))
05216 keyfile = NULL;
05217 else
05218 keyfile = cfg_obj_asstring(obj);
05219 } else
05220 keyfile = ns_g_defaultsessionkeyfile;
05221
05222 obj = NULL;
05223 result = ns_config_get(maps, "session-keyname", &obj);
05224 INSIST(result == ISC_R_SUCCESS);
05225 keynamestr = cfg_obj_asstring(obj);
05226 dns_fixedname_init(&fname);
05227 isc_buffer_constinit(&buffer, keynamestr, strlen(keynamestr));
05228 isc_buffer_add(&buffer, strlen(keynamestr));
05229 keyname = dns_fixedname_name(&fname);
05230 result = dns_name_fromtext(keyname, &buffer, dns_rootname, 0, NULL);
05231 if (result != ISC_R_SUCCESS)
05232 return (result);
05233
05234 obj = NULL;
05235 result = ns_config_get(maps, "session-keyalg", &obj);
05236 INSIST(result == ISC_R_SUCCESS);
05237 algstr = cfg_obj_asstring(obj);
05238 algname = NULL;
05239 result = ns_config_getkeyalgorithm2(algstr, &algname, &algtype, &bits);
05240 if (result != ISC_R_SUCCESS) {
05241 const char *s = " (keeping current key)";
05242
05243 cfg_obj_log(obj, ns_g_lctx, ISC_LOG_ERROR, "session-keyalg: "
05244 "unsupported or unknown algorithm '%s'%s",
05245 algstr,
05246 server->session_keyfile != NULL ? s : "");
05247 return (result);
05248 }
05249
05250
05251 if (keyfile == NULL) {
05252 if (server->session_keyfile != NULL)
05253 need_deleteold = ISC_TRUE;
05254 } else if (server->session_keyfile == NULL)
05255 need_createnew = ISC_TRUE;
05256 else if (strcmp(keyfile, server->session_keyfile) != 0 ||
05257 !dns_name_equal(server->session_keyname, keyname) ||
05258 server->session_keyalg != algtype ||
05259 server->session_keybits != bits) {
05260 need_deleteold = ISC_TRUE;
05261 need_createnew = ISC_TRUE;
05262 }
05263
05264 if (need_deleteold) {
05265 INSIST(server->session_keyfile != NULL);
05266 INSIST(server->session_keyname != NULL);
05267 INSIST(server->sessionkey != NULL);
05268
05269 cleanup_session_key(server, mctx);
05270 }
05271
05272 if (need_createnew) {
05273 INSIST(server->sessionkey == NULL);
05274 INSIST(server->session_keyfile == NULL);
05275 INSIST(server->session_keyname == NULL);
05276 INSIST(server->session_keyalg == DST_ALG_UNKNOWN);
05277 INSIST(server->session_keybits == 0);
05278
05279 server->session_keyname = isc_mem_get(mctx, sizeof(dns_name_t));
05280 if (server->session_keyname == NULL)
05281 goto cleanup;
05282 dns_name_init(server->session_keyname, NULL);
05283 CHECK(dns_name_dup(keyname, mctx, server->session_keyname));
05284
05285 server->session_keyfile = isc_mem_strdup(mctx, keyfile);
05286 if (server->session_keyfile == NULL)
05287 goto cleanup;
05288
05289 server->session_keyalg = algtype;
05290 server->session_keybits = bits;
05291
05292 CHECK(generate_session_key(keyfile, keynamestr, keyname, algstr,
05293 algname, algtype, bits, mctx,
05294 &server->sessionkey));
05295 }
05296
05297 return (result);
05298
05299 cleanup:
05300 cleanup_session_key(server, mctx);
05301 return (result);
05302 }
05303
05304 static isc_result_t
05305 setup_newzones(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
05306 cfg_parser_t *conf_parser, cfg_aclconfctx_t *actx)
05307 {
05308 isc_result_t result = ISC_R_SUCCESS;
05309 isc_boolean_t allow = ISC_FALSE;
05310 ns_cfgctx_t *nzcfg = NULL;
05311 const cfg_obj_t *maps[4];
05312 const cfg_obj_t *options = NULL, *voptions = NULL;
05313 const cfg_obj_t *nz = NULL;
05314 int i = 0;
05315
05316 REQUIRE (config != NULL);
05317
05318 if (vconfig != NULL)
05319 voptions = cfg_tuple_get(vconfig, "options");
05320 if (voptions != NULL)
05321 maps[i++] = voptions;
05322 result = cfg_map_get(config, "options", &options);
05323 if (result == ISC_R_SUCCESS)
05324 maps[i++] = options;
05325 maps[i++] = ns_g_defaults;
05326 maps[i] = NULL;
05327
05328 result = ns_config_get(maps, "allow-new-zones", &nz);
05329 if (result == ISC_R_SUCCESS)
05330 allow = cfg_obj_asboolean(nz);
05331
05332 if (!allow) {
05333 dns_view_setnewzones(view, ISC_FALSE, NULL, NULL);
05334 return (ISC_R_SUCCESS);
05335 }
05336
05337 nzcfg = isc_mem_get(view->mctx, sizeof(*nzcfg));
05338 if (nzcfg == NULL) {
05339 dns_view_setnewzones(view, ISC_FALSE, NULL, NULL);
05340 return (ISC_R_NOMEMORY);
05341 }
05342
05343 memset(nzcfg, 0, sizeof(*nzcfg));
05344
05345 dns_view_setnewzones(view, allow, nzcfg, newzone_cfgctx_destroy);
05346
05347 cfg_obj_attach(config, &nzcfg->config);
05348 if (vconfig != NULL)
05349 cfg_obj_attach(vconfig, &nzcfg->vconfig);
05350
05351
05352
05353
05354
05355
05356 cfg_parser_attach(conf_parser, &nzcfg->conf_parser);
05357 cfg_parser_attach(ns_g_addparser, &nzcfg->add_parser);
05358 isc_mem_attach(view->mctx, &nzcfg->mctx);
05359 cfg_aclconfctx_attach(actx, &nzcfg->actx);
05360
05361
05362
05363
05364
05365 cfg_parser_reset(ns_g_addparser);
05366 result = cfg_parse_file(ns_g_addparser, view->new_zone_file,
05367 &cfg_type_newzones, &nzcfg->nzconfig);
05368
05369 return (ISC_R_SUCCESS);
05370 }
05371
05372 static int
05373 count_zones(const cfg_obj_t *conf) {
05374 const cfg_obj_t *zonelist = NULL;
05375 const cfg_listelt_t *element;
05376 int n = 0;
05377
05378 REQUIRE(conf != NULL);
05379
05380 cfg_map_get(conf, "zone", &zonelist);
05381 for (element = cfg_list_first(zonelist);
05382 element != NULL;
05383 element = cfg_list_next(element))
05384 n++;
05385
05386 return (n);
05387 }
05388
05389 static isc_result_t
05390 check_lockfile(ns_server_t *server, const cfg_obj_t *config,
05391 isc_boolean_t first_time)
05392 {
05393 isc_result_t result;
05394 const char *filename = NULL;
05395 const cfg_obj_t *maps[3];
05396 const cfg_obj_t *options;
05397 const cfg_obj_t *obj;
05398 int i;
05399
05400 i = 0;
05401 options = NULL;
05402 result = cfg_map_get(config, "options", &options);
05403 if (result == ISC_R_SUCCESS)
05404 maps[i++] = options;
05405 maps[i++] = ns_g_defaults;
05406 maps[i] = NULL;
05407
05408 obj = NULL;
05409 (void) ns_config_get(maps, "lock-file", &obj);
05410
05411 if (!first_time) {
05412 if (obj != NULL && !cfg_obj_isstring(obj) &&
05413 server->lockfile != NULL &&
05414 strcmp(cfg_obj_asstring(obj), server->lockfile) != 0)
05415 isc_log_write(ns_g_lctx,
05416 NS_LOGCATEGORY_GENERAL,
05417 NS_LOGMODULE_SERVER,
05418 ISC_LOG_WARNING,
05419 "changing 'lock-file' "
05420 "has no effect until the "
05421 "server is restarted");
05422
05423 return (ISC_R_SUCCESS);
05424 }
05425
05426 if (obj != NULL) {
05427 if (cfg_obj_isvoid(obj)) {
05428 isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
05429 NS_LOGMODULE_SERVER, ISC_LOG_DEBUG(1),
05430 "skipping lock-file check ");
05431 return (ISC_R_SUCCESS);
05432 } else if (ns_g_forcelock) {
05433 isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
05434 NS_LOGMODULE_SERVER, ISC_LOG_WARNING,
05435 "'lock-file' has no effect "
05436 "because the server was run with -X");
05437 server->lockfile = isc_mem_strdup(server->mctx,
05438 ns_g_defaultlockfile);
05439 } else {
05440 filename = cfg_obj_asstring(obj);
05441 server->lockfile = isc_mem_strdup(server->mctx,
05442 filename);
05443 }
05444
05445 if (server->lockfile == NULL)
05446 return (ISC_R_NOMEMORY);
05447 }
05448
05449 if (ns_g_forcelock && ns_g_defaultlockfile != NULL) {
05450 INSIST(server->lockfile == NULL);
05451 server->lockfile = isc_mem_strdup(server->mctx,
05452 ns_g_defaultlockfile);
05453 }
05454
05455 if (server->lockfile == NULL)
05456 return (ISC_R_SUCCESS);
05457
05458 if (ns_os_issingleton(server->lockfile))
05459 return (ISC_R_SUCCESS);
05460
05461 isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
05462 NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
05463 "could not lock %s; another named "
05464 "process may be running", server->lockfile);
05465 return (ISC_R_FAILURE);
05466 }
05467
05468 static isc_result_t
05469 load_configuration(const char *filename, ns_server_t *server,
05470 isc_boolean_t first_time)
05471 {
05472 cfg_obj_t *config = NULL, *bindkeys = NULL;
05473 cfg_parser_t *conf_parser = NULL, *bindkeys_parser = NULL;
05474 const cfg_listelt_t *element;
05475 const cfg_obj_t *builtin_views;
05476 const cfg_obj_t *maps[3];
05477 const cfg_obj_t *obj;
05478 const cfg_obj_t *options;
05479 const cfg_obj_t *usev4ports, *avoidv4ports, *usev6ports, *avoidv6ports;
05480 const cfg_obj_t *views;
05481 dns_view_t *view = NULL;
05482 dns_view_t *view_next;
05483 dns_viewlist_t tmpviewlist;
05484 dns_viewlist_t viewlist, builtin_viewlist;
05485 in_port_t listen_port, udpport_low, udpport_high;
05486 int i;
05487 int num_zones = 0;
05488 isc_boolean_t exclusive = ISC_FALSE;
05489 isc_interval_t interval;
05490 isc_logconfig_t *logc = NULL;
05491 isc_portset_t *v4portset = NULL;
05492 isc_portset_t *v6portset = NULL;
05493 isc_resourcevalue_t nfiles;
05494 isc_result_t result, tresult;
05495 isc_uint32_t heartbeat_interval;
05496 isc_uint32_t interface_interval;
05497 isc_uint32_t reserved;
05498 isc_uint32_t udpsize;
05499 ns_cache_t *nsc;
05500 ns_cachelist_t cachelist, tmpcachelist;
05501 ns_cfgctx_t *nzctx;
05502 unsigned int maxsocks;
05503
05504 ISC_LIST_INIT(viewlist);
05505 ISC_LIST_INIT(builtin_viewlist);
05506 ISC_LIST_INIT(cachelist);
05507
05508
05509 if (ns_g_aclconfctx != NULL)
05510 cfg_aclconfctx_detach(&ns_g_aclconfctx);
05511 CHECK(cfg_aclconfctx_create(ns_g_mctx, &ns_g_aclconfctx));
05512
05513
05514
05515
05516 if (first_time) {
05517 CHECK(ns_config_parsedefaults(ns_g_parser, &ns_g_config));
05518 RUNTIME_CHECK(cfg_map_get(ns_g_config, "options",
05519 &ns_g_defaults) == ISC_R_SUCCESS);
05520 }
05521
05522
05523
05524
05525 result = ISC_R_FAILURE;
05526 config = NULL;
05527
05528
05529
05530
05531 if (!(ns_g_lwresdonly && lwresd_g_useresolvconf)) {
05532 isc_log_write(ns_g_lctx,
05533 NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER,
05534 ISC_LOG_INFO, "loading configuration from '%s'",
05535 filename);
05536 CHECK(cfg_parser_create(ns_g_mctx, ns_g_lctx, &conf_parser));
05537 cfg_parser_setcallback(conf_parser, directory_callback, NULL);
05538 result = cfg_parse_file(conf_parser, filename,
05539 &cfg_type_namedconf, &config);
05540 }
05541
05542
05543
05544
05545
05546 if (ns_g_lwresdonly &&
05547 (lwresd_g_useresolvconf ||
05548 (!ns_g_conffileset && result == ISC_R_FILENOTFOUND)))
05549 {
05550 isc_log_write(ns_g_lctx,
05551 NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER,
05552 ISC_LOG_INFO, "loading configuration from '%s'",
05553 lwresd_g_resolvconffile);
05554 if (conf_parser != NULL)
05555 cfg_parser_destroy(&conf_parser);
05556 CHECK(cfg_parser_create(ns_g_mctx, ns_g_lctx, &conf_parser));
05557 result = ns_lwresd_parseeresolvconf(ns_g_mctx, conf_parser,
05558 &config);
05559 }
05560 CHECK(result);
05561
05562
05563
05564
05565 CHECK(bind9_check_namedconf(config, ns_g_lctx, ns_g_mctx));
05566
05567
05568
05569
05570 i = 0;
05571 options = NULL;
05572 result = cfg_map_get(config, "options", &options);
05573 if (result == ISC_R_SUCCESS)
05574 maps[i++] = options;
05575 maps[i++] = ns_g_defaults;
05576 maps[i] = NULL;
05577
05578
05579
05580
05581
05582
05583
05584 obj = NULL;
05585 result = ns_config_get(maps, "bindkeys-file", &obj);
05586 INSIST(result == ISC_R_SUCCESS);
05587 CHECKM(setstring(server, &server->bindkeysfile,
05588 cfg_obj_asstring(obj)), "strdup");
05589
05590 if (access(server->bindkeysfile, R_OK) == 0) {
05591 isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
05592 NS_LOGMODULE_SERVER, ISC_LOG_INFO,
05593 "reading built-in trusted "
05594 "keys from file '%s'", server->bindkeysfile);
05595
05596 CHECK(cfg_parser_create(ns_g_mctx, ns_g_lctx,
05597 &bindkeys_parser));
05598
05599 result = cfg_parse_file(bindkeys_parser, server->bindkeysfile,
05600 &cfg_type_bindkeys, &bindkeys);
05601 CHECK(result);
05602 }
05603
05604
05605 if (!exclusive) {
05606 result = isc_task_beginexclusive(server->task);
05607 RUNTIME_CHECK(result == ISC_R_SUCCESS);
05608 exclusive = ISC_TRUE;
05609 }
05610
05611
05612
05613
05614 set_limits(maps);
05615
05616
05617
05618
05619 CHECK(check_lockfile(server, config, first_time));
05620
05621
05622
05623
05624
05625
05626
05627 result = isc_socketmgr_getmaxsockets(ns_g_socketmgr, &maxsocks);
05628 if (result != ISC_R_SUCCESS)
05629 maxsocks = 0;
05630 result = isc_resource_getcurlimit(isc_resource_openfiles, &nfiles);
05631 if (result == ISC_R_SUCCESS && (isc_resourcevalue_t)maxsocks > nfiles) {
05632 isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
05633 NS_LOGMODULE_SERVER, ISC_LOG_WARNING,
05634 "max open files (%" ISC_PRINT_QUADFORMAT "u)"
05635 " is smaller than max sockets (%u)",
05636 nfiles, maxsocks);
05637 }
05638
05639
05640
05641
05642 obj = NULL;
05643 result = ns_config_get(maps, "reserved-sockets", &obj);
05644 INSIST(result == ISC_R_SUCCESS);
05645 reserved = cfg_obj_asuint32(obj);
05646 if (maxsocks != 0) {
05647 if (maxsocks < 128U)
05648 reserved = 0;
05649 else if (reserved > maxsocks - 128U)
05650 reserved = maxsocks - 128;
05651 }
05652
05653 if (reserved < 128U)
05654 reserved = 128;
05655 if (reserved + 128U > maxsocks && maxsocks != 0) {
05656 isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
05657 NS_LOGMODULE_SERVER, ISC_LOG_WARNING,
05658 "less than 128 UDP sockets available after "
05659 "applying 'reserved-sockets' and 'maxsockets'");
05660 }
05661 isc__socketmgr_setreserved(ns_g_socketmgr, reserved);
05662
05663 #ifdef HAVE_GEOIP
05664
05665
05666
05667
05668
05669
05670 obj = NULL;
05671 result = ns_config_get(maps, "geoip-directory", &obj);
05672 if (result == ISC_R_SUCCESS && cfg_obj_isstring(obj)) {
05673 char *dir;
05674 DE_CONST(cfg_obj_asstring(obj), dir);
05675 ns_geoip_load(dir);
05676 } else
05677 ns_geoip_load(NULL);
05678 ns_g_aclconfctx->geoip = ns_g_geoip;
05679
05680 obj = NULL;
05681 result = ns_config_get(maps, "geoip-use-ecs", &obj);
05682 INSIST(result == ISC_R_SUCCESS);
05683 ns_g_server->aclenv.geoip_use_ecs = cfg_obj_asboolean(obj);
05684 #endif
05685
05686
05687
05688
05689 configure_server_quota(maps, "transfers-out", &server->xfroutquota);
05690 configure_server_quota(maps, "tcp-clients", &server->tcpquota);
05691 configure_server_quota(maps, "recursive-clients",
05692 &server->recursionquota);
05693 if (server->recursionquota.max > 1000)
05694 isc_quota_soft(&server->recursionquota,
05695 server->recursionquota.max - 100);
05696 else
05697 isc_quota_soft(&server->recursionquota, 0);
05698
05699 CHECK(configure_view_acl(NULL, config, "blackhole", NULL,
05700 ns_g_aclconfctx, ns_g_mctx,
05701 &server->blackholeacl));
05702 if (server->blackholeacl != NULL)
05703 dns_dispatchmgr_setblackhole(ns_g_dispatchmgr,
05704 server->blackholeacl);
05705
05706 CHECK(configure_view_acl(NULL, config, "keep-response-order", NULL,
05707 ns_g_aclconfctx, ns_g_mctx,
05708 &server->keepresporder));
05709
05710 obj = NULL;
05711 result = ns_config_get(maps, "match-mapped-addresses", &obj);
05712 INSIST(result == ISC_R_SUCCESS);
05713 server->aclenv.match_mapped = cfg_obj_asboolean(obj);
05714
05715 CHECKM(ns_statschannels_configure(ns_g_server, config, ns_g_aclconfctx),
05716 "configuring statistics server(s)");
05717
05718
05719
05720
05721 CHECKM(isc_portset_create(ns_g_mctx, &v4portset),
05722 "creating UDP port set");
05723 CHECKM(isc_portset_create(ns_g_mctx, &v6portset),
05724 "creating UDP port set");
05725
05726 usev4ports = NULL;
05727 usev6ports = NULL;
05728 avoidv4ports = NULL;
05729 avoidv6ports = NULL;
05730
05731 (void)ns_config_get(maps, "use-v4-udp-ports", &usev4ports);
05732 if (usev4ports != NULL)
05733 portset_fromconf(v4portset, usev4ports, ISC_TRUE);
05734 else {
05735 CHECKM(isc_net_getudpportrange(AF_INET, &udpport_low,
05736 &udpport_high),
05737 "get the default UDP/IPv4 port range");
05738 if (udpport_low == udpport_high)
05739 isc_portset_add(v4portset, udpport_low);
05740 else {
05741 isc_portset_addrange(v4portset, udpport_low,
05742 udpport_high);
05743 }
05744 if (!ns_g_disable4)
05745 isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
05746 NS_LOGMODULE_SERVER, ISC_LOG_INFO,
05747 "using default UDP/IPv4 port range: "
05748 "[%d, %d]", udpport_low, udpport_high);
05749 }
05750 (void)ns_config_get(maps, "avoid-v4-udp-ports", &avoidv4ports);
05751 if (avoidv4ports != NULL)
05752 portset_fromconf(v4portset, avoidv4ports, ISC_FALSE);
05753
05754 (void)ns_config_get(maps, "use-v6-udp-ports", &usev6ports);
05755 if (usev6ports != NULL)
05756 portset_fromconf(v6portset, usev6ports, ISC_TRUE);
05757 else {
05758 CHECKM(isc_net_getudpportrange(AF_INET6, &udpport_low,
05759 &udpport_high),
05760 "get the default UDP/IPv6 port range");
05761 if (udpport_low == udpport_high)
05762 isc_portset_add(v6portset, udpport_low);
05763 else {
05764 isc_portset_addrange(v6portset, udpport_low,
05765 udpport_high);
05766 }
05767 if (!ns_g_disable6)
05768 isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
05769 NS_LOGMODULE_SERVER, ISC_LOG_INFO,
05770 "using default UDP/IPv6 port range: "
05771 "[%d, %d]", udpport_low, udpport_high);
05772 }
05773 (void)ns_config_get(maps, "avoid-v6-udp-ports", &avoidv6ports);
05774 if (avoidv6ports != NULL)
05775 portset_fromconf(v6portset, avoidv6ports, ISC_FALSE);
05776
05777 dns_dispatchmgr_setavailports(ns_g_dispatchmgr, v4portset, v6portset);
05778
05779
05780
05781
05782 obj = NULL;
05783 result = ns_config_get(maps, "edns-udp-size", &obj);
05784 INSIST(result == ISC_R_SUCCESS);
05785 udpsize = cfg_obj_asuint32(obj);
05786 if (udpsize < 512)
05787 udpsize = 512;
05788 if (udpsize > 4096)
05789 udpsize = 4096;
05790 ns_g_udpsize = (isc_uint16_t)udpsize;
05791
05792
05793
05794
05795 obj = NULL;
05796 result = ns_config_get(maps, "transfers-in", &obj);
05797 INSIST(result == ISC_R_SUCCESS);
05798 dns_zonemgr_settransfersin(server->zonemgr, cfg_obj_asuint32(obj));
05799
05800 obj = NULL;
05801 result = ns_config_get(maps, "transfers-per-ns", &obj);
05802 INSIST(result == ISC_R_SUCCESS);
05803 dns_zonemgr_settransfersperns(server->zonemgr, cfg_obj_asuint32(obj));
05804
05805 obj = NULL;
05806 result = ns_config_get(maps, "notify-rate", &obj);
05807 INSIST(result == ISC_R_SUCCESS);
05808 dns_zonemgr_setnotifyrate(server->zonemgr, cfg_obj_asuint32(obj));
05809
05810 obj = NULL;
05811 result = ns_config_get(maps, "startup-notify-rate", &obj);
05812 INSIST(result == ISC_R_SUCCESS);
05813 dns_zonemgr_setstartupnotifyrate(server->zonemgr, cfg_obj_asuint32(obj));
05814
05815 obj = NULL;
05816 result = ns_config_get(maps, "serial-query-rate", &obj);
05817 INSIST(result == ISC_R_SUCCESS);
05818 dns_zonemgr_setserialqueryrate(server->zonemgr, cfg_obj_asuint32(obj));
05819
05820
05821
05822
05823 if (ns_g_port != 0)
05824 listen_port = ns_g_port;
05825 else
05826 CHECKM(ns_config_getport(config, &listen_port), "port");
05827
05828
05829
05830
05831 CHECKM(ns_config_getdscp(config, &ns_g_dscp), "dscp");
05832
05833
05834
05835
05836 obj = NULL;
05837 result = ns_config_get(maps, "tcp-listen-queue", &obj);
05838 INSIST(result == ISC_R_SUCCESS);
05839 ns_g_listen = cfg_obj_asuint32(obj);
05840 if ((ns_g_listen > 0) && (ns_g_listen < 10))
05841 ns_g_listen = 10;
05842
05843
05844
05845
05846
05847 {
05848 const cfg_obj_t *clistenon = NULL;
05849 ns_listenlist_t *listenon = NULL;
05850
05851 clistenon = NULL;
05852
05853
05854
05855
05856
05857 if (options != NULL)
05858 (void)cfg_map_get(options, "listen-on", &clistenon);
05859 if (clistenon != NULL) {
05860
05861 (void)ns_listenlist_fromconfig(clistenon, config,
05862 ns_g_aclconfctx,
05863 ns_g_mctx, AF_INET,
05864 &listenon);
05865 } else if (!ns_g_lwresdonly) {
05866
05867
05868
05869 CHECK(ns_listenlist_default(ns_g_mctx, listen_port,
05870 -1, ISC_TRUE, &listenon));
05871 }
05872 if (listenon != NULL) {
05873 ns_interfacemgr_setlistenon4(server->interfacemgr,
05874 listenon);
05875 ns_listenlist_detach(&listenon);
05876 }
05877 }
05878
05879
05880
05881 {
05882 const cfg_obj_t *clistenon = NULL;
05883 ns_listenlist_t *listenon = NULL;
05884
05885 if (options != NULL)
05886 (void)cfg_map_get(options, "listen-on-v6", &clistenon);
05887 if (clistenon != NULL) {
05888
05889 (void)ns_listenlist_fromconfig(clistenon, config,
05890 ns_g_aclconfctx,
05891 ns_g_mctx, AF_INET6,
05892 &listenon);
05893 } else if (!ns_g_lwresdonly) {
05894
05895
05896
05897 CHECK(ns_listenlist_default(ns_g_mctx, listen_port,
05898 -1, ISC_TRUE, &listenon));
05899 }
05900 if (listenon != NULL) {
05901 ns_interfacemgr_setlistenon6(server->interfacemgr,
05902 listenon);
05903 ns_listenlist_detach(&listenon);
05904 }
05905 }
05906
05907
05908
05909
05910
05911
05912
05913 result = scan_interfaces(server, ISC_TRUE);
05914
05915
05916
05917
05918
05919
05920 if (first_time && (result == ISC_R_ADDRINUSE)) {
05921 isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
05922 NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
05923 "unable to listen on any configured interfaces");
05924 result = ISC_R_FAILURE;
05925 goto cleanup;
05926 }
05927
05928
05929
05930
05931
05932 obj = NULL;
05933 result = ns_config_get(maps, "interface-interval", &obj);
05934 INSIST(result == ISC_R_SUCCESS);
05935 interface_interval = cfg_obj_asuint32(obj) * 60;
05936 if (interface_interval == 0) {
05937 CHECK(isc_timer_reset(server->interface_timer,
05938 isc_timertype_inactive,
05939 NULL, NULL, ISC_TRUE));
05940 } else if (server->interface_interval != interface_interval) {
05941 isc_interval_set(&interval, interface_interval, 0);
05942 CHECK(isc_timer_reset(server->interface_timer,
05943 isc_timertype_ticker,
05944 NULL, &interval, ISC_FALSE));
05945 }
05946 server->interface_interval = interface_interval;
05947
05948
05949
05950
05951 obj = NULL;
05952 result = ns_config_get(maps, "automatic-interface-scan", &obj);
05953 INSIST(result == ISC_R_SUCCESS);
05954 server->interface_auto = cfg_obj_asboolean(obj);
05955
05956
05957
05958
05959 obj = NULL;
05960 result = ns_config_get(maps, "heartbeat-interval", &obj);
05961 INSIST(result == ISC_R_SUCCESS);
05962 heartbeat_interval = cfg_obj_asuint32(obj) * 60;
05963 if (heartbeat_interval == 0) {
05964 CHECK(isc_timer_reset(server->heartbeat_timer,
05965 isc_timertype_inactive,
05966 NULL, NULL, ISC_TRUE));
05967 } else if (server->heartbeat_interval != heartbeat_interval) {
05968 isc_interval_set(&interval, heartbeat_interval, 0);
05969 CHECK(isc_timer_reset(server->heartbeat_timer,
05970 isc_timertype_ticker,
05971 NULL, &interval, ISC_FALSE));
05972 }
05973 server->heartbeat_interval = heartbeat_interval;
05974
05975 isc_interval_set(&interval, 1200, 0);
05976 CHECK(isc_timer_reset(server->pps_timer, isc_timertype_ticker, NULL,
05977 &interval, ISC_FALSE));
05978
05979
05980
05981
05982 obj = NULL;
05983 if (ns_config_get(maps, "pid-file", &obj) == ISC_R_SUCCESS)
05984 if (cfg_obj_isvoid(obj))
05985 ns_os_writepidfile(NULL, first_time);
05986 else
05987 ns_os_writepidfile(cfg_obj_asstring(obj), first_time);
05988 else if (ns_g_lwresdonly)
05989 ns_os_writepidfile(lwresd_g_defaultpidfile, first_time);
05990 else
05991 ns_os_writepidfile(ns_g_defaultpidfile, first_time);
05992
05993
05994
05995
05996
05997
05998
05999
06000
06001
06002 (void)configure_session_key(maps, server, ns_g_mctx);
06003
06004 views = NULL;
06005 (void)cfg_map_get(config, "view", &views);
06006
06007
06008
06009
06010
06011
06012
06013
06014
06015
06016
06017
06018
06019 for (element = cfg_list_first(views);
06020 element != NULL;
06021 element = cfg_list_next(element))
06022 {
06023 cfg_obj_t *vconfig = cfg_listelt_value(element);
06024 const cfg_obj_t *voptions = cfg_tuple_get(vconfig, "options");
06025 view = NULL;
06026
06027 CHECK(create_view(vconfig, &viewlist, &view));
06028 INSIST(view != NULL);
06029
06030 num_zones += count_zones(voptions);
06031
06032 CHECK(setup_newzones(view, config, vconfig, conf_parser,
06033 ns_g_aclconfctx));
06034 nzctx = view->new_zone_config;
06035 if (nzctx != NULL && nzctx->nzconfig != NULL)
06036 num_zones += count_zones(nzctx->nzconfig);
06037
06038 dns_view_detach(&view);
06039 }
06040
06041
06042
06043
06044
06045 if (views == NULL) {
06046 CHECK(create_view(NULL, &viewlist, &view));
06047 INSIST(view != NULL);
06048
06049 num_zones = count_zones(config);
06050
06051 CHECK(setup_newzones(view, config, NULL, conf_parser,
06052 ns_g_aclconfctx));
06053
06054 nzctx = view->new_zone_config;
06055 if (nzctx != NULL && nzctx->nzconfig != NULL)
06056 num_zones += count_zones(nzctx->nzconfig);
06057
06058 dns_view_detach(&view);
06059 }
06060
06061
06062
06063
06064 isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
06065 NS_LOGMODULE_SERVER, ISC_LOG_INFO,
06066 "sizing zone task pool based on %d zones", num_zones);
06067 CHECK(dns_zonemgr_setsize(ns_g_server->zonemgr, num_zones));
06068
06069
06070
06071
06072
06073
06074 for (element = cfg_list_first(views);
06075 element != NULL;
06076 element = cfg_list_next(element))
06077 {
06078 cfg_obj_t *vconfig = cfg_listelt_value(element);
06079
06080 view = NULL;
06081 CHECK(find_view(vconfig, &viewlist, &view));
06082 CHECK(configure_view(view, &viewlist, config, vconfig,
06083 &cachelist, bindkeys, ns_g_mctx,
06084 ns_g_aclconfctx, ISC_TRUE));
06085 dns_view_freeze(view);
06086 dns_view_detach(&view);
06087 }
06088
06089
06090
06091
06092
06093 if (views == NULL) {
06094 view = NULL;
06095 CHECK(find_view(NULL, &viewlist, &view));
06096 CHECK(configure_view(view, &viewlist, config, NULL,
06097 &cachelist, bindkeys,
06098 ns_g_mctx, ns_g_aclconfctx, ISC_TRUE));
06099 dns_view_freeze(view);
06100 dns_view_detach(&view);
06101 }
06102
06103
06104
06105
06106 builtin_views = NULL;
06107 RUNTIME_CHECK(cfg_map_get(ns_g_config, "view",
06108 &builtin_views) == ISC_R_SUCCESS);
06109 for (element = cfg_list_first(builtin_views);
06110 element != NULL;
06111 element = cfg_list_next(element))
06112 {
06113 cfg_obj_t *vconfig = cfg_listelt_value(element);
06114
06115 CHECK(create_view(vconfig, &builtin_viewlist, &view));
06116 CHECK(configure_view(view, &viewlist, config, vconfig,
06117 &cachelist, bindkeys,
06118 ns_g_mctx, ns_g_aclconfctx, ISC_FALSE));
06119 dns_view_freeze(view);
06120 dns_view_detach(&view);
06121 view = NULL;
06122 }
06123
06124
06125 ISC_LIST_APPENDLIST(viewlist, builtin_viewlist, link);
06126
06127
06128 tmpviewlist = server->viewlist;
06129 server->viewlist = viewlist;
06130 viewlist = tmpviewlist;
06131
06132
06133 view = ISC_LIST_HEAD(server->viewlist);
06134 while (view != NULL) {
06135 view->viewlist = &server->viewlist;
06136 view = ISC_LIST_NEXT(view, link);
06137 }
06138
06139
06140 tmpcachelist = server->cachelist;
06141 server->cachelist = cachelist;
06142 cachelist = tmpcachelist;
06143
06144
06145 if (options != NULL) {
06146 dns_tkeyctx_t *t = NULL;
06147 CHECKM(ns_tkeyctx_fromconfig(options, ns_g_mctx, ns_g_entropy,
06148 &t),
06149 "configuring TKEY");
06150 if (server->tkeyctx != NULL)
06151 dns_tkeyctx_destroy(&server->tkeyctx);
06152 server->tkeyctx = t;
06153 }
06154
06155
06156
06157
06158 CHECKM(ns_controls_configure(ns_g_server->controls, config,
06159 ns_g_aclconfctx),
06160 "binding control channel(s)");
06161
06162
06163
06164
06165 CHECKM(ns_lwresd_configure(ns_g_mctx, config),
06166 "binding lightweight resolver ports");
06167
06168
06169
06170
06171 if (first_time) {
06172 obj = NULL;
06173 result = ns_config_get(maps, "random-device", &obj);
06174 if (result != ISC_R_SUCCESS) {
06175 isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
06176 NS_LOGMODULE_SERVER, ISC_LOG_INFO,
06177 "no source of entropy found");
06178 } else {
06179 const char *randomdev = cfg_obj_asstring(obj);
06180 result = isc_entropy_createfilesource(ns_g_entropy,
06181 randomdev);
06182 if (result != ISC_R_SUCCESS)
06183 isc_log_write(ns_g_lctx,
06184 NS_LOGCATEGORY_GENERAL,
06185 NS_LOGMODULE_SERVER,
06186 ISC_LOG_INFO,
06187 "could not open entropy source "
06188 "%s: %s",
06189 randomdev,
06190 isc_result_totext(result));
06191 #ifdef PATH_RANDOMDEV
06192 if (ns_g_fallbackentropy != NULL) {
06193 if (result != ISC_R_SUCCESS) {
06194 isc_log_write(ns_g_lctx,
06195 NS_LOGCATEGORY_GENERAL,
06196 NS_LOGMODULE_SERVER,
06197 ISC_LOG_INFO,
06198 "using pre-chroot entropy source "
06199 "%s",
06200 PATH_RANDOMDEV);
06201 isc_entropy_detach(&ns_g_entropy);
06202 isc_entropy_attach(ns_g_fallbackentropy,
06203 &ns_g_entropy);
06204 }
06205 isc_entropy_detach(&ns_g_fallbackentropy);
06206 }
06207 #endif
06208 }
06209 }
06210
06211
06212
06213
06214 if (first_time)
06215 ns_os_changeuser();
06216
06217
06218
06219
06220 if (access(".", W_OK) != 0) {
06221 isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
06222 NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
06223 "the working directory is not writable");
06224 }
06225
06226
06227
06228
06229
06230
06231
06232
06233 if (ns_g_logstderr) {
06234 const cfg_obj_t *logobj = NULL;
06235
06236 isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
06237 NS_LOGMODULE_SERVER, ISC_LOG_INFO,
06238 "not using config file logging "
06239 "statement for logging due to "
06240 "-g option");
06241
06242 (void)cfg_map_get(config, "logging", &logobj);
06243 if (logobj != NULL) {
06244 result = ns_log_configure(NULL, logobj);
06245 if (result != ISC_R_SUCCESS) {
06246 isc_log_write(ns_g_lctx,
06247 NS_LOGCATEGORY_GENERAL,
06248 NS_LOGMODULE_SERVER,
06249 ISC_LOG_ERROR,
06250 "checking logging configuration "
06251 "failed: %s",
06252 isc_result_totext(result));
06253 goto cleanup;
06254 }
06255 }
06256 } else {
06257 const cfg_obj_t *logobj = NULL;
06258
06259 CHECKM(isc_logconfig_create(ns_g_lctx, &logc),
06260 "creating new logging configuration");
06261
06262 logobj = NULL;
06263 (void)cfg_map_get(config, "logging", &logobj);
06264 if (logobj != NULL) {
06265 CHECKM(ns_log_configure(logc, logobj),
06266 "configuring logging");
06267 } else {
06268 CHECKM(ns_log_setdefaultchannels(logc),
06269 "setting up default logging channels");
06270 CHECKM(ns_log_setunmatchedcategory(logc),
06271 "setting up default 'category unmatched'");
06272 CHECKM(ns_log_setdefaultcategory(logc),
06273 "setting up default 'category default'");
06274 }
06275
06276 CHECKM(isc_logconfig_use(ns_g_lctx, logc),
06277 "installing logging configuration");
06278 logc = NULL;
06279
06280 isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
06281 NS_LOGMODULE_SERVER, ISC_LOG_DEBUG(1),
06282 "now using logging configuration from "
06283 "config file");
06284 }
06285
06286
06287
06288
06289
06290
06291
06292 if (first_time) {
06293 const cfg_obj_t *logobj = NULL;
06294 const cfg_obj_t *categories = NULL;
06295
06296 obj = NULL;
06297 if (ns_config_get(maps, "querylog", &obj) == ISC_R_SUCCESS) {
06298 server->log_queries = cfg_obj_asboolean(obj);
06299 } else {
06300
06301 (void)cfg_map_get(config, "logging", &logobj);
06302 if (logobj != NULL)
06303 (void)cfg_map_get(logobj, "category",
06304 &categories);
06305 if (categories != NULL) {
06306 for (element = cfg_list_first(categories);
06307 element != NULL;
06308 element = cfg_list_next(element))
06309 {
06310 const cfg_obj_t *catobj;
06311 const char *str;
06312
06313 obj = cfg_listelt_value(element);
06314 catobj = cfg_tuple_get(obj, "name");
06315 str = cfg_obj_asstring(catobj);
06316 if (strcasecmp(str, "queries") == 0)
06317 server->log_queries = ISC_TRUE;
06318 }
06319 }
06320 }
06321 }
06322
06323
06324 obj = NULL;
06325 if (options != NULL &&
06326 cfg_map_get(options, "memstatistics", &obj) == ISC_R_SUCCESS)
06327 ns_g_memstatistics = cfg_obj_asboolean(obj);
06328 else
06329 ns_g_memstatistics =
06330 ISC_TF((isc_mem_debugging & ISC_MEM_DEBUGRECORD) != 0);
06331
06332 obj = NULL;
06333 if (ns_config_get(maps, "memstatistics-file", &obj) == ISC_R_SUCCESS)
06334 ns_main_setmemstats(cfg_obj_asstring(obj));
06335 else if (ns_g_memstatistics)
06336 ns_main_setmemstats("named.memstats");
06337 else
06338 ns_main_setmemstats(NULL);
06339
06340 obj = NULL;
06341 result = ns_config_get(maps, "statistics-file", &obj);
06342 INSIST(result == ISC_R_SUCCESS);
06343 CHECKM(setstring(server, &server->statsfile, cfg_obj_asstring(obj)),
06344 "strdup");
06345
06346 obj = NULL;
06347 result = ns_config_get(maps, "dump-file", &obj);
06348 INSIST(result == ISC_R_SUCCESS);
06349 CHECKM(setstring(server, &server->dumpfile, cfg_obj_asstring(obj)),
06350 "strdup");
06351
06352 obj = NULL;
06353 result = ns_config_get(maps, "secroots-file", &obj);
06354 INSIST(result == ISC_R_SUCCESS);
06355 CHECKM(setstring(server, &server->secrootsfile, cfg_obj_asstring(obj)),
06356 "strdup");
06357
06358 obj = NULL;
06359 result = ns_config_get(maps, "recursing-file", &obj);
06360 INSIST(result == ISC_R_SUCCESS);
06361 CHECKM(setstring(server, &server->recfile, cfg_obj_asstring(obj)),
06362 "strdup");
06363
06364 obj = NULL;
06365 result = ns_config_get(maps, "version", &obj);
06366 if (result == ISC_R_SUCCESS) {
06367 CHECKM(setoptstring(server, &server->version, obj), "strdup");
06368 server->version_set = ISC_TRUE;
06369 } else {
06370 server->version_set = ISC_FALSE;
06371 }
06372
06373 obj = NULL;
06374 result = ns_config_get(maps, "hostname", &obj);
06375 if (result == ISC_R_SUCCESS) {
06376 CHECKM(setoptstring(server, &server->hostname, obj), "strdup");
06377 server->hostname_set = ISC_TRUE;
06378 } else {
06379 server->hostname_set = ISC_FALSE;
06380 }
06381
06382 obj = NULL;
06383 result = ns_config_get(maps, "server-id", &obj);
06384 server->server_usehostname = ISC_FALSE;
06385 if (result == ISC_R_SUCCESS && cfg_obj_isboolean(obj)) {
06386
06387 server->server_usehostname = cfg_obj_asboolean(obj);
06388 result = setstring(server, &server->server_id, NULL);
06389 RUNTIME_CHECK(result == ISC_R_SUCCESS);
06390 } else if (result == ISC_R_SUCCESS) {
06391
06392 CHECKM(setoptstring(server, &server->server_id, obj), "strdup");
06393 } else {
06394 result = setstring(server, &server->server_id, NULL);
06395 RUNTIME_CHECK(result == ISC_R_SUCCESS);
06396 }
06397
06398 obj = NULL;
06399 result = ns_config_get(maps, "flush-zones-on-shutdown", &obj);
06400 if (result == ISC_R_SUCCESS) {
06401 server->flushonshutdown = cfg_obj_asboolean(obj);
06402 } else {
06403 server->flushonshutdown = ISC_FALSE;
06404 }
06405
06406 #ifdef ISC_PLATFORM_USESIT
06407 obj = NULL;
06408 result = ns_config_get(maps, "sit-secret", &obj);
06409 if (result == ISC_R_SUCCESS) {
06410 isc_buffer_t b;
06411
06412 memset(server->secret, 0, sizeof(server->secret));
06413 isc_buffer_init(&b, server->secret, sizeof(server->secret));
06414 result = isc_hex_decodestring(cfg_obj_asstring(obj), &b);
06415 if (result != ISC_R_SUCCESS && result != ISC_R_NOSPACE)
06416 goto cleanup;
06417 #ifdef AES_SIT
06418 if (isc_buffer_usedlength(&b) != ISC_AES128_KEYLENGTH)
06419 CHECKM(ISC_R_RANGE,
06420 "AES sit-secret must be on 128 bits");
06421 #endif
06422 #ifdef HMAC_SHA1_SIT
06423 if (isc_buffer_usedlength(&b) != ISC_SHA1_DIGESTLENGTH)
06424 CHECKM(ISC_R_RANGE,
06425 "SHA1 sit-secret must be on 160 bits");
06426 #endif
06427 #ifdef HMAC_SHA256_SIT
06428 if (isc_buffer_usedlength(&b) != ISC_SHA256_DIGESTLENGTH)
06429 CHECKM(ISC_R_RANGE,
06430 "SHA256 sit-secret must be on 256 bits");
06431 #endif
06432 } else {
06433 result = isc_entropy_getdata(ns_g_entropy,
06434 server->secret,
06435 sizeof(server->secret),
06436 NULL,
06437 0);
06438 if (result != ISC_R_SUCCESS)
06439 goto cleanup;
06440 }
06441 #endif
06442
06443 result = ISC_R_SUCCESS;
06444
06445 cleanup:
06446 if (logc != NULL)
06447 isc_logconfig_destroy(&logc);
06448
06449 if (v4portset != NULL)
06450 isc_portset_destroy(ns_g_mctx, &v4portset);
06451
06452 if (v6portset != NULL)
06453 isc_portset_destroy(ns_g_mctx, &v6portset);
06454
06455 if (conf_parser != NULL) {
06456 if (config != NULL)
06457 cfg_obj_destroy(conf_parser, &config);
06458 cfg_parser_destroy(&conf_parser);
06459 }
06460
06461 if (bindkeys_parser != NULL) {
06462 if (bindkeys != NULL)
06463 cfg_obj_destroy(bindkeys_parser, &bindkeys);
06464 cfg_parser_destroy(&bindkeys_parser);
06465 }
06466
06467 if (view != NULL)
06468 dns_view_detach(&view);
06469
06470 ISC_LIST_APPENDLIST(viewlist, builtin_viewlist, link);
06471
06472
06473
06474
06475
06476
06477 for (view = ISC_LIST_HEAD(viewlist);
06478 view != NULL;
06479 view = view_next) {
06480 view_next = ISC_LIST_NEXT(view, link);
06481 ISC_LIST_UNLINK(viewlist, view, link);
06482 if (result == ISC_R_SUCCESS &&
06483 strcmp(view->name, "_bind") != 0)
06484 (void)dns_zt_apply(view->zonetable, ISC_FALSE,
06485 removed, view);
06486 dns_view_detach(&view);
06487 }
06488
06489
06490 while ((nsc = ISC_LIST_HEAD(cachelist)) != NULL) {
06491 ISC_LIST_UNLINK(cachelist, nsc, link);
06492 dns_cache_detach(&nsc->cache);
06493 isc_mem_put(server->mctx, nsc, sizeof(*nsc));
06494 }
06495
06496
06497
06498
06499
06500 if (isc_net_probeipv6() == ISC_R_SUCCESS)
06501 adjust_interfaces(server, ns_g_mctx);
06502
06503
06504
06505
06506 tresult = isc_time_now(&ns_g_configtime);
06507 if (tresult != ISC_R_SUCCESS)
06508 ns_main_earlyfatal("isc_time_now() failed: %s",
06509 isc_result_totext(result));
06510
06511
06512 if (exclusive)
06513 isc_task_endexclusive(server->task);
06514
06515 isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER,
06516 ISC_LOG_DEBUG(1), "load_configuration: %s",
06517 isc_result_totext(result));
06518
06519 return (result);
06520 }
06521
06522 static isc_result_t
06523 view_loaded(void *arg) {
06524 isc_result_t result;
06525 ns_zoneload_t *zl = (ns_zoneload_t *) arg;
06526 ns_server_t *server = zl->server;
06527 unsigned int refs;
06528
06529
06530
06531
06532
06533
06534
06535
06536
06537
06538 isc_refcount_decrement(&zl->refs, &refs);
06539 if (refs != 0)
06540 return (ISC_R_SUCCESS);
06541
06542 isc_refcount_destroy(&zl->refs);
06543 isc_mem_put(server->mctx, zl, sizeof (*zl));
06544
06545 isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER,
06546 ISC_LOG_NOTICE, "all zones loaded");
06547 CHECKFATAL(dns_zonemgr_forcemaint(server->zonemgr),
06548 "forcing zone maintenance");
06549
06550 ns_os_started();
06551 isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER,
06552 ISC_LOG_NOTICE, "running");
06553
06554 return (ISC_R_SUCCESS);
06555 }
06556
06557 static isc_result_t
06558 load_zones(ns_server_t *server, isc_boolean_t init) {
06559 isc_result_t result;
06560 dns_view_t *view;
06561 ns_zoneload_t *zl;
06562 unsigned int refs = 0;
06563
06564 zl = isc_mem_get(server->mctx, sizeof (*zl));
06565 if (zl == NULL)
06566 return (ISC_R_NOMEMORY);
06567 zl->server = server;
06568
06569 result = isc_task_beginexclusive(server->task);
06570 RUNTIME_CHECK(result == ISC_R_SUCCESS);
06571
06572 isc_refcount_init(&zl->refs, 1);
06573
06574
06575
06576
06577 for (view = ISC_LIST_HEAD(server->viewlist);
06578 view != NULL;
06579 view = ISC_LIST_NEXT(view, link))
06580 {
06581 if (view->managed_keys != NULL) {
06582 result = dns_zone_load(view->managed_keys);
06583 if (result != ISC_R_SUCCESS &&
06584 result != DNS_R_UPTODATE &&
06585 result != DNS_R_CONTINUE)
06586 goto cleanup;
06587 }
06588 if (view->redirect != NULL) {
06589 result = dns_zone_load(view->redirect);
06590 if (result != ISC_R_SUCCESS &&
06591 result != DNS_R_UPTODATE &&
06592 result != DNS_R_CONTINUE)
06593 goto cleanup;
06594 }
06595
06596
06597
06598
06599
06600 isc_refcount_increment(&zl->refs, NULL);
06601 CHECK(dns_view_asyncload(view, view_loaded, zl));
06602 }
06603
06604 cleanup:
06605 isc_refcount_decrement(&zl->refs, &refs);
06606 if (refs == 0) {
06607 isc_refcount_destroy(&zl->refs);
06608 isc_mem_put(server->mctx, zl, sizeof (*zl));
06609 } else if (init) {
06610
06611
06612
06613
06614
06615
06616
06617
06618 isc_taskmgr_setmode(ns_g_taskmgr, isc_taskmgrmode_privileged);
06619 }
06620
06621 isc_task_endexclusive(server->task);
06622 return (result);
06623 }
06624
06625 static isc_result_t
06626 load_new_zones(ns_server_t *server, isc_boolean_t stop) {
06627 isc_result_t result;
06628 dns_view_t *view;
06629
06630 result = isc_task_beginexclusive(server->task);
06631 RUNTIME_CHECK(result == ISC_R_SUCCESS);
06632
06633
06634
06635
06636 for (view = ISC_LIST_HEAD(server->viewlist);
06637 view != NULL;
06638 view = ISC_LIST_NEXT(view, link))
06639 {
06640 CHECK(dns_view_loadnew(view, stop));
06641
06642
06643 if (view->managed_keys != NULL)
06644 CHECK(dns_zone_loadnew(view->managed_keys));
06645 if (view->redirect != NULL)
06646 CHECK(dns_zone_loadnew(view->redirect));
06647 }
06648
06649
06650
06651
06652 dns_zonemgr_resumexfrs(server->zonemgr);
06653 cleanup:
06654 isc_task_endexclusive(server->task);
06655 return (result);
06656 }
06657
06658 static void
06659 run_server(isc_task_t *task, isc_event_t *event) {
06660 isc_result_t result;
06661 ns_server_t *server = (ns_server_t *)event->ev_arg;
06662
06663 INSIST(task == server->task);
06664
06665 isc_event_free(&event);
06666
06667 CHECKFATAL(dns_dispatchmgr_create(ns_g_mctx, ns_g_entropy,
06668 &ns_g_dispatchmgr),
06669 "creating dispatch manager");
06670
06671 dns_dispatchmgr_setstats(ns_g_dispatchmgr, server->resolverstats);
06672
06673 CHECKFATAL(ns_interfacemgr_create(ns_g_mctx, ns_g_taskmgr,
06674 ns_g_socketmgr, ns_g_dispatchmgr,
06675 server->task, &server->interfacemgr),
06676 "creating interface manager");
06677
06678 CHECKFATAL(isc_timer_create(ns_g_timermgr, isc_timertype_inactive,
06679 NULL, NULL, server->task,
06680 interface_timer_tick,
06681 server, &server->interface_timer),
06682 "creating interface timer");
06683
06684 CHECKFATAL(isc_timer_create(ns_g_timermgr, isc_timertype_inactive,
06685 NULL, NULL, server->task,
06686 heartbeat_timer_tick,
06687 server, &server->heartbeat_timer),
06688 "creating heartbeat timer");
06689
06690 CHECKFATAL(isc_timer_create(ns_g_timermgr, isc_timertype_inactive,
06691 NULL, NULL, server->task, pps_timer_tick,
06692 server, &server->pps_timer),
06693 "creating pps timer");
06694
06695 CHECKFATAL(cfg_parser_create(ns_g_mctx, NULL, &ns_g_parser),
06696 "creating default configuration parser");
06697
06698 CHECKFATAL(cfg_parser_create(ns_g_mctx, NULL, &ns_g_addparser),
06699 "creating additional configuration parser");
06700
06701 if (ns_g_lwresdonly)
06702 CHECKFATAL(load_configuration(lwresd_g_conffile, server,
06703 ISC_TRUE),
06704 "loading configuration");
06705 else
06706 CHECKFATAL(load_configuration(ns_g_conffile, server, ISC_TRUE),
06707 "loading configuration");
06708
06709 isc_hash_init();
06710
06711 CHECKFATAL(load_zones(server, ISC_TRUE), "loading zones");
06712
06713 (void) ns_server_loadnta(server);
06714 }
06715
06716 void
06717 ns_server_flushonshutdown(ns_server_t *server, isc_boolean_t flush) {
06718
06719 REQUIRE(NS_SERVER_VALID(server));
06720
06721 server->flushonshutdown = flush;
06722 }
06723
06724 static void
06725 shutdown_server(isc_task_t *task, isc_event_t *event) {
06726 isc_result_t result;
06727 dns_view_t *view, *view_next;
06728 ns_server_t *server = (ns_server_t *)event->ev_arg;
06729 isc_boolean_t flush = server->flushonshutdown;
06730 ns_cache_t *nsc;
06731
06732 UNUSED(task);
06733 INSIST(task == server->task);
06734
06735 result = isc_task_beginexclusive(server->task);
06736 RUNTIME_CHECK(result == ISC_R_SUCCESS);
06737
06738 isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER,
06739 ISC_LOG_INFO, "shutting down%s",
06740 flush ? ": flushing changes" : "");
06741
06742 ns_statschannels_shutdown(server);
06743 ns_controls_shutdown(server->controls);
06744 end_reserved_dispatches(server, ISC_TRUE);
06745 cleanup_session_key(server, server->mctx);
06746
06747 if (ns_g_aclconfctx != NULL)
06748 cfg_aclconfctx_detach(&ns_g_aclconfctx);
06749
06750 cfg_obj_destroy(ns_g_parser, &ns_g_config);
06751 cfg_parser_destroy(&ns_g_parser);
06752 cfg_parser_destroy(&ns_g_addparser);
06753
06754 (void) ns_server_saventa(server);
06755
06756 for (view = ISC_LIST_HEAD(server->viewlist);
06757 view != NULL;
06758 view = view_next) {
06759 view_next = ISC_LIST_NEXT(view, link);
06760 ISC_LIST_UNLINK(server->viewlist, view, link);
06761 if (flush)
06762 dns_view_flushanddetach(&view);
06763 else
06764 dns_view_detach(&view);
06765 }
06766
06767 while ((nsc = ISC_LIST_HEAD(server->cachelist)) != NULL) {
06768 ISC_LIST_UNLINK(server-&g