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
);