xref: /minix3/external/bsd/bind/dist/bin/named/zoneconf.c (revision 00b67f09dd46474d133c95011a48590a8e8f94c7)
1*00b67f09SDavid van Moolenbroek /*	$NetBSD: zoneconf.c,v 1.8 2015/07/08 17:28:55 christos Exp $	*/
2*00b67f09SDavid van Moolenbroek 
3*00b67f09SDavid van Moolenbroek /*
4*00b67f09SDavid van Moolenbroek  * Copyright (C) 2004-2015  Internet Systems Consortium, Inc. ("ISC")
5*00b67f09SDavid van Moolenbroek  * Copyright (C) 1999-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 /* Id */
21*00b67f09SDavid van Moolenbroek 
22*00b67f09SDavid van Moolenbroek /*% */
23*00b67f09SDavid van Moolenbroek 
24*00b67f09SDavid van Moolenbroek #include <config.h>
25*00b67f09SDavid van Moolenbroek 
26*00b67f09SDavid van Moolenbroek #include <isc/buffer.h>
27*00b67f09SDavid van Moolenbroek #include <isc/file.h>
28*00b67f09SDavid van Moolenbroek #include <isc/mem.h>
29*00b67f09SDavid van Moolenbroek #include <isc/print.h>
30*00b67f09SDavid van Moolenbroek #include <isc/stats.h>
31*00b67f09SDavid van Moolenbroek #include <isc/string.h>		/* Required for HP/UX (and others?) */
32*00b67f09SDavid van Moolenbroek #include <isc/util.h>
33*00b67f09SDavid van Moolenbroek 
34*00b67f09SDavid van Moolenbroek #include <dns/acl.h>
35*00b67f09SDavid van Moolenbroek #include <dns/db.h>
36*00b67f09SDavid van Moolenbroek #include <dns/fixedname.h>
37*00b67f09SDavid van Moolenbroek #include <dns/log.h>
38*00b67f09SDavid van Moolenbroek #include <dns/name.h>
39*00b67f09SDavid van Moolenbroek #include <dns/rdata.h>
40*00b67f09SDavid van Moolenbroek #include <dns/rdatatype.h>
41*00b67f09SDavid van Moolenbroek #include <dns/rdataset.h>
42*00b67f09SDavid van Moolenbroek #include <dns/rdatalist.h>
43*00b67f09SDavid van Moolenbroek #include <dns/result.h>
44*00b67f09SDavid van Moolenbroek #include <dns/sdlz.h>
45*00b67f09SDavid van Moolenbroek #include <dns/ssu.h>
46*00b67f09SDavid van Moolenbroek #include <dns/stats.h>
47*00b67f09SDavid van Moolenbroek #include <dns/view.h>
48*00b67f09SDavid van Moolenbroek #include <dns/zone.h>
49*00b67f09SDavid van Moolenbroek 
50*00b67f09SDavid van Moolenbroek #include <named/client.h>
51*00b67f09SDavid van Moolenbroek #include <named/config.h>
52*00b67f09SDavid van Moolenbroek #include <named/globals.h>
53*00b67f09SDavid van Moolenbroek #include <named/log.h>
54*00b67f09SDavid van Moolenbroek #include <named/server.h>
55*00b67f09SDavid van Moolenbroek #include <named/zoneconf.h>
56*00b67f09SDavid van Moolenbroek 
57*00b67f09SDavid van Moolenbroek /* ACLs associated with zone */
58*00b67f09SDavid van Moolenbroek typedef enum {
59*00b67f09SDavid van Moolenbroek 	allow_notify,
60*00b67f09SDavid van Moolenbroek 	allow_query,
61*00b67f09SDavid van Moolenbroek 	allow_query_on,
62*00b67f09SDavid van Moolenbroek 	allow_transfer,
63*00b67f09SDavid van Moolenbroek 	allow_update,
64*00b67f09SDavid van Moolenbroek 	allow_update_forwarding
65*00b67f09SDavid van Moolenbroek } acl_type_t;
66*00b67f09SDavid van Moolenbroek 
67*00b67f09SDavid van Moolenbroek #define RETERR(x) do { \
68*00b67f09SDavid van Moolenbroek 	isc_result_t _r = (x); \
69*00b67f09SDavid van Moolenbroek 	if (_r != ISC_R_SUCCESS) \
70*00b67f09SDavid van Moolenbroek 		return (_r); \
71*00b67f09SDavid van Moolenbroek 	} while (/*CONSTCOND*/0)
72*00b67f09SDavid van Moolenbroek 
73*00b67f09SDavid van Moolenbroek #define CHECK(x) do { \
74*00b67f09SDavid van Moolenbroek 	result = (x); \
75*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS) \
76*00b67f09SDavid van Moolenbroek 		goto cleanup; \
77*00b67f09SDavid van Moolenbroek 	} while (/*CONSTCOND*/0)
78*00b67f09SDavid van Moolenbroek 
79*00b67f09SDavid van Moolenbroek /*%
80*00b67f09SDavid van Moolenbroek  * Convenience function for configuring a single zone ACL.
81*00b67f09SDavid van Moolenbroek  */
82*00b67f09SDavid van Moolenbroek static isc_result_t
configure_zone_acl(const cfg_obj_t * zconfig,const cfg_obj_t * vconfig,const cfg_obj_t * config,acl_type_t acltype,cfg_aclconfctx_t * actx,dns_zone_t * zone,void (* setzacl)(dns_zone_t *,dns_acl_t *),void (* clearzacl)(dns_zone_t *))83*00b67f09SDavid van Moolenbroek configure_zone_acl(const cfg_obj_t *zconfig, const cfg_obj_t *vconfig,
84*00b67f09SDavid van Moolenbroek 		   const cfg_obj_t *config, acl_type_t acltype,
85*00b67f09SDavid van Moolenbroek 		   cfg_aclconfctx_t *actx, dns_zone_t *zone,
86*00b67f09SDavid van Moolenbroek 		   void (*setzacl)(dns_zone_t *, dns_acl_t *),
87*00b67f09SDavid van Moolenbroek 		   void (*clearzacl)(dns_zone_t *))
88*00b67f09SDavid van Moolenbroek {
89*00b67f09SDavid van Moolenbroek 	isc_result_t result;
90*00b67f09SDavid van Moolenbroek 	const cfg_obj_t *maps[5] = {NULL, NULL, NULL, NULL, NULL};
91*00b67f09SDavid van Moolenbroek 	const cfg_obj_t *aclobj = NULL;
92*00b67f09SDavid van Moolenbroek 	int i = 0;
93*00b67f09SDavid van Moolenbroek 	dns_acl_t **aclp = NULL, *acl = NULL;
94*00b67f09SDavid van Moolenbroek 	const char *aclname;
95*00b67f09SDavid van Moolenbroek 	dns_view_t *view;
96*00b67f09SDavid van Moolenbroek 
97*00b67f09SDavid van Moolenbroek 	view = dns_zone_getview(zone);
98*00b67f09SDavid van Moolenbroek 
99*00b67f09SDavid van Moolenbroek 	switch (acltype) {
100*00b67f09SDavid van Moolenbroek 	    case allow_notify:
101*00b67f09SDavid van Moolenbroek 		if (view != NULL)
102*00b67f09SDavid van Moolenbroek 			aclp = &view->notifyacl;
103*00b67f09SDavid van Moolenbroek 		aclname = "allow-notify";
104*00b67f09SDavid van Moolenbroek 		break;
105*00b67f09SDavid van Moolenbroek 	    case allow_query:
106*00b67f09SDavid van Moolenbroek 		if (view != NULL)
107*00b67f09SDavid van Moolenbroek 			aclp = &view->queryacl;
108*00b67f09SDavid van Moolenbroek 		aclname = "allow-query";
109*00b67f09SDavid van Moolenbroek 		break;
110*00b67f09SDavid van Moolenbroek 	    case allow_query_on:
111*00b67f09SDavid van Moolenbroek 		if (view != NULL)
112*00b67f09SDavid van Moolenbroek 			aclp = &view->queryonacl;
113*00b67f09SDavid van Moolenbroek 		aclname = "allow-query-on";
114*00b67f09SDavid van Moolenbroek 		break;
115*00b67f09SDavid van Moolenbroek 	    case allow_transfer:
116*00b67f09SDavid van Moolenbroek 		if (view != NULL)
117*00b67f09SDavid van Moolenbroek 			aclp = &view->transferacl;
118*00b67f09SDavid van Moolenbroek 		aclname = "allow-transfer";
119*00b67f09SDavid van Moolenbroek 		break;
120*00b67f09SDavid van Moolenbroek 	    case allow_update:
121*00b67f09SDavid van Moolenbroek 		if (view != NULL)
122*00b67f09SDavid van Moolenbroek 			aclp = &view->updateacl;
123*00b67f09SDavid van Moolenbroek 		aclname = "allow-update";
124*00b67f09SDavid van Moolenbroek 		break;
125*00b67f09SDavid van Moolenbroek 	    case allow_update_forwarding:
126*00b67f09SDavid van Moolenbroek 		if (view != NULL)
127*00b67f09SDavid van Moolenbroek 			aclp = &view->upfwdacl;
128*00b67f09SDavid van Moolenbroek 		aclname = "allow-update-forwarding";
129*00b67f09SDavid van Moolenbroek 		break;
130*00b67f09SDavid van Moolenbroek 	    default:
131*00b67f09SDavid van Moolenbroek 		INSIST(0);
132*00b67f09SDavid van Moolenbroek 		return (ISC_R_FAILURE);
133*00b67f09SDavid van Moolenbroek 	}
134*00b67f09SDavid van Moolenbroek 
135*00b67f09SDavid van Moolenbroek 	/* First check to see if ACL is defined within the zone */
136*00b67f09SDavid van Moolenbroek 	if (zconfig != NULL) {
137*00b67f09SDavid van Moolenbroek 		maps[0] = cfg_tuple_get(zconfig, "options");
138*00b67f09SDavid van Moolenbroek 		(void)ns_config_get(maps, aclname, &aclobj);
139*00b67f09SDavid van Moolenbroek 		if (aclobj != NULL) {
140*00b67f09SDavid van Moolenbroek 			aclp = NULL;
141*00b67f09SDavid van Moolenbroek 			goto parse_acl;
142*00b67f09SDavid van Moolenbroek 		}
143*00b67f09SDavid van Moolenbroek 	}
144*00b67f09SDavid van Moolenbroek 
145*00b67f09SDavid van Moolenbroek 	/* Failing that, see if there's a default ACL already in the view */
146*00b67f09SDavid van Moolenbroek 	if (aclp != NULL && *aclp != NULL) {
147*00b67f09SDavid van Moolenbroek 		(*setzacl)(zone, *aclp);
148*00b67f09SDavid van Moolenbroek 		return (ISC_R_SUCCESS);
149*00b67f09SDavid van Moolenbroek 	}
150*00b67f09SDavid van Moolenbroek 
151*00b67f09SDavid van Moolenbroek 	/* Check for default ACLs that haven't been parsed yet */
152*00b67f09SDavid van Moolenbroek 	if (vconfig != NULL) {
153*00b67f09SDavid van Moolenbroek 		const cfg_obj_t *options = cfg_tuple_get(vconfig, "options");
154*00b67f09SDavid van Moolenbroek 		if (options != NULL)
155*00b67f09SDavid van Moolenbroek 			maps[i++] = options;
156*00b67f09SDavid van Moolenbroek 	}
157*00b67f09SDavid van Moolenbroek 	if (config != NULL) {
158*00b67f09SDavid van Moolenbroek 		const cfg_obj_t *options = NULL;
159*00b67f09SDavid van Moolenbroek 		(void)cfg_map_get(config, "options", &options);
160*00b67f09SDavid van Moolenbroek 		if (options != NULL)
161*00b67f09SDavid van Moolenbroek 			maps[i++] = options;
162*00b67f09SDavid van Moolenbroek 	}
163*00b67f09SDavid van Moolenbroek 	maps[i++] = ns_g_defaults;
164*00b67f09SDavid van Moolenbroek 	maps[i] = NULL;
165*00b67f09SDavid van Moolenbroek 
166*00b67f09SDavid van Moolenbroek 	(void)ns_config_get(maps, aclname, &aclobj);
167*00b67f09SDavid van Moolenbroek 	if (aclobj == NULL) {
168*00b67f09SDavid van Moolenbroek 		(*clearzacl)(zone);
169*00b67f09SDavid van Moolenbroek 		return (ISC_R_SUCCESS);
170*00b67f09SDavid van Moolenbroek 	}
171*00b67f09SDavid van Moolenbroek 
172*00b67f09SDavid van Moolenbroek parse_acl:
173*00b67f09SDavid van Moolenbroek 	result = cfg_acl_fromconfig(aclobj, config, ns_g_lctx, actx,
174*00b67f09SDavid van Moolenbroek 				    dns_zone_getmctx(zone), 0, &acl);
175*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS)
176*00b67f09SDavid van Moolenbroek 		return (result);
177*00b67f09SDavid van Moolenbroek 	(*setzacl)(zone, acl);
178*00b67f09SDavid van Moolenbroek 
179*00b67f09SDavid van Moolenbroek 	/* Set the view default now */
180*00b67f09SDavid van Moolenbroek 	if (aclp != NULL)
181*00b67f09SDavid van Moolenbroek 		dns_acl_attach(acl, aclp);
182*00b67f09SDavid van Moolenbroek 
183*00b67f09SDavid van Moolenbroek 	dns_acl_detach(&acl);
184*00b67f09SDavid van Moolenbroek 	return (ISC_R_SUCCESS);
185*00b67f09SDavid van Moolenbroek }
186*00b67f09SDavid van Moolenbroek 
187*00b67f09SDavid van Moolenbroek /*%
188*00b67f09SDavid van Moolenbroek  * Parse the zone update-policy statement.
189*00b67f09SDavid van Moolenbroek  */
190*00b67f09SDavid van Moolenbroek static isc_result_t
configure_zone_ssutable(const cfg_obj_t * zconfig,dns_zone_t * zone,const char * zname)191*00b67f09SDavid van Moolenbroek configure_zone_ssutable(const cfg_obj_t *zconfig, dns_zone_t *zone,
192*00b67f09SDavid van Moolenbroek 			const char *zname)
193*00b67f09SDavid van Moolenbroek {
194*00b67f09SDavid van Moolenbroek 	const cfg_obj_t *updatepolicy = NULL;
195*00b67f09SDavid van Moolenbroek 	const cfg_listelt_t *element, *element2;
196*00b67f09SDavid van Moolenbroek 	dns_ssutable_t *table = NULL;
197*00b67f09SDavid van Moolenbroek 	isc_mem_t *mctx = dns_zone_getmctx(zone);
198*00b67f09SDavid van Moolenbroek 	isc_boolean_t autoddns = ISC_FALSE;
199*00b67f09SDavid van Moolenbroek 	isc_result_t result;
200*00b67f09SDavid van Moolenbroek 
201*00b67f09SDavid van Moolenbroek 	(void)cfg_map_get(zconfig, "update-policy", &updatepolicy);
202*00b67f09SDavid van Moolenbroek 
203*00b67f09SDavid van Moolenbroek 	if (updatepolicy == NULL) {
204*00b67f09SDavid van Moolenbroek 		dns_zone_setssutable(zone, NULL);
205*00b67f09SDavid van Moolenbroek 		return (ISC_R_SUCCESS);
206*00b67f09SDavid van Moolenbroek 	}
207*00b67f09SDavid van Moolenbroek 
208*00b67f09SDavid van Moolenbroek 	if (cfg_obj_isstring(updatepolicy) &&
209*00b67f09SDavid van Moolenbroek 	    strcmp("local", cfg_obj_asstring(updatepolicy)) == 0) {
210*00b67f09SDavid van Moolenbroek 		autoddns = ISC_TRUE;
211*00b67f09SDavid van Moolenbroek 		updatepolicy = NULL;
212*00b67f09SDavid van Moolenbroek 	}
213*00b67f09SDavid van Moolenbroek 
214*00b67f09SDavid van Moolenbroek 	result = dns_ssutable_create(mctx, &table);
215*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS)
216*00b67f09SDavid van Moolenbroek 		return (result);
217*00b67f09SDavid van Moolenbroek 
218*00b67f09SDavid van Moolenbroek 	for (element = cfg_list_first(updatepolicy);
219*00b67f09SDavid van Moolenbroek 	     element != NULL;
220*00b67f09SDavid van Moolenbroek 	     element = cfg_list_next(element))
221*00b67f09SDavid van Moolenbroek 	{
222*00b67f09SDavid van Moolenbroek 		const cfg_obj_t *stmt = cfg_listelt_value(element);
223*00b67f09SDavid van Moolenbroek 		const cfg_obj_t *mode = cfg_tuple_get(stmt, "mode");
224*00b67f09SDavid van Moolenbroek 		const cfg_obj_t *identity = cfg_tuple_get(stmt, "identity");
225*00b67f09SDavid van Moolenbroek 		const cfg_obj_t *matchtype = cfg_tuple_get(stmt, "matchtype");
226*00b67f09SDavid van Moolenbroek 		const cfg_obj_t *dname = cfg_tuple_get(stmt, "name");
227*00b67f09SDavid van Moolenbroek 		const cfg_obj_t *typelist = cfg_tuple_get(stmt, "types");
228*00b67f09SDavid van Moolenbroek 		const char *str;
229*00b67f09SDavid van Moolenbroek 		isc_boolean_t grant = ISC_FALSE;
230*00b67f09SDavid van Moolenbroek 		isc_boolean_t usezone = ISC_FALSE;
231*00b67f09SDavid van Moolenbroek 		unsigned int mtype = DNS_SSUMATCHTYPE_NAME;
232*00b67f09SDavid van Moolenbroek 		dns_fixedname_t fname, fident;
233*00b67f09SDavid van Moolenbroek 		isc_buffer_t b;
234*00b67f09SDavid van Moolenbroek 		dns_rdatatype_t *types;
235*00b67f09SDavid van Moolenbroek 		unsigned int i, n;
236*00b67f09SDavid van Moolenbroek 
237*00b67f09SDavid van Moolenbroek 		str = cfg_obj_asstring(mode);
238*00b67f09SDavid van Moolenbroek 		if (strcasecmp(str, "grant") == 0)
239*00b67f09SDavid van Moolenbroek 			grant = ISC_TRUE;
240*00b67f09SDavid van Moolenbroek 		else if (strcasecmp(str, "deny") == 0)
241*00b67f09SDavid van Moolenbroek 			grant = ISC_FALSE;
242*00b67f09SDavid van Moolenbroek 		else
243*00b67f09SDavid van Moolenbroek 			INSIST(0);
244*00b67f09SDavid van Moolenbroek 
245*00b67f09SDavid van Moolenbroek 		str = cfg_obj_asstring(matchtype);
246*00b67f09SDavid van Moolenbroek 		if (strcasecmp(str, "name") == 0)
247*00b67f09SDavid van Moolenbroek 			mtype = DNS_SSUMATCHTYPE_NAME;
248*00b67f09SDavid van Moolenbroek 		else if (strcasecmp(str, "subdomain") == 0)
249*00b67f09SDavid van Moolenbroek 			mtype = DNS_SSUMATCHTYPE_SUBDOMAIN;
250*00b67f09SDavid van Moolenbroek 		else if (strcasecmp(str, "wildcard") == 0)
251*00b67f09SDavid van Moolenbroek 			mtype = DNS_SSUMATCHTYPE_WILDCARD;
252*00b67f09SDavid van Moolenbroek 		else if (strcasecmp(str, "self") == 0)
253*00b67f09SDavid van Moolenbroek 			mtype = DNS_SSUMATCHTYPE_SELF;
254*00b67f09SDavid van Moolenbroek 		else if (strcasecmp(str, "selfsub") == 0)
255*00b67f09SDavid van Moolenbroek 			mtype = DNS_SSUMATCHTYPE_SELFSUB;
256*00b67f09SDavid van Moolenbroek 		else if (strcasecmp(str, "selfwild") == 0)
257*00b67f09SDavid van Moolenbroek 			mtype = DNS_SSUMATCHTYPE_SELFWILD;
258*00b67f09SDavid van Moolenbroek 		else if (strcasecmp(str, "ms-self") == 0)
259*00b67f09SDavid van Moolenbroek 			mtype = DNS_SSUMATCHTYPE_SELFMS;
260*00b67f09SDavid van Moolenbroek 		else if (strcasecmp(str, "krb5-self") == 0)
261*00b67f09SDavid van Moolenbroek 			mtype = DNS_SSUMATCHTYPE_SELFKRB5;
262*00b67f09SDavid van Moolenbroek 		else if (strcasecmp(str, "ms-subdomain") == 0)
263*00b67f09SDavid van Moolenbroek 			mtype = DNS_SSUMATCHTYPE_SUBDOMAINMS;
264*00b67f09SDavid van Moolenbroek 		else if (strcasecmp(str, "krb5-subdomain") == 0)
265*00b67f09SDavid van Moolenbroek 			mtype = DNS_SSUMATCHTYPE_SUBDOMAINKRB5;
266*00b67f09SDavid van Moolenbroek 		else if (strcasecmp(str, "tcp-self") == 0)
267*00b67f09SDavid van Moolenbroek 			mtype = DNS_SSUMATCHTYPE_TCPSELF;
268*00b67f09SDavid van Moolenbroek 		else if (strcasecmp(str, "6to4-self") == 0)
269*00b67f09SDavid van Moolenbroek 			mtype = DNS_SSUMATCHTYPE_6TO4SELF;
270*00b67f09SDavid van Moolenbroek 		else if (strcasecmp(str, "zonesub") == 0) {
271*00b67f09SDavid van Moolenbroek 			mtype = DNS_SSUMATCHTYPE_SUBDOMAIN;
272*00b67f09SDavid van Moolenbroek 			usezone = ISC_TRUE;
273*00b67f09SDavid van Moolenbroek 		} else if (strcasecmp(str, "external") == 0)
274*00b67f09SDavid van Moolenbroek 			mtype = DNS_SSUMATCHTYPE_EXTERNAL;
275*00b67f09SDavid van Moolenbroek 		else
276*00b67f09SDavid van Moolenbroek 			INSIST(0);
277*00b67f09SDavid van Moolenbroek 
278*00b67f09SDavid van Moolenbroek 		dns_fixedname_init(&fident);
279*00b67f09SDavid van Moolenbroek 		str = cfg_obj_asstring(identity);
280*00b67f09SDavid van Moolenbroek 		isc_buffer_constinit(&b, str, strlen(str));
281*00b67f09SDavid van Moolenbroek 		isc_buffer_add(&b, strlen(str));
282*00b67f09SDavid van Moolenbroek 		result = dns_name_fromtext(dns_fixedname_name(&fident), &b,
283*00b67f09SDavid van Moolenbroek 					   dns_rootname, 0, NULL);
284*00b67f09SDavid van Moolenbroek 		if (result != ISC_R_SUCCESS) {
285*00b67f09SDavid van Moolenbroek 			cfg_obj_log(identity, ns_g_lctx, ISC_LOG_ERROR,
286*00b67f09SDavid van Moolenbroek 				    "'%s' is not a valid name", str);
287*00b67f09SDavid van Moolenbroek 			goto cleanup;
288*00b67f09SDavid van Moolenbroek 		}
289*00b67f09SDavid van Moolenbroek 
290*00b67f09SDavid van Moolenbroek 		dns_fixedname_init(&fname);
291*00b67f09SDavid van Moolenbroek 		if (usezone) {
292*00b67f09SDavid van Moolenbroek 			result = dns_name_copy(dns_zone_getorigin(zone),
293*00b67f09SDavid van Moolenbroek 					       dns_fixedname_name(&fname),
294*00b67f09SDavid van Moolenbroek 					       NULL);
295*00b67f09SDavid van Moolenbroek 			if (result != ISC_R_SUCCESS) {
296*00b67f09SDavid van Moolenbroek 				cfg_obj_log(identity, ns_g_lctx, ISC_LOG_ERROR,
297*00b67f09SDavid van Moolenbroek 					    "error copying origin: %s",
298*00b67f09SDavid van Moolenbroek 					    isc_result_totext(result));
299*00b67f09SDavid van Moolenbroek 				goto cleanup;
300*00b67f09SDavid van Moolenbroek 			}
301*00b67f09SDavid van Moolenbroek 		} else {
302*00b67f09SDavid van Moolenbroek 			str = cfg_obj_asstring(dname);
303*00b67f09SDavid van Moolenbroek 			isc_buffer_constinit(&b, str, strlen(str));
304*00b67f09SDavid van Moolenbroek 			isc_buffer_add(&b, strlen(str));
305*00b67f09SDavid van Moolenbroek 			result = dns_name_fromtext(dns_fixedname_name(&fname),
306*00b67f09SDavid van Moolenbroek 						   &b, dns_rootname, 0, NULL);
307*00b67f09SDavid van Moolenbroek 			if (result != ISC_R_SUCCESS) {
308*00b67f09SDavid van Moolenbroek 				cfg_obj_log(identity, ns_g_lctx, ISC_LOG_ERROR,
309*00b67f09SDavid van Moolenbroek 					    "'%s' is not a valid name", str);
310*00b67f09SDavid van Moolenbroek 				goto cleanup;
311*00b67f09SDavid van Moolenbroek 			}
312*00b67f09SDavid van Moolenbroek 		}
313*00b67f09SDavid van Moolenbroek 
314*00b67f09SDavid van Moolenbroek 		n = ns_config_listcount(typelist);
315*00b67f09SDavid van Moolenbroek 		if (n == 0)
316*00b67f09SDavid van Moolenbroek 			types = NULL;
317*00b67f09SDavid van Moolenbroek 		else {
318*00b67f09SDavid van Moolenbroek 			types = isc_mem_get(mctx, n * sizeof(dns_rdatatype_t));
319*00b67f09SDavid van Moolenbroek 			if (types == NULL) {
320*00b67f09SDavid van Moolenbroek 				result = ISC_R_NOMEMORY;
321*00b67f09SDavid van Moolenbroek 				goto cleanup;
322*00b67f09SDavid van Moolenbroek 			}
323*00b67f09SDavid van Moolenbroek 		}
324*00b67f09SDavid van Moolenbroek 
325*00b67f09SDavid van Moolenbroek 		i = 0;
326*00b67f09SDavid van Moolenbroek 		for (element2 = cfg_list_first(typelist);
327*00b67f09SDavid van Moolenbroek 		     element2 != NULL;
328*00b67f09SDavid van Moolenbroek 		     element2 = cfg_list_next(element2))
329*00b67f09SDavid van Moolenbroek 		{
330*00b67f09SDavid van Moolenbroek 			const cfg_obj_t *typeobj;
331*00b67f09SDavid van Moolenbroek 			isc_textregion_t r;
332*00b67f09SDavid van Moolenbroek 
333*00b67f09SDavid van Moolenbroek 			INSIST(i < n);
334*00b67f09SDavid van Moolenbroek 
335*00b67f09SDavid van Moolenbroek 			typeobj = cfg_listelt_value(element2);
336*00b67f09SDavid van Moolenbroek 			str = cfg_obj_asstring(typeobj);
337*00b67f09SDavid van Moolenbroek 			DE_CONST(str, r.base);
338*00b67f09SDavid van Moolenbroek 			r.length = strlen(str);
339*00b67f09SDavid van Moolenbroek 
340*00b67f09SDavid van Moolenbroek 			result = dns_rdatatype_fromtext(&types[i++], &r);
341*00b67f09SDavid van Moolenbroek 			if (result != ISC_R_SUCCESS) {
342*00b67f09SDavid van Moolenbroek 				cfg_obj_log(identity, ns_g_lctx, ISC_LOG_ERROR,
343*00b67f09SDavid van Moolenbroek 					    "'%s' is not a valid type", str);
344*00b67f09SDavid van Moolenbroek 				isc_mem_put(mctx, types,
345*00b67f09SDavid van Moolenbroek 					    n * sizeof(dns_rdatatype_t));
346*00b67f09SDavid van Moolenbroek 				goto cleanup;
347*00b67f09SDavid van Moolenbroek 			}
348*00b67f09SDavid van Moolenbroek 		}
349*00b67f09SDavid van Moolenbroek 		INSIST(i == n);
350*00b67f09SDavid van Moolenbroek 
351*00b67f09SDavid van Moolenbroek 		result = dns_ssutable_addrule(table, grant,
352*00b67f09SDavid van Moolenbroek 					      dns_fixedname_name(&fident),
353*00b67f09SDavid van Moolenbroek 					      mtype,
354*00b67f09SDavid van Moolenbroek 					      dns_fixedname_name(&fname),
355*00b67f09SDavid van Moolenbroek 					      n, types);
356*00b67f09SDavid van Moolenbroek 		if (types != NULL)
357*00b67f09SDavid van Moolenbroek 			isc_mem_put(mctx, types, n * sizeof(dns_rdatatype_t));
358*00b67f09SDavid van Moolenbroek 		if (result != ISC_R_SUCCESS) {
359*00b67f09SDavid van Moolenbroek 			goto cleanup;
360*00b67f09SDavid van Moolenbroek 		}
361*00b67f09SDavid van Moolenbroek 	}
362*00b67f09SDavid van Moolenbroek 
363*00b67f09SDavid van Moolenbroek 	/*
364*00b67f09SDavid van Moolenbroek 	 * If "update-policy local;" and a session key exists,
365*00b67f09SDavid van Moolenbroek 	 * then use the default policy, which is equivalent to:
366*00b67f09SDavid van Moolenbroek 	 * update-policy { grant <session-keyname> zonesub any; };
367*00b67f09SDavid van Moolenbroek 	 */
368*00b67f09SDavid van Moolenbroek 	if (autoddns) {
369*00b67f09SDavid van Moolenbroek 		dns_rdatatype_t any = dns_rdatatype_any;
370*00b67f09SDavid van Moolenbroek 
371*00b67f09SDavid van Moolenbroek 		if (ns_g_server->session_keyname == NULL) {
372*00b67f09SDavid van Moolenbroek 			isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
373*00b67f09SDavid van Moolenbroek 				      NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
374*00b67f09SDavid van Moolenbroek 				      "failed to enable auto DDNS policy "
375*00b67f09SDavid van Moolenbroek 				      "for zone %s: session key not found",
376*00b67f09SDavid van Moolenbroek 				      zname);
377*00b67f09SDavid van Moolenbroek 			result = ISC_R_NOTFOUND;
378*00b67f09SDavid van Moolenbroek 			goto cleanup;
379*00b67f09SDavid van Moolenbroek 		}
380*00b67f09SDavid van Moolenbroek 
381*00b67f09SDavid van Moolenbroek 		result = dns_ssutable_addrule(table, ISC_TRUE,
382*00b67f09SDavid van Moolenbroek 					      ns_g_server->session_keyname,
383*00b67f09SDavid van Moolenbroek 					      DNS_SSUMATCHTYPE_SUBDOMAIN,
384*00b67f09SDavid van Moolenbroek 					      dns_zone_getorigin(zone),
385*00b67f09SDavid van Moolenbroek 					      1, &any);
386*00b67f09SDavid van Moolenbroek 
387*00b67f09SDavid van Moolenbroek 		if (result != ISC_R_SUCCESS)
388*00b67f09SDavid van Moolenbroek 			goto cleanup;
389*00b67f09SDavid van Moolenbroek 	}
390*00b67f09SDavid van Moolenbroek 
391*00b67f09SDavid van Moolenbroek 	result = ISC_R_SUCCESS;
392*00b67f09SDavid van Moolenbroek 	dns_zone_setssutable(zone, table);
393*00b67f09SDavid van Moolenbroek 
394*00b67f09SDavid van Moolenbroek  cleanup:
395*00b67f09SDavid van Moolenbroek 	dns_ssutable_detach(&table);
396*00b67f09SDavid van Moolenbroek 	return (result);
397*00b67f09SDavid van Moolenbroek }
398*00b67f09SDavid van Moolenbroek 
399*00b67f09SDavid van Moolenbroek /*
400*00b67f09SDavid van Moolenbroek  * This is the TTL used for internally generated RRsets for static-stub zones.
401*00b67f09SDavid van Moolenbroek  * The value doesn't matter because the mapping is static, but needs to be
402*00b67f09SDavid van Moolenbroek  * defined for the sake of implementation.
403*00b67f09SDavid van Moolenbroek  */
404*00b67f09SDavid van Moolenbroek #define STATICSTUB_SERVER_TTL 86400
405*00b67f09SDavid van Moolenbroek 
406*00b67f09SDavid van Moolenbroek /*%
407*00b67f09SDavid van Moolenbroek  * Configure an apex NS with glues for a static-stub zone.
408*00b67f09SDavid van Moolenbroek  * For example, for the zone named "example.com", the following RRs will be
409*00b67f09SDavid van Moolenbroek  * added to the zone DB:
410*00b67f09SDavid van Moolenbroek  * example.com. NS example.com.
411*00b67f09SDavid van Moolenbroek  * example.com. A 192.0.2.1
412*00b67f09SDavid van Moolenbroek  * example.com. AAAA 2001:db8::1
413*00b67f09SDavid van Moolenbroek  */
414*00b67f09SDavid van Moolenbroek static isc_result_t
configure_staticstub_serveraddrs(const cfg_obj_t * zconfig,dns_zone_t * zone,dns_rdatalist_t * rdatalist_ns,dns_rdatalist_t * rdatalist_a,dns_rdatalist_t * rdatalist_aaaa)415*00b67f09SDavid van Moolenbroek configure_staticstub_serveraddrs(const cfg_obj_t *zconfig, dns_zone_t *zone,
416*00b67f09SDavid van Moolenbroek 				 dns_rdatalist_t *rdatalist_ns,
417*00b67f09SDavid van Moolenbroek 				 dns_rdatalist_t *rdatalist_a,
418*00b67f09SDavid van Moolenbroek 				 dns_rdatalist_t *rdatalist_aaaa)
419*00b67f09SDavid van Moolenbroek {
420*00b67f09SDavid van Moolenbroek 	const cfg_listelt_t *element;
421*00b67f09SDavid van Moolenbroek 	isc_mem_t *mctx = dns_zone_getmctx(zone);
422*00b67f09SDavid van Moolenbroek 	isc_region_t region, sregion;
423*00b67f09SDavid van Moolenbroek 	dns_rdata_t *rdata;
424*00b67f09SDavid van Moolenbroek 	isc_result_t result = ISC_R_SUCCESS;
425*00b67f09SDavid van Moolenbroek 
426*00b67f09SDavid van Moolenbroek 	for (element = cfg_list_first(zconfig);
427*00b67f09SDavid van Moolenbroek 	     element != NULL;
428*00b67f09SDavid van Moolenbroek 	     element = cfg_list_next(element))
429*00b67f09SDavid van Moolenbroek 	{
430*00b67f09SDavid van Moolenbroek 		const isc_sockaddr_t* sa;
431*00b67f09SDavid van Moolenbroek 		isc_netaddr_t na;
432*00b67f09SDavid van Moolenbroek 		const cfg_obj_t *address = cfg_listelt_value(element);
433*00b67f09SDavid van Moolenbroek 		dns_rdatalist_t *rdatalist;
434*00b67f09SDavid van Moolenbroek 
435*00b67f09SDavid van Moolenbroek 		sa = cfg_obj_assockaddr(address);
436*00b67f09SDavid van Moolenbroek 		if (isc_sockaddr_getport(sa) != 0) {
437*00b67f09SDavid van Moolenbroek 			cfg_obj_log(zconfig, ns_g_lctx, ISC_LOG_ERROR,
438*00b67f09SDavid van Moolenbroek 				    "port is not configurable for "
439*00b67f09SDavid van Moolenbroek 				    "static stub server-addresses");
440*00b67f09SDavid van Moolenbroek 			return (ISC_R_FAILURE);
441*00b67f09SDavid van Moolenbroek 		}
442*00b67f09SDavid van Moolenbroek 		isc_netaddr_fromsockaddr(&na, sa);
443*00b67f09SDavid van Moolenbroek 		if (isc_netaddr_getzone(&na) != 0) {
444*00b67f09SDavid van Moolenbroek 			cfg_obj_log(zconfig, ns_g_lctx, ISC_LOG_ERROR,
445*00b67f09SDavid van Moolenbroek 					    "scoped address is not allowed "
446*00b67f09SDavid van Moolenbroek 					    "for static stub "
447*00b67f09SDavid van Moolenbroek 					    "server-addresses");
448*00b67f09SDavid van Moolenbroek 			return (ISC_R_FAILURE);
449*00b67f09SDavid van Moolenbroek 		}
450*00b67f09SDavid van Moolenbroek 
451*00b67f09SDavid van Moolenbroek 		switch (na.family) {
452*00b67f09SDavid van Moolenbroek 		case AF_INET:
453*00b67f09SDavid van Moolenbroek 			region.length = sizeof(na.type.in);
454*00b67f09SDavid van Moolenbroek 			rdatalist = rdatalist_a;
455*00b67f09SDavid van Moolenbroek 			break;
456*00b67f09SDavid van Moolenbroek 		default:
457*00b67f09SDavid van Moolenbroek 			INSIST(na.family == AF_INET6);
458*00b67f09SDavid van Moolenbroek 			region.length = sizeof(na.type.in6);
459*00b67f09SDavid van Moolenbroek 			rdatalist = rdatalist_aaaa;
460*00b67f09SDavid van Moolenbroek 			break;
461*00b67f09SDavid van Moolenbroek 		}
462*00b67f09SDavid van Moolenbroek 
463*00b67f09SDavid van Moolenbroek 		rdata = isc_mem_get(mctx, sizeof(*rdata) + region.length);
464*00b67f09SDavid van Moolenbroek 		if (rdata == NULL)
465*00b67f09SDavid van Moolenbroek 			return (ISC_R_NOMEMORY);
466*00b67f09SDavid van Moolenbroek 		region.base = (unsigned char *)(rdata + 1);
467*00b67f09SDavid van Moolenbroek 		memmove(region.base, &na.type, region.length);
468*00b67f09SDavid van Moolenbroek 		dns_rdata_init(rdata);
469*00b67f09SDavid van Moolenbroek 		dns_rdata_fromregion(rdata, dns_zone_getclass(zone),
470*00b67f09SDavid van Moolenbroek 				     rdatalist->type, &region);
471*00b67f09SDavid van Moolenbroek 		ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
472*00b67f09SDavid van Moolenbroek 	}
473*00b67f09SDavid van Moolenbroek 
474*00b67f09SDavid van Moolenbroek 	/*
475*00b67f09SDavid van Moolenbroek 	 * If no address is specified (unlikely in this context, but possible),
476*00b67f09SDavid van Moolenbroek 	 * there's nothing to do anymore.
477*00b67f09SDavid van Moolenbroek 	 */
478*00b67f09SDavid van Moolenbroek 	if (ISC_LIST_EMPTY(rdatalist_a->rdata) &&
479*00b67f09SDavid van Moolenbroek 	    ISC_LIST_EMPTY(rdatalist_aaaa->rdata)) {
480*00b67f09SDavid van Moolenbroek 		return (ISC_R_SUCCESS);
481*00b67f09SDavid van Moolenbroek 	}
482*00b67f09SDavid van Moolenbroek 
483*00b67f09SDavid van Moolenbroek 	/* Add to the list an apex NS with the ns name being the origin name */
484*00b67f09SDavid van Moolenbroek 	dns_name_toregion(dns_zone_getorigin(zone), &sregion);
485*00b67f09SDavid van Moolenbroek 	rdata = isc_mem_get(mctx, sizeof(*rdata) + sregion.length);
486*00b67f09SDavid van Moolenbroek 	if (rdata == NULL) {
487*00b67f09SDavid van Moolenbroek 		/*
488*00b67f09SDavid van Moolenbroek 		 * Already allocated data will be freed in the caller, so
489*00b67f09SDavid van Moolenbroek 		 * we can simply return here.
490*00b67f09SDavid van Moolenbroek 		 */
491*00b67f09SDavid van Moolenbroek 		return (ISC_R_NOMEMORY);
492*00b67f09SDavid van Moolenbroek 	}
493*00b67f09SDavid van Moolenbroek 	region.length = sregion.length;
494*00b67f09SDavid van Moolenbroek 	region.base = (unsigned char *)(rdata + 1);
495*00b67f09SDavid van Moolenbroek 	memmove(region.base, sregion.base, region.length);
496*00b67f09SDavid van Moolenbroek 	dns_rdata_init(rdata);
497*00b67f09SDavid van Moolenbroek 	dns_rdata_fromregion(rdata, dns_zone_getclass(zone),
498*00b67f09SDavid van Moolenbroek 			     dns_rdatatype_ns, &region);
499*00b67f09SDavid van Moolenbroek 	ISC_LIST_APPEND(rdatalist_ns->rdata, rdata, link);
500*00b67f09SDavid van Moolenbroek 
501*00b67f09SDavid van Moolenbroek 	return (result);
502*00b67f09SDavid van Moolenbroek }
503*00b67f09SDavid van Moolenbroek 
504*00b67f09SDavid van Moolenbroek /*%
505*00b67f09SDavid van Moolenbroek  * Configure an apex NS with an out-of-zone NS names for a static-stub zone.
506*00b67f09SDavid van Moolenbroek  * For example, for the zone named "example.com", something like the following
507*00b67f09SDavid van Moolenbroek  * RRs will be added to the zone DB:
508*00b67f09SDavid van Moolenbroek  * example.com. NS ns.example.net.
509*00b67f09SDavid van Moolenbroek  */
510*00b67f09SDavid van Moolenbroek static isc_result_t
configure_staticstub_servernames(const cfg_obj_t * zconfig,dns_zone_t * zone,dns_rdatalist_t * rdatalist,const char * zname)511*00b67f09SDavid van Moolenbroek configure_staticstub_servernames(const cfg_obj_t *zconfig, dns_zone_t *zone,
512*00b67f09SDavid van Moolenbroek 				 dns_rdatalist_t *rdatalist, const char *zname)
513*00b67f09SDavid van Moolenbroek {
514*00b67f09SDavid van Moolenbroek 	const cfg_listelt_t *element;
515*00b67f09SDavid van Moolenbroek 	isc_mem_t *mctx = dns_zone_getmctx(zone);
516*00b67f09SDavid van Moolenbroek 	dns_rdata_t *rdata;
517*00b67f09SDavid van Moolenbroek 	isc_region_t sregion, region;
518*00b67f09SDavid van Moolenbroek 	isc_result_t result = ISC_R_SUCCESS;
519*00b67f09SDavid van Moolenbroek 
520*00b67f09SDavid van Moolenbroek 	for (element = cfg_list_first(zconfig);
521*00b67f09SDavid van Moolenbroek 	     element != NULL;
522*00b67f09SDavid van Moolenbroek 	     element = cfg_list_next(element))
523*00b67f09SDavid van Moolenbroek 	{
524*00b67f09SDavid van Moolenbroek 		const cfg_obj_t *obj;
525*00b67f09SDavid van Moolenbroek 		const char *str;
526*00b67f09SDavid van Moolenbroek 		dns_fixedname_t fixed_name;
527*00b67f09SDavid van Moolenbroek 		dns_name_t *nsname;
528*00b67f09SDavid van Moolenbroek 		isc_buffer_t b;
529*00b67f09SDavid van Moolenbroek 
530*00b67f09SDavid van Moolenbroek 		obj = cfg_listelt_value(element);
531*00b67f09SDavid van Moolenbroek 		str = cfg_obj_asstring(obj);
532*00b67f09SDavid van Moolenbroek 
533*00b67f09SDavid van Moolenbroek 		dns_fixedname_init(&fixed_name);
534*00b67f09SDavid van Moolenbroek 		nsname = dns_fixedname_name(&fixed_name);
535*00b67f09SDavid van Moolenbroek 
536*00b67f09SDavid van Moolenbroek 		isc_buffer_constinit(&b, str, strlen(str));
537*00b67f09SDavid van Moolenbroek 		isc_buffer_add(&b, strlen(str));
538*00b67f09SDavid van Moolenbroek 		result = dns_name_fromtext(nsname, &b, dns_rootname, 0, NULL);
539*00b67f09SDavid van Moolenbroek 		if (result != ISC_R_SUCCESS) {
540*00b67f09SDavid van Moolenbroek 			cfg_obj_log(zconfig, ns_g_lctx, ISC_LOG_ERROR,
541*00b67f09SDavid van Moolenbroek 					    "server-name '%s' is not a valid "
542*00b67f09SDavid van Moolenbroek 					    "name", str);
543*00b67f09SDavid van Moolenbroek 			return (result);
544*00b67f09SDavid van Moolenbroek 		}
545*00b67f09SDavid van Moolenbroek 		if (dns_name_issubdomain(nsname, dns_zone_getorigin(zone))) {
546*00b67f09SDavid van Moolenbroek 			cfg_obj_log(zconfig, ns_g_lctx, ISC_LOG_ERROR,
547*00b67f09SDavid van Moolenbroek 				    "server-name '%s' must not be a "
548*00b67f09SDavid van Moolenbroek 				    "subdomain of zone name '%s'",
549*00b67f09SDavid van Moolenbroek 				    str, zname);
550*00b67f09SDavid van Moolenbroek 			return (ISC_R_FAILURE);
551*00b67f09SDavid van Moolenbroek 		}
552*00b67f09SDavid van Moolenbroek 
553*00b67f09SDavid van Moolenbroek 		dns_name_toregion(nsname, &sregion);
554*00b67f09SDavid van Moolenbroek 		rdata = isc_mem_get(mctx, sizeof(*rdata) + sregion.length);
555*00b67f09SDavid van Moolenbroek 		if (rdata == NULL)
556*00b67f09SDavid van Moolenbroek 			return (ISC_R_NOMEMORY);
557*00b67f09SDavid van Moolenbroek 		region.length = sregion.length;
558*00b67f09SDavid van Moolenbroek 		region.base = (unsigned char *)(rdata + 1);
559*00b67f09SDavid van Moolenbroek 		memmove(region.base, sregion.base, region.length);
560*00b67f09SDavid van Moolenbroek 		dns_rdata_init(rdata);
561*00b67f09SDavid van Moolenbroek 		dns_rdata_fromregion(rdata, dns_zone_getclass(zone),
562*00b67f09SDavid van Moolenbroek 				     dns_rdatatype_ns, &region);
563*00b67f09SDavid van Moolenbroek 		ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
564*00b67f09SDavid van Moolenbroek 	}
565*00b67f09SDavid van Moolenbroek 
566*00b67f09SDavid van Moolenbroek 	return (result);
567*00b67f09SDavid van Moolenbroek }
568*00b67f09SDavid van Moolenbroek 
569*00b67f09SDavid van Moolenbroek /*%
570*00b67f09SDavid van Moolenbroek  * Configure static-stub zone.
571*00b67f09SDavid van Moolenbroek  */
572*00b67f09SDavid van Moolenbroek static isc_result_t
configure_staticstub(const cfg_obj_t * zconfig,dns_zone_t * zone,const char * zname,const char * dbtype)573*00b67f09SDavid van Moolenbroek configure_staticstub(const cfg_obj_t *zconfig, dns_zone_t *zone,
574*00b67f09SDavid van Moolenbroek 		     const char *zname, const char *dbtype)
575*00b67f09SDavid van Moolenbroek {
576*00b67f09SDavid van Moolenbroek 	int i = 0;
577*00b67f09SDavid van Moolenbroek 	const cfg_obj_t *obj;
578*00b67f09SDavid van Moolenbroek 	isc_mem_t *mctx = dns_zone_getmctx(zone);
579*00b67f09SDavid van Moolenbroek 	dns_db_t *db = NULL;
580*00b67f09SDavid van Moolenbroek 	dns_dbversion_t *dbversion = NULL;
581*00b67f09SDavid van Moolenbroek 	dns_dbnode_t *apexnode = NULL;
582*00b67f09SDavid van Moolenbroek 	dns_name_t apexname;
583*00b67f09SDavid van Moolenbroek 	isc_result_t result;
584*00b67f09SDavid van Moolenbroek 	dns_rdataset_t rdataset;
585*00b67f09SDavid van Moolenbroek 	dns_rdatalist_t rdatalist_ns, rdatalist_a, rdatalist_aaaa;
586*00b67f09SDavid van Moolenbroek 	dns_rdatalist_t* rdatalists[] = {
587*00b67f09SDavid van Moolenbroek 		&rdatalist_ns, &rdatalist_a, &rdatalist_aaaa, NULL
588*00b67f09SDavid van Moolenbroek 	};
589*00b67f09SDavid van Moolenbroek 	dns_rdata_t *rdata;
590*00b67f09SDavid van Moolenbroek 	isc_region_t region;
591*00b67f09SDavid van Moolenbroek 
592*00b67f09SDavid van Moolenbroek 	/* Create the DB beforehand */
593*00b67f09SDavid van Moolenbroek 	RETERR(dns_db_create(mctx, dbtype, dns_zone_getorigin(zone),
594*00b67f09SDavid van Moolenbroek 			     dns_dbtype_stub, dns_zone_getclass(zone),
595*00b67f09SDavid van Moolenbroek 			     0, NULL, &db));
596*00b67f09SDavid van Moolenbroek 	dns_zone_setdb(zone, db);
597*00b67f09SDavid van Moolenbroek 
598*00b67f09SDavid van Moolenbroek 	dns_rdatalist_init(&rdatalist_ns);
599*00b67f09SDavid van Moolenbroek 	rdatalist_ns.rdclass = dns_zone_getclass(zone);
600*00b67f09SDavid van Moolenbroek 	rdatalist_ns.type = dns_rdatatype_ns;
601*00b67f09SDavid van Moolenbroek 	rdatalist_ns.ttl = STATICSTUB_SERVER_TTL;
602*00b67f09SDavid van Moolenbroek 
603*00b67f09SDavid van Moolenbroek 	dns_rdatalist_init(&rdatalist_a);
604*00b67f09SDavid van Moolenbroek 	rdatalist_a.rdclass = dns_zone_getclass(zone);
605*00b67f09SDavid van Moolenbroek 	rdatalist_a.type = dns_rdatatype_a;
606*00b67f09SDavid van Moolenbroek 	rdatalist_a.ttl = STATICSTUB_SERVER_TTL;
607*00b67f09SDavid van Moolenbroek 
608*00b67f09SDavid van Moolenbroek 	dns_rdatalist_init(&rdatalist_aaaa);
609*00b67f09SDavid van Moolenbroek 	rdatalist_aaaa.rdclass = dns_zone_getclass(zone);
610*00b67f09SDavid van Moolenbroek 	rdatalist_aaaa.type = dns_rdatatype_aaaa;
611*00b67f09SDavid van Moolenbroek 	rdatalist_aaaa.ttl = STATICSTUB_SERVER_TTL;
612*00b67f09SDavid van Moolenbroek 
613*00b67f09SDavid van Moolenbroek 	/* Prepare zone RRs from the configuration */
614*00b67f09SDavid van Moolenbroek 	obj = NULL;
615*00b67f09SDavid van Moolenbroek 	result = cfg_map_get(zconfig, "server-addresses", &obj);
616*00b67f09SDavid van Moolenbroek 	if (result == ISC_R_SUCCESS) {
617*00b67f09SDavid van Moolenbroek 		INSIST(obj != NULL);
618*00b67f09SDavid van Moolenbroek 		result = configure_staticstub_serveraddrs(obj, zone,
619*00b67f09SDavid van Moolenbroek 							  &rdatalist_ns,
620*00b67f09SDavid van Moolenbroek 							  &rdatalist_a,
621*00b67f09SDavid van Moolenbroek 							  &rdatalist_aaaa);
622*00b67f09SDavid van Moolenbroek 		if (result != ISC_R_SUCCESS)
623*00b67f09SDavid van Moolenbroek 			goto cleanup;
624*00b67f09SDavid van Moolenbroek 	}
625*00b67f09SDavid van Moolenbroek 
626*00b67f09SDavid van Moolenbroek 	obj = NULL;
627*00b67f09SDavid van Moolenbroek 	result = cfg_map_get(zconfig, "server-names", &obj);
628*00b67f09SDavid van Moolenbroek 	if (result == ISC_R_SUCCESS) {
629*00b67f09SDavid van Moolenbroek 		INSIST(obj != NULL);
630*00b67f09SDavid van Moolenbroek 		result = configure_staticstub_servernames(obj, zone,
631*00b67f09SDavid van Moolenbroek 							  &rdatalist_ns,
632*00b67f09SDavid van Moolenbroek 							  zname);
633*00b67f09SDavid van Moolenbroek 		if (result != ISC_R_SUCCESS)
634*00b67f09SDavid van Moolenbroek 			goto cleanup;
635*00b67f09SDavid van Moolenbroek 	}
636*00b67f09SDavid van Moolenbroek 
637*00b67f09SDavid van Moolenbroek 	/*
638*00b67f09SDavid van Moolenbroek 	 * Sanity check: there should be at least one NS RR at the zone apex
639*00b67f09SDavid van Moolenbroek 	 * to trigger delegation.
640*00b67f09SDavid van Moolenbroek 	 */
641*00b67f09SDavid van Moolenbroek 	if (ISC_LIST_EMPTY(rdatalist_ns.rdata)) {
642*00b67f09SDavid van Moolenbroek 		isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
643*00b67f09SDavid van Moolenbroek 			      NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
644*00b67f09SDavid van Moolenbroek 			      "No NS record is configured for a "
645*00b67f09SDavid van Moolenbroek 			      "static-stub zone '%s'", zname);
646*00b67f09SDavid van Moolenbroek 		result = ISC_R_FAILURE;
647*00b67f09SDavid van Moolenbroek 		goto cleanup;
648*00b67f09SDavid van Moolenbroek 	}
649*00b67f09SDavid van Moolenbroek 
650*00b67f09SDavid van Moolenbroek 	/*
651*00b67f09SDavid van Moolenbroek 	 * Now add NS and glue A/AAAA RRsets to the zone DB.
652*00b67f09SDavid van Moolenbroek 	 * First open a new version for the add operation and get a pointer
653*00b67f09SDavid van Moolenbroek 	 * to the apex node (all RRs are of the apex name).
654*00b67f09SDavid van Moolenbroek 	 */
655*00b67f09SDavid van Moolenbroek 	result = dns_db_newversion(db, &dbversion);
656*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS)
657*00b67f09SDavid van Moolenbroek 		goto cleanup;
658*00b67f09SDavid van Moolenbroek 	dns_name_init(&apexname, NULL);
659*00b67f09SDavid van Moolenbroek 	dns_name_clone(dns_zone_getorigin(zone), &apexname);
660*00b67f09SDavid van Moolenbroek 	result = dns_db_findnode(db, &apexname, ISC_FALSE, &apexnode);
661*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS)
662*00b67f09SDavid van Moolenbroek 		goto cleanup;
663*00b67f09SDavid van Moolenbroek 
664*00b67f09SDavid van Moolenbroek 	/* Add NS RRset */
665*00b67f09SDavid van Moolenbroek 	dns_rdataset_init(&rdataset);
666*00b67f09SDavid van Moolenbroek 	RUNTIME_CHECK(dns_rdatalist_tordataset(&rdatalist_ns, &rdataset)
667*00b67f09SDavid van Moolenbroek 		      == ISC_R_SUCCESS);
668*00b67f09SDavid van Moolenbroek 	result = dns_db_addrdataset(db, apexnode, dbversion, 0, &rdataset,
669*00b67f09SDavid van Moolenbroek 				    0, NULL);
670*00b67f09SDavid van Moolenbroek 	dns_rdataset_disassociate(&rdataset);
671*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS)
672*00b67f09SDavid van Moolenbroek 		goto cleanup;
673*00b67f09SDavid van Moolenbroek 
674*00b67f09SDavid van Moolenbroek 	/* Add glue A RRset, if any */
675*00b67f09SDavid van Moolenbroek 	if (!ISC_LIST_EMPTY(rdatalist_a.rdata)) {
676*00b67f09SDavid van Moolenbroek 		RUNTIME_CHECK(dns_rdatalist_tordataset(&rdatalist_a, &rdataset)
677*00b67f09SDavid van Moolenbroek 			      == ISC_R_SUCCESS);
678*00b67f09SDavid van Moolenbroek 		result = dns_db_addrdataset(db, apexnode, dbversion, 0,
679*00b67f09SDavid van Moolenbroek 					    &rdataset, 0, NULL);
680*00b67f09SDavid van Moolenbroek 		dns_rdataset_disassociate(&rdataset);
681*00b67f09SDavid van Moolenbroek 		if (result != ISC_R_SUCCESS)
682*00b67f09SDavid van Moolenbroek 			goto cleanup;
683*00b67f09SDavid van Moolenbroek 	}
684*00b67f09SDavid van Moolenbroek 
685*00b67f09SDavid van Moolenbroek 	/* Add glue AAAA RRset, if any */
686*00b67f09SDavid van Moolenbroek 	if (!ISC_LIST_EMPTY(rdatalist_aaaa.rdata)) {
687*00b67f09SDavid van Moolenbroek 		RUNTIME_CHECK(dns_rdatalist_tordataset(&rdatalist_aaaa,
688*00b67f09SDavid van Moolenbroek 						       &rdataset)
689*00b67f09SDavid van Moolenbroek 			      == ISC_R_SUCCESS);
690*00b67f09SDavid van Moolenbroek 		result = dns_db_addrdataset(db, apexnode, dbversion, 0,
691*00b67f09SDavid van Moolenbroek 					    &rdataset, 0, NULL);
692*00b67f09SDavid van Moolenbroek 		dns_rdataset_disassociate(&rdataset);
693*00b67f09SDavid van Moolenbroek 		if (result != ISC_R_SUCCESS)
694*00b67f09SDavid van Moolenbroek 			goto cleanup;
695*00b67f09SDavid van Moolenbroek 	}
696*00b67f09SDavid van Moolenbroek 
697*00b67f09SDavid van Moolenbroek 	result = ISC_R_SUCCESS;
698*00b67f09SDavid van Moolenbroek 
699*00b67f09SDavid van Moolenbroek   cleanup:
700*00b67f09SDavid van Moolenbroek 	if (apexnode != NULL)
701*00b67f09SDavid van Moolenbroek 		dns_db_detachnode(db, &apexnode);
702*00b67f09SDavid van Moolenbroek 	if (dbversion != NULL)
703*00b67f09SDavid van Moolenbroek 		dns_db_closeversion(db, &dbversion, ISC_TRUE);
704*00b67f09SDavid van Moolenbroek 	if (db != NULL)
705*00b67f09SDavid van Moolenbroek 		dns_db_detach(&db);
706*00b67f09SDavid van Moolenbroek 	for (i = 0; rdatalists[i] != NULL; i++) {
707*00b67f09SDavid van Moolenbroek 		while ((rdata = ISC_LIST_HEAD(rdatalists[i]->rdata)) != NULL) {
708*00b67f09SDavid van Moolenbroek 			ISC_LIST_UNLINK(rdatalists[i]->rdata, rdata, link);
709*00b67f09SDavid van Moolenbroek 			dns_rdata_toregion(rdata, &region);
710*00b67f09SDavid van Moolenbroek 			isc_mem_put(mctx, rdata,
711*00b67f09SDavid van Moolenbroek 				    sizeof(*rdata) + region.length);
712*00b67f09SDavid van Moolenbroek 		}
713*00b67f09SDavid van Moolenbroek 	}
714*00b67f09SDavid van Moolenbroek 
715*00b67f09SDavid van Moolenbroek 	INSIST(dbversion == NULL);
716*00b67f09SDavid van Moolenbroek 
717*00b67f09SDavid van Moolenbroek 	return (result);
718*00b67f09SDavid van Moolenbroek }
719*00b67f09SDavid van Moolenbroek 
720*00b67f09SDavid van Moolenbroek /*%
721*00b67f09SDavid van Moolenbroek  * Convert a config file zone type into a server zone type.
722*00b67f09SDavid van Moolenbroek  */
723*00b67f09SDavid van Moolenbroek static inline dns_zonetype_t
zonetype_fromconfig(const cfg_obj_t * map)724*00b67f09SDavid van Moolenbroek zonetype_fromconfig(const cfg_obj_t *map) {
725*00b67f09SDavid van Moolenbroek 	const cfg_obj_t *obj = NULL;
726*00b67f09SDavid van Moolenbroek 	isc_result_t result;
727*00b67f09SDavid van Moolenbroek 
728*00b67f09SDavid van Moolenbroek 	result = cfg_map_get(map, "type", &obj);
729*00b67f09SDavid van Moolenbroek 	INSIST(result == ISC_R_SUCCESS && obj != NULL);
730*00b67f09SDavid van Moolenbroek 	return (ns_config_getzonetype(obj));
731*00b67f09SDavid van Moolenbroek }
732*00b67f09SDavid van Moolenbroek 
733*00b67f09SDavid van Moolenbroek /*%
734*00b67f09SDavid van Moolenbroek  * Helper function for strtoargv().  Pardon the gratuitous recursion.
735*00b67f09SDavid van Moolenbroek  */
736*00b67f09SDavid van Moolenbroek static isc_result_t
strtoargvsub(isc_mem_t * mctx,char * s,unsigned int * argcp,char *** argvp,unsigned int n)737*00b67f09SDavid van Moolenbroek strtoargvsub(isc_mem_t *mctx, char *s, unsigned int *argcp,
738*00b67f09SDavid van Moolenbroek 	     char ***argvp, unsigned int n)
739*00b67f09SDavid van Moolenbroek {
740*00b67f09SDavid van Moolenbroek 	isc_result_t result;
741*00b67f09SDavid van Moolenbroek 
742*00b67f09SDavid van Moolenbroek 	/* Discard leading whitespace. */
743*00b67f09SDavid van Moolenbroek 	while (*s == ' ' || *s == '\t')
744*00b67f09SDavid van Moolenbroek 		s++;
745*00b67f09SDavid van Moolenbroek 
746*00b67f09SDavid van Moolenbroek 	if (*s == '\0') {
747*00b67f09SDavid van Moolenbroek 		/* We have reached the end of the string. */
748*00b67f09SDavid van Moolenbroek 		*argcp = n;
749*00b67f09SDavid van Moolenbroek 		*argvp = isc_mem_get(mctx, n * sizeof(char *));
750*00b67f09SDavid van Moolenbroek 		if (*argvp == NULL)
751*00b67f09SDavid van Moolenbroek 			return (ISC_R_NOMEMORY);
752*00b67f09SDavid van Moolenbroek 	} else {
753*00b67f09SDavid van Moolenbroek 		char *p = s;
754*00b67f09SDavid van Moolenbroek 		while (*p != ' ' && *p != '\t' && *p != '\0')
755*00b67f09SDavid van Moolenbroek 			p++;
756*00b67f09SDavid van Moolenbroek 		if (*p != '\0')
757*00b67f09SDavid van Moolenbroek 			*p++ = '\0';
758*00b67f09SDavid van Moolenbroek 
759*00b67f09SDavid van Moolenbroek 		result = strtoargvsub(mctx, p, argcp, argvp, n + 1);
760*00b67f09SDavid van Moolenbroek 		if (result != ISC_R_SUCCESS)
761*00b67f09SDavid van Moolenbroek 			return (result);
762*00b67f09SDavid van Moolenbroek 		(*argvp)[n] = s;
763*00b67f09SDavid van Moolenbroek 	}
764*00b67f09SDavid van Moolenbroek 	return (ISC_R_SUCCESS);
765*00b67f09SDavid van Moolenbroek }
766*00b67f09SDavid van Moolenbroek 
767*00b67f09SDavid van Moolenbroek /*%
768*00b67f09SDavid van Moolenbroek  * Tokenize the string "s" into whitespace-separated words,
769*00b67f09SDavid van Moolenbroek  * return the number of words in '*argcp' and an array
770*00b67f09SDavid van Moolenbroek  * of pointers to the words in '*argvp'.  The caller
771*00b67f09SDavid van Moolenbroek  * must free the array using isc_mem_put().  The string
772*00b67f09SDavid van Moolenbroek  * is modified in-place.
773*00b67f09SDavid van Moolenbroek  */
774*00b67f09SDavid van Moolenbroek static isc_result_t
strtoargv(isc_mem_t * mctx,char * s,unsigned int * argcp,char *** argvp)775*00b67f09SDavid van Moolenbroek strtoargv(isc_mem_t *mctx, char *s, unsigned int *argcp, char ***argvp) {
776*00b67f09SDavid van Moolenbroek 	return (strtoargvsub(mctx, s, argcp, argvp, 0));
777*00b67f09SDavid van Moolenbroek }
778*00b67f09SDavid van Moolenbroek 
779*00b67f09SDavid van Moolenbroek static void
checknames(dns_zonetype_t ztype,const cfg_obj_t ** maps,const cfg_obj_t ** objp)780*00b67f09SDavid van Moolenbroek checknames(dns_zonetype_t ztype, const cfg_obj_t **maps,
781*00b67f09SDavid van Moolenbroek 	   const cfg_obj_t **objp)
782*00b67f09SDavid van Moolenbroek {
783*00b67f09SDavid van Moolenbroek 	const char *zone = NULL;
784*00b67f09SDavid van Moolenbroek 	isc_result_t result;
785*00b67f09SDavid van Moolenbroek 
786*00b67f09SDavid van Moolenbroek 	switch (ztype) {
787*00b67f09SDavid van Moolenbroek 	case dns_zone_slave: zone = "slave"; break;
788*00b67f09SDavid van Moolenbroek 	case dns_zone_master: zone = "master"; break;
789*00b67f09SDavid van Moolenbroek 	default:
790*00b67f09SDavid van Moolenbroek 		INSIST(0);
791*00b67f09SDavid van Moolenbroek 	}
792*00b67f09SDavid van Moolenbroek 	result = ns_checknames_get(maps, zone, objp);
793*00b67f09SDavid van Moolenbroek 	INSIST(result == ISC_R_SUCCESS && objp != NULL && *objp != NULL);
794*00b67f09SDavid van Moolenbroek }
795*00b67f09SDavid van Moolenbroek 
796*00b67f09SDavid van Moolenbroek isc_result_t
ns_zone_configure(const cfg_obj_t * config,const cfg_obj_t * vconfig,const cfg_obj_t * zconfig,cfg_aclconfctx_t * ac,dns_zone_t * zone,dns_zone_t * raw)797*00b67f09SDavid van Moolenbroek ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
798*00b67f09SDavid van Moolenbroek 		  const cfg_obj_t *zconfig, cfg_aclconfctx_t *ac,
799*00b67f09SDavid van Moolenbroek 		  dns_zone_t *zone, dns_zone_t *raw)
800*00b67f09SDavid van Moolenbroek {
801*00b67f09SDavid van Moolenbroek 	isc_result_t result;
802*00b67f09SDavid van Moolenbroek 	const char *zname;
803*00b67f09SDavid van Moolenbroek 	dns_rdataclass_t zclass;
804*00b67f09SDavid van Moolenbroek 	dns_rdataclass_t vclass;
805*00b67f09SDavid van Moolenbroek 	const cfg_obj_t *maps[5];
806*00b67f09SDavid van Moolenbroek 	const cfg_obj_t *nodefault[4];
807*00b67f09SDavid van Moolenbroek 	const cfg_obj_t *zoptions = NULL;
808*00b67f09SDavid van Moolenbroek 	const cfg_obj_t *options = NULL;
809*00b67f09SDavid van Moolenbroek 	const cfg_obj_t *obj;
810*00b67f09SDavid van Moolenbroek 	const char *filename = NULL;
811*00b67f09SDavid van Moolenbroek 	const char *dupcheck;
812*00b67f09SDavid van Moolenbroek 	dns_notifytype_t notifytype = dns_notifytype_yes;
813*00b67f09SDavid van Moolenbroek 	isc_sockaddr_t *addrs;
814*00b67f09SDavid van Moolenbroek 	isc_dscp_t *dscps;
815*00b67f09SDavid van Moolenbroek 	dns_name_t **keynames;
816*00b67f09SDavid van Moolenbroek 	isc_uint32_t count;
817*00b67f09SDavid van Moolenbroek 	unsigned int dbargc;
818*00b67f09SDavid van Moolenbroek 	char **dbargv;
819*00b67f09SDavid van Moolenbroek 	static char default_dbtype[] = "rbt";
820*00b67f09SDavid van Moolenbroek 	static char dlz_dbtype[] = "dlz";
821*00b67f09SDavid van Moolenbroek 	char *cpval = default_dbtype;
822*00b67f09SDavid van Moolenbroek 	isc_mem_t *mctx = dns_zone_getmctx(zone);
823*00b67f09SDavid van Moolenbroek 	dns_dialuptype_t dialup = dns_dialuptype_no;
824*00b67f09SDavid van Moolenbroek 	dns_zonetype_t ztype;
825*00b67f09SDavid van Moolenbroek 	int i;
826*00b67f09SDavid van Moolenbroek 	isc_int32_t journal_size;
827*00b67f09SDavid van Moolenbroek 	isc_boolean_t multi;
828*00b67f09SDavid van Moolenbroek 	isc_boolean_t alt;
829*00b67f09SDavid van Moolenbroek 	dns_view_t *view;
830*00b67f09SDavid van Moolenbroek 	isc_boolean_t check = ISC_FALSE, fail = ISC_FALSE;
831*00b67f09SDavid van Moolenbroek 	isc_boolean_t warn = ISC_FALSE, ignore = ISC_FALSE;
832*00b67f09SDavid van Moolenbroek 	isc_boolean_t ixfrdiff;
833*00b67f09SDavid van Moolenbroek 	dns_masterformat_t masterformat;
834*00b67f09SDavid van Moolenbroek 	isc_stats_t *zoneqrystats;
835*00b67f09SDavid van Moolenbroek 	dns_stats_t *rcvquerystats;
836*00b67f09SDavid van Moolenbroek 	dns_zonestat_level_t statlevel;
837*00b67f09SDavid van Moolenbroek 	int seconds;
838*00b67f09SDavid van Moolenbroek 	dns_zone_t *mayberaw = (raw != NULL) ? raw : zone;
839*00b67f09SDavid van Moolenbroek 	isc_dscp_t dscp;
840*00b67f09SDavid van Moolenbroek 
841*00b67f09SDavid van Moolenbroek 	i = 0;
842*00b67f09SDavid van Moolenbroek 	if (zconfig != NULL) {
843*00b67f09SDavid van Moolenbroek 		zoptions = cfg_tuple_get(zconfig, "options");
844*00b67f09SDavid van Moolenbroek 		nodefault[i] = maps[i] = zoptions;
845*00b67f09SDavid van Moolenbroek 		i++;
846*00b67f09SDavid van Moolenbroek 	}
847*00b67f09SDavid van Moolenbroek 	if (vconfig != NULL) {
848*00b67f09SDavid van Moolenbroek 		nodefault[i] = maps[i] = cfg_tuple_get(vconfig, "options");
849*00b67f09SDavid van Moolenbroek 		i++;
850*00b67f09SDavid van Moolenbroek 	}
851*00b67f09SDavid van Moolenbroek 	if (config != NULL) {
852*00b67f09SDavid van Moolenbroek 		(void)cfg_map_get(config, "options", &options);
853*00b67f09SDavid van Moolenbroek 		if (options != NULL) {
854*00b67f09SDavid van Moolenbroek 			nodefault[i] = maps[i] = options;
855*00b67f09SDavid van Moolenbroek 			i++;
856*00b67f09SDavid van Moolenbroek 		}
857*00b67f09SDavid van Moolenbroek 	}
858*00b67f09SDavid van Moolenbroek 	nodefault[i] = NULL;
859*00b67f09SDavid van Moolenbroek 	maps[i++] = ns_g_defaults;
860*00b67f09SDavid van Moolenbroek 	maps[i] = NULL;
861*00b67f09SDavid van Moolenbroek 
862*00b67f09SDavid van Moolenbroek 	if (vconfig != NULL)
863*00b67f09SDavid van Moolenbroek 		RETERR(ns_config_getclass(cfg_tuple_get(vconfig, "class"),
864*00b67f09SDavid van Moolenbroek 					  dns_rdataclass_in, &vclass));
865*00b67f09SDavid van Moolenbroek 	else
866*00b67f09SDavid van Moolenbroek 		vclass = dns_rdataclass_in;
867*00b67f09SDavid van Moolenbroek 
868*00b67f09SDavid van Moolenbroek 	/*
869*00b67f09SDavid van Moolenbroek 	 * Configure values common to all zone types.
870*00b67f09SDavid van Moolenbroek 	 */
871*00b67f09SDavid van Moolenbroek 
872*00b67f09SDavid van Moolenbroek 	zname = cfg_obj_asstring(cfg_tuple_get(zconfig, "name"));
873*00b67f09SDavid van Moolenbroek 
874*00b67f09SDavid van Moolenbroek 	RETERR(ns_config_getclass(cfg_tuple_get(zconfig, "class"),
875*00b67f09SDavid van Moolenbroek 				  vclass, &zclass));
876*00b67f09SDavid van Moolenbroek 	dns_zone_setclass(zone, zclass);
877*00b67f09SDavid van Moolenbroek 	if (raw != NULL)
878*00b67f09SDavid van Moolenbroek 		dns_zone_setclass(raw, zclass);
879*00b67f09SDavid van Moolenbroek 
880*00b67f09SDavid van Moolenbroek 	ztype = zonetype_fromconfig(zoptions);
881*00b67f09SDavid van Moolenbroek 	if (raw != NULL) {
882*00b67f09SDavid van Moolenbroek 		dns_zone_settype(raw, ztype);
883*00b67f09SDavid van Moolenbroek 		dns_zone_settype(zone, dns_zone_master);
884*00b67f09SDavid van Moolenbroek 	} else
885*00b67f09SDavid van Moolenbroek 		dns_zone_settype(zone, ztype);
886*00b67f09SDavid van Moolenbroek 
887*00b67f09SDavid van Moolenbroek 	obj = NULL;
888*00b67f09SDavid van Moolenbroek 	result = cfg_map_get(zoptions, "database", &obj);
889*00b67f09SDavid van Moolenbroek 	if (result == ISC_R_SUCCESS)
890*00b67f09SDavid van Moolenbroek 		cpval = isc_mem_strdup(mctx, cfg_obj_asstring(obj));
891*00b67f09SDavid van Moolenbroek 	if (cpval == NULL)
892*00b67f09SDavid van Moolenbroek 		return(ISC_R_NOMEMORY);
893*00b67f09SDavid van Moolenbroek 
894*00b67f09SDavid van Moolenbroek 	obj = NULL;
895*00b67f09SDavid van Moolenbroek 	result = cfg_map_get(zoptions, "dlz", &obj);
896*00b67f09SDavid van Moolenbroek 	if (result == ISC_R_SUCCESS) {
897*00b67f09SDavid van Moolenbroek 		const char *dlzname = cfg_obj_asstring(obj);
898*00b67f09SDavid van Moolenbroek 		size_t len;
899*00b67f09SDavid van Moolenbroek 
900*00b67f09SDavid van Moolenbroek 		if (cpval != default_dbtype) {
901*00b67f09SDavid van Moolenbroek 		       isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
902*00b67f09SDavid van Moolenbroek 				     NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
903*00b67f09SDavid van Moolenbroek 				     "zone '%s': both 'database' and 'dlz' "
904*00b67f09SDavid van Moolenbroek 				     "specified", zname);
905*00b67f09SDavid van Moolenbroek 		       return (ISC_R_FAILURE);
906*00b67f09SDavid van Moolenbroek 		}
907*00b67f09SDavid van Moolenbroek 
908*00b67f09SDavid van Moolenbroek 		len = strlen(dlzname) + 5;
909*00b67f09SDavid van Moolenbroek 		cpval = isc_mem_allocate(mctx, len);
910*00b67f09SDavid van Moolenbroek 		snprintf(cpval, len, "dlz %s", dlzname);
911*00b67f09SDavid van Moolenbroek 	}
912*00b67f09SDavid van Moolenbroek 
913*00b67f09SDavid van Moolenbroek 	result = strtoargv(mctx, cpval, &dbargc, &dbargv);
914*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS && cpval != default_dbtype) {
915*00b67f09SDavid van Moolenbroek 		isc_mem_free(mctx, cpval);
916*00b67f09SDavid van Moolenbroek 		return (result);
917*00b67f09SDavid van Moolenbroek 	}
918*00b67f09SDavid van Moolenbroek 
919*00b67f09SDavid van Moolenbroek 	/*
920*00b67f09SDavid van Moolenbroek 	 * ANSI C is strange here.  There is no logical reason why (char **)
921*00b67f09SDavid van Moolenbroek 	 * cannot be promoted automatically to (const char * const *) by the
922*00b67f09SDavid van Moolenbroek 	 * compiler w/o generating a warning.
923*00b67f09SDavid van Moolenbroek 	 */
924*00b67f09SDavid van Moolenbroek 	result = dns_zone_setdbtype(zone, dbargc, (const char * const *)dbargv);
925*00b67f09SDavid van Moolenbroek 	isc_mem_put(mctx, dbargv, dbargc * sizeof(*dbargv));
926*00b67f09SDavid van Moolenbroek 	if (cpval != default_dbtype && cpval != dlz_dbtype)
927*00b67f09SDavid van Moolenbroek 		isc_mem_free(mctx, cpval);
928*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS)
929*00b67f09SDavid van Moolenbroek 		return (result);
930*00b67f09SDavid van Moolenbroek 
931*00b67f09SDavid van Moolenbroek 	obj = NULL;
932*00b67f09SDavid van Moolenbroek 	result = cfg_map_get(zoptions, "file", &obj);
933*00b67f09SDavid van Moolenbroek 	if (result == ISC_R_SUCCESS)
934*00b67f09SDavid van Moolenbroek 		filename = cfg_obj_asstring(obj);
935*00b67f09SDavid van Moolenbroek 
936*00b67f09SDavid van Moolenbroek 	/*
937*00b67f09SDavid van Moolenbroek 	 * Unless we're using some alternative database, a master zone
938*00b67f09SDavid van Moolenbroek 	 * will be needing a master file.
939*00b67f09SDavid van Moolenbroek 	 */
940*00b67f09SDavid van Moolenbroek 	if (ztype == dns_zone_master && cpval == default_dbtype &&
941*00b67f09SDavid van Moolenbroek 	    filename == NULL) {
942*00b67f09SDavid van Moolenbroek 		isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
943*00b67f09SDavid van Moolenbroek 			      NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
944*00b67f09SDavid van Moolenbroek 			      "zone '%s': 'file' not specified",
945*00b67f09SDavid van Moolenbroek 			      zname);
946*00b67f09SDavid van Moolenbroek 		return (ISC_R_FAILURE);
947*00b67f09SDavid van Moolenbroek 	}
948*00b67f09SDavid van Moolenbroek 
949*00b67f09SDavid van Moolenbroek 	if (ztype == dns_zone_slave)
950*00b67f09SDavid van Moolenbroek 		masterformat = dns_masterformat_raw;
951*00b67f09SDavid van Moolenbroek 	else
952*00b67f09SDavid van Moolenbroek 		masterformat = dns_masterformat_text;
953*00b67f09SDavid van Moolenbroek 	obj = NULL;
954*00b67f09SDavid van Moolenbroek 	result= ns_config_get(maps, "masterfile-format", &obj);
955*00b67f09SDavid van Moolenbroek 	if (result == ISC_R_SUCCESS) {
956*00b67f09SDavid van Moolenbroek 		const char *masterformatstr = cfg_obj_asstring(obj);
957*00b67f09SDavid van Moolenbroek 
958*00b67f09SDavid van Moolenbroek 		if (strcasecmp(masterformatstr, "text") == 0)
959*00b67f09SDavid van Moolenbroek 			masterformat = dns_masterformat_text;
960*00b67f09SDavid van Moolenbroek 		else if (strcasecmp(masterformatstr, "raw") == 0)
961*00b67f09SDavid van Moolenbroek 			masterformat = dns_masterformat_raw;
962*00b67f09SDavid van Moolenbroek 		else if (strcasecmp(masterformatstr, "map") == 0)
963*00b67f09SDavid van Moolenbroek 			masterformat = dns_masterformat_map;
964*00b67f09SDavid van Moolenbroek 		else
965*00b67f09SDavid van Moolenbroek 			INSIST(0);
966*00b67f09SDavid van Moolenbroek 	}
967*00b67f09SDavid van Moolenbroek 
968*00b67f09SDavid van Moolenbroek 	obj = NULL;
969*00b67f09SDavid van Moolenbroek 	result = ns_config_get(maps, "max-zone-ttl", &obj);
970*00b67f09SDavid van Moolenbroek 	if (result == ISC_R_SUCCESS && masterformat == dns_masterformat_map) {
971*00b67f09SDavid van Moolenbroek 		isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
972*00b67f09SDavid van Moolenbroek 			      NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
973*00b67f09SDavid van Moolenbroek 			      "zone '%s': 'max-zone-ttl' is not compatible "
974*00b67f09SDavid van Moolenbroek 			      "with 'masterfile-format map'", zname);
975*00b67f09SDavid van Moolenbroek 		return (ISC_R_FAILURE);
976*00b67f09SDavid van Moolenbroek 	} else if (result == ISC_R_SUCCESS) {
977*00b67f09SDavid van Moolenbroek 		dns_ttl_t maxttl = cfg_obj_asuint32(obj);
978*00b67f09SDavid van Moolenbroek 		dns_zone_setmaxttl(zone, maxttl);
979*00b67f09SDavid van Moolenbroek 		if (raw != NULL)
980*00b67f09SDavid van Moolenbroek 			dns_zone_setmaxttl(raw, maxttl);
981*00b67f09SDavid van Moolenbroek 	}
982*00b67f09SDavid van Moolenbroek 
983*00b67f09SDavid van Moolenbroek 	if (raw != NULL && filename != NULL) {
984*00b67f09SDavid van Moolenbroek #define SIGNED ".signed"
985*00b67f09SDavid van Moolenbroek 		size_t signedlen = strlen(filename) + sizeof(SIGNED);
986*00b67f09SDavid van Moolenbroek 		char *signedname;
987*00b67f09SDavid van Moolenbroek 
988*00b67f09SDavid van Moolenbroek 		RETERR(dns_zone_setfile2(raw, filename, masterformat));
989*00b67f09SDavid van Moolenbroek 		signedname = isc_mem_get(mctx, signedlen);
990*00b67f09SDavid van Moolenbroek 		if (signedname == NULL)
991*00b67f09SDavid van Moolenbroek 			return (ISC_R_NOMEMORY);
992*00b67f09SDavid van Moolenbroek 
993*00b67f09SDavid van Moolenbroek 		(void)snprintf(signedname, signedlen, "%s" SIGNED, filename);
994*00b67f09SDavid van Moolenbroek 		result = dns_zone_setfile2(zone, signedname,
995*00b67f09SDavid van Moolenbroek 					   dns_masterformat_raw);
996*00b67f09SDavid van Moolenbroek 		isc_mem_put(mctx, signedname, signedlen);
997*00b67f09SDavid van Moolenbroek 		if (result != ISC_R_SUCCESS)
998*00b67f09SDavid van Moolenbroek 			return (result);
999*00b67f09SDavid van Moolenbroek 	} else
1000*00b67f09SDavid van Moolenbroek 		RETERR(dns_zone_setfile2(zone, filename, masterformat));
1001*00b67f09SDavid van Moolenbroek 
1002*00b67f09SDavid van Moolenbroek 	obj = NULL;
1003*00b67f09SDavid van Moolenbroek 	result = cfg_map_get(zoptions, "journal", &obj);
1004*00b67f09SDavid van Moolenbroek 	if (result == ISC_R_SUCCESS)
1005*00b67f09SDavid van Moolenbroek 		RETERR(dns_zone_setjournal(mayberaw, cfg_obj_asstring(obj)));
1006*00b67f09SDavid van Moolenbroek 
1007*00b67f09SDavid van Moolenbroek 	/*
1008*00b67f09SDavid van Moolenbroek 	 * Notify messages are processed by the raw zone if it exists.
1009*00b67f09SDavid van Moolenbroek 	 */
1010*00b67f09SDavid van Moolenbroek 	if (ztype == dns_zone_slave)
1011*00b67f09SDavid van Moolenbroek 		RETERR(configure_zone_acl(zconfig, vconfig, config,
1012*00b67f09SDavid van Moolenbroek 					  allow_notify, ac, mayberaw,
1013*00b67f09SDavid van Moolenbroek 					  dns_zone_setnotifyacl,
1014*00b67f09SDavid van Moolenbroek 					  dns_zone_clearnotifyacl));
1015*00b67f09SDavid van Moolenbroek 
1016*00b67f09SDavid van Moolenbroek 	/*
1017*00b67f09SDavid van Moolenbroek 	 * XXXAG This probably does not make sense for stubs.
1018*00b67f09SDavid van Moolenbroek 	 */
1019*00b67f09SDavid van Moolenbroek 	RETERR(configure_zone_acl(zconfig, vconfig, config,
1020*00b67f09SDavid van Moolenbroek 				  allow_query, ac, zone,
1021*00b67f09SDavid van Moolenbroek 				  dns_zone_setqueryacl,
1022*00b67f09SDavid van Moolenbroek 				  dns_zone_clearqueryacl));
1023*00b67f09SDavid van Moolenbroek 
1024*00b67f09SDavid van Moolenbroek 	RETERR(configure_zone_acl(zconfig, vconfig, config,
1025*00b67f09SDavid van Moolenbroek 				  allow_query_on, ac, zone,
1026*00b67f09SDavid van Moolenbroek 				  dns_zone_setqueryonacl,
1027*00b67f09SDavid van Moolenbroek 				  dns_zone_clearqueryonacl));
1028*00b67f09SDavid van Moolenbroek 
1029*00b67f09SDavid van Moolenbroek 	obj = NULL;
1030*00b67f09SDavid van Moolenbroek 	result = ns_config_get(maps, "dialup", &obj);
1031*00b67f09SDavid van Moolenbroek 	INSIST(result == ISC_R_SUCCESS && obj != NULL);
1032*00b67f09SDavid van Moolenbroek 	if (cfg_obj_isboolean(obj)) {
1033*00b67f09SDavid van Moolenbroek 		if (cfg_obj_asboolean(obj))
1034*00b67f09SDavid van Moolenbroek 			dialup = dns_dialuptype_yes;
1035*00b67f09SDavid van Moolenbroek 		else
1036*00b67f09SDavid van Moolenbroek 			dialup = dns_dialuptype_no;
1037*00b67f09SDavid van Moolenbroek 	} else {
1038*00b67f09SDavid van Moolenbroek 		const char *dialupstr = cfg_obj_asstring(obj);
1039*00b67f09SDavid van Moolenbroek 		if (strcasecmp(dialupstr, "notify") == 0)
1040*00b67f09SDavid van Moolenbroek 			dialup = dns_dialuptype_notify;
1041*00b67f09SDavid van Moolenbroek 		else if (strcasecmp(dialupstr, "notify-passive") == 0)
1042*00b67f09SDavid van Moolenbroek 			dialup = dns_dialuptype_notifypassive;
1043*00b67f09SDavid van Moolenbroek 		else if (strcasecmp(dialupstr, "refresh") == 0)
1044*00b67f09SDavid van Moolenbroek 			dialup = dns_dialuptype_refresh;
1045*00b67f09SDavid van Moolenbroek 		else if (strcasecmp(dialupstr, "passive") == 0)
1046*00b67f09SDavid van Moolenbroek 			dialup = dns_dialuptype_passive;
1047*00b67f09SDavid van Moolenbroek 		else
1048*00b67f09SDavid van Moolenbroek 			INSIST(0);
1049*00b67f09SDavid van Moolenbroek 	}
1050*00b67f09SDavid van Moolenbroek 	if (raw != NULL)
1051*00b67f09SDavid van Moolenbroek 		dns_zone_setdialup(raw, dialup);
1052*00b67f09SDavid van Moolenbroek 	dns_zone_setdialup(zone, dialup);
1053*00b67f09SDavid van Moolenbroek 
1054*00b67f09SDavid van Moolenbroek 	obj = NULL;
1055*00b67f09SDavid van Moolenbroek 	result = ns_config_get(maps, "zone-statistics", &obj);
1056*00b67f09SDavid van Moolenbroek 	INSIST(result == ISC_R_SUCCESS && obj != NULL);
1057*00b67f09SDavid van Moolenbroek 	if (cfg_obj_isboolean(obj)) {
1058*00b67f09SDavid van Moolenbroek 		if (cfg_obj_asboolean(obj))
1059*00b67f09SDavid van Moolenbroek 			statlevel = dns_zonestat_full;
1060*00b67f09SDavid van Moolenbroek 		else
1061*00b67f09SDavid van Moolenbroek 			statlevel = dns_zonestat_none;
1062*00b67f09SDavid van Moolenbroek 	} else {
1063*00b67f09SDavid van Moolenbroek 		const char *levelstr = cfg_obj_asstring(obj);
1064*00b67f09SDavid van Moolenbroek 		if (strcasecmp(levelstr, "full") == 0)
1065*00b67f09SDavid van Moolenbroek 			statlevel = dns_zonestat_full;
1066*00b67f09SDavid van Moolenbroek 		else if (strcasecmp(levelstr, "terse") == 0)
1067*00b67f09SDavid van Moolenbroek 			statlevel = dns_zonestat_terse;
1068*00b67f09SDavid van Moolenbroek 		else if (strcasecmp(levelstr, "none") == 0)
1069*00b67f09SDavid van Moolenbroek 			statlevel = dns_zonestat_none;
1070*00b67f09SDavid van Moolenbroek 		else
1071*00b67f09SDavid van Moolenbroek 			INSIST(0);
1072*00b67f09SDavid van Moolenbroek 	}
1073*00b67f09SDavid van Moolenbroek 	dns_zone_setstatlevel(zone, statlevel);
1074*00b67f09SDavid van Moolenbroek 
1075*00b67f09SDavid van Moolenbroek 	zoneqrystats  = NULL;
1076*00b67f09SDavid van Moolenbroek 	rcvquerystats = NULL;
1077*00b67f09SDavid van Moolenbroek 	if (statlevel == dns_zonestat_full) {
1078*00b67f09SDavid van Moolenbroek 		RETERR(isc_stats_create(mctx, &zoneqrystats,
1079*00b67f09SDavid van Moolenbroek 					dns_nsstatscounter_max));
1080*00b67f09SDavid van Moolenbroek 		RETERR(dns_rdatatypestats_create(mctx,
1081*00b67f09SDavid van Moolenbroek 					&rcvquerystats));
1082*00b67f09SDavid van Moolenbroek 	}
1083*00b67f09SDavid van Moolenbroek 	dns_zone_setrequeststats(zone,  zoneqrystats);
1084*00b67f09SDavid van Moolenbroek 	dns_zone_setrcvquerystats(zone, rcvquerystats);
1085*00b67f09SDavid van Moolenbroek 
1086*00b67f09SDavid van Moolenbroek 	if (zoneqrystats != NULL)
1087*00b67f09SDavid van Moolenbroek 		isc_stats_detach(&zoneqrystats);
1088*00b67f09SDavid van Moolenbroek 
1089*00b67f09SDavid van Moolenbroek 	if(rcvquerystats != NULL)
1090*00b67f09SDavid van Moolenbroek 		dns_stats_detach(&rcvquerystats);
1091*00b67f09SDavid van Moolenbroek 
1092*00b67f09SDavid van Moolenbroek 	/*
1093*00b67f09SDavid van Moolenbroek 	 * Configure master functionality.  This applies
1094*00b67f09SDavid van Moolenbroek 	 * to primary masters (type "master") and slaves
1095*00b67f09SDavid van Moolenbroek 	 * acting as masters (type "slave"), but not to stubs.
1096*00b67f09SDavid van Moolenbroek 	 */
1097*00b67f09SDavid van Moolenbroek 	if (ztype != dns_zone_stub && ztype != dns_zone_staticstub &&
1098*00b67f09SDavid van Moolenbroek 	    ztype != dns_zone_redirect) {
1099*00b67f09SDavid van Moolenbroek 		obj = NULL;
1100*00b67f09SDavid van Moolenbroek 		result = ns_config_get(maps, "notify", &obj);
1101*00b67f09SDavid van Moolenbroek 		INSIST(result == ISC_R_SUCCESS && obj != NULL);
1102*00b67f09SDavid van Moolenbroek 		if (cfg_obj_isboolean(obj)) {
1103*00b67f09SDavid van Moolenbroek 			if (cfg_obj_asboolean(obj))
1104*00b67f09SDavid van Moolenbroek 				notifytype = dns_notifytype_yes;
1105*00b67f09SDavid van Moolenbroek 			else
1106*00b67f09SDavid van Moolenbroek 				notifytype = dns_notifytype_no;
1107*00b67f09SDavid van Moolenbroek 		} else {
1108*00b67f09SDavid van Moolenbroek 			const char *notifystr = cfg_obj_asstring(obj);
1109*00b67f09SDavid van Moolenbroek 			if (strcasecmp(notifystr, "explicit") == 0)
1110*00b67f09SDavid van Moolenbroek 				notifytype = dns_notifytype_explicit;
1111*00b67f09SDavid van Moolenbroek 			else if (strcasecmp(notifystr, "master-only") == 0)
1112*00b67f09SDavid van Moolenbroek 				notifytype = dns_notifytype_masteronly;
1113*00b67f09SDavid van Moolenbroek 			else
1114*00b67f09SDavid van Moolenbroek 				INSIST(0);
1115*00b67f09SDavid van Moolenbroek 		}
1116*00b67f09SDavid van Moolenbroek 		if (raw != NULL)
1117*00b67f09SDavid van Moolenbroek 			dns_zone_setnotifytype(raw, dns_notifytype_no);
1118*00b67f09SDavid van Moolenbroek 		dns_zone_setnotifytype(zone, notifytype);
1119*00b67f09SDavid van Moolenbroek 
1120*00b67f09SDavid van Moolenbroek 		obj = NULL;
1121*00b67f09SDavid van Moolenbroek 		result = ns_config_get(maps, "also-notify", &obj);
1122*00b67f09SDavid van Moolenbroek 		if (result == ISC_R_SUCCESS &&
1123*00b67f09SDavid van Moolenbroek 		    (notifytype == dns_notifytype_yes ||
1124*00b67f09SDavid van Moolenbroek 		     notifytype == dns_notifytype_explicit ||
1125*00b67f09SDavid van Moolenbroek 		     (notifytype == dns_notifytype_masteronly &&
1126*00b67f09SDavid van Moolenbroek 		      ztype == dns_zone_master)))
1127*00b67f09SDavid van Moolenbroek 		{
1128*00b67f09SDavid van Moolenbroek 			isc_uint32_t addrcount;
1129*00b67f09SDavid van Moolenbroek 			addrs = NULL;
1130*00b67f09SDavid van Moolenbroek 			keynames = NULL;
1131*00b67f09SDavid van Moolenbroek 			dscps = NULL;
1132*00b67f09SDavid van Moolenbroek 			RETERR(ns_config_getipandkeylist(config, obj, mctx,
1133*00b67f09SDavid van Moolenbroek 							 &addrs, &dscps,
1134*00b67f09SDavid van Moolenbroek 							 &keynames,
1135*00b67f09SDavid van Moolenbroek 							 &addrcount));
1136*00b67f09SDavid van Moolenbroek 			result = dns_zone_setalsonotifydscpkeys(zone, addrs,
1137*00b67f09SDavid van Moolenbroek 								dscps, keynames,
1138*00b67f09SDavid van Moolenbroek 								addrcount);
1139*00b67f09SDavid van Moolenbroek 			if (addrcount != 0)
1140*00b67f09SDavid van Moolenbroek 				ns_config_putipandkeylist(mctx, &addrs, &dscps,
1141*00b67f09SDavid van Moolenbroek 							  &keynames, addrcount);
1142*00b67f09SDavid van Moolenbroek 			else
1143*00b67f09SDavid van Moolenbroek 				INSIST(addrs == NULL && dscps == NULL &&
1144*00b67f09SDavid van Moolenbroek 				       keynames == NULL);
1145*00b67f09SDavid van Moolenbroek 			RETERR(result);
1146*00b67f09SDavid van Moolenbroek 		} else
1147*00b67f09SDavid van Moolenbroek 			RETERR(dns_zone_setalsonotify(zone, NULL, 0));
1148*00b67f09SDavid van Moolenbroek 
1149*00b67f09SDavid van Moolenbroek 		obj = NULL;
1150*00b67f09SDavid van Moolenbroek 		result = ns_config_get(maps, "notify-source", &obj);
1151*00b67f09SDavid van Moolenbroek 		INSIST(result == ISC_R_SUCCESS && obj != NULL);
1152*00b67f09SDavid van Moolenbroek 		RETERR(dns_zone_setnotifysrc4(zone, cfg_obj_assockaddr(obj)));
1153*00b67f09SDavid van Moolenbroek 		dscp = cfg_obj_getdscp(obj);
1154*00b67f09SDavid van Moolenbroek 		if (dscp == -1)
1155*00b67f09SDavid van Moolenbroek 			dscp = ns_g_dscp;
1156*00b67f09SDavid van Moolenbroek 		RETERR(dns_zone_setnotifysrc4dscp(zone, dscp));
1157*00b67f09SDavid van Moolenbroek 		ns_add_reserved_dispatch(ns_g_server, cfg_obj_assockaddr(obj));
1158*00b67f09SDavid van Moolenbroek 
1159*00b67f09SDavid van Moolenbroek 		obj = NULL;
1160*00b67f09SDavid van Moolenbroek 		result = ns_config_get(maps, "notify-source-v6", &obj);
1161*00b67f09SDavid van Moolenbroek 		INSIST(result == ISC_R_SUCCESS && obj != NULL);
1162*00b67f09SDavid van Moolenbroek 		RETERR(dns_zone_setnotifysrc6(zone, cfg_obj_assockaddr(obj)));
1163*00b67f09SDavid van Moolenbroek 		dscp = cfg_obj_getdscp(obj);
1164*00b67f09SDavid van Moolenbroek 		if (dscp == -1)
1165*00b67f09SDavid van Moolenbroek 			dscp = ns_g_dscp;
1166*00b67f09SDavid van Moolenbroek 		RETERR(dns_zone_setnotifysrc6dscp(zone, dscp));
1167*00b67f09SDavid van Moolenbroek 		ns_add_reserved_dispatch(ns_g_server, cfg_obj_assockaddr(obj));
1168*00b67f09SDavid van Moolenbroek 
1169*00b67f09SDavid van Moolenbroek 		obj = NULL;
1170*00b67f09SDavid van Moolenbroek 		result = ns_config_get(maps, "notify-to-soa", &obj);
1171*00b67f09SDavid van Moolenbroek 		INSIST(result == ISC_R_SUCCESS && obj != NULL);
1172*00b67f09SDavid van Moolenbroek 		dns_zone_setoption(zone, DNS_ZONEOPT_NOTIFYTOSOA,
1173*00b67f09SDavid van Moolenbroek 				   cfg_obj_asboolean(obj));
1174*00b67f09SDavid van Moolenbroek 
1175*00b67f09SDavid van Moolenbroek 		dns_zone_setisself(zone, ns_client_isself, NULL);
1176*00b67f09SDavid van Moolenbroek 
1177*00b67f09SDavid van Moolenbroek 		RETERR(configure_zone_acl(zconfig, vconfig, config,
1178*00b67f09SDavid van Moolenbroek 					  allow_transfer, ac, zone,
1179*00b67f09SDavid van Moolenbroek 					  dns_zone_setxfracl,
1180*00b67f09SDavid van Moolenbroek 					  dns_zone_clearxfracl));
1181*00b67f09SDavid van Moolenbroek 
1182*00b67f09SDavid van Moolenbroek 		obj = NULL;
1183*00b67f09SDavid van Moolenbroek 		result = ns_config_get(maps, "max-transfer-time-out", &obj);
1184*00b67f09SDavid van Moolenbroek 		INSIST(result == ISC_R_SUCCESS && obj != NULL);
1185*00b67f09SDavid van Moolenbroek 		dns_zone_setmaxxfrout(zone, cfg_obj_asuint32(obj) * 60);
1186*00b67f09SDavid van Moolenbroek 
1187*00b67f09SDavid van Moolenbroek 		obj = NULL;
1188*00b67f09SDavid van Moolenbroek 		result = ns_config_get(maps, "max-transfer-idle-out", &obj);
1189*00b67f09SDavid van Moolenbroek 		INSIST(result == ISC_R_SUCCESS && obj != NULL);
1190*00b67f09SDavid van Moolenbroek 		dns_zone_setidleout(zone, cfg_obj_asuint32(obj) * 60);
1191*00b67f09SDavid van Moolenbroek 
1192*00b67f09SDavid van Moolenbroek 		obj = NULL;
1193*00b67f09SDavid van Moolenbroek 		result = ns_config_get(maps, "max-journal-size", &obj);
1194*00b67f09SDavid van Moolenbroek 		INSIST(result == ISC_R_SUCCESS && obj != NULL);
1195*00b67f09SDavid van Moolenbroek 		if (raw != NULL)
1196*00b67f09SDavid van Moolenbroek 			dns_zone_setjournalsize(raw, -1);
1197*00b67f09SDavid van Moolenbroek 		dns_zone_setjournalsize(zone, -1);
1198*00b67f09SDavid van Moolenbroek 		if (cfg_obj_isstring(obj)) {
1199*00b67f09SDavid van Moolenbroek 			const char *str = cfg_obj_asstring(obj);
1200*00b67f09SDavid van Moolenbroek 			INSIST(strcasecmp(str, "unlimited") == 0);
1201*00b67f09SDavid van Moolenbroek 			journal_size = ISC_UINT32_MAX / 2;
1202*00b67f09SDavid van Moolenbroek 		} else {
1203*00b67f09SDavid van Moolenbroek 			isc_resourcevalue_t value;
1204*00b67f09SDavid van Moolenbroek 			value = cfg_obj_asuint64(obj);
1205*00b67f09SDavid van Moolenbroek 			if (value > ISC_UINT32_MAX / 2) {
1206*00b67f09SDavid van Moolenbroek 				cfg_obj_log(obj, ns_g_lctx,
1207*00b67f09SDavid van Moolenbroek 					    ISC_LOG_ERROR,
1208*00b67f09SDavid van Moolenbroek 					    "'max-journal-size "
1209*00b67f09SDavid van Moolenbroek 					    "%" ISC_PRINT_QUADFORMAT "d' "
1210*00b67f09SDavid van Moolenbroek 					    "is too large",
1211*00b67f09SDavid van Moolenbroek 					    value);
1212*00b67f09SDavid van Moolenbroek 				RETERR(ISC_R_RANGE);
1213*00b67f09SDavid van Moolenbroek 			}
1214*00b67f09SDavid van Moolenbroek 			journal_size = (isc_uint32_t)value;
1215*00b67f09SDavid van Moolenbroek 		}
1216*00b67f09SDavid van Moolenbroek 		if (raw != NULL)
1217*00b67f09SDavid van Moolenbroek 			dns_zone_setjournalsize(raw, journal_size);
1218*00b67f09SDavid van Moolenbroek 		dns_zone_setjournalsize(zone, journal_size);
1219*00b67f09SDavid van Moolenbroek 
1220*00b67f09SDavid van Moolenbroek 		obj = NULL;
1221*00b67f09SDavid van Moolenbroek 		result = ns_config_get(maps, "ixfr-from-differences", &obj);
1222*00b67f09SDavid van Moolenbroek 		INSIST(result == ISC_R_SUCCESS && obj != NULL);
1223*00b67f09SDavid van Moolenbroek 		if (cfg_obj_isboolean(obj))
1224*00b67f09SDavid van Moolenbroek 			ixfrdiff = cfg_obj_asboolean(obj);
1225*00b67f09SDavid van Moolenbroek 		else if (!strcasecmp(cfg_obj_asstring(obj), "master") &&
1226*00b67f09SDavid van Moolenbroek 			 ztype == dns_zone_master)
1227*00b67f09SDavid van Moolenbroek 			ixfrdiff = ISC_TRUE;
1228*00b67f09SDavid van Moolenbroek 		else if (!strcasecmp(cfg_obj_asstring(obj), "slave") &&
1229*00b67f09SDavid van Moolenbroek 			ztype == dns_zone_slave)
1230*00b67f09SDavid van Moolenbroek 			ixfrdiff = ISC_TRUE;
1231*00b67f09SDavid van Moolenbroek 		else
1232*00b67f09SDavid van Moolenbroek 			ixfrdiff = ISC_FALSE;
1233*00b67f09SDavid van Moolenbroek 		if (raw != NULL) {
1234*00b67f09SDavid van Moolenbroek 			dns_zone_setoption(raw, DNS_ZONEOPT_IXFRFROMDIFFS,
1235*00b67f09SDavid van Moolenbroek 					   ISC_TRUE);
1236*00b67f09SDavid van Moolenbroek 			dns_zone_setoption(zone, DNS_ZONEOPT_IXFRFROMDIFFS,
1237*00b67f09SDavid van Moolenbroek 					   ISC_TRUE);
1238*00b67f09SDavid van Moolenbroek 		} else
1239*00b67f09SDavid van Moolenbroek 			dns_zone_setoption(zone, DNS_ZONEOPT_IXFRFROMDIFFS,
1240*00b67f09SDavid van Moolenbroek 					   ixfrdiff);
1241*00b67f09SDavid van Moolenbroek 
1242*00b67f09SDavid van Moolenbroek 		obj = NULL;
1243*00b67f09SDavid van Moolenbroek 		result = ns_config_get(maps, "request-ixfr", &obj);
1244*00b67f09SDavid van Moolenbroek 		INSIST(result == ISC_R_SUCCESS);
1245*00b67f09SDavid van Moolenbroek 		dns_zone_setrequestixfr(zone, cfg_obj_asboolean(obj));
1246*00b67f09SDavid van Moolenbroek 
1247*00b67f09SDavid van Moolenbroek 		checknames(ztype, maps, &obj);
1248*00b67f09SDavid van Moolenbroek 		INSIST(obj != NULL);
1249*00b67f09SDavid van Moolenbroek 		if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) {
1250*00b67f09SDavid van Moolenbroek 			fail = ISC_FALSE;
1251*00b67f09SDavid van Moolenbroek 			check = ISC_TRUE;
1252*00b67f09SDavid van Moolenbroek 		} else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) {
1253*00b67f09SDavid van Moolenbroek 			fail = check = ISC_TRUE;
1254*00b67f09SDavid van Moolenbroek 		} else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) {
1255*00b67f09SDavid van Moolenbroek 			fail = check = ISC_FALSE;
1256*00b67f09SDavid van Moolenbroek 		} else
1257*00b67f09SDavid van Moolenbroek 			INSIST(0);
1258*00b67f09SDavid van Moolenbroek 		if (raw != NULL) {
1259*00b67f09SDavid van Moolenbroek 			dns_zone_setoption(raw, DNS_ZONEOPT_CHECKNAMES,
1260*00b67f09SDavid van Moolenbroek 					   check);
1261*00b67f09SDavid van Moolenbroek 			dns_zone_setoption(raw, DNS_ZONEOPT_CHECKNAMESFAIL,
1262*00b67f09SDavid van Moolenbroek 					   fail);
1263*00b67f09SDavid van Moolenbroek 			dns_zone_setoption(zone, DNS_ZONEOPT_CHECKNAMES,
1264*00b67f09SDavid van Moolenbroek 					   ISC_FALSE);
1265*00b67f09SDavid van Moolenbroek 			dns_zone_setoption(zone, DNS_ZONEOPT_CHECKNAMESFAIL,
1266*00b67f09SDavid van Moolenbroek 					   ISC_FALSE);
1267*00b67f09SDavid van Moolenbroek 		} else {
1268*00b67f09SDavid van Moolenbroek 			dns_zone_setoption(zone, DNS_ZONEOPT_CHECKNAMES,
1269*00b67f09SDavid van Moolenbroek 					   check);
1270*00b67f09SDavid van Moolenbroek 			dns_zone_setoption(zone, DNS_ZONEOPT_CHECKNAMESFAIL,
1271*00b67f09SDavid van Moolenbroek 					   fail);
1272*00b67f09SDavid van Moolenbroek 		}
1273*00b67f09SDavid van Moolenbroek 
1274*00b67f09SDavid van Moolenbroek 		obj = NULL;
1275*00b67f09SDavid van Moolenbroek 		result = ns_config_get(maps, "notify-delay", &obj);
1276*00b67f09SDavid van Moolenbroek 		INSIST(result == ISC_R_SUCCESS && obj != NULL);
1277*00b67f09SDavid van Moolenbroek 		dns_zone_setnotifydelay(zone, cfg_obj_asuint32(obj));
1278*00b67f09SDavid van Moolenbroek 
1279*00b67f09SDavid van Moolenbroek 		obj = NULL;
1280*00b67f09SDavid van Moolenbroek 		result = ns_config_get(maps, "check-sibling", &obj);
1281*00b67f09SDavid van Moolenbroek 		INSIST(result == ISC_R_SUCCESS && obj != NULL);
1282*00b67f09SDavid van Moolenbroek 		dns_zone_setoption(zone, DNS_ZONEOPT_CHECKSIBLING,
1283*00b67f09SDavid van Moolenbroek 				   cfg_obj_asboolean(obj));
1284*00b67f09SDavid van Moolenbroek 
1285*00b67f09SDavid van Moolenbroek 		obj = NULL;
1286*00b67f09SDavid van Moolenbroek 		result = ns_config_get(maps, "check-spf", &obj);
1287*00b67f09SDavid van Moolenbroek 		INSIST(result == ISC_R_SUCCESS && obj != NULL);
1288*00b67f09SDavid van Moolenbroek 		if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) {
1289*00b67f09SDavid van Moolenbroek 			check = ISC_TRUE;
1290*00b67f09SDavid van Moolenbroek 		} else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) {
1291*00b67f09SDavid van Moolenbroek 			check = ISC_FALSE;
1292*00b67f09SDavid van Moolenbroek 		} else
1293*00b67f09SDavid van Moolenbroek 			INSIST(0);
1294*00b67f09SDavid van Moolenbroek 		dns_zone_setoption(zone, DNS_ZONEOPT_CHECKSPF, check);
1295*00b67f09SDavid van Moolenbroek 
1296*00b67f09SDavid van Moolenbroek 		obj = NULL;
1297*00b67f09SDavid van Moolenbroek 		result = ns_config_get(maps, "zero-no-soa-ttl", &obj);
1298*00b67f09SDavid van Moolenbroek 		INSIST(result == ISC_R_SUCCESS && obj != NULL);
1299*00b67f09SDavid van Moolenbroek 		dns_zone_setzeronosoattl(zone, cfg_obj_asboolean(obj));
1300*00b67f09SDavid van Moolenbroek 
1301*00b67f09SDavid van Moolenbroek 		obj = NULL;
1302*00b67f09SDavid van Moolenbroek 		result = ns_config_get(maps, "nsec3-test-zone", &obj);
1303*00b67f09SDavid van Moolenbroek 		INSIST(result == ISC_R_SUCCESS && obj != NULL);
1304*00b67f09SDavid van Moolenbroek 		dns_zone_setoption(zone, DNS_ZONEOPT_NSEC3TESTZONE,
1305*00b67f09SDavid van Moolenbroek 				   cfg_obj_asboolean(obj));
1306*00b67f09SDavid van Moolenbroek 	} else if (ztype == dns_zone_redirect) {
1307*00b67f09SDavid van Moolenbroek 		dns_zone_setnotifytype(zone, dns_notifytype_no);
1308*00b67f09SDavid van Moolenbroek 
1309*00b67f09SDavid van Moolenbroek 		obj = NULL;
1310*00b67f09SDavid van Moolenbroek 		result = ns_config_get(maps, "max-journal-size", &obj);
1311*00b67f09SDavid van Moolenbroek 		INSIST(result == ISC_R_SUCCESS && obj != NULL);
1312*00b67f09SDavid van Moolenbroek 		dns_zone_setjournalsize(zone, -1);
1313*00b67f09SDavid van Moolenbroek 		if (cfg_obj_isstring(obj)) {
1314*00b67f09SDavid van Moolenbroek 			const char *str = cfg_obj_asstring(obj);
1315*00b67f09SDavid van Moolenbroek 			INSIST(strcasecmp(str, "unlimited") == 0);
1316*00b67f09SDavid van Moolenbroek 			journal_size = ISC_UINT32_MAX / 2;
1317*00b67f09SDavid van Moolenbroek 		} else {
1318*00b67f09SDavid van Moolenbroek 			isc_resourcevalue_t value;
1319*00b67f09SDavid van Moolenbroek 			value = cfg_obj_asuint64(obj);
1320*00b67f09SDavid van Moolenbroek 			if (value > ISC_UINT32_MAX / 2) {
1321*00b67f09SDavid van Moolenbroek 				cfg_obj_log(obj, ns_g_lctx,
1322*00b67f09SDavid van Moolenbroek 					    ISC_LOG_ERROR,
1323*00b67f09SDavid van Moolenbroek 					    "'max-journal-size "
1324*00b67f09SDavid van Moolenbroek 					    "%" ISC_PRINT_QUADFORMAT "d' "
1325*00b67f09SDavid van Moolenbroek 					    "is too large",
1326*00b67f09SDavid van Moolenbroek 					    value);
1327*00b67f09SDavid van Moolenbroek 				RETERR(ISC_R_RANGE);
1328*00b67f09SDavid van Moolenbroek 			}
1329*00b67f09SDavid van Moolenbroek 			journal_size = (isc_uint32_t)value;
1330*00b67f09SDavid van Moolenbroek 		}
1331*00b67f09SDavid van Moolenbroek 		dns_zone_setjournalsize(zone, journal_size);
1332*00b67f09SDavid van Moolenbroek 	}
1333*00b67f09SDavid van Moolenbroek 
1334*00b67f09SDavid van Moolenbroek 	/*
1335*00b67f09SDavid van Moolenbroek 	 * Configure update-related options.  These apply to
1336*00b67f09SDavid van Moolenbroek 	 * primary masters only.
1337*00b67f09SDavid van Moolenbroek 	 */
1338*00b67f09SDavid van Moolenbroek 	if (ztype == dns_zone_master) {
1339*00b67f09SDavid van Moolenbroek 		dns_acl_t *updateacl;
1340*00b67f09SDavid van Moolenbroek 
1341*00b67f09SDavid van Moolenbroek 		RETERR(configure_zone_acl(zconfig, vconfig, config,
1342*00b67f09SDavid van Moolenbroek 					  allow_update, ac, mayberaw,
1343*00b67f09SDavid van Moolenbroek 					  dns_zone_setupdateacl,
1344*00b67f09SDavid van Moolenbroek 					  dns_zone_clearupdateacl));
1345*00b67f09SDavid van Moolenbroek 
1346*00b67f09SDavid van Moolenbroek 		updateacl = dns_zone_getupdateacl(mayberaw);
1347*00b67f09SDavid van Moolenbroek 		if (updateacl != NULL  && dns_acl_isinsecure(updateacl))
1348*00b67f09SDavid van Moolenbroek 			isc_log_write(ns_g_lctx, DNS_LOGCATEGORY_SECURITY,
1349*00b67f09SDavid van Moolenbroek 				      NS_LOGMODULE_SERVER, ISC_LOG_WARNING,
1350*00b67f09SDavid van Moolenbroek 				      "zone '%s' allows updates by IP "
1351*00b67f09SDavid van Moolenbroek 				      "address, which is insecure",
1352*00b67f09SDavid van Moolenbroek 				      zname);
1353*00b67f09SDavid van Moolenbroek 
1354*00b67f09SDavid van Moolenbroek 		RETERR(configure_zone_ssutable(zoptions, mayberaw, zname));
1355*00b67f09SDavid van Moolenbroek 	}
1356*00b67f09SDavid van Moolenbroek 
1357*00b67f09SDavid van Moolenbroek 	if (ztype == dns_zone_master || raw != NULL) {
1358*00b67f09SDavid van Moolenbroek 		isc_boolean_t allow = ISC_FALSE, maint = ISC_FALSE;
1359*00b67f09SDavid van Moolenbroek 
1360*00b67f09SDavid van Moolenbroek 		obj = NULL;
1361*00b67f09SDavid van Moolenbroek 		result = ns_config_get(maps, "sig-validity-interval", &obj);
1362*00b67f09SDavid van Moolenbroek 		INSIST(result == ISC_R_SUCCESS && obj != NULL);
1363*00b67f09SDavid van Moolenbroek 		{
1364*00b67f09SDavid van Moolenbroek 			const cfg_obj_t *validity, *resign;
1365*00b67f09SDavid van Moolenbroek 
1366*00b67f09SDavid van Moolenbroek 			validity = cfg_tuple_get(obj, "validity");
1367*00b67f09SDavid van Moolenbroek 			seconds = cfg_obj_asuint32(validity) * 86400;
1368*00b67f09SDavid van Moolenbroek 			dns_zone_setsigvalidityinterval(zone, seconds);
1369*00b67f09SDavid van Moolenbroek 
1370*00b67f09SDavid van Moolenbroek 			resign = cfg_tuple_get(obj, "re-sign");
1371*00b67f09SDavid van Moolenbroek 			if (cfg_obj_isvoid(resign)) {
1372*00b67f09SDavid van Moolenbroek 				seconds /= 4;
1373*00b67f09SDavid van Moolenbroek 			} else {
1374*00b67f09SDavid van Moolenbroek 				if (seconds > 7 * 86400)
1375*00b67f09SDavid van Moolenbroek 					seconds = cfg_obj_asuint32(resign) *
1376*00b67f09SDavid van Moolenbroek 							86400;
1377*00b67f09SDavid van Moolenbroek 				else
1378*00b67f09SDavid van Moolenbroek 					seconds = cfg_obj_asuint32(resign) *
1379*00b67f09SDavid van Moolenbroek 							3600;
1380*00b67f09SDavid van Moolenbroek 			}
1381*00b67f09SDavid van Moolenbroek 			dns_zone_setsigresigninginterval(zone, seconds);
1382*00b67f09SDavid van Moolenbroek 		}
1383*00b67f09SDavid van Moolenbroek 
1384*00b67f09SDavid van Moolenbroek 		obj = NULL;
1385*00b67f09SDavid van Moolenbroek 		result = ns_config_get(maps, "key-directory", &obj);
1386*00b67f09SDavid van Moolenbroek 		if (result == ISC_R_SUCCESS) {
1387*00b67f09SDavid van Moolenbroek 			filename = cfg_obj_asstring(obj);
1388*00b67f09SDavid van Moolenbroek 			RETERR(dns_zone_setkeydirectory(zone, filename));
1389*00b67f09SDavid van Moolenbroek 		}
1390*00b67f09SDavid van Moolenbroek 
1391*00b67f09SDavid van Moolenbroek 		obj = NULL;
1392*00b67f09SDavid van Moolenbroek 		result = ns_config_get(maps, "sig-signing-signatures", &obj);
1393*00b67f09SDavid van Moolenbroek 		INSIST(result == ISC_R_SUCCESS && obj != NULL);
1394*00b67f09SDavid van Moolenbroek 		dns_zone_setsignatures(zone, cfg_obj_asuint32(obj));
1395*00b67f09SDavid van Moolenbroek 
1396*00b67f09SDavid van Moolenbroek 		obj = NULL;
1397*00b67f09SDavid van Moolenbroek 		result = ns_config_get(maps, "sig-signing-nodes", &obj);
1398*00b67f09SDavid van Moolenbroek 		INSIST(result == ISC_R_SUCCESS && obj != NULL);
1399*00b67f09SDavid van Moolenbroek 		dns_zone_setnodes(zone, cfg_obj_asuint32(obj));
1400*00b67f09SDavid van Moolenbroek 
1401*00b67f09SDavid van Moolenbroek 		obj = NULL;
1402*00b67f09SDavid van Moolenbroek 		result = ns_config_get(maps, "sig-signing-type", &obj);
1403*00b67f09SDavid van Moolenbroek 		INSIST(result == ISC_R_SUCCESS && obj != NULL);
1404*00b67f09SDavid van Moolenbroek 		dns_zone_setprivatetype(zone, cfg_obj_asuint32(obj));
1405*00b67f09SDavid van Moolenbroek 
1406*00b67f09SDavid van Moolenbroek 		obj = NULL;
1407*00b67f09SDavid van Moolenbroek 		result = ns_config_get(maps, "update-check-ksk", &obj);
1408*00b67f09SDavid van Moolenbroek 		INSIST(result == ISC_R_SUCCESS && obj != NULL);
1409*00b67f09SDavid van Moolenbroek 		dns_zone_setoption(zone, DNS_ZONEOPT_UPDATECHECKKSK,
1410*00b67f09SDavid van Moolenbroek 				   cfg_obj_asboolean(obj));
1411*00b67f09SDavid van Moolenbroek 
1412*00b67f09SDavid van Moolenbroek 		obj = NULL;
1413*00b67f09SDavid van Moolenbroek 		result = ns_config_get(maps, "dnssec-dnskey-kskonly", &obj);
1414*00b67f09SDavid van Moolenbroek 		INSIST(result == ISC_R_SUCCESS && obj != NULL);
1415*00b67f09SDavid van Moolenbroek 		dns_zone_setoption(zone, DNS_ZONEOPT_DNSKEYKSKONLY,
1416*00b67f09SDavid van Moolenbroek 				   cfg_obj_asboolean(obj));
1417*00b67f09SDavid van Moolenbroek 
1418*00b67f09SDavid van Moolenbroek 		obj = NULL;
1419*00b67f09SDavid van Moolenbroek 		result = ns_config_get(maps, "dnssec-loadkeys-interval", &obj);
1420*00b67f09SDavid van Moolenbroek 		INSIST(result == ISC_R_SUCCESS && obj != NULL);
1421*00b67f09SDavid van Moolenbroek 		RETERR(dns_zone_setrefreshkeyinterval(zone,
1422*00b67f09SDavid van Moolenbroek 						      cfg_obj_asuint32(obj)));
1423*00b67f09SDavid van Moolenbroek 
1424*00b67f09SDavid van Moolenbroek 		obj = NULL;
1425*00b67f09SDavid van Moolenbroek 		result = cfg_map_get(zoptions, "auto-dnssec", &obj);
1426*00b67f09SDavid van Moolenbroek 		if (result == ISC_R_SUCCESS) {
1427*00b67f09SDavid van Moolenbroek 			const char *arg = cfg_obj_asstring(obj);
1428*00b67f09SDavid van Moolenbroek 			if (strcasecmp(arg, "allow") == 0)
1429*00b67f09SDavid van Moolenbroek 				allow = ISC_TRUE;
1430*00b67f09SDavid van Moolenbroek 			else if (strcasecmp(arg, "maintain") == 0)
1431*00b67f09SDavid van Moolenbroek 				allow = maint = ISC_TRUE;
1432*00b67f09SDavid van Moolenbroek 			else if (strcasecmp(arg, "off") == 0)
1433*00b67f09SDavid van Moolenbroek 				;
1434*00b67f09SDavid van Moolenbroek 			else
1435*00b67f09SDavid van Moolenbroek 				INSIST(0);
1436*00b67f09SDavid van Moolenbroek 			dns_zone_setkeyopt(zone, DNS_ZONEKEY_ALLOW, allow);
1437*00b67f09SDavid van Moolenbroek 			dns_zone_setkeyopt(zone, DNS_ZONEKEY_MAINTAIN, maint);
1438*00b67f09SDavid van Moolenbroek 		}
1439*00b67f09SDavid van Moolenbroek 	}
1440*00b67f09SDavid van Moolenbroek 
1441*00b67f09SDavid van Moolenbroek 	if (ztype == dns_zone_slave) {
1442*00b67f09SDavid van Moolenbroek 		RETERR(configure_zone_acl(zconfig, vconfig, config,
1443*00b67f09SDavid van Moolenbroek 					  allow_update_forwarding, ac,
1444*00b67f09SDavid van Moolenbroek 					  mayberaw, dns_zone_setforwardacl,
1445*00b67f09SDavid van Moolenbroek 					  dns_zone_clearforwardacl));
1446*00b67f09SDavid van Moolenbroek 	}
1447*00b67f09SDavid van Moolenbroek 
1448*00b67f09SDavid van Moolenbroek 	/*%
1449*00b67f09SDavid van Moolenbroek 	 * Primary master functionality.
1450*00b67f09SDavid van Moolenbroek 	 */
1451*00b67f09SDavid van Moolenbroek 	if (ztype == dns_zone_master) {
1452*00b67f09SDavid van Moolenbroek 		obj = NULL;
1453*00b67f09SDavid van Moolenbroek 		result = ns_config_get(maps, "check-wildcard", &obj);
1454*00b67f09SDavid van Moolenbroek 		if (result == ISC_R_SUCCESS)
1455*00b67f09SDavid van Moolenbroek 			check = cfg_obj_asboolean(obj);
1456*00b67f09SDavid van Moolenbroek 		else
1457*00b67f09SDavid van Moolenbroek 			check = ISC_FALSE;
1458*00b67f09SDavid van Moolenbroek 		dns_zone_setoption(mayberaw, DNS_ZONEOPT_CHECKWILDCARD, check);
1459*00b67f09SDavid van Moolenbroek 
1460*00b67f09SDavid van Moolenbroek 		/*
1461*00b67f09SDavid van Moolenbroek 		 * With map files, the default is ignore duplicate
1462*00b67f09SDavid van Moolenbroek 		 * records.  With other master formats, the default is
1463*00b67f09SDavid van Moolenbroek 		 * taken from the global configuration.
1464*00b67f09SDavid van Moolenbroek 		 */
1465*00b67f09SDavid van Moolenbroek 		obj = NULL;
1466*00b67f09SDavid van Moolenbroek 		if (masterformat != dns_masterformat_map) {
1467*00b67f09SDavid van Moolenbroek 			result = ns_config_get(maps, "check-dup-records", &obj);
1468*00b67f09SDavid van Moolenbroek 			INSIST(result == ISC_R_SUCCESS && obj != NULL);
1469*00b67f09SDavid van Moolenbroek 			dupcheck = cfg_obj_asstring(obj);
1470*00b67f09SDavid van Moolenbroek 		} else {
1471*00b67f09SDavid van Moolenbroek 			result = ns_config_get(nodefault, "check-dup-records",
1472*00b67f09SDavid van Moolenbroek 					       &obj);
1473*00b67f09SDavid van Moolenbroek 			if (result == ISC_R_SUCCESS)
1474*00b67f09SDavid van Moolenbroek 				dupcheck = cfg_obj_asstring(obj);
1475*00b67f09SDavid van Moolenbroek 			else
1476*00b67f09SDavid van Moolenbroek 				dupcheck = "ignore";
1477*00b67f09SDavid van Moolenbroek 
1478*00b67f09SDavid van Moolenbroek 		}
1479*00b67f09SDavid van Moolenbroek 		if (strcasecmp(dupcheck, "warn") == 0) {
1480*00b67f09SDavid van Moolenbroek 			fail = ISC_FALSE;
1481*00b67f09SDavid van Moolenbroek 			check = ISC_TRUE;
1482*00b67f09SDavid van Moolenbroek 		} else if (strcasecmp(dupcheck, "fail") == 0) {
1483*00b67f09SDavid van Moolenbroek 			fail = check = ISC_TRUE;
1484*00b67f09SDavid van Moolenbroek 		} else if (strcasecmp(dupcheck, "ignore") == 0) {
1485*00b67f09SDavid van Moolenbroek 			fail = check = ISC_FALSE;
1486*00b67f09SDavid van Moolenbroek 		} else
1487*00b67f09SDavid van Moolenbroek 			INSIST(0);
1488*00b67f09SDavid van Moolenbroek 		dns_zone_setoption(mayberaw, DNS_ZONEOPT_CHECKDUPRR, check);
1489*00b67f09SDavid van Moolenbroek 		dns_zone_setoption(mayberaw, DNS_ZONEOPT_CHECKDUPRRFAIL, fail);
1490*00b67f09SDavid van Moolenbroek 
1491*00b67f09SDavid van Moolenbroek 		obj = NULL;
1492*00b67f09SDavid van Moolenbroek 		result = ns_config_get(maps, "check-mx", &obj);
1493*00b67f09SDavid van Moolenbroek 		INSIST(result == ISC_R_SUCCESS && obj != NULL);
1494*00b67f09SDavid van Moolenbroek 		if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) {
1495*00b67f09SDavid van Moolenbroek 			fail = ISC_FALSE;
1496*00b67f09SDavid van Moolenbroek 			check = ISC_TRUE;
1497*00b67f09SDavid van Moolenbroek 		} else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) {
1498*00b67f09SDavid van Moolenbroek 			fail = check = ISC_TRUE;
1499*00b67f09SDavid van Moolenbroek 		} else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) {
1500*00b67f09SDavid van Moolenbroek 			fail = check = ISC_FALSE;
1501*00b67f09SDavid van Moolenbroek 		} else
1502*00b67f09SDavid van Moolenbroek 			INSIST(0);
1503*00b67f09SDavid van Moolenbroek 		dns_zone_setoption(mayberaw, DNS_ZONEOPT_CHECKMX, check);
1504*00b67f09SDavid van Moolenbroek 		dns_zone_setoption(mayberaw, DNS_ZONEOPT_CHECKMXFAIL, fail);
1505*00b67f09SDavid van Moolenbroek 
1506*00b67f09SDavid van Moolenbroek 		/*
1507*00b67f09SDavid van Moolenbroek 		 * With map files, the default is *not* to check
1508*00b67f09SDavid van Moolenbroek 		 * integrity.  With other master formats, the default is
1509*00b67f09SDavid van Moolenbroek 		 * taken from the global configuration.
1510*00b67f09SDavid van Moolenbroek 		 */
1511*00b67f09SDavid van Moolenbroek 		obj = NULL;
1512*00b67f09SDavid van Moolenbroek 		if (masterformat != dns_masterformat_map) {
1513*00b67f09SDavid van Moolenbroek 			result = ns_config_get(maps, "check-integrity", &obj);
1514*00b67f09SDavid van Moolenbroek 			INSIST(result == ISC_R_SUCCESS && obj != NULL);
1515*00b67f09SDavid van Moolenbroek 			dns_zone_setoption(mayberaw, DNS_ZONEOPT_CHECKINTEGRITY,
1516*00b67f09SDavid van Moolenbroek 					   cfg_obj_asboolean(obj));
1517*00b67f09SDavid van Moolenbroek 		} else {
1518*00b67f09SDavid van Moolenbroek 			check = ISC_FALSE;
1519*00b67f09SDavid van Moolenbroek 			result = ns_config_get(nodefault, "check-integrity",
1520*00b67f09SDavid van Moolenbroek 					       &obj);
1521*00b67f09SDavid van Moolenbroek 			if (result == ISC_R_SUCCESS)
1522*00b67f09SDavid van Moolenbroek 				check = cfg_obj_asboolean(obj);
1523*00b67f09SDavid van Moolenbroek 			dns_zone_setoption(mayberaw, DNS_ZONEOPT_CHECKINTEGRITY,
1524*00b67f09SDavid van Moolenbroek 					   check);
1525*00b67f09SDavid van Moolenbroek 		}
1526*00b67f09SDavid van Moolenbroek 
1527*00b67f09SDavid van Moolenbroek 		obj = NULL;
1528*00b67f09SDavid van Moolenbroek 		result = ns_config_get(maps, "check-mx-cname", &obj);
1529*00b67f09SDavid van Moolenbroek 		INSIST(result == ISC_R_SUCCESS && obj != NULL);
1530*00b67f09SDavid van Moolenbroek 		if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) {
1531*00b67f09SDavid van Moolenbroek 			warn = ISC_TRUE;
1532*00b67f09SDavid van Moolenbroek 			ignore = ISC_FALSE;
1533*00b67f09SDavid van Moolenbroek 		} else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) {
1534*00b67f09SDavid van Moolenbroek 			warn = ignore = ISC_FALSE;
1535*00b67f09SDavid van Moolenbroek 		} else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) {
1536*00b67f09SDavid van Moolenbroek 			warn = ignore = ISC_TRUE;
1537*00b67f09SDavid van Moolenbroek 		} else
1538*00b67f09SDavid van Moolenbroek 			INSIST(0);
1539*00b67f09SDavid van Moolenbroek 		dns_zone_setoption(mayberaw, DNS_ZONEOPT_WARNMXCNAME, warn);
1540*00b67f09SDavid van Moolenbroek 		dns_zone_setoption(mayberaw, DNS_ZONEOPT_IGNOREMXCNAME, ignore);
1541*00b67f09SDavid van Moolenbroek 
1542*00b67f09SDavid van Moolenbroek 		obj = NULL;
1543*00b67f09SDavid van Moolenbroek 		result = ns_config_get(maps, "check-srv-cname", &obj);
1544*00b67f09SDavid van Moolenbroek 		INSIST(result == ISC_R_SUCCESS && obj != NULL);
1545*00b67f09SDavid van Moolenbroek 		if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) {
1546*00b67f09SDavid van Moolenbroek 			warn = ISC_TRUE;
1547*00b67f09SDavid van Moolenbroek 			ignore = ISC_FALSE;
1548*00b67f09SDavid van Moolenbroek 		} else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) {
1549*00b67f09SDavid van Moolenbroek 			warn = ignore = ISC_FALSE;
1550*00b67f09SDavid van Moolenbroek 		} else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) {
1551*00b67f09SDavid van Moolenbroek 			warn = ignore = ISC_TRUE;
1552*00b67f09SDavid van Moolenbroek 		} else
1553*00b67f09SDavid van Moolenbroek 			INSIST(0);
1554*00b67f09SDavid van Moolenbroek 		dns_zone_setoption(mayberaw, DNS_ZONEOPT_WARNSRVCNAME, warn);
1555*00b67f09SDavid van Moolenbroek 		dns_zone_setoption(mayberaw, DNS_ZONEOPT_IGNORESRVCNAME,
1556*00b67f09SDavid van Moolenbroek 				   ignore);
1557*00b67f09SDavid van Moolenbroek 
1558*00b67f09SDavid van Moolenbroek 		obj = NULL;
1559*00b67f09SDavid van Moolenbroek 		result = ns_config_get(maps, "dnssec-secure-to-insecure", &obj);
1560*00b67f09SDavid van Moolenbroek 		INSIST(result == ISC_R_SUCCESS && obj != NULL);
1561*00b67f09SDavid van Moolenbroek 		dns_zone_setoption(mayberaw, DNS_ZONEOPT_SECURETOINSECURE,
1562*00b67f09SDavid van Moolenbroek 				   cfg_obj_asboolean(obj));
1563*00b67f09SDavid van Moolenbroek 
1564*00b67f09SDavid van Moolenbroek 		obj = NULL;
1565*00b67f09SDavid van Moolenbroek 		result = cfg_map_get(zoptions, "dnssec-update-mode", &obj);
1566*00b67f09SDavid van Moolenbroek 		if (result == ISC_R_SUCCESS) {
1567*00b67f09SDavid van Moolenbroek 			const char *arg = cfg_obj_asstring(obj);
1568*00b67f09SDavid van Moolenbroek 			if (strcasecmp(arg, "no-resign") == 0)
1569*00b67f09SDavid van Moolenbroek 				dns_zone_setkeyopt(zone, DNS_ZONEKEY_NORESIGN,
1570*00b67f09SDavid van Moolenbroek 						   ISC_TRUE);
1571*00b67f09SDavid van Moolenbroek 			else if (strcasecmp(arg, "maintain") == 0)
1572*00b67f09SDavid van Moolenbroek 				;
1573*00b67f09SDavid van Moolenbroek 			else
1574*00b67f09SDavid van Moolenbroek 				INSIST(0);
1575*00b67f09SDavid van Moolenbroek 		}
1576*00b67f09SDavid van Moolenbroek 
1577*00b67f09SDavid van Moolenbroek 		obj = NULL;
1578*00b67f09SDavid van Moolenbroek 		result = ns_config_get(maps, "serial-update-method", &obj);
1579*00b67f09SDavid van Moolenbroek 		INSIST(result == ISC_R_SUCCESS && obj != NULL);
1580*00b67f09SDavid van Moolenbroek 		if (strcasecmp(cfg_obj_asstring(obj), "unixtime") == 0)
1581*00b67f09SDavid van Moolenbroek 			dns_zone_setserialupdatemethod(zone,
1582*00b67f09SDavid van Moolenbroek 						    dns_updatemethod_unixtime);
1583*00b67f09SDavid van Moolenbroek 		else
1584*00b67f09SDavid van Moolenbroek 			dns_zone_setserialupdatemethod(zone,
1585*00b67f09SDavid van Moolenbroek 						  dns_updatemethod_increment);
1586*00b67f09SDavid van Moolenbroek 	}
1587*00b67f09SDavid van Moolenbroek 
1588*00b67f09SDavid van Moolenbroek 	/*
1589*00b67f09SDavid van Moolenbroek 	 * Configure slave functionality.
1590*00b67f09SDavid van Moolenbroek 	 */
1591*00b67f09SDavid van Moolenbroek 	switch (ztype) {
1592*00b67f09SDavid van Moolenbroek 	case dns_zone_slave:
1593*00b67f09SDavid van Moolenbroek 	case dns_zone_stub:
1594*00b67f09SDavid van Moolenbroek 	case dns_zone_redirect:
1595*00b67f09SDavid van Moolenbroek 		count = 0;
1596*00b67f09SDavid van Moolenbroek 		obj = NULL;
1597*00b67f09SDavid van Moolenbroek 		(void)cfg_map_get(zoptions, "masters", &obj);
1598*00b67f09SDavid van Moolenbroek 		if (obj != NULL) {
1599*00b67f09SDavid van Moolenbroek 			addrs = NULL;
1600*00b67f09SDavid van Moolenbroek 			dscps = NULL;
1601*00b67f09SDavid van Moolenbroek 			keynames = NULL;
1602*00b67f09SDavid van Moolenbroek 			RETERR(ns_config_getipandkeylist(config, obj, mctx,
1603*00b67f09SDavid van Moolenbroek 							 &addrs, &dscps,
1604*00b67f09SDavid van Moolenbroek 							 &keynames, &count));
1605*00b67f09SDavid van Moolenbroek 			result = dns_zone_setmasterswithkeys(mayberaw, addrs,
1606*00b67f09SDavid van Moolenbroek 							     keynames, count);
1607*00b67f09SDavid van Moolenbroek 			if (count != 0)
1608*00b67f09SDavid van Moolenbroek 				ns_config_putipandkeylist(mctx, &addrs, &dscps,
1609*00b67f09SDavid van Moolenbroek 							  &keynames, count);
1610*00b67f09SDavid van Moolenbroek 			else
1611*00b67f09SDavid van Moolenbroek 				INSIST(addrs == NULL && keynames == NULL);
1612*00b67f09SDavid van Moolenbroek 		} else
1613*00b67f09SDavid van Moolenbroek 			result = dns_zone_setmasters(mayberaw, NULL, 0);
1614*00b67f09SDavid van Moolenbroek 		RETERR(result);
1615*00b67f09SDavid van Moolenbroek 
1616*00b67f09SDavid van Moolenbroek 		multi = ISC_FALSE;
1617*00b67f09SDavid van Moolenbroek 		if (count > 1) {
1618*00b67f09SDavid van Moolenbroek 			obj = NULL;
1619*00b67f09SDavid van Moolenbroek 			result = ns_config_get(maps, "multi-master", &obj);
1620*00b67f09SDavid van Moolenbroek 			INSIST(result == ISC_R_SUCCESS && obj != NULL);
1621*00b67f09SDavid van Moolenbroek 			multi = cfg_obj_asboolean(obj);
1622*00b67f09SDavid van Moolenbroek 		}
1623*00b67f09SDavid van Moolenbroek 		dns_zone_setoption(mayberaw, DNS_ZONEOPT_MULTIMASTER, multi);
1624*00b67f09SDavid van Moolenbroek 
1625*00b67f09SDavid van Moolenbroek 		obj = NULL;
1626*00b67f09SDavid van Moolenbroek 		result = ns_config_get(maps, "max-transfer-time-in", &obj);
1627*00b67f09SDavid van Moolenbroek 		INSIST(result == ISC_R_SUCCESS && obj != NULL);
1628*00b67f09SDavid van Moolenbroek 		dns_zone_setmaxxfrin(mayberaw, cfg_obj_asuint32(obj) * 60);
1629*00b67f09SDavid van Moolenbroek 
1630*00b67f09SDavid van Moolenbroek 		obj = NULL;
1631*00b67f09SDavid van Moolenbroek 		result = ns_config_get(maps, "max-transfer-idle-in", &obj);
1632*00b67f09SDavid van Moolenbroek 		INSIST(result == ISC_R_SUCCESS && obj != NULL);
1633*00b67f09SDavid van Moolenbroek 		dns_zone_setidlein(mayberaw, cfg_obj_asuint32(obj) * 60);
1634*00b67f09SDavid van Moolenbroek 
1635*00b67f09SDavid van Moolenbroek 		obj = NULL;
1636*00b67f09SDavid van Moolenbroek 		result = ns_config_get(maps, "max-refresh-time", &obj);
1637*00b67f09SDavid van Moolenbroek 		INSIST(result == ISC_R_SUCCESS && obj != NULL);
1638*00b67f09SDavid van Moolenbroek 		dns_zone_setmaxrefreshtime(mayberaw, cfg_obj_asuint32(obj));
1639*00b67f09SDavid van Moolenbroek 
1640*00b67f09SDavid van Moolenbroek 		obj = NULL;
1641*00b67f09SDavid van Moolenbroek 		result = ns_config_get(maps, "min-refresh-time", &obj);
1642*00b67f09SDavid van Moolenbroek 		INSIST(result == ISC_R_SUCCESS && obj != NULL);
1643*00b67f09SDavid van Moolenbroek 		dns_zone_setminrefreshtime(mayberaw, cfg_obj_asuint32(obj));
1644*00b67f09SDavid van Moolenbroek 
1645*00b67f09SDavid van Moolenbroek 		obj = NULL;
1646*00b67f09SDavid van Moolenbroek 		result = ns_config_get(maps, "max-retry-time", &obj);
1647*00b67f09SDavid van Moolenbroek 		INSIST(result == ISC_R_SUCCESS && obj != NULL);
1648*00b67f09SDavid van Moolenbroek 		dns_zone_setmaxretrytime(mayberaw, cfg_obj_asuint32(obj));
1649*00b67f09SDavid van Moolenbroek 
1650*00b67f09SDavid van Moolenbroek 		obj = NULL;
1651*00b67f09SDavid van Moolenbroek 		result = ns_config_get(maps, "min-retry-time", &obj);
1652*00b67f09SDavid van Moolenbroek 		INSIST(result == ISC_R_SUCCESS && obj != NULL);
1653*00b67f09SDavid van Moolenbroek 		dns_zone_setminretrytime(mayberaw, cfg_obj_asuint32(obj));
1654*00b67f09SDavid van Moolenbroek 
1655*00b67f09SDavid van Moolenbroek 		obj = NULL;
1656*00b67f09SDavid van Moolenbroek 		result = ns_config_get(maps, "transfer-source", &obj);
1657*00b67f09SDavid van Moolenbroek 		INSIST(result == ISC_R_SUCCESS && obj != NULL);
1658*00b67f09SDavid van Moolenbroek 		RETERR(dns_zone_setxfrsource4(mayberaw,
1659*00b67f09SDavid van Moolenbroek 					      cfg_obj_assockaddr(obj)));
1660*00b67f09SDavid van Moolenbroek 		dscp = cfg_obj_getdscp(obj);
1661*00b67f09SDavid van Moolenbroek 		if (dscp == -1)
1662*00b67f09SDavid van Moolenbroek 			dscp = ns_g_dscp;
1663*00b67f09SDavid van Moolenbroek 		RETERR(dns_zone_setxfrsource4dscp(mayberaw, dscp));
1664*00b67f09SDavid van Moolenbroek 		ns_add_reserved_dispatch(ns_g_server, cfg_obj_assockaddr(obj));
1665*00b67f09SDavid van Moolenbroek 
1666*00b67f09SDavid van Moolenbroek 		obj = NULL;
1667*00b67f09SDavid van Moolenbroek 		result = ns_config_get(maps, "transfer-source-v6", &obj);
1668*00b67f09SDavid van Moolenbroek 		INSIST(result == ISC_R_SUCCESS && obj != NULL);
1669*00b67f09SDavid van Moolenbroek 		RETERR(dns_zone_setxfrsource6(mayberaw,
1670*00b67f09SDavid van Moolenbroek 					      cfg_obj_assockaddr(obj)));
1671*00b67f09SDavid van Moolenbroek 		dscp = cfg_obj_getdscp(obj);
1672*00b67f09SDavid van Moolenbroek 		if (dscp == -1)
1673*00b67f09SDavid van Moolenbroek 			dscp = ns_g_dscp;
1674*00b67f09SDavid van Moolenbroek 		RETERR(dns_zone_setxfrsource6dscp(mayberaw, dscp));
1675*00b67f09SDavid van Moolenbroek 		ns_add_reserved_dispatch(ns_g_server, cfg_obj_assockaddr(obj));
1676*00b67f09SDavid van Moolenbroek 
1677*00b67f09SDavid van Moolenbroek 		obj = NULL;
1678*00b67f09SDavid van Moolenbroek 		result = ns_config_get(maps, "alt-transfer-source", &obj);
1679*00b67f09SDavid van Moolenbroek 		INSIST(result == ISC_R_SUCCESS && obj != NULL);
1680*00b67f09SDavid van Moolenbroek 		RETERR(dns_zone_setaltxfrsource4(mayberaw,
1681*00b67f09SDavid van Moolenbroek 						 cfg_obj_assockaddr(obj)));
1682*00b67f09SDavid van Moolenbroek 		dscp = cfg_obj_getdscp(obj);
1683*00b67f09SDavid van Moolenbroek 		if (dscp == -1)
1684*00b67f09SDavid van Moolenbroek 			dscp = ns_g_dscp;
1685*00b67f09SDavid van Moolenbroek 		RETERR(dns_zone_setaltxfrsource4dscp(mayberaw, dscp));
1686*00b67f09SDavid van Moolenbroek 
1687*00b67f09SDavid van Moolenbroek 		obj = NULL;
1688*00b67f09SDavid van Moolenbroek 		result = ns_config_get(maps, "alt-transfer-source-v6", &obj);
1689*00b67f09SDavid van Moolenbroek 		INSIST(result == ISC_R_SUCCESS && obj != NULL);
1690*00b67f09SDavid van Moolenbroek 		RETERR(dns_zone_setaltxfrsource6(mayberaw,
1691*00b67f09SDavid van Moolenbroek 						 cfg_obj_assockaddr(obj)));
1692*00b67f09SDavid van Moolenbroek 		dscp = cfg_obj_getdscp(obj);
1693*00b67f09SDavid van Moolenbroek 		if (dscp == -1)
1694*00b67f09SDavid van Moolenbroek 			dscp = ns_g_dscp;
1695*00b67f09SDavid van Moolenbroek 		RETERR(dns_zone_setaltxfrsource6dscp(mayberaw, dscp));
1696*00b67f09SDavid van Moolenbroek 
1697*00b67f09SDavid van Moolenbroek 		obj = NULL;
1698*00b67f09SDavid van Moolenbroek 		(void)ns_config_get(maps, "use-alt-transfer-source", &obj);
1699*00b67f09SDavid van Moolenbroek 		if (obj == NULL) {
1700*00b67f09SDavid van Moolenbroek 			/*
1701*00b67f09SDavid van Moolenbroek 			 * Default off when views are in use otherwise
1702*00b67f09SDavid van Moolenbroek 			 * on for BIND 8 compatibility.
1703*00b67f09SDavid van Moolenbroek 			 */
1704*00b67f09SDavid van Moolenbroek 			view = dns_zone_getview(zone);
1705*00b67f09SDavid van Moolenbroek 			if (view != NULL && strcmp(view->name, "_default") == 0)
1706*00b67f09SDavid van Moolenbroek 				alt = ISC_TRUE;
1707*00b67f09SDavid van Moolenbroek 			else
1708*00b67f09SDavid van Moolenbroek 				alt = ISC_FALSE;
1709*00b67f09SDavid van Moolenbroek 		} else
1710*00b67f09SDavid van Moolenbroek 			alt = cfg_obj_asboolean(obj);
1711*00b67f09SDavid van Moolenbroek 		dns_zone_setoption(mayberaw, DNS_ZONEOPT_USEALTXFRSRC, alt);
1712*00b67f09SDavid van Moolenbroek 
1713*00b67f09SDavid van Moolenbroek 		obj = NULL;
1714*00b67f09SDavid van Moolenbroek 		(void)ns_config_get(maps, "try-tcp-refresh", &obj);
1715*00b67f09SDavid van Moolenbroek 		dns_zone_setoption(mayberaw, DNS_ZONEOPT_TRYTCPREFRESH,
1716*00b67f09SDavid van Moolenbroek 				   cfg_obj_asboolean(obj));
1717*00b67f09SDavid van Moolenbroek 		break;
1718*00b67f09SDavid van Moolenbroek 
1719*00b67f09SDavid van Moolenbroek 	case dns_zone_staticstub:
1720*00b67f09SDavid van Moolenbroek 		RETERR(configure_staticstub(zoptions, zone, zname,
1721*00b67f09SDavid van Moolenbroek 					    default_dbtype));
1722*00b67f09SDavid van Moolenbroek 		break;
1723*00b67f09SDavid van Moolenbroek 
1724*00b67f09SDavid van Moolenbroek 	default:
1725*00b67f09SDavid van Moolenbroek 		break;
1726*00b67f09SDavid van Moolenbroek 	}
1727*00b67f09SDavid van Moolenbroek 
1728*00b67f09SDavid van Moolenbroek 	return (ISC_R_SUCCESS);
1729*00b67f09SDavid van Moolenbroek }
1730*00b67f09SDavid van Moolenbroek 
1731*00b67f09SDavid van Moolenbroek 
1732*00b67f09SDavid van Moolenbroek /*
1733*00b67f09SDavid van Moolenbroek  * Set up a DLZ zone as writeable
1734*00b67f09SDavid van Moolenbroek  */
1735*00b67f09SDavid van Moolenbroek isc_result_t
ns_zone_configure_writeable_dlz(dns_dlzdb_t * dlzdatabase,dns_zone_t * zone,dns_rdataclass_t rdclass,dns_name_t * name)1736*00b67f09SDavid van Moolenbroek ns_zone_configure_writeable_dlz(dns_dlzdb_t *dlzdatabase, dns_zone_t *zone,
1737*00b67f09SDavid van Moolenbroek 				dns_rdataclass_t rdclass, dns_name_t *name)
1738*00b67f09SDavid van Moolenbroek {
1739*00b67f09SDavid van Moolenbroek 	dns_db_t *db = NULL;
1740*00b67f09SDavid van Moolenbroek 	isc_time_t now;
1741*00b67f09SDavid van Moolenbroek 	isc_result_t result;
1742*00b67f09SDavid van Moolenbroek 
1743*00b67f09SDavid van Moolenbroek 	TIME_NOW(&now);
1744*00b67f09SDavid van Moolenbroek 
1745*00b67f09SDavid van Moolenbroek 	dns_zone_settype(zone, dns_zone_dlz);
1746*00b67f09SDavid van Moolenbroek 	result = dns_sdlz_setdb(dlzdatabase, rdclass, name, &db);
1747*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS)
1748*00b67f09SDavid van Moolenbroek 		return (result);
1749*00b67f09SDavid van Moolenbroek 	result = dns_zone_dlzpostload(zone, db);
1750*00b67f09SDavid van Moolenbroek 	dns_db_detach(&db);
1751*00b67f09SDavid van Moolenbroek 	return (result);
1752*00b67f09SDavid van Moolenbroek }
1753*00b67f09SDavid van Moolenbroek 
1754*00b67f09SDavid van Moolenbroek isc_boolean_t
ns_zone_reusable(dns_zone_t * zone,const cfg_obj_t * zconfig)1755*00b67f09SDavid van Moolenbroek ns_zone_reusable(dns_zone_t *zone, const cfg_obj_t *zconfig) {
1756*00b67f09SDavid van Moolenbroek 	const cfg_obj_t *zoptions = NULL;
1757*00b67f09SDavid van Moolenbroek 	const cfg_obj_t *obj = NULL;
1758*00b67f09SDavid van Moolenbroek 	const char *cfilename;
1759*00b67f09SDavid van Moolenbroek 	const char *zfilename;
1760*00b67f09SDavid van Moolenbroek 	dns_zone_t *raw = NULL;
1761*00b67f09SDavid van Moolenbroek 	isc_boolean_t has_raw;
1762*00b67f09SDavid van Moolenbroek 	dns_zonetype_t ztype;
1763*00b67f09SDavid van Moolenbroek 
1764*00b67f09SDavid van Moolenbroek 	zoptions = cfg_tuple_get(zconfig, "options");
1765*00b67f09SDavid van Moolenbroek 
1766*00b67f09SDavid van Moolenbroek 	/*
1767*00b67f09SDavid van Moolenbroek 	 * We always reconfigure a static-stub zone for simplicity, assuming
1768*00b67f09SDavid van Moolenbroek 	 * the amount of data to be loaded is small.
1769*00b67f09SDavid van Moolenbroek 	 */
1770*00b67f09SDavid van Moolenbroek 	if (zonetype_fromconfig(zoptions) == dns_zone_staticstub) {
1771*00b67f09SDavid van Moolenbroek 		dns_zone_log(zone, ISC_LOG_DEBUG(1),
1772*00b67f09SDavid van Moolenbroek 			     "not reusable: staticstub");
1773*00b67f09SDavid van Moolenbroek 		return (ISC_FALSE);
1774*00b67f09SDavid van Moolenbroek 	}
1775*00b67f09SDavid van Moolenbroek 
1776*00b67f09SDavid van Moolenbroek 	/* If there's a raw zone, use that for filename and type comparison */
1777*00b67f09SDavid van Moolenbroek 	dns_zone_getraw(zone, &raw);
1778*00b67f09SDavid van Moolenbroek 	if (raw != NULL) {
1779*00b67f09SDavid van Moolenbroek 		zfilename = dns_zone_getfile(raw);
1780*00b67f09SDavid van Moolenbroek 		ztype = dns_zone_gettype(raw);
1781*00b67f09SDavid van Moolenbroek 		dns_zone_detach(&raw);
1782*00b67f09SDavid van Moolenbroek 		has_raw = ISC_TRUE;
1783*00b67f09SDavid van Moolenbroek 	} else {
1784*00b67f09SDavid van Moolenbroek 		zfilename = dns_zone_getfile(zone);
1785*00b67f09SDavid van Moolenbroek 		ztype = dns_zone_gettype(zone);
1786*00b67f09SDavid van Moolenbroek 		has_raw = ISC_FALSE;
1787*00b67f09SDavid van Moolenbroek 	}
1788*00b67f09SDavid van Moolenbroek 
1789*00b67f09SDavid van Moolenbroek 	obj = NULL;
1790*00b67f09SDavid van Moolenbroek 	(void)cfg_map_get(zoptions, "inline-signing", &obj);
1791*00b67f09SDavid van Moolenbroek 	if ((obj == NULL || !cfg_obj_asboolean(obj)) && has_raw) {
1792*00b67f09SDavid van Moolenbroek 		dns_zone_log(zone, ISC_LOG_DEBUG(1),
1793*00b67f09SDavid van Moolenbroek 			     "not reusable: old zone was inline-signing");
1794*00b67f09SDavid van Moolenbroek 		return (ISC_FALSE);
1795*00b67f09SDavid van Moolenbroek 	} else if ((obj != NULL && cfg_obj_asboolean(obj)) && !has_raw) {
1796*00b67f09SDavid van Moolenbroek 		dns_zone_log(zone, ISC_LOG_DEBUG(1),
1797*00b67f09SDavid van Moolenbroek 			     "not reusable: old zone was not inline-signing");
1798*00b67f09SDavid van Moolenbroek 		return (ISC_FALSE);
1799*00b67f09SDavid van Moolenbroek 	}
1800*00b67f09SDavid van Moolenbroek 
1801*00b67f09SDavid van Moolenbroek 	if (zonetype_fromconfig(zoptions) != ztype) {
1802*00b67f09SDavid van Moolenbroek 		dns_zone_log(zone, ISC_LOG_DEBUG(1),
1803*00b67f09SDavid van Moolenbroek 			     "not reusable: type mismatch");
1804*00b67f09SDavid van Moolenbroek 		return (ISC_FALSE);
1805*00b67f09SDavid van Moolenbroek 	}
1806*00b67f09SDavid van Moolenbroek 
1807*00b67f09SDavid van Moolenbroek 	obj = NULL;
1808*00b67f09SDavid van Moolenbroek 	(void)cfg_map_get(zoptions, "file", &obj);
1809*00b67f09SDavid van Moolenbroek 	if (obj != NULL)
1810*00b67f09SDavid van Moolenbroek 		cfilename = cfg_obj_asstring(obj);
1811*00b67f09SDavid van Moolenbroek 	else
1812*00b67f09SDavid van Moolenbroek 		cfilename = NULL;
1813*00b67f09SDavid van Moolenbroek 	if (!((cfilename == NULL && zfilename == NULL) ||
1814*00b67f09SDavid van Moolenbroek 	      (cfilename != NULL && zfilename != NULL &&
1815*00b67f09SDavid van Moolenbroek 	       strcmp(cfilename, zfilename) == 0)))
1816*00b67f09SDavid van Moolenbroek 	{
1817*00b67f09SDavid van Moolenbroek 		dns_zone_log(zone, ISC_LOG_DEBUG(1),
1818*00b67f09SDavid van Moolenbroek 			     "not reusable: filename mismatch");
1819*00b67f09SDavid van Moolenbroek 		return (ISC_FALSE);
1820*00b67f09SDavid van Moolenbroek 	}
1821*00b67f09SDavid van Moolenbroek 
1822*00b67f09SDavid van Moolenbroek 	return (ISC_TRUE);
1823*00b67f09SDavid van Moolenbroek }
1824