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
00024 #include <isc/buffer.h>
00025 #include <isc/log.h>
00026 #include <isc/mem.h>
00027 #include <isc/parseint.h>
00028 #include <isc/region.h>
00029 #include <isc/result.h>
00030 #include <isc/sockaddr.h>
00031 #include <isc/string.h>
00032 #include <isc/util.h>
00033
00034 #include <isccfg/namedconf.h>
00035
00036 #include <dns/fixedname.h>
00037 #include <dns/name.h>
00038 #include <dns/rdataclass.h>
00039 #include <dns/rdatatype.h>
00040 #include <dns/tsig.h>
00041 #include <dns/zone.h>
00042
00043 #include <dst/dst.h>
00044
00045 #include <named/config.h>
00046 #include <named/globals.h>
00047
00048 #include <bind.keys.h>
00049
00050
00051 static char defaultconf[] = "\
00052 options {\n\
00053 automatic-interface-scan yes;\n\
00054 bindkeys-file \"" NS_SYSCONFDIR "/bind.keys\";\n\
00055 # blackhole {none;};\n"
00056 #ifndef WIN32
00057 " coresize default;\n\
00058 datasize default;\n\
00059 files unlimited;\n\
00060 stacksize default;\n"
00061 #endif
00062 "# session-keyfile \"" NS_LOCALSTATEDIR "/run/named/session.key\";\n\
00063 session-keyname local-ddns;\n\
00064 session-keyalg hmac-sha256;\n\
00065 deallocate-on-exit true;\n\
00066 # directory <none>\n\
00067 dump-file \"named_dump.db\";\n\
00068 fake-iquery no;\n\
00069 has-old-clients false;\n\
00070 heartbeat-interval 60;\n\
00071 host-statistics no;\n\
00072 interface-interval 60;\n\
00073 # keep-response-order {none;};\n\
00074 listen-on {any;};\n\
00075 listen-on-v6 {any;};\n\
00076 match-mapped-addresses no;\n\
00077 max-rsa-exponent-size 0; /* no limit */\n\
00078 memstatistics-file \"named.memstats\";\n\
00079 multiple-cnames no;\n\
00080 # named-xfer <obsolete>;\n\
00081 nta-lifetime 3600;\n\
00082 nta-recheck 300;\n\
00083 notify-rate 20;\n\
00084 # pid-file \"" NS_LOCALSTATEDIR "/run/named/named.pid\"; /* or /lwresd.pid */\n\
00085 # lock-file \"" NS_LOCALSTATEDIR "/run/named/named.lock\";\n\
00086 port 53;\n\
00087 prefetch 2 9;\n\
00088 recursing-file \"named.recursing\";\n\
00089 secroots-file \"named.secroots\";\n\
00090 "
00091 #ifdef PATH_RANDOMDEV
00092 "\
00093 random-device \"" PATH_RANDOMDEV "\";\n\
00094 "
00095 #endif
00096 "\
00097 recursive-clients 1000;\n\
00098 resolver-query-timeout 10;\n\
00099 rrset-order { order random; };\n\
00100 serial-queries 20;\n\
00101 serial-query-rate 20;\n\
00102 server-id none;\n\
00103 startup-notify-rate 20;\n\
00104 statistics-file \"named.stats\";\n\
00105 statistics-interval 60;\n\
00106 tcp-clients 150;\n\
00107 tcp-listen-queue 10;\n\
00108 # tkey-dhkey <none>\n\
00109 # tkey-gssapi-credential <none>\n\
00110 # tkey-domain <none>\n\
00111 transfers-per-ns 2;\n\
00112 transfers-in 10;\n\
00113 transfers-out 10;\n\
00114 treat-cr-as-space true;\n\
00115 use-id-pool true;\n\
00116 use-ixfr true;\n\
00117 edns-udp-size 4096;\n\
00118 max-udp-size 4096;\n\
00119 "
00120 #ifdef ISC_PLATFORM_USESIT
00121 "\
00122 nosit-udp-size 4096;\n\
00123 request-sit true;\n\
00124 "
00125 #endif
00126 "\
00127 request-nsid false;\n\
00128 reserved-sockets 512;\n\
00129 \n\
00130 /* DLV */\n\
00131 dnssec-lookaside . trust-anchor dlv.isc.org;\n\
00132 \n\
00133 /* view */\n\
00134 allow-notify {none;};\n\
00135 allow-update-forwarding {none;};\n\
00136 allow-query-cache { localnets; localhost; };\n\
00137 allow-query-cache-on { any; };\n\
00138 allow-recursion { localnets; localhost; };\n\
00139 allow-recursion-on { any; };\n\
00140 # allow-v6-synthesis <obsolete>;\n\
00141 # sortlist <none>\n\
00142 # topology <none>\n\
00143 auth-nxdomain false;\n\
00144 minimal-responses false;\n\
00145 recursion true;\n\
00146 provide-ixfr true;\n\
00147 request-ixfr true;\n\
00148 request-expire true;\n\
00149 fetch-glue no;\n\
00150 rfc2308-type1 no;\n\
00151 additional-from-auth true;\n\
00152 additional-from-cache true;\n\
00153 query-source address *;\n\
00154 query-source-v6 address *;\n\
00155 notify-source *;\n\
00156 notify-source-v6 *;\n\
00157 cleaning-interval 0; /* now meaningless */\n\
00158 min-roots 2;\n\
00159 lame-ttl 600;\n\
00160 servfail-ttl 10;\n\
00161 max-ncache-ttl 10800; /* 3 hours */\n\
00162 max-cache-ttl 604800; /* 1 week */\n\
00163 transfer-format many-answers;\n\
00164 max-cache-size 0;\n\
00165 check-names master fail;\n\
00166 check-names slave warn;\n\
00167 check-names response ignore;\n\
00168 check-dup-records warn;\n\
00169 check-mx warn;\n\
00170 check-spf warn;\n\
00171 acache-enable no;\n\
00172 acache-cleaning-interval 60;\n\
00173 max-acache-size 16M;\n\
00174 dnssec-enable yes;\n\
00175 dnssec-validation yes; \n\
00176 dnssec-accept-expired no;\n\
00177 clients-per-query 10;\n\
00178 max-clients-per-query 100;\n\
00179 max-recursion-depth 7;\n\
00180 max-recursion-queries 75;\n\
00181 zero-no-soa-ttl-cache no;\n\
00182 nsec3-test-zone no;\n\
00183 allow-new-zones no;\n\
00184 "
00185 #ifdef HAVE_GEOIP
00186 "\
00187 geoip-use-ecs yes;\n\
00188 "
00189 #endif
00190 #ifdef ALLOW_FILTER_AAAA
00191 " filter-aaaa-on-v4 no;\n\
00192 filter-aaaa-on-v6 no;\n\
00193 filter-aaaa { any; };\n\
00194 "
00195 #endif
00196
00197 " /* zone */\n\
00198 allow-query {any;};\n\
00199 allow-query-on {any;};\n\
00200 allow-transfer {any;};\n\
00201 notify yes;\n\
00202 # also-notify <none>\n\
00203 notify-delay 5;\n\
00204 notify-to-soa no;\n\
00205 dialup no;\n\
00206 # forward <none>\n\
00207 # forwarders <none>\n\
00208 maintain-ixfr-base no;\n\
00209 # max-ixfr-log-size <obsolete>\n\
00210 transfer-source *;\n\
00211 transfer-source-v6 *;\n\
00212 alt-transfer-source *;\n\
00213 alt-transfer-source-v6 *;\n\
00214 max-transfer-time-in 120;\n\
00215 max-transfer-time-out 120;\n\
00216 max-transfer-idle-in 60;\n\
00217 max-transfer-idle-out 60;\n\
00218 max-retry-time 1209600; /* 2 weeks */\n\
00219 min-retry-time 500;\n\
00220 max-refresh-time 2419200; /* 4 weeks */\n\
00221 min-refresh-time 300;\n\
00222 multi-master no;\n\
00223 dnssec-secure-to-insecure no;\n\
00224 sig-validity-interval 30; /* days */\n\
00225 sig-signing-nodes 100;\n\
00226 sig-signing-signatures 10;\n\
00227 sig-signing-type 65534;\n\
00228 inline-signing no;\n\
00229 zone-statistics terse;\n\
00230 max-journal-size unlimited;\n\
00231 ixfr-from-differences false;\n\
00232 check-wildcard yes;\n\
00233 check-sibling yes;\n\
00234 check-integrity yes;\n\
00235 check-mx-cname warn;\n\
00236 check-srv-cname warn;\n\
00237 zero-no-soa-ttl yes;\n\
00238 update-check-ksk yes;\n\
00239 serial-update-method increment;\n\
00240 dnssec-update-mode maintain;\n\
00241 dnssec-dnskey-kskonly no;\n\
00242 dnssec-loadkeys-interval 60;\n\
00243 try-tcp-refresh yes; /* BIND 8 compat */\n\
00244 };\n\
00245 "
00246
00247 "#\n\
00248 # Zones in the \"_bind\" view are NOT counted in the count of zones.\n\
00249 #\n\
00250 view \"_bind\" chaos {\n\
00251 recursion no;\n\
00252 notify no;\n\
00253 allow-new-zones no;\n\
00254 \n\
00255 # Prevent use of this zone in DNS amplified reflection DoS attacks\n\
00256 rate-limit {\n\
00257 responses-per-second 3;\n\
00258 slip 0;\n\
00259 min-table-size 10;\n\
00260 };\n\
00261 \n\
00262 zone \"version.bind\" chaos {\n\
00263 type master;\n\
00264 database \"_builtin version\";\n\
00265 };\n\
00266 \n\
00267 zone \"hostname.bind\" chaos {\n\
00268 type master;\n\
00269 database \"_builtin hostname\";\n\
00270 };\n\
00271 \n\
00272 zone \"authors.bind\" chaos {\n\
00273 type master;\n\
00274 database \"_builtin authors\";\n\
00275 };\n\
00276 \n\
00277 zone \"id.server\" chaos {\n\
00278 type master;\n\
00279 database \"_builtin id\";\n\
00280 };\n\
00281 };\n\
00282 "
00283 "#\n\
00284 # Default trusted key(s) for builtin DLV support\n\
00285 # (used if \"dnssec-lookaside auto;\" is set and\n\
00286 # sysconfdir/bind.keys doesn't exist).\n\
00287 #\n\
00288 # BEGIN MANAGED KEYS\n"
00289
00290
00291 MANAGED_KEYS
00292
00293 "# END MANAGED KEYS\n\
00294 ";
00295
00296 isc_result_t
00297 ns_config_parsedefaults(cfg_parser_t *parser, cfg_obj_t **conf) {
00298 isc_buffer_t b;
00299
00300 isc_buffer_init(&b, defaultconf, sizeof(defaultconf) - 1);
00301 isc_buffer_add(&b, sizeof(defaultconf) - 1);
00302 return (cfg_parse_buffer(parser, &b, &cfg_type_namedconf, conf));
00303 }
00304
00305 isc_result_t
00306 ns_config_get(cfg_obj_t const * const *maps, const char *name,
00307 const cfg_obj_t **obj)
00308 {
00309 int i;
00310
00311 for (i = 0;; i++) {
00312 if (maps[i] == NULL)
00313 return (ISC_R_NOTFOUND);
00314 if (cfg_map_get(maps[i], name, obj) == ISC_R_SUCCESS)
00315 return (ISC_R_SUCCESS);
00316 }
00317 }
00318
00319 isc_result_t
00320 ns_checknames_get(const cfg_obj_t **maps, const char *which,
00321 const cfg_obj_t **obj)
00322 {
00323 const cfg_listelt_t *element;
00324 const cfg_obj_t *checknames;
00325 const cfg_obj_t *type;
00326 const cfg_obj_t *value;
00327 int i;
00328
00329 for (i = 0;; i++) {
00330 if (maps[i] == NULL)
00331 return (ISC_R_NOTFOUND);
00332 checknames = NULL;
00333 if (cfg_map_get(maps[i], "check-names",
00334 &checknames) == ISC_R_SUCCESS) {
00335
00336
00337
00338 if (checknames != NULL && !cfg_obj_islist(checknames)) {
00339 *obj = checknames;
00340 return (ISC_R_SUCCESS);
00341 }
00342 for (element = cfg_list_first(checknames);
00343 element != NULL;
00344 element = cfg_list_next(element)) {
00345 value = cfg_listelt_value(element);
00346 type = cfg_tuple_get(value, "type");
00347 if (strcasecmp(cfg_obj_asstring(type),
00348 which) == 0) {
00349 *obj = cfg_tuple_get(value, "mode");
00350 return (ISC_R_SUCCESS);
00351 }
00352 }
00353
00354 }
00355 }
00356 }
00357
00358 int
00359 ns_config_listcount(const cfg_obj_t *list) {
00360 const cfg_listelt_t *e;
00361 int i = 0;
00362
00363 for (e = cfg_list_first(list); e != NULL; e = cfg_list_next(e))
00364 i++;
00365
00366 return (i);
00367 }
00368
00369 isc_result_t
00370 ns_config_getclass(const cfg_obj_t *classobj, dns_rdataclass_t defclass,
00371 dns_rdataclass_t *classp) {
00372 isc_textregion_t r;
00373 isc_result_t result;
00374
00375 if (!cfg_obj_isstring(classobj)) {
00376 *classp = defclass;
00377 return (ISC_R_SUCCESS);
00378 }
00379 DE_CONST(cfg_obj_asstring(classobj), r.base);
00380 r.length = strlen(r.base);
00381 result = dns_rdataclass_fromtext(classp, &r);
00382 if (result != ISC_R_SUCCESS)
00383 cfg_obj_log(classobj, ns_g_lctx, ISC_LOG_ERROR,
00384 "unknown class '%s'", r.base);
00385 return (result);
00386 }
00387
00388 isc_result_t
00389 ns_config_gettype(const cfg_obj_t *typeobj, dns_rdatatype_t deftype,
00390 dns_rdatatype_t *typep) {
00391 isc_textregion_t r;
00392 isc_result_t result;
00393
00394 if (!cfg_obj_isstring(typeobj)) {
00395 *typep = deftype;
00396 return (ISC_R_SUCCESS);
00397 }
00398 DE_CONST(cfg_obj_asstring(typeobj), r.base);
00399 r.length = strlen(r.base);
00400 result = dns_rdatatype_fromtext(typep, &r);
00401 if (result != ISC_R_SUCCESS)
00402 cfg_obj_log(typeobj, ns_g_lctx, ISC_LOG_ERROR,
00403 "unknown type '%s'", r.base);
00404 return (result);
00405 }
00406
00407 dns_zonetype_t
00408 ns_config_getzonetype(const cfg_obj_t *zonetypeobj) {
00409 dns_zonetype_t ztype = dns_zone_none;
00410 const char *str;
00411
00412 str = cfg_obj_asstring(zonetypeobj);
00413 if (strcasecmp(str, "master") == 0)
00414 ztype = dns_zone_master;
00415 else if (strcasecmp(str, "slave") == 0)
00416 ztype = dns_zone_slave;
00417 else if (strcasecmp(str, "stub") == 0)
00418 ztype = dns_zone_stub;
00419 else if (strcasecmp(str, "static-stub") == 0)
00420 ztype = dns_zone_staticstub;
00421 else if (strcasecmp(str, "redirect") == 0)
00422 ztype = dns_zone_redirect;
00423 else
00424 INSIST(0);
00425 return (ztype);
00426 }
00427
00428 isc_result_t
00429 ns_config_getiplist(const cfg_obj_t *config, const cfg_obj_t *list,
00430 in_port_t defport, isc_mem_t *mctx,
00431 isc_sockaddr_t **addrsp, isc_dscp_t **dscpsp,
00432 isc_uint32_t *countp)
00433 {
00434 int count, i = 0;
00435 const cfg_obj_t *addrlist;
00436 const cfg_obj_t *portobj, *dscpobj;
00437 const cfg_listelt_t *element;
00438 isc_sockaddr_t *addrs;
00439 in_port_t port;
00440 isc_dscp_t dscp = -1, *dscps = NULL;
00441 isc_result_t result;
00442
00443 INSIST(addrsp != NULL && *addrsp == NULL);
00444 INSIST(dscpsp == NULL || *dscpsp == NULL);
00445 INSIST(countp != NULL);
00446
00447 addrlist = cfg_tuple_get(list, "addresses");
00448 count = ns_config_listcount(addrlist);
00449
00450 portobj = cfg_tuple_get(list, "port");
00451 if (cfg_obj_isuint32(portobj)) {
00452 isc_uint32_t val = cfg_obj_asuint32(portobj);
00453 if (val > ISC_UINT16_MAX) {
00454 cfg_obj_log(portobj, ns_g_lctx, ISC_LOG_ERROR,
00455 "port '%u' out of range", val);
00456 return (ISC_R_RANGE);
00457 }
00458 port = (in_port_t) val;
00459 } else if (defport != 0)
00460 port = defport;
00461 else {
00462 result = ns_config_getport(config, &port);
00463 if (result != ISC_R_SUCCESS)
00464 return (result);
00465 }
00466
00467 if (dscpsp != NULL) {
00468 dscpobj = cfg_tuple_get(list, "dscp");
00469 if (dscpobj != NULL && cfg_obj_isuint32(dscpobj)) {
00470 if (cfg_obj_asuint32(dscpobj) > 63) {
00471 cfg_obj_log(dscpobj, ns_g_lctx, ISC_LOG_ERROR,
00472 "dscp value '%u' is out of range",
00473 cfg_obj_asuint32(dscpobj));
00474 return (ISC_R_RANGE);
00475 }
00476 dscp = (isc_dscp_t)cfg_obj_asuint32(dscpobj);
00477 }
00478
00479 dscps = isc_mem_get(mctx, count * sizeof(isc_dscp_t));
00480 if (dscps == NULL)
00481 return (ISC_R_NOMEMORY);
00482 }
00483
00484 addrs = isc_mem_get(mctx, count * sizeof(isc_sockaddr_t));
00485 if (addrs == NULL) {
00486 if (dscps != NULL)
00487 isc_mem_put(mctx, dscps, count * sizeof(isc_dscp_t));
00488 return (ISC_R_NOMEMORY);
00489 }
00490
00491 for (element = cfg_list_first(addrlist);
00492 element != NULL;
00493 element = cfg_list_next(element), i++)
00494 {
00495 const cfg_obj_t *addr;
00496 INSIST(i < count);
00497 addr = cfg_listelt_value(element);
00498 addrs[i] = *cfg_obj_assockaddr(addr);
00499 if (dscpsp != NULL) {
00500 isc_dscp_t innerdscp;
00501 innerdscp = cfg_obj_getdscp(addr);
00502 if (innerdscp == -1)
00503 innerdscp = dscp;
00504 dscps[i] = innerdscp;
00505 }
00506 if (isc_sockaddr_getport(&addrs[i]) == 0)
00507 isc_sockaddr_setport(&addrs[i], port);
00508 }
00509 INSIST(i == count);
00510
00511 *addrsp = addrs;
00512 *countp = count;
00513
00514 if (dscpsp != NULL)
00515 *dscpsp = dscps;
00516
00517 return (ISC_R_SUCCESS);
00518 }
00519
00520 void
00521 ns_config_putiplist(isc_mem_t *mctx, isc_sockaddr_t **addrsp,
00522 isc_dscp_t **dscpsp, isc_uint32_t count)
00523 {
00524 INSIST(addrsp != NULL && *addrsp != NULL);
00525 INSIST(dscpsp == NULL || *dscpsp != NULL);
00526
00527 isc_mem_put(mctx, *addrsp, count * sizeof(isc_sockaddr_t));
00528 *addrsp = NULL;
00529
00530 if (dscpsp != NULL) {
00531 isc_mem_put(mctx, *dscpsp, count * sizeof(isc_dscp_t));
00532 *dscpsp = NULL;
00533 }
00534 }
00535
00536 static isc_result_t
00537 get_masters_def(const cfg_obj_t *cctx, const char *name,
00538 const cfg_obj_t **ret)
00539 {
00540 isc_result_t result;
00541 const cfg_obj_t *masters = NULL;
00542 const cfg_listelt_t *elt;
00543
00544 result = cfg_map_get(cctx, "masters", &masters);
00545 if (result != ISC_R_SUCCESS)
00546 return (result);
00547 for (elt = cfg_list_first(masters);
00548 elt != NULL;
00549 elt = cfg_list_next(elt)) {
00550 const cfg_obj_t *list;
00551 const char *listname;
00552
00553 list = cfg_listelt_value(elt);
00554 listname = cfg_obj_asstring(cfg_tuple_get(list, "name"));
00555
00556 if (strcasecmp(listname, name) == 0) {
00557 *ret = list;
00558 return (ISC_R_SUCCESS);
00559 }
00560 }
00561 return (ISC_R_NOTFOUND);
00562 }
00563
00564 isc_result_t
00565 ns_config_getipandkeylist(const cfg_obj_t *config, const cfg_obj_t *list,
00566 isc_mem_t *mctx, isc_sockaddr_t **addrsp,
00567 isc_dscp_t **dscpsp, dns_name_t ***keysp,
00568 isc_uint32_t *countp)
00569 {
00570 isc_uint32_t addrcount = 0, dscpcount = 0, keycount = 0, i = 0;
00571 isc_uint32_t listcount = 0, l = 0, j;
00572 isc_uint32_t stackcount = 0, pushed = 0;
00573 isc_result_t result;
00574 const cfg_listelt_t *element;
00575 const cfg_obj_t *addrlist;
00576 const cfg_obj_t *portobj;
00577 const cfg_obj_t *dscpobj;
00578 in_port_t port;
00579 isc_dscp_t dscp;
00580 dns_fixedname_t fname;
00581 isc_sockaddr_t *addrs = NULL;
00582 isc_dscp_t *dscps = NULL;
00583 dns_name_t **keys = NULL;
00584 struct { const char *name; } *lists = NULL;
00585 struct {
00586 const cfg_listelt_t *element;
00587 in_port_t port;
00588 isc_dscp_t dscp;
00589 } *stack = NULL;
00590
00591 REQUIRE(addrsp != NULL && *addrsp == NULL);
00592 REQUIRE(dscpsp != NULL && *dscpsp == NULL);
00593 REQUIRE(keysp != NULL && *keysp == NULL);
00594 REQUIRE(countp != NULL);
00595
00596
00597
00598
00599 result = ns_config_getport(config, &port);
00600 if (result != ISC_R_SUCCESS)
00601 goto cleanup;
00602
00603 result = ns_config_getdscp(config, &dscp);
00604 if (result != ISC_R_SUCCESS)
00605 goto cleanup;
00606
00607 newlist:
00608 addrlist = cfg_tuple_get(list, "addresses");
00609 portobj = cfg_tuple_get(list, "port");
00610 dscpobj = cfg_tuple_get(list, "dscp");
00611
00612 if (cfg_obj_isuint32(portobj)) {
00613 isc_uint32_t val = cfg_obj_asuint32(portobj);
00614 if (val > ISC_UINT16_MAX) {
00615 cfg_obj_log(portobj, ns_g_lctx, ISC_LOG_ERROR,
00616 "port '%u' out of range", val);
00617 result = ISC_R_RANGE;
00618 goto cleanup;
00619 }
00620 port = (in_port_t) val;
00621 }
00622
00623 if (dscpobj != NULL && cfg_obj_isuint32(dscpobj)) {
00624 if (cfg_obj_asuint32(dscpobj) > 63) {
00625 cfg_obj_log(dscpobj, ns_g_lctx, ISC_LOG_ERROR,
00626 "dscp value '%u' is out of range",
00627 cfg_obj_asuint32(dscpobj));
00628 result = ISC_R_RANGE;
00629 goto cleanup;
00630 }
00631 dscp = (isc_dscp_t)cfg_obj_asuint32(dscpobj);
00632 }
00633
00634 result = ISC_R_NOMEMORY;
00635
00636 element = cfg_list_first(addrlist);
00637 resume:
00638 for ( ;
00639 element != NULL;
00640 element = cfg_list_next(element))
00641 {
00642 const cfg_obj_t *addr;
00643 const cfg_obj_t *key;
00644 const char *keystr;
00645 isc_buffer_t b;
00646
00647 addr = cfg_tuple_get(cfg_listelt_value(element),
00648 "masterselement");
00649 key = cfg_tuple_get(cfg_listelt_value(element), "key");
00650
00651 if (!cfg_obj_issockaddr(addr)) {
00652 const char *listname = cfg_obj_asstring(addr);
00653 isc_result_t tresult;
00654
00655
00656 if (listcount == l) {
00657 void * new;
00658 isc_uint32_t newlen = listcount + 16;
00659 size_t newsize, oldsize;
00660
00661 newsize = newlen * sizeof(*lists);
00662 oldsize = listcount * sizeof(*lists);
00663 new = isc_mem_get(mctx, newsize);
00664 if (new == NULL)
00665 goto cleanup;
00666 if (listcount != 0) {
00667 memmove(new, lists, oldsize);
00668 isc_mem_put(mctx, lists, oldsize);
00669 }
00670 lists = new;
00671 listcount = newlen;
00672 }
00673
00674 for (j = 0; j < l; j++)
00675 if (strcasecmp(lists[j].name, listname) == 0)
00676 break;
00677 if (j < l)
00678 continue;
00679 tresult = get_masters_def(config, listname, &list);
00680 if (tresult == ISC_R_NOTFOUND) {
00681 cfg_obj_log(addr, ns_g_lctx, ISC_LOG_ERROR,
00682 "masters \"%s\" not found", listname);
00683
00684 result = tresult;
00685 goto cleanup;
00686 }
00687 if (tresult != ISC_R_SUCCESS)
00688 goto cleanup;
00689 lists[l++].name = listname;
00690
00691 if (stackcount == pushed) {
00692 void * new;
00693 isc_uint32_t newlen = stackcount + 16;
00694 size_t newsize, oldsize;
00695
00696 newsize = newlen * sizeof(*stack);
00697 oldsize = stackcount * sizeof(*stack);
00698 new = isc_mem_get(mctx, newsize);
00699 if (new == NULL)
00700 goto cleanup;
00701 if (stackcount != 0) {
00702 memmove(new, stack, oldsize);
00703 isc_mem_put(mctx, stack, oldsize);
00704 }
00705 stack = new;
00706 stackcount = newlen;
00707 }
00708
00709
00710
00711
00712 stack[pushed].element = cfg_list_next(element);
00713 stack[pushed].port = port;
00714 stack[pushed].dscp = dscp;
00715 pushed++;
00716 goto newlist;
00717 }
00718
00719 if (i == addrcount) {
00720 void * new;
00721 isc_uint32_t newlen = addrcount + 16;
00722 size_t newsize, oldsize;
00723
00724 newsize = newlen * sizeof(isc_sockaddr_t);
00725 oldsize = addrcount * sizeof(isc_sockaddr_t);
00726 new = isc_mem_get(mctx, newsize);
00727 if (new == NULL)
00728 goto cleanup;
00729 if (addrcount != 0) {
00730 memmove(new, addrs, oldsize);
00731 isc_mem_put(mctx, addrs, oldsize);
00732 }
00733 addrs = new;
00734 addrcount = newlen;
00735
00736 newsize = newlen * sizeof(isc_dscp_t);
00737 oldsize = dscpcount * sizeof(isc_dscp_t);
00738 new = isc_mem_get(mctx, newsize);
00739 if (new == NULL)
00740 goto cleanup;
00741 if (dscpcount != 0) {
00742 memmove(new, dscps, oldsize);
00743 isc_mem_put(mctx, dscps, oldsize);
00744 }
00745 dscps = new;
00746 dscpcount = newlen;
00747
00748 newsize = newlen * sizeof(dns_name_t *);
00749 oldsize = keycount * sizeof(dns_name_t *);
00750 new = isc_mem_get(mctx, newsize);
00751 if (new == NULL)
00752 goto cleanup;
00753 if (keycount != 0) {
00754 memmove(new, keys, oldsize);
00755 isc_mem_put(mctx, keys, oldsize);
00756 }
00757 keys = new;
00758 keycount = newlen;
00759 }
00760
00761 addrs[i] = *cfg_obj_assockaddr(addr);
00762 if (isc_sockaddr_getport(&addrs[i]) == 0)
00763 isc_sockaddr_setport(&addrs[i], port);
00764 dscps[i] = cfg_obj_getdscp(addr);
00765 if (dscps[i] == -1)
00766 dscps[i] = dscp;
00767 keys[i] = NULL;
00768 i++;
00769 if (!cfg_obj_isstring(key))
00770 continue;
00771 keys[i - 1] = isc_mem_get(mctx, sizeof(dns_name_t));
00772 if (keys[i - 1] == NULL)
00773 goto cleanup;
00774 dns_name_init(keys[i - 1], NULL);
00775
00776 keystr = cfg_obj_asstring(key);
00777 isc_buffer_constinit(&b, keystr, strlen(keystr));
00778 isc_buffer_add(&b, strlen(keystr));
00779 dns_fixedname_init(&fname);
00780 result = dns_name_fromtext(dns_fixedname_name(&fname), &b,
00781 dns_rootname, 0, NULL);
00782 if (result != ISC_R_SUCCESS)
00783 goto cleanup;
00784 result = dns_name_dup(dns_fixedname_name(&fname), mctx,
00785 keys[i - 1]);
00786 if (result != ISC_R_SUCCESS)
00787 goto cleanup;
00788 }
00789 if (pushed != 0) {
00790 pushed--;
00791 element = stack[pushed].element;
00792 port = stack[pushed].port;
00793 dscp = stack[pushed].dscp;
00794 goto resume;
00795 }
00796 if (i < addrcount) {
00797 void * new;
00798 size_t newsize, oldsize;
00799
00800 newsize = i * sizeof(isc_sockaddr_t);
00801 oldsize = addrcount * sizeof(isc_sockaddr_t);
00802 if (i != 0) {
00803 new = isc_mem_get(mctx, newsize);
00804 if (new == NULL)
00805 goto cleanup;
00806 memmove(new, addrs, newsize);
00807 } else
00808 new = NULL;
00809 isc_mem_put(mctx, addrs, oldsize);
00810 addrs = new;
00811 addrcount = i;
00812
00813 newsize = i * sizeof(isc_dscp_t);
00814 oldsize = dscpcount * sizeof(isc_dscp_t);
00815 if (i != 0) {
00816 new = isc_mem_get(mctx, newsize);
00817 if (new == NULL)
00818 goto cleanup;
00819 memmove(new, dscps, newsize);
00820 } else
00821 new = NULL;
00822 isc_mem_put(mctx, dscps, oldsize);
00823 dscps = new;
00824 dscpcount = i;
00825
00826 newsize = i * sizeof(dns_name_t *);
00827 oldsize = keycount * sizeof(dns_name_t *);
00828 if (i != 0) {
00829 new = isc_mem_get(mctx, newsize);
00830 if (new == NULL)
00831 goto cleanup;
00832 memmove(new, keys, newsize);
00833 } else
00834 new = NULL;
00835 isc_mem_put(mctx, keys, oldsize);
00836 keys = new;
00837 keycount = i;
00838 }
00839
00840 if (lists != NULL)
00841 isc_mem_put(mctx, lists, listcount * sizeof(*lists));
00842 if (stack != NULL)
00843 isc_mem_put(mctx, stack, stackcount * sizeof(*stack));
00844
00845 INSIST(keycount == addrcount);
00846
00847 *addrsp = addrs;
00848 *dscpsp = dscps;
00849 *keysp = keys;
00850 *countp = addrcount;
00851
00852 return (ISC_R_SUCCESS);
00853
00854 cleanup:
00855 if (addrs != NULL)
00856 isc_mem_put(mctx, addrs, addrcount * sizeof(isc_sockaddr_t));
00857 if (dscps != NULL)
00858 isc_mem_put(mctx, dscps, dscpcount * sizeof(isc_dscp_t));
00859 if (keys != NULL) {
00860 for (j = 0; j < i; j++) {
00861 if (keys[j] == NULL)
00862 continue;
00863 if (dns_name_dynamic(keys[j]))
00864 dns_name_free(keys[j], mctx);
00865 isc_mem_put(mctx, keys[j], sizeof(dns_name_t));
00866 }
00867 isc_mem_put(mctx, keys, keycount * sizeof(dns_name_t *));
00868 }
00869 if (lists != NULL)
00870 isc_mem_put(mctx, lists, listcount * sizeof(*lists));
00871 if (stack != NULL)
00872 isc_mem_put(mctx, stack, stackcount * sizeof(*stack));
00873 return (result);
00874 }
00875
00876 void
00877 ns_config_putipandkeylist(isc_mem_t *mctx, isc_sockaddr_t **addrsp,
00878 isc_dscp_t **dscpsp, dns_name_t ***keysp,
00879 isc_uint32_t count)
00880 {
00881 unsigned int i;
00882 dns_name_t **keys;
00883
00884 REQUIRE(addrsp != NULL && *addrsp != NULL);
00885 REQUIRE(dscpsp == NULL || *dscpsp != NULL);
00886 REQUIRE(keysp != NULL && *keysp != NULL);
00887
00888 keys = *keysp;
00889
00890 isc_mem_put(mctx, *addrsp, count * sizeof(isc_sockaddr_t));
00891 if (dscpsp != NULL)
00892 isc_mem_put(mctx, *dscpsp, count * sizeof(isc_dscp_t));
00893 for (i = 0; i < count; i++) {
00894 if (keys[i] == NULL)
00895 continue;
00896 if (dns_name_dynamic(keys[i]))
00897 dns_name_free(keys[i], mctx);
00898 isc_mem_put(mctx, keys[i], sizeof(dns_name_t));
00899 }
00900 isc_mem_put(mctx, *keysp, count * sizeof(dns_name_t *));
00901 *addrsp = NULL;
00902 if (dscpsp != NULL)
00903 *dscpsp = NULL;
00904 *keysp = NULL;
00905 }
00906
00907 isc_result_t
00908 ns_config_getport(const cfg_obj_t *config, in_port_t *portp) {
00909 const cfg_obj_t *maps[3];
00910 const cfg_obj_t *options = NULL;
00911 const cfg_obj_t *portobj = NULL;
00912 isc_result_t result;
00913 int i;
00914
00915 (void)cfg_map_get(config, "options", &options);
00916 i = 0;
00917 if (options != NULL)
00918 maps[i++] = options;
00919 maps[i++] = ns_g_defaults;
00920 maps[i] = NULL;
00921
00922 result = ns_config_get(maps, "port", &portobj);
00923 INSIST(result == ISC_R_SUCCESS);
00924 if (cfg_obj_asuint32(portobj) >= ISC_UINT16_MAX) {
00925 cfg_obj_log(portobj, ns_g_lctx, ISC_LOG_ERROR,
00926 "port '%u' out of range",
00927 cfg_obj_asuint32(portobj));
00928 return (ISC_R_RANGE);
00929 }
00930 *portp = (in_port_t)cfg_obj_asuint32(portobj);
00931 return (ISC_R_SUCCESS);
00932 }
00933
00934 isc_result_t
00935 ns_config_getdscp(const cfg_obj_t *config, isc_dscp_t *dscpp) {
00936 const cfg_obj_t *options = NULL;
00937 const cfg_obj_t *dscpobj = NULL;
00938 isc_result_t result;
00939
00940 (void)cfg_map_get(config, "options", &options);
00941 if (options == NULL)
00942 return (ISC_R_SUCCESS);
00943
00944 result = cfg_map_get(options, "dscp", &dscpobj);
00945 if (result != ISC_R_SUCCESS || dscpobj == NULL) {
00946 *dscpp = -1;
00947 return (ISC_R_SUCCESS);
00948 }
00949 if (cfg_obj_asuint32(dscpobj) >= 64) {
00950 cfg_obj_log(dscpobj, ns_g_lctx, ISC_LOG_ERROR,
00951 "dscp '%u' out of range",
00952 cfg_obj_asuint32(dscpobj));
00953 return (ISC_R_RANGE);
00954 }
00955 *dscpp = (isc_dscp_t)cfg_obj_asuint32(dscpobj);
00956 return (ISC_R_SUCCESS);
00957 }
00958
00959 struct keyalgorithms {
00960 const char *str;
00961 enum { hmacnone, hmacmd5, hmacsha1, hmacsha224,
00962 hmacsha256, hmacsha384, hmacsha512 } hmac;
00963 unsigned int type;
00964 isc_uint16_t size;
00965 } algorithms[] = {
00966 { "hmac-md5", hmacmd5, DST_ALG_HMACMD5, 128 },
00967 { "hmac-md5.sig-alg.reg.int", hmacmd5, DST_ALG_HMACMD5, 0 },
00968 { "hmac-md5.sig-alg.reg.int.", hmacmd5, DST_ALG_HMACMD5, 0 },
00969 { "hmac-sha1", hmacsha1, DST_ALG_HMACSHA1, 160 },
00970 { "hmac-sha224", hmacsha224, DST_ALG_HMACSHA224, 224 },
00971 { "hmac-sha256", hmacsha256, DST_ALG_HMACSHA256, 256 },
00972 { "hmac-sha384", hmacsha384, DST_ALG_HMACSHA384, 384 },
00973 { "hmac-sha512", hmacsha512, DST_ALG_HMACSHA512, 512 },
00974 { NULL, hmacnone, DST_ALG_UNKNOWN, 0 }
00975 };
00976
00977 isc_result_t
00978 ns_config_getkeyalgorithm(const char *str, dns_name_t **name,
00979 isc_uint16_t *digestbits)
00980 {
00981 return (ns_config_getkeyalgorithm2(str, name, NULL, digestbits));
00982 }
00983
00984 isc_result_t
00985 ns_config_getkeyalgorithm2(const char *str, dns_name_t **name,
00986 unsigned int *typep, isc_uint16_t *digestbits)
00987 {
00988 int i;
00989 size_t len = 0;
00990 isc_uint16_t bits;
00991 isc_result_t result;
00992
00993 for (i = 0; algorithms[i].str != NULL; i++) {
00994 len = strlen(algorithms[i].str);
00995 if (strncasecmp(algorithms[i].str, str, len) == 0 &&
00996 (str[len] == '\0' ||
00997 (algorithms[i].size != 0 && str[len] == '-')))
00998 break;
00999 }
01000 if (algorithms[i].str == NULL)
01001 return (ISC_R_NOTFOUND);
01002 if (str[len] == '-') {
01003 result = isc_parse_uint16(&bits, str + len + 1, 10);
01004 if (result != ISC_R_SUCCESS)
01005 return (result);
01006 if (bits > algorithms[i].size)
01007 return (ISC_R_RANGE);
01008 } else if (algorithms[i].size == 0)
01009 bits = 128;
01010 else
01011 bits = algorithms[i].size;
01012
01013 if (name != NULL) {
01014 switch (algorithms[i].hmac) {
01015 case hmacmd5: *name = dns_tsig_hmacmd5_name; break;
01016 case hmacsha1: *name = dns_tsig_hmacsha1_name; break;
01017 case hmacsha224: *name = dns_tsig_hmacsha224_name; break;
01018 case hmacsha256: *name = dns_tsig_hmacsha256_name; break;
01019 case hmacsha384: *name = dns_tsig_hmacsha384_name; break;
01020 case hmacsha512: *name = dns_tsig_hmacsha512_name; break;
01021 default:
01022 INSIST(0);
01023 }
01024 }
01025 if (typep != NULL)
01026 *typep = algorithms[i].type;
01027 if (digestbits != NULL)
01028 *digestbits = bits;
01029 return (ISC_R_SUCCESS);
01030 }