1*00b67f09SDavid van Moolenbroek /* $NetBSD: check.c,v 1.12 2015/07/08 17:28:58 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) 2001-2003 Internet Software Consortium.
6*00b67f09SDavid van Moolenbroek *
7*00b67f09SDavid van Moolenbroek * Permission to use, copy, modify, and/or distribute this software for any
8*00b67f09SDavid van Moolenbroek * purpose with or without fee is hereby granted, provided that the above
9*00b67f09SDavid van Moolenbroek * copyright notice and this permission notice appear in all copies.
10*00b67f09SDavid van Moolenbroek *
11*00b67f09SDavid van Moolenbroek * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12*00b67f09SDavid van Moolenbroek * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13*00b67f09SDavid van Moolenbroek * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14*00b67f09SDavid van Moolenbroek * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15*00b67f09SDavid van Moolenbroek * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16*00b67f09SDavid van Moolenbroek * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17*00b67f09SDavid van Moolenbroek * PERFORMANCE OF THIS SOFTWARE.
18*00b67f09SDavid van Moolenbroek */
19*00b67f09SDavid van Moolenbroek
20*00b67f09SDavid van Moolenbroek /*! \file */
21*00b67f09SDavid van Moolenbroek
22*00b67f09SDavid van Moolenbroek #include <config.h>
23*00b67f09SDavid van Moolenbroek
24*00b67f09SDavid van Moolenbroek #include <stdlib.h>
25*00b67f09SDavid van Moolenbroek
26*00b67f09SDavid van Moolenbroek #include <isc/base64.h>
27*00b67f09SDavid van Moolenbroek #include <isc/buffer.h>
28*00b67f09SDavid van Moolenbroek #include <isc/file.h>
29*00b67f09SDavid van Moolenbroek #include <isc/hex.h>
30*00b67f09SDavid van Moolenbroek #include <isc/log.h>
31*00b67f09SDavid van Moolenbroek #include <isc/mem.h>
32*00b67f09SDavid van Moolenbroek #include <isc/netaddr.h>
33*00b67f09SDavid van Moolenbroek #include <isc/parseint.h>
34*00b67f09SDavid van Moolenbroek #include <isc/platform.h>
35*00b67f09SDavid van Moolenbroek #include <isc/region.h>
36*00b67f09SDavid van Moolenbroek #include <isc/result.h>
37*00b67f09SDavid van Moolenbroek #include <isc/sockaddr.h>
38*00b67f09SDavid van Moolenbroek #include <isc/string.h>
39*00b67f09SDavid van Moolenbroek #include <isc/symtab.h>
40*00b67f09SDavid van Moolenbroek #include <isc/util.h>
41*00b67f09SDavid van Moolenbroek
42*00b67f09SDavid van Moolenbroek #ifdef ISC_PLATFORM_USESIT
43*00b67f09SDavid van Moolenbroek #ifdef AES_SIT
44*00b67f09SDavid van Moolenbroek #include <isc/aes.h>
45*00b67f09SDavid van Moolenbroek #endif
46*00b67f09SDavid van Moolenbroek #ifdef HMAC_SHA1_SIT
47*00b67f09SDavid van Moolenbroek #include <isc/sha1.h>
48*00b67f09SDavid van Moolenbroek #endif
49*00b67f09SDavid van Moolenbroek #ifdef HMAC_SHA256_SIT
50*00b67f09SDavid van Moolenbroek #include <isc/sha2.h>
51*00b67f09SDavid van Moolenbroek #endif
52*00b67f09SDavid van Moolenbroek #endif
53*00b67f09SDavid van Moolenbroek
54*00b67f09SDavid van Moolenbroek #include <dns/acl.h>
55*00b67f09SDavid van Moolenbroek #include <dns/fixedname.h>
56*00b67f09SDavid van Moolenbroek #include <dns/rdataclass.h>
57*00b67f09SDavid van Moolenbroek #include <dns/rdatatype.h>
58*00b67f09SDavid van Moolenbroek #include <dns/secalg.h>
59*00b67f09SDavid van Moolenbroek
60*00b67f09SDavid van Moolenbroek #include <dst/dst.h>
61*00b67f09SDavid van Moolenbroek
62*00b67f09SDavid van Moolenbroek #include <isccfg/aclconf.h>
63*00b67f09SDavid van Moolenbroek #include <isccfg/cfg.h>
64*00b67f09SDavid van Moolenbroek
65*00b67f09SDavid van Moolenbroek #include <bind9/check.h>
66*00b67f09SDavid van Moolenbroek
67*00b67f09SDavid van Moolenbroek static isc_result_t
68*00b67f09SDavid van Moolenbroek fileexist(const cfg_obj_t *obj, isc_symtab_t *symtab, isc_boolean_t writeable,
69*00b67f09SDavid van Moolenbroek isc_log_t *logctxlogc);
70*00b67f09SDavid van Moolenbroek
71*00b67f09SDavid van Moolenbroek static void
freekey(char * key,unsigned int type,isc_symvalue_t value,void * userarg)72*00b67f09SDavid van Moolenbroek freekey(char *key, unsigned int type, isc_symvalue_t value, void *userarg) {
73*00b67f09SDavid van Moolenbroek UNUSED(type);
74*00b67f09SDavid van Moolenbroek UNUSED(value);
75*00b67f09SDavid van Moolenbroek isc_mem_free(userarg, key);
76*00b67f09SDavid van Moolenbroek }
77*00b67f09SDavid van Moolenbroek
78*00b67f09SDavid van Moolenbroek static isc_result_t
check_orderent(const cfg_obj_t * ent,isc_log_t * logctx)79*00b67f09SDavid van Moolenbroek check_orderent(const cfg_obj_t *ent, isc_log_t *logctx) {
80*00b67f09SDavid van Moolenbroek isc_result_t result = ISC_R_SUCCESS;
81*00b67f09SDavid van Moolenbroek isc_result_t tresult;
82*00b67f09SDavid van Moolenbroek isc_textregion_t r;
83*00b67f09SDavid van Moolenbroek dns_fixedname_t fixed;
84*00b67f09SDavid van Moolenbroek const cfg_obj_t *obj;
85*00b67f09SDavid van Moolenbroek dns_rdataclass_t rdclass;
86*00b67f09SDavid van Moolenbroek dns_rdatatype_t rdtype;
87*00b67f09SDavid van Moolenbroek isc_buffer_t b;
88*00b67f09SDavid van Moolenbroek const char *str;
89*00b67f09SDavid van Moolenbroek
90*00b67f09SDavid van Moolenbroek dns_fixedname_init(&fixed);
91*00b67f09SDavid van Moolenbroek obj = cfg_tuple_get(ent, "class");
92*00b67f09SDavid van Moolenbroek if (cfg_obj_isstring(obj)) {
93*00b67f09SDavid van Moolenbroek
94*00b67f09SDavid van Moolenbroek DE_CONST(cfg_obj_asstring(obj), r.base);
95*00b67f09SDavid van Moolenbroek r.length = strlen(r.base);
96*00b67f09SDavid van Moolenbroek tresult = dns_rdataclass_fromtext(&rdclass, &r);
97*00b67f09SDavid van Moolenbroek if (tresult != ISC_R_SUCCESS) {
98*00b67f09SDavid van Moolenbroek cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
99*00b67f09SDavid van Moolenbroek "rrset-order: invalid class '%s'",
100*00b67f09SDavid van Moolenbroek r.base);
101*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
102*00b67f09SDavid van Moolenbroek }
103*00b67f09SDavid van Moolenbroek }
104*00b67f09SDavid van Moolenbroek
105*00b67f09SDavid van Moolenbroek obj = cfg_tuple_get(ent, "type");
106*00b67f09SDavid van Moolenbroek if (cfg_obj_isstring(obj)) {
107*00b67f09SDavid van Moolenbroek DE_CONST(cfg_obj_asstring(obj), r.base);
108*00b67f09SDavid van Moolenbroek r.length = strlen(r.base);
109*00b67f09SDavid van Moolenbroek tresult = dns_rdatatype_fromtext(&rdtype, &r);
110*00b67f09SDavid van Moolenbroek if (tresult != ISC_R_SUCCESS) {
111*00b67f09SDavid van Moolenbroek cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
112*00b67f09SDavid van Moolenbroek "rrset-order: invalid type '%s'",
113*00b67f09SDavid van Moolenbroek r.base);
114*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
115*00b67f09SDavid van Moolenbroek }
116*00b67f09SDavid van Moolenbroek }
117*00b67f09SDavid van Moolenbroek
118*00b67f09SDavid van Moolenbroek obj = cfg_tuple_get(ent, "name");
119*00b67f09SDavid van Moolenbroek if (cfg_obj_isstring(obj)) {
120*00b67f09SDavid van Moolenbroek str = cfg_obj_asstring(obj);
121*00b67f09SDavid van Moolenbroek isc_buffer_constinit(&b, str, strlen(str));
122*00b67f09SDavid van Moolenbroek isc_buffer_add(&b, strlen(str));
123*00b67f09SDavid van Moolenbroek tresult = dns_name_fromtext(dns_fixedname_name(&fixed), &b,
124*00b67f09SDavid van Moolenbroek dns_rootname, 0, NULL);
125*00b67f09SDavid van Moolenbroek if (tresult != ISC_R_SUCCESS) {
126*00b67f09SDavid van Moolenbroek cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
127*00b67f09SDavid van Moolenbroek "rrset-order: invalid name '%s'", str);
128*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
129*00b67f09SDavid van Moolenbroek }
130*00b67f09SDavid van Moolenbroek }
131*00b67f09SDavid van Moolenbroek
132*00b67f09SDavid van Moolenbroek obj = cfg_tuple_get(ent, "order");
133*00b67f09SDavid van Moolenbroek if (!cfg_obj_isstring(obj) ||
134*00b67f09SDavid van Moolenbroek strcasecmp("order", cfg_obj_asstring(obj)) != 0) {
135*00b67f09SDavid van Moolenbroek cfg_obj_log(ent, logctx, ISC_LOG_ERROR,
136*00b67f09SDavid van Moolenbroek "rrset-order: keyword 'order' missing");
137*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
138*00b67f09SDavid van Moolenbroek }
139*00b67f09SDavid van Moolenbroek
140*00b67f09SDavid van Moolenbroek obj = cfg_tuple_get(ent, "ordering");
141*00b67f09SDavid van Moolenbroek if (!cfg_obj_isstring(obj)) {
142*00b67f09SDavid van Moolenbroek cfg_obj_log(ent, logctx, ISC_LOG_ERROR,
143*00b67f09SDavid van Moolenbroek "rrset-order: missing ordering");
144*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
145*00b67f09SDavid van Moolenbroek } else if (strcasecmp(cfg_obj_asstring(obj), "fixed") == 0) {
146*00b67f09SDavid van Moolenbroek #if !DNS_RDATASET_FIXED
147*00b67f09SDavid van Moolenbroek cfg_obj_log(obj, logctx, ISC_LOG_WARNING,
148*00b67f09SDavid van Moolenbroek "rrset-order: order 'fixed' was disabled at "
149*00b67f09SDavid van Moolenbroek "compilation time");
150*00b67f09SDavid van Moolenbroek #endif
151*00b67f09SDavid van Moolenbroek } else if (strcasecmp(cfg_obj_asstring(obj), "random") != 0 &&
152*00b67f09SDavid van Moolenbroek strcasecmp(cfg_obj_asstring(obj), "cyclic") != 0) {
153*00b67f09SDavid van Moolenbroek cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
154*00b67f09SDavid van Moolenbroek "rrset-order: invalid order '%s'",
155*00b67f09SDavid van Moolenbroek cfg_obj_asstring(obj));
156*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
157*00b67f09SDavid van Moolenbroek }
158*00b67f09SDavid van Moolenbroek return (result);
159*00b67f09SDavid van Moolenbroek }
160*00b67f09SDavid van Moolenbroek
161*00b67f09SDavid van Moolenbroek static isc_result_t
check_order(const cfg_obj_t * options,isc_log_t * logctx)162*00b67f09SDavid van Moolenbroek check_order(const cfg_obj_t *options, isc_log_t *logctx) {
163*00b67f09SDavid van Moolenbroek isc_result_t result = ISC_R_SUCCESS;
164*00b67f09SDavid van Moolenbroek isc_result_t tresult;
165*00b67f09SDavid van Moolenbroek const cfg_listelt_t *element;
166*00b67f09SDavid van Moolenbroek const cfg_obj_t *obj = NULL;
167*00b67f09SDavid van Moolenbroek
168*00b67f09SDavid van Moolenbroek if (cfg_map_get(options, "rrset-order", &obj) != ISC_R_SUCCESS)
169*00b67f09SDavid van Moolenbroek return (result);
170*00b67f09SDavid van Moolenbroek
171*00b67f09SDavid van Moolenbroek for (element = cfg_list_first(obj);
172*00b67f09SDavid van Moolenbroek element != NULL;
173*00b67f09SDavid van Moolenbroek element = cfg_list_next(element))
174*00b67f09SDavid van Moolenbroek {
175*00b67f09SDavid van Moolenbroek tresult = check_orderent(cfg_listelt_value(element), logctx);
176*00b67f09SDavid van Moolenbroek if (tresult != ISC_R_SUCCESS)
177*00b67f09SDavid van Moolenbroek result = tresult;
178*00b67f09SDavid van Moolenbroek }
179*00b67f09SDavid van Moolenbroek return (result);
180*00b67f09SDavid van Moolenbroek }
181*00b67f09SDavid van Moolenbroek
182*00b67f09SDavid van Moolenbroek static isc_result_t
check_dual_stack(const cfg_obj_t * options,isc_log_t * logctx)183*00b67f09SDavid van Moolenbroek check_dual_stack(const cfg_obj_t *options, isc_log_t *logctx) {
184*00b67f09SDavid van Moolenbroek const cfg_listelt_t *element;
185*00b67f09SDavid van Moolenbroek const cfg_obj_t *alternates = NULL;
186*00b67f09SDavid van Moolenbroek const cfg_obj_t *value;
187*00b67f09SDavid van Moolenbroek const cfg_obj_t *obj;
188*00b67f09SDavid van Moolenbroek const char *str;
189*00b67f09SDavid van Moolenbroek dns_fixedname_t fixed;
190*00b67f09SDavid van Moolenbroek dns_name_t *name;
191*00b67f09SDavid van Moolenbroek isc_buffer_t buffer;
192*00b67f09SDavid van Moolenbroek isc_result_t result = ISC_R_SUCCESS;
193*00b67f09SDavid van Moolenbroek isc_result_t tresult;
194*00b67f09SDavid van Moolenbroek
195*00b67f09SDavid van Moolenbroek (void)cfg_map_get(options, "dual-stack-servers", &alternates);
196*00b67f09SDavid van Moolenbroek
197*00b67f09SDavid van Moolenbroek if (alternates == NULL)
198*00b67f09SDavid van Moolenbroek return (ISC_R_SUCCESS);
199*00b67f09SDavid van Moolenbroek
200*00b67f09SDavid van Moolenbroek obj = cfg_tuple_get(alternates, "port");
201*00b67f09SDavid van Moolenbroek if (cfg_obj_isuint32(obj)) {
202*00b67f09SDavid van Moolenbroek isc_uint32_t val = cfg_obj_asuint32(obj);
203*00b67f09SDavid van Moolenbroek if (val > ISC_UINT16_MAX) {
204*00b67f09SDavid van Moolenbroek cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
205*00b67f09SDavid van Moolenbroek "port '%u' out of range", val);
206*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
207*00b67f09SDavid van Moolenbroek }
208*00b67f09SDavid van Moolenbroek }
209*00b67f09SDavid van Moolenbroek obj = cfg_tuple_get(alternates, "addresses");
210*00b67f09SDavid van Moolenbroek for (element = cfg_list_first(obj);
211*00b67f09SDavid van Moolenbroek element != NULL;
212*00b67f09SDavid van Moolenbroek element = cfg_list_next(element)) {
213*00b67f09SDavid van Moolenbroek value = cfg_listelt_value(element);
214*00b67f09SDavid van Moolenbroek if (cfg_obj_issockaddr(value))
215*00b67f09SDavid van Moolenbroek continue;
216*00b67f09SDavid van Moolenbroek obj = cfg_tuple_get(value, "name");
217*00b67f09SDavid van Moolenbroek str = cfg_obj_asstring(obj);
218*00b67f09SDavid van Moolenbroek isc_buffer_constinit(&buffer, str, strlen(str));
219*00b67f09SDavid van Moolenbroek isc_buffer_add(&buffer, strlen(str));
220*00b67f09SDavid van Moolenbroek dns_fixedname_init(&fixed);
221*00b67f09SDavid van Moolenbroek name = dns_fixedname_name(&fixed);
222*00b67f09SDavid van Moolenbroek tresult = dns_name_fromtext(name, &buffer, dns_rootname,
223*00b67f09SDavid van Moolenbroek 0, NULL);
224*00b67f09SDavid van Moolenbroek if (tresult != ISC_R_SUCCESS) {
225*00b67f09SDavid van Moolenbroek cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
226*00b67f09SDavid van Moolenbroek "bad name '%s'", str);
227*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
228*00b67f09SDavid van Moolenbroek }
229*00b67f09SDavid van Moolenbroek obj = cfg_tuple_get(value, "port");
230*00b67f09SDavid van Moolenbroek if (cfg_obj_isuint32(obj)) {
231*00b67f09SDavid van Moolenbroek isc_uint32_t val = cfg_obj_asuint32(obj);
232*00b67f09SDavid van Moolenbroek if (val > ISC_UINT16_MAX) {
233*00b67f09SDavid van Moolenbroek cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
234*00b67f09SDavid van Moolenbroek "port '%u' out of range", val);
235*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
236*00b67f09SDavid van Moolenbroek }
237*00b67f09SDavid van Moolenbroek }
238*00b67f09SDavid van Moolenbroek }
239*00b67f09SDavid van Moolenbroek return (result);
240*00b67f09SDavid van Moolenbroek }
241*00b67f09SDavid van Moolenbroek
242*00b67f09SDavid van Moolenbroek static isc_result_t
check_forward(const cfg_obj_t * options,const cfg_obj_t * global,isc_log_t * logctx)243*00b67f09SDavid van Moolenbroek check_forward(const cfg_obj_t *options, const cfg_obj_t *global,
244*00b67f09SDavid van Moolenbroek isc_log_t *logctx)
245*00b67f09SDavid van Moolenbroek {
246*00b67f09SDavid van Moolenbroek const cfg_obj_t *forward = NULL;
247*00b67f09SDavid van Moolenbroek const cfg_obj_t *forwarders = NULL;
248*00b67f09SDavid van Moolenbroek
249*00b67f09SDavid van Moolenbroek (void)cfg_map_get(options, "forward", &forward);
250*00b67f09SDavid van Moolenbroek (void)cfg_map_get(options, "forwarders", &forwarders);
251*00b67f09SDavid van Moolenbroek
252*00b67f09SDavid van Moolenbroek if (forwarders != NULL && global != NULL) {
253*00b67f09SDavid van Moolenbroek const char *file = cfg_obj_file(global);
254*00b67f09SDavid van Moolenbroek unsigned int line = cfg_obj_line(global);
255*00b67f09SDavid van Moolenbroek cfg_obj_log(forwarders, logctx, ISC_LOG_ERROR,
256*00b67f09SDavid van Moolenbroek "forwarders declared in root zone and "
257*00b67f09SDavid van Moolenbroek "in general configuration: %s:%u",
258*00b67f09SDavid van Moolenbroek file, line);
259*00b67f09SDavid van Moolenbroek return (ISC_R_FAILURE);
260*00b67f09SDavid van Moolenbroek }
261*00b67f09SDavid van Moolenbroek if (forward != NULL && forwarders == NULL) {
262*00b67f09SDavid van Moolenbroek cfg_obj_log(forward, logctx, ISC_LOG_ERROR,
263*00b67f09SDavid van Moolenbroek "no matching 'forwarders' statement");
264*00b67f09SDavid van Moolenbroek return (ISC_R_FAILURE);
265*00b67f09SDavid van Moolenbroek }
266*00b67f09SDavid van Moolenbroek return (ISC_R_SUCCESS);
267*00b67f09SDavid van Moolenbroek }
268*00b67f09SDavid van Moolenbroek
269*00b67f09SDavid van Moolenbroek static isc_result_t
disabled_algorithms(const cfg_obj_t * disabled,isc_log_t * logctx)270*00b67f09SDavid van Moolenbroek disabled_algorithms(const cfg_obj_t *disabled, isc_log_t *logctx) {
271*00b67f09SDavid van Moolenbroek isc_result_t result = ISC_R_SUCCESS;
272*00b67f09SDavid van Moolenbroek isc_result_t tresult;
273*00b67f09SDavid van Moolenbroek const cfg_listelt_t *element;
274*00b67f09SDavid van Moolenbroek const char *str;
275*00b67f09SDavid van Moolenbroek isc_buffer_t b;
276*00b67f09SDavid van Moolenbroek dns_fixedname_t fixed;
277*00b67f09SDavid van Moolenbroek dns_name_t *name;
278*00b67f09SDavid van Moolenbroek const cfg_obj_t *obj;
279*00b67f09SDavid van Moolenbroek
280*00b67f09SDavid van Moolenbroek dns_fixedname_init(&fixed);
281*00b67f09SDavid van Moolenbroek name = dns_fixedname_name(&fixed);
282*00b67f09SDavid van Moolenbroek obj = cfg_tuple_get(disabled, "name");
283*00b67f09SDavid van Moolenbroek str = cfg_obj_asstring(obj);
284*00b67f09SDavid van Moolenbroek isc_buffer_constinit(&b, str, strlen(str));
285*00b67f09SDavid van Moolenbroek isc_buffer_add(&b, strlen(str));
286*00b67f09SDavid van Moolenbroek tresult = dns_name_fromtext(name, &b, dns_rootname, 0, NULL);
287*00b67f09SDavid van Moolenbroek if (tresult != ISC_R_SUCCESS) {
288*00b67f09SDavid van Moolenbroek cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
289*00b67f09SDavid van Moolenbroek "bad domain name '%s'", str);
290*00b67f09SDavid van Moolenbroek result = tresult;
291*00b67f09SDavid van Moolenbroek }
292*00b67f09SDavid van Moolenbroek
293*00b67f09SDavid van Moolenbroek obj = cfg_tuple_get(disabled, "algorithms");
294*00b67f09SDavid van Moolenbroek
295*00b67f09SDavid van Moolenbroek for (element = cfg_list_first(obj);
296*00b67f09SDavid van Moolenbroek element != NULL;
297*00b67f09SDavid van Moolenbroek element = cfg_list_next(element))
298*00b67f09SDavid van Moolenbroek {
299*00b67f09SDavid van Moolenbroek isc_textregion_t r;
300*00b67f09SDavid van Moolenbroek dns_secalg_t alg;
301*00b67f09SDavid van Moolenbroek
302*00b67f09SDavid van Moolenbroek DE_CONST(cfg_obj_asstring(cfg_listelt_value(element)), r.base);
303*00b67f09SDavid van Moolenbroek r.length = strlen(r.base);
304*00b67f09SDavid van Moolenbroek
305*00b67f09SDavid van Moolenbroek tresult = dns_secalg_fromtext(&alg, &r);
306*00b67f09SDavid van Moolenbroek if (tresult != ISC_R_SUCCESS) {
307*00b67f09SDavid van Moolenbroek cfg_obj_log(cfg_listelt_value(element), logctx,
308*00b67f09SDavid van Moolenbroek ISC_LOG_ERROR, "invalid algorithm '%s'",
309*00b67f09SDavid van Moolenbroek r.base);
310*00b67f09SDavid van Moolenbroek result = tresult;
311*00b67f09SDavid van Moolenbroek }
312*00b67f09SDavid van Moolenbroek }
313*00b67f09SDavid van Moolenbroek return (result);
314*00b67f09SDavid van Moolenbroek }
315*00b67f09SDavid van Moolenbroek
316*00b67f09SDavid van Moolenbroek static isc_result_t
disabled_ds_digests(const cfg_obj_t * disabled,isc_log_t * logctx)317*00b67f09SDavid van Moolenbroek disabled_ds_digests(const cfg_obj_t *disabled, isc_log_t *logctx) {
318*00b67f09SDavid van Moolenbroek isc_result_t result = ISC_R_SUCCESS;
319*00b67f09SDavid van Moolenbroek isc_result_t tresult;
320*00b67f09SDavid van Moolenbroek const cfg_listelt_t *element;
321*00b67f09SDavid van Moolenbroek const char *str;
322*00b67f09SDavid van Moolenbroek isc_buffer_t b;
323*00b67f09SDavid van Moolenbroek dns_fixedname_t fixed;
324*00b67f09SDavid van Moolenbroek dns_name_t *name;
325*00b67f09SDavid van Moolenbroek const cfg_obj_t *obj;
326*00b67f09SDavid van Moolenbroek
327*00b67f09SDavid van Moolenbroek dns_fixedname_init(&fixed);
328*00b67f09SDavid van Moolenbroek name = dns_fixedname_name(&fixed);
329*00b67f09SDavid van Moolenbroek obj = cfg_tuple_get(disabled, "name");
330*00b67f09SDavid van Moolenbroek str = cfg_obj_asstring(obj);
331*00b67f09SDavid van Moolenbroek isc_buffer_constinit(&b, str, strlen(str));
332*00b67f09SDavid van Moolenbroek isc_buffer_add(&b, strlen(str));
333*00b67f09SDavid van Moolenbroek tresult = dns_name_fromtext(name, &b, dns_rootname, 0, NULL);
334*00b67f09SDavid van Moolenbroek if (tresult != ISC_R_SUCCESS) {
335*00b67f09SDavid van Moolenbroek cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
336*00b67f09SDavid van Moolenbroek "bad domain name '%s'", str);
337*00b67f09SDavid van Moolenbroek result = tresult;
338*00b67f09SDavid van Moolenbroek }
339*00b67f09SDavid van Moolenbroek
340*00b67f09SDavid van Moolenbroek obj = cfg_tuple_get(disabled, "digests");
341*00b67f09SDavid van Moolenbroek
342*00b67f09SDavid van Moolenbroek for (element = cfg_list_first(obj);
343*00b67f09SDavid van Moolenbroek element != NULL;
344*00b67f09SDavid van Moolenbroek element = cfg_list_next(element))
345*00b67f09SDavid van Moolenbroek {
346*00b67f09SDavid van Moolenbroek isc_textregion_t r;
347*00b67f09SDavid van Moolenbroek dns_dsdigest_t digest;
348*00b67f09SDavid van Moolenbroek
349*00b67f09SDavid van Moolenbroek DE_CONST(cfg_obj_asstring(cfg_listelt_value(element)), r.base);
350*00b67f09SDavid van Moolenbroek r.length = strlen(r.base);
351*00b67f09SDavid van Moolenbroek
352*00b67f09SDavid van Moolenbroek /* works with a numeric argument too */
353*00b67f09SDavid van Moolenbroek tresult = dns_dsdigest_fromtext(&digest, &r);
354*00b67f09SDavid van Moolenbroek if (tresult != ISC_R_SUCCESS) {
355*00b67f09SDavid van Moolenbroek cfg_obj_log(cfg_listelt_value(element), logctx,
356*00b67f09SDavid van Moolenbroek ISC_LOG_ERROR, "invalid digest type '%s'",
357*00b67f09SDavid van Moolenbroek r.base);
358*00b67f09SDavid van Moolenbroek result = tresult;
359*00b67f09SDavid van Moolenbroek }
360*00b67f09SDavid van Moolenbroek }
361*00b67f09SDavid van Moolenbroek return (result);
362*00b67f09SDavid van Moolenbroek }
363*00b67f09SDavid van Moolenbroek
364*00b67f09SDavid van Moolenbroek static isc_result_t
nameexist(const cfg_obj_t * obj,const char * name,int value,isc_symtab_t * symtab,const char * fmt,isc_log_t * logctx,isc_mem_t * mctx)365*00b67f09SDavid van Moolenbroek nameexist(const cfg_obj_t *obj, const char *name, int value,
366*00b67f09SDavid van Moolenbroek isc_symtab_t *symtab, const char *fmt, isc_log_t *logctx,
367*00b67f09SDavid van Moolenbroek isc_mem_t *mctx)
368*00b67f09SDavid van Moolenbroek {
369*00b67f09SDavid van Moolenbroek char *key;
370*00b67f09SDavid van Moolenbroek const char *file;
371*00b67f09SDavid van Moolenbroek unsigned int line;
372*00b67f09SDavid van Moolenbroek isc_result_t result;
373*00b67f09SDavid van Moolenbroek isc_symvalue_t symvalue;
374*00b67f09SDavid van Moolenbroek
375*00b67f09SDavid van Moolenbroek key = isc_mem_strdup(mctx, name);
376*00b67f09SDavid van Moolenbroek if (key == NULL)
377*00b67f09SDavid van Moolenbroek return (ISC_R_NOMEMORY);
378*00b67f09SDavid van Moolenbroek symvalue.as_cpointer = obj;
379*00b67f09SDavid van Moolenbroek result = isc_symtab_define(symtab, key, value, symvalue,
380*00b67f09SDavid van Moolenbroek isc_symexists_reject);
381*00b67f09SDavid van Moolenbroek if (result == ISC_R_EXISTS) {
382*00b67f09SDavid van Moolenbroek RUNTIME_CHECK(isc_symtab_lookup(symtab, key, value,
383*00b67f09SDavid van Moolenbroek &symvalue) == ISC_R_SUCCESS);
384*00b67f09SDavid van Moolenbroek file = cfg_obj_file(symvalue.as_cpointer);
385*00b67f09SDavid van Moolenbroek line = cfg_obj_line(symvalue.as_cpointer);
386*00b67f09SDavid van Moolenbroek
387*00b67f09SDavid van Moolenbroek if (file == NULL)
388*00b67f09SDavid van Moolenbroek file = "<unknown file>";
389*00b67f09SDavid van Moolenbroek cfg_obj_log(obj, logctx, ISC_LOG_ERROR, fmt, key, file, line);
390*00b67f09SDavid van Moolenbroek isc_mem_free(mctx, key);
391*00b67f09SDavid van Moolenbroek result = ISC_R_EXISTS;
392*00b67f09SDavid van Moolenbroek } else if (result != ISC_R_SUCCESS) {
393*00b67f09SDavid van Moolenbroek isc_mem_free(mctx, key);
394*00b67f09SDavid van Moolenbroek }
395*00b67f09SDavid van Moolenbroek return (result);
396*00b67f09SDavid van Moolenbroek }
397*00b67f09SDavid van Moolenbroek
398*00b67f09SDavid van Moolenbroek static isc_result_t
mustbesecure(const cfg_obj_t * secure,isc_symtab_t * symtab,isc_log_t * logctx,isc_mem_t * mctx)399*00b67f09SDavid van Moolenbroek mustbesecure(const cfg_obj_t *secure, isc_symtab_t *symtab, isc_log_t *logctx,
400*00b67f09SDavid van Moolenbroek isc_mem_t *mctx)
401*00b67f09SDavid van Moolenbroek {
402*00b67f09SDavid van Moolenbroek const cfg_obj_t *obj;
403*00b67f09SDavid van Moolenbroek char namebuf[DNS_NAME_FORMATSIZE];
404*00b67f09SDavid van Moolenbroek const char *str;
405*00b67f09SDavid van Moolenbroek dns_fixedname_t fixed;
406*00b67f09SDavid van Moolenbroek dns_name_t *name;
407*00b67f09SDavid van Moolenbroek isc_buffer_t b;
408*00b67f09SDavid van Moolenbroek isc_result_t result = ISC_R_SUCCESS;
409*00b67f09SDavid van Moolenbroek
410*00b67f09SDavid van Moolenbroek dns_fixedname_init(&fixed);
411*00b67f09SDavid van Moolenbroek name = dns_fixedname_name(&fixed);
412*00b67f09SDavid van Moolenbroek obj = cfg_tuple_get(secure, "name");
413*00b67f09SDavid van Moolenbroek str = cfg_obj_asstring(obj);
414*00b67f09SDavid van Moolenbroek isc_buffer_constinit(&b, str, strlen(str));
415*00b67f09SDavid van Moolenbroek isc_buffer_add(&b, strlen(str));
416*00b67f09SDavid van Moolenbroek result = dns_name_fromtext(name, &b, dns_rootname, 0, NULL);
417*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS) {
418*00b67f09SDavid van Moolenbroek cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
419*00b67f09SDavid van Moolenbroek "bad domain name '%s'", str);
420*00b67f09SDavid van Moolenbroek } else {
421*00b67f09SDavid van Moolenbroek dns_name_format(name, namebuf, sizeof(namebuf));
422*00b67f09SDavid van Moolenbroek result = nameexist(secure, namebuf, 1, symtab,
423*00b67f09SDavid van Moolenbroek "dnssec-must-be-secure '%s': already "
424*00b67f09SDavid van Moolenbroek "exists previous definition: %s:%u",
425*00b67f09SDavid van Moolenbroek logctx, mctx);
426*00b67f09SDavid van Moolenbroek }
427*00b67f09SDavid van Moolenbroek return (result);
428*00b67f09SDavid van Moolenbroek }
429*00b67f09SDavid van Moolenbroek
430*00b67f09SDavid van Moolenbroek static isc_result_t
checkacl(const char * aclname,cfg_aclconfctx_t * actx,const cfg_obj_t * zconfig,const cfg_obj_t * voptions,const cfg_obj_t * config,isc_log_t * logctx,isc_mem_t * mctx)431*00b67f09SDavid van Moolenbroek checkacl(const char *aclname, cfg_aclconfctx_t *actx, const cfg_obj_t *zconfig,
432*00b67f09SDavid van Moolenbroek const cfg_obj_t *voptions, const cfg_obj_t *config,
433*00b67f09SDavid van Moolenbroek isc_log_t *logctx, isc_mem_t *mctx)
434*00b67f09SDavid van Moolenbroek {
435*00b67f09SDavid van Moolenbroek isc_result_t result;
436*00b67f09SDavid van Moolenbroek const cfg_obj_t *aclobj = NULL;
437*00b67f09SDavid van Moolenbroek const cfg_obj_t *options;
438*00b67f09SDavid van Moolenbroek dns_acl_t *acl = NULL;
439*00b67f09SDavid van Moolenbroek
440*00b67f09SDavid van Moolenbroek if (zconfig != NULL) {
441*00b67f09SDavid van Moolenbroek options = cfg_tuple_get(zconfig, "options");
442*00b67f09SDavid van Moolenbroek cfg_map_get(options, aclname, &aclobj);
443*00b67f09SDavid van Moolenbroek }
444*00b67f09SDavid van Moolenbroek if (voptions != NULL && aclobj == NULL)
445*00b67f09SDavid van Moolenbroek cfg_map_get(voptions, aclname, &aclobj);
446*00b67f09SDavid van Moolenbroek if (config != NULL && aclobj == NULL) {
447*00b67f09SDavid van Moolenbroek options = NULL;
448*00b67f09SDavid van Moolenbroek cfg_map_get(config, "options", &options);
449*00b67f09SDavid van Moolenbroek if (options != NULL)
450*00b67f09SDavid van Moolenbroek cfg_map_get(options, aclname, &aclobj);
451*00b67f09SDavid van Moolenbroek }
452*00b67f09SDavid van Moolenbroek if (aclobj == NULL)
453*00b67f09SDavid van Moolenbroek return (ISC_R_SUCCESS);
454*00b67f09SDavid van Moolenbroek result = cfg_acl_fromconfig(aclobj, config, logctx,
455*00b67f09SDavid van Moolenbroek actx, mctx, 0, &acl);
456*00b67f09SDavid van Moolenbroek if (acl != NULL)
457*00b67f09SDavid van Moolenbroek dns_acl_detach(&acl);
458*00b67f09SDavid van Moolenbroek return (result);
459*00b67f09SDavid van Moolenbroek }
460*00b67f09SDavid van Moolenbroek
461*00b67f09SDavid van Moolenbroek static isc_result_t
check_viewacls(cfg_aclconfctx_t * actx,const cfg_obj_t * voptions,const cfg_obj_t * config,isc_log_t * logctx,isc_mem_t * mctx)462*00b67f09SDavid van Moolenbroek check_viewacls(cfg_aclconfctx_t *actx, const cfg_obj_t *voptions,
463*00b67f09SDavid van Moolenbroek const cfg_obj_t *config, isc_log_t *logctx, isc_mem_t *mctx)
464*00b67f09SDavid van Moolenbroek {
465*00b67f09SDavid van Moolenbroek isc_result_t result = ISC_R_SUCCESS, tresult;
466*00b67f09SDavid van Moolenbroek int i = 0;
467*00b67f09SDavid van Moolenbroek
468*00b67f09SDavid van Moolenbroek static const char *acls[] = { "allow-query", "allow-query-on",
469*00b67f09SDavid van Moolenbroek "allow-query-cache", "allow-query-cache-on",
470*00b67f09SDavid van Moolenbroek "blackhole", "match-clients", "match-destinations",
471*00b67f09SDavid van Moolenbroek "sortlist", "filter-aaaa", NULL };
472*00b67f09SDavid van Moolenbroek
473*00b67f09SDavid van Moolenbroek while (acls[i] != NULL) {
474*00b67f09SDavid van Moolenbroek tresult = checkacl(acls[i++], actx, NULL, voptions, config,
475*00b67f09SDavid van Moolenbroek logctx, mctx);
476*00b67f09SDavid van Moolenbroek if (tresult != ISC_R_SUCCESS)
477*00b67f09SDavid van Moolenbroek result = tresult;
478*00b67f09SDavid van Moolenbroek }
479*00b67f09SDavid van Moolenbroek return (result);
480*00b67f09SDavid van Moolenbroek }
481*00b67f09SDavid van Moolenbroek
482*00b67f09SDavid van Moolenbroek static const unsigned char zeros[16];
483*00b67f09SDavid van Moolenbroek
484*00b67f09SDavid van Moolenbroek static isc_result_t
check_dns64(cfg_aclconfctx_t * actx,const cfg_obj_t * voptions,const cfg_obj_t * config,isc_log_t * logctx,isc_mem_t * mctx)485*00b67f09SDavid van Moolenbroek check_dns64(cfg_aclconfctx_t *actx, const cfg_obj_t *voptions,
486*00b67f09SDavid van Moolenbroek const cfg_obj_t *config, isc_log_t *logctx, isc_mem_t *mctx)
487*00b67f09SDavid van Moolenbroek {
488*00b67f09SDavid van Moolenbroek isc_result_t result = ISC_R_SUCCESS;
489*00b67f09SDavid van Moolenbroek const cfg_obj_t *dns64 = NULL;
490*00b67f09SDavid van Moolenbroek const cfg_obj_t *options;
491*00b67f09SDavid van Moolenbroek const cfg_listelt_t *element;
492*00b67f09SDavid van Moolenbroek const cfg_obj_t *map, *obj;
493*00b67f09SDavid van Moolenbroek isc_netaddr_t na, sa;
494*00b67f09SDavid van Moolenbroek unsigned int prefixlen;
495*00b67f09SDavid van Moolenbroek int nbytes;
496*00b67f09SDavid van Moolenbroek int i;
497*00b67f09SDavid van Moolenbroek
498*00b67f09SDavid van Moolenbroek static const char *acls[] = { "clients", "exclude", "mapped", NULL};
499*00b67f09SDavid van Moolenbroek
500*00b67f09SDavid van Moolenbroek if (voptions != NULL)
501*00b67f09SDavid van Moolenbroek cfg_map_get(voptions, "dns64", &dns64);
502*00b67f09SDavid van Moolenbroek if (config != NULL && dns64 == NULL) {
503*00b67f09SDavid van Moolenbroek options = NULL;
504*00b67f09SDavid van Moolenbroek cfg_map_get(config, "options", &options);
505*00b67f09SDavid van Moolenbroek if (options != NULL)
506*00b67f09SDavid van Moolenbroek cfg_map_get(options, "dns64", &dns64);
507*00b67f09SDavid van Moolenbroek }
508*00b67f09SDavid van Moolenbroek if (dns64 == NULL)
509*00b67f09SDavid van Moolenbroek return (ISC_R_SUCCESS);
510*00b67f09SDavid van Moolenbroek
511*00b67f09SDavid van Moolenbroek for (element = cfg_list_first(dns64);
512*00b67f09SDavid van Moolenbroek element != NULL;
513*00b67f09SDavid van Moolenbroek element = cfg_list_next(element))
514*00b67f09SDavid van Moolenbroek {
515*00b67f09SDavid van Moolenbroek map = cfg_listelt_value(element);
516*00b67f09SDavid van Moolenbroek obj = cfg_map_getname(map);
517*00b67f09SDavid van Moolenbroek
518*00b67f09SDavid van Moolenbroek cfg_obj_asnetprefix(obj, &na, &prefixlen);
519*00b67f09SDavid van Moolenbroek if (na.family != AF_INET6) {
520*00b67f09SDavid van Moolenbroek cfg_obj_log(map, logctx, ISC_LOG_ERROR,
521*00b67f09SDavid van Moolenbroek "dns64 requires a IPv6 prefix");
522*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
523*00b67f09SDavid van Moolenbroek continue;
524*00b67f09SDavid van Moolenbroek }
525*00b67f09SDavid van Moolenbroek
526*00b67f09SDavid van Moolenbroek if (prefixlen != 32 && prefixlen != 40 && prefixlen != 48 &&
527*00b67f09SDavid van Moolenbroek prefixlen != 56 && prefixlen != 64 && prefixlen != 96) {
528*00b67f09SDavid van Moolenbroek cfg_obj_log(map, logctx, ISC_LOG_ERROR,
529*00b67f09SDavid van Moolenbroek "bad prefix length %u [32/40/48/56/64/96]",
530*00b67f09SDavid van Moolenbroek prefixlen);
531*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
532*00b67f09SDavid van Moolenbroek continue;
533*00b67f09SDavid van Moolenbroek }
534*00b67f09SDavid van Moolenbroek
535*00b67f09SDavid van Moolenbroek for (i = 0; acls[i] != NULL; i++) {
536*00b67f09SDavid van Moolenbroek obj = NULL;
537*00b67f09SDavid van Moolenbroek (void)cfg_map_get(map, acls[i], &obj);
538*00b67f09SDavid van Moolenbroek if (obj != NULL) {
539*00b67f09SDavid van Moolenbroek dns_acl_t *acl = NULL;
540*00b67f09SDavid van Moolenbroek isc_result_t tresult;
541*00b67f09SDavid van Moolenbroek
542*00b67f09SDavid van Moolenbroek tresult = cfg_acl_fromconfig(obj, config,
543*00b67f09SDavid van Moolenbroek logctx, actx,
544*00b67f09SDavid van Moolenbroek mctx, 0, &acl);
545*00b67f09SDavid van Moolenbroek if (acl != NULL)
546*00b67f09SDavid van Moolenbroek dns_acl_detach(&acl);
547*00b67f09SDavid van Moolenbroek if (tresult != ISC_R_SUCCESS)
548*00b67f09SDavid van Moolenbroek result = tresult;
549*00b67f09SDavid van Moolenbroek }
550*00b67f09SDavid van Moolenbroek }
551*00b67f09SDavid van Moolenbroek
552*00b67f09SDavid van Moolenbroek obj = NULL;
553*00b67f09SDavid van Moolenbroek (void)cfg_map_get(map, "suffix", &obj);
554*00b67f09SDavid van Moolenbroek if (obj != NULL) {
555*00b67f09SDavid van Moolenbroek isc_netaddr_fromsockaddr(&sa, cfg_obj_assockaddr(obj));
556*00b67f09SDavid van Moolenbroek if (sa.family != AF_INET6) {
557*00b67f09SDavid van Moolenbroek cfg_obj_log(map, logctx, ISC_LOG_ERROR,
558*00b67f09SDavid van Moolenbroek "dns64 requires a IPv6 suffix");
559*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
560*00b67f09SDavid van Moolenbroek continue;
561*00b67f09SDavid van Moolenbroek }
562*00b67f09SDavid van Moolenbroek nbytes = prefixlen / 8 + 4;
563*00b67f09SDavid van Moolenbroek if (prefixlen >= 32 && prefixlen <= 64)
564*00b67f09SDavid van Moolenbroek nbytes++;
565*00b67f09SDavid van Moolenbroek if (memcmp(sa.type.in6.s6_addr, zeros, nbytes) != 0) {
566*00b67f09SDavid van Moolenbroek char netaddrbuf[ISC_NETADDR_FORMATSIZE];
567*00b67f09SDavid van Moolenbroek isc_netaddr_format(&sa, netaddrbuf,
568*00b67f09SDavid van Moolenbroek sizeof(netaddrbuf));
569*00b67f09SDavid van Moolenbroek cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
570*00b67f09SDavid van Moolenbroek "bad suffix '%s' leading "
571*00b67f09SDavid van Moolenbroek "%u octets not zeros",
572*00b67f09SDavid van Moolenbroek netaddrbuf, nbytes);
573*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
574*00b67f09SDavid van Moolenbroek }
575*00b67f09SDavid van Moolenbroek }
576*00b67f09SDavid van Moolenbroek }
577*00b67f09SDavid van Moolenbroek
578*00b67f09SDavid van Moolenbroek return (result);
579*00b67f09SDavid van Moolenbroek }
580*00b67f09SDavid van Moolenbroek
581*00b67f09SDavid van Moolenbroek
582*00b67f09SDavid van Moolenbroek /*
583*00b67f09SDavid van Moolenbroek * Check allow-recursion and allow-recursion-on acls, and also log a
584*00b67f09SDavid van Moolenbroek * warning if they're inconsistent with the "recursion" option.
585*00b67f09SDavid van Moolenbroek */
586*00b67f09SDavid van Moolenbroek static isc_result_t
check_recursionacls(cfg_aclconfctx_t * actx,const cfg_obj_t * voptions,const char * viewname,const cfg_obj_t * config,isc_log_t * logctx,isc_mem_t * mctx)587*00b67f09SDavid van Moolenbroek check_recursionacls(cfg_aclconfctx_t *actx, const cfg_obj_t *voptions,
588*00b67f09SDavid van Moolenbroek const char *viewname, const cfg_obj_t *config,
589*00b67f09SDavid van Moolenbroek isc_log_t *logctx, isc_mem_t *mctx)
590*00b67f09SDavid van Moolenbroek {
591*00b67f09SDavid van Moolenbroek const cfg_obj_t *options, *aclobj, *obj = NULL;
592*00b67f09SDavid van Moolenbroek dns_acl_t *acl = NULL;
593*00b67f09SDavid van Moolenbroek isc_result_t result = ISC_R_SUCCESS, tresult;
594*00b67f09SDavid van Moolenbroek isc_boolean_t recursion;
595*00b67f09SDavid van Moolenbroek const char *forview = " for view ";
596*00b67f09SDavid van Moolenbroek int i = 0;
597*00b67f09SDavid van Moolenbroek
598*00b67f09SDavid van Moolenbroek static const char *acls[] = { "allow-recursion", "allow-recursion-on",
599*00b67f09SDavid van Moolenbroek NULL };
600*00b67f09SDavid van Moolenbroek
601*00b67f09SDavid van Moolenbroek if (voptions != NULL)
602*00b67f09SDavid van Moolenbroek cfg_map_get(voptions, "recursion", &obj);
603*00b67f09SDavid van Moolenbroek if (obj == NULL && config != NULL) {
604*00b67f09SDavid van Moolenbroek options = NULL;
605*00b67f09SDavid van Moolenbroek cfg_map_get(config, "options", &options);
606*00b67f09SDavid van Moolenbroek if (options != NULL)
607*00b67f09SDavid van Moolenbroek cfg_map_get(options, "recursion", &obj);
608*00b67f09SDavid van Moolenbroek }
609*00b67f09SDavid van Moolenbroek if (obj == NULL)
610*00b67f09SDavid van Moolenbroek recursion = ISC_TRUE;
611*00b67f09SDavid van Moolenbroek else
612*00b67f09SDavid van Moolenbroek recursion = cfg_obj_asboolean(obj);
613*00b67f09SDavid van Moolenbroek
614*00b67f09SDavid van Moolenbroek if (viewname == NULL) {
615*00b67f09SDavid van Moolenbroek viewname = "";
616*00b67f09SDavid van Moolenbroek forview = "";
617*00b67f09SDavid van Moolenbroek }
618*00b67f09SDavid van Moolenbroek
619*00b67f09SDavid van Moolenbroek for (i = 0; acls[i] != NULL; i++) {
620*00b67f09SDavid van Moolenbroek aclobj = options = NULL;
621*00b67f09SDavid van Moolenbroek acl = NULL;
622*00b67f09SDavid van Moolenbroek
623*00b67f09SDavid van Moolenbroek if (voptions != NULL)
624*00b67f09SDavid van Moolenbroek cfg_map_get(voptions, acls[i], &aclobj);
625*00b67f09SDavid van Moolenbroek if (config != NULL && aclobj == NULL) {
626*00b67f09SDavid van Moolenbroek options = NULL;
627*00b67f09SDavid van Moolenbroek cfg_map_get(config, "options", &options);
628*00b67f09SDavid van Moolenbroek if (options != NULL)
629*00b67f09SDavid van Moolenbroek cfg_map_get(options, acls[i], &aclobj);
630*00b67f09SDavid van Moolenbroek }
631*00b67f09SDavid van Moolenbroek if (aclobj == NULL)
632*00b67f09SDavid van Moolenbroek continue;
633*00b67f09SDavid van Moolenbroek
634*00b67f09SDavid van Moolenbroek tresult = cfg_acl_fromconfig(aclobj, config, logctx,
635*00b67f09SDavid van Moolenbroek actx, mctx, 0, &acl);
636*00b67f09SDavid van Moolenbroek
637*00b67f09SDavid van Moolenbroek if (tresult != ISC_R_SUCCESS)
638*00b67f09SDavid van Moolenbroek result = tresult;
639*00b67f09SDavid van Moolenbroek
640*00b67f09SDavid van Moolenbroek if (acl == NULL)
641*00b67f09SDavid van Moolenbroek continue;
642*00b67f09SDavid van Moolenbroek
643*00b67f09SDavid van Moolenbroek if (recursion == ISC_FALSE && !dns_acl_isnone(acl)) {
644*00b67f09SDavid van Moolenbroek cfg_obj_log(aclobj, logctx, ISC_LOG_WARNING,
645*00b67f09SDavid van Moolenbroek "both \"recursion no;\" and "
646*00b67f09SDavid van Moolenbroek "\"%s\" active%s%s",
647*00b67f09SDavid van Moolenbroek acls[i], forview, viewname);
648*00b67f09SDavid van Moolenbroek }
649*00b67f09SDavid van Moolenbroek
650*00b67f09SDavid van Moolenbroek if (acl != NULL)
651*00b67f09SDavid van Moolenbroek dns_acl_detach(&acl);
652*00b67f09SDavid van Moolenbroek }
653*00b67f09SDavid van Moolenbroek
654*00b67f09SDavid van Moolenbroek return (result);
655*00b67f09SDavid van Moolenbroek }
656*00b67f09SDavid van Moolenbroek
657*00b67f09SDavid van Moolenbroek static isc_result_t
check_filteraaaa(cfg_aclconfctx_t * actx,const cfg_obj_t * voptions,const char * viewname,const cfg_obj_t * config,isc_log_t * logctx,isc_mem_t * mctx)658*00b67f09SDavid van Moolenbroek check_filteraaaa(cfg_aclconfctx_t *actx, const cfg_obj_t *voptions,
659*00b67f09SDavid van Moolenbroek const char *viewname, const cfg_obj_t *config,
660*00b67f09SDavid van Moolenbroek isc_log_t *logctx, isc_mem_t *mctx)
661*00b67f09SDavid van Moolenbroek {
662*00b67f09SDavid van Moolenbroek const cfg_obj_t *options, *aclobj, *obj;
663*00b67f09SDavid van Moolenbroek dns_acl_t *acl = NULL;
664*00b67f09SDavid van Moolenbroek isc_result_t result = ISC_R_SUCCESS;
665*00b67f09SDavid van Moolenbroek dns_aaaa_t filter4, filter6;
666*00b67f09SDavid van Moolenbroek const char *forview = " for view ";
667*00b67f09SDavid van Moolenbroek
668*00b67f09SDavid van Moolenbroek if (viewname == NULL) {
669*00b67f09SDavid van Moolenbroek viewname = "";
670*00b67f09SDavid van Moolenbroek forview = "";
671*00b67f09SDavid van Moolenbroek }
672*00b67f09SDavid van Moolenbroek
673*00b67f09SDavid van Moolenbroek aclobj = options = NULL;
674*00b67f09SDavid van Moolenbroek acl = NULL;
675*00b67f09SDavid van Moolenbroek
676*00b67f09SDavid van Moolenbroek if (voptions != NULL)
677*00b67f09SDavid van Moolenbroek cfg_map_get(voptions, "filter-aaaa", &aclobj);
678*00b67f09SDavid van Moolenbroek if (config != NULL && aclobj == NULL) {
679*00b67f09SDavid van Moolenbroek options = NULL;
680*00b67f09SDavid van Moolenbroek cfg_map_get(config, "options", &options);
681*00b67f09SDavid van Moolenbroek if (options != NULL)
682*00b67f09SDavid van Moolenbroek cfg_map_get(options, "filter-aaaa", &aclobj);
683*00b67f09SDavid van Moolenbroek }
684*00b67f09SDavid van Moolenbroek if (aclobj == NULL)
685*00b67f09SDavid van Moolenbroek return (result);
686*00b67f09SDavid van Moolenbroek
687*00b67f09SDavid van Moolenbroek result = cfg_acl_fromconfig(aclobj, config, logctx,
688*00b67f09SDavid van Moolenbroek actx, mctx, 0, &acl);
689*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
690*00b67f09SDavid van Moolenbroek goto failure;
691*00b67f09SDavid van Moolenbroek
692*00b67f09SDavid van Moolenbroek obj = NULL;
693*00b67f09SDavid van Moolenbroek if (voptions != NULL)
694*00b67f09SDavid van Moolenbroek cfg_map_get(voptions, "filter-aaaa-on-v4", &obj);
695*00b67f09SDavid van Moolenbroek if (obj == NULL && config != NULL) {
696*00b67f09SDavid van Moolenbroek options = NULL;
697*00b67f09SDavid van Moolenbroek cfg_map_get(config, "options", &options);
698*00b67f09SDavid van Moolenbroek if (options != NULL)
699*00b67f09SDavid van Moolenbroek cfg_map_get(options, "filter-aaaa-on-v4", &obj);
700*00b67f09SDavid van Moolenbroek }
701*00b67f09SDavid van Moolenbroek
702*00b67f09SDavid van Moolenbroek if (obj == NULL)
703*00b67f09SDavid van Moolenbroek filter4 = dns_aaaa_ok; /* default */
704*00b67f09SDavid van Moolenbroek else if (cfg_obj_isboolean(obj))
705*00b67f09SDavid van Moolenbroek filter4 = cfg_obj_asboolean(obj) ? dns_aaaa_filter :
706*00b67f09SDavid van Moolenbroek dns_aaaa_ok;
707*00b67f09SDavid van Moolenbroek else
708*00b67f09SDavid van Moolenbroek filter4 = dns_aaaa_break_dnssec; /* break-dnssec */
709*00b67f09SDavid van Moolenbroek
710*00b67f09SDavid van Moolenbroek obj = NULL;
711*00b67f09SDavid van Moolenbroek if (voptions != NULL)
712*00b67f09SDavid van Moolenbroek cfg_map_get(voptions, "filter-aaaa-on-v6", &obj);
713*00b67f09SDavid van Moolenbroek if (obj == NULL && config != NULL) {
714*00b67f09SDavid van Moolenbroek options = NULL;
715*00b67f09SDavid van Moolenbroek cfg_map_get(config, "options", &options);
716*00b67f09SDavid van Moolenbroek if (options != NULL)
717*00b67f09SDavid van Moolenbroek cfg_map_get(options, "filter-aaaa-on-v6", &obj);
718*00b67f09SDavid van Moolenbroek }
719*00b67f09SDavid van Moolenbroek
720*00b67f09SDavid van Moolenbroek if (obj == NULL)
721*00b67f09SDavid van Moolenbroek filter6 = dns_aaaa_ok; /* default */
722*00b67f09SDavid van Moolenbroek else if (cfg_obj_isboolean(obj))
723*00b67f09SDavid van Moolenbroek filter6 = cfg_obj_asboolean(obj) ? dns_aaaa_filter :
724*00b67f09SDavid van Moolenbroek dns_aaaa_ok;
725*00b67f09SDavid van Moolenbroek else
726*00b67f09SDavid van Moolenbroek filter6 = dns_aaaa_break_dnssec; /* break-dnssec */
727*00b67f09SDavid van Moolenbroek
728*00b67f09SDavid van Moolenbroek if ((filter4 != dns_aaaa_ok || filter6 != dns_aaaa_ok) &&
729*00b67f09SDavid van Moolenbroek dns_acl_isnone(acl))
730*00b67f09SDavid van Moolenbroek {
731*00b67f09SDavid van Moolenbroek cfg_obj_log(aclobj, logctx, ISC_LOG_WARNING,
732*00b67f09SDavid van Moolenbroek "\"filter-aaaa\" is 'none;' but "
733*00b67f09SDavid van Moolenbroek "either filter-aaaa-on-v4 or filter-aaaa-on-v6 "
734*00b67f09SDavid van Moolenbroek "is enabled%s%s", forview, viewname);
735*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
736*00b67f09SDavid van Moolenbroek } else if (filter4 == dns_aaaa_ok && filter6 == dns_aaaa_ok &&
737*00b67f09SDavid van Moolenbroek !dns_acl_isnone(acl))
738*00b67f09SDavid van Moolenbroek {
739*00b67f09SDavid van Moolenbroek cfg_obj_log(aclobj, logctx, ISC_LOG_WARNING,
740*00b67f09SDavid van Moolenbroek "\"filter-aaaa\" is set but "
741*00b67f09SDavid van Moolenbroek "neither filter-aaaa-on-v4 or filter-aaaa-on-v6 "
742*00b67f09SDavid van Moolenbroek "is enabled%s%s", forview, viewname);
743*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
744*00b67f09SDavid van Moolenbroek }
745*00b67f09SDavid van Moolenbroek
746*00b67f09SDavid van Moolenbroek failure:
747*00b67f09SDavid van Moolenbroek if (acl != NULL)
748*00b67f09SDavid van Moolenbroek dns_acl_detach(&acl);
749*00b67f09SDavid van Moolenbroek
750*00b67f09SDavid van Moolenbroek return (result);
751*00b67f09SDavid van Moolenbroek }
752*00b67f09SDavid van Moolenbroek
753*00b67f09SDavid van Moolenbroek typedef struct {
754*00b67f09SDavid van Moolenbroek const char *name;
755*00b67f09SDavid van Moolenbroek unsigned int scale;
756*00b67f09SDavid van Moolenbroek unsigned int max;
757*00b67f09SDavid van Moolenbroek } intervaltable;
758*00b67f09SDavid van Moolenbroek
759*00b67f09SDavid van Moolenbroek typedef enum {
760*00b67f09SDavid van Moolenbroek optlevel_config,
761*00b67f09SDavid van Moolenbroek optlevel_options,
762*00b67f09SDavid van Moolenbroek optlevel_view,
763*00b67f09SDavid van Moolenbroek optlevel_zone
764*00b67f09SDavid van Moolenbroek } optlevel_t;
765*00b67f09SDavid van Moolenbroek
766*00b67f09SDavid van Moolenbroek static isc_result_t
check_dscp(const cfg_obj_t * options,isc_log_t * logctx)767*00b67f09SDavid van Moolenbroek check_dscp(const cfg_obj_t *options, isc_log_t *logctx) {
768*00b67f09SDavid van Moolenbroek isc_result_t result = ISC_R_SUCCESS;
769*00b67f09SDavid van Moolenbroek const cfg_obj_t *obj = NULL;
770*00b67f09SDavid van Moolenbroek
771*00b67f09SDavid van Moolenbroek /*
772*00b67f09SDavid van Moolenbroek * Check that DSCP setting is within range
773*00b67f09SDavid van Moolenbroek */
774*00b67f09SDavid van Moolenbroek obj = NULL;
775*00b67f09SDavid van Moolenbroek (void)cfg_map_get(options, "dscp", &obj);
776*00b67f09SDavid van Moolenbroek if (obj != NULL) {
777*00b67f09SDavid van Moolenbroek isc_uint32_t dscp = cfg_obj_asuint32(obj);
778*00b67f09SDavid van Moolenbroek if (dscp >= 64) {
779*00b67f09SDavid van Moolenbroek cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
780*00b67f09SDavid van Moolenbroek "'dscp' out of range (0-63)");
781*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
782*00b67f09SDavid van Moolenbroek }
783*00b67f09SDavid van Moolenbroek }
784*00b67f09SDavid van Moolenbroek
785*00b67f09SDavid van Moolenbroek return (result);
786*00b67f09SDavid van Moolenbroek }
787*00b67f09SDavid van Moolenbroek
788*00b67f09SDavid van Moolenbroek static isc_result_t
check_name(const char * str)789*00b67f09SDavid van Moolenbroek check_name(const char *str) {
790*00b67f09SDavid van Moolenbroek dns_fixedname_t fixed;
791*00b67f09SDavid van Moolenbroek
792*00b67f09SDavid van Moolenbroek dns_fixedname_init(&fixed);
793*00b67f09SDavid van Moolenbroek return (dns_name_fromstring(dns_fixedname_name(&fixed), str, 0, NULL));
794*00b67f09SDavid van Moolenbroek }
795*00b67f09SDavid van Moolenbroek
796*00b67f09SDavid van Moolenbroek static isc_result_t
check_options(const cfg_obj_t * options,isc_log_t * logctx,isc_mem_t * mctx,optlevel_t optlevel)797*00b67f09SDavid van Moolenbroek check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx,
798*00b67f09SDavid van Moolenbroek optlevel_t optlevel)
799*00b67f09SDavid van Moolenbroek {
800*00b67f09SDavid van Moolenbroek isc_result_t result = ISC_R_SUCCESS;
801*00b67f09SDavid van Moolenbroek isc_result_t tresult;
802*00b67f09SDavid van Moolenbroek unsigned int i;
803*00b67f09SDavid van Moolenbroek const cfg_obj_t *obj = NULL;
804*00b67f09SDavid van Moolenbroek const cfg_obj_t *resignobj = NULL;
805*00b67f09SDavid van Moolenbroek const cfg_listelt_t *element;
806*00b67f09SDavid van Moolenbroek isc_symtab_t *symtab = NULL;
807*00b67f09SDavid van Moolenbroek dns_fixedname_t fixed;
808*00b67f09SDavid van Moolenbroek const char *str;
809*00b67f09SDavid van Moolenbroek dns_name_t *name;
810*00b67f09SDavid van Moolenbroek #ifdef ISC_PLATFORM_USESIT
811*00b67f09SDavid van Moolenbroek isc_buffer_t b;
812*00b67f09SDavid van Moolenbroek #endif
813*00b67f09SDavid van Moolenbroek
814*00b67f09SDavid van Moolenbroek static intervaltable intervals[] = {
815*00b67f09SDavid van Moolenbroek { "cleaning-interval", 60, 28 * 24 * 60 }, /* 28 days */
816*00b67f09SDavid van Moolenbroek { "heartbeat-interval", 60, 28 * 24 * 60 }, /* 28 days */
817*00b67f09SDavid van Moolenbroek { "interface-interval", 60, 28 * 24 * 60 }, /* 28 days */
818*00b67f09SDavid van Moolenbroek { "max-transfer-idle-in", 60, 28 * 24 * 60 }, /* 28 days */
819*00b67f09SDavid van Moolenbroek { "max-transfer-idle-out", 60, 28 * 24 * 60 }, /* 28 days */
820*00b67f09SDavid van Moolenbroek { "max-transfer-time-in", 60, 28 * 24 * 60 }, /* 28 days */
821*00b67f09SDavid van Moolenbroek { "max-transfer-time-out", 60, 28 * 24 * 60 }, /* 28 days */
822*00b67f09SDavid van Moolenbroek { "statistics-interval", 60, 28 * 24 * 60 }, /* 28 days */
823*00b67f09SDavid van Moolenbroek };
824*00b67f09SDavid van Moolenbroek
825*00b67f09SDavid van Moolenbroek static const char *server_contact[] = {
826*00b67f09SDavid van Moolenbroek "empty-server", "empty-contact",
827*00b67f09SDavid van Moolenbroek "dns64-server", "dns64-contact",
828*00b67f09SDavid van Moolenbroek NULL
829*00b67f09SDavid van Moolenbroek };
830*00b67f09SDavid van Moolenbroek
831*00b67f09SDavid van Moolenbroek /*
832*00b67f09SDavid van Moolenbroek * Check that fields specified in units of time other than seconds
833*00b67f09SDavid van Moolenbroek * have reasonable values.
834*00b67f09SDavid van Moolenbroek */
835*00b67f09SDavid van Moolenbroek for (i = 0; i < sizeof(intervals) / sizeof(intervals[0]); i++) {
836*00b67f09SDavid van Moolenbroek isc_uint32_t val;
837*00b67f09SDavid van Moolenbroek obj = NULL;
838*00b67f09SDavid van Moolenbroek (void)cfg_map_get(options, intervals[i].name, &obj);
839*00b67f09SDavid van Moolenbroek if (obj == NULL)
840*00b67f09SDavid van Moolenbroek continue;
841*00b67f09SDavid van Moolenbroek val = cfg_obj_asuint32(obj);
842*00b67f09SDavid van Moolenbroek if (val > intervals[i].max) {
843*00b67f09SDavid van Moolenbroek cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
844*00b67f09SDavid van Moolenbroek "%s '%u' is out of range (0..%u)",
845*00b67f09SDavid van Moolenbroek intervals[i].name, val,
846*00b67f09SDavid van Moolenbroek intervals[i].max);
847*00b67f09SDavid van Moolenbroek result = ISC_R_RANGE;
848*00b67f09SDavid van Moolenbroek } else if (val > (ISC_UINT32_MAX / intervals[i].scale)) {
849*00b67f09SDavid van Moolenbroek cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
850*00b67f09SDavid van Moolenbroek "%s '%d' is out of range",
851*00b67f09SDavid van Moolenbroek intervals[i].name, val);
852*00b67f09SDavid van Moolenbroek result = ISC_R_RANGE;
853*00b67f09SDavid van Moolenbroek }
854*00b67f09SDavid van Moolenbroek }
855*00b67f09SDavid van Moolenbroek
856*00b67f09SDavid van Moolenbroek obj = NULL;
857*00b67f09SDavid van Moolenbroek cfg_map_get(options, "max-rsa-exponent-size", &obj);
858*00b67f09SDavid van Moolenbroek if (obj != NULL) {
859*00b67f09SDavid van Moolenbroek isc_uint32_t val;
860*00b67f09SDavid van Moolenbroek
861*00b67f09SDavid van Moolenbroek val = cfg_obj_asuint32(obj);
862*00b67f09SDavid van Moolenbroek if (val != 0 && (val < 35 || val > 4096)) {
863*00b67f09SDavid van Moolenbroek cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
864*00b67f09SDavid van Moolenbroek "max-rsa-exponent-size '%u' is out of "
865*00b67f09SDavid van Moolenbroek "range (35..4096)", val);
866*00b67f09SDavid van Moolenbroek result = ISC_R_RANGE;
867*00b67f09SDavid van Moolenbroek }
868*00b67f09SDavid van Moolenbroek }
869*00b67f09SDavid van Moolenbroek
870*00b67f09SDavid van Moolenbroek obj = NULL;
871*00b67f09SDavid van Moolenbroek cfg_map_get(options, "sig-validity-interval", &obj);
872*00b67f09SDavid van Moolenbroek if (obj != NULL) {
873*00b67f09SDavid van Moolenbroek isc_uint32_t validity, resign = 0;
874*00b67f09SDavid van Moolenbroek
875*00b67f09SDavid van Moolenbroek validity = cfg_obj_asuint32(cfg_tuple_get(obj, "validity"));
876*00b67f09SDavid van Moolenbroek resignobj = cfg_tuple_get(obj, "re-sign");
877*00b67f09SDavid van Moolenbroek if (!cfg_obj_isvoid(resignobj))
878*00b67f09SDavid van Moolenbroek resign = cfg_obj_asuint32(resignobj);
879*00b67f09SDavid van Moolenbroek
880*00b67f09SDavid van Moolenbroek if (validity > 3660 || validity == 0) { /* 10 years */
881*00b67f09SDavid van Moolenbroek cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
882*00b67f09SDavid van Moolenbroek "%s '%u' is out of range (1..3660)",
883*00b67f09SDavid van Moolenbroek "sig-validity-interval", validity);
884*00b67f09SDavid van Moolenbroek result = ISC_R_RANGE;
885*00b67f09SDavid van Moolenbroek }
886*00b67f09SDavid van Moolenbroek
887*00b67f09SDavid van Moolenbroek if (!cfg_obj_isvoid(resignobj)) {
888*00b67f09SDavid van Moolenbroek if (resign > 3660 || resign == 0) { /* 10 years */
889*00b67f09SDavid van Moolenbroek cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
890*00b67f09SDavid van Moolenbroek "%s '%u' is out of range (1..3660)",
891*00b67f09SDavid van Moolenbroek "sig-validity-interval (re-sign)",
892*00b67f09SDavid van Moolenbroek validity);
893*00b67f09SDavid van Moolenbroek result = ISC_R_RANGE;
894*00b67f09SDavid van Moolenbroek } else if ((validity > 7 && validity < resign) ||
895*00b67f09SDavid van Moolenbroek (validity <= 7 && validity * 24 < resign)) {
896*00b67f09SDavid van Moolenbroek cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
897*00b67f09SDavid van Moolenbroek "validity interval (%u days) "
898*00b67f09SDavid van Moolenbroek "less than re-signing interval "
899*00b67f09SDavid van Moolenbroek "(%u %s)", validity, resign,
900*00b67f09SDavid van Moolenbroek (validity > 7) ? "days" : "hours");
901*00b67f09SDavid van Moolenbroek result = ISC_R_RANGE;
902*00b67f09SDavid van Moolenbroek }
903*00b67f09SDavid van Moolenbroek }
904*00b67f09SDavid van Moolenbroek }
905*00b67f09SDavid van Moolenbroek
906*00b67f09SDavid van Moolenbroek obj = NULL;
907*00b67f09SDavid van Moolenbroek (void)cfg_map_get(options, "preferred-glue", &obj);
908*00b67f09SDavid van Moolenbroek if (obj != NULL) {
909*00b67f09SDavid van Moolenbroek str = cfg_obj_asstring(obj);
910*00b67f09SDavid van Moolenbroek if (strcasecmp(str, "a") != 0 &&
911*00b67f09SDavid van Moolenbroek strcasecmp(str, "aaaa") != 0 &&
912*00b67f09SDavid van Moolenbroek strcasecmp(str, "none") != 0)
913*00b67f09SDavid van Moolenbroek cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
914*00b67f09SDavid van Moolenbroek "preferred-glue unexpected value '%s'",
915*00b67f09SDavid van Moolenbroek str);
916*00b67f09SDavid van Moolenbroek }
917*00b67f09SDavid van Moolenbroek
918*00b67f09SDavid van Moolenbroek obj = NULL;
919*00b67f09SDavid van Moolenbroek (void)cfg_map_get(options, "root-delegation-only", &obj);
920*00b67f09SDavid van Moolenbroek if (obj != NULL) {
921*00b67f09SDavid van Moolenbroek if (!cfg_obj_isvoid(obj)) {
922*00b67f09SDavid van Moolenbroek for (element = cfg_list_first(obj);
923*00b67f09SDavid van Moolenbroek element != NULL;
924*00b67f09SDavid van Moolenbroek element = cfg_list_next(element)) {
925*00b67f09SDavid van Moolenbroek const cfg_obj_t *exclude;
926*00b67f09SDavid van Moolenbroek
927*00b67f09SDavid van Moolenbroek exclude = cfg_listelt_value(element);
928*00b67f09SDavid van Moolenbroek str = cfg_obj_asstring(exclude);
929*00b67f09SDavid van Moolenbroek tresult = check_name(str);
930*00b67f09SDavid van Moolenbroek if (tresult != ISC_R_SUCCESS) {
931*00b67f09SDavid van Moolenbroek cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
932*00b67f09SDavid van Moolenbroek "bad domain name '%s'",
933*00b67f09SDavid van Moolenbroek str);
934*00b67f09SDavid van Moolenbroek result = tresult;
935*00b67f09SDavid van Moolenbroek }
936*00b67f09SDavid van Moolenbroek }
937*00b67f09SDavid van Moolenbroek }
938*00b67f09SDavid van Moolenbroek }
939*00b67f09SDavid van Moolenbroek
940*00b67f09SDavid van Moolenbroek /*
941*00b67f09SDavid van Moolenbroek * Set supported DNSSEC algorithms.
942*00b67f09SDavid van Moolenbroek */
943*00b67f09SDavid van Moolenbroek obj = NULL;
944*00b67f09SDavid van Moolenbroek (void)cfg_map_get(options, "disable-algorithms", &obj);
945*00b67f09SDavid van Moolenbroek if (obj != NULL) {
946*00b67f09SDavid van Moolenbroek for (element = cfg_list_first(obj);
947*00b67f09SDavid van Moolenbroek element != NULL;
948*00b67f09SDavid van Moolenbroek element = cfg_list_next(element))
949*00b67f09SDavid van Moolenbroek {
950*00b67f09SDavid van Moolenbroek obj = cfg_listelt_value(element);
951*00b67f09SDavid van Moolenbroek tresult = disabled_algorithms(obj, logctx);
952*00b67f09SDavid van Moolenbroek if (tresult != ISC_R_SUCCESS)
953*00b67f09SDavid van Moolenbroek result = tresult;
954*00b67f09SDavid van Moolenbroek }
955*00b67f09SDavid van Moolenbroek }
956*00b67f09SDavid van Moolenbroek
957*00b67f09SDavid van Moolenbroek /*
958*00b67f09SDavid van Moolenbroek * Set supported DS/DLV digest types.
959*00b67f09SDavid van Moolenbroek */
960*00b67f09SDavid van Moolenbroek obj = NULL;
961*00b67f09SDavid van Moolenbroek (void)cfg_map_get(options, "disable-ds-digests", &obj);
962*00b67f09SDavid van Moolenbroek if (obj != NULL) {
963*00b67f09SDavid van Moolenbroek for (element = cfg_list_first(obj);
964*00b67f09SDavid van Moolenbroek element != NULL;
965*00b67f09SDavid van Moolenbroek element = cfg_list_next(element))
966*00b67f09SDavid van Moolenbroek {
967*00b67f09SDavid van Moolenbroek obj = cfg_listelt_value(element);
968*00b67f09SDavid van Moolenbroek tresult = disabled_ds_digests(obj, logctx);
969*00b67f09SDavid van Moolenbroek if (tresult != ISC_R_SUCCESS)
970*00b67f09SDavid van Moolenbroek result = tresult;
971*00b67f09SDavid van Moolenbroek }
972*00b67f09SDavid van Moolenbroek }
973*00b67f09SDavid van Moolenbroek
974*00b67f09SDavid van Moolenbroek dns_fixedname_init(&fixed);
975*00b67f09SDavid van Moolenbroek name = dns_fixedname_name(&fixed);
976*00b67f09SDavid van Moolenbroek
977*00b67f09SDavid van Moolenbroek /*
978*00b67f09SDavid van Moolenbroek * Check the DLV zone name.
979*00b67f09SDavid van Moolenbroek */
980*00b67f09SDavid van Moolenbroek obj = NULL;
981*00b67f09SDavid van Moolenbroek (void)cfg_map_get(options, "dnssec-lookaside", &obj);
982*00b67f09SDavid van Moolenbroek if (obj != NULL) {
983*00b67f09SDavid van Moolenbroek tresult = isc_symtab_create(mctx, 100, freekey, mctx,
984*00b67f09SDavid van Moolenbroek ISC_FALSE, &symtab);
985*00b67f09SDavid van Moolenbroek if (tresult != ISC_R_SUCCESS)
986*00b67f09SDavid van Moolenbroek result = tresult;
987*00b67f09SDavid van Moolenbroek for (element = cfg_list_first(obj);
988*00b67f09SDavid van Moolenbroek element != NULL;
989*00b67f09SDavid van Moolenbroek element = cfg_list_next(element))
990*00b67f09SDavid van Moolenbroek {
991*00b67f09SDavid van Moolenbroek const char *dlv;
992*00b67f09SDavid van Moolenbroek const cfg_obj_t *dlvobj, *anchor;
993*00b67f09SDavid van Moolenbroek
994*00b67f09SDavid van Moolenbroek obj = cfg_listelt_value(element);
995*00b67f09SDavid van Moolenbroek
996*00b67f09SDavid van Moolenbroek anchor = cfg_tuple_get(obj, "trust-anchor");
997*00b67f09SDavid van Moolenbroek dlvobj = cfg_tuple_get(obj, "domain");
998*00b67f09SDavid van Moolenbroek dlv = cfg_obj_asstring(dlvobj);
999*00b67f09SDavid van Moolenbroek
1000*00b67f09SDavid van Moolenbroek /*
1001*00b67f09SDavid van Moolenbroek * If domain is "auto" or "no" and trust anchor
1002*00b67f09SDavid van Moolenbroek * is missing, skip remaining tests
1003*00b67f09SDavid van Moolenbroek */
1004*00b67f09SDavid van Moolenbroek if (cfg_obj_isvoid(anchor)) {
1005*00b67f09SDavid van Moolenbroek if (!strcasecmp(dlv, "no") ||
1006*00b67f09SDavid van Moolenbroek !strcasecmp(dlv, "auto"))
1007*00b67f09SDavid van Moolenbroek continue;
1008*00b67f09SDavid van Moolenbroek }
1009*00b67f09SDavid van Moolenbroek
1010*00b67f09SDavid van Moolenbroek tresult = dns_name_fromstring(name, dlv, 0, NULL);
1011*00b67f09SDavid van Moolenbroek if (tresult != ISC_R_SUCCESS) {
1012*00b67f09SDavid van Moolenbroek cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
1013*00b67f09SDavid van Moolenbroek "bad domain name '%s'", dlv);
1014*00b67f09SDavid van Moolenbroek result = tresult;
1015*00b67f09SDavid van Moolenbroek continue;
1016*00b67f09SDavid van Moolenbroek }
1017*00b67f09SDavid van Moolenbroek if (symtab != NULL) {
1018*00b67f09SDavid van Moolenbroek tresult = nameexist(obj, dlv, 1, symtab,
1019*00b67f09SDavid van Moolenbroek "dnssec-lookaside '%s': "
1020*00b67f09SDavid van Moolenbroek "already exists previous "
1021*00b67f09SDavid van Moolenbroek "definition: %s:%u",
1022*00b67f09SDavid van Moolenbroek logctx, mctx);
1023*00b67f09SDavid van Moolenbroek if (tresult != ISC_R_SUCCESS &&
1024*00b67f09SDavid van Moolenbroek result == ISC_R_SUCCESS)
1025*00b67f09SDavid van Moolenbroek result = tresult;
1026*00b67f09SDavid van Moolenbroek }
1027*00b67f09SDavid van Moolenbroek
1028*00b67f09SDavid van Moolenbroek /*
1029*00b67f09SDavid van Moolenbroek * XXXMPA to be removed when multiple lookaside
1030*00b67f09SDavid van Moolenbroek * namespaces are supported.
1031*00b67f09SDavid van Moolenbroek */
1032*00b67f09SDavid van Moolenbroek if (!dns_name_equal(dns_rootname, name)) {
1033*00b67f09SDavid van Moolenbroek cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
1034*00b67f09SDavid van Moolenbroek "dnssec-lookaside '%s': "
1035*00b67f09SDavid van Moolenbroek "non-root not yet supported", dlv);
1036*00b67f09SDavid van Moolenbroek if (result == ISC_R_SUCCESS)
1037*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
1038*00b67f09SDavid van Moolenbroek }
1039*00b67f09SDavid van Moolenbroek
1040*00b67f09SDavid van Moolenbroek if (!cfg_obj_isvoid(anchor)) {
1041*00b67f09SDavid van Moolenbroek dlv = cfg_obj_asstring(anchor);
1042*00b67f09SDavid van Moolenbroek tresult = check_name(dlv);
1043*00b67f09SDavid van Moolenbroek if (tresult != ISC_R_SUCCESS) {
1044*00b67f09SDavid van Moolenbroek cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
1045*00b67f09SDavid van Moolenbroek "bad domain name '%s'",
1046*00b67f09SDavid van Moolenbroek dlv);
1047*00b67f09SDavid van Moolenbroek if (result == ISC_R_SUCCESS)
1048*00b67f09SDavid van Moolenbroek result = tresult;
1049*00b67f09SDavid van Moolenbroek }
1050*00b67f09SDavid van Moolenbroek } else {
1051*00b67f09SDavid van Moolenbroek cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
1052*00b67f09SDavid van Moolenbroek "dnssec-lookaside requires "
1053*00b67f09SDavid van Moolenbroek "either 'auto' or 'no', or a "
1054*00b67f09SDavid van Moolenbroek "domain and trust anchor");
1055*00b67f09SDavid van Moolenbroek if (result == ISC_R_SUCCESS)
1056*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
1057*00b67f09SDavid van Moolenbroek }
1058*00b67f09SDavid van Moolenbroek }
1059*00b67f09SDavid van Moolenbroek
1060*00b67f09SDavid van Moolenbroek if (symtab != NULL)
1061*00b67f09SDavid van Moolenbroek isc_symtab_destroy(&symtab);
1062*00b67f09SDavid van Moolenbroek }
1063*00b67f09SDavid van Moolenbroek
1064*00b67f09SDavid van Moolenbroek /*
1065*00b67f09SDavid van Moolenbroek * Check auto-dnssec at the view/options level
1066*00b67f09SDavid van Moolenbroek */
1067*00b67f09SDavid van Moolenbroek obj = NULL;
1068*00b67f09SDavid van Moolenbroek (void)cfg_map_get(options, "auto-dnssec", &obj);
1069*00b67f09SDavid van Moolenbroek if (obj != NULL) {
1070*00b67f09SDavid van Moolenbroek const char *arg = cfg_obj_asstring(obj);
1071*00b67f09SDavid van Moolenbroek if (optlevel != optlevel_zone && strcasecmp(arg, "off") != 0) {
1072*00b67f09SDavid van Moolenbroek cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
1073*00b67f09SDavid van Moolenbroek "auto-dnssec may only be activated at the "
1074*00b67f09SDavid van Moolenbroek "zone level");
1075*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
1076*00b67f09SDavid van Moolenbroek }
1077*00b67f09SDavid van Moolenbroek }
1078*00b67f09SDavid van Moolenbroek
1079*00b67f09SDavid van Moolenbroek /*
1080*00b67f09SDavid van Moolenbroek * Check dnssec-must-be-secure.
1081*00b67f09SDavid van Moolenbroek */
1082*00b67f09SDavid van Moolenbroek obj = NULL;
1083*00b67f09SDavid van Moolenbroek (void)cfg_map_get(options, "dnssec-must-be-secure", &obj);
1084*00b67f09SDavid van Moolenbroek if (obj != NULL) {
1085*00b67f09SDavid van Moolenbroek tresult = isc_symtab_create(mctx, 100, freekey, mctx,
1086*00b67f09SDavid van Moolenbroek ISC_FALSE, &symtab);
1087*00b67f09SDavid van Moolenbroek if (tresult != ISC_R_SUCCESS)
1088*00b67f09SDavid van Moolenbroek result = tresult;
1089*00b67f09SDavid van Moolenbroek for (element = cfg_list_first(obj);
1090*00b67f09SDavid van Moolenbroek element != NULL;
1091*00b67f09SDavid van Moolenbroek element = cfg_list_next(element))
1092*00b67f09SDavid van Moolenbroek {
1093*00b67f09SDavid van Moolenbroek obj = cfg_listelt_value(element);
1094*00b67f09SDavid van Moolenbroek tresult = mustbesecure(obj, symtab, logctx, mctx);
1095*00b67f09SDavid van Moolenbroek if (tresult != ISC_R_SUCCESS)
1096*00b67f09SDavid van Moolenbroek result = tresult;
1097*00b67f09SDavid van Moolenbroek }
1098*00b67f09SDavid van Moolenbroek if (symtab != NULL)
1099*00b67f09SDavid van Moolenbroek isc_symtab_destroy(&symtab);
1100*00b67f09SDavid van Moolenbroek }
1101*00b67f09SDavid van Moolenbroek
1102*00b67f09SDavid van Moolenbroek /*
1103*00b67f09SDavid van Moolenbroek * Check server/contacts for syntactic validity.
1104*00b67f09SDavid van Moolenbroek */
1105*00b67f09SDavid van Moolenbroek for (i= 0; server_contact[i] != NULL; i++) {
1106*00b67f09SDavid van Moolenbroek obj = NULL;
1107*00b67f09SDavid van Moolenbroek (void)cfg_map_get(options, server_contact[i], &obj);
1108*00b67f09SDavid van Moolenbroek if (obj != NULL) {
1109*00b67f09SDavid van Moolenbroek str = cfg_obj_asstring(obj);
1110*00b67f09SDavid van Moolenbroek if (check_name(str) != ISC_R_SUCCESS) {
1111*00b67f09SDavid van Moolenbroek cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
1112*00b67f09SDavid van Moolenbroek "%s: invalid name '%s'",
1113*00b67f09SDavid van Moolenbroek server_contact[i], str);
1114*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
1115*00b67f09SDavid van Moolenbroek }
1116*00b67f09SDavid van Moolenbroek }
1117*00b67f09SDavid van Moolenbroek }
1118*00b67f09SDavid van Moolenbroek
1119*00b67f09SDavid van Moolenbroek /*
1120*00b67f09SDavid van Moolenbroek * Check empty zone configuration.
1121*00b67f09SDavid van Moolenbroek */
1122*00b67f09SDavid van Moolenbroek obj = NULL;
1123*00b67f09SDavid van Moolenbroek (void)cfg_map_get(options, "disable-empty-zone", &obj);
1124*00b67f09SDavid van Moolenbroek for (element = cfg_list_first(obj);
1125*00b67f09SDavid van Moolenbroek element != NULL;
1126*00b67f09SDavid van Moolenbroek element = cfg_list_next(element))
1127*00b67f09SDavid van Moolenbroek {
1128*00b67f09SDavid van Moolenbroek obj = cfg_listelt_value(element);
1129*00b67f09SDavid van Moolenbroek str = cfg_obj_asstring(obj);
1130*00b67f09SDavid van Moolenbroek if (check_name(str) != ISC_R_SUCCESS) {
1131*00b67f09SDavid van Moolenbroek cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
1132*00b67f09SDavid van Moolenbroek "disable-empty-zone: invalid name '%s'",
1133*00b67f09SDavid van Moolenbroek str);
1134*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
1135*00b67f09SDavid van Moolenbroek }
1136*00b67f09SDavid van Moolenbroek }
1137*00b67f09SDavid van Moolenbroek
1138*00b67f09SDavid van Moolenbroek /*
1139*00b67f09SDavid van Moolenbroek * Check that server-id is not too long.
1140*00b67f09SDavid van Moolenbroek * 1024 bytes should be big enough.
1141*00b67f09SDavid van Moolenbroek */
1142*00b67f09SDavid van Moolenbroek obj = NULL;
1143*00b67f09SDavid van Moolenbroek (void)cfg_map_get(options, "server-id", &obj);
1144*00b67f09SDavid van Moolenbroek if (obj != NULL && cfg_obj_isstring(obj) &&
1145*00b67f09SDavid van Moolenbroek strlen(cfg_obj_asstring(obj)) > 1024U) {
1146*00b67f09SDavid van Moolenbroek cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
1147*00b67f09SDavid van Moolenbroek "'server-id' too big (>1024 bytes)");
1148*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
1149*00b67f09SDavid van Moolenbroek }
1150*00b67f09SDavid van Moolenbroek
1151*00b67f09SDavid van Moolenbroek tresult = check_dscp(options, logctx);
1152*00b67f09SDavid van Moolenbroek if (tresult != ISC_R_SUCCESS)
1153*00b67f09SDavid van Moolenbroek result = tresult;
1154*00b67f09SDavid van Moolenbroek
1155*00b67f09SDavid van Moolenbroek #ifdef ISC_PLATFORM_USESIT
1156*00b67f09SDavid van Moolenbroek obj = NULL;
1157*00b67f09SDavid van Moolenbroek (void) cfg_map_get(options, "sit-secret", &obj);
1158*00b67f09SDavid van Moolenbroek if (obj != NULL) {
1159*00b67f09SDavid van Moolenbroek unsigned char secret[32];
1160*00b67f09SDavid van Moolenbroek
1161*00b67f09SDavid van Moolenbroek memset(secret, 0, sizeof(secret));
1162*00b67f09SDavid van Moolenbroek isc_buffer_init(&b, secret, sizeof(secret));
1163*00b67f09SDavid van Moolenbroek tresult = isc_hex_decodestring(cfg_obj_asstring(obj), &b);
1164*00b67f09SDavid van Moolenbroek if (tresult == ISC_R_NOSPACE) {
1165*00b67f09SDavid van Moolenbroek cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
1166*00b67f09SDavid van Moolenbroek "sit-secret: too long");
1167*00b67f09SDavid van Moolenbroek } else if (tresult != ISC_R_SUCCESS) {
1168*00b67f09SDavid van Moolenbroek cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
1169*00b67f09SDavid van Moolenbroek "sit-secret: invalid hex string");
1170*00b67f09SDavid van Moolenbroek }
1171*00b67f09SDavid van Moolenbroek if (tresult != ISC_R_SUCCESS)
1172*00b67f09SDavid van Moolenbroek result = tresult;
1173*00b67f09SDavid van Moolenbroek #ifdef AES_SIT
1174*00b67f09SDavid van Moolenbroek if (tresult == ISC_R_SUCCESS &&
1175*00b67f09SDavid van Moolenbroek isc_buffer_usedlength(&b) != ISC_AES128_KEYLENGTH) {
1176*00b67f09SDavid van Moolenbroek cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
1177*00b67f09SDavid van Moolenbroek "AES sit-secret must be on 128 bits");
1178*00b67f09SDavid van Moolenbroek result = ISC_R_RANGE;
1179*00b67f09SDavid van Moolenbroek }
1180*00b67f09SDavid van Moolenbroek #endif
1181*00b67f09SDavid van Moolenbroek #ifdef HMAC_SHA1_SIT
1182*00b67f09SDavid van Moolenbroek if (tresult == ISC_R_SUCCESS &&
1183*00b67f09SDavid van Moolenbroek isc_buffer_usedlength(&b) != ISC_SHA1_DIGESTLENGTH) {
1184*00b67f09SDavid van Moolenbroek cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
1185*00b67f09SDavid van Moolenbroek "SHA1 sit-secret must be on 160 bits");
1186*00b67f09SDavid van Moolenbroek result = ISC_R_RANGE;
1187*00b67f09SDavid van Moolenbroek }
1188*00b67f09SDavid van Moolenbroek #endif
1189*00b67f09SDavid van Moolenbroek #ifdef HMAC_SHA256_SIT
1190*00b67f09SDavid van Moolenbroek if (tresult == ISC_R_SUCCESS &&
1191*00b67f09SDavid van Moolenbroek isc_buffer_usedlength(&b) != ISC_SHA256_DIGESTLENGTH) {
1192*00b67f09SDavid van Moolenbroek cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
1193*00b67f09SDavid van Moolenbroek "SHA256 sit-secret must be on 256 bits");
1194*00b67f09SDavid van Moolenbroek result = ISC_R_RANGE;
1195*00b67f09SDavid van Moolenbroek }
1196*00b67f09SDavid van Moolenbroek #endif
1197*00b67f09SDavid van Moolenbroek }
1198*00b67f09SDavid van Moolenbroek #endif
1199*00b67f09SDavid van Moolenbroek
1200*00b67f09SDavid van Moolenbroek return (result);
1201*00b67f09SDavid van Moolenbroek }
1202*00b67f09SDavid van Moolenbroek
1203*00b67f09SDavid van Moolenbroek static isc_result_t
get_masters_def(const cfg_obj_t * cctx,const char * name,const cfg_obj_t ** ret)1204*00b67f09SDavid van Moolenbroek get_masters_def(const cfg_obj_t *cctx, const char *name, const cfg_obj_t **ret) {
1205*00b67f09SDavid van Moolenbroek isc_result_t result;
1206*00b67f09SDavid van Moolenbroek const cfg_obj_t *masters = NULL;
1207*00b67f09SDavid van Moolenbroek const cfg_listelt_t *elt;
1208*00b67f09SDavid van Moolenbroek
1209*00b67f09SDavid van Moolenbroek result = cfg_map_get(cctx, "masters", &masters);
1210*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
1211*00b67f09SDavid van Moolenbroek return (result);
1212*00b67f09SDavid van Moolenbroek for (elt = cfg_list_first(masters);
1213*00b67f09SDavid van Moolenbroek elt != NULL;
1214*00b67f09SDavid van Moolenbroek elt = cfg_list_next(elt)) {
1215*00b67f09SDavid van Moolenbroek const cfg_obj_t *list;
1216*00b67f09SDavid van Moolenbroek const char *listname;
1217*00b67f09SDavid van Moolenbroek
1218*00b67f09SDavid van Moolenbroek list = cfg_listelt_value(elt);
1219*00b67f09SDavid van Moolenbroek listname = cfg_obj_asstring(cfg_tuple_get(list, "name"));
1220*00b67f09SDavid van Moolenbroek
1221*00b67f09SDavid van Moolenbroek if (strcasecmp(listname, name) == 0) {
1222*00b67f09SDavid van Moolenbroek *ret = list;
1223*00b67f09SDavid van Moolenbroek return (ISC_R_SUCCESS);
1224*00b67f09SDavid van Moolenbroek }
1225*00b67f09SDavid van Moolenbroek }
1226*00b67f09SDavid van Moolenbroek return (ISC_R_NOTFOUND);
1227*00b67f09SDavid van Moolenbroek }
1228*00b67f09SDavid van Moolenbroek
1229*00b67f09SDavid van Moolenbroek static isc_result_t
validate_masters(const cfg_obj_t * obj,const cfg_obj_t * config,isc_uint32_t * countp,isc_log_t * logctx,isc_mem_t * mctx)1230*00b67f09SDavid van Moolenbroek validate_masters(const cfg_obj_t *obj, const cfg_obj_t *config,
1231*00b67f09SDavid van Moolenbroek isc_uint32_t *countp, isc_log_t *logctx, isc_mem_t *mctx)
1232*00b67f09SDavid van Moolenbroek {
1233*00b67f09SDavid van Moolenbroek isc_result_t result = ISC_R_SUCCESS;
1234*00b67f09SDavid van Moolenbroek isc_result_t tresult;
1235*00b67f09SDavid van Moolenbroek isc_uint32_t count = 0;
1236*00b67f09SDavid van Moolenbroek isc_symtab_t *symtab = NULL;
1237*00b67f09SDavid van Moolenbroek isc_symvalue_t symvalue;
1238*00b67f09SDavid van Moolenbroek const cfg_listelt_t *element;
1239*00b67f09SDavid van Moolenbroek const cfg_listelt_t **stack = NULL;
1240*00b67f09SDavid van Moolenbroek isc_uint32_t stackcount = 0, pushed = 0;
1241*00b67f09SDavid van Moolenbroek const cfg_obj_t *list;
1242*00b67f09SDavid van Moolenbroek
1243*00b67f09SDavid van Moolenbroek REQUIRE(countp != NULL);
1244*00b67f09SDavid van Moolenbroek result = isc_symtab_create(mctx, 100, NULL, NULL, ISC_FALSE, &symtab);
1245*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS) {
1246*00b67f09SDavid van Moolenbroek *countp = count;
1247*00b67f09SDavid van Moolenbroek return (result);
1248*00b67f09SDavid van Moolenbroek }
1249*00b67f09SDavid van Moolenbroek
1250*00b67f09SDavid van Moolenbroek newlist:
1251*00b67f09SDavid van Moolenbroek list = cfg_tuple_get(obj, "addresses");
1252*00b67f09SDavid van Moolenbroek element = cfg_list_first(list);
1253*00b67f09SDavid van Moolenbroek resume:
1254*00b67f09SDavid van Moolenbroek for ( ;
1255*00b67f09SDavid van Moolenbroek element != NULL;
1256*00b67f09SDavid van Moolenbroek element = cfg_list_next(element))
1257*00b67f09SDavid van Moolenbroek {
1258*00b67f09SDavid van Moolenbroek const char *listname;
1259*00b67f09SDavid van Moolenbroek const cfg_obj_t *addr;
1260*00b67f09SDavid van Moolenbroek const cfg_obj_t *key;
1261*00b67f09SDavid van Moolenbroek
1262*00b67f09SDavid van Moolenbroek addr = cfg_tuple_get(cfg_listelt_value(element),
1263*00b67f09SDavid van Moolenbroek "masterselement");
1264*00b67f09SDavid van Moolenbroek key = cfg_tuple_get(cfg_listelt_value(element), "key");
1265*00b67f09SDavid van Moolenbroek
1266*00b67f09SDavid van Moolenbroek if (cfg_obj_issockaddr(addr)) {
1267*00b67f09SDavid van Moolenbroek count++;
1268*00b67f09SDavid van Moolenbroek continue;
1269*00b67f09SDavid van Moolenbroek }
1270*00b67f09SDavid van Moolenbroek if (!cfg_obj_isvoid(key)) {
1271*00b67f09SDavid van Moolenbroek cfg_obj_log(key, logctx, ISC_LOG_ERROR,
1272*00b67f09SDavid van Moolenbroek "unexpected token '%s'",
1273*00b67f09SDavid van Moolenbroek cfg_obj_asstring(key));
1274*00b67f09SDavid van Moolenbroek if (result == ISC_R_SUCCESS)
1275*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
1276*00b67f09SDavid van Moolenbroek }
1277*00b67f09SDavid van Moolenbroek listname = cfg_obj_asstring(addr);
1278*00b67f09SDavid van Moolenbroek symvalue.as_cpointer = addr;
1279*00b67f09SDavid van Moolenbroek tresult = isc_symtab_define(symtab, listname, 1, symvalue,
1280*00b67f09SDavid van Moolenbroek isc_symexists_reject);
1281*00b67f09SDavid van Moolenbroek if (tresult == ISC_R_EXISTS)
1282*00b67f09SDavid van Moolenbroek continue;
1283*00b67f09SDavid van Moolenbroek tresult = get_masters_def(config, listname, &obj);
1284*00b67f09SDavid van Moolenbroek if (tresult != ISC_R_SUCCESS) {
1285*00b67f09SDavid van Moolenbroek if (result == ISC_R_SUCCESS)
1286*00b67f09SDavid van Moolenbroek result = tresult;
1287*00b67f09SDavid van Moolenbroek cfg_obj_log(addr, logctx, ISC_LOG_ERROR,
1288*00b67f09SDavid van Moolenbroek "unable to find masters list '%s'",
1289*00b67f09SDavid van Moolenbroek listname);
1290*00b67f09SDavid van Moolenbroek continue;
1291*00b67f09SDavid van Moolenbroek }
1292*00b67f09SDavid van Moolenbroek /* Grow stack? */
1293*00b67f09SDavid van Moolenbroek if (stackcount == pushed) {
1294*00b67f09SDavid van Moolenbroek void * new;
1295*00b67f09SDavid van Moolenbroek isc_uint32_t newlen = stackcount + 16;
1296*00b67f09SDavid van Moolenbroek size_t newsize, oldsize;
1297*00b67f09SDavid van Moolenbroek
1298*00b67f09SDavid van Moolenbroek newsize = newlen * sizeof(*stack);
1299*00b67f09SDavid van Moolenbroek oldsize = stackcount * sizeof(*stack);
1300*00b67f09SDavid van Moolenbroek new = isc_mem_get(mctx, newsize);
1301*00b67f09SDavid van Moolenbroek if (new == NULL)
1302*00b67f09SDavid van Moolenbroek goto cleanup;
1303*00b67f09SDavid van Moolenbroek if (stackcount != 0) {
1304*00b67f09SDavid van Moolenbroek void *ptr;
1305*00b67f09SDavid van Moolenbroek
1306*00b67f09SDavid van Moolenbroek DE_CONST(stack, ptr);
1307*00b67f09SDavid van Moolenbroek memmove(new, stack, oldsize);
1308*00b67f09SDavid van Moolenbroek isc_mem_put(mctx, ptr, oldsize);
1309*00b67f09SDavid van Moolenbroek }
1310*00b67f09SDavid van Moolenbroek stack = new;
1311*00b67f09SDavid van Moolenbroek stackcount = newlen;
1312*00b67f09SDavid van Moolenbroek }
1313*00b67f09SDavid van Moolenbroek stack[pushed++] = cfg_list_next(element);
1314*00b67f09SDavid van Moolenbroek goto newlist;
1315*00b67f09SDavid van Moolenbroek }
1316*00b67f09SDavid van Moolenbroek if (pushed != 0) {
1317*00b67f09SDavid van Moolenbroek element = stack[--pushed];
1318*00b67f09SDavid van Moolenbroek goto resume;
1319*00b67f09SDavid van Moolenbroek }
1320*00b67f09SDavid van Moolenbroek cleanup:
1321*00b67f09SDavid van Moolenbroek if (stack != NULL) {
1322*00b67f09SDavid van Moolenbroek void *ptr;
1323*00b67f09SDavid van Moolenbroek
1324*00b67f09SDavid van Moolenbroek DE_CONST(stack, ptr);
1325*00b67f09SDavid van Moolenbroek isc_mem_put(mctx, ptr, stackcount * sizeof(*stack));
1326*00b67f09SDavid van Moolenbroek }
1327*00b67f09SDavid van Moolenbroek isc_symtab_destroy(&symtab);
1328*00b67f09SDavid van Moolenbroek *countp = count;
1329*00b67f09SDavid van Moolenbroek return (result);
1330*00b67f09SDavid van Moolenbroek }
1331*00b67f09SDavid van Moolenbroek
1332*00b67f09SDavid van Moolenbroek static isc_result_t
check_update_policy(const cfg_obj_t * policy,isc_log_t * logctx)1333*00b67f09SDavid van Moolenbroek check_update_policy(const cfg_obj_t *policy, isc_log_t *logctx) {
1334*00b67f09SDavid van Moolenbroek isc_result_t result = ISC_R_SUCCESS;
1335*00b67f09SDavid van Moolenbroek isc_result_t tresult;
1336*00b67f09SDavid van Moolenbroek const cfg_listelt_t *element;
1337*00b67f09SDavid van Moolenbroek const cfg_listelt_t *element2;
1338*00b67f09SDavid van Moolenbroek dns_fixedname_t fixed;
1339*00b67f09SDavid van Moolenbroek const char *str;
1340*00b67f09SDavid van Moolenbroek isc_buffer_t b;
1341*00b67f09SDavid van Moolenbroek
1342*00b67f09SDavid van Moolenbroek /* Check for "update-policy local;" */
1343*00b67f09SDavid van Moolenbroek if (cfg_obj_isstring(policy) &&
1344*00b67f09SDavid van Moolenbroek strcmp("local", cfg_obj_asstring(policy)) == 0)
1345*00b67f09SDavid van Moolenbroek return (ISC_R_SUCCESS);
1346*00b67f09SDavid van Moolenbroek
1347*00b67f09SDavid van Moolenbroek /* Now check the grant policy */
1348*00b67f09SDavid van Moolenbroek for (element = cfg_list_first(policy);
1349*00b67f09SDavid van Moolenbroek element != NULL;
1350*00b67f09SDavid van Moolenbroek element = cfg_list_next(element))
1351*00b67f09SDavid van Moolenbroek {
1352*00b67f09SDavid van Moolenbroek const cfg_obj_t *stmt = cfg_listelt_value(element);
1353*00b67f09SDavid van Moolenbroek const cfg_obj_t *identity = cfg_tuple_get(stmt, "identity");
1354*00b67f09SDavid van Moolenbroek const cfg_obj_t *matchtype = cfg_tuple_get(stmt, "matchtype");
1355*00b67f09SDavid van Moolenbroek const cfg_obj_t *dname = cfg_tuple_get(stmt, "name");
1356*00b67f09SDavid van Moolenbroek const cfg_obj_t *typelist = cfg_tuple_get(stmt, "types");
1357*00b67f09SDavid van Moolenbroek
1358*00b67f09SDavid van Moolenbroek dns_fixedname_init(&fixed);
1359*00b67f09SDavid van Moolenbroek str = cfg_obj_asstring(identity);
1360*00b67f09SDavid van Moolenbroek isc_buffer_constinit(&b, str, strlen(str));
1361*00b67f09SDavid van Moolenbroek isc_buffer_add(&b, strlen(str));
1362*00b67f09SDavid van Moolenbroek tresult = dns_name_fromtext(dns_fixedname_name(&fixed), &b,
1363*00b67f09SDavid van Moolenbroek dns_rootname, 0, NULL);
1364*00b67f09SDavid van Moolenbroek if (tresult != ISC_R_SUCCESS) {
1365*00b67f09SDavid van Moolenbroek cfg_obj_log(identity, logctx, ISC_LOG_ERROR,
1366*00b67f09SDavid van Moolenbroek "'%s' is not a valid name", str);
1367*00b67f09SDavid van Moolenbroek result = tresult;
1368*00b67f09SDavid van Moolenbroek }
1369*00b67f09SDavid van Moolenbroek
1370*00b67f09SDavid van Moolenbroek if (tresult == ISC_R_SUCCESS &&
1371*00b67f09SDavid van Moolenbroek strcasecmp(cfg_obj_asstring(matchtype), "zonesub") != 0) {
1372*00b67f09SDavid van Moolenbroek dns_fixedname_init(&fixed);
1373*00b67f09SDavid van Moolenbroek str = cfg_obj_asstring(dname);
1374*00b67f09SDavid van Moolenbroek isc_buffer_constinit(&b, str, strlen(str));
1375*00b67f09SDavid van Moolenbroek isc_buffer_add(&b, strlen(str));
1376*00b67f09SDavid van Moolenbroek tresult = dns_name_fromtext(dns_fixedname_name(&fixed),
1377*00b67f09SDavid van Moolenbroek &b, dns_rootname, 0, NULL);
1378*00b67f09SDavid van Moolenbroek if (tresult != ISC_R_SUCCESS) {
1379*00b67f09SDavid van Moolenbroek cfg_obj_log(dname, logctx, ISC_LOG_ERROR,
1380*00b67f09SDavid van Moolenbroek "'%s' is not a valid name", str);
1381*00b67f09SDavid van Moolenbroek result = tresult;
1382*00b67f09SDavid van Moolenbroek }
1383*00b67f09SDavid van Moolenbroek }
1384*00b67f09SDavid van Moolenbroek
1385*00b67f09SDavid van Moolenbroek if (tresult == ISC_R_SUCCESS &&
1386*00b67f09SDavid van Moolenbroek strcasecmp(cfg_obj_asstring(matchtype), "wildcard") == 0 &&
1387*00b67f09SDavid van Moolenbroek !dns_name_iswildcard(dns_fixedname_name(&fixed))) {
1388*00b67f09SDavid van Moolenbroek cfg_obj_log(identity, logctx, ISC_LOG_ERROR,
1389*00b67f09SDavid van Moolenbroek "'%s' is not a wildcard", str);
1390*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
1391*00b67f09SDavid van Moolenbroek }
1392*00b67f09SDavid van Moolenbroek
1393*00b67f09SDavid van Moolenbroek for (element2 = cfg_list_first(typelist);
1394*00b67f09SDavid van Moolenbroek element2 != NULL;
1395*00b67f09SDavid van Moolenbroek element2 = cfg_list_next(element2))
1396*00b67f09SDavid van Moolenbroek {
1397*00b67f09SDavid van Moolenbroek const cfg_obj_t *typeobj;
1398*00b67f09SDavid van Moolenbroek isc_textregion_t r;
1399*00b67f09SDavid van Moolenbroek dns_rdatatype_t type;
1400*00b67f09SDavid van Moolenbroek
1401*00b67f09SDavid van Moolenbroek typeobj = cfg_listelt_value(element2);
1402*00b67f09SDavid van Moolenbroek DE_CONST(cfg_obj_asstring(typeobj), r.base);
1403*00b67f09SDavid van Moolenbroek r.length = strlen(r.base);
1404*00b67f09SDavid van Moolenbroek
1405*00b67f09SDavid van Moolenbroek tresult = dns_rdatatype_fromtext(&type, &r);
1406*00b67f09SDavid van Moolenbroek if (tresult != ISC_R_SUCCESS) {
1407*00b67f09SDavid van Moolenbroek cfg_obj_log(typeobj, logctx, ISC_LOG_ERROR,
1408*00b67f09SDavid van Moolenbroek "'%s' is not a valid type", r.base);
1409*00b67f09SDavid van Moolenbroek result = tresult;
1410*00b67f09SDavid van Moolenbroek }
1411*00b67f09SDavid van Moolenbroek }
1412*00b67f09SDavid van Moolenbroek }
1413*00b67f09SDavid van Moolenbroek return (result);
1414*00b67f09SDavid van Moolenbroek }
1415*00b67f09SDavid van Moolenbroek
1416*00b67f09SDavid van Moolenbroek #define MASTERZONE 1
1417*00b67f09SDavid van Moolenbroek #define SLAVEZONE 2
1418*00b67f09SDavid van Moolenbroek #define STUBZONE 4
1419*00b67f09SDavid van Moolenbroek #define HINTZONE 8
1420*00b67f09SDavid van Moolenbroek #define FORWARDZONE 16
1421*00b67f09SDavid van Moolenbroek #define DELEGATIONZONE 32
1422*00b67f09SDavid van Moolenbroek #define STATICSTUBZONE 64
1423*00b67f09SDavid van Moolenbroek #define REDIRECTZONE 128
1424*00b67f09SDavid van Moolenbroek #define STREDIRECTZONE 0 /* Set to REDIRECTZONE to allow xfr-in. */
1425*00b67f09SDavid van Moolenbroek #define CHECKACL 512
1426*00b67f09SDavid van Moolenbroek
1427*00b67f09SDavid van Moolenbroek typedef struct {
1428*00b67f09SDavid van Moolenbroek const char *name;
1429*00b67f09SDavid van Moolenbroek int allowed;
1430*00b67f09SDavid van Moolenbroek } optionstable;
1431*00b67f09SDavid van Moolenbroek
1432*00b67f09SDavid van Moolenbroek static isc_result_t
check_nonzero(const cfg_obj_t * options,isc_log_t * logctx)1433*00b67f09SDavid van Moolenbroek check_nonzero(const cfg_obj_t *options, isc_log_t *logctx) {
1434*00b67f09SDavid van Moolenbroek isc_result_t result = ISC_R_SUCCESS;
1435*00b67f09SDavid van Moolenbroek const cfg_obj_t *obj = NULL;
1436*00b67f09SDavid van Moolenbroek unsigned int i;
1437*00b67f09SDavid van Moolenbroek
1438*00b67f09SDavid van Moolenbroek static const char *nonzero[] = { "max-retry-time", "min-retry-time",
1439*00b67f09SDavid van Moolenbroek "max-refresh-time", "min-refresh-time" };
1440*00b67f09SDavid van Moolenbroek /*
1441*00b67f09SDavid van Moolenbroek * Check if value is zero.
1442*00b67f09SDavid van Moolenbroek */
1443*00b67f09SDavid van Moolenbroek for (i = 0; i < sizeof(nonzero) / sizeof(nonzero[0]); i++) {
1444*00b67f09SDavid van Moolenbroek obj = NULL;
1445*00b67f09SDavid van Moolenbroek if (cfg_map_get(options, nonzero[i], &obj) == ISC_R_SUCCESS &&
1446*00b67f09SDavid van Moolenbroek cfg_obj_asuint32(obj) == 0) {
1447*00b67f09SDavid van Moolenbroek cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
1448*00b67f09SDavid van Moolenbroek "'%s' must not be zero", nonzero[i]);
1449*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
1450*00b67f09SDavid van Moolenbroek }
1451*00b67f09SDavid van Moolenbroek }
1452*00b67f09SDavid van Moolenbroek return (result);
1453*00b67f09SDavid van Moolenbroek }
1454*00b67f09SDavid van Moolenbroek
1455*00b67f09SDavid van Moolenbroek static isc_result_t
check_zoneconf(const cfg_obj_t * zconfig,const cfg_obj_t * voptions,const cfg_obj_t * config,isc_symtab_t * symtab,isc_symtab_t * files,dns_rdataclass_t defclass,cfg_aclconfctx_t * actx,isc_log_t * logctx,isc_mem_t * mctx)1456*00b67f09SDavid van Moolenbroek check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
1457*00b67f09SDavid van Moolenbroek const cfg_obj_t *config, isc_symtab_t *symtab,
1458*00b67f09SDavid van Moolenbroek isc_symtab_t *files, dns_rdataclass_t defclass,
1459*00b67f09SDavid van Moolenbroek cfg_aclconfctx_t *actx, isc_log_t *logctx, isc_mem_t *mctx)
1460*00b67f09SDavid van Moolenbroek {
1461*00b67f09SDavid van Moolenbroek const char *znamestr;
1462*00b67f09SDavid van Moolenbroek const char *typestr;
1463*00b67f09SDavid van Moolenbroek unsigned int ztype;
1464*00b67f09SDavid van Moolenbroek const cfg_obj_t *zoptions, *goptions = NULL;
1465*00b67f09SDavid van Moolenbroek const cfg_obj_t *obj = NULL;
1466*00b67f09SDavid van Moolenbroek isc_result_t result = ISC_R_SUCCESS;
1467*00b67f09SDavid van Moolenbroek isc_result_t tresult;
1468*00b67f09SDavid van Moolenbroek unsigned int i;
1469*00b67f09SDavid van Moolenbroek dns_rdataclass_t zclass;
1470*00b67f09SDavid van Moolenbroek dns_fixedname_t fixedname;
1471*00b67f09SDavid van Moolenbroek dns_name_t *zname = NULL;
1472*00b67f09SDavid van Moolenbroek isc_buffer_t b;
1473*00b67f09SDavid van Moolenbroek isc_boolean_t root = ISC_FALSE;
1474*00b67f09SDavid van Moolenbroek const cfg_listelt_t *element;
1475*00b67f09SDavid van Moolenbroek isc_boolean_t dlz;
1476*00b67f09SDavid van Moolenbroek dns_masterformat_t masterformat;
1477*00b67f09SDavid van Moolenbroek isc_boolean_t ddns = ISC_FALSE;
1478*00b67f09SDavid van Moolenbroek
1479*00b67f09SDavid van Moolenbroek static optionstable options[] = {
1480*00b67f09SDavid van Moolenbroek { "allow-notify", SLAVEZONE | CHECKACL },
1481*00b67f09SDavid van Moolenbroek { "allow-query", MASTERZONE | SLAVEZONE | STUBZONE | REDIRECTZONE |
1482*00b67f09SDavid van Moolenbroek CHECKACL | STATICSTUBZONE },
1483*00b67f09SDavid van Moolenbroek { "allow-transfer", MASTERZONE | SLAVEZONE | CHECKACL },
1484*00b67f09SDavid van Moolenbroek { "allow-update", MASTERZONE | CHECKACL },
1485*00b67f09SDavid van Moolenbroek { "allow-update-forwarding", SLAVEZONE | CHECKACL },
1486*00b67f09SDavid van Moolenbroek { "also-notify", MASTERZONE | SLAVEZONE },
1487*00b67f09SDavid van Moolenbroek { "auto-dnssec", MASTERZONE | SLAVEZONE },
1488*00b67f09SDavid van Moolenbroek { "check-dup-records", MASTERZONE },
1489*00b67f09SDavid van Moolenbroek { "check-mx", MASTERZONE },
1490*00b67f09SDavid van Moolenbroek { "check-mx-cname", MASTERZONE },
1491*00b67f09SDavid van Moolenbroek { "check-srv-cname", MASTERZONE },
1492*00b67f09SDavid van Moolenbroek { "check-wildcard", MASTERZONE },
1493*00b67f09SDavid van Moolenbroek { "database", MASTERZONE | SLAVEZONE | STUBZONE | REDIRECTZONE },
1494*00b67f09SDavid van Moolenbroek { "delegation-only", HINTZONE | STUBZONE | FORWARDZONE |
1495*00b67f09SDavid van Moolenbroek DELEGATIONZONE },
1496*00b67f09SDavid van Moolenbroek { "dialup", MASTERZONE | SLAVEZONE | STUBZONE | STREDIRECTZONE },
1497*00b67f09SDavid van Moolenbroek { "dnssec-dnskey-kskonly", MASTERZONE | SLAVEZONE },
1498*00b67f09SDavid van Moolenbroek { "dnssec-loadkeys-interval", MASTERZONE | SLAVEZONE },
1499*00b67f09SDavid van Moolenbroek { "dnssec-secure-to-insecure", MASTERZONE },
1500*00b67f09SDavid van Moolenbroek { "file", MASTERZONE | SLAVEZONE | STUBZONE | HINTZONE | REDIRECTZONE },
1501*00b67f09SDavid van Moolenbroek { "forward", MASTERZONE | SLAVEZONE | STUBZONE | STATICSTUBZONE |
1502*00b67f09SDavid van Moolenbroek FORWARDZONE },
1503*00b67f09SDavid van Moolenbroek { "forwarders", MASTERZONE | SLAVEZONE | STUBZONE | STATICSTUBZONE |
1504*00b67f09SDavid van Moolenbroek FORWARDZONE },
1505*00b67f09SDavid van Moolenbroek { "integrity-check", MASTERZONE },
1506*00b67f09SDavid van Moolenbroek { "ixfr-base", MASTERZONE | SLAVEZONE },
1507*00b67f09SDavid van Moolenbroek { "ixfr-tmp-file", MASTERZONE | SLAVEZONE },
1508*00b67f09SDavid van Moolenbroek { "journal", MASTERZONE | SLAVEZONE | STREDIRECTZONE },
1509*00b67f09SDavid van Moolenbroek { "key-directory", MASTERZONE | SLAVEZONE },
1510*00b67f09SDavid van Moolenbroek { "maintain-ixfr-base", MASTERZONE | SLAVEZONE | STREDIRECTZONE },
1511*00b67f09SDavid van Moolenbroek { "masterfile-format", MASTERZONE | SLAVEZONE | STUBZONE |
1512*00b67f09SDavid van Moolenbroek REDIRECTZONE },
1513*00b67f09SDavid van Moolenbroek { "masters", SLAVEZONE | STUBZONE | REDIRECTZONE },
1514*00b67f09SDavid van Moolenbroek { "max-ixfr-log-size", MASTERZONE | SLAVEZONE | STREDIRECTZONE },
1515*00b67f09SDavid van Moolenbroek { "max-refresh-time", SLAVEZONE | STUBZONE | STREDIRECTZONE },
1516*00b67f09SDavid van Moolenbroek { "max-retry-time", SLAVEZONE | STUBZONE | STREDIRECTZONE },
1517*00b67f09SDavid van Moolenbroek { "max-transfer-idle-in", SLAVEZONE | STUBZONE | STREDIRECTZONE },
1518*00b67f09SDavid van Moolenbroek { "max-transfer-idle-out", MASTERZONE | SLAVEZONE },
1519*00b67f09SDavid van Moolenbroek { "max-transfer-time-in", SLAVEZONE | STUBZONE | STREDIRECTZONE },
1520*00b67f09SDavid van Moolenbroek { "max-transfer-time-out", MASTERZONE | SLAVEZONE },
1521*00b67f09SDavid van Moolenbroek { "max-zone-ttl", MASTERZONE | REDIRECTZONE },
1522*00b67f09SDavid van Moolenbroek { "min-refresh-time", SLAVEZONE | STUBZONE | STREDIRECTZONE },
1523*00b67f09SDavid van Moolenbroek { "min-retry-time", SLAVEZONE | STUBZONE | STREDIRECTZONE },
1524*00b67f09SDavid van Moolenbroek { "notify", MASTERZONE | SLAVEZONE },
1525*00b67f09SDavid van Moolenbroek { "notify-source", MASTERZONE | SLAVEZONE },
1526*00b67f09SDavid van Moolenbroek { "notify-source-v6", MASTERZONE | SLAVEZONE },
1527*00b67f09SDavid van Moolenbroek { "pubkey", MASTERZONE | SLAVEZONE | STUBZONE },
1528*00b67f09SDavid van Moolenbroek { "request-ixfr", SLAVEZONE | REDIRECTZONE },
1529*00b67f09SDavid van Moolenbroek { "server-addresses", STATICSTUBZONE },
1530*00b67f09SDavid van Moolenbroek { "server-names", STATICSTUBZONE },
1531*00b67f09SDavid van Moolenbroek { "sig-re-signing-interval", MASTERZONE | SLAVEZONE },
1532*00b67f09SDavid van Moolenbroek { "sig-signing-nodes", MASTERZONE | SLAVEZONE },
1533*00b67f09SDavid van Moolenbroek { "sig-signing-signatures", MASTERZONE | SLAVEZONE },
1534*00b67f09SDavid van Moolenbroek { "sig-signing-type", MASTERZONE | SLAVEZONE },
1535*00b67f09SDavid van Moolenbroek { "sig-validity-interval", MASTERZONE | SLAVEZONE },
1536*00b67f09SDavid van Moolenbroek { "signing", MASTERZONE | SLAVEZONE },
1537*00b67f09SDavid van Moolenbroek { "transfer-source", SLAVEZONE | STUBZONE | STREDIRECTZONE },
1538*00b67f09SDavid van Moolenbroek { "transfer-source-v6", SLAVEZONE | STUBZONE | STREDIRECTZONE },
1539*00b67f09SDavid van Moolenbroek { "try-tcp-refresh", SLAVEZONE | STREDIRECTZONE },
1540*00b67f09SDavid van Moolenbroek { "update-check-ksk", MASTERZONE | SLAVEZONE },
1541*00b67f09SDavid van Moolenbroek { "update-policy", MASTERZONE },
1542*00b67f09SDavid van Moolenbroek { "zone-statistics", MASTERZONE | SLAVEZONE | STUBZONE |
1543*00b67f09SDavid van Moolenbroek STATICSTUBZONE | REDIRECTZONE },
1544*00b67f09SDavid van Moolenbroek };
1545*00b67f09SDavid van Moolenbroek
1546*00b67f09SDavid van Moolenbroek static optionstable dialups[] = {
1547*00b67f09SDavid van Moolenbroek { "notify", MASTERZONE | SLAVEZONE | STREDIRECTZONE },
1548*00b67f09SDavid van Moolenbroek { "notify-passive", SLAVEZONE | STREDIRECTZONE },
1549*00b67f09SDavid van Moolenbroek { "refresh", SLAVEZONE | STUBZONE | STREDIRECTZONE },
1550*00b67f09SDavid van Moolenbroek { "passive", SLAVEZONE | STUBZONE | STREDIRECTZONE },
1551*00b67f09SDavid van Moolenbroek };
1552*00b67f09SDavid van Moolenbroek
1553*00b67f09SDavid van Moolenbroek znamestr = cfg_obj_asstring(cfg_tuple_get(zconfig, "name"));
1554*00b67f09SDavid van Moolenbroek
1555*00b67f09SDavid van Moolenbroek zoptions = cfg_tuple_get(zconfig, "options");
1556*00b67f09SDavid van Moolenbroek
1557*00b67f09SDavid van Moolenbroek if (config != NULL)
1558*00b67f09SDavid van Moolenbroek cfg_map_get(config, "options", &goptions);
1559*00b67f09SDavid van Moolenbroek
1560*00b67f09SDavid van Moolenbroek obj = NULL;
1561*00b67f09SDavid van Moolenbroek (void)cfg_map_get(zoptions, "in-view", &obj);
1562*00b67f09SDavid van Moolenbroek if (obj != NULL) {
1563*00b67f09SDavid van Moolenbroek const cfg_obj_t *fwd = NULL;
1564*00b67f09SDavid van Moolenbroek unsigned int maxopts = 1;
1565*00b67f09SDavid van Moolenbroek (void)cfg_map_get(zoptions, "forward", &fwd);
1566*00b67f09SDavid van Moolenbroek if (fwd != NULL)
1567*00b67f09SDavid van Moolenbroek maxopts++;
1568*00b67f09SDavid van Moolenbroek fwd = NULL;
1569*00b67f09SDavid van Moolenbroek (void)cfg_map_get(zoptions, "forwarders", &fwd);
1570*00b67f09SDavid van Moolenbroek if (fwd != NULL)
1571*00b67f09SDavid van Moolenbroek maxopts++;
1572*00b67f09SDavid van Moolenbroek if (cfg_map_count(zoptions) > maxopts) {
1573*00b67f09SDavid van Moolenbroek cfg_obj_log(zconfig, logctx, ISC_LOG_ERROR,
1574*00b67f09SDavid van Moolenbroek "zone '%s': 'in-view' used "
1575*00b67f09SDavid van Moolenbroek "with incompatible zone options",
1576*00b67f09SDavid van Moolenbroek znamestr);
1577*00b67f09SDavid van Moolenbroek return (ISC_R_FAILURE);
1578*00b67f09SDavid van Moolenbroek }
1579*00b67f09SDavid van Moolenbroek return (ISC_R_SUCCESS);
1580*00b67f09SDavid van Moolenbroek }
1581*00b67f09SDavid van Moolenbroek
1582*00b67f09SDavid van Moolenbroek obj = NULL;
1583*00b67f09SDavid van Moolenbroek (void)cfg_map_get(zoptions, "type", &obj);
1584*00b67f09SDavid van Moolenbroek if (obj == NULL) {
1585*00b67f09SDavid van Moolenbroek cfg_obj_log(zconfig, logctx, ISC_LOG_ERROR,
1586*00b67f09SDavid van Moolenbroek "zone '%s': type not present", znamestr);
1587*00b67f09SDavid van Moolenbroek return (ISC_R_FAILURE);
1588*00b67f09SDavid van Moolenbroek }
1589*00b67f09SDavid van Moolenbroek
1590*00b67f09SDavid van Moolenbroek typestr = cfg_obj_asstring(obj);
1591*00b67f09SDavid van Moolenbroek if (strcasecmp(typestr, "master") == 0)
1592*00b67f09SDavid van Moolenbroek ztype = MASTERZONE;
1593*00b67f09SDavid van Moolenbroek else if (strcasecmp(typestr, "slave") == 0)
1594*00b67f09SDavid van Moolenbroek ztype = SLAVEZONE;
1595*00b67f09SDavid van Moolenbroek else if (strcasecmp(typestr, "stub") == 0)
1596*00b67f09SDavid van Moolenbroek ztype = STUBZONE;
1597*00b67f09SDavid van Moolenbroek else if (strcasecmp(typestr, "static-stub") == 0)
1598*00b67f09SDavid van Moolenbroek ztype = STATICSTUBZONE;
1599*00b67f09SDavid van Moolenbroek else if (strcasecmp(typestr, "forward") == 0)
1600*00b67f09SDavid van Moolenbroek ztype = FORWARDZONE;
1601*00b67f09SDavid van Moolenbroek else if (strcasecmp(typestr, "hint") == 0)
1602*00b67f09SDavid van Moolenbroek ztype = HINTZONE;
1603*00b67f09SDavid van Moolenbroek else if (strcasecmp(typestr, "delegation-only") == 0)
1604*00b67f09SDavid van Moolenbroek ztype = DELEGATIONZONE;
1605*00b67f09SDavid van Moolenbroek else if (strcasecmp(typestr, "redirect") == 0)
1606*00b67f09SDavid van Moolenbroek ztype = REDIRECTZONE;
1607*00b67f09SDavid van Moolenbroek else {
1608*00b67f09SDavid van Moolenbroek cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
1609*00b67f09SDavid van Moolenbroek "zone '%s': invalid type %s",
1610*00b67f09SDavid van Moolenbroek znamestr, typestr);
1611*00b67f09SDavid van Moolenbroek return (ISC_R_FAILURE);
1612*00b67f09SDavid van Moolenbroek }
1613*00b67f09SDavid van Moolenbroek
1614*00b67f09SDavid van Moolenbroek if (ztype == REDIRECTZONE && strcmp(znamestr, ".") != 0) {
1615*00b67f09SDavid van Moolenbroek cfg_obj_log(zconfig, logctx, ISC_LOG_ERROR,
1616*00b67f09SDavid van Moolenbroek "redirect zones must be called \".\"");
1617*00b67f09SDavid van Moolenbroek return (ISC_R_FAILURE);
1618*00b67f09SDavid van Moolenbroek }
1619*00b67f09SDavid van Moolenbroek obj = cfg_tuple_get(zconfig, "class");
1620*00b67f09SDavid van Moolenbroek if (cfg_obj_isstring(obj)) {
1621*00b67f09SDavid van Moolenbroek isc_textregion_t r;
1622*00b67f09SDavid van Moolenbroek
1623*00b67f09SDavid van Moolenbroek DE_CONST(cfg_obj_asstring(obj), r.base);
1624*00b67f09SDavid van Moolenbroek r.length = strlen(r.base);
1625*00b67f09SDavid van Moolenbroek result = dns_rdataclass_fromtext(&zclass, &r);
1626*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS) {
1627*00b67f09SDavid van Moolenbroek cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
1628*00b67f09SDavid van Moolenbroek "zone '%s': invalid class %s",
1629*00b67f09SDavid van Moolenbroek znamestr, r.base);
1630*00b67f09SDavid van Moolenbroek return (ISC_R_FAILURE);
1631*00b67f09SDavid van Moolenbroek }
1632*00b67f09SDavid van Moolenbroek if (zclass != defclass) {
1633*00b67f09SDavid van Moolenbroek cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
1634*00b67f09SDavid van Moolenbroek "zone '%s': class '%s' does not "
1635*00b67f09SDavid van Moolenbroek "match view/default class",
1636*00b67f09SDavid van Moolenbroek znamestr, r.base);
1637*00b67f09SDavid van Moolenbroek return (ISC_R_FAILURE);
1638*00b67f09SDavid van Moolenbroek }
1639*00b67f09SDavid van Moolenbroek }
1640*00b67f09SDavid van Moolenbroek
1641*00b67f09SDavid van Moolenbroek /*
1642*00b67f09SDavid van Moolenbroek * Look for an already existing zone.
1643*00b67f09SDavid van Moolenbroek * We need to make this canonical as isc_symtab_define()
1644*00b67f09SDavid van Moolenbroek * deals with strings.
1645*00b67f09SDavid van Moolenbroek */
1646*00b67f09SDavid van Moolenbroek dns_fixedname_init(&fixedname);
1647*00b67f09SDavid van Moolenbroek isc_buffer_constinit(&b, znamestr, strlen(znamestr));
1648*00b67f09SDavid van Moolenbroek isc_buffer_add(&b, strlen(znamestr));
1649*00b67f09SDavid van Moolenbroek tresult = dns_name_fromtext(dns_fixedname_name(&fixedname), &b,
1650*00b67f09SDavid van Moolenbroek dns_rootname, DNS_NAME_DOWNCASE, NULL);
1651*00b67f09SDavid van Moolenbroek if (tresult != ISC_R_SUCCESS) {
1652*00b67f09SDavid van Moolenbroek cfg_obj_log(zconfig, logctx, ISC_LOG_ERROR,
1653*00b67f09SDavid van Moolenbroek "zone '%s': is not a valid name", znamestr);
1654*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
1655*00b67f09SDavid van Moolenbroek } else {
1656*00b67f09SDavid van Moolenbroek char namebuf[DNS_NAME_FORMATSIZE];
1657*00b67f09SDavid van Moolenbroek
1658*00b67f09SDavid van Moolenbroek zname = dns_fixedname_name(&fixedname);
1659*00b67f09SDavid van Moolenbroek dns_name_format(zname, namebuf, sizeof(namebuf));
1660*00b67f09SDavid van Moolenbroek tresult = nameexist(zconfig, namebuf, ztype == HINTZONE ? 1 :
1661*00b67f09SDavid van Moolenbroek ztype == REDIRECTZONE ? 2 : 3,
1662*00b67f09SDavid van Moolenbroek symtab, "zone '%s': already exists "
1663*00b67f09SDavid van Moolenbroek "previous definition: %s:%u", logctx, mctx);
1664*00b67f09SDavid van Moolenbroek if (tresult != ISC_R_SUCCESS)
1665*00b67f09SDavid van Moolenbroek result = tresult;
1666*00b67f09SDavid van Moolenbroek if (dns_name_equal(zname, dns_rootname))
1667*00b67f09SDavid van Moolenbroek root = ISC_TRUE;
1668*00b67f09SDavid van Moolenbroek }
1669*00b67f09SDavid van Moolenbroek
1670*00b67f09SDavid van Moolenbroek /*
1671*00b67f09SDavid van Moolenbroek * Check if value is zero.
1672*00b67f09SDavid van Moolenbroek */
1673*00b67f09SDavid van Moolenbroek if (check_nonzero(zoptions, logctx) != ISC_R_SUCCESS)
1674*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
1675*00b67f09SDavid van Moolenbroek
1676*00b67f09SDavid van Moolenbroek /*
1677*00b67f09SDavid van Moolenbroek * Look for inappropriate options for the given zone type.
1678*00b67f09SDavid van Moolenbroek * Check that ACLs expand correctly.
1679*00b67f09SDavid van Moolenbroek */
1680*00b67f09SDavid van Moolenbroek for (i = 0; i < sizeof(options) / sizeof(options[0]); i++) {
1681*00b67f09SDavid van Moolenbroek obj = NULL;
1682*00b67f09SDavid van Moolenbroek if ((options[i].allowed & ztype) == 0 &&
1683*00b67f09SDavid van Moolenbroek cfg_map_get(zoptions, options[i].name, &obj) ==
1684*00b67f09SDavid van Moolenbroek ISC_R_SUCCESS)
1685*00b67f09SDavid van Moolenbroek {
1686*00b67f09SDavid van Moolenbroek if (strcmp(options[i].name, "allow-update") != 0 ||
1687*00b67f09SDavid van Moolenbroek ztype != SLAVEZONE) {
1688*00b67f09SDavid van Moolenbroek cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
1689*00b67f09SDavid van Moolenbroek "option '%s' is not allowed "
1690*00b67f09SDavid van Moolenbroek "in '%s' zone '%s'",
1691*00b67f09SDavid van Moolenbroek options[i].name, typestr,
1692*00b67f09SDavid van Moolenbroek znamestr);
1693*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
1694*00b67f09SDavid van Moolenbroek } else
1695*00b67f09SDavid van Moolenbroek cfg_obj_log(obj, logctx, ISC_LOG_WARNING,
1696*00b67f09SDavid van Moolenbroek "option '%s' is not allowed "
1697*00b67f09SDavid van Moolenbroek "in '%s' zone '%s'",
1698*00b67f09SDavid van Moolenbroek options[i].name, typestr,
1699*00b67f09SDavid van Moolenbroek znamestr);
1700*00b67f09SDavid van Moolenbroek }
1701*00b67f09SDavid van Moolenbroek obj = NULL;
1702*00b67f09SDavid van Moolenbroek if ((options[i].allowed & ztype) != 0 &&
1703*00b67f09SDavid van Moolenbroek (options[i].allowed & CHECKACL) != 0) {
1704*00b67f09SDavid van Moolenbroek
1705*00b67f09SDavid van Moolenbroek tresult = checkacl(options[i].name, actx, zconfig,
1706*00b67f09SDavid van Moolenbroek voptions, config, logctx, mctx);
1707*00b67f09SDavid van Moolenbroek if (tresult != ISC_R_SUCCESS)
1708*00b67f09SDavid van Moolenbroek result = tresult;
1709*00b67f09SDavid van Moolenbroek }
1710*00b67f09SDavid van Moolenbroek
1711*00b67f09SDavid van Moolenbroek }
1712*00b67f09SDavid van Moolenbroek
1713*00b67f09SDavid van Moolenbroek /*
1714*00b67f09SDavid van Moolenbroek * Master & slave zones may have an "also-notify" field, but
1715*00b67f09SDavid van Moolenbroek * shouldn't if notify is disabled.
1716*00b67f09SDavid van Moolenbroek */
1717*00b67f09SDavid van Moolenbroek if (ztype == MASTERZONE || ztype == SLAVEZONE ) {
1718*00b67f09SDavid van Moolenbroek isc_boolean_t donotify = ISC_TRUE;
1719*00b67f09SDavid van Moolenbroek
1720*00b67f09SDavid van Moolenbroek obj = NULL;
1721*00b67f09SDavid van Moolenbroek tresult = cfg_map_get(zoptions, "notify", &obj);
1722*00b67f09SDavid van Moolenbroek if (tresult != ISC_R_SUCCESS && voptions != NULL)
1723*00b67f09SDavid van Moolenbroek tresult = cfg_map_get(voptions, "notify", &obj);
1724*00b67f09SDavid van Moolenbroek if (tresult != ISC_R_SUCCESS && goptions != NULL)
1725*00b67f09SDavid van Moolenbroek tresult = cfg_map_get(goptions, "notify", &obj);
1726*00b67f09SDavid van Moolenbroek if (tresult == ISC_R_SUCCESS) {
1727*00b67f09SDavid van Moolenbroek if (cfg_obj_isboolean(obj))
1728*00b67f09SDavid van Moolenbroek donotify = cfg_obj_asboolean(obj);
1729*00b67f09SDavid van Moolenbroek else {
1730*00b67f09SDavid van Moolenbroek const char *notifystr = cfg_obj_asstring(obj);
1731*00b67f09SDavid van Moolenbroek if (ztype != MASTERZONE &&
1732*00b67f09SDavid van Moolenbroek strcasecmp(notifystr, "master-only") == 0)
1733*00b67f09SDavid van Moolenbroek donotify = ISC_FALSE;
1734*00b67f09SDavid van Moolenbroek }
1735*00b67f09SDavid van Moolenbroek }
1736*00b67f09SDavid van Moolenbroek
1737*00b67f09SDavid van Moolenbroek obj = NULL;
1738*00b67f09SDavid van Moolenbroek tresult = cfg_map_get(zoptions, "also-notify", &obj);
1739*00b67f09SDavid van Moolenbroek if (tresult == ISC_R_SUCCESS && !donotify) {
1740*00b67f09SDavid van Moolenbroek cfg_obj_log(zoptions, logctx, ISC_LOG_WARNING,
1741*00b67f09SDavid van Moolenbroek "zone '%s': 'also-notify' set but "
1742*00b67f09SDavid van Moolenbroek "'notify' is disabled", znamestr);
1743*00b67f09SDavid van Moolenbroek } else if (tresult == ISC_R_SUCCESS) {
1744*00b67f09SDavid van Moolenbroek isc_uint32_t count;
1745*00b67f09SDavid van Moolenbroek tresult = validate_masters(obj, config, &count,
1746*00b67f09SDavid van Moolenbroek logctx, mctx);
1747*00b67f09SDavid van Moolenbroek if (tresult != ISC_R_SUCCESS && result == ISC_R_SUCCESS)
1748*00b67f09SDavid van Moolenbroek result = tresult;
1749*00b67f09SDavid van Moolenbroek }
1750*00b67f09SDavid van Moolenbroek }
1751*00b67f09SDavid van Moolenbroek
1752*00b67f09SDavid van Moolenbroek /*
1753*00b67f09SDavid van Moolenbroek * Slave & stub zones must have a "masters" field.
1754*00b67f09SDavid van Moolenbroek */
1755*00b67f09SDavid van Moolenbroek if (ztype == SLAVEZONE || ztype == STUBZONE) {
1756*00b67f09SDavid van Moolenbroek obj = NULL;
1757*00b67f09SDavid van Moolenbroek if (cfg_map_get(zoptions, "masters", &obj) != ISC_R_SUCCESS) {
1758*00b67f09SDavid van Moolenbroek cfg_obj_log(zoptions, logctx, ISC_LOG_ERROR,
1759*00b67f09SDavid van Moolenbroek "zone '%s': missing 'masters' entry",
1760*00b67f09SDavid van Moolenbroek znamestr);
1761*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
1762*00b67f09SDavid van Moolenbroek } else {
1763*00b67f09SDavid van Moolenbroek isc_uint32_t count;
1764*00b67f09SDavid van Moolenbroek tresult = validate_masters(obj, config, &count,
1765*00b67f09SDavid van Moolenbroek logctx, mctx);
1766*00b67f09SDavid van Moolenbroek if (tresult != ISC_R_SUCCESS && result == ISC_R_SUCCESS)
1767*00b67f09SDavid van Moolenbroek result = tresult;
1768*00b67f09SDavid van Moolenbroek if (tresult == ISC_R_SUCCESS && count == 0) {
1769*00b67f09SDavid van Moolenbroek cfg_obj_log(zoptions, logctx, ISC_LOG_ERROR,
1770*00b67f09SDavid van Moolenbroek "zone '%s': empty 'masters' entry",
1771*00b67f09SDavid van Moolenbroek znamestr);
1772*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
1773*00b67f09SDavid van Moolenbroek }
1774*00b67f09SDavid van Moolenbroek }
1775*00b67f09SDavid van Moolenbroek }
1776*00b67f09SDavid van Moolenbroek
1777*00b67f09SDavid van Moolenbroek /*
1778*00b67f09SDavid van Moolenbroek * Master zones can't have both "allow-update" and "update-policy".
1779*00b67f09SDavid van Moolenbroek */
1780*00b67f09SDavid van Moolenbroek if (ztype == MASTERZONE || ztype == SLAVEZONE) {
1781*00b67f09SDavid van Moolenbroek isc_boolean_t signing = ISC_FALSE;
1782*00b67f09SDavid van Moolenbroek isc_result_t res1, res2, res3;
1783*00b67f09SDavid van Moolenbroek const cfg_obj_t *au = NULL;
1784*00b67f09SDavid van Moolenbroek const char *arg;
1785*00b67f09SDavid van Moolenbroek
1786*00b67f09SDavid van Moolenbroek obj = NULL;
1787*00b67f09SDavid van Moolenbroek res1 = cfg_map_get(zoptions, "allow-update", &au);
1788*00b67f09SDavid van Moolenbroek obj = NULL;
1789*00b67f09SDavid van Moolenbroek res2 = cfg_map_get(zoptions, "update-policy", &obj);
1790*00b67f09SDavid van Moolenbroek if (res1 == ISC_R_SUCCESS && res2 == ISC_R_SUCCESS) {
1791*00b67f09SDavid van Moolenbroek cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
1792*00b67f09SDavid van Moolenbroek "zone '%s': 'allow-update' is ignored "
1793*00b67f09SDavid van Moolenbroek "when 'update-policy' is present",
1794*00b67f09SDavid van Moolenbroek znamestr);
1795*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
1796*00b67f09SDavid van Moolenbroek } else if (res2 == ISC_R_SUCCESS) {
1797*00b67f09SDavid van Moolenbroek res3 = check_update_policy(obj, logctx);
1798*00b67f09SDavid van Moolenbroek if (res3 != ISC_R_SUCCESS)
1799*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
1800*00b67f09SDavid van Moolenbroek }
1801*00b67f09SDavid van Moolenbroek
1802*00b67f09SDavid van Moolenbroek /*
1803*00b67f09SDavid van Moolenbroek * To determine whether auto-dnssec is allowed,
1804*00b67f09SDavid van Moolenbroek * we should also check for allow-update at the
1805*00b67f09SDavid van Moolenbroek * view and options levels.
1806*00b67f09SDavid van Moolenbroek */
1807*00b67f09SDavid van Moolenbroek if (res1 != ISC_R_SUCCESS && voptions != NULL)
1808*00b67f09SDavid van Moolenbroek res1 = cfg_map_get(voptions, "allow-update", &au);
1809*00b67f09SDavid van Moolenbroek if (res1 != ISC_R_SUCCESS && goptions != NULL)
1810*00b67f09SDavid van Moolenbroek res1 = cfg_map_get(goptions, "allow-update", &au);
1811*00b67f09SDavid van Moolenbroek
1812*00b67f09SDavid van Moolenbroek if (res2 == ISC_R_SUCCESS)
1813*00b67f09SDavid van Moolenbroek ddns = ISC_TRUE;
1814*00b67f09SDavid van Moolenbroek else if (res1 == ISC_R_SUCCESS) {
1815*00b67f09SDavid van Moolenbroek dns_acl_t *acl = NULL;
1816*00b67f09SDavid van Moolenbroek res1 = cfg_acl_fromconfig(au, config, logctx,
1817*00b67f09SDavid van Moolenbroek actx, mctx, 0, &acl);
1818*00b67f09SDavid van Moolenbroek if (res1 != ISC_R_SUCCESS) {
1819*00b67f09SDavid van Moolenbroek cfg_obj_log(au, logctx, ISC_LOG_ERROR,
1820*00b67f09SDavid van Moolenbroek "acl expansion failed: %s",
1821*00b67f09SDavid van Moolenbroek isc_result_totext(result));
1822*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
1823*00b67f09SDavid van Moolenbroek } else if (acl != NULL) {
1824*00b67f09SDavid van Moolenbroek if (!dns_acl_isnone(acl))
1825*00b67f09SDavid van Moolenbroek ddns = ISC_TRUE;
1826*00b67f09SDavid van Moolenbroek dns_acl_detach(&acl);
1827*00b67f09SDavid van Moolenbroek }
1828*00b67f09SDavid van Moolenbroek }
1829*00b67f09SDavid van Moolenbroek
1830*00b67f09SDavid van Moolenbroek obj = NULL;
1831*00b67f09SDavid van Moolenbroek res1 = cfg_map_get(zoptions, "inline-signing", &obj);
1832*00b67f09SDavid van Moolenbroek if (res1 == ISC_R_SUCCESS)
1833*00b67f09SDavid van Moolenbroek signing = cfg_obj_asboolean(obj);
1834*00b67f09SDavid van Moolenbroek
1835*00b67f09SDavid van Moolenbroek obj = NULL;
1836*00b67f09SDavid van Moolenbroek arg = "off";
1837*00b67f09SDavid van Moolenbroek res3 = cfg_map_get(zoptions, "auto-dnssec", &obj);
1838*00b67f09SDavid van Moolenbroek if (res3 == ISC_R_SUCCESS)
1839*00b67f09SDavid van Moolenbroek arg = cfg_obj_asstring(obj);
1840*00b67f09SDavid van Moolenbroek if (strcasecmp(arg, "off") != 0 && !ddns && !signing) {
1841*00b67f09SDavid van Moolenbroek cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
1842*00b67f09SDavid van Moolenbroek "'auto-dnssec %s;' requires%s "
1843*00b67f09SDavid van Moolenbroek "inline-signing to be configured for "
1844*00b67f09SDavid van Moolenbroek "the zone", arg,
1845*00b67f09SDavid van Moolenbroek (ztype == MASTERZONE) ?
1846*00b67f09SDavid van Moolenbroek " dynamic DNS or" : "");
1847*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
1848*00b67f09SDavid van Moolenbroek }
1849*00b67f09SDavid van Moolenbroek
1850*00b67f09SDavid van Moolenbroek obj = NULL;
1851*00b67f09SDavid van Moolenbroek res1 = cfg_map_get(zoptions, "sig-signing-type", &obj);
1852*00b67f09SDavid van Moolenbroek if (res1 == ISC_R_SUCCESS) {
1853*00b67f09SDavid van Moolenbroek isc_uint32_t type = cfg_obj_asuint32(obj);
1854*00b67f09SDavid van Moolenbroek if (type < 0xff00U || type > 0xffffU)
1855*00b67f09SDavid van Moolenbroek cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
1856*00b67f09SDavid van Moolenbroek "sig-signing-type: %u out of "
1857*00b67f09SDavid van Moolenbroek "range [%u..%u]", type,
1858*00b67f09SDavid van Moolenbroek 0xff00U, 0xffffU);
1859*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
1860*00b67f09SDavid van Moolenbroek }
1861*00b67f09SDavid van Moolenbroek
1862*00b67f09SDavid van Moolenbroek obj = NULL;
1863*00b67f09SDavid van Moolenbroek res1 = cfg_map_get(zoptions, "dnssec-dnskey-kskonly", &obj);
1864*00b67f09SDavid van Moolenbroek if (res1 == ISC_R_SUCCESS && ztype == SLAVEZONE && !signing) {
1865*00b67f09SDavid van Moolenbroek cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
1866*00b67f09SDavid van Moolenbroek "dnssec-dnskey-kskonly: requires "
1867*00b67f09SDavid van Moolenbroek "inline-signing when used in slave zone");
1868*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
1869*00b67f09SDavid van Moolenbroek }
1870*00b67f09SDavid van Moolenbroek
1871*00b67f09SDavid van Moolenbroek obj = NULL;
1872*00b67f09SDavid van Moolenbroek res1 = cfg_map_get(zoptions, "dnssec-loadkeys-interval", &obj);
1873*00b67f09SDavid van Moolenbroek if (res1 == ISC_R_SUCCESS && ztype == SLAVEZONE && !signing) {
1874*00b67f09SDavid van Moolenbroek cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
1875*00b67f09SDavid van Moolenbroek "dnssec-loadkeys-interval: requires "
1876*00b67f09SDavid van Moolenbroek "inline-signing when used in slave zone");
1877*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
1878*00b67f09SDavid van Moolenbroek }
1879*00b67f09SDavid van Moolenbroek
1880*00b67f09SDavid van Moolenbroek obj = NULL;
1881*00b67f09SDavid van Moolenbroek res1 = cfg_map_get(zoptions, "update-check-ksk", &obj);
1882*00b67f09SDavid van Moolenbroek if (res1 == ISC_R_SUCCESS && ztype == SLAVEZONE && !signing) {
1883*00b67f09SDavid van Moolenbroek cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
1884*00b67f09SDavid van Moolenbroek "update-check-ksk: requires "
1885*00b67f09SDavid van Moolenbroek "inline-signing when used in slave zone");
1886*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
1887*00b67f09SDavid van Moolenbroek }
1888*00b67f09SDavid van Moolenbroek }
1889*00b67f09SDavid van Moolenbroek
1890*00b67f09SDavid van Moolenbroek /*
1891*00b67f09SDavid van Moolenbroek * Check the excessively complicated "dialup" option.
1892*00b67f09SDavid van Moolenbroek */
1893*00b67f09SDavid van Moolenbroek if (ztype == MASTERZONE || ztype == SLAVEZONE || ztype == STUBZONE) {
1894*00b67f09SDavid van Moolenbroek const cfg_obj_t *dialup = NULL;
1895*00b67f09SDavid van Moolenbroek (void)cfg_map_get(zoptions, "dialup", &dialup);
1896*00b67f09SDavid van Moolenbroek if (dialup != NULL && cfg_obj_isstring(dialup)) {
1897*00b67f09SDavid van Moolenbroek const char *str = cfg_obj_asstring(dialup);
1898*00b67f09SDavid van Moolenbroek for (i = 0;
1899*00b67f09SDavid van Moolenbroek i < sizeof(dialups) / sizeof(dialups[0]);
1900*00b67f09SDavid van Moolenbroek i++)
1901*00b67f09SDavid van Moolenbroek {
1902*00b67f09SDavid van Moolenbroek if (strcasecmp(dialups[i].name, str) != 0)
1903*00b67f09SDavid van Moolenbroek continue;
1904*00b67f09SDavid van Moolenbroek if ((dialups[i].allowed & ztype) == 0) {
1905*00b67f09SDavid van Moolenbroek cfg_obj_log(obj, logctx,
1906*00b67f09SDavid van Moolenbroek ISC_LOG_ERROR,
1907*00b67f09SDavid van Moolenbroek "dialup type '%s' is not "
1908*00b67f09SDavid van Moolenbroek "allowed in '%s' "
1909*00b67f09SDavid van Moolenbroek "zone '%s'",
1910*00b67f09SDavid van Moolenbroek str, typestr, znamestr);
1911*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
1912*00b67f09SDavid van Moolenbroek }
1913*00b67f09SDavid van Moolenbroek break;
1914*00b67f09SDavid van Moolenbroek }
1915*00b67f09SDavid van Moolenbroek if (i == sizeof(dialups) / sizeof(dialups[0])) {
1916*00b67f09SDavid van Moolenbroek cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
1917*00b67f09SDavid van Moolenbroek "invalid dialup type '%s' in zone "
1918*00b67f09SDavid van Moolenbroek "'%s'", str, znamestr);
1919*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
1920*00b67f09SDavid van Moolenbroek }
1921*00b67f09SDavid van Moolenbroek }
1922*00b67f09SDavid van Moolenbroek }
1923*00b67f09SDavid van Moolenbroek
1924*00b67f09SDavid van Moolenbroek /*
1925*00b67f09SDavid van Moolenbroek * Check that forwarding is reasonable.
1926*00b67f09SDavid van Moolenbroek */
1927*00b67f09SDavid van Moolenbroek obj = NULL;
1928*00b67f09SDavid van Moolenbroek if (root) {
1929*00b67f09SDavid van Moolenbroek if (voptions != NULL)
1930*00b67f09SDavid van Moolenbroek (void)cfg_map_get(voptions, "forwarders", &obj);
1931*00b67f09SDavid van Moolenbroek if (obj == NULL && goptions != NULL)
1932*00b67f09SDavid van Moolenbroek (void)cfg_map_get(goptions, "forwarders", &obj);
1933*00b67f09SDavid van Moolenbroek }
1934*00b67f09SDavid van Moolenbroek if (check_forward(zoptions, obj, logctx) != ISC_R_SUCCESS)
1935*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
1936*00b67f09SDavid van Moolenbroek
1937*00b67f09SDavid van Moolenbroek /*
1938*00b67f09SDavid van Moolenbroek * Check validity of static stub server addresses.
1939*00b67f09SDavid van Moolenbroek */
1940*00b67f09SDavid van Moolenbroek obj = NULL;
1941*00b67f09SDavid van Moolenbroek (void)cfg_map_get(zoptions, "server-addresses", &obj);
1942*00b67f09SDavid van Moolenbroek if (ztype == STATICSTUBZONE && obj != NULL) {
1943*00b67f09SDavid van Moolenbroek for (element = cfg_list_first(obj);
1944*00b67f09SDavid van Moolenbroek element != NULL;
1945*00b67f09SDavid van Moolenbroek element = cfg_list_next(element))
1946*00b67f09SDavid van Moolenbroek {
1947*00b67f09SDavid van Moolenbroek isc_sockaddr_t sa;
1948*00b67f09SDavid van Moolenbroek isc_netaddr_t na;
1949*00b67f09SDavid van Moolenbroek obj = cfg_listelt_value(element);
1950*00b67f09SDavid van Moolenbroek sa = *cfg_obj_assockaddr(obj);
1951*00b67f09SDavid van Moolenbroek
1952*00b67f09SDavid van Moolenbroek if (isc_sockaddr_getport(&sa) != 0) {
1953*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
1954*00b67f09SDavid van Moolenbroek cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
1955*00b67f09SDavid van Moolenbroek "port is not configurable for "
1956*00b67f09SDavid van Moolenbroek "static stub server-addresses");
1957*00b67f09SDavid van Moolenbroek }
1958*00b67f09SDavid van Moolenbroek
1959*00b67f09SDavid van Moolenbroek isc_netaddr_fromsockaddr(&na, &sa);
1960*00b67f09SDavid van Moolenbroek if (isc_netaddr_getzone(&na) != 0) {
1961*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
1962*00b67f09SDavid van Moolenbroek cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
1963*00b67f09SDavid van Moolenbroek "scoped address is not allowed "
1964*00b67f09SDavid van Moolenbroek "for static stub "
1965*00b67f09SDavid van Moolenbroek "server-addresses");
1966*00b67f09SDavid van Moolenbroek }
1967*00b67f09SDavid van Moolenbroek }
1968*00b67f09SDavid van Moolenbroek }
1969*00b67f09SDavid van Moolenbroek
1970*00b67f09SDavid van Moolenbroek /*
1971*00b67f09SDavid van Moolenbroek * Check validity of static stub server names.
1972*00b67f09SDavid van Moolenbroek */
1973*00b67f09SDavid van Moolenbroek obj = NULL;
1974*00b67f09SDavid van Moolenbroek (void)cfg_map_get(zoptions, "server-names", &obj);
1975*00b67f09SDavid van Moolenbroek if (zname != NULL && ztype == STATICSTUBZONE && obj != NULL) {
1976*00b67f09SDavid van Moolenbroek for (element = cfg_list_first(obj);
1977*00b67f09SDavid van Moolenbroek element != NULL;
1978*00b67f09SDavid van Moolenbroek element = cfg_list_next(element))
1979*00b67f09SDavid van Moolenbroek {
1980*00b67f09SDavid van Moolenbroek const char *snamestr;
1981*00b67f09SDavid van Moolenbroek dns_fixedname_t fixed_sname;
1982*00b67f09SDavid van Moolenbroek isc_buffer_t b2;
1983*00b67f09SDavid van Moolenbroek dns_name_t *sname;
1984*00b67f09SDavid van Moolenbroek
1985*00b67f09SDavid van Moolenbroek obj = cfg_listelt_value(element);
1986*00b67f09SDavid van Moolenbroek snamestr = cfg_obj_asstring(obj);
1987*00b67f09SDavid van Moolenbroek
1988*00b67f09SDavid van Moolenbroek dns_fixedname_init(&fixed_sname);
1989*00b67f09SDavid van Moolenbroek isc_buffer_constinit(&b2, snamestr, strlen(snamestr));
1990*00b67f09SDavid van Moolenbroek isc_buffer_add(&b2, strlen(snamestr));
1991*00b67f09SDavid van Moolenbroek sname = dns_fixedname_name(&fixed_sname);
1992*00b67f09SDavid van Moolenbroek tresult = dns_name_fromtext(sname, &b2, dns_rootname,
1993*00b67f09SDavid van Moolenbroek 0, NULL);
1994*00b67f09SDavid van Moolenbroek if (tresult != ISC_R_SUCCESS) {
1995*00b67f09SDavid van Moolenbroek cfg_obj_log(zconfig, logctx, ISC_LOG_ERROR,
1996*00b67f09SDavid van Moolenbroek "server-name '%s' is not a valid "
1997*00b67f09SDavid van Moolenbroek "name", snamestr);
1998*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
1999*00b67f09SDavid van Moolenbroek } else if (dns_name_issubdomain(sname, zname)) {
2000*00b67f09SDavid van Moolenbroek cfg_obj_log(zconfig, logctx, ISC_LOG_ERROR,
2001*00b67f09SDavid van Moolenbroek "server-name '%s' must not be a "
2002*00b67f09SDavid van Moolenbroek "subdomain of zone name '%s'",
2003*00b67f09SDavid van Moolenbroek snamestr, znamestr);
2004*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
2005*00b67f09SDavid van Moolenbroek }
2006*00b67f09SDavid van Moolenbroek }
2007*00b67f09SDavid van Moolenbroek }
2008*00b67f09SDavid van Moolenbroek
2009*00b67f09SDavid van Moolenbroek
2010*00b67f09SDavid van Moolenbroek /*
2011*00b67f09SDavid van Moolenbroek * Check that max-zone-ttl isn't used with masterfile-format map
2012*00b67f09SDavid van Moolenbroek */
2013*00b67f09SDavid van Moolenbroek masterformat = dns_masterformat_text;
2014*00b67f09SDavid van Moolenbroek obj = NULL;
2015*00b67f09SDavid van Moolenbroek (void)cfg_map_get(zoptions, "masterfile-format", &obj);
2016*00b67f09SDavid van Moolenbroek if (obj != NULL) {
2017*00b67f09SDavid van Moolenbroek const char *masterformatstr = cfg_obj_asstring(obj);
2018*00b67f09SDavid van Moolenbroek if (strcasecmp(masterformatstr, "text") == 0)
2019*00b67f09SDavid van Moolenbroek masterformat = dns_masterformat_text;
2020*00b67f09SDavid van Moolenbroek else if (strcasecmp(masterformatstr, "raw") == 0)
2021*00b67f09SDavid van Moolenbroek masterformat = dns_masterformat_raw;
2022*00b67f09SDavid van Moolenbroek else if (strcasecmp(masterformatstr, "map") == 0)
2023*00b67f09SDavid van Moolenbroek masterformat = dns_masterformat_map;
2024*00b67f09SDavid van Moolenbroek else
2025*00b67f09SDavid van Moolenbroek INSIST(0);
2026*00b67f09SDavid van Moolenbroek }
2027*00b67f09SDavid van Moolenbroek
2028*00b67f09SDavid van Moolenbroek if (masterformat == dns_masterformat_map) {
2029*00b67f09SDavid van Moolenbroek obj = NULL;
2030*00b67f09SDavid van Moolenbroek (void)cfg_map_get(zoptions, "max-zone-ttl", &obj);
2031*00b67f09SDavid van Moolenbroek if (obj == NULL && voptions != NULL)
2032*00b67f09SDavid van Moolenbroek (void)cfg_map_get(voptions, "max-zone-ttl", &obj);
2033*00b67f09SDavid van Moolenbroek if (obj == NULL && goptions !=NULL)
2034*00b67f09SDavid van Moolenbroek (void)cfg_map_get(goptions, "max-zone-ttl", &obj);
2035*00b67f09SDavid van Moolenbroek if (obj != NULL) {
2036*00b67f09SDavid van Moolenbroek cfg_obj_log(zconfig, logctx, ISC_LOG_ERROR,
2037*00b67f09SDavid van Moolenbroek "zone '%s': 'max-zone-ttl' is not "
2038*00b67f09SDavid van Moolenbroek "compatible with 'masterfile-format map'",
2039*00b67f09SDavid van Moolenbroek znamestr);
2040*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
2041*00b67f09SDavid van Moolenbroek }
2042*00b67f09SDavid van Moolenbroek }
2043*00b67f09SDavid van Moolenbroek
2044*00b67f09SDavid van Moolenbroek /*
2045*00b67f09SDavid van Moolenbroek * Warn if key-directory doesn't exist
2046*00b67f09SDavid van Moolenbroek */
2047*00b67f09SDavid van Moolenbroek obj = NULL;
2048*00b67f09SDavid van Moolenbroek tresult = cfg_map_get(zoptions, "key-directory", &obj);
2049*00b67f09SDavid van Moolenbroek if (tresult == ISC_R_SUCCESS) {
2050*00b67f09SDavid van Moolenbroek const char *dir = cfg_obj_asstring(obj);
2051*00b67f09SDavid van Moolenbroek tresult = isc_file_isdirectory(dir);
2052*00b67f09SDavid van Moolenbroek switch (tresult) {
2053*00b67f09SDavid van Moolenbroek case ISC_R_SUCCESS:
2054*00b67f09SDavid van Moolenbroek break;
2055*00b67f09SDavid van Moolenbroek case ISC_R_FILENOTFOUND:
2056*00b67f09SDavid van Moolenbroek cfg_obj_log(obj, logctx, ISC_LOG_WARNING,
2057*00b67f09SDavid van Moolenbroek "key-directory: '%s' does not exist",
2058*00b67f09SDavid van Moolenbroek dir);
2059*00b67f09SDavid van Moolenbroek break;
2060*00b67f09SDavid van Moolenbroek case ISC_R_INVALIDFILE:
2061*00b67f09SDavid van Moolenbroek cfg_obj_log(obj, logctx, ISC_LOG_WARNING,
2062*00b67f09SDavid van Moolenbroek "key-directory: '%s' is not a directory",
2063*00b67f09SDavid van Moolenbroek dir);
2064*00b67f09SDavid van Moolenbroek break;
2065*00b67f09SDavid van Moolenbroek default:
2066*00b67f09SDavid van Moolenbroek cfg_obj_log(obj, logctx, ISC_LOG_WARNING,
2067*00b67f09SDavid van Moolenbroek "key-directory: '%s' %s",
2068*00b67f09SDavid van Moolenbroek dir, isc_result_totext(tresult));
2069*00b67f09SDavid van Moolenbroek result = tresult;
2070*00b67f09SDavid van Moolenbroek }
2071*00b67f09SDavid van Moolenbroek }
2072*00b67f09SDavid van Moolenbroek
2073*00b67f09SDavid van Moolenbroek /*
2074*00b67f09SDavid van Moolenbroek * Check various options.
2075*00b67f09SDavid van Moolenbroek */
2076*00b67f09SDavid van Moolenbroek tresult = check_options(zoptions, logctx, mctx, optlevel_zone);
2077*00b67f09SDavid van Moolenbroek if (tresult != ISC_R_SUCCESS)
2078*00b67f09SDavid van Moolenbroek result = tresult;
2079*00b67f09SDavid van Moolenbroek
2080*00b67f09SDavid van Moolenbroek /*
2081*00b67f09SDavid van Moolenbroek * If the zone type is rbt/rbt64 then master/hint zones
2082*00b67f09SDavid van Moolenbroek * require file clauses.
2083*00b67f09SDavid van Moolenbroek * If inline signing is used, then slave zones require a
2084*00b67f09SDavid van Moolenbroek * file clause as well
2085*00b67f09SDavid van Moolenbroek */
2086*00b67f09SDavid van Moolenbroek obj = NULL;
2087*00b67f09SDavid van Moolenbroek dlz = ISC_FALSE;
2088*00b67f09SDavid van Moolenbroek tresult = cfg_map_get(zoptions, "dlz", &obj);
2089*00b67f09SDavid van Moolenbroek if (tresult == ISC_R_SUCCESS)
2090*00b67f09SDavid van Moolenbroek dlz = ISC_TRUE;
2091*00b67f09SDavid van Moolenbroek
2092*00b67f09SDavid van Moolenbroek obj = NULL;
2093*00b67f09SDavid van Moolenbroek tresult = cfg_map_get(zoptions, "database", &obj);
2094*00b67f09SDavid van Moolenbroek if (dlz && tresult == ISC_R_SUCCESS) {
2095*00b67f09SDavid van Moolenbroek cfg_obj_log(zconfig, logctx, ISC_LOG_ERROR,
2096*00b67f09SDavid van Moolenbroek "zone '%s': cannot specify both 'dlz' "
2097*00b67f09SDavid van Moolenbroek "and 'database'", znamestr);
2098*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
2099*00b67f09SDavid van Moolenbroek } else if (!dlz &&
2100*00b67f09SDavid van Moolenbroek (tresult == ISC_R_NOTFOUND ||
2101*00b67f09SDavid van Moolenbroek (tresult == ISC_R_SUCCESS &&
2102*00b67f09SDavid van Moolenbroek (strcmp("rbt", cfg_obj_asstring(obj)) == 0 ||
2103*00b67f09SDavid van Moolenbroek strcmp("rbt64", cfg_obj_asstring(obj)) == 0))))
2104*00b67f09SDavid van Moolenbroek {
2105*00b67f09SDavid van Moolenbroek isc_result_t res1;
2106*00b67f09SDavid van Moolenbroek const cfg_obj_t *fileobj = NULL;
2107*00b67f09SDavid van Moolenbroek tresult = cfg_map_get(zoptions, "file", &fileobj);
2108*00b67f09SDavid van Moolenbroek obj = NULL;
2109*00b67f09SDavid van Moolenbroek res1 = cfg_map_get(zoptions, "inline-signing", &obj);
2110*00b67f09SDavid van Moolenbroek if ((tresult != ISC_R_SUCCESS &&
2111*00b67f09SDavid van Moolenbroek (ztype == MASTERZONE || ztype == HINTZONE ||
2112*00b67f09SDavid van Moolenbroek (ztype == SLAVEZONE && res1 == ISC_R_SUCCESS &&
2113*00b67f09SDavid van Moolenbroek cfg_obj_asboolean(obj))))) {
2114*00b67f09SDavid van Moolenbroek cfg_obj_log(zconfig, logctx, ISC_LOG_ERROR,
2115*00b67f09SDavid van Moolenbroek "zone '%s': missing 'file' entry",
2116*00b67f09SDavid van Moolenbroek znamestr);
2117*00b67f09SDavid van Moolenbroek result = tresult;
2118*00b67f09SDavid van Moolenbroek } else if (tresult == ISC_R_SUCCESS &&
2119*00b67f09SDavid van Moolenbroek (ztype == SLAVEZONE || ddns)) {
2120*00b67f09SDavid van Moolenbroek tresult = fileexist(fileobj, files, ISC_TRUE, logctx);
2121*00b67f09SDavid van Moolenbroek if (tresult != ISC_R_SUCCESS)
2122*00b67f09SDavid van Moolenbroek result = tresult;
2123*00b67f09SDavid van Moolenbroek } else if (tresult == ISC_R_SUCCESS &&
2124*00b67f09SDavid van Moolenbroek (ztype == MASTERZONE || ztype == HINTZONE)) {
2125*00b67f09SDavid van Moolenbroek tresult = fileexist(fileobj, files, ISC_FALSE, logctx);
2126*00b67f09SDavid van Moolenbroek if (tresult != ISC_R_SUCCESS)
2127*00b67f09SDavid van Moolenbroek result = tresult;
2128*00b67f09SDavid van Moolenbroek }
2129*00b67f09SDavid van Moolenbroek }
2130*00b67f09SDavid van Moolenbroek
2131*00b67f09SDavid van Moolenbroek return (result);
2132*00b67f09SDavid van Moolenbroek }
2133*00b67f09SDavid van Moolenbroek
2134*00b67f09SDavid van Moolenbroek
2135*00b67f09SDavid van Moolenbroek typedef struct keyalgorithms {
2136*00b67f09SDavid van Moolenbroek const char *name;
2137*00b67f09SDavid van Moolenbroek isc_uint16_t size;
2138*00b67f09SDavid van Moolenbroek } algorithmtable;
2139*00b67f09SDavid van Moolenbroek
2140*00b67f09SDavid van Moolenbroek isc_result_t
bind9_check_key(const cfg_obj_t * key,isc_log_t * logctx)2141*00b67f09SDavid van Moolenbroek bind9_check_key(const cfg_obj_t *key, isc_log_t *logctx) {
2142*00b67f09SDavid van Moolenbroek const cfg_obj_t *algobj = NULL;
2143*00b67f09SDavid van Moolenbroek const cfg_obj_t *secretobj = NULL;
2144*00b67f09SDavid van Moolenbroek const char *keyname = cfg_obj_asstring(cfg_map_getname(key));
2145*00b67f09SDavid van Moolenbroek const char *algorithm;
2146*00b67f09SDavid van Moolenbroek int i;
2147*00b67f09SDavid van Moolenbroek size_t len = 0;
2148*00b67f09SDavid van Moolenbroek isc_result_t result;
2149*00b67f09SDavid van Moolenbroek isc_buffer_t buf;
2150*00b67f09SDavid van Moolenbroek unsigned char secretbuf[1024];
2151*00b67f09SDavid van Moolenbroek static const algorithmtable algorithms[] = {
2152*00b67f09SDavid van Moolenbroek { "hmac-md5", 128 },
2153*00b67f09SDavid van Moolenbroek { "hmac-md5.sig-alg.reg.int", 0 },
2154*00b67f09SDavid van Moolenbroek { "hmac-md5.sig-alg.reg.int.", 0 },
2155*00b67f09SDavid van Moolenbroek { "hmac-sha1", 160 },
2156*00b67f09SDavid van Moolenbroek { "hmac-sha224", 224 },
2157*00b67f09SDavid van Moolenbroek { "hmac-sha256", 256 },
2158*00b67f09SDavid van Moolenbroek { "hmac-sha384", 384 },
2159*00b67f09SDavid van Moolenbroek { "hmac-sha512", 512 },
2160*00b67f09SDavid van Moolenbroek { NULL, 0 }
2161*00b67f09SDavid van Moolenbroek };
2162*00b67f09SDavid van Moolenbroek
2163*00b67f09SDavid van Moolenbroek (void)cfg_map_get(key, "algorithm", &algobj);
2164*00b67f09SDavid van Moolenbroek (void)cfg_map_get(key, "secret", &secretobj);
2165*00b67f09SDavid van Moolenbroek if (secretobj == NULL || algobj == NULL) {
2166*00b67f09SDavid van Moolenbroek cfg_obj_log(key, logctx, ISC_LOG_ERROR,
2167*00b67f09SDavid van Moolenbroek "key '%s' must have both 'secret' and "
2168*00b67f09SDavid van Moolenbroek "'algorithm' defined",
2169*00b67f09SDavid van Moolenbroek keyname);
2170*00b67f09SDavid van Moolenbroek return (ISC_R_FAILURE);
2171*00b67f09SDavid van Moolenbroek }
2172*00b67f09SDavid van Moolenbroek
2173*00b67f09SDavid van Moolenbroek isc_buffer_init(&buf, secretbuf, sizeof(secretbuf));
2174*00b67f09SDavid van Moolenbroek result = isc_base64_decodestring(cfg_obj_asstring(secretobj), &buf);
2175*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS) {
2176*00b67f09SDavid van Moolenbroek cfg_obj_log(secretobj, logctx, ISC_LOG_ERROR,
2177*00b67f09SDavid van Moolenbroek "bad secret '%s'", isc_result_totext(result));
2178*00b67f09SDavid van Moolenbroek return (result);
2179*00b67f09SDavid van Moolenbroek }
2180*00b67f09SDavid van Moolenbroek
2181*00b67f09SDavid van Moolenbroek algorithm = cfg_obj_asstring(algobj);
2182*00b67f09SDavid van Moolenbroek for (i = 0; algorithms[i].name != NULL; i++) {
2183*00b67f09SDavid van Moolenbroek len = strlen(algorithms[i].name);
2184*00b67f09SDavid van Moolenbroek if (strncasecmp(algorithms[i].name, algorithm, len) == 0 &&
2185*00b67f09SDavid van Moolenbroek (algorithm[len] == '\0' ||
2186*00b67f09SDavid van Moolenbroek (algorithms[i].size != 0 && algorithm[len] == '-')))
2187*00b67f09SDavid van Moolenbroek break;
2188*00b67f09SDavid van Moolenbroek }
2189*00b67f09SDavid van Moolenbroek if (algorithms[i].name == NULL) {
2190*00b67f09SDavid van Moolenbroek cfg_obj_log(algobj, logctx, ISC_LOG_ERROR,
2191*00b67f09SDavid van Moolenbroek "unknown algorithm '%s'", algorithm);
2192*00b67f09SDavid van Moolenbroek return (ISC_R_NOTFOUND);
2193*00b67f09SDavid van Moolenbroek }
2194*00b67f09SDavid van Moolenbroek if (algorithm[len] == '-') {
2195*00b67f09SDavid van Moolenbroek isc_uint16_t digestbits;
2196*00b67f09SDavid van Moolenbroek result = isc_parse_uint16(&digestbits, algorithm + len + 1, 10);
2197*00b67f09SDavid van Moolenbroek if (result == ISC_R_SUCCESS || result == ISC_R_RANGE) {
2198*00b67f09SDavid van Moolenbroek if (result == ISC_R_RANGE ||
2199*00b67f09SDavid van Moolenbroek digestbits > algorithms[i].size) {
2200*00b67f09SDavid van Moolenbroek cfg_obj_log(algobj, logctx, ISC_LOG_ERROR,
2201*00b67f09SDavid van Moolenbroek "key '%s' digest-bits too large "
2202*00b67f09SDavid van Moolenbroek "[%u..%u]", keyname,
2203*00b67f09SDavid van Moolenbroek algorithms[i].size / 2,
2204*00b67f09SDavid van Moolenbroek algorithms[i].size);
2205*00b67f09SDavid van Moolenbroek return (ISC_R_RANGE);
2206*00b67f09SDavid van Moolenbroek }
2207*00b67f09SDavid van Moolenbroek if ((digestbits % 8) != 0) {
2208*00b67f09SDavid van Moolenbroek cfg_obj_log(algobj, logctx, ISC_LOG_ERROR,
2209*00b67f09SDavid van Moolenbroek "key '%s' digest-bits not multiple"
2210*00b67f09SDavid van Moolenbroek " of 8", keyname);
2211*00b67f09SDavid van Moolenbroek return (ISC_R_RANGE);
2212*00b67f09SDavid van Moolenbroek }
2213*00b67f09SDavid van Moolenbroek /*
2214*00b67f09SDavid van Moolenbroek * Recommended minima for hmac algorithms.
2215*00b67f09SDavid van Moolenbroek */
2216*00b67f09SDavid van Moolenbroek if ((digestbits < (algorithms[i].size / 2U) ||
2217*00b67f09SDavid van Moolenbroek (digestbits < 80U)))
2218*00b67f09SDavid van Moolenbroek cfg_obj_log(algobj, logctx, ISC_LOG_WARNING,
2219*00b67f09SDavid van Moolenbroek "key '%s' digest-bits too small "
2220*00b67f09SDavid van Moolenbroek "[<%u]", keyname,
2221*00b67f09SDavid van Moolenbroek algorithms[i].size/2);
2222*00b67f09SDavid van Moolenbroek } else {
2223*00b67f09SDavid van Moolenbroek cfg_obj_log(algobj, logctx, ISC_LOG_ERROR,
2224*00b67f09SDavid van Moolenbroek "key '%s': unable to parse digest-bits",
2225*00b67f09SDavid van Moolenbroek keyname);
2226*00b67f09SDavid van Moolenbroek return (result);
2227*00b67f09SDavid van Moolenbroek }
2228*00b67f09SDavid van Moolenbroek }
2229*00b67f09SDavid van Moolenbroek return (ISC_R_SUCCESS);
2230*00b67f09SDavid van Moolenbroek }
2231*00b67f09SDavid van Moolenbroek
2232*00b67f09SDavid van Moolenbroek static isc_result_t
fileexist(const cfg_obj_t * obj,isc_symtab_t * symtab,isc_boolean_t writeable,isc_log_t * logctx)2233*00b67f09SDavid van Moolenbroek fileexist(const cfg_obj_t *obj, isc_symtab_t *symtab, isc_boolean_t writeable,
2234*00b67f09SDavid van Moolenbroek isc_log_t *logctx)
2235*00b67f09SDavid van Moolenbroek {
2236*00b67f09SDavid van Moolenbroek isc_result_t result;
2237*00b67f09SDavid van Moolenbroek isc_symvalue_t symvalue;
2238*00b67f09SDavid van Moolenbroek unsigned int line;
2239*00b67f09SDavid van Moolenbroek const char *file;
2240*00b67f09SDavid van Moolenbroek
2241*00b67f09SDavid van Moolenbroek result = isc_symtab_lookup(symtab, cfg_obj_asstring(obj), 0, &symvalue);
2242*00b67f09SDavid van Moolenbroek if (result == ISC_R_SUCCESS) {
2243*00b67f09SDavid van Moolenbroek if (writeable) {
2244*00b67f09SDavid van Moolenbroek file = cfg_obj_file(symvalue.as_cpointer);
2245*00b67f09SDavid van Moolenbroek line = cfg_obj_line(symvalue.as_cpointer);
2246*00b67f09SDavid van Moolenbroek cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
2247*00b67f09SDavid van Moolenbroek "writeable file '%s': already in use: "
2248*00b67f09SDavid van Moolenbroek "%s:%u", cfg_obj_asstring(obj),
2249*00b67f09SDavid van Moolenbroek file, line);
2250*00b67f09SDavid van Moolenbroek return (ISC_R_EXISTS);
2251*00b67f09SDavid van Moolenbroek }
2252*00b67f09SDavid van Moolenbroek result = isc_symtab_lookup(symtab, cfg_obj_asstring(obj), 2,
2253*00b67f09SDavid van Moolenbroek &symvalue);
2254*00b67f09SDavid van Moolenbroek if (result == ISC_R_SUCCESS) {
2255*00b67f09SDavid van Moolenbroek file = cfg_obj_file(symvalue.as_cpointer);
2256*00b67f09SDavid van Moolenbroek line = cfg_obj_line(symvalue.as_cpointer);
2257*00b67f09SDavid van Moolenbroek cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
2258*00b67f09SDavid van Moolenbroek "writeable file '%s': already in use: "
2259*00b67f09SDavid van Moolenbroek "%s:%u", cfg_obj_asstring(obj),
2260*00b67f09SDavid van Moolenbroek file, line);
2261*00b67f09SDavid van Moolenbroek return (ISC_R_EXISTS);
2262*00b67f09SDavid van Moolenbroek }
2263*00b67f09SDavid van Moolenbroek return (ISC_R_SUCCESS);
2264*00b67f09SDavid van Moolenbroek }
2265*00b67f09SDavid van Moolenbroek
2266*00b67f09SDavid van Moolenbroek symvalue.as_cpointer = obj;
2267*00b67f09SDavid van Moolenbroek result = isc_symtab_define(symtab, cfg_obj_asstring(obj),
2268*00b67f09SDavid van Moolenbroek writeable ? 2 : 1, symvalue,
2269*00b67f09SDavid van Moolenbroek isc_symexists_reject);
2270*00b67f09SDavid van Moolenbroek return (result);
2271*00b67f09SDavid van Moolenbroek }
2272*00b67f09SDavid van Moolenbroek
2273*00b67f09SDavid van Moolenbroek /*
2274*00b67f09SDavid van Moolenbroek * Check key list for duplicates key names and that the key names
2275*00b67f09SDavid van Moolenbroek * are valid domain names as these keys are used for TSIG.
2276*00b67f09SDavid van Moolenbroek *
2277*00b67f09SDavid van Moolenbroek * Check the key contents for validity.
2278*00b67f09SDavid van Moolenbroek */
2279*00b67f09SDavid van Moolenbroek static isc_result_t
check_keylist(const cfg_obj_t * keys,isc_symtab_t * symtab,isc_mem_t * mctx,isc_log_t * logctx)2280*00b67f09SDavid van Moolenbroek check_keylist(const cfg_obj_t *keys, isc_symtab_t *symtab,
2281*00b67f09SDavid van Moolenbroek isc_mem_t *mctx, isc_log_t *logctx)
2282*00b67f09SDavid van Moolenbroek {
2283*00b67f09SDavid van Moolenbroek char namebuf[DNS_NAME_FORMATSIZE];
2284*00b67f09SDavid van Moolenbroek dns_fixedname_t fname;
2285*00b67f09SDavid van Moolenbroek dns_name_t *name;
2286*00b67f09SDavid van Moolenbroek isc_result_t result = ISC_R_SUCCESS;
2287*00b67f09SDavid van Moolenbroek isc_result_t tresult;
2288*00b67f09SDavid van Moolenbroek const cfg_listelt_t *element;
2289*00b67f09SDavid van Moolenbroek
2290*00b67f09SDavid van Moolenbroek dns_fixedname_init(&fname);
2291*00b67f09SDavid van Moolenbroek name = dns_fixedname_name(&fname);
2292*00b67f09SDavid van Moolenbroek for (element = cfg_list_first(keys);
2293*00b67f09SDavid van Moolenbroek element != NULL;
2294*00b67f09SDavid van Moolenbroek element = cfg_list_next(element))
2295*00b67f09SDavid van Moolenbroek {
2296*00b67f09SDavid van Moolenbroek const cfg_obj_t *key = cfg_listelt_value(element);
2297*00b67f09SDavid van Moolenbroek const char *keyid = cfg_obj_asstring(cfg_map_getname(key));
2298*00b67f09SDavid van Moolenbroek isc_symvalue_t symvalue;
2299*00b67f09SDavid van Moolenbroek isc_buffer_t b;
2300*00b67f09SDavid van Moolenbroek char *keyname;
2301*00b67f09SDavid van Moolenbroek
2302*00b67f09SDavid van Moolenbroek isc_buffer_constinit(&b, keyid, strlen(keyid));
2303*00b67f09SDavid van Moolenbroek isc_buffer_add(&b, strlen(keyid));
2304*00b67f09SDavid van Moolenbroek tresult = dns_name_fromtext(name, &b, dns_rootname,
2305*00b67f09SDavid van Moolenbroek 0, NULL);
2306*00b67f09SDavid van Moolenbroek if (tresult != ISC_R_SUCCESS) {
2307*00b67f09SDavid van Moolenbroek cfg_obj_log(key, logctx, ISC_LOG_ERROR,
2308*00b67f09SDavid van Moolenbroek "key '%s': bad key name", keyid);
2309*00b67f09SDavid van Moolenbroek result = tresult;
2310*00b67f09SDavid van Moolenbroek continue;
2311*00b67f09SDavid van Moolenbroek }
2312*00b67f09SDavid van Moolenbroek tresult = bind9_check_key(key, logctx);
2313*00b67f09SDavid van Moolenbroek if (tresult != ISC_R_SUCCESS)
2314*00b67f09SDavid van Moolenbroek return (tresult);
2315*00b67f09SDavid van Moolenbroek
2316*00b67f09SDavid van Moolenbroek dns_name_format(name, namebuf, sizeof(namebuf));
2317*00b67f09SDavid van Moolenbroek keyname = isc_mem_strdup(mctx, namebuf);
2318*00b67f09SDavid van Moolenbroek if (keyname == NULL)
2319*00b67f09SDavid van Moolenbroek return (ISC_R_NOMEMORY);
2320*00b67f09SDavid van Moolenbroek symvalue.as_cpointer = key;
2321*00b67f09SDavid van Moolenbroek tresult = isc_symtab_define(symtab, keyname, 1, symvalue,
2322*00b67f09SDavid van Moolenbroek isc_symexists_reject);
2323*00b67f09SDavid van Moolenbroek if (tresult == ISC_R_EXISTS) {
2324*00b67f09SDavid van Moolenbroek const char *file;
2325*00b67f09SDavid van Moolenbroek unsigned int line;
2326*00b67f09SDavid van Moolenbroek
2327*00b67f09SDavid van Moolenbroek RUNTIME_CHECK(isc_symtab_lookup(symtab, keyname,
2328*00b67f09SDavid van Moolenbroek 1, &symvalue) == ISC_R_SUCCESS);
2329*00b67f09SDavid van Moolenbroek file = cfg_obj_file(symvalue.as_cpointer);
2330*00b67f09SDavid van Moolenbroek line = cfg_obj_line(symvalue.as_cpointer);
2331*00b67f09SDavid van Moolenbroek
2332*00b67f09SDavid van Moolenbroek if (file == NULL)
2333*00b67f09SDavid van Moolenbroek file = "<unknown file>";
2334*00b67f09SDavid van Moolenbroek cfg_obj_log(key, logctx, ISC_LOG_ERROR,
2335*00b67f09SDavid van Moolenbroek "key '%s': already exists "
2336*00b67f09SDavid van Moolenbroek "previous definition: %s:%u",
2337*00b67f09SDavid van Moolenbroek keyid, file, line);
2338*00b67f09SDavid van Moolenbroek isc_mem_free(mctx, keyname);
2339*00b67f09SDavid van Moolenbroek result = tresult;
2340*00b67f09SDavid van Moolenbroek } else if (tresult != ISC_R_SUCCESS) {
2341*00b67f09SDavid van Moolenbroek isc_mem_free(mctx, keyname);
2342*00b67f09SDavid van Moolenbroek return (tresult);
2343*00b67f09SDavid van Moolenbroek }
2344*00b67f09SDavid van Moolenbroek }
2345*00b67f09SDavid van Moolenbroek return (result);
2346*00b67f09SDavid van Moolenbroek }
2347*00b67f09SDavid van Moolenbroek
2348*00b67f09SDavid van Moolenbroek static struct {
2349*00b67f09SDavid van Moolenbroek const char *v4;
2350*00b67f09SDavid van Moolenbroek const char *v6;
2351*00b67f09SDavid van Moolenbroek } sources[] = {
2352*00b67f09SDavid van Moolenbroek { "transfer-source", "transfer-source-v6" },
2353*00b67f09SDavid van Moolenbroek { "notify-source", "notify-source-v6" },
2354*00b67f09SDavid van Moolenbroek { "query-source", "query-source-v6" },
2355*00b67f09SDavid van Moolenbroek { NULL, NULL }
2356*00b67f09SDavid van Moolenbroek };
2357*00b67f09SDavid van Moolenbroek
2358*00b67f09SDavid van Moolenbroek /*
2359*00b67f09SDavid van Moolenbroek * RNDC keys are not normalised unlike TSIG keys.
2360*00b67f09SDavid van Moolenbroek *
2361*00b67f09SDavid van Moolenbroek * "foo." is different to "foo".
2362*00b67f09SDavid van Moolenbroek */
2363*00b67f09SDavid van Moolenbroek static isc_boolean_t
rndckey_exists(const cfg_obj_t * keylist,const char * keyname)2364*00b67f09SDavid van Moolenbroek rndckey_exists(const cfg_obj_t *keylist, const char *keyname) {
2365*00b67f09SDavid van Moolenbroek const cfg_listelt_t *element;
2366*00b67f09SDavid van Moolenbroek const cfg_obj_t *obj;
2367*00b67f09SDavid van Moolenbroek const char *str;
2368*00b67f09SDavid van Moolenbroek
2369*00b67f09SDavid van Moolenbroek if (keylist == NULL)
2370*00b67f09SDavid van Moolenbroek return (ISC_FALSE);
2371*00b67f09SDavid van Moolenbroek
2372*00b67f09SDavid van Moolenbroek for (element = cfg_list_first(keylist);
2373*00b67f09SDavid van Moolenbroek element != NULL;
2374*00b67f09SDavid van Moolenbroek element = cfg_list_next(element))
2375*00b67f09SDavid van Moolenbroek {
2376*00b67f09SDavid van Moolenbroek obj = cfg_listelt_value(element);
2377*00b67f09SDavid van Moolenbroek str = cfg_obj_asstring(cfg_map_getname(obj));
2378*00b67f09SDavid van Moolenbroek if (!strcasecmp(str, keyname))
2379*00b67f09SDavid van Moolenbroek return (ISC_TRUE);
2380*00b67f09SDavid van Moolenbroek }
2381*00b67f09SDavid van Moolenbroek return (ISC_FALSE);
2382*00b67f09SDavid van Moolenbroek }
2383*00b67f09SDavid van Moolenbroek
2384*00b67f09SDavid van Moolenbroek static isc_result_t
check_servers(const cfg_obj_t * config,const cfg_obj_t * voptions,isc_symtab_t * symtab,isc_log_t * logctx)2385*00b67f09SDavid van Moolenbroek check_servers(const cfg_obj_t *config, const cfg_obj_t *voptions,
2386*00b67f09SDavid van Moolenbroek isc_symtab_t *symtab, isc_log_t *logctx)
2387*00b67f09SDavid van Moolenbroek {
2388*00b67f09SDavid van Moolenbroek dns_fixedname_t fname;
2389*00b67f09SDavid van Moolenbroek isc_result_t result = ISC_R_SUCCESS;
2390*00b67f09SDavid van Moolenbroek isc_result_t tresult;
2391*00b67f09SDavid van Moolenbroek const cfg_listelt_t *e1, *e2;
2392*00b67f09SDavid van Moolenbroek const cfg_obj_t *v1, *v2, *keys;
2393*00b67f09SDavid van Moolenbroek const cfg_obj_t *servers;
2394*00b67f09SDavid van Moolenbroek isc_netaddr_t n1, n2;
2395*00b67f09SDavid van Moolenbroek unsigned int p1, p2;
2396*00b67f09SDavid van Moolenbroek const cfg_obj_t *obj;
2397*00b67f09SDavid van Moolenbroek char buf[ISC_NETADDR_FORMATSIZE];
2398*00b67f09SDavid van Moolenbroek char namebuf[DNS_NAME_FORMATSIZE];
2399*00b67f09SDavid van Moolenbroek const char *xfr;
2400*00b67f09SDavid van Moolenbroek const char *keyval;
2401*00b67f09SDavid van Moolenbroek isc_buffer_t b;
2402*00b67f09SDavid van Moolenbroek int source;
2403*00b67f09SDavid van Moolenbroek dns_name_t *keyname;
2404*00b67f09SDavid van Moolenbroek
2405*00b67f09SDavid van Moolenbroek servers = NULL;
2406*00b67f09SDavid van Moolenbroek if (voptions != NULL)
2407*00b67f09SDavid van Moolenbroek (void)cfg_map_get(voptions, "server", &servers);
2408*00b67f09SDavid van Moolenbroek if (servers == NULL)
2409*00b67f09SDavid van Moolenbroek (void)cfg_map_get(config, "server", &servers);
2410*00b67f09SDavid van Moolenbroek if (servers == NULL)
2411*00b67f09SDavid van Moolenbroek return (ISC_R_SUCCESS);
2412*00b67f09SDavid van Moolenbroek
2413*00b67f09SDavid van Moolenbroek for (e1 = cfg_list_first(servers); e1 != NULL; e1 = cfg_list_next(e1)) {
2414*00b67f09SDavid van Moolenbroek v1 = cfg_listelt_value(e1);
2415*00b67f09SDavid van Moolenbroek cfg_obj_asnetprefix(cfg_map_getname(v1), &n1, &p1);
2416*00b67f09SDavid van Moolenbroek /*
2417*00b67f09SDavid van Moolenbroek * Check that unused bits are zero.
2418*00b67f09SDavid van Moolenbroek */
2419*00b67f09SDavid van Moolenbroek tresult = isc_netaddr_prefixok(&n1, p1);
2420*00b67f09SDavid van Moolenbroek if (tresult != ISC_R_SUCCESS) {
2421*00b67f09SDavid van Moolenbroek INSIST(tresult == ISC_R_FAILURE);
2422*00b67f09SDavid van Moolenbroek isc_netaddr_format(&n1, buf, sizeof(buf));
2423*00b67f09SDavid van Moolenbroek cfg_obj_log(v1, logctx, ISC_LOG_ERROR,
2424*00b67f09SDavid van Moolenbroek "server '%s/%u': invalid prefix "
2425*00b67f09SDavid van Moolenbroek "(extra bits specified)", buf, p1);
2426*00b67f09SDavid van Moolenbroek result = tresult;
2427*00b67f09SDavid van Moolenbroek }
2428*00b67f09SDavid van Moolenbroek source = 0;
2429*00b67f09SDavid van Moolenbroek do {
2430*00b67f09SDavid van Moolenbroek obj = NULL;
2431*00b67f09SDavid van Moolenbroek if (n1.family == AF_INET)
2432*00b67f09SDavid van Moolenbroek xfr = sources[source].v6;
2433*00b67f09SDavid van Moolenbroek else
2434*00b67f09SDavid van Moolenbroek xfr = sources[source].v4;
2435*00b67f09SDavid van Moolenbroek (void)cfg_map_get(v1, xfr, &obj);
2436*00b67f09SDavid van Moolenbroek if (obj != NULL) {
2437*00b67f09SDavid van Moolenbroek isc_netaddr_format(&n1, buf, sizeof(buf));
2438*00b67f09SDavid van Moolenbroek cfg_obj_log(v1, logctx, ISC_LOG_ERROR,
2439*00b67f09SDavid van Moolenbroek "server '%s/%u': %s not legal",
2440*00b67f09SDavid van Moolenbroek buf, p1, xfr);
2441*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
2442*00b67f09SDavid van Moolenbroek }
2443*00b67f09SDavid van Moolenbroek } while (sources[++source].v4 != NULL);
2444*00b67f09SDavid van Moolenbroek e2 = e1;
2445*00b67f09SDavid van Moolenbroek while ((e2 = cfg_list_next(e2)) != NULL) {
2446*00b67f09SDavid van Moolenbroek v2 = cfg_listelt_value(e2);
2447*00b67f09SDavid van Moolenbroek cfg_obj_asnetprefix(cfg_map_getname(v2), &n2, &p2);
2448*00b67f09SDavid van Moolenbroek if (p1 == p2 && isc_netaddr_equal(&n1, &n2)) {
2449*00b67f09SDavid van Moolenbroek const char *file = cfg_obj_file(v1);
2450*00b67f09SDavid van Moolenbroek unsigned int line = cfg_obj_line(v1);
2451*00b67f09SDavid van Moolenbroek
2452*00b67f09SDavid van Moolenbroek if (file == NULL)
2453*00b67f09SDavid van Moolenbroek file = "<unknown file>";
2454*00b67f09SDavid van Moolenbroek
2455*00b67f09SDavid van Moolenbroek isc_netaddr_format(&n2, buf, sizeof(buf));
2456*00b67f09SDavid van Moolenbroek cfg_obj_log(v2, logctx, ISC_LOG_ERROR,
2457*00b67f09SDavid van Moolenbroek "server '%s/%u': already exists "
2458*00b67f09SDavid van Moolenbroek "previous definition: %s:%u",
2459*00b67f09SDavid van Moolenbroek buf, p2, file, line);
2460*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
2461*00b67f09SDavid van Moolenbroek }
2462*00b67f09SDavid van Moolenbroek }
2463*00b67f09SDavid van Moolenbroek keys = NULL;
2464*00b67f09SDavid van Moolenbroek cfg_map_get(v1, "keys", &keys);
2465*00b67f09SDavid van Moolenbroek if (keys != NULL) {
2466*00b67f09SDavid van Moolenbroek /*
2467*00b67f09SDavid van Moolenbroek * Normalize key name.
2468*00b67f09SDavid van Moolenbroek */
2469*00b67f09SDavid van Moolenbroek keyval = cfg_obj_asstring(keys);
2470*00b67f09SDavid van Moolenbroek dns_fixedname_init(&fname);
2471*00b67f09SDavid van Moolenbroek isc_buffer_constinit(&b, keyval, strlen(keyval));
2472*00b67f09SDavid van Moolenbroek isc_buffer_add(&b, strlen(keyval));
2473*00b67f09SDavid van Moolenbroek keyname = dns_fixedname_name(&fname);
2474*00b67f09SDavid van Moolenbroek tresult = dns_name_fromtext(keyname, &b, dns_rootname,
2475*00b67f09SDavid van Moolenbroek 0, NULL);
2476*00b67f09SDavid van Moolenbroek if (tresult != ISC_R_SUCCESS) {
2477*00b67f09SDavid van Moolenbroek cfg_obj_log(keys, logctx, ISC_LOG_ERROR,
2478*00b67f09SDavid van Moolenbroek "bad key name '%s'", keyval);
2479*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
2480*00b67f09SDavid van Moolenbroek continue;
2481*00b67f09SDavid van Moolenbroek }
2482*00b67f09SDavid van Moolenbroek dns_name_format(keyname, namebuf, sizeof(namebuf));
2483*00b67f09SDavid van Moolenbroek tresult = isc_symtab_lookup(symtab, namebuf, 1, NULL);
2484*00b67f09SDavid van Moolenbroek if (tresult != ISC_R_SUCCESS) {
2485*00b67f09SDavid van Moolenbroek cfg_obj_log(keys, logctx, ISC_LOG_ERROR,
2486*00b67f09SDavid van Moolenbroek "unknown key '%s'", keyval);
2487*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
2488*00b67f09SDavid van Moolenbroek }
2489*00b67f09SDavid van Moolenbroek }
2490*00b67f09SDavid van Moolenbroek }
2491*00b67f09SDavid van Moolenbroek return (result);
2492*00b67f09SDavid van Moolenbroek }
2493*00b67f09SDavid van Moolenbroek
2494*00b67f09SDavid van Moolenbroek static isc_result_t
check_trusted_key(const cfg_obj_t * key,isc_boolean_t managed,isc_log_t * logctx)2495*00b67f09SDavid van Moolenbroek check_trusted_key(const cfg_obj_t *key, isc_boolean_t managed,
2496*00b67f09SDavid van Moolenbroek isc_log_t *logctx)
2497*00b67f09SDavid van Moolenbroek {
2498*00b67f09SDavid van Moolenbroek const char *keystr, *keynamestr;
2499*00b67f09SDavid van Moolenbroek dns_fixedname_t fkeyname;
2500*00b67f09SDavid van Moolenbroek dns_name_t *keyname;
2501*00b67f09SDavid van Moolenbroek isc_buffer_t b;
2502*00b67f09SDavid van Moolenbroek isc_region_t r;
2503*00b67f09SDavid van Moolenbroek isc_result_t result = ISC_R_SUCCESS;
2504*00b67f09SDavid van Moolenbroek isc_result_t tresult;
2505*00b67f09SDavid van Moolenbroek isc_uint32_t flags, proto, alg;
2506*00b67f09SDavid van Moolenbroek unsigned char keydata[4096];
2507*00b67f09SDavid van Moolenbroek
2508*00b67f09SDavid van Moolenbroek flags = cfg_obj_asuint32(cfg_tuple_get(key, "flags"));
2509*00b67f09SDavid van Moolenbroek proto = cfg_obj_asuint32(cfg_tuple_get(key, "protocol"));
2510*00b67f09SDavid van Moolenbroek alg = cfg_obj_asuint32(cfg_tuple_get(key, "algorithm"));
2511*00b67f09SDavid van Moolenbroek
2512*00b67f09SDavid van Moolenbroek dns_fixedname_init(&fkeyname);
2513*00b67f09SDavid van Moolenbroek keyname = dns_fixedname_name(&fkeyname);
2514*00b67f09SDavid van Moolenbroek keynamestr = cfg_obj_asstring(cfg_tuple_get(key, "name"));
2515*00b67f09SDavid van Moolenbroek
2516*00b67f09SDavid van Moolenbroek isc_buffer_constinit(&b, keynamestr, strlen(keynamestr));
2517*00b67f09SDavid van Moolenbroek isc_buffer_add(&b, strlen(keynamestr));
2518*00b67f09SDavid van Moolenbroek result = dns_name_fromtext(keyname, &b, dns_rootname, 0, NULL);
2519*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS) {
2520*00b67f09SDavid van Moolenbroek cfg_obj_log(key, logctx, ISC_LOG_WARNING, "bad key name: %s\n",
2521*00b67f09SDavid van Moolenbroek isc_result_totext(result));
2522*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
2523*00b67f09SDavid van Moolenbroek }
2524*00b67f09SDavid van Moolenbroek
2525*00b67f09SDavid van Moolenbroek if (flags > 0xffff) {
2526*00b67f09SDavid van Moolenbroek cfg_obj_log(key, logctx, ISC_LOG_WARNING,
2527*00b67f09SDavid van Moolenbroek "flags too big: %u\n", flags);
2528*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
2529*00b67f09SDavid van Moolenbroek }
2530*00b67f09SDavid van Moolenbroek if (proto > 0xff) {
2531*00b67f09SDavid van Moolenbroek cfg_obj_log(key, logctx, ISC_LOG_WARNING,
2532*00b67f09SDavid van Moolenbroek "protocol too big: %u\n", proto);
2533*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
2534*00b67f09SDavid van Moolenbroek }
2535*00b67f09SDavid van Moolenbroek if (alg > 0xff) {
2536*00b67f09SDavid van Moolenbroek cfg_obj_log(key, logctx, ISC_LOG_WARNING,
2537*00b67f09SDavid van Moolenbroek "algorithm too big: %u\n", alg);
2538*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
2539*00b67f09SDavid van Moolenbroek }
2540*00b67f09SDavid van Moolenbroek
2541*00b67f09SDavid van Moolenbroek if (managed) {
2542*00b67f09SDavid van Moolenbroek const char *initmethod;
2543*00b67f09SDavid van Moolenbroek initmethod = cfg_obj_asstring(cfg_tuple_get(key, "init"));
2544*00b67f09SDavid van Moolenbroek
2545*00b67f09SDavid van Moolenbroek if (strcasecmp(initmethod, "initial-key") != 0) {
2546*00b67f09SDavid van Moolenbroek cfg_obj_log(key, logctx, ISC_LOG_ERROR,
2547*00b67f09SDavid van Moolenbroek "managed key '%s': "
2548*00b67f09SDavid van Moolenbroek "invalid initialization method '%s'",
2549*00b67f09SDavid van Moolenbroek keynamestr, initmethod);
2550*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
2551*00b67f09SDavid van Moolenbroek }
2552*00b67f09SDavid van Moolenbroek }
2553*00b67f09SDavid van Moolenbroek
2554*00b67f09SDavid van Moolenbroek isc_buffer_init(&b, keydata, sizeof(keydata));
2555*00b67f09SDavid van Moolenbroek
2556*00b67f09SDavid van Moolenbroek keystr = cfg_obj_asstring(cfg_tuple_get(key, "key"));
2557*00b67f09SDavid van Moolenbroek tresult = isc_base64_decodestring(keystr, &b);
2558*00b67f09SDavid van Moolenbroek
2559*00b67f09SDavid van Moolenbroek if (tresult != ISC_R_SUCCESS) {
2560*00b67f09SDavid van Moolenbroek cfg_obj_log(key, logctx, ISC_LOG_ERROR,
2561*00b67f09SDavid van Moolenbroek "%s", isc_result_totext(tresult));
2562*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
2563*00b67f09SDavid van Moolenbroek } else {
2564*00b67f09SDavid van Moolenbroek isc_buffer_usedregion(&b, &r);
2565*00b67f09SDavid van Moolenbroek
2566*00b67f09SDavid van Moolenbroek if ((alg == DST_ALG_RSASHA1 || alg == DST_ALG_RSAMD5) &&
2567*00b67f09SDavid van Moolenbroek r.length > 1 && r.base[0] == 1 && r.base[1] == 3)
2568*00b67f09SDavid van Moolenbroek cfg_obj_log(key, logctx, ISC_LOG_WARNING,
2569*00b67f09SDavid van Moolenbroek "%s key '%s' has a weak exponent",
2570*00b67f09SDavid van Moolenbroek managed ? "managed" : "trusted",
2571*00b67f09SDavid van Moolenbroek keynamestr);
2572*00b67f09SDavid van Moolenbroek }
2573*00b67f09SDavid van Moolenbroek
2574*00b67f09SDavid van Moolenbroek return (result);
2575*00b67f09SDavid van Moolenbroek }
2576*00b67f09SDavid van Moolenbroek
2577*00b67f09SDavid van Moolenbroek static isc_result_t
check_viewconf(const cfg_obj_t * config,const cfg_obj_t * voptions,const char * viewname,dns_rdataclass_t vclass,isc_symtab_t * files,isc_log_t * logctx,isc_mem_t * mctx)2578*00b67f09SDavid van Moolenbroek check_viewconf(const cfg_obj_t *config, const cfg_obj_t *voptions,
2579*00b67f09SDavid van Moolenbroek const char *viewname, dns_rdataclass_t vclass,
2580*00b67f09SDavid van Moolenbroek isc_symtab_t *files, isc_log_t *logctx, isc_mem_t *mctx)
2581*00b67f09SDavid van Moolenbroek {
2582*00b67f09SDavid van Moolenbroek const cfg_obj_t *zones = NULL;
2583*00b67f09SDavid van Moolenbroek const cfg_obj_t *keys = NULL;
2584*00b67f09SDavid van Moolenbroek const cfg_listelt_t *element, *element2;
2585*00b67f09SDavid van Moolenbroek isc_symtab_t *symtab = NULL;
2586*00b67f09SDavid van Moolenbroek isc_result_t result = ISC_R_SUCCESS;
2587*00b67f09SDavid van Moolenbroek isc_result_t tresult = ISC_R_SUCCESS;
2588*00b67f09SDavid van Moolenbroek cfg_aclconfctx_t *actx = NULL;
2589*00b67f09SDavid van Moolenbroek const cfg_obj_t *obj;
2590*00b67f09SDavid van Moolenbroek const cfg_obj_t *options = NULL;
2591*00b67f09SDavid van Moolenbroek isc_boolean_t enablednssec, enablevalidation;
2592*00b67f09SDavid van Moolenbroek const char *valstr = "no";
2593*00b67f09SDavid van Moolenbroek
2594*00b67f09SDavid van Moolenbroek /*
2595*00b67f09SDavid van Moolenbroek * Get global options block
2596*00b67f09SDavid van Moolenbroek */
2597*00b67f09SDavid van Moolenbroek (void)cfg_map_get(config, "options", &options);
2598*00b67f09SDavid van Moolenbroek
2599*00b67f09SDavid van Moolenbroek /*
2600*00b67f09SDavid van Moolenbroek * Check that all zone statements are syntactically correct and
2601*00b67f09SDavid van Moolenbroek * there are no duplicate zones.
2602*00b67f09SDavid van Moolenbroek */
2603*00b67f09SDavid van Moolenbroek tresult = isc_symtab_create(mctx, 1000, freekey, mctx,
2604*00b67f09SDavid van Moolenbroek ISC_FALSE, &symtab);
2605*00b67f09SDavid van Moolenbroek if (tresult != ISC_R_SUCCESS)
2606*00b67f09SDavid van Moolenbroek return (ISC_R_NOMEMORY);
2607*00b67f09SDavid van Moolenbroek
2608*00b67f09SDavid van Moolenbroek cfg_aclconfctx_create(mctx, &actx);
2609*00b67f09SDavid van Moolenbroek
2610*00b67f09SDavid van Moolenbroek if (voptions != NULL)
2611*00b67f09SDavid van Moolenbroek (void)cfg_map_get(voptions, "zone", &zones);
2612*00b67f09SDavid van Moolenbroek else
2613*00b67f09SDavid van Moolenbroek (void)cfg_map_get(config, "zone", &zones);
2614*00b67f09SDavid van Moolenbroek
2615*00b67f09SDavid van Moolenbroek for (element = cfg_list_first(zones);
2616*00b67f09SDavid van Moolenbroek element != NULL;
2617*00b67f09SDavid van Moolenbroek element = cfg_list_next(element))
2618*00b67f09SDavid van Moolenbroek {
2619*00b67f09SDavid van Moolenbroek const cfg_obj_t *zone = cfg_listelt_value(element);
2620*00b67f09SDavid van Moolenbroek
2621*00b67f09SDavid van Moolenbroek tresult = check_zoneconf(zone, voptions, config, symtab,
2622*00b67f09SDavid van Moolenbroek files, vclass, actx, logctx,
2623*00b67f09SDavid van Moolenbroek mctx);
2624*00b67f09SDavid van Moolenbroek if (tresult != ISC_R_SUCCESS)
2625*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
2626*00b67f09SDavid van Moolenbroek }
2627*00b67f09SDavid van Moolenbroek
2628*00b67f09SDavid van Moolenbroek isc_symtab_destroy(&symtab);
2629*00b67f09SDavid van Moolenbroek
2630*00b67f09SDavid van Moolenbroek /*
2631*00b67f09SDavid van Moolenbroek * Check that forwarding is reasonable.
2632*00b67f09SDavid van Moolenbroek */
2633*00b67f09SDavid van Moolenbroek if (voptions == NULL) {
2634*00b67f09SDavid van Moolenbroek if (options != NULL)
2635*00b67f09SDavid van Moolenbroek if (check_forward(options, NULL,
2636*00b67f09SDavid van Moolenbroek logctx) != ISC_R_SUCCESS)
2637*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
2638*00b67f09SDavid van Moolenbroek } else {
2639*00b67f09SDavid van Moolenbroek if (check_forward(voptions, NULL, logctx) != ISC_R_SUCCESS)
2640*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
2641*00b67f09SDavid van Moolenbroek }
2642*00b67f09SDavid van Moolenbroek
2643*00b67f09SDavid van Moolenbroek /*
2644*00b67f09SDavid van Moolenbroek * Check non-zero options at the global and view levels.
2645*00b67f09SDavid van Moolenbroek */
2646*00b67f09SDavid van Moolenbroek if (options != NULL && check_nonzero(options, logctx) != ISC_R_SUCCESS)
2647*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
2648*00b67f09SDavid van Moolenbroek if (voptions != NULL &&check_nonzero(voptions, logctx) != ISC_R_SUCCESS)
2649*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
2650*00b67f09SDavid van Moolenbroek
2651*00b67f09SDavid van Moolenbroek /*
2652*00b67f09SDavid van Moolenbroek * Check that dual-stack-servers is reasonable.
2653*00b67f09SDavid van Moolenbroek */
2654*00b67f09SDavid van Moolenbroek if (voptions == NULL) {
2655*00b67f09SDavid van Moolenbroek if (options != NULL)
2656*00b67f09SDavid van Moolenbroek if (check_dual_stack(options, logctx) != ISC_R_SUCCESS)
2657*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
2658*00b67f09SDavid van Moolenbroek } else {
2659*00b67f09SDavid van Moolenbroek if (check_dual_stack(voptions, logctx) != ISC_R_SUCCESS)
2660*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
2661*00b67f09SDavid van Moolenbroek }
2662*00b67f09SDavid van Moolenbroek
2663*00b67f09SDavid van Moolenbroek /*
2664*00b67f09SDavid van Moolenbroek * Check that rrset-order is reasonable.
2665*00b67f09SDavid van Moolenbroek */
2666*00b67f09SDavid van Moolenbroek if (voptions != NULL) {
2667*00b67f09SDavid van Moolenbroek if (check_order(voptions, logctx) != ISC_R_SUCCESS)
2668*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
2669*00b67f09SDavid van Moolenbroek }
2670*00b67f09SDavid van Moolenbroek
2671*00b67f09SDavid van Moolenbroek /*
2672*00b67f09SDavid van Moolenbroek * Check that all key statements are syntactically correct and
2673*00b67f09SDavid van Moolenbroek * there are no duplicate keys.
2674*00b67f09SDavid van Moolenbroek */
2675*00b67f09SDavid van Moolenbroek tresult = isc_symtab_create(mctx, 1000, freekey, mctx,
2676*00b67f09SDavid van Moolenbroek ISC_FALSE, &symtab);
2677*00b67f09SDavid van Moolenbroek if (tresult != ISC_R_SUCCESS)
2678*00b67f09SDavid van Moolenbroek goto cleanup;
2679*00b67f09SDavid van Moolenbroek
2680*00b67f09SDavid van Moolenbroek (void)cfg_map_get(config, "key", &keys);
2681*00b67f09SDavid van Moolenbroek tresult = check_keylist(keys, symtab, mctx, logctx);
2682*00b67f09SDavid van Moolenbroek if (tresult == ISC_R_EXISTS)
2683*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
2684*00b67f09SDavid van Moolenbroek else if (tresult != ISC_R_SUCCESS) {
2685*00b67f09SDavid van Moolenbroek result = tresult;
2686*00b67f09SDavid van Moolenbroek goto cleanup;
2687*00b67f09SDavid van Moolenbroek }
2688*00b67f09SDavid van Moolenbroek
2689*00b67f09SDavid van Moolenbroek if (voptions != NULL) {
2690*00b67f09SDavid van Moolenbroek keys = NULL;
2691*00b67f09SDavid van Moolenbroek (void)cfg_map_get(voptions, "key", &keys);
2692*00b67f09SDavid van Moolenbroek tresult = check_keylist(keys, symtab, mctx, logctx);
2693*00b67f09SDavid van Moolenbroek if (tresult == ISC_R_EXISTS)
2694*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
2695*00b67f09SDavid van Moolenbroek else if (tresult != ISC_R_SUCCESS) {
2696*00b67f09SDavid van Moolenbroek result = tresult;
2697*00b67f09SDavid van Moolenbroek goto cleanup;
2698*00b67f09SDavid van Moolenbroek }
2699*00b67f09SDavid van Moolenbroek }
2700*00b67f09SDavid van Moolenbroek
2701*00b67f09SDavid van Moolenbroek /*
2702*00b67f09SDavid van Moolenbroek * Global servers can refer to keys in views.
2703*00b67f09SDavid van Moolenbroek */
2704*00b67f09SDavid van Moolenbroek if (check_servers(config, voptions, symtab, logctx) != ISC_R_SUCCESS)
2705*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
2706*00b67f09SDavid van Moolenbroek
2707*00b67f09SDavid van Moolenbroek isc_symtab_destroy(&symtab);
2708*00b67f09SDavid van Moolenbroek
2709*00b67f09SDavid van Moolenbroek /*
2710*00b67f09SDavid van Moolenbroek * Check that dnssec-enable/dnssec-validation are sensible.
2711*00b67f09SDavid van Moolenbroek */
2712*00b67f09SDavid van Moolenbroek obj = NULL;
2713*00b67f09SDavid van Moolenbroek if (voptions != NULL)
2714*00b67f09SDavid van Moolenbroek (void)cfg_map_get(voptions, "dnssec-enable", &obj);
2715*00b67f09SDavid van Moolenbroek if (obj == NULL && options != NULL)
2716*00b67f09SDavid van Moolenbroek (void)cfg_map_get(options, "dnssec-enable", &obj);
2717*00b67f09SDavid van Moolenbroek if (obj == NULL)
2718*00b67f09SDavid van Moolenbroek enablednssec = ISC_TRUE;
2719*00b67f09SDavid van Moolenbroek else
2720*00b67f09SDavid van Moolenbroek enablednssec = cfg_obj_asboolean(obj);
2721*00b67f09SDavid van Moolenbroek
2722*00b67f09SDavid van Moolenbroek obj = NULL;
2723*00b67f09SDavid van Moolenbroek if (voptions != NULL)
2724*00b67f09SDavid van Moolenbroek (void)cfg_map_get(voptions, "dnssec-validation", &obj);
2725*00b67f09SDavid van Moolenbroek if (obj == NULL && options != NULL)
2726*00b67f09SDavid van Moolenbroek (void)cfg_map_get(options, "dnssec-validation", &obj);
2727*00b67f09SDavid van Moolenbroek if (obj == NULL) {
2728*00b67f09SDavid van Moolenbroek enablevalidation = enablednssec;
2729*00b67f09SDavid van Moolenbroek valstr = "yes";
2730*00b67f09SDavid van Moolenbroek } else if (cfg_obj_isboolean(obj)) {
2731*00b67f09SDavid van Moolenbroek enablevalidation = cfg_obj_asboolean(obj);
2732*00b67f09SDavid van Moolenbroek valstr = enablevalidation ? "yes" : "no";
2733*00b67f09SDavid van Moolenbroek } else {
2734*00b67f09SDavid van Moolenbroek enablevalidation = ISC_TRUE;
2735*00b67f09SDavid van Moolenbroek valstr = "auto";
2736*00b67f09SDavid van Moolenbroek }
2737*00b67f09SDavid van Moolenbroek
2738*00b67f09SDavid van Moolenbroek if (enablevalidation && !enablednssec)
2739*00b67f09SDavid van Moolenbroek cfg_obj_log(obj, logctx, ISC_LOG_WARNING,
2740*00b67f09SDavid van Moolenbroek "'dnssec-validation %s;' and 'dnssec-enable no;'",
2741*00b67f09SDavid van Moolenbroek valstr);
2742*00b67f09SDavid van Moolenbroek
2743*00b67f09SDavid van Moolenbroek /*
2744*00b67f09SDavid van Moolenbroek * Check trusted-keys and managed-keys.
2745*00b67f09SDavid van Moolenbroek */
2746*00b67f09SDavid van Moolenbroek keys = NULL;
2747*00b67f09SDavid van Moolenbroek if (voptions != NULL)
2748*00b67f09SDavid van Moolenbroek (void)cfg_map_get(voptions, "trusted-keys", &keys);
2749*00b67f09SDavid van Moolenbroek if (keys == NULL)
2750*00b67f09SDavid van Moolenbroek (void)cfg_map_get(config, "trusted-keys", &keys);
2751*00b67f09SDavid van Moolenbroek
2752*00b67f09SDavid van Moolenbroek for (element = cfg_list_first(keys);
2753*00b67f09SDavid van Moolenbroek element != NULL;
2754*00b67f09SDavid van Moolenbroek element = cfg_list_next(element))
2755*00b67f09SDavid van Moolenbroek {
2756*00b67f09SDavid van Moolenbroek const cfg_obj_t *keylist = cfg_listelt_value(element);
2757*00b67f09SDavid van Moolenbroek for (element2 = cfg_list_first(keylist);
2758*00b67f09SDavid van Moolenbroek element2 != NULL;
2759*00b67f09SDavid van Moolenbroek element2 = cfg_list_next(element2)) {
2760*00b67f09SDavid van Moolenbroek obj = cfg_listelt_value(element2);
2761*00b67f09SDavid van Moolenbroek tresult = check_trusted_key(obj, ISC_FALSE, logctx);
2762*00b67f09SDavid van Moolenbroek if (tresult != ISC_R_SUCCESS)
2763*00b67f09SDavid van Moolenbroek result = tresult;
2764*00b67f09SDavid van Moolenbroek }
2765*00b67f09SDavid van Moolenbroek }
2766*00b67f09SDavid van Moolenbroek
2767*00b67f09SDavid van Moolenbroek keys = NULL;
2768*00b67f09SDavid van Moolenbroek if (voptions != NULL)
2769*00b67f09SDavid van Moolenbroek (void)cfg_map_get(voptions, "managed-keys", &keys);
2770*00b67f09SDavid van Moolenbroek if (keys == NULL)
2771*00b67f09SDavid van Moolenbroek (void)cfg_map_get(config, "managed-keys", &keys);
2772*00b67f09SDavid van Moolenbroek
2773*00b67f09SDavid van Moolenbroek for (element = cfg_list_first(keys);
2774*00b67f09SDavid van Moolenbroek element != NULL;
2775*00b67f09SDavid van Moolenbroek element = cfg_list_next(element))
2776*00b67f09SDavid van Moolenbroek {
2777*00b67f09SDavid van Moolenbroek const cfg_obj_t *keylist = cfg_listelt_value(element);
2778*00b67f09SDavid van Moolenbroek for (element2 = cfg_list_first(keylist);
2779*00b67f09SDavid van Moolenbroek element2 != NULL;
2780*00b67f09SDavid van Moolenbroek element2 = cfg_list_next(element2)) {
2781*00b67f09SDavid van Moolenbroek obj = cfg_listelt_value(element2);
2782*00b67f09SDavid van Moolenbroek tresult = check_trusted_key(obj, ISC_TRUE, logctx);
2783*00b67f09SDavid van Moolenbroek if (tresult != ISC_R_SUCCESS)
2784*00b67f09SDavid van Moolenbroek result = tresult;
2785*00b67f09SDavid van Moolenbroek }
2786*00b67f09SDavid van Moolenbroek }
2787*00b67f09SDavid van Moolenbroek
2788*00b67f09SDavid van Moolenbroek /*
2789*00b67f09SDavid van Moolenbroek * Check options.
2790*00b67f09SDavid van Moolenbroek */
2791*00b67f09SDavid van Moolenbroek if (voptions != NULL)
2792*00b67f09SDavid van Moolenbroek tresult = check_options(voptions, logctx, mctx,
2793*00b67f09SDavid van Moolenbroek optlevel_view);
2794*00b67f09SDavid van Moolenbroek else
2795*00b67f09SDavid van Moolenbroek tresult = check_options(config, logctx, mctx,
2796*00b67f09SDavid van Moolenbroek optlevel_config);
2797*00b67f09SDavid van Moolenbroek if (tresult != ISC_R_SUCCESS)
2798*00b67f09SDavid van Moolenbroek result = tresult;
2799*00b67f09SDavid van Moolenbroek
2800*00b67f09SDavid van Moolenbroek tresult = check_viewacls(actx, voptions, config, logctx, mctx);
2801*00b67f09SDavid van Moolenbroek if (tresult != ISC_R_SUCCESS)
2802*00b67f09SDavid van Moolenbroek result = tresult;
2803*00b67f09SDavid van Moolenbroek
2804*00b67f09SDavid van Moolenbroek tresult = check_recursionacls(actx, voptions, viewname,
2805*00b67f09SDavid van Moolenbroek config, logctx, mctx);
2806*00b67f09SDavid van Moolenbroek if (tresult != ISC_R_SUCCESS)
2807*00b67f09SDavid van Moolenbroek result = tresult;
2808*00b67f09SDavid van Moolenbroek
2809*00b67f09SDavid van Moolenbroek tresult = check_filteraaaa(actx, voptions, viewname, config,
2810*00b67f09SDavid van Moolenbroek logctx, mctx);
2811*00b67f09SDavid van Moolenbroek if (tresult != ISC_R_SUCCESS)
2812*00b67f09SDavid van Moolenbroek result = tresult;
2813*00b67f09SDavid van Moolenbroek
2814*00b67f09SDavid van Moolenbroek tresult = check_dns64(actx, voptions, config, logctx, mctx);
2815*00b67f09SDavid van Moolenbroek if (tresult != ISC_R_SUCCESS)
2816*00b67f09SDavid van Moolenbroek result = tresult;
2817*00b67f09SDavid van Moolenbroek
2818*00b67f09SDavid van Moolenbroek cleanup:
2819*00b67f09SDavid van Moolenbroek if (symtab != NULL)
2820*00b67f09SDavid van Moolenbroek isc_symtab_destroy(&symtab);
2821*00b67f09SDavid van Moolenbroek if (actx != NULL)
2822*00b67f09SDavid van Moolenbroek cfg_aclconfctx_detach(&actx);
2823*00b67f09SDavid van Moolenbroek
2824*00b67f09SDavid van Moolenbroek return (result);
2825*00b67f09SDavid van Moolenbroek }
2826*00b67f09SDavid van Moolenbroek
2827*00b67f09SDavid van Moolenbroek static const char *
2828*00b67f09SDavid van Moolenbroek default_channels[] = {
2829*00b67f09SDavid van Moolenbroek "default_syslog",
2830*00b67f09SDavid van Moolenbroek "default_stderr",
2831*00b67f09SDavid van Moolenbroek "default_debug",
2832*00b67f09SDavid van Moolenbroek "null",
2833*00b67f09SDavid van Moolenbroek NULL
2834*00b67f09SDavid van Moolenbroek };
2835*00b67f09SDavid van Moolenbroek
2836*00b67f09SDavid van Moolenbroek static isc_result_t
bind9_check_logging(const cfg_obj_t * config,isc_log_t * logctx,isc_mem_t * mctx)2837*00b67f09SDavid van Moolenbroek bind9_check_logging(const cfg_obj_t *config, isc_log_t *logctx,
2838*00b67f09SDavid van Moolenbroek isc_mem_t *mctx)
2839*00b67f09SDavid van Moolenbroek {
2840*00b67f09SDavid van Moolenbroek const cfg_obj_t *categories = NULL;
2841*00b67f09SDavid van Moolenbroek const cfg_obj_t *category;
2842*00b67f09SDavid van Moolenbroek const cfg_obj_t *channels = NULL;
2843*00b67f09SDavid van Moolenbroek const cfg_obj_t *channel;
2844*00b67f09SDavid van Moolenbroek const cfg_listelt_t *element;
2845*00b67f09SDavid van Moolenbroek const cfg_listelt_t *delement;
2846*00b67f09SDavid van Moolenbroek const char *channelname;
2847*00b67f09SDavid van Moolenbroek const char *catname;
2848*00b67f09SDavid van Moolenbroek const cfg_obj_t *fileobj = NULL;
2849*00b67f09SDavid van Moolenbroek const cfg_obj_t *syslogobj = NULL;
2850*00b67f09SDavid van Moolenbroek const cfg_obj_t *nullobj = NULL;
2851*00b67f09SDavid van Moolenbroek const cfg_obj_t *stderrobj = NULL;
2852*00b67f09SDavid van Moolenbroek const cfg_obj_t *logobj = NULL;
2853*00b67f09SDavid van Moolenbroek isc_result_t result = ISC_R_SUCCESS;
2854*00b67f09SDavid van Moolenbroek isc_result_t tresult;
2855*00b67f09SDavid van Moolenbroek isc_symtab_t *symtab = NULL;
2856*00b67f09SDavid van Moolenbroek isc_symvalue_t symvalue;
2857*00b67f09SDavid van Moolenbroek int i;
2858*00b67f09SDavid van Moolenbroek
2859*00b67f09SDavid van Moolenbroek (void)cfg_map_get(config, "logging", &logobj);
2860*00b67f09SDavid van Moolenbroek if (logobj == NULL)
2861*00b67f09SDavid van Moolenbroek return (ISC_R_SUCCESS);
2862*00b67f09SDavid van Moolenbroek
2863*00b67f09SDavid van Moolenbroek result = isc_symtab_create(mctx, 100, NULL, NULL, ISC_FALSE, &symtab);
2864*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
2865*00b67f09SDavid van Moolenbroek return (result);
2866*00b67f09SDavid van Moolenbroek
2867*00b67f09SDavid van Moolenbroek symvalue.as_cpointer = NULL;
2868*00b67f09SDavid van Moolenbroek for (i = 0; default_channels[i] != NULL; i++) {
2869*00b67f09SDavid van Moolenbroek tresult = isc_symtab_define(symtab, default_channels[i], 1,
2870*00b67f09SDavid van Moolenbroek symvalue, isc_symexists_replace);
2871*00b67f09SDavid van Moolenbroek if (tresult != ISC_R_SUCCESS)
2872*00b67f09SDavid van Moolenbroek result = tresult;
2873*00b67f09SDavid van Moolenbroek }
2874*00b67f09SDavid van Moolenbroek
2875*00b67f09SDavid van Moolenbroek cfg_map_get(logobj, "channel", &channels);
2876*00b67f09SDavid van Moolenbroek
2877*00b67f09SDavid van Moolenbroek for (element = cfg_list_first(channels);
2878*00b67f09SDavid van Moolenbroek element != NULL;
2879*00b67f09SDavid van Moolenbroek element = cfg_list_next(element))
2880*00b67f09SDavid van Moolenbroek {
2881*00b67f09SDavid van Moolenbroek channel = cfg_listelt_value(element);
2882*00b67f09SDavid van Moolenbroek channelname = cfg_obj_asstring(cfg_map_getname(channel));
2883*00b67f09SDavid van Moolenbroek fileobj = syslogobj = nullobj = stderrobj = NULL;
2884*00b67f09SDavid van Moolenbroek (void)cfg_map_get(channel, "file", &fileobj);
2885*00b67f09SDavid van Moolenbroek (void)cfg_map_get(channel, "syslog", &syslogobj);
2886*00b67f09SDavid van Moolenbroek (void)cfg_map_get(channel, "null", &nullobj);
2887*00b67f09SDavid van Moolenbroek (void)cfg_map_get(channel, "stderr", &stderrobj);
2888*00b67f09SDavid van Moolenbroek i = 0;
2889*00b67f09SDavid van Moolenbroek if (fileobj != NULL)
2890*00b67f09SDavid van Moolenbroek i++;
2891*00b67f09SDavid van Moolenbroek if (syslogobj != NULL)
2892*00b67f09SDavid van Moolenbroek i++;
2893*00b67f09SDavid van Moolenbroek if (nullobj != NULL)
2894*00b67f09SDavid van Moolenbroek i++;
2895*00b67f09SDavid van Moolenbroek if (stderrobj != NULL)
2896*00b67f09SDavid van Moolenbroek i++;
2897*00b67f09SDavid van Moolenbroek if (i != 1) {
2898*00b67f09SDavid van Moolenbroek cfg_obj_log(channel, logctx, ISC_LOG_ERROR,
2899*00b67f09SDavid van Moolenbroek "channel '%s': exactly one of file, syslog, "
2900*00b67f09SDavid van Moolenbroek "null, and stderr must be present",
2901*00b67f09SDavid van Moolenbroek channelname);
2902*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
2903*00b67f09SDavid van Moolenbroek }
2904*00b67f09SDavid van Moolenbroek tresult = isc_symtab_define(symtab, channelname, 1,
2905*00b67f09SDavid van Moolenbroek symvalue, isc_symexists_replace);
2906*00b67f09SDavid van Moolenbroek if (tresult != ISC_R_SUCCESS)
2907*00b67f09SDavid van Moolenbroek result = tresult;
2908*00b67f09SDavid van Moolenbroek }
2909*00b67f09SDavid van Moolenbroek
2910*00b67f09SDavid van Moolenbroek cfg_map_get(logobj, "category", &categories);
2911*00b67f09SDavid van Moolenbroek
2912*00b67f09SDavid van Moolenbroek for (element = cfg_list_first(categories);
2913*00b67f09SDavid van Moolenbroek element != NULL;
2914*00b67f09SDavid van Moolenbroek element = cfg_list_next(element))
2915*00b67f09SDavid van Moolenbroek {
2916*00b67f09SDavid van Moolenbroek category = cfg_listelt_value(element);
2917*00b67f09SDavid van Moolenbroek catname = cfg_obj_asstring(cfg_tuple_get(category, "name"));
2918*00b67f09SDavid van Moolenbroek if (isc_log_categorybyname(logctx, catname) == NULL) {
2919*00b67f09SDavid van Moolenbroek cfg_obj_log(category, logctx, ISC_LOG_ERROR,
2920*00b67f09SDavid van Moolenbroek "undefined category: '%s'", catname);
2921*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
2922*00b67f09SDavid van Moolenbroek }
2923*00b67f09SDavid van Moolenbroek channels = cfg_tuple_get(category, "destinations");
2924*00b67f09SDavid van Moolenbroek for (delement = cfg_list_first(channels);
2925*00b67f09SDavid van Moolenbroek delement != NULL;
2926*00b67f09SDavid van Moolenbroek delement = cfg_list_next(delement))
2927*00b67f09SDavid van Moolenbroek {
2928*00b67f09SDavid van Moolenbroek channel = cfg_listelt_value(delement);
2929*00b67f09SDavid van Moolenbroek channelname = cfg_obj_asstring(channel);
2930*00b67f09SDavid van Moolenbroek tresult = isc_symtab_lookup(symtab, channelname, 1,
2931*00b67f09SDavid van Moolenbroek &symvalue);
2932*00b67f09SDavid van Moolenbroek if (tresult != ISC_R_SUCCESS) {
2933*00b67f09SDavid van Moolenbroek cfg_obj_log(channel, logctx, ISC_LOG_ERROR,
2934*00b67f09SDavid van Moolenbroek "undefined channel: '%s'",
2935*00b67f09SDavid van Moolenbroek channelname);
2936*00b67f09SDavid van Moolenbroek result = tresult;
2937*00b67f09SDavid van Moolenbroek }
2938*00b67f09SDavid van Moolenbroek }
2939*00b67f09SDavid van Moolenbroek }
2940*00b67f09SDavid van Moolenbroek isc_symtab_destroy(&symtab);
2941*00b67f09SDavid van Moolenbroek return (result);
2942*00b67f09SDavid van Moolenbroek }
2943*00b67f09SDavid van Moolenbroek
2944*00b67f09SDavid van Moolenbroek static isc_result_t
bind9_check_controlskeys(const cfg_obj_t * control,const cfg_obj_t * keylist,isc_log_t * logctx)2945*00b67f09SDavid van Moolenbroek bind9_check_controlskeys(const cfg_obj_t *control, const cfg_obj_t *keylist,
2946*00b67f09SDavid van Moolenbroek isc_log_t *logctx)
2947*00b67f09SDavid van Moolenbroek {
2948*00b67f09SDavid van Moolenbroek isc_result_t result = ISC_R_SUCCESS;
2949*00b67f09SDavid van Moolenbroek const cfg_obj_t *control_keylist;
2950*00b67f09SDavid van Moolenbroek const cfg_listelt_t *element;
2951*00b67f09SDavid van Moolenbroek const cfg_obj_t *key;
2952*00b67f09SDavid van Moolenbroek const char *keyval;
2953*00b67f09SDavid van Moolenbroek
2954*00b67f09SDavid van Moolenbroek control_keylist = cfg_tuple_get(control, "keys");
2955*00b67f09SDavid van Moolenbroek if (cfg_obj_isvoid(control_keylist))
2956*00b67f09SDavid van Moolenbroek return (ISC_R_SUCCESS);
2957*00b67f09SDavid van Moolenbroek
2958*00b67f09SDavid van Moolenbroek for (element = cfg_list_first(control_keylist);
2959*00b67f09SDavid van Moolenbroek element != NULL;
2960*00b67f09SDavid van Moolenbroek element = cfg_list_next(element))
2961*00b67f09SDavid van Moolenbroek {
2962*00b67f09SDavid van Moolenbroek key = cfg_listelt_value(element);
2963*00b67f09SDavid van Moolenbroek keyval = cfg_obj_asstring(key);
2964*00b67f09SDavid van Moolenbroek
2965*00b67f09SDavid van Moolenbroek if (!rndckey_exists(keylist, keyval)) {
2966*00b67f09SDavid van Moolenbroek cfg_obj_log(key, logctx, ISC_LOG_ERROR,
2967*00b67f09SDavid van Moolenbroek "unknown key '%s'", keyval);
2968*00b67f09SDavid van Moolenbroek result = ISC_R_NOTFOUND;
2969*00b67f09SDavid van Moolenbroek }
2970*00b67f09SDavid van Moolenbroek }
2971*00b67f09SDavid van Moolenbroek return (result);
2972*00b67f09SDavid van Moolenbroek }
2973*00b67f09SDavid van Moolenbroek
2974*00b67f09SDavid van Moolenbroek static isc_result_t
bind9_check_controls(const cfg_obj_t * config,isc_log_t * logctx,isc_mem_t * mctx)2975*00b67f09SDavid van Moolenbroek bind9_check_controls(const cfg_obj_t *config, isc_log_t *logctx,
2976*00b67f09SDavid van Moolenbroek isc_mem_t *mctx)
2977*00b67f09SDavid van Moolenbroek {
2978*00b67f09SDavid van Moolenbroek isc_result_t result = ISC_R_SUCCESS, tresult;
2979*00b67f09SDavid van Moolenbroek cfg_aclconfctx_t *actx = NULL;
2980*00b67f09SDavid van Moolenbroek const cfg_listelt_t *element, *element2;
2981*00b67f09SDavid van Moolenbroek const cfg_obj_t *allow;
2982*00b67f09SDavid van Moolenbroek const cfg_obj_t *control;
2983*00b67f09SDavid van Moolenbroek const cfg_obj_t *controls;
2984*00b67f09SDavid van Moolenbroek const cfg_obj_t *controlslist = NULL;
2985*00b67f09SDavid van Moolenbroek const cfg_obj_t *inetcontrols;
2986*00b67f09SDavid van Moolenbroek const cfg_obj_t *unixcontrols;
2987*00b67f09SDavid van Moolenbroek const cfg_obj_t *keylist = NULL;
2988*00b67f09SDavid van Moolenbroek const char *path;
2989*00b67f09SDavid van Moolenbroek isc_uint32_t perm, mask;
2990*00b67f09SDavid van Moolenbroek dns_acl_t *acl = NULL;
2991*00b67f09SDavid van Moolenbroek isc_sockaddr_t addr;
2992*00b67f09SDavid van Moolenbroek int i;
2993*00b67f09SDavid van Moolenbroek
2994*00b67f09SDavid van Moolenbroek (void)cfg_map_get(config, "controls", &controlslist);
2995*00b67f09SDavid van Moolenbroek if (controlslist == NULL)
2996*00b67f09SDavid van Moolenbroek return (ISC_R_SUCCESS);
2997*00b67f09SDavid van Moolenbroek
2998*00b67f09SDavid van Moolenbroek (void)cfg_map_get(config, "key", &keylist);
2999*00b67f09SDavid van Moolenbroek
3000*00b67f09SDavid van Moolenbroek cfg_aclconfctx_create(mctx, &actx);
3001*00b67f09SDavid van Moolenbroek
3002*00b67f09SDavid van Moolenbroek /*
3003*00b67f09SDavid van Moolenbroek * INET: Check allow clause.
3004*00b67f09SDavid van Moolenbroek * UNIX: Check "perm" for sanity, check path length.
3005*00b67f09SDavid van Moolenbroek */
3006*00b67f09SDavid van Moolenbroek for (element = cfg_list_first(controlslist);
3007*00b67f09SDavid van Moolenbroek element != NULL;
3008*00b67f09SDavid van Moolenbroek element = cfg_list_next(element)) {
3009*00b67f09SDavid van Moolenbroek controls = cfg_listelt_value(element);
3010*00b67f09SDavid van Moolenbroek unixcontrols = NULL;
3011*00b67f09SDavid van Moolenbroek inetcontrols = NULL;
3012*00b67f09SDavid van Moolenbroek (void)cfg_map_get(controls, "unix", &unixcontrols);
3013*00b67f09SDavid van Moolenbroek (void)cfg_map_get(controls, "inet", &inetcontrols);
3014*00b67f09SDavid van Moolenbroek for (element2 = cfg_list_first(inetcontrols);
3015*00b67f09SDavid van Moolenbroek element2 != NULL;
3016*00b67f09SDavid van Moolenbroek element2 = cfg_list_next(element2)) {
3017*00b67f09SDavid van Moolenbroek control = cfg_listelt_value(element2);
3018*00b67f09SDavid van Moolenbroek allow = cfg_tuple_get(control, "allow");
3019*00b67f09SDavid van Moolenbroek tresult = cfg_acl_fromconfig(allow, config, logctx,
3020*00b67f09SDavid van Moolenbroek actx, mctx, 0, &acl);
3021*00b67f09SDavid van Moolenbroek if (acl != NULL)
3022*00b67f09SDavid van Moolenbroek dns_acl_detach(&acl);
3023*00b67f09SDavid van Moolenbroek if (tresult != ISC_R_SUCCESS)
3024*00b67f09SDavid van Moolenbroek result = tresult;
3025*00b67f09SDavid van Moolenbroek tresult = bind9_check_controlskeys(control, keylist,
3026*00b67f09SDavid van Moolenbroek logctx);
3027*00b67f09SDavid van Moolenbroek if (tresult != ISC_R_SUCCESS)
3028*00b67f09SDavid van Moolenbroek result = tresult;
3029*00b67f09SDavid van Moolenbroek }
3030*00b67f09SDavid van Moolenbroek for (element2 = cfg_list_first(unixcontrols);
3031*00b67f09SDavid van Moolenbroek element2 != NULL;
3032*00b67f09SDavid van Moolenbroek element2 = cfg_list_next(element2)) {
3033*00b67f09SDavid van Moolenbroek control = cfg_listelt_value(element2);
3034*00b67f09SDavid van Moolenbroek path = cfg_obj_asstring(cfg_tuple_get(control, "path"));
3035*00b67f09SDavid van Moolenbroek tresult = isc_sockaddr_frompath(&addr, path);
3036*00b67f09SDavid van Moolenbroek if (tresult == ISC_R_NOSPACE) {
3037*00b67f09SDavid van Moolenbroek cfg_obj_log(control, logctx, ISC_LOG_ERROR,
3038*00b67f09SDavid van Moolenbroek "unix control '%s': path too long",
3039*00b67f09SDavid van Moolenbroek path);
3040*00b67f09SDavid van Moolenbroek result = ISC_R_NOSPACE;
3041*00b67f09SDavid van Moolenbroek }
3042*00b67f09SDavid van Moolenbroek perm = cfg_obj_asuint32(cfg_tuple_get(control, "perm"));
3043*00b67f09SDavid van Moolenbroek for (i = 0; i < 3; i++) {
3044*00b67f09SDavid van Moolenbroek #ifdef NEED_SECURE_DIRECTORY
3045*00b67f09SDavid van Moolenbroek mask = (0x1 << (i*3)); /* SEARCH */
3046*00b67f09SDavid van Moolenbroek #else
3047*00b67f09SDavid van Moolenbroek mask = (0x6 << (i*3)); /* READ + WRITE */
3048*00b67f09SDavid van Moolenbroek #endif
3049*00b67f09SDavid van Moolenbroek if ((perm & mask) == mask)
3050*00b67f09SDavid van Moolenbroek break;
3051*00b67f09SDavid van Moolenbroek }
3052*00b67f09SDavid van Moolenbroek if (i == 0) {
3053*00b67f09SDavid van Moolenbroek cfg_obj_log(control, logctx, ISC_LOG_WARNING,
3054*00b67f09SDavid van Moolenbroek "unix control '%s' allows access "
3055*00b67f09SDavid van Moolenbroek "to everyone", path);
3056*00b67f09SDavid van Moolenbroek } else if (i == 3) {
3057*00b67f09SDavid van Moolenbroek cfg_obj_log(control, logctx, ISC_LOG_WARNING,
3058*00b67f09SDavid van Moolenbroek "unix control '%s' allows access "
3059*00b67f09SDavid van Moolenbroek "to nobody", path);
3060*00b67f09SDavid van Moolenbroek }
3061*00b67f09SDavid van Moolenbroek tresult = bind9_check_controlskeys(control, keylist,
3062*00b67f09SDavid van Moolenbroek logctx);
3063*00b67f09SDavid van Moolenbroek if (tresult != ISC_R_SUCCESS)
3064*00b67f09SDavid van Moolenbroek result = tresult;
3065*00b67f09SDavid van Moolenbroek }
3066*00b67f09SDavid van Moolenbroek }
3067*00b67f09SDavid van Moolenbroek cfg_aclconfctx_detach(&actx);
3068*00b67f09SDavid van Moolenbroek return (result);
3069*00b67f09SDavid van Moolenbroek }
3070*00b67f09SDavid van Moolenbroek
3071*00b67f09SDavid van Moolenbroek isc_result_t
bind9_check_namedconf(const cfg_obj_t * config,isc_log_t * logctx,isc_mem_t * mctx)3072*00b67f09SDavid van Moolenbroek bind9_check_namedconf(const cfg_obj_t *config, isc_log_t *logctx,
3073*00b67f09SDavid van Moolenbroek isc_mem_t *mctx)
3074*00b67f09SDavid van Moolenbroek {
3075*00b67f09SDavid van Moolenbroek const cfg_obj_t *options = NULL;
3076*00b67f09SDavid van Moolenbroek const cfg_obj_t *views = NULL;
3077*00b67f09SDavid van Moolenbroek const cfg_obj_t *acls = NULL;
3078*00b67f09SDavid van Moolenbroek const cfg_obj_t *kals = NULL;
3079*00b67f09SDavid van Moolenbroek const cfg_obj_t *obj;
3080*00b67f09SDavid van Moolenbroek const cfg_listelt_t *velement;
3081*00b67f09SDavid van Moolenbroek isc_result_t result = ISC_R_SUCCESS;
3082*00b67f09SDavid van Moolenbroek isc_result_t tresult;
3083*00b67f09SDavid van Moolenbroek isc_symtab_t *symtab = NULL;
3084*00b67f09SDavid van Moolenbroek isc_symtab_t *files = NULL;
3085*00b67f09SDavid van Moolenbroek
3086*00b67f09SDavid van Moolenbroek static const char *builtin[] = { "localhost", "localnets",
3087*00b67f09SDavid van Moolenbroek "any", "none"};
3088*00b67f09SDavid van Moolenbroek
3089*00b67f09SDavid van Moolenbroek (void)cfg_map_get(config, "options", &options);
3090*00b67f09SDavid van Moolenbroek
3091*00b67f09SDavid van Moolenbroek if (options != NULL &&
3092*00b67f09SDavid van Moolenbroek check_options(options, logctx, mctx,
3093*00b67f09SDavid van Moolenbroek optlevel_options) != ISC_R_SUCCESS)
3094*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
3095*00b67f09SDavid van Moolenbroek
3096*00b67f09SDavid van Moolenbroek if (bind9_check_logging(config, logctx, mctx) != ISC_R_SUCCESS)
3097*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
3098*00b67f09SDavid van Moolenbroek
3099*00b67f09SDavid van Moolenbroek if (bind9_check_controls(config, logctx, mctx) != ISC_R_SUCCESS)
3100*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
3101*00b67f09SDavid van Moolenbroek
3102*00b67f09SDavid van Moolenbroek if (options != NULL &&
3103*00b67f09SDavid van Moolenbroek check_order(options, logctx) != ISC_R_SUCCESS)
3104*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
3105*00b67f09SDavid van Moolenbroek
3106*00b67f09SDavid van Moolenbroek (void)cfg_map_get(config, "view", &views);
3107*00b67f09SDavid van Moolenbroek
3108*00b67f09SDavid van Moolenbroek if (views != NULL && options != NULL)
3109*00b67f09SDavid van Moolenbroek if (check_dual_stack(options, logctx) != ISC_R_SUCCESS)
3110*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
3111*00b67f09SDavid van Moolenbroek
3112*00b67f09SDavid van Moolenbroek /*
3113*00b67f09SDavid van Moolenbroek * Use case insensitve comparision as not all file systems are
3114*00b67f09SDavid van Moolenbroek * case sensitive. This will prevent people using FOO.DB and foo.db
3115*00b67f09SDavid van Moolenbroek * on case sensitive file systems but that shouldn't be a major issue.
3116*00b67f09SDavid van Moolenbroek */
3117*00b67f09SDavid van Moolenbroek tresult = isc_symtab_create(mctx, 100, NULL, NULL, ISC_FALSE,
3118*00b67f09SDavid van Moolenbroek &files);
3119*00b67f09SDavid van Moolenbroek if (tresult != ISC_R_SUCCESS)
3120*00b67f09SDavid van Moolenbroek result = tresult;
3121*00b67f09SDavid van Moolenbroek
3122*00b67f09SDavid van Moolenbroek if (views == NULL) {
3123*00b67f09SDavid van Moolenbroek if (check_viewconf(config, NULL, NULL, dns_rdataclass_in,
3124*00b67f09SDavid van Moolenbroek files, logctx, mctx) != ISC_R_SUCCESS)
3125*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
3126*00b67f09SDavid van Moolenbroek } else {
3127*00b67f09SDavid van Moolenbroek const cfg_obj_t *zones = NULL;
3128*00b67f09SDavid van Moolenbroek
3129*00b67f09SDavid van Moolenbroek (void)cfg_map_get(config, "zone", &zones);
3130*00b67f09SDavid van Moolenbroek if (zones != NULL) {
3131*00b67f09SDavid van Moolenbroek cfg_obj_log(zones, logctx, ISC_LOG_ERROR,
3132*00b67f09SDavid van Moolenbroek "when using 'view' statements, "
3133*00b67f09SDavid van Moolenbroek "all zones must be in views");
3134*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
3135*00b67f09SDavid van Moolenbroek }
3136*00b67f09SDavid van Moolenbroek }
3137*00b67f09SDavid van Moolenbroek
3138*00b67f09SDavid van Moolenbroek tresult = isc_symtab_create(mctx, 100, NULL, NULL, ISC_TRUE, &symtab);
3139*00b67f09SDavid van Moolenbroek if (tresult != ISC_R_SUCCESS)
3140*00b67f09SDavid van Moolenbroek result = tresult;
3141*00b67f09SDavid van Moolenbroek for (velement = cfg_list_first(views);
3142*00b67f09SDavid van Moolenbroek velement != NULL;
3143*00b67f09SDavid van Moolenbroek velement = cfg_list_next(velement))
3144*00b67f09SDavid van Moolenbroek {
3145*00b67f09SDavid van Moolenbroek const cfg_obj_t *view = cfg_listelt_value(velement);
3146*00b67f09SDavid van Moolenbroek const cfg_obj_t *vname = cfg_tuple_get(view, "name");
3147*00b67f09SDavid van Moolenbroek const cfg_obj_t *voptions = cfg_tuple_get(view, "options");
3148*00b67f09SDavid van Moolenbroek const cfg_obj_t *vclassobj = cfg_tuple_get(view, "class");
3149*00b67f09SDavid van Moolenbroek dns_rdataclass_t vclass = dns_rdataclass_in;
3150*00b67f09SDavid van Moolenbroek const char *key = cfg_obj_asstring(vname);
3151*00b67f09SDavid van Moolenbroek isc_symvalue_t symvalue;
3152*00b67f09SDavid van Moolenbroek
3153*00b67f09SDavid van Moolenbroek tresult = ISC_R_SUCCESS;
3154*00b67f09SDavid van Moolenbroek if (cfg_obj_isstring(vclassobj)) {
3155*00b67f09SDavid van Moolenbroek isc_textregion_t r;
3156*00b67f09SDavid van Moolenbroek
3157*00b67f09SDavid van Moolenbroek DE_CONST(cfg_obj_asstring(vclassobj), r.base);
3158*00b67f09SDavid van Moolenbroek r.length = strlen(r.base);
3159*00b67f09SDavid van Moolenbroek tresult = dns_rdataclass_fromtext(&vclass, &r);
3160*00b67f09SDavid van Moolenbroek if (tresult != ISC_R_SUCCESS)
3161*00b67f09SDavid van Moolenbroek cfg_obj_log(vclassobj, logctx, ISC_LOG_ERROR,
3162*00b67f09SDavid van Moolenbroek "view '%s': invalid class %s",
3163*00b67f09SDavid van Moolenbroek cfg_obj_asstring(vname), r.base);
3164*00b67f09SDavid van Moolenbroek }
3165*00b67f09SDavid van Moolenbroek if (tresult == ISC_R_SUCCESS && symtab != NULL) {
3166*00b67f09SDavid van Moolenbroek symvalue.as_cpointer = view;
3167*00b67f09SDavid van Moolenbroek tresult = isc_symtab_define(symtab, key, vclass,
3168*00b67f09SDavid van Moolenbroek symvalue,
3169*00b67f09SDavid van Moolenbroek isc_symexists_reject);
3170*00b67f09SDavid van Moolenbroek if (tresult == ISC_R_EXISTS) {
3171*00b67f09SDavid van Moolenbroek const char *file;
3172*00b67f09SDavid van Moolenbroek unsigned int line;
3173*00b67f09SDavid van Moolenbroek RUNTIME_CHECK(isc_symtab_lookup(symtab, key,
3174*00b67f09SDavid van Moolenbroek vclass, &symvalue) == ISC_R_SUCCESS);
3175*00b67f09SDavid van Moolenbroek file = cfg_obj_file(symvalue.as_cpointer);
3176*00b67f09SDavid van Moolenbroek line = cfg_obj_line(symvalue.as_cpointer);
3177*00b67f09SDavid van Moolenbroek cfg_obj_log(view, logctx, ISC_LOG_ERROR,
3178*00b67f09SDavid van Moolenbroek "view '%s': already exists "
3179*00b67f09SDavid van Moolenbroek "previous definition: %s:%u",
3180*00b67f09SDavid van Moolenbroek key, file, line);
3181*00b67f09SDavid van Moolenbroek result = tresult;
3182*00b67f09SDavid van Moolenbroek } else if (tresult != ISC_R_SUCCESS) {
3183*00b67f09SDavid van Moolenbroek result = tresult;
3184*00b67f09SDavid van Moolenbroek } else if ((strcasecmp(key, "_bind") == 0 &&
3185*00b67f09SDavid van Moolenbroek vclass == dns_rdataclass_ch) ||
3186*00b67f09SDavid van Moolenbroek (strcasecmp(key, "_default") == 0 &&
3187*00b67f09SDavid van Moolenbroek vclass == dns_rdataclass_in)) {
3188*00b67f09SDavid van Moolenbroek cfg_obj_log(view, logctx, ISC_LOG_ERROR,
3189*00b67f09SDavid van Moolenbroek "attempt to redefine builtin view "
3190*00b67f09SDavid van Moolenbroek "'%s'", key);
3191*00b67f09SDavid van Moolenbroek result = ISC_R_EXISTS;
3192*00b67f09SDavid van Moolenbroek }
3193*00b67f09SDavid van Moolenbroek }
3194*00b67f09SDavid van Moolenbroek if (tresult == ISC_R_SUCCESS)
3195*00b67f09SDavid van Moolenbroek tresult = check_viewconf(config, voptions, key, vclass,
3196*00b67f09SDavid van Moolenbroek files, logctx, mctx);
3197*00b67f09SDavid van Moolenbroek if (tresult != ISC_R_SUCCESS)
3198*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
3199*00b67f09SDavid van Moolenbroek }
3200*00b67f09SDavid van Moolenbroek if (symtab != NULL)
3201*00b67f09SDavid van Moolenbroek isc_symtab_destroy(&symtab);
3202*00b67f09SDavid van Moolenbroek if (files != NULL)
3203*00b67f09SDavid van Moolenbroek isc_symtab_destroy(&files);
3204*00b67f09SDavid van Moolenbroek
3205*00b67f09SDavid van Moolenbroek if (views != NULL && options != NULL) {
3206*00b67f09SDavid van Moolenbroek obj = NULL;
3207*00b67f09SDavid van Moolenbroek tresult = cfg_map_get(options, "cache-file", &obj);
3208*00b67f09SDavid van Moolenbroek if (tresult == ISC_R_SUCCESS) {
3209*00b67f09SDavid van Moolenbroek cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
3210*00b67f09SDavid van Moolenbroek "'cache-file' cannot be a global "
3211*00b67f09SDavid van Moolenbroek "option if views are present");
3212*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
3213*00b67f09SDavid van Moolenbroek }
3214*00b67f09SDavid van Moolenbroek }
3215*00b67f09SDavid van Moolenbroek
3216*00b67f09SDavid van Moolenbroek cfg_map_get(config, "acl", &acls);
3217*00b67f09SDavid van Moolenbroek
3218*00b67f09SDavid van Moolenbroek if (acls != NULL) {
3219*00b67f09SDavid van Moolenbroek const cfg_listelt_t *elt;
3220*00b67f09SDavid van Moolenbroek const cfg_listelt_t *elt2;
3221*00b67f09SDavid van Moolenbroek const char *aclname;
3222*00b67f09SDavid van Moolenbroek
3223*00b67f09SDavid van Moolenbroek for (elt = cfg_list_first(acls);
3224*00b67f09SDavid van Moolenbroek elt != NULL;
3225*00b67f09SDavid van Moolenbroek elt = cfg_list_next(elt)) {
3226*00b67f09SDavid van Moolenbroek const cfg_obj_t *acl = cfg_listelt_value(elt);
3227*00b67f09SDavid van Moolenbroek unsigned int line = cfg_obj_line(acl);
3228*00b67f09SDavid van Moolenbroek unsigned int i;
3229*00b67f09SDavid van Moolenbroek
3230*00b67f09SDavid van Moolenbroek aclname = cfg_obj_asstring(cfg_tuple_get(acl, "name"));
3231*00b67f09SDavid van Moolenbroek for (i = 0;
3232*00b67f09SDavid van Moolenbroek i < sizeof(builtin) / sizeof(builtin[0]);
3233*00b67f09SDavid van Moolenbroek i++)
3234*00b67f09SDavid van Moolenbroek if (strcasecmp(aclname, builtin[i]) == 0) {
3235*00b67f09SDavid van Moolenbroek cfg_obj_log(acl, logctx, ISC_LOG_ERROR,
3236*00b67f09SDavid van Moolenbroek "attempt to redefine "
3237*00b67f09SDavid van Moolenbroek "builtin acl '%s'",
3238*00b67f09SDavid van Moolenbroek aclname);
3239*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
3240*00b67f09SDavid van Moolenbroek break;
3241*00b67f09SDavid van Moolenbroek }
3242*00b67f09SDavid van Moolenbroek
3243*00b67f09SDavid van Moolenbroek for (elt2 = cfg_list_next(elt);
3244*00b67f09SDavid van Moolenbroek elt2 != NULL;
3245*00b67f09SDavid van Moolenbroek elt2 = cfg_list_next(elt2)) {
3246*00b67f09SDavid van Moolenbroek const cfg_obj_t *acl2 = cfg_listelt_value(elt2);
3247*00b67f09SDavid van Moolenbroek const char *name;
3248*00b67f09SDavid van Moolenbroek name = cfg_obj_asstring(cfg_tuple_get(acl2,
3249*00b67f09SDavid van Moolenbroek "name"));
3250*00b67f09SDavid van Moolenbroek if (strcasecmp(aclname, name) == 0) {
3251*00b67f09SDavid van Moolenbroek const char *file = cfg_obj_file(acl);
3252*00b67f09SDavid van Moolenbroek
3253*00b67f09SDavid van Moolenbroek if (file == NULL)
3254*00b67f09SDavid van Moolenbroek file = "<unknown file>";
3255*00b67f09SDavid van Moolenbroek
3256*00b67f09SDavid van Moolenbroek cfg_obj_log(acl2, logctx, ISC_LOG_ERROR,
3257*00b67f09SDavid van Moolenbroek "attempt to redefine "
3258*00b67f09SDavid van Moolenbroek "acl '%s' previous "
3259*00b67f09SDavid van Moolenbroek "definition: %s:%u",
3260*00b67f09SDavid van Moolenbroek name, file, line);
3261*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
3262*00b67f09SDavid van Moolenbroek }
3263*00b67f09SDavid van Moolenbroek }
3264*00b67f09SDavid van Moolenbroek }
3265*00b67f09SDavid van Moolenbroek }
3266*00b67f09SDavid van Moolenbroek
3267*00b67f09SDavid van Moolenbroek tresult = cfg_map_get(config, "kal", &kals);
3268*00b67f09SDavid van Moolenbroek if (tresult == ISC_R_SUCCESS) {
3269*00b67f09SDavid van Moolenbroek const cfg_listelt_t *elt;
3270*00b67f09SDavid van Moolenbroek const cfg_listelt_t *elt2;
3271*00b67f09SDavid van Moolenbroek const char *aclname;
3272*00b67f09SDavid van Moolenbroek
3273*00b67f09SDavid van Moolenbroek for (elt = cfg_list_first(kals);
3274*00b67f09SDavid van Moolenbroek elt != NULL;
3275*00b67f09SDavid van Moolenbroek elt = cfg_list_next(elt)) {
3276*00b67f09SDavid van Moolenbroek const cfg_obj_t *acl = cfg_listelt_value(elt);
3277*00b67f09SDavid van Moolenbroek
3278*00b67f09SDavid van Moolenbroek aclname = cfg_obj_asstring(cfg_tuple_get(acl, "name"));
3279*00b67f09SDavid van Moolenbroek
3280*00b67f09SDavid van Moolenbroek for (elt2 = cfg_list_next(elt);
3281*00b67f09SDavid van Moolenbroek elt2 != NULL;
3282*00b67f09SDavid van Moolenbroek elt2 = cfg_list_next(elt2)) {
3283*00b67f09SDavid van Moolenbroek const cfg_obj_t *acl2 = cfg_listelt_value(elt2);
3284*00b67f09SDavid van Moolenbroek const char *name;
3285*00b67f09SDavid van Moolenbroek name = cfg_obj_asstring(cfg_tuple_get(acl2,
3286*00b67f09SDavid van Moolenbroek "name"));
3287*00b67f09SDavid van Moolenbroek if (strcasecmp(aclname, name) == 0) {
3288*00b67f09SDavid van Moolenbroek const char *file = cfg_obj_file(acl);
3289*00b67f09SDavid van Moolenbroek unsigned int line = cfg_obj_line(acl);
3290*00b67f09SDavid van Moolenbroek
3291*00b67f09SDavid van Moolenbroek if (file == NULL)
3292*00b67f09SDavid van Moolenbroek file = "<unknown file>";
3293*00b67f09SDavid van Moolenbroek
3294*00b67f09SDavid van Moolenbroek cfg_obj_log(acl2, logctx, ISC_LOG_ERROR,
3295*00b67f09SDavid van Moolenbroek "attempt to redefine "
3296*00b67f09SDavid van Moolenbroek "kal '%s' previous "
3297*00b67f09SDavid van Moolenbroek "definition: %s:%u",
3298*00b67f09SDavid van Moolenbroek name, file, line);
3299*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
3300*00b67f09SDavid van Moolenbroek }
3301*00b67f09SDavid van Moolenbroek }
3302*00b67f09SDavid van Moolenbroek }
3303*00b67f09SDavid van Moolenbroek }
3304*00b67f09SDavid van Moolenbroek
3305*00b67f09SDavid van Moolenbroek return (result);
3306*00b67f09SDavid van Moolenbroek }
3307