2 * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 2001, 2002 Internet Software Consortium.
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15 * PERFORMANCE OF THIS SOFTWARE.
18 /* $Id: config.c,v 1.11.2.6 2004/04/19 23:15:38 marka Exp $ */
25 #include <isc/buffer.h>
28 #include <isc/region.h>
29 #include <isc/result.h>
30 #include <isc/sockaddr.h>
33 #include <isccfg/cfg.h>
35 #include <dns/fixedname.h>
37 #include <dns/rdataclass.h>
41 #include <named/config.h>
42 #include <named/globals.h>
44 static char defaultconf[] = "\
46 # blackhole {none;};\n"
48 " coresize default;\n\
53 " deallocate-on-exit true;\n\
55 dump-file \"named_dump.db\";\n\
57 has-old-clients false;\n\
58 heartbeat-interval 60;\n\
59 host-statistics no;\n\
60 interface-interval 60;\n\
62 listen-on-v6 {none;};\n\
63 match-mapped-addresses no;\n\
64 memstatistics-file \"named.memstats\";\n\
65 multiple-cnames no;\n\
66 # named-xfer <obsolete>;\n\
67 # pid-file \"" NS_LOCALSTATEDIR "/named.pid\"; /* or /lwresd.pid */\n\
72 random-device \"" PATH_RANDOMDEV "\";\n\
76 recursive-clients 1000;\n\
77 rrset-order {order cyclic;};\n\
79 serial-query-rate 20;\n\
80 statistics-file \"named.stats\";\n\
81 statistics-interval 60;\n\
83 # tkey-dhkey <none>\n\
84 # tkey-gssapi-credential <none>\n\
85 # tkey-domain <none>\n\
86 transfers-per-ns 2;\n\
89 treat-cr-as-space true;\n\
92 version \""VERSION"\";\n\
95 allow-notify {none;};\n\
96 allow-update-forwarding {none;};\n\
97 allow-recursion {any;};\n\
98 allow-v6-synthesis {none;};\n\
101 auth-nxdomain false;\n\
102 minimal-responses false;\n\
104 provide-ixfr true;\n\
105 request-ixfr true;\n\
108 additional-from-auth true;\n\
109 additional-from-cache true;\n\
110 query-source address *;\n\
111 query-source-v6 address *;\n\
113 notify-source-v6 *;\n\
114 cleaning-interval 60;\n\
117 max-ncache-ttl 10800; /* 3 hours */\n\
118 max-cache-ttl 604800; /* 1 week */\n\
119 transfer-format many-answers;\n\
121 check-names master ignore;\n\
122 check-names slave ignore;\n\
123 check-names response ignore;\n\
126 allow-query {any;};\n\
127 allow-transfer {any;};\n\
129 # also-notify <none>\n\
132 # forwarders <none>\n\
133 maintain-ixfr-base no;\n\
134 # max-ixfr-log-size <obsolete>\n\
135 transfer-source *;\n\
136 transfer-source-v6 *;\n\
137 max-transfer-time-in 120;\n\
138 max-transfer-time-out 120;\n\
139 max-transfer-idle-in 60;\n\
140 max-transfer-idle-out 60;\n\
141 max-retry-time 1209600; /* 2 weeks */\n\
142 min-retry-time 500;\n\
143 max-refresh-time 2419200; /* 4 weeks */\n\
144 min-refresh-time 300;\n\
145 sig-validity-interval 30; /* days */\n\
146 zone-statistics false;\n\
150 ns_config_parsedefaults(cfg_parser_t *parser, cfg_obj_t **conf) {
153 isc_buffer_init(&b, defaultconf, sizeof(defaultconf) - 1);
154 isc_buffer_add(&b, sizeof(defaultconf) - 1);
155 return (cfg_parse_buffer(parser, &b, &cfg_type_namedconf, conf));
159 ns_config_get(cfg_obj_t **maps, const char* name, cfg_obj_t **obj) {
164 return (ISC_R_NOTFOUND);
165 if (cfg_map_get(maps[i], name, obj) == ISC_R_SUCCESS)
166 return (ISC_R_SUCCESS);
171 ns_config_listcount(cfg_obj_t *list) {
175 for (e = cfg_list_first(list); e != NULL; e = cfg_list_next(e))
182 ns_config_getclass(cfg_obj_t *classobj, dns_rdataclass_t defclass,
183 dns_rdataclass_t *classp) {
188 if (!cfg_obj_isstring(classobj)) {
190 return (ISC_R_SUCCESS);
192 str = cfg_obj_asstring(classobj);
194 r.length = strlen(str);
195 result = dns_rdataclass_fromtext(classp, &r);
196 if (result != ISC_R_SUCCESS)
197 cfg_obj_log(classobj, ns_g_lctx, ISC_LOG_ERROR,
198 "unknown class '%s'", str);
203 ns_config_getzonetype(cfg_obj_t *zonetypeobj) {
204 dns_zonetype_t ztype = dns_zone_none;
207 str = cfg_obj_asstring(zonetypeobj);
208 if (strcasecmp(str, "master") == 0)
209 ztype = dns_zone_master;
210 else if (strcasecmp(str, "slave") == 0)
211 ztype = dns_zone_slave;
212 else if (strcasecmp(str, "stub") == 0)
213 ztype = dns_zone_stub;
220 ns_config_getiplist(cfg_obj_t *config, cfg_obj_t *list,
221 in_port_t defport, isc_mem_t *mctx,
222 isc_sockaddr_t **addrsp, isc_uint32_t *countp)
227 cfg_listelt_t *element;
228 isc_sockaddr_t *addrs;
232 INSIST(addrsp != NULL && *addrsp == NULL);
234 addrlist = cfg_tuple_get(list, "addresses");
235 count = ns_config_listcount(addrlist);
237 portobj = cfg_tuple_get(list, "port");
238 if (cfg_obj_isuint32(portobj)) {
239 isc_uint32_t val = cfg_obj_asuint32(portobj);
240 if (val > ISC_UINT16_MAX) {
241 cfg_obj_log(portobj, ns_g_lctx, ISC_LOG_ERROR,
242 "port '%u' out of range", val);
243 return (ISC_R_RANGE);
245 port = (in_port_t) val;
246 } else if (defport != 0)
249 result = ns_config_getport(config, &port);
250 if (result != ISC_R_SUCCESS)
254 addrs = isc_mem_get(mctx, count * sizeof(isc_sockaddr_t));
256 return (ISC_R_NOMEMORY);
258 for (element = cfg_list_first(addrlist);
260 element = cfg_list_next(element), i++)
263 addrs[i] = *cfg_obj_assockaddr(cfg_listelt_value(element));
264 if (isc_sockaddr_getport(&addrs[i]) == 0)
265 isc_sockaddr_setport(&addrs[i], port);
272 return (ISC_R_SUCCESS);
276 ns_config_putiplist(isc_mem_t *mctx, isc_sockaddr_t **addrsp,
279 INSIST(addrsp != NULL && *addrsp != NULL);
281 isc_mem_put(mctx, *addrsp, count * sizeof(isc_sockaddr_t));
286 ns_config_getipandkeylist(cfg_obj_t *config, cfg_obj_t *list, isc_mem_t *mctx,
287 isc_sockaddr_t **addrsp, dns_name_t ***keysp,
288 isc_uint32_t *countp)
290 isc_uint32_t count, i = 0;
292 cfg_listelt_t *element;
296 dns_fixedname_t fname;
297 isc_sockaddr_t *addrs = NULL;
298 dns_name_t **keys = NULL;
300 INSIST(addrsp != NULL && *addrsp == NULL);
302 addrlist = cfg_tuple_get(list, "addresses");
303 count = ns_config_listcount(addrlist);
305 portobj = cfg_tuple_get(list, "port");
306 if (cfg_obj_isuint32(portobj)) {
307 isc_uint32_t val = cfg_obj_asuint32(portobj);
308 if (val > ISC_UINT16_MAX) {
309 cfg_obj_log(portobj, ns_g_lctx, ISC_LOG_ERROR,
310 "port '%u' out of range", val);
311 return (ISC_R_RANGE);
313 port = (in_port_t) val;
315 result = ns_config_getport(config, &port);
316 if (result != ISC_R_SUCCESS)
320 result = ISC_R_NOMEMORY;
322 addrs = isc_mem_get(mctx, count * sizeof(isc_sockaddr_t));
326 keys = isc_mem_get(mctx, count * sizeof(dns_name_t *));
330 for (element = cfg_list_first(addrlist);
332 element = cfg_list_next(element), i++)
341 addr = cfg_tuple_get(cfg_listelt_value(element), "sockaddr");
342 key = cfg_tuple_get(cfg_listelt_value(element), "key");
344 addrs[i] = *cfg_obj_assockaddr(addr);
345 if (isc_sockaddr_getport(&addrs[i]) == 0)
346 isc_sockaddr_setport(&addrs[i], port);
349 if (!cfg_obj_isstring(key))
351 keys[i] = isc_mem_get(mctx, sizeof(dns_name_t));
354 dns_name_init(keys[i], NULL);
356 keystr = cfg_obj_asstring(key);
357 isc_buffer_init(&b, keystr, strlen(keystr));
358 isc_buffer_add(&b, strlen(keystr));
359 dns_fixedname_init(&fname);
360 result = dns_name_fromtext(dns_fixedname_name(&fname), &b,
361 dns_rootname, ISC_FALSE, NULL);
362 if (result != ISC_R_SUCCESS)
364 result = dns_name_dup(dns_fixedname_name(&fname), mctx,
366 if (result != ISC_R_SUCCESS)
375 return (ISC_R_SUCCESS);
379 isc_mem_put(mctx, addrs, count * sizeof(isc_sockaddr_t));
382 for (j = 0 ; j <= i; j++) {
385 if (dns_name_dynamic(keys[j]))
386 dns_name_free(keys[j], mctx);
387 isc_mem_put(mctx, keys[j], sizeof(dns_name_t));
389 isc_mem_put(mctx, keys, count * sizeof(dns_name_t *));
395 ns_config_putipandkeylist(isc_mem_t *mctx, isc_sockaddr_t **addrsp,
396 dns_name_t ***keysp, isc_uint32_t count)
399 dns_name_t **keys = *keysp;
401 INSIST(addrsp != NULL && *addrsp != NULL);
403 isc_mem_put(mctx, *addrsp, count * sizeof(isc_sockaddr_t));
404 for (i = 0; i < count; i++) {
407 if (dns_name_dynamic(keys[i]))
408 dns_name_free(keys[i], mctx);
409 isc_mem_put(mctx, keys[i], sizeof(dns_name_t));
411 isc_mem_put(mctx, *keysp, count * sizeof(dns_name_t *));
417 ns_config_getport(cfg_obj_t *config, in_port_t *portp) {
419 cfg_obj_t *options = NULL;
420 cfg_obj_t *portobj = NULL;
424 cfg_map_get(config, "options", &options);
428 maps[i++] = ns_g_defaults;
431 result = ns_config_get(maps, "port", &portobj);
432 INSIST(result == ISC_R_SUCCESS);
433 if (cfg_obj_asuint32(portobj) >= ISC_UINT16_MAX) {
434 cfg_obj_log(portobj, ns_g_lctx, ISC_LOG_ERROR,
435 "port '%u' out of range",
436 cfg_obj_asuint32(portobj));
437 return (ISC_R_RANGE);
439 *portp = (in_port_t)cfg_obj_asuint32(portobj);
440 return (ISC_R_SUCCESS);
444 ns_config_getkeyalgorithm(const char *str, dns_name_t **name)
446 if (strcasecmp(str, "hmac-md5") == 0 ||
447 strcasecmp(str, "hmac-md5.sig-alg.reg.int") == 0 ||
448 strcasecmp(str, "hmac-md5.sig-alg.reg.int.") == 0)
451 *name = dns_tsig_hmacmd5_name;
452 return (ISC_R_SUCCESS);
454 return (ISC_R_NOTFOUND);