xref: /minix3/external/bsd/bind/dist/bin/named/config.c (revision 00b67f09dd46474d133c95011a48590a8e8f94c7)
1*00b67f09SDavid van Moolenbroek /*	$NetBSD: config.c,v 1.11 2015/07/08 17:28:55 christos Exp $	*/
2*00b67f09SDavid van Moolenbroek 
3*00b67f09SDavid van Moolenbroek /*
4*00b67f09SDavid van Moolenbroek  * Copyright (C) 2004-2014  Internet Systems Consortium, Inc. ("ISC")
5*00b67f09SDavid van Moolenbroek  * Copyright (C) 2001-2003  Internet Software Consortium.
6*00b67f09SDavid van Moolenbroek  *
7*00b67f09SDavid van Moolenbroek  * Permission to use, copy, modify, and/or distribute this software for any
8*00b67f09SDavid van Moolenbroek  * purpose with or without fee is hereby granted, provided that the above
9*00b67f09SDavid van Moolenbroek  * copyright notice and this permission notice appear in all copies.
10*00b67f09SDavid van Moolenbroek  *
11*00b67f09SDavid van Moolenbroek  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12*00b67f09SDavid van Moolenbroek  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13*00b67f09SDavid van Moolenbroek  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14*00b67f09SDavid van Moolenbroek  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15*00b67f09SDavid van Moolenbroek  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16*00b67f09SDavid van Moolenbroek  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17*00b67f09SDavid van Moolenbroek  * PERFORMANCE OF THIS SOFTWARE.
18*00b67f09SDavid van Moolenbroek  */
19*00b67f09SDavid van Moolenbroek 
20*00b67f09SDavid van Moolenbroek /*! \file */
21*00b67f09SDavid van Moolenbroek 
22*00b67f09SDavid van Moolenbroek #include <config.h>
23*00b67f09SDavid van Moolenbroek 
24*00b67f09SDavid van Moolenbroek #include <stdlib.h>
25*00b67f09SDavid van Moolenbroek 
26*00b67f09SDavid van Moolenbroek #include <isc/buffer.h>
27*00b67f09SDavid van Moolenbroek #include <isc/log.h>
28*00b67f09SDavid van Moolenbroek #include <isc/mem.h>
29*00b67f09SDavid van Moolenbroek #include <isc/parseint.h>
30*00b67f09SDavid van Moolenbroek #include <isc/region.h>
31*00b67f09SDavid van Moolenbroek #include <isc/result.h>
32*00b67f09SDavid van Moolenbroek #include <isc/sockaddr.h>
33*00b67f09SDavid van Moolenbroek #include <isc/string.h>
34*00b67f09SDavid van Moolenbroek #include <isc/util.h>
35*00b67f09SDavid van Moolenbroek 
36*00b67f09SDavid van Moolenbroek #include <isccfg/namedconf.h>
37*00b67f09SDavid van Moolenbroek 
38*00b67f09SDavid van Moolenbroek #include <dns/fixedname.h>
39*00b67f09SDavid van Moolenbroek #include <dns/name.h>
40*00b67f09SDavid van Moolenbroek #include <dns/rdataclass.h>
41*00b67f09SDavid van Moolenbroek #include <dns/rdatatype.h>
42*00b67f09SDavid van Moolenbroek #include <dns/tsig.h>
43*00b67f09SDavid van Moolenbroek #include <dns/zone.h>
44*00b67f09SDavid van Moolenbroek 
45*00b67f09SDavid van Moolenbroek #include <dst/dst.h>
46*00b67f09SDavid van Moolenbroek 
47*00b67f09SDavid van Moolenbroek #include <named/config.h>
48*00b67f09SDavid van Moolenbroek #include <named/globals.h>
49*00b67f09SDavid van Moolenbroek 
50*00b67f09SDavid van Moolenbroek #include <bind.keys.h>
51*00b67f09SDavid van Moolenbroek 
52*00b67f09SDavid van Moolenbroek /*% default configuration */
53*00b67f09SDavid van Moolenbroek static char defaultconf[] = "\
54*00b67f09SDavid van Moolenbroek options {\n\
55*00b67f09SDavid van Moolenbroek 	automatic-interface-scan yes;\n\
56*00b67f09SDavid van Moolenbroek #	blackhole {none;};\n"
57*00b67f09SDavid van Moolenbroek #ifndef WIN32
58*00b67f09SDavid van Moolenbroek "	coresize default;\n\
59*00b67f09SDavid van Moolenbroek 	datasize default;\n\
60*00b67f09SDavid van Moolenbroek 	files unlimited;\n\
61*00b67f09SDavid van Moolenbroek 	stacksize default;\n"
62*00b67f09SDavid van Moolenbroek #endif
63*00b67f09SDavid van Moolenbroek "#	session-keyfile \"" NS_LOCALSTATEDIR "/run/named/session.key\";\n\
64*00b67f09SDavid van Moolenbroek 	session-keyname local-ddns;\n\
65*00b67f09SDavid van Moolenbroek 	session-keyalg hmac-sha256;\n\
66*00b67f09SDavid van Moolenbroek 	deallocate-on-exit true;\n\
67*00b67f09SDavid van Moolenbroek #	directory <none>\n\
68*00b67f09SDavid van Moolenbroek 	dump-file \"named_dump.db\";\n\
69*00b67f09SDavid van Moolenbroek 	fake-iquery no;\n\
70*00b67f09SDavid van Moolenbroek 	has-old-clients false;\n\
71*00b67f09SDavid van Moolenbroek 	heartbeat-interval 60;\n\
72*00b67f09SDavid van Moolenbroek 	host-statistics no;\n\
73*00b67f09SDavid van Moolenbroek 	interface-interval 60;\n\
74*00b67f09SDavid van Moolenbroek 	listen-on {any;};\n\
75*00b67f09SDavid van Moolenbroek 	listen-on-v6 {any;};\n\
76*00b67f09SDavid van Moolenbroek 	match-mapped-addresses no;\n\
77*00b67f09SDavid van Moolenbroek 	max-rsa-exponent-size 0; /* no limit */\n\
78*00b67f09SDavid van Moolenbroek 	memstatistics-file \"named.memstats\";\n\
79*00b67f09SDavid van Moolenbroek 	multiple-cnames no;\n\
80*00b67f09SDavid van Moolenbroek #	named-xfer <obsolete>;\n\
81*00b67f09SDavid van Moolenbroek #	pid-file \"" NS_LOCALSTATEDIR "/run/named/named.pid\"; /* or /lwresd.pid */\n\
82*00b67f09SDavid van Moolenbroek 	bindkeys-file \"" NS_SYSCONFDIR "/bind.keys\";\n\
83*00b67f09SDavid van Moolenbroek 	port 53;\n\
84*00b67f09SDavid van Moolenbroek 	prefetch 2 9;\n\
85*00b67f09SDavid van Moolenbroek 	recursing-file \"named.recursing\";\n\
86*00b67f09SDavid van Moolenbroek 	secroots-file \"named.secroots\";\n\
87*00b67f09SDavid van Moolenbroek "
88*00b67f09SDavid van Moolenbroek #ifdef PATH_RANDOMDEV
89*00b67f09SDavid van Moolenbroek "\
90*00b67f09SDavid van Moolenbroek 	random-device \"" PATH_RANDOMDEV "\";\n\
91*00b67f09SDavid van Moolenbroek "
92*00b67f09SDavid van Moolenbroek #endif
93*00b67f09SDavid van Moolenbroek "\
94*00b67f09SDavid van Moolenbroek 	recursive-clients 1000;\n\
95*00b67f09SDavid van Moolenbroek 	resolver-query-timeout 10;\n\
96*00b67f09SDavid van Moolenbroek 	rrset-order { order random; };\n\
97*00b67f09SDavid van Moolenbroek 	serial-queries 20;\n\
98*00b67f09SDavid van Moolenbroek 	serial-query-rate 20;\n\
99*00b67f09SDavid van Moolenbroek 	server-id none;\n\
100*00b67f09SDavid van Moolenbroek 	statistics-file \"named.stats\";\n\
101*00b67f09SDavid van Moolenbroek 	statistics-interval 60;\n\
102*00b67f09SDavid van Moolenbroek 	tcp-clients 100;\n\
103*00b67f09SDavid van Moolenbroek 	tcp-listen-queue 10;\n\
104*00b67f09SDavid van Moolenbroek #	tkey-dhkey <none>\n\
105*00b67f09SDavid van Moolenbroek #	tkey-gssapi-credential <none>\n\
106*00b67f09SDavid van Moolenbroek #	tkey-domain <none>\n\
107*00b67f09SDavid van Moolenbroek 	transfers-per-ns 2;\n\
108*00b67f09SDavid van Moolenbroek 	transfers-in 10;\n\
109*00b67f09SDavid van Moolenbroek 	transfers-out 10;\n\
110*00b67f09SDavid van Moolenbroek 	treat-cr-as-space true;\n\
111*00b67f09SDavid van Moolenbroek 	use-id-pool true;\n\
112*00b67f09SDavid van Moolenbroek 	use-ixfr true;\n\
113*00b67f09SDavid van Moolenbroek 	edns-udp-size 4096;\n\
114*00b67f09SDavid van Moolenbroek 	max-udp-size 4096;\n\
115*00b67f09SDavid van Moolenbroek "
116*00b67f09SDavid van Moolenbroek #ifdef ISC_PLATFORM_USESIT
117*00b67f09SDavid van Moolenbroek "\
118*00b67f09SDavid van Moolenbroek 	nosit-udp-size 4096;\n\
119*00b67f09SDavid van Moolenbroek 	request-sit true;\n\
120*00b67f09SDavid van Moolenbroek "
121*00b67f09SDavid van Moolenbroek #endif
122*00b67f09SDavid van Moolenbroek "\
123*00b67f09SDavid van Moolenbroek 	request-nsid false;\n\
124*00b67f09SDavid van Moolenbroek 	reserved-sockets 512;\n\
125*00b67f09SDavid van Moolenbroek \n\
126*00b67f09SDavid van Moolenbroek 	/* DLV */\n\
127*00b67f09SDavid van Moolenbroek 	dnssec-lookaside . trust-anchor dlv.isc.org;\n\
128*00b67f09SDavid van Moolenbroek \n\
129*00b67f09SDavid van Moolenbroek 	/* view */\n\
130*00b67f09SDavid van Moolenbroek 	allow-notify {none;};\n\
131*00b67f09SDavid van Moolenbroek 	allow-update-forwarding {none;};\n\
132*00b67f09SDavid van Moolenbroek 	allow-query-cache { localnets; localhost; };\n\
133*00b67f09SDavid van Moolenbroek 	allow-query-cache-on { any; };\n\
134*00b67f09SDavid van Moolenbroek 	allow-recursion { localnets; localhost; };\n\
135*00b67f09SDavid van Moolenbroek 	allow-recursion-on { any; };\n\
136*00b67f09SDavid van Moolenbroek #	allow-v6-synthesis <obsolete>;\n\
137*00b67f09SDavid van Moolenbroek #	sortlist <none>\n\
138*00b67f09SDavid van Moolenbroek #	topology <none>\n\
139*00b67f09SDavid van Moolenbroek 	auth-nxdomain false;\n\
140*00b67f09SDavid van Moolenbroek 	minimal-responses false;\n\
141*00b67f09SDavid van Moolenbroek 	recursion true;\n\
142*00b67f09SDavid van Moolenbroek 	provide-ixfr true;\n\
143*00b67f09SDavid van Moolenbroek 	request-ixfr true;\n\
144*00b67f09SDavid van Moolenbroek 	fetch-glue no;\n\
145*00b67f09SDavid van Moolenbroek 	rfc2308-type1 no;\n\
146*00b67f09SDavid van Moolenbroek 	additional-from-auth true;\n\
147*00b67f09SDavid van Moolenbroek 	additional-from-cache true;\n\
148*00b67f09SDavid van Moolenbroek 	query-source address *;\n\
149*00b67f09SDavid van Moolenbroek 	query-source-v6 address *;\n\
150*00b67f09SDavid van Moolenbroek 	notify-source *;\n\
151*00b67f09SDavid van Moolenbroek 	notify-source-v6 *;\n\
152*00b67f09SDavid van Moolenbroek 	cleaning-interval 0;  /* now meaningless */\n\
153*00b67f09SDavid van Moolenbroek 	min-roots 2;\n\
154*00b67f09SDavid van Moolenbroek 	lame-ttl 600;\n\
155*00b67f09SDavid van Moolenbroek 	max-ncache-ttl 10800; /* 3 hours */\n\
156*00b67f09SDavid van Moolenbroek 	max-cache-ttl 604800; /* 1 week */\n\
157*00b67f09SDavid van Moolenbroek 	transfer-format many-answers;\n\
158*00b67f09SDavid van Moolenbroek 	max-cache-size 0;\n\
159*00b67f09SDavid van Moolenbroek 	check-names master fail;\n\
160*00b67f09SDavid van Moolenbroek 	check-names slave warn;\n\
161*00b67f09SDavid van Moolenbroek 	check-names response ignore;\n\
162*00b67f09SDavid van Moolenbroek 	check-dup-records warn;\n\
163*00b67f09SDavid van Moolenbroek 	check-mx warn;\n\
164*00b67f09SDavid van Moolenbroek 	check-spf warn;\n\
165*00b67f09SDavid van Moolenbroek 	acache-enable no;\n\
166*00b67f09SDavid van Moolenbroek 	acache-cleaning-interval 60;\n\
167*00b67f09SDavid van Moolenbroek 	max-acache-size 16M;\n\
168*00b67f09SDavid van Moolenbroek 	dnssec-enable yes;\n\
169*00b67f09SDavid van Moolenbroek 	dnssec-validation yes; \n\
170*00b67f09SDavid van Moolenbroek 	dnssec-accept-expired no;\n\
171*00b67f09SDavid van Moolenbroek 	clients-per-query 10;\n\
172*00b67f09SDavid van Moolenbroek 	max-clients-per-query 100;\n\
173*00b67f09SDavid van Moolenbroek 	max-recursion-depth 7;\n\
174*00b67f09SDavid van Moolenbroek 	max-recursion-queries 75;\n\
175*00b67f09SDavid van Moolenbroek 	zero-no-soa-ttl-cache no;\n\
176*00b67f09SDavid van Moolenbroek 	nsec3-test-zone no;\n\
177*00b67f09SDavid van Moolenbroek 	allow-new-zones no;\n\
178*00b67f09SDavid van Moolenbroek "
179*00b67f09SDavid van Moolenbroek #ifdef ALLOW_FILTER_AAAA
180*00b67f09SDavid van Moolenbroek "	filter-aaaa-on-v4 no;\n\
181*00b67f09SDavid van Moolenbroek 	filter-aaaa-on-v6 no;\n\
182*00b67f09SDavid van Moolenbroek 	filter-aaaa { any; };\n\
183*00b67f09SDavid van Moolenbroek "
184*00b67f09SDavid van Moolenbroek #endif
185*00b67f09SDavid van Moolenbroek 
186*00b67f09SDavid van Moolenbroek "	/* zone */\n\
187*00b67f09SDavid van Moolenbroek 	allow-query {any;};\n\
188*00b67f09SDavid van Moolenbroek 	allow-query-on {any;};\n\
189*00b67f09SDavid van Moolenbroek 	allow-transfer {any;};\n\
190*00b67f09SDavid van Moolenbroek 	notify yes;\n\
191*00b67f09SDavid van Moolenbroek #	also-notify <none>\n\
192*00b67f09SDavid van Moolenbroek 	notify-delay 5;\n\
193*00b67f09SDavid van Moolenbroek 	notify-to-soa no;\n\
194*00b67f09SDavid van Moolenbroek 	dialup no;\n\
195*00b67f09SDavid van Moolenbroek #	forward <none>\n\
196*00b67f09SDavid van Moolenbroek #	forwarders <none>\n\
197*00b67f09SDavid van Moolenbroek 	maintain-ixfr-base no;\n\
198*00b67f09SDavid van Moolenbroek #	max-ixfr-log-size <obsolete>\n\
199*00b67f09SDavid van Moolenbroek 	transfer-source *;\n\
200*00b67f09SDavid van Moolenbroek 	transfer-source-v6 *;\n\
201*00b67f09SDavid van Moolenbroek 	alt-transfer-source *;\n\
202*00b67f09SDavid van Moolenbroek 	alt-transfer-source-v6 *;\n\
203*00b67f09SDavid van Moolenbroek 	max-transfer-time-in 120;\n\
204*00b67f09SDavid van Moolenbroek 	max-transfer-time-out 120;\n\
205*00b67f09SDavid van Moolenbroek 	max-transfer-idle-in 60;\n\
206*00b67f09SDavid van Moolenbroek 	max-transfer-idle-out 60;\n\
207*00b67f09SDavid van Moolenbroek 	max-retry-time 1209600; /* 2 weeks */\n\
208*00b67f09SDavid van Moolenbroek 	min-retry-time 500;\n\
209*00b67f09SDavid van Moolenbroek 	max-refresh-time 2419200; /* 4 weeks */\n\
210*00b67f09SDavid van Moolenbroek 	min-refresh-time 300;\n\
211*00b67f09SDavid van Moolenbroek 	multi-master no;\n\
212*00b67f09SDavid van Moolenbroek 	dnssec-secure-to-insecure no;\n\
213*00b67f09SDavid van Moolenbroek 	sig-validity-interval 30; /* days */\n\
214*00b67f09SDavid van Moolenbroek 	sig-signing-nodes 100;\n\
215*00b67f09SDavid van Moolenbroek 	sig-signing-signatures 10;\n\
216*00b67f09SDavid van Moolenbroek 	sig-signing-type 65534;\n\
217*00b67f09SDavid van Moolenbroek 	inline-signing no;\n\
218*00b67f09SDavid van Moolenbroek 	zone-statistics terse;\n\
219*00b67f09SDavid van Moolenbroek 	max-journal-size unlimited;\n\
220*00b67f09SDavid van Moolenbroek 	ixfr-from-differences false;\n\
221*00b67f09SDavid van Moolenbroek 	check-wildcard yes;\n\
222*00b67f09SDavid van Moolenbroek 	check-sibling yes;\n\
223*00b67f09SDavid van Moolenbroek 	check-integrity yes;\n\
224*00b67f09SDavid van Moolenbroek 	check-mx-cname warn;\n\
225*00b67f09SDavid van Moolenbroek 	check-srv-cname warn;\n\
226*00b67f09SDavid van Moolenbroek 	zero-no-soa-ttl yes;\n\
227*00b67f09SDavid van Moolenbroek 	update-check-ksk yes;\n\
228*00b67f09SDavid van Moolenbroek 	serial-update-method increment;\n\
229*00b67f09SDavid van Moolenbroek 	dnssec-update-mode maintain;\n\
230*00b67f09SDavid van Moolenbroek 	dnssec-dnskey-kskonly no;\n\
231*00b67f09SDavid van Moolenbroek 	dnssec-loadkeys-interval 60;\n\
232*00b67f09SDavid van Moolenbroek 	try-tcp-refresh yes; /* BIND 8 compat */\n\
233*00b67f09SDavid van Moolenbroek };\n\
234*00b67f09SDavid van Moolenbroek "
235*00b67f09SDavid van Moolenbroek 
236*00b67f09SDavid van Moolenbroek "#\n\
237*00b67f09SDavid van Moolenbroek #  Zones in the \"_bind\" view are NOT counted in the count of zones.\n\
238*00b67f09SDavid van Moolenbroek #\n\
239*00b67f09SDavid van Moolenbroek view \"_bind\" chaos {\n\
240*00b67f09SDavid van Moolenbroek 	recursion no;\n\
241*00b67f09SDavid van Moolenbroek 	notify no;\n\
242*00b67f09SDavid van Moolenbroek 	allow-new-zones no;\n\
243*00b67f09SDavid van Moolenbroek \n\
244*00b67f09SDavid van Moolenbroek 	# Prevent use of this zone in DNS amplified reflection DoS attacks\n\
245*00b67f09SDavid van Moolenbroek 	rate-limit {\n\
246*00b67f09SDavid van Moolenbroek 		responses-per-second 3;\n\
247*00b67f09SDavid van Moolenbroek 		slip 0;\n\
248*00b67f09SDavid van Moolenbroek 		min-table-size 10;\n\
249*00b67f09SDavid van Moolenbroek 	};\n\
250*00b67f09SDavid van Moolenbroek \n\
251*00b67f09SDavid van Moolenbroek 	zone \"version.bind\" chaos {\n\
252*00b67f09SDavid van Moolenbroek 		type master;\n\
253*00b67f09SDavid van Moolenbroek 		database \"_builtin version\";\n\
254*00b67f09SDavid van Moolenbroek 	};\n\
255*00b67f09SDavid van Moolenbroek \n\
256*00b67f09SDavid van Moolenbroek 	zone \"hostname.bind\" chaos {\n\
257*00b67f09SDavid van Moolenbroek 		type master;\n\
258*00b67f09SDavid van Moolenbroek 		database \"_builtin hostname\";\n\
259*00b67f09SDavid van Moolenbroek 	};\n\
260*00b67f09SDavid van Moolenbroek \n\
261*00b67f09SDavid van Moolenbroek 	zone \"authors.bind\" chaos {\n\
262*00b67f09SDavid van Moolenbroek 		type master;\n\
263*00b67f09SDavid van Moolenbroek 		database \"_builtin authors\";\n\
264*00b67f09SDavid van Moolenbroek 	};\n\
265*00b67f09SDavid van Moolenbroek \n\
266*00b67f09SDavid van Moolenbroek 	zone \"id.server\" chaos {\n\
267*00b67f09SDavid van Moolenbroek 		type master;\n\
268*00b67f09SDavid van Moolenbroek 		database \"_builtin id\";\n\
269*00b67f09SDavid van Moolenbroek 	};\n\
270*00b67f09SDavid van Moolenbroek };\n\
271*00b67f09SDavid van Moolenbroek "
272*00b67f09SDavid van Moolenbroek "#\n\
273*00b67f09SDavid van Moolenbroek #  Default trusted key(s) for builtin DLV support\n\
274*00b67f09SDavid van Moolenbroek #  (used if \"dnssec-lookaside auto;\" is set and\n\
275*00b67f09SDavid van Moolenbroek #  sysconfdir/bind.keys doesn't exist).\n\
276*00b67f09SDavid van Moolenbroek #\n\
277*00b67f09SDavid van Moolenbroek # BEGIN MANAGED KEYS\n"
278*00b67f09SDavid van Moolenbroek 
279*00b67f09SDavid van Moolenbroek /* Imported from bind.keys.h: */
280*00b67f09SDavid van Moolenbroek MANAGED_KEYS
281*00b67f09SDavid van Moolenbroek 
282*00b67f09SDavid van Moolenbroek "# END MANAGED KEYS\n\
283*00b67f09SDavid van Moolenbroek ";
284*00b67f09SDavid van Moolenbroek 
285*00b67f09SDavid van Moolenbroek isc_result_t
ns_config_parsedefaults(cfg_parser_t * parser,cfg_obj_t ** conf)286*00b67f09SDavid van Moolenbroek ns_config_parsedefaults(cfg_parser_t *parser, cfg_obj_t **conf) {
287*00b67f09SDavid van Moolenbroek 	isc_buffer_t b;
288*00b67f09SDavid van Moolenbroek 
289*00b67f09SDavid van Moolenbroek 	isc_buffer_init(&b, defaultconf, sizeof(defaultconf) - 1);
290*00b67f09SDavid van Moolenbroek 	isc_buffer_add(&b, sizeof(defaultconf) - 1);
291*00b67f09SDavid van Moolenbroek 	return (cfg_parse_buffer(parser, &b, &cfg_type_namedconf, conf));
292*00b67f09SDavid van Moolenbroek }
293*00b67f09SDavid van Moolenbroek 
294*00b67f09SDavid van Moolenbroek isc_result_t
ns_config_get(cfg_obj_t const * const * maps,const char * name,const cfg_obj_t ** obj)295*00b67f09SDavid van Moolenbroek ns_config_get(cfg_obj_t const * const *maps, const char *name,
296*00b67f09SDavid van Moolenbroek 	      const cfg_obj_t **obj)
297*00b67f09SDavid van Moolenbroek {
298*00b67f09SDavid van Moolenbroek 	int i;
299*00b67f09SDavid van Moolenbroek 
300*00b67f09SDavid van Moolenbroek 	for (i = 0;; i++) {
301*00b67f09SDavid van Moolenbroek 		if (maps[i] == NULL)
302*00b67f09SDavid van Moolenbroek 			return (ISC_R_NOTFOUND);
303*00b67f09SDavid van Moolenbroek 		if (cfg_map_get(maps[i], name, obj) == ISC_R_SUCCESS)
304*00b67f09SDavid van Moolenbroek 			return (ISC_R_SUCCESS);
305*00b67f09SDavid van Moolenbroek 	}
306*00b67f09SDavid van Moolenbroek }
307*00b67f09SDavid van Moolenbroek 
308*00b67f09SDavid van Moolenbroek isc_result_t
ns_checknames_get(const cfg_obj_t ** maps,const char * which,const cfg_obj_t ** obj)309*00b67f09SDavid van Moolenbroek ns_checknames_get(const cfg_obj_t **maps, const char *which,
310*00b67f09SDavid van Moolenbroek 		  const cfg_obj_t **obj)
311*00b67f09SDavid van Moolenbroek {
312*00b67f09SDavid van Moolenbroek 	const cfg_listelt_t *element;
313*00b67f09SDavid van Moolenbroek 	const cfg_obj_t *checknames;
314*00b67f09SDavid van Moolenbroek 	const cfg_obj_t *type;
315*00b67f09SDavid van Moolenbroek 	const cfg_obj_t *value;
316*00b67f09SDavid van Moolenbroek 	int i;
317*00b67f09SDavid van Moolenbroek 
318*00b67f09SDavid van Moolenbroek 	for (i = 0;; i++) {
319*00b67f09SDavid van Moolenbroek 		if (maps[i] == NULL)
320*00b67f09SDavid van Moolenbroek 			return (ISC_R_NOTFOUND);
321*00b67f09SDavid van Moolenbroek 		checknames = NULL;
322*00b67f09SDavid van Moolenbroek 		if (cfg_map_get(maps[i], "check-names",
323*00b67f09SDavid van Moolenbroek 				&checknames) == ISC_R_SUCCESS) {
324*00b67f09SDavid van Moolenbroek 			/*
325*00b67f09SDavid van Moolenbroek 			 * Zone map entry is not a list.
326*00b67f09SDavid van Moolenbroek 			 */
327*00b67f09SDavid van Moolenbroek 			if (checknames != NULL && !cfg_obj_islist(checknames)) {
328*00b67f09SDavid van Moolenbroek 				*obj = checknames;
329*00b67f09SDavid van Moolenbroek 				return (ISC_R_SUCCESS);
330*00b67f09SDavid van Moolenbroek 			}
331*00b67f09SDavid van Moolenbroek 			for (element = cfg_list_first(checknames);
332*00b67f09SDavid van Moolenbroek 			     element != NULL;
333*00b67f09SDavid van Moolenbroek 			     element = cfg_list_next(element)) {
334*00b67f09SDavid van Moolenbroek 				value = cfg_listelt_value(element);
335*00b67f09SDavid van Moolenbroek 				type = cfg_tuple_get(value, "type");
336*00b67f09SDavid van Moolenbroek 				if (strcasecmp(cfg_obj_asstring(type),
337*00b67f09SDavid van Moolenbroek 					       which) == 0) {
338*00b67f09SDavid van Moolenbroek 					*obj = cfg_tuple_get(value, "mode");
339*00b67f09SDavid van Moolenbroek 					return (ISC_R_SUCCESS);
340*00b67f09SDavid van Moolenbroek 				}
341*00b67f09SDavid van Moolenbroek 			}
342*00b67f09SDavid van Moolenbroek 
343*00b67f09SDavid van Moolenbroek 		}
344*00b67f09SDavid van Moolenbroek 	}
345*00b67f09SDavid van Moolenbroek }
346*00b67f09SDavid van Moolenbroek 
347*00b67f09SDavid van Moolenbroek int
ns_config_listcount(const cfg_obj_t * list)348*00b67f09SDavid van Moolenbroek ns_config_listcount(const cfg_obj_t *list) {
349*00b67f09SDavid van Moolenbroek 	const cfg_listelt_t *e;
350*00b67f09SDavid van Moolenbroek 	int i = 0;
351*00b67f09SDavid van Moolenbroek 
352*00b67f09SDavid van Moolenbroek 	for (e = cfg_list_first(list); e != NULL; e = cfg_list_next(e))
353*00b67f09SDavid van Moolenbroek 		i++;
354*00b67f09SDavid van Moolenbroek 
355*00b67f09SDavid van Moolenbroek 	return (i);
356*00b67f09SDavid van Moolenbroek }
357*00b67f09SDavid van Moolenbroek 
358*00b67f09SDavid van Moolenbroek isc_result_t
ns_config_getclass(const cfg_obj_t * classobj,dns_rdataclass_t defclass,dns_rdataclass_t * classp)359*00b67f09SDavid van Moolenbroek ns_config_getclass(const cfg_obj_t *classobj, dns_rdataclass_t defclass,
360*00b67f09SDavid van Moolenbroek 		   dns_rdataclass_t *classp) {
361*00b67f09SDavid van Moolenbroek 	isc_textregion_t r;
362*00b67f09SDavid van Moolenbroek 	isc_result_t result;
363*00b67f09SDavid van Moolenbroek 
364*00b67f09SDavid van Moolenbroek 	if (!cfg_obj_isstring(classobj)) {
365*00b67f09SDavid van Moolenbroek 		*classp = defclass;
366*00b67f09SDavid van Moolenbroek 		return (ISC_R_SUCCESS);
367*00b67f09SDavid van Moolenbroek 	}
368*00b67f09SDavid van Moolenbroek 	DE_CONST(cfg_obj_asstring(classobj), r.base);
369*00b67f09SDavid van Moolenbroek 	r.length = strlen(r.base);
370*00b67f09SDavid van Moolenbroek 	result = dns_rdataclass_fromtext(classp, &r);
371*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS)
372*00b67f09SDavid van Moolenbroek 		cfg_obj_log(classobj, ns_g_lctx, ISC_LOG_ERROR,
373*00b67f09SDavid van Moolenbroek 			    "unknown class '%s'", r.base);
374*00b67f09SDavid van Moolenbroek 	return (result);
375*00b67f09SDavid van Moolenbroek }
376*00b67f09SDavid van Moolenbroek 
377*00b67f09SDavid van Moolenbroek isc_result_t
ns_config_gettype(const cfg_obj_t * typeobj,dns_rdatatype_t deftype,dns_rdatatype_t * typep)378*00b67f09SDavid van Moolenbroek ns_config_gettype(const cfg_obj_t *typeobj, dns_rdatatype_t deftype,
379*00b67f09SDavid van Moolenbroek 		   dns_rdatatype_t *typep) {
380*00b67f09SDavid van Moolenbroek 	isc_textregion_t r;
381*00b67f09SDavid van Moolenbroek 	isc_result_t result;
382*00b67f09SDavid van Moolenbroek 
383*00b67f09SDavid van Moolenbroek 	if (!cfg_obj_isstring(typeobj)) {
384*00b67f09SDavid van Moolenbroek 		*typep = deftype;
385*00b67f09SDavid van Moolenbroek 		return (ISC_R_SUCCESS);
386*00b67f09SDavid van Moolenbroek 	}
387*00b67f09SDavid van Moolenbroek 	DE_CONST(cfg_obj_asstring(typeobj), r.base);
388*00b67f09SDavid van Moolenbroek 	r.length = strlen(r.base);
389*00b67f09SDavid van Moolenbroek 	result = dns_rdatatype_fromtext(typep, &r);
390*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS)
391*00b67f09SDavid van Moolenbroek 		cfg_obj_log(typeobj, ns_g_lctx, ISC_LOG_ERROR,
392*00b67f09SDavid van Moolenbroek 			    "unknown type '%s'", r.base);
393*00b67f09SDavid van Moolenbroek 	return (result);
394*00b67f09SDavid van Moolenbroek }
395*00b67f09SDavid van Moolenbroek 
396*00b67f09SDavid van Moolenbroek dns_zonetype_t
ns_config_getzonetype(const cfg_obj_t * zonetypeobj)397*00b67f09SDavid van Moolenbroek ns_config_getzonetype(const cfg_obj_t *zonetypeobj) {
398*00b67f09SDavid van Moolenbroek 	dns_zonetype_t ztype = dns_zone_none;
399*00b67f09SDavid van Moolenbroek 	const char *str;
400*00b67f09SDavid van Moolenbroek 
401*00b67f09SDavid van Moolenbroek 	str = cfg_obj_asstring(zonetypeobj);
402*00b67f09SDavid van Moolenbroek 	if (strcasecmp(str, "master") == 0)
403*00b67f09SDavid van Moolenbroek 		ztype = dns_zone_master;
404*00b67f09SDavid van Moolenbroek 	else if (strcasecmp(str, "slave") == 0)
405*00b67f09SDavid van Moolenbroek 		ztype = dns_zone_slave;
406*00b67f09SDavid van Moolenbroek 	else if (strcasecmp(str, "stub") == 0)
407*00b67f09SDavid van Moolenbroek 		ztype = dns_zone_stub;
408*00b67f09SDavid van Moolenbroek 	else if (strcasecmp(str, "static-stub") == 0)
409*00b67f09SDavid van Moolenbroek 		ztype = dns_zone_staticstub;
410*00b67f09SDavid van Moolenbroek 	else if (strcasecmp(str, "redirect") == 0)
411*00b67f09SDavid van Moolenbroek 		ztype = dns_zone_redirect;
412*00b67f09SDavid van Moolenbroek 	else
413*00b67f09SDavid van Moolenbroek 		INSIST(0);
414*00b67f09SDavid van Moolenbroek 	return (ztype);
415*00b67f09SDavid van Moolenbroek }
416*00b67f09SDavid van Moolenbroek 
417*00b67f09SDavid van Moolenbroek isc_result_t
ns_config_getiplist(const cfg_obj_t * config,const cfg_obj_t * list,in_port_t defport,isc_mem_t * mctx,isc_sockaddr_t ** addrsp,isc_dscp_t ** dscpsp,isc_uint32_t * countp)418*00b67f09SDavid van Moolenbroek ns_config_getiplist(const cfg_obj_t *config, const cfg_obj_t *list,
419*00b67f09SDavid van Moolenbroek 		    in_port_t defport, isc_mem_t *mctx,
420*00b67f09SDavid van Moolenbroek 		    isc_sockaddr_t **addrsp, isc_dscp_t **dscpsp,
421*00b67f09SDavid van Moolenbroek 		    isc_uint32_t *countp)
422*00b67f09SDavid van Moolenbroek {
423*00b67f09SDavid van Moolenbroek 	int count, i = 0;
424*00b67f09SDavid van Moolenbroek 	const cfg_obj_t *addrlist;
425*00b67f09SDavid van Moolenbroek 	const cfg_obj_t *portobj, *dscpobj;
426*00b67f09SDavid van Moolenbroek 	const cfg_listelt_t *element;
427*00b67f09SDavid van Moolenbroek 	isc_sockaddr_t *addrs;
428*00b67f09SDavid van Moolenbroek 	in_port_t port;
429*00b67f09SDavid van Moolenbroek 	isc_dscp_t dscp = -1, *dscps = NULL;
430*00b67f09SDavid van Moolenbroek 	isc_result_t result;
431*00b67f09SDavid van Moolenbroek 
432*00b67f09SDavid van Moolenbroek 	INSIST(addrsp != NULL && *addrsp == NULL);
433*00b67f09SDavid van Moolenbroek 	INSIST(dscpsp == NULL || *dscpsp == NULL);
434*00b67f09SDavid van Moolenbroek 	INSIST(countp != NULL);
435*00b67f09SDavid van Moolenbroek 
436*00b67f09SDavid van Moolenbroek 	addrlist = cfg_tuple_get(list, "addresses");
437*00b67f09SDavid van Moolenbroek 	count = ns_config_listcount(addrlist);
438*00b67f09SDavid van Moolenbroek 
439*00b67f09SDavid van Moolenbroek 	portobj = cfg_tuple_get(list, "port");
440*00b67f09SDavid van Moolenbroek 	if (cfg_obj_isuint32(portobj)) {
441*00b67f09SDavid van Moolenbroek 		isc_uint32_t val = cfg_obj_asuint32(portobj);
442*00b67f09SDavid van Moolenbroek 		if (val > ISC_UINT16_MAX) {
443*00b67f09SDavid van Moolenbroek 			cfg_obj_log(portobj, ns_g_lctx, ISC_LOG_ERROR,
444*00b67f09SDavid van Moolenbroek 				    "port '%u' out of range", val);
445*00b67f09SDavid van Moolenbroek 			return (ISC_R_RANGE);
446*00b67f09SDavid van Moolenbroek 		}
447*00b67f09SDavid van Moolenbroek 		port = (in_port_t) val;
448*00b67f09SDavid van Moolenbroek 	} else if (defport != 0)
449*00b67f09SDavid van Moolenbroek 		port = defport;
450*00b67f09SDavid van Moolenbroek 	else {
451*00b67f09SDavid van Moolenbroek 		result = ns_config_getport(config, &port);
452*00b67f09SDavid van Moolenbroek 		if (result != ISC_R_SUCCESS)
453*00b67f09SDavid van Moolenbroek 			return (result);
454*00b67f09SDavid van Moolenbroek 	}
455*00b67f09SDavid van Moolenbroek 
456*00b67f09SDavid van Moolenbroek 	if (dscpsp != NULL) {
457*00b67f09SDavid van Moolenbroek 		dscps = isc_mem_get(mctx, count * sizeof(isc_dscp_t));
458*00b67f09SDavid van Moolenbroek 		if (dscps == NULL)
459*00b67f09SDavid van Moolenbroek 			return (ISC_R_NOMEMORY);
460*00b67f09SDavid van Moolenbroek 
461*00b67f09SDavid van Moolenbroek 		dscpobj = cfg_tuple_get(list, "dscp");
462*00b67f09SDavid van Moolenbroek 		if (dscpobj != NULL && cfg_obj_isuint32(dscpobj)) {
463*00b67f09SDavid van Moolenbroek 			if (cfg_obj_asuint32(dscpobj) > 63) {
464*00b67f09SDavid van Moolenbroek 				cfg_obj_log(dscpobj, ns_g_lctx, ISC_LOG_ERROR,
465*00b67f09SDavid van Moolenbroek 					    "dscp value '%u' is out of range",
466*00b67f09SDavid van Moolenbroek 					    cfg_obj_asuint32(dscpobj));
467*00b67f09SDavid van Moolenbroek 				return (ISC_R_RANGE);
468*00b67f09SDavid van Moolenbroek 			}
469*00b67f09SDavid van Moolenbroek 			dscp = (isc_dscp_t)cfg_obj_asuint32(dscpobj);
470*00b67f09SDavid van Moolenbroek 		}
471*00b67f09SDavid van Moolenbroek 	}
472*00b67f09SDavid van Moolenbroek 
473*00b67f09SDavid van Moolenbroek 	addrs = isc_mem_get(mctx, count * sizeof(isc_sockaddr_t));
474*00b67f09SDavid van Moolenbroek 	if (addrs == NULL)
475*00b67f09SDavid van Moolenbroek 		return (ISC_R_NOMEMORY);
476*00b67f09SDavid van Moolenbroek 
477*00b67f09SDavid van Moolenbroek 	for (element = cfg_list_first(addrlist);
478*00b67f09SDavid van Moolenbroek 	     element != NULL;
479*00b67f09SDavid van Moolenbroek 	     element = cfg_list_next(element), i++)
480*00b67f09SDavid van Moolenbroek 	{
481*00b67f09SDavid van Moolenbroek 		const cfg_obj_t *addr;
482*00b67f09SDavid van Moolenbroek 		INSIST(i < count);
483*00b67f09SDavid van Moolenbroek 		addr = cfg_listelt_value(element);
484*00b67f09SDavid van Moolenbroek 		addrs[i] = *cfg_obj_assockaddr(addr);
485*00b67f09SDavid van Moolenbroek 		if (dscpsp != NULL) {
486*00b67f09SDavid van Moolenbroek 			isc_dscp_t innerdscp;
487*00b67f09SDavid van Moolenbroek 			innerdscp = cfg_obj_getdscp(addr);
488*00b67f09SDavid van Moolenbroek 			if (innerdscp == -1)
489*00b67f09SDavid van Moolenbroek 				innerdscp = dscp;
490*00b67f09SDavid van Moolenbroek 			dscps[i] = innerdscp;
491*00b67f09SDavid van Moolenbroek 		}
492*00b67f09SDavid van Moolenbroek 		if (isc_sockaddr_getport(&addrs[i]) == 0)
493*00b67f09SDavid van Moolenbroek 			isc_sockaddr_setport(&addrs[i], port);
494*00b67f09SDavid van Moolenbroek 	}
495*00b67f09SDavid van Moolenbroek 	INSIST(i == count);
496*00b67f09SDavid van Moolenbroek 
497*00b67f09SDavid van Moolenbroek 	*addrsp = addrs;
498*00b67f09SDavid van Moolenbroek 	*countp = count;
499*00b67f09SDavid van Moolenbroek 
500*00b67f09SDavid van Moolenbroek 	if (dscpsp != NULL)
501*00b67f09SDavid van Moolenbroek 		*dscpsp = dscps;
502*00b67f09SDavid van Moolenbroek 
503*00b67f09SDavid van Moolenbroek 	return (ISC_R_SUCCESS);
504*00b67f09SDavid van Moolenbroek }
505*00b67f09SDavid van Moolenbroek 
506*00b67f09SDavid van Moolenbroek void
ns_config_putiplist(isc_mem_t * mctx,isc_sockaddr_t ** addrsp,isc_dscp_t ** dscpsp,isc_uint32_t count)507*00b67f09SDavid van Moolenbroek ns_config_putiplist(isc_mem_t *mctx, isc_sockaddr_t **addrsp,
508*00b67f09SDavid van Moolenbroek 		    isc_dscp_t **dscpsp, isc_uint32_t count)
509*00b67f09SDavid van Moolenbroek {
510*00b67f09SDavid van Moolenbroek 	INSIST(addrsp != NULL && *addrsp != NULL);
511*00b67f09SDavid van Moolenbroek 	INSIST(dscpsp == NULL || *dscpsp != NULL);
512*00b67f09SDavid van Moolenbroek 
513*00b67f09SDavid van Moolenbroek 	isc_mem_put(mctx, *addrsp, count * sizeof(isc_sockaddr_t));
514*00b67f09SDavid van Moolenbroek 	*addrsp = NULL;
515*00b67f09SDavid van Moolenbroek 
516*00b67f09SDavid van Moolenbroek 	if (dscpsp != NULL) {
517*00b67f09SDavid van Moolenbroek 		isc_mem_put(mctx, *dscpsp, count * sizeof(isc_dscp_t));
518*00b67f09SDavid van Moolenbroek 		*dscpsp = NULL;
519*00b67f09SDavid van Moolenbroek 	}
520*00b67f09SDavid van Moolenbroek }
521*00b67f09SDavid van Moolenbroek 
522*00b67f09SDavid van Moolenbroek static isc_result_t
get_masters_def(const cfg_obj_t * cctx,const char * name,const cfg_obj_t ** ret)523*00b67f09SDavid van Moolenbroek get_masters_def(const cfg_obj_t *cctx, const char *name,
524*00b67f09SDavid van Moolenbroek 		const cfg_obj_t **ret)
525*00b67f09SDavid van Moolenbroek {
526*00b67f09SDavid van Moolenbroek 	isc_result_t result;
527*00b67f09SDavid van Moolenbroek 	const cfg_obj_t *masters = NULL;
528*00b67f09SDavid van Moolenbroek 	const cfg_listelt_t *elt;
529*00b67f09SDavid van Moolenbroek 
530*00b67f09SDavid van Moolenbroek 	result = cfg_map_get(cctx, "masters", &masters);
531*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS)
532*00b67f09SDavid van Moolenbroek 		return (result);
533*00b67f09SDavid van Moolenbroek 	for (elt = cfg_list_first(masters);
534*00b67f09SDavid van Moolenbroek 	     elt != NULL;
535*00b67f09SDavid van Moolenbroek 	     elt = cfg_list_next(elt)) {
536*00b67f09SDavid van Moolenbroek 		const cfg_obj_t *list;
537*00b67f09SDavid van Moolenbroek 		const char *listname;
538*00b67f09SDavid van Moolenbroek 
539*00b67f09SDavid van Moolenbroek 		list = cfg_listelt_value(elt);
540*00b67f09SDavid van Moolenbroek 		listname = cfg_obj_asstring(cfg_tuple_get(list, "name"));
541*00b67f09SDavid van Moolenbroek 
542*00b67f09SDavid van Moolenbroek 		if (strcasecmp(listname, name) == 0) {
543*00b67f09SDavid van Moolenbroek 			*ret = list;
544*00b67f09SDavid van Moolenbroek 			return (ISC_R_SUCCESS);
545*00b67f09SDavid van Moolenbroek 		}
546*00b67f09SDavid van Moolenbroek 	}
547*00b67f09SDavid van Moolenbroek 	return (ISC_R_NOTFOUND);
548*00b67f09SDavid van Moolenbroek }
549*00b67f09SDavid van Moolenbroek 
550*00b67f09SDavid van Moolenbroek isc_result_t
ns_config_getipandkeylist(const cfg_obj_t * config,const cfg_obj_t * list,isc_mem_t * mctx,isc_sockaddr_t ** addrsp,isc_dscp_t ** dscpsp,dns_name_t *** keysp,isc_uint32_t * countp)551*00b67f09SDavid van Moolenbroek ns_config_getipandkeylist(const cfg_obj_t *config, const cfg_obj_t *list,
552*00b67f09SDavid van Moolenbroek 			  isc_mem_t *mctx, isc_sockaddr_t **addrsp,
553*00b67f09SDavid van Moolenbroek 			  isc_dscp_t **dscpsp, dns_name_t ***keysp,
554*00b67f09SDavid van Moolenbroek 			  isc_uint32_t *countp)
555*00b67f09SDavid van Moolenbroek {
556*00b67f09SDavid van Moolenbroek 	isc_uint32_t addrcount = 0, dscpcount = 0, keycount = 0, i = 0;
557*00b67f09SDavid van Moolenbroek 	isc_uint32_t listcount = 0, l = 0, j;
558*00b67f09SDavid van Moolenbroek 	isc_uint32_t stackcount = 0, pushed = 0;
559*00b67f09SDavid van Moolenbroek 	isc_result_t result;
560*00b67f09SDavid van Moolenbroek 	const cfg_listelt_t *element;
561*00b67f09SDavid van Moolenbroek 	const cfg_obj_t *addrlist;
562*00b67f09SDavid van Moolenbroek 	const cfg_obj_t *portobj;
563*00b67f09SDavid van Moolenbroek 	const cfg_obj_t *dscpobj;
564*00b67f09SDavid van Moolenbroek 	in_port_t port;
565*00b67f09SDavid van Moolenbroek 	isc_dscp_t dscp;
566*00b67f09SDavid van Moolenbroek 	dns_fixedname_t fname;
567*00b67f09SDavid van Moolenbroek 	isc_sockaddr_t *addrs = NULL;
568*00b67f09SDavid van Moolenbroek 	isc_dscp_t *dscps = NULL;
569*00b67f09SDavid van Moolenbroek 	dns_name_t **keys = NULL;
570*00b67f09SDavid van Moolenbroek 	struct { const char *name; } *lists = NULL;
571*00b67f09SDavid van Moolenbroek 	struct {
572*00b67f09SDavid van Moolenbroek 		const cfg_listelt_t *element;
573*00b67f09SDavid van Moolenbroek 		in_port_t port;
574*00b67f09SDavid van Moolenbroek 		isc_dscp_t dscp;
575*00b67f09SDavid van Moolenbroek 	} *stack = NULL;
576*00b67f09SDavid van Moolenbroek 
577*00b67f09SDavid van Moolenbroek 	REQUIRE(addrsp != NULL && *addrsp == NULL);
578*00b67f09SDavid van Moolenbroek 	REQUIRE(dscpsp != NULL && *dscpsp == NULL);
579*00b67f09SDavid van Moolenbroek 	REQUIRE(keysp != NULL && *keysp == NULL);
580*00b67f09SDavid van Moolenbroek 	REQUIRE(countp != NULL);
581*00b67f09SDavid van Moolenbroek 
582*00b67f09SDavid van Moolenbroek 	/*
583*00b67f09SDavid van Moolenbroek 	 * Get system defaults.
584*00b67f09SDavid van Moolenbroek 	 */
585*00b67f09SDavid van Moolenbroek 	result = ns_config_getport(config, &port);
586*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS)
587*00b67f09SDavid van Moolenbroek 		goto cleanup;
588*00b67f09SDavid van Moolenbroek 
589*00b67f09SDavid van Moolenbroek 	result = ns_config_getdscp(config, &dscp);
590*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS)
591*00b67f09SDavid van Moolenbroek 		goto cleanup;
592*00b67f09SDavid van Moolenbroek 
593*00b67f09SDavid van Moolenbroek  newlist:
594*00b67f09SDavid van Moolenbroek 	addrlist = cfg_tuple_get(list, "addresses");
595*00b67f09SDavid van Moolenbroek 	portobj = cfg_tuple_get(list, "port");
596*00b67f09SDavid van Moolenbroek 	dscpobj = cfg_tuple_get(list, "dscp");
597*00b67f09SDavid van Moolenbroek 
598*00b67f09SDavid van Moolenbroek 	if (cfg_obj_isuint32(portobj)) {
599*00b67f09SDavid van Moolenbroek 		isc_uint32_t val = cfg_obj_asuint32(portobj);
600*00b67f09SDavid van Moolenbroek 		if (val > ISC_UINT16_MAX) {
601*00b67f09SDavid van Moolenbroek 			cfg_obj_log(portobj, ns_g_lctx, ISC_LOG_ERROR,
602*00b67f09SDavid van Moolenbroek 				    "port '%u' out of range", val);
603*00b67f09SDavid van Moolenbroek 			result = ISC_R_RANGE;
604*00b67f09SDavid van Moolenbroek 			goto cleanup;
605*00b67f09SDavid van Moolenbroek 		}
606*00b67f09SDavid van Moolenbroek 		port = (in_port_t) val;
607*00b67f09SDavid van Moolenbroek 	}
608*00b67f09SDavid van Moolenbroek 
609*00b67f09SDavid van Moolenbroek 	if (dscpobj != NULL && cfg_obj_isuint32(dscpobj)) {
610*00b67f09SDavid van Moolenbroek 		if (cfg_obj_asuint32(dscpobj) > 63) {
611*00b67f09SDavid van Moolenbroek 			cfg_obj_log(dscpobj, ns_g_lctx, ISC_LOG_ERROR,
612*00b67f09SDavid van Moolenbroek 				    "dscp value '%u' is out of range",
613*00b67f09SDavid van Moolenbroek 				    cfg_obj_asuint32(dscpobj));
614*00b67f09SDavid van Moolenbroek 			return (ISC_R_RANGE);
615*00b67f09SDavid van Moolenbroek 		}
616*00b67f09SDavid van Moolenbroek 		dscp = (isc_dscp_t)cfg_obj_asuint32(dscpobj);
617*00b67f09SDavid van Moolenbroek 	}
618*00b67f09SDavid van Moolenbroek 
619*00b67f09SDavid van Moolenbroek 	result = ISC_R_NOMEMORY;
620*00b67f09SDavid van Moolenbroek 
621*00b67f09SDavid van Moolenbroek 	element = cfg_list_first(addrlist);
622*00b67f09SDavid van Moolenbroek  resume:
623*00b67f09SDavid van Moolenbroek 	for ( ;
624*00b67f09SDavid van Moolenbroek 	     element != NULL;
625*00b67f09SDavid van Moolenbroek 	     element = cfg_list_next(element))
626*00b67f09SDavid van Moolenbroek 	{
627*00b67f09SDavid van Moolenbroek 		const cfg_obj_t *addr;
628*00b67f09SDavid van Moolenbroek 		const cfg_obj_t *key;
629*00b67f09SDavid van Moolenbroek 		const char *keystr;
630*00b67f09SDavid van Moolenbroek 		isc_buffer_t b;
631*00b67f09SDavid van Moolenbroek 
632*00b67f09SDavid van Moolenbroek 		addr = cfg_tuple_get(cfg_listelt_value(element),
633*00b67f09SDavid van Moolenbroek 				     "masterselement");
634*00b67f09SDavid van Moolenbroek 		key = cfg_tuple_get(cfg_listelt_value(element), "key");
635*00b67f09SDavid van Moolenbroek 
636*00b67f09SDavid van Moolenbroek 		if (!cfg_obj_issockaddr(addr)) {
637*00b67f09SDavid van Moolenbroek 			const char *listname = cfg_obj_asstring(addr);
638*00b67f09SDavid van Moolenbroek 			isc_result_t tresult;
639*00b67f09SDavid van Moolenbroek 
640*00b67f09SDavid van Moolenbroek 			/* Grow lists? */
641*00b67f09SDavid van Moolenbroek 			if (listcount == l) {
642*00b67f09SDavid van Moolenbroek 				void * new;
643*00b67f09SDavid van Moolenbroek 				isc_uint32_t newlen = listcount + 16;
644*00b67f09SDavid van Moolenbroek 				size_t newsize, oldsize;
645*00b67f09SDavid van Moolenbroek 
646*00b67f09SDavid van Moolenbroek 				newsize = newlen * sizeof(*lists);
647*00b67f09SDavid van Moolenbroek 				oldsize = listcount * sizeof(*lists);
648*00b67f09SDavid van Moolenbroek 				new = isc_mem_get(mctx, newsize);
649*00b67f09SDavid van Moolenbroek 				if (new == NULL)
650*00b67f09SDavid van Moolenbroek 					goto cleanup;
651*00b67f09SDavid van Moolenbroek 				if (listcount != 0) {
652*00b67f09SDavid van Moolenbroek 					memmove(new, lists, oldsize);
653*00b67f09SDavid van Moolenbroek 					isc_mem_put(mctx, lists, oldsize);
654*00b67f09SDavid van Moolenbroek 				}
655*00b67f09SDavid van Moolenbroek 				lists = new;
656*00b67f09SDavid van Moolenbroek 				listcount = newlen;
657*00b67f09SDavid van Moolenbroek 			}
658*00b67f09SDavid van Moolenbroek 			/* Seen? */
659*00b67f09SDavid van Moolenbroek 			for (j = 0; j < l; j++)
660*00b67f09SDavid van Moolenbroek 				if (strcasecmp(lists[j].name, listname) == 0)
661*00b67f09SDavid van Moolenbroek 					break;
662*00b67f09SDavid van Moolenbroek 			if (j < l)
663*00b67f09SDavid van Moolenbroek 				continue;
664*00b67f09SDavid van Moolenbroek 			tresult = get_masters_def(config, listname, &list);
665*00b67f09SDavid van Moolenbroek 			if (tresult == ISC_R_NOTFOUND) {
666*00b67f09SDavid van Moolenbroek 				cfg_obj_log(addr, ns_g_lctx, ISC_LOG_ERROR,
667*00b67f09SDavid van Moolenbroek 				    "masters \"%s\" not found", listname);
668*00b67f09SDavid van Moolenbroek 
669*00b67f09SDavid van Moolenbroek 				result = tresult;
670*00b67f09SDavid van Moolenbroek 				goto cleanup;
671*00b67f09SDavid van Moolenbroek 			}
672*00b67f09SDavid van Moolenbroek 			if (tresult != ISC_R_SUCCESS)
673*00b67f09SDavid van Moolenbroek 				goto cleanup;
674*00b67f09SDavid van Moolenbroek 			lists[l++].name = listname;
675*00b67f09SDavid van Moolenbroek 			/* Grow stack? */
676*00b67f09SDavid van Moolenbroek 			if (stackcount == pushed) {
677*00b67f09SDavid van Moolenbroek 				void * new;
678*00b67f09SDavid van Moolenbroek 				isc_uint32_t newlen = stackcount + 16;
679*00b67f09SDavid van Moolenbroek 				size_t newsize, oldsize;
680*00b67f09SDavid van Moolenbroek 
681*00b67f09SDavid van Moolenbroek 				newsize = newlen * sizeof(*stack);
682*00b67f09SDavid van Moolenbroek 				oldsize = stackcount * sizeof(*stack);
683*00b67f09SDavid van Moolenbroek 				new = isc_mem_get(mctx, newsize);
684*00b67f09SDavid van Moolenbroek 				if (new == NULL)
685*00b67f09SDavid van Moolenbroek 					goto cleanup;
686*00b67f09SDavid van Moolenbroek 				if (stackcount != 0) {
687*00b67f09SDavid van Moolenbroek 					memmove(new, stack, oldsize);
688*00b67f09SDavid van Moolenbroek 					isc_mem_put(mctx, stack, oldsize);
689*00b67f09SDavid van Moolenbroek 				}
690*00b67f09SDavid van Moolenbroek 				stack = new;
691*00b67f09SDavid van Moolenbroek 				stackcount = newlen;
692*00b67f09SDavid van Moolenbroek 			}
693*00b67f09SDavid van Moolenbroek 			/*
694*00b67f09SDavid van Moolenbroek 			 * We want to resume processing this list on the
695*00b67f09SDavid van Moolenbroek 			 * next element.
696*00b67f09SDavid van Moolenbroek 			 */
697*00b67f09SDavid van Moolenbroek 			stack[pushed].element = cfg_list_next(element);
698*00b67f09SDavid van Moolenbroek 			stack[pushed].port = port;
699*00b67f09SDavid van Moolenbroek 			stack[pushed].dscp = dscp;
700*00b67f09SDavid van Moolenbroek 			pushed++;
701*00b67f09SDavid van Moolenbroek 			goto newlist;
702*00b67f09SDavid van Moolenbroek 		}
703*00b67f09SDavid van Moolenbroek 
704*00b67f09SDavid van Moolenbroek 		if (i == addrcount) {
705*00b67f09SDavid van Moolenbroek 			void * new;
706*00b67f09SDavid van Moolenbroek 			isc_uint32_t newlen = addrcount + 16;
707*00b67f09SDavid van Moolenbroek 			size_t newsize, oldsize;
708*00b67f09SDavid van Moolenbroek 
709*00b67f09SDavid van Moolenbroek 			newsize = newlen * sizeof(isc_sockaddr_t);
710*00b67f09SDavid van Moolenbroek 			oldsize = addrcount * sizeof(isc_sockaddr_t);
711*00b67f09SDavid van Moolenbroek 			new = isc_mem_get(mctx, newsize);
712*00b67f09SDavid van Moolenbroek 			if (new == NULL)
713*00b67f09SDavid van Moolenbroek 				goto cleanup;
714*00b67f09SDavid van Moolenbroek 			if (addrcount != 0) {
715*00b67f09SDavid van Moolenbroek 				memmove(new, addrs, oldsize);
716*00b67f09SDavid van Moolenbroek 				isc_mem_put(mctx, addrs, oldsize);
717*00b67f09SDavid van Moolenbroek 			}
718*00b67f09SDavid van Moolenbroek 			addrs = new;
719*00b67f09SDavid van Moolenbroek 			addrcount = newlen;
720*00b67f09SDavid van Moolenbroek 
721*00b67f09SDavid van Moolenbroek 			newsize = newlen * sizeof(isc_dscp_t);
722*00b67f09SDavid van Moolenbroek 			oldsize = dscpcount * sizeof(isc_dscp_t);
723*00b67f09SDavid van Moolenbroek 			new = isc_mem_get(mctx, newsize);
724*00b67f09SDavid van Moolenbroek 			if (new == NULL)
725*00b67f09SDavid van Moolenbroek 				goto cleanup;
726*00b67f09SDavid van Moolenbroek 			if (dscpcount != 0) {
727*00b67f09SDavid van Moolenbroek 				memmove(new, dscps, oldsize);
728*00b67f09SDavid van Moolenbroek 				isc_mem_put(mctx, dscps, oldsize);
729*00b67f09SDavid van Moolenbroek 			}
730*00b67f09SDavid van Moolenbroek 			dscps = new;
731*00b67f09SDavid van Moolenbroek 			dscpcount = newlen;
732*00b67f09SDavid van Moolenbroek 
733*00b67f09SDavid van Moolenbroek 			newsize = newlen * sizeof(dns_name_t *);
734*00b67f09SDavid van Moolenbroek 			oldsize = keycount * sizeof(dns_name_t *);
735*00b67f09SDavid van Moolenbroek 			new = isc_mem_get(mctx, newsize);
736*00b67f09SDavid van Moolenbroek 			if (new == NULL)
737*00b67f09SDavid van Moolenbroek 				goto cleanup;
738*00b67f09SDavid van Moolenbroek 			if (keycount != 0) {
739*00b67f09SDavid van Moolenbroek 				memmove(new, keys, oldsize);
740*00b67f09SDavid van Moolenbroek 				isc_mem_put(mctx, keys, oldsize);
741*00b67f09SDavid van Moolenbroek 			}
742*00b67f09SDavid van Moolenbroek 			keys = new;
743*00b67f09SDavid van Moolenbroek 			keycount = newlen;
744*00b67f09SDavid van Moolenbroek 		}
745*00b67f09SDavid van Moolenbroek 
746*00b67f09SDavid van Moolenbroek 		addrs[i] = *cfg_obj_assockaddr(addr);
747*00b67f09SDavid van Moolenbroek 		if (isc_sockaddr_getport(&addrs[i]) == 0)
748*00b67f09SDavid van Moolenbroek 			isc_sockaddr_setport(&addrs[i], port);
749*00b67f09SDavid van Moolenbroek 		dscps[i] = cfg_obj_getdscp(addr);
750*00b67f09SDavid van Moolenbroek 		if (dscps[i] == -1)
751*00b67f09SDavid van Moolenbroek 			dscps[i] = dscp;
752*00b67f09SDavid van Moolenbroek 		keys[i] = NULL;
753*00b67f09SDavid van Moolenbroek 		i++;	/* Increment here so that cleanup on error works. */
754*00b67f09SDavid van Moolenbroek 		if (!cfg_obj_isstring(key))
755*00b67f09SDavid van Moolenbroek 			continue;
756*00b67f09SDavid van Moolenbroek 		keys[i - 1] = isc_mem_get(mctx, sizeof(dns_name_t));
757*00b67f09SDavid van Moolenbroek 		if (keys[i - 1] == NULL)
758*00b67f09SDavid van Moolenbroek 			goto cleanup;
759*00b67f09SDavid van Moolenbroek 		dns_name_init(keys[i - 1], NULL);
760*00b67f09SDavid van Moolenbroek 
761*00b67f09SDavid van Moolenbroek 		keystr = cfg_obj_asstring(key);
762*00b67f09SDavid van Moolenbroek 		isc_buffer_constinit(&b, keystr, strlen(keystr));
763*00b67f09SDavid van Moolenbroek 		isc_buffer_add(&b, strlen(keystr));
764*00b67f09SDavid van Moolenbroek 		dns_fixedname_init(&fname);
765*00b67f09SDavid van Moolenbroek 		result = dns_name_fromtext(dns_fixedname_name(&fname), &b,
766*00b67f09SDavid van Moolenbroek 					   dns_rootname, 0, NULL);
767*00b67f09SDavid van Moolenbroek 		if (result != ISC_R_SUCCESS)
768*00b67f09SDavid van Moolenbroek 			goto cleanup;
769*00b67f09SDavid van Moolenbroek 		result = dns_name_dup(dns_fixedname_name(&fname), mctx,
770*00b67f09SDavid van Moolenbroek 				      keys[i - 1]);
771*00b67f09SDavid van Moolenbroek 		if (result != ISC_R_SUCCESS)
772*00b67f09SDavid van Moolenbroek 			goto cleanup;
773*00b67f09SDavid van Moolenbroek 	}
774*00b67f09SDavid van Moolenbroek 	if (pushed != 0) {
775*00b67f09SDavid van Moolenbroek 		pushed--;
776*00b67f09SDavid van Moolenbroek 		element = stack[pushed].element;
777*00b67f09SDavid van Moolenbroek 		port = stack[pushed].port;
778*00b67f09SDavid van Moolenbroek 		dscp = stack[pushed].dscp;
779*00b67f09SDavid van Moolenbroek 		goto resume;
780*00b67f09SDavid van Moolenbroek 	}
781*00b67f09SDavid van Moolenbroek 	if (i < addrcount) {
782*00b67f09SDavid van Moolenbroek 		void * new;
783*00b67f09SDavid van Moolenbroek 		size_t newsize, oldsize;
784*00b67f09SDavid van Moolenbroek 
785*00b67f09SDavid van Moolenbroek 		newsize = i * sizeof(isc_sockaddr_t);
786*00b67f09SDavid van Moolenbroek 		oldsize = addrcount * sizeof(isc_sockaddr_t);
787*00b67f09SDavid van Moolenbroek 		if (i != 0) {
788*00b67f09SDavid van Moolenbroek 			new = isc_mem_get(mctx, newsize);
789*00b67f09SDavid van Moolenbroek 			if (new == NULL)
790*00b67f09SDavid van Moolenbroek 				goto cleanup;
791*00b67f09SDavid van Moolenbroek 			memmove(new, addrs, newsize);
792*00b67f09SDavid van Moolenbroek 		} else
793*00b67f09SDavid van Moolenbroek 			new = NULL;
794*00b67f09SDavid van Moolenbroek 		isc_mem_put(mctx, addrs, oldsize);
795*00b67f09SDavid van Moolenbroek 		addrs = new;
796*00b67f09SDavid van Moolenbroek 		addrcount = i;
797*00b67f09SDavid van Moolenbroek 
798*00b67f09SDavid van Moolenbroek 		newsize = i * sizeof(isc_dscp_t);
799*00b67f09SDavid van Moolenbroek 		oldsize = dscpcount * sizeof(isc_dscp_t);
800*00b67f09SDavid van Moolenbroek 		if (i != 0) {
801*00b67f09SDavid van Moolenbroek 			new = isc_mem_get(mctx, newsize);
802*00b67f09SDavid van Moolenbroek 			if (new == NULL)
803*00b67f09SDavid van Moolenbroek 				goto cleanup;
804*00b67f09SDavid van Moolenbroek 			memmove(new, dscps, newsize);
805*00b67f09SDavid van Moolenbroek 		} else
806*00b67f09SDavid van Moolenbroek 			new = NULL;
807*00b67f09SDavid van Moolenbroek 		isc_mem_put(mctx, dscps, oldsize);
808*00b67f09SDavid van Moolenbroek 		dscps = new;
809*00b67f09SDavid van Moolenbroek 		dscpcount = i;
810*00b67f09SDavid van Moolenbroek 
811*00b67f09SDavid van Moolenbroek 		newsize = i * sizeof(dns_name_t *);
812*00b67f09SDavid van Moolenbroek 		oldsize = keycount * sizeof(dns_name_t *);
813*00b67f09SDavid van Moolenbroek 		if (i != 0) {
814*00b67f09SDavid van Moolenbroek 			new = isc_mem_get(mctx, newsize);
815*00b67f09SDavid van Moolenbroek 			if (new == NULL)
816*00b67f09SDavid van Moolenbroek 				goto cleanup;
817*00b67f09SDavid van Moolenbroek 			memmove(new, keys,  newsize);
818*00b67f09SDavid van Moolenbroek 		} else
819*00b67f09SDavid van Moolenbroek 			new = NULL;
820*00b67f09SDavid van Moolenbroek 		isc_mem_put(mctx, keys, oldsize);
821*00b67f09SDavid van Moolenbroek 		keys = new;
822*00b67f09SDavid van Moolenbroek 		keycount = i;
823*00b67f09SDavid van Moolenbroek 	}
824*00b67f09SDavid van Moolenbroek 
825*00b67f09SDavid van Moolenbroek 	if (lists != NULL)
826*00b67f09SDavid van Moolenbroek 		isc_mem_put(mctx, lists, listcount * sizeof(*lists));
827*00b67f09SDavid van Moolenbroek 	if (stack != NULL)
828*00b67f09SDavid van Moolenbroek 		isc_mem_put(mctx, stack, stackcount * sizeof(*stack));
829*00b67f09SDavid van Moolenbroek 
830*00b67f09SDavid van Moolenbroek 	INSIST(keycount == addrcount);
831*00b67f09SDavid van Moolenbroek 
832*00b67f09SDavid van Moolenbroek 	*addrsp = addrs;
833*00b67f09SDavid van Moolenbroek 	*dscpsp = dscps;
834*00b67f09SDavid van Moolenbroek 	*keysp = keys;
835*00b67f09SDavid van Moolenbroek 	*countp = addrcount;
836*00b67f09SDavid van Moolenbroek 
837*00b67f09SDavid van Moolenbroek 	return (ISC_R_SUCCESS);
838*00b67f09SDavid van Moolenbroek 
839*00b67f09SDavid van Moolenbroek  cleanup:
840*00b67f09SDavid van Moolenbroek 	if (addrs != NULL)
841*00b67f09SDavid van Moolenbroek 		isc_mem_put(mctx, addrs, addrcount * sizeof(isc_sockaddr_t));
842*00b67f09SDavid van Moolenbroek 	if (dscps != NULL)
843*00b67f09SDavid van Moolenbroek 		isc_mem_put(mctx, dscps, dscpcount * sizeof(isc_dscp_t));
844*00b67f09SDavid van Moolenbroek 	if (keys != NULL) {
845*00b67f09SDavid van Moolenbroek 		for (j = 0; j < i; j++) {
846*00b67f09SDavid van Moolenbroek 			if (keys[j] == NULL)
847*00b67f09SDavid van Moolenbroek 				continue;
848*00b67f09SDavid van Moolenbroek 			if (dns_name_dynamic(keys[j]))
849*00b67f09SDavid van Moolenbroek 				dns_name_free(keys[j], mctx);
850*00b67f09SDavid van Moolenbroek 			isc_mem_put(mctx, keys[j], sizeof(dns_name_t));
851*00b67f09SDavid van Moolenbroek 		}
852*00b67f09SDavid van Moolenbroek 		isc_mem_put(mctx, keys, keycount * sizeof(dns_name_t *));
853*00b67f09SDavid van Moolenbroek 	}
854*00b67f09SDavid van Moolenbroek 	if (lists != NULL)
855*00b67f09SDavid van Moolenbroek 		isc_mem_put(mctx, lists, listcount * sizeof(*lists));
856*00b67f09SDavid van Moolenbroek 	if (stack != NULL)
857*00b67f09SDavid van Moolenbroek 		isc_mem_put(mctx, stack, stackcount * sizeof(*stack));
858*00b67f09SDavid van Moolenbroek 	return (result);
859*00b67f09SDavid van Moolenbroek }
860*00b67f09SDavid van Moolenbroek 
861*00b67f09SDavid van Moolenbroek void
ns_config_putipandkeylist(isc_mem_t * mctx,isc_sockaddr_t ** addrsp,isc_dscp_t ** dscpsp,dns_name_t *** keysp,isc_uint32_t count)862*00b67f09SDavid van Moolenbroek ns_config_putipandkeylist(isc_mem_t *mctx, isc_sockaddr_t **addrsp,
863*00b67f09SDavid van Moolenbroek 			  isc_dscp_t **dscpsp, dns_name_t ***keysp,
864*00b67f09SDavid van Moolenbroek 			  isc_uint32_t count)
865*00b67f09SDavid van Moolenbroek {
866*00b67f09SDavid van Moolenbroek 	unsigned int i;
867*00b67f09SDavid van Moolenbroek 	dns_name_t **keys;
868*00b67f09SDavid van Moolenbroek 
869*00b67f09SDavid van Moolenbroek 	REQUIRE(addrsp != NULL && *addrsp != NULL);
870*00b67f09SDavid van Moolenbroek 	REQUIRE(dscpsp == NULL || *dscpsp != NULL);
871*00b67f09SDavid van Moolenbroek 	REQUIRE(keysp != NULL && *keysp != NULL);
872*00b67f09SDavid van Moolenbroek 
873*00b67f09SDavid van Moolenbroek 	keys = *keysp;
874*00b67f09SDavid van Moolenbroek 
875*00b67f09SDavid van Moolenbroek 	isc_mem_put(mctx, *addrsp, count * sizeof(isc_sockaddr_t));
876*00b67f09SDavid van Moolenbroek 	if (dscpsp != NULL)
877*00b67f09SDavid van Moolenbroek 		isc_mem_put(mctx, *dscpsp, count * sizeof(isc_dscp_t));
878*00b67f09SDavid van Moolenbroek 	for (i = 0; i < count; i++) {
879*00b67f09SDavid van Moolenbroek 		if (keys[i] == NULL)
880*00b67f09SDavid van Moolenbroek 			continue;
881*00b67f09SDavid van Moolenbroek 		if (dns_name_dynamic(keys[i]))
882*00b67f09SDavid van Moolenbroek 			dns_name_free(keys[i], mctx);
883*00b67f09SDavid van Moolenbroek 		isc_mem_put(mctx, keys[i], sizeof(dns_name_t));
884*00b67f09SDavid van Moolenbroek 	}
885*00b67f09SDavid van Moolenbroek 	isc_mem_put(mctx, *keysp, count * sizeof(dns_name_t *));
886*00b67f09SDavid van Moolenbroek 	*addrsp = NULL;
887*00b67f09SDavid van Moolenbroek 	if (dscpsp != NULL)
888*00b67f09SDavid van Moolenbroek 		*dscpsp = NULL;
889*00b67f09SDavid van Moolenbroek 	*keysp = NULL;
890*00b67f09SDavid van Moolenbroek }
891*00b67f09SDavid van Moolenbroek 
892*00b67f09SDavid van Moolenbroek isc_result_t
ns_config_getport(const cfg_obj_t * config,in_port_t * portp)893*00b67f09SDavid van Moolenbroek ns_config_getport(const cfg_obj_t *config, in_port_t *portp) {
894*00b67f09SDavid van Moolenbroek 	const cfg_obj_t *maps[3];
895*00b67f09SDavid van Moolenbroek 	const cfg_obj_t *options = NULL;
896*00b67f09SDavid van Moolenbroek 	const cfg_obj_t *portobj = NULL;
897*00b67f09SDavid van Moolenbroek 	isc_result_t result;
898*00b67f09SDavid van Moolenbroek 	int i;
899*00b67f09SDavid van Moolenbroek 
900*00b67f09SDavid van Moolenbroek 	(void)cfg_map_get(config, "options", &options);
901*00b67f09SDavid van Moolenbroek 	i = 0;
902*00b67f09SDavid van Moolenbroek 	if (options != NULL)
903*00b67f09SDavid van Moolenbroek 		maps[i++] = options;
904*00b67f09SDavid van Moolenbroek 	maps[i++] = ns_g_defaults;
905*00b67f09SDavid van Moolenbroek 	maps[i] = NULL;
906*00b67f09SDavid van Moolenbroek 
907*00b67f09SDavid van Moolenbroek 	result = ns_config_get(maps, "port", &portobj);
908*00b67f09SDavid van Moolenbroek 	INSIST(result == ISC_R_SUCCESS);
909*00b67f09SDavid van Moolenbroek 	if (cfg_obj_asuint32(portobj) >= ISC_UINT16_MAX) {
910*00b67f09SDavid van Moolenbroek 		cfg_obj_log(portobj, ns_g_lctx, ISC_LOG_ERROR,
911*00b67f09SDavid van Moolenbroek 			    "port '%u' out of range",
912*00b67f09SDavid van Moolenbroek 			    cfg_obj_asuint32(portobj));
913*00b67f09SDavid van Moolenbroek 		return (ISC_R_RANGE);
914*00b67f09SDavid van Moolenbroek 	}
915*00b67f09SDavid van Moolenbroek 	*portp = (in_port_t)cfg_obj_asuint32(portobj);
916*00b67f09SDavid van Moolenbroek 	return (ISC_R_SUCCESS);
917*00b67f09SDavid van Moolenbroek }
918*00b67f09SDavid van Moolenbroek 
919*00b67f09SDavid van Moolenbroek isc_result_t
ns_config_getdscp(const cfg_obj_t * config,isc_dscp_t * dscpp)920*00b67f09SDavid van Moolenbroek ns_config_getdscp(const cfg_obj_t *config, isc_dscp_t *dscpp) {
921*00b67f09SDavid van Moolenbroek 	const cfg_obj_t *options = NULL;
922*00b67f09SDavid van Moolenbroek 	const cfg_obj_t *dscpobj = NULL;
923*00b67f09SDavid van Moolenbroek 	isc_result_t result;
924*00b67f09SDavid van Moolenbroek 
925*00b67f09SDavid van Moolenbroek 	(void)cfg_map_get(config, "options", &options);
926*00b67f09SDavid van Moolenbroek 	if (options == NULL)
927*00b67f09SDavid van Moolenbroek 		return (ISC_R_SUCCESS);
928*00b67f09SDavid van Moolenbroek 
929*00b67f09SDavid van Moolenbroek 	result = cfg_map_get(options, "dscp", &dscpobj);
930*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS || dscpobj == NULL) {
931*00b67f09SDavid van Moolenbroek 		*dscpp = -1;
932*00b67f09SDavid van Moolenbroek 		return (ISC_R_SUCCESS);
933*00b67f09SDavid van Moolenbroek 	}
934*00b67f09SDavid van Moolenbroek 	if (cfg_obj_asuint32(dscpobj) >= 64) {
935*00b67f09SDavid van Moolenbroek 		cfg_obj_log(dscpobj, ns_g_lctx, ISC_LOG_ERROR,
936*00b67f09SDavid van Moolenbroek 			    "dscp '%u' out of range",
937*00b67f09SDavid van Moolenbroek 			    cfg_obj_asuint32(dscpobj));
938*00b67f09SDavid van Moolenbroek 		return (ISC_R_RANGE);
939*00b67f09SDavid van Moolenbroek 	}
940*00b67f09SDavid van Moolenbroek 	*dscpp = (isc_dscp_t)cfg_obj_asuint32(dscpobj);
941*00b67f09SDavid van Moolenbroek 	return (ISC_R_SUCCESS);
942*00b67f09SDavid van Moolenbroek }
943*00b67f09SDavid van Moolenbroek 
944*00b67f09SDavid van Moolenbroek struct keyalgorithms {
945*00b67f09SDavid van Moolenbroek 	const char *str;
946*00b67f09SDavid van Moolenbroek 	enum { hmacnone, hmacmd5, hmacsha1, hmacsha224,
947*00b67f09SDavid van Moolenbroek 	       hmacsha256, hmacsha384, hmacsha512 } hmac;
948*00b67f09SDavid van Moolenbroek 	unsigned int type;
949*00b67f09SDavid van Moolenbroek 	isc_uint16_t size;
950*00b67f09SDavid van Moolenbroek } algorithms[] = {
951*00b67f09SDavid van Moolenbroek 	{ "hmac-md5", hmacmd5, DST_ALG_HMACMD5, 128 },
952*00b67f09SDavid van Moolenbroek 	{ "hmac-md5.sig-alg.reg.int", hmacmd5, DST_ALG_HMACMD5, 0 },
953*00b67f09SDavid van Moolenbroek 	{ "hmac-md5.sig-alg.reg.int.", hmacmd5, DST_ALG_HMACMD5, 0 },
954*00b67f09SDavid van Moolenbroek 	{ "hmac-sha1", hmacsha1, DST_ALG_HMACSHA1, 160 },
955*00b67f09SDavid van Moolenbroek 	{ "hmac-sha224", hmacsha224, DST_ALG_HMACSHA224, 224 },
956*00b67f09SDavid van Moolenbroek 	{ "hmac-sha256", hmacsha256, DST_ALG_HMACSHA256, 256 },
957*00b67f09SDavid van Moolenbroek 	{ "hmac-sha384", hmacsha384, DST_ALG_HMACSHA384, 384 },
958*00b67f09SDavid van Moolenbroek 	{ "hmac-sha512", hmacsha512, DST_ALG_HMACSHA512, 512 },
959*00b67f09SDavid van Moolenbroek 	{  NULL, hmacnone, DST_ALG_UNKNOWN, 0 }
960*00b67f09SDavid van Moolenbroek };
961*00b67f09SDavid van Moolenbroek 
962*00b67f09SDavid van Moolenbroek isc_result_t
ns_config_getkeyalgorithm(const char * str,dns_name_t ** name,isc_uint16_t * digestbits)963*00b67f09SDavid van Moolenbroek ns_config_getkeyalgorithm(const char *str, dns_name_t **name,
964*00b67f09SDavid van Moolenbroek 			  isc_uint16_t *digestbits)
965*00b67f09SDavid van Moolenbroek {
966*00b67f09SDavid van Moolenbroek 	return (ns_config_getkeyalgorithm2(str, name, NULL, digestbits));
967*00b67f09SDavid van Moolenbroek }
968*00b67f09SDavid van Moolenbroek 
969*00b67f09SDavid van Moolenbroek isc_result_t
ns_config_getkeyalgorithm2(const char * str,dns_name_t ** name,unsigned int * typep,isc_uint16_t * digestbits)970*00b67f09SDavid van Moolenbroek ns_config_getkeyalgorithm2(const char *str, dns_name_t **name,
971*00b67f09SDavid van Moolenbroek 			   unsigned int *typep, isc_uint16_t *digestbits)
972*00b67f09SDavid van Moolenbroek {
973*00b67f09SDavid van Moolenbroek 	int i;
974*00b67f09SDavid van Moolenbroek 	size_t len = 0;
975*00b67f09SDavid van Moolenbroek 	isc_uint16_t bits;
976*00b67f09SDavid van Moolenbroek 	isc_result_t result;
977*00b67f09SDavid van Moolenbroek 
978*00b67f09SDavid van Moolenbroek 	for (i = 0; algorithms[i].str != NULL; i++) {
979*00b67f09SDavid van Moolenbroek 		len = strlen(algorithms[i].str);
980*00b67f09SDavid van Moolenbroek 		if (strncasecmp(algorithms[i].str, str, len) == 0 &&
981*00b67f09SDavid van Moolenbroek 		    (str[len] == '\0' ||
982*00b67f09SDavid van Moolenbroek 		     (algorithms[i].size != 0 && str[len] == '-')))
983*00b67f09SDavid van Moolenbroek 			break;
984*00b67f09SDavid van Moolenbroek 	}
985*00b67f09SDavid van Moolenbroek 	if (algorithms[i].str == NULL)
986*00b67f09SDavid van Moolenbroek 		return (ISC_R_NOTFOUND);
987*00b67f09SDavid van Moolenbroek 	if (str[len] == '-') {
988*00b67f09SDavid van Moolenbroek 		result = isc_parse_uint16(&bits, str + len + 1, 10);
989*00b67f09SDavid van Moolenbroek 		if (result != ISC_R_SUCCESS)
990*00b67f09SDavid van Moolenbroek 			return (result);
991*00b67f09SDavid van Moolenbroek 		if (bits > algorithms[i].size)
992*00b67f09SDavid van Moolenbroek 			return (ISC_R_RANGE);
993*00b67f09SDavid van Moolenbroek 	} else if (algorithms[i].size == 0)
994*00b67f09SDavid van Moolenbroek 		bits = 128;
995*00b67f09SDavid van Moolenbroek 	else
996*00b67f09SDavid van Moolenbroek 		bits = algorithms[i].size;
997*00b67f09SDavid van Moolenbroek 
998*00b67f09SDavid van Moolenbroek 	if (name != NULL) {
999*00b67f09SDavid van Moolenbroek 		switch (algorithms[i].hmac) {
1000*00b67f09SDavid van Moolenbroek 		case hmacmd5: *name = dns_tsig_hmacmd5_name; break;
1001*00b67f09SDavid van Moolenbroek 		case hmacsha1: *name = dns_tsig_hmacsha1_name; break;
1002*00b67f09SDavid van Moolenbroek 		case hmacsha224: *name = dns_tsig_hmacsha224_name; break;
1003*00b67f09SDavid van Moolenbroek 		case hmacsha256: *name = dns_tsig_hmacsha256_name; break;
1004*00b67f09SDavid van Moolenbroek 		case hmacsha384: *name = dns_tsig_hmacsha384_name; break;
1005*00b67f09SDavid van Moolenbroek 		case hmacsha512: *name = dns_tsig_hmacsha512_name; break;
1006*00b67f09SDavid van Moolenbroek 		default:
1007*00b67f09SDavid van Moolenbroek 			INSIST(0);
1008*00b67f09SDavid van Moolenbroek 		}
1009*00b67f09SDavid van Moolenbroek 	}
1010*00b67f09SDavid van Moolenbroek 	if (typep != NULL)
1011*00b67f09SDavid van Moolenbroek 		*typep = algorithms[i].type;
1012*00b67f09SDavid van Moolenbroek 	if (digestbits != NULL)
1013*00b67f09SDavid van Moolenbroek 		*digestbits = bits;
1014*00b67f09SDavid van Moolenbroek 	return (ISC_R_SUCCESS);
1015*00b67f09SDavid van Moolenbroek }
1016