2 * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 2001-2003 Internet Software Consortium.
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15 * PERFORMANCE OF THIS SOFTWARE.
18 /* $Id: check.c,v 1.14.2.25 2004/07/29 00:08:17 marka Exp $ */
25 #include <isc/buffer.h>
28 #include <isc/netaddr.h>
29 #include <isc/result.h>
30 #include <isc/sockaddr.h>
31 #include <isc/symtab.h>
34 #include <dns/fixedname.h>
35 #include <dns/rdataclass.h>
37 #include <isccfg/cfg.h>
38 #include <isccfg/check.h>
41 freekey(char *key
, unsigned int type
, isc_symvalue_t value
, void *userarg
) {
44 isc_mem_free(userarg
, key
);
48 check_forward(cfg_obj_t
*options
, isc_log_t
*logctx
) {
49 cfg_obj_t
*forward
= NULL
;
50 cfg_obj_t
*forwarders
= NULL
;
52 (void)cfg_map_get(options
, "forward", &forward
);
53 (void)cfg_map_get(options
, "forwarders", &forwarders
);
55 if (forward
!= NULL
&& forwarders
== NULL
) {
56 cfg_obj_log(forward
, logctx
, ISC_LOG_ERROR
,
57 "no matching 'forwarders' statement");
58 return (ISC_R_FAILURE
);
60 return (ISC_R_SUCCESS
);
69 check_options(cfg_obj_t
*options
, isc_log_t
*logctx
) {
70 isc_result_t result
= ISC_R_SUCCESS
;
74 static intervaltable intervals
[] = {
75 { "cleaning-interval", 60 },
76 { "heartbeat-interval", 60 },
77 { "interface-interval", 60 },
78 { "max-transfer-idle-in", 60 },
79 { "max-transfer-idle-out", 60 },
80 { "max-transfer-time-in", 60 },
81 { "max-transfer-time-out", 60 },
82 { "sig-validity-interval", 86400},
83 { "statistics-interval", 60 },
87 * Check that fields specified in units of time other than seconds
88 * have reasonable values.
90 for (i
= 0; i
< sizeof(intervals
) / sizeof(intervals
[0]); i
++) {
92 cfg_obj_t
*obj
= NULL
;
93 (void)cfg_map_get(options
, intervals
[i
].name
, &obj
);
96 val
= cfg_obj_asuint32(obj
);
97 if (val
> (ISC_UINT32_MAX
/ intervals
[i
].scale
)) {
98 cfg_obj_log(obj
, logctx
, ISC_LOG_ERROR
,
99 "%s '%d' is out of range",
100 intervals
[i
].name
, val
);
101 result
= ISC_R_RANGE
;
106 (void)cfg_map_get(options
, "root-delegation-only", &obj
);
108 if (!cfg_obj_isvoid(obj
)) {
109 cfg_listelt_t
*element
;
112 dns_fixedname_t fixed
;
115 isc_result_t tresult
;
117 dns_fixedname_init(&fixed
);
118 name
= dns_fixedname_name(&fixed
);
119 for (element
= cfg_list_first(obj
);
121 element
= cfg_list_next(element
)) {
122 exclude
= cfg_listelt_value(element
);
123 str
= cfg_obj_asstring(exclude
);
124 isc_buffer_init(&b
, str
, strlen(str
));
125 isc_buffer_add(&b
, strlen(str
));
126 tresult
= dns_name_fromtext(name
, &b
,
129 if (tresult
!= ISC_R_SUCCESS
) {
130 cfg_obj_log(obj
, logctx
, ISC_LOG_ERROR
,
131 "bad domain name '%s'",
145 #define FORWARDZONE 16
146 #define DELEGATIONZONE 32
154 check_zoneconf(cfg_obj_t
*zconfig
, isc_symtab_t
*symtab
, isc_log_t
*logctx
,
161 cfg_obj_t
*obj
= NULL
;
162 cfg_obj_t
*addrlist
= NULL
;
163 isc_symvalue_t symvalue
;
164 isc_result_t result
= ISC_R_SUCCESS
;
165 isc_result_t tresult
;
167 dns_fixedname_t fixedname
;
170 static optionstable options
[] = {
171 { "allow-query", MASTERZONE
| SLAVEZONE
| STUBZONE
},
172 { "allow-notify", SLAVEZONE
},
173 { "allow-transfer", MASTERZONE
| SLAVEZONE
},
174 { "notify", MASTERZONE
| SLAVEZONE
},
175 { "also-notify", MASTERZONE
| SLAVEZONE
},
176 { "dialup", MASTERZONE
| SLAVEZONE
| STUBZONE
},
177 { "delegation-only", HINTZONE
| STUBZONE
},
178 { "forward", MASTERZONE
| SLAVEZONE
| STUBZONE
| FORWARDZONE
},
179 { "forwarders", MASTERZONE
| SLAVEZONE
| STUBZONE
| FORWARDZONE
},
180 { "maintain-ixfr-base", MASTERZONE
| SLAVEZONE
},
181 { "max-ixfr-log-size", MASTERZONE
| SLAVEZONE
},
182 { "notify-source", MASTERZONE
| SLAVEZONE
},
183 { "notify-source-v6", MASTERZONE
| SLAVEZONE
},
184 { "transfer-source", SLAVEZONE
| STUBZONE
},
185 { "transfer-source-v6", SLAVEZONE
| STUBZONE
},
186 { "max-transfer-time-in", SLAVEZONE
| STUBZONE
},
187 { "max-transfer-time-out", MASTERZONE
| SLAVEZONE
},
188 { "max-transfer-idle-in", SLAVEZONE
| STUBZONE
},
189 { "max-transfer-idle-out", MASTERZONE
| SLAVEZONE
},
190 { "max-retry-time", SLAVEZONE
| STUBZONE
},
191 { "min-retry-time", SLAVEZONE
| STUBZONE
},
192 { "max-refresh-time", SLAVEZONE
| STUBZONE
},
193 { "min-refresh-time", SLAVEZONE
| STUBZONE
},
194 { "sig-validity-interval", MASTERZONE
},
195 { "zone-statistics", MASTERZONE
| SLAVEZONE
| STUBZONE
},
196 { "allow-update", MASTERZONE
},
197 { "allow-update-forwarding", SLAVEZONE
},
198 { "file", MASTERZONE
| SLAVEZONE
| STUBZONE
| HINTZONE
},
199 { "ixfr-base", MASTERZONE
| SLAVEZONE
},
200 { "ixfr-tmp-file", MASTERZONE
| SLAVEZONE
},
201 { "masters", SLAVEZONE
| STUBZONE
},
202 { "pubkey", MASTERZONE
| SLAVEZONE
| STUBZONE
},
203 { "update-policy", MASTERZONE
},
204 { "database", MASTERZONE
| SLAVEZONE
| STUBZONE
},
207 static optionstable dialups
[] = {
208 { "notify", MASTERZONE
| SLAVEZONE
},
209 { "notify-passive", SLAVEZONE
},
210 { "refresh", SLAVEZONE
| STUBZONE
},
211 { "passive", SLAVEZONE
| STUBZONE
},
214 zname
= cfg_obj_asstring(cfg_tuple_get(zconfig
, "name"));
216 zoptions
= cfg_tuple_get(zconfig
, "options");
219 (void)cfg_map_get(zoptions
, "type", &obj
);
221 cfg_obj_log(zconfig
, logctx
, ISC_LOG_ERROR
,
222 "zone '%s': type not present", zname
);
223 return (ISC_R_FAILURE
);
226 typestr
= cfg_obj_asstring(obj
);
227 if (strcasecmp(typestr
, "master") == 0)
229 else if (strcasecmp(typestr
, "slave") == 0)
231 else if (strcasecmp(typestr
, "stub") == 0)
233 else if (strcasecmp(typestr
, "forward") == 0)
235 else if (strcasecmp(typestr
, "hint") == 0)
237 else if (strcasecmp(typestr
, "delegation-only") == 0)
238 ztype
= DELEGATIONZONE
;
240 cfg_obj_log(obj
, logctx
, ISC_LOG_ERROR
,
241 "zone '%s': invalid type %s",
243 return (ISC_R_FAILURE
);
247 * Look for an already existing zone.
248 * We need to make this cannonical as isc_symtab_define()
249 * deals with strings.
251 dns_fixedname_init(&fixedname
);
252 isc_buffer_init(&b
, zname
, strlen(zname
));
253 isc_buffer_add(&b
, strlen(zname
));
254 result
= dns_name_fromtext(dns_fixedname_name(&fixedname
), &b
,
255 dns_rootname
, ISC_TRUE
, NULL
);
256 if (result
!= ISC_R_SUCCESS
) {
257 cfg_obj_log(zconfig
, logctx
, ISC_LOG_ERROR
,
258 "zone '%s': is not a valid name", zname
);
259 result
= ISC_R_FAILURE
;
261 char namebuf
[DNS_NAME_FORMATSIZE
];
264 dns_name_format(dns_fixedname_name(&fixedname
),
265 namebuf
, sizeof(namebuf
));
266 key
= isc_mem_strdup(mctx
, namebuf
);
268 return (ISC_R_NOMEMORY
);
269 symvalue
.as_pointer
= NULL
;
270 tresult
= isc_symtab_define(symtab
, key
,
271 ztype
== HINTZONE
? 1 : 2,
272 symvalue
, isc_symexists_reject
);
273 if (tresult
== ISC_R_EXISTS
) {
274 isc_mem_free(mctx
, key
);
275 cfg_obj_log(zconfig
, logctx
, ISC_LOG_ERROR
,
276 "zone '%s': already exists ", zname
);
277 result
= ISC_R_FAILURE
;
278 } else if (tresult
!= ISC_R_SUCCESS
) {
279 isc_mem_free(mctx
, key
);
286 * Look for inappropriate options for the given zone type.
288 for (i
= 0; i
< sizeof(options
) / sizeof(options
[0]); i
++) {
290 if ((options
[i
].allowed
& ztype
) == 0 &&
291 cfg_map_get(zoptions
, options
[i
].name
, &obj
) ==
294 if (strcmp(options
[i
].name
, "allow-update") != 0 ||
295 ztype
!= SLAVEZONE
) {
296 cfg_obj_log(obj
, logctx
, ISC_LOG_ERROR
,
297 "option '%s' is not allowed "
299 options
[i
].name
, typestr
, zname
);
300 result
= ISC_R_FAILURE
;
302 cfg_obj_log(obj
, logctx
, ISC_LOG_WARNING
,
303 "option '%s' is not allowed "
305 options
[i
].name
, typestr
, zname
);
310 * Slave & stub zones must have a "masters" field.
312 if (ztype
== SLAVEZONE
|| ztype
== STUBZONE
) {
314 if (cfg_map_get(zoptions
, "masters", &obj
) != ISC_R_SUCCESS
) {
315 cfg_obj_log(zoptions
, logctx
, ISC_LOG_ERROR
,
316 "zone '%s': missing 'masters' entry",
318 result
= ISC_R_FAILURE
;
320 addrlist
= cfg_tuple_get(obj
, "addresses");
321 if (cfg_list_first(addrlist
) == NULL
) {
322 cfg_obj_log(zoptions
, logctx
, ISC_LOG_ERROR
,
323 "zone '%s': empty 'masters' entry",
325 result
= ISC_R_FAILURE
;
331 * Master zones can't have both "allow-update" and "update-policy".
333 if (ztype
== MASTERZONE
) {
334 isc_result_t res1
, res2
;
336 res1
= cfg_map_get(zoptions
, "allow-update", &obj
);
338 res2
= cfg_map_get(zoptions
, "update-policy", &obj
);
339 if (res1
== ISC_R_SUCCESS
&& res2
== ISC_R_SUCCESS
) {
340 cfg_obj_log(obj
, logctx
, ISC_LOG_ERROR
,
341 "zone '%s': 'allow-update' is ignored "
342 "when 'update-policy' is present",
344 result
= ISC_R_FAILURE
;
349 * Check the excessively complicated "dialup" option.
351 if (ztype
== MASTERZONE
|| ztype
== SLAVEZONE
|| ztype
== STUBZONE
) {
352 cfg_obj_t
*dialup
= NULL
;
353 cfg_map_get(zoptions
, "dialup", &dialup
);
354 if (dialup
!= NULL
&& cfg_obj_isstring(dialup
)) {
355 char *str
= cfg_obj_asstring(dialup
);
357 i
< sizeof(dialups
) / sizeof(dialups
[0]);
360 if (strcasecmp(dialups
[i
].name
, str
) != 0)
362 if ((dialups
[i
].allowed
& ztype
) == 0) {
363 cfg_obj_log(obj
, logctx
,
365 "dialup type '%s' is not "
368 str
, typestr
, zname
);
369 result
= ISC_R_FAILURE
;
373 if (i
== sizeof(dialups
) / sizeof(dialups
[0])) {
374 cfg_obj_log(obj
, logctx
, ISC_LOG_ERROR
,
375 "invalid dialup type '%s' in zone "
377 result
= ISC_R_FAILURE
;
383 * Check that forwarding is reasonable.
385 if (check_forward(zoptions
, logctx
) != ISC_R_SUCCESS
)
386 result
= ISC_R_FAILURE
;
389 * Check various options.
391 tresult
= check_options(zoptions
, logctx
);
392 if (tresult
!= ISC_R_SUCCESS
)
399 cfg_check_key(cfg_obj_t
*key
, isc_log_t
*logctx
) {
400 cfg_obj_t
*algobj
= NULL
;
401 cfg_obj_t
*secretobj
= NULL
;
402 const char *keyname
= cfg_obj_asstring(cfg_map_getname(key
));
404 cfg_map_get(key
, "algorithm", &algobj
);
405 cfg_map_get(key
, "secret", &secretobj
);
406 if (secretobj
== NULL
|| algobj
== NULL
) {
407 cfg_obj_log(key
, logctx
, ISC_LOG_ERROR
,
408 "key '%s' must have both 'secret' and "
409 "'algorithm' defined",
411 return ISC_R_FAILURE
;
413 return ISC_R_SUCCESS
;
417 check_keylist(cfg_obj_t
*keys
, isc_symtab_t
*symtab
, isc_log_t
*logctx
) {
418 isc_result_t result
= ISC_R_SUCCESS
;
419 isc_result_t tresult
;
420 cfg_listelt_t
*element
;
422 for (element
= cfg_list_first(keys
);
424 element
= cfg_list_next(element
))
426 cfg_obj_t
*key
= cfg_listelt_value(element
);
427 const char *keyname
= cfg_obj_asstring(cfg_map_getname(key
));
428 isc_symvalue_t symvalue
;
430 symvalue
.as_pointer
= NULL
;
431 tresult
= isc_symtab_define(symtab
, keyname
, 1,
432 symvalue
, isc_symexists_reject
);
433 if (tresult
== ISC_R_EXISTS
) {
434 cfg_obj_log(key
, logctx
, ISC_LOG_ERROR
,
435 "key '%s': already exists ", keyname
);
437 } else if (tresult
!= ISC_R_SUCCESS
)
440 tresult
= cfg_check_key(key
, logctx
);
441 if (tresult
!= ISC_R_SUCCESS
)
448 check_servers(cfg_obj_t
*servers
, isc_log_t
*logctx
) {
449 isc_result_t result
= ISC_R_SUCCESS
;
450 cfg_listelt_t
*e1
, *e2
;
452 isc_sockaddr_t
*s1
, *s2
;
455 for (e1
= cfg_list_first(servers
); e1
!= NULL
; e1
= cfg_list_next(e1
)) {
456 v1
= cfg_listelt_value(e1
);
457 s1
= cfg_obj_assockaddr(cfg_map_getname(v1
));
459 while ((e2
= cfg_list_next(e2
)) != NULL
) {
460 v2
= cfg_listelt_value(e2
);
461 s2
= cfg_obj_assockaddr(cfg_map_getname(v2
));
462 if (isc_sockaddr_eqaddr(s1
, s2
)) {
466 isc_netaddr_fromsockaddr(&na
, s2
);
467 isc_buffer_init(&target
, buf
, sizeof(buf
) - 1);
468 INSIST(isc_netaddr_totext(&na
, &target
)
470 buf
[isc_buffer_usedlength(&target
)] = '\0';
472 cfg_obj_log(v2
, logctx
, ISC_LOG_ERROR
,
473 "server '%s': already exists",
475 result
= ISC_R_FAILURE
;
483 check_viewconf(cfg_obj_t
*config
, cfg_obj_t
*vconfig
, isc_log_t
*logctx
, isc_mem_t
*mctx
)
485 cfg_obj_t
*servers
= NULL
;
486 cfg_obj_t
*zones
= NULL
;
487 cfg_obj_t
*keys
= NULL
;
488 cfg_listelt_t
*element
;
489 isc_symtab_t
*symtab
= NULL
;
490 isc_result_t result
= ISC_R_SUCCESS
;
491 isc_result_t tresult
= ISC_R_SUCCESS
;
494 * Check that all zone statements are syntactically correct and
495 * there are no duplicate zones.
497 tresult
= isc_symtab_create(mctx
, 100, freekey
, mctx
,
499 if (tresult
!= ISC_R_SUCCESS
)
500 return (ISC_R_NOMEMORY
);
503 (void)cfg_map_get(vconfig
, "zone", &zones
);
505 (void)cfg_map_get(config
, "zone", &zones
);
507 for (element
= cfg_list_first(zones
);
509 element
= cfg_list_next(element
))
511 cfg_obj_t
*zone
= cfg_listelt_value(element
);
513 if (check_zoneconf(zone
, symtab
, logctx
, mctx
) != ISC_R_SUCCESS
)
514 result
= ISC_R_FAILURE
;
517 isc_symtab_destroy(&symtab
);
520 * Check that all key statements are syntactically correct and
521 * there are no duplicate keys.
523 tresult
= isc_symtab_create(mctx
, 100, NULL
, NULL
, ISC_TRUE
, &symtab
);
524 if (tresult
!= ISC_R_SUCCESS
)
525 return (ISC_R_NOMEMORY
);
527 cfg_map_get(config
, "key", &keys
);
528 tresult
= check_keylist(keys
, symtab
, logctx
);
529 if (tresult
== ISC_R_EXISTS
)
530 result
= ISC_R_FAILURE
;
531 else if (tresult
!= ISC_R_SUCCESS
) {
532 isc_symtab_destroy(&symtab
);
536 if (vconfig
!= NULL
) {
538 (void)cfg_map_get(vconfig
, "key", &keys
);
539 tresult
= check_keylist(keys
, symtab
, logctx
);
540 if (tresult
== ISC_R_EXISTS
)
541 result
= ISC_R_FAILURE
;
542 else if (tresult
!= ISC_R_SUCCESS
) {
543 isc_symtab_destroy(&symtab
);
548 isc_symtab_destroy(&symtab
);
551 * Check that forwarding is reasonable.
553 if (vconfig
== NULL
) {
554 cfg_obj_t
*options
= NULL
;
555 cfg_map_get(config
, "options", &options
);
557 if (check_forward(options
, logctx
) != ISC_R_SUCCESS
)
558 result
= ISC_R_FAILURE
;
560 if (check_forward(vconfig
, logctx
) != ISC_R_SUCCESS
)
561 result
= ISC_R_FAILURE
;
565 if (vconfig
!= NULL
) {
566 (void)cfg_map_get(vconfig
, "server", &servers
);
567 if (servers
!= NULL
&&
568 check_servers(servers
, logctx
) != ISC_R_SUCCESS
)
569 result
= ISC_R_FAILURE
;
573 tresult
= check_options(vconfig
, logctx
);
575 tresult
= check_options(config
, logctx
);
576 if (tresult
!= ISC_R_SUCCESS
)
584 cfg_check_namedconf(cfg_obj_t
*config
, isc_log_t
*logctx
, isc_mem_t
*mctx
) {
585 cfg_obj_t
*options
= NULL
;
586 cfg_obj_t
*servers
= NULL
;
587 cfg_obj_t
*views
= NULL
;
588 cfg_obj_t
*acls
= NULL
;
590 cfg_listelt_t
*velement
;
591 isc_result_t result
= ISC_R_SUCCESS
;
592 isc_result_t tresult
;
593 isc_symtab_t
*symtab
= NULL
;
595 static const char *builtin
[] = { "localhost", "localnets",
598 (void)cfg_map_get(config
, "options", &options
);
600 if (options
!= NULL
&&
601 check_options(options
, logctx
) != ISC_R_SUCCESS
)
602 result
= ISC_R_FAILURE
;
604 (void)cfg_map_get(config
, "server", &servers
);
605 if (servers
!= NULL
&&
606 check_servers(servers
, logctx
) != ISC_R_SUCCESS
)
607 result
= ISC_R_FAILURE
;
609 (void)cfg_map_get(config
, "view", &views
);
612 if (check_viewconf(config
, NULL
, logctx
, mctx
)
614 result
= ISC_R_FAILURE
;
616 cfg_obj_t
*zones
= NULL
;
618 (void)cfg_map_get(config
, "zone", &zones
);
620 cfg_obj_log(zones
, logctx
, ISC_LOG_ERROR
,
621 "when using 'view' statements, "
622 "all zones must be in views");
623 result
= ISC_R_FAILURE
;
627 tresult
= isc_symtab_create(mctx
, 100, NULL
, NULL
, ISC_TRUE
, &symtab
);
628 if (tresult
!= ISC_R_SUCCESS
)
630 for (velement
= cfg_list_first(views
);
632 velement
= cfg_list_next(velement
))
634 cfg_obj_t
*view
= cfg_listelt_value(velement
);
635 cfg_obj_t
*vname
= cfg_tuple_get(view
, "name");
636 cfg_obj_t
*voptions
= cfg_tuple_get(view
, "options");
637 cfg_obj_t
*vclassobj
= cfg_tuple_get(view
, "class");
638 dns_rdataclass_t vclass
= dns_rdataclass_in
;
639 isc_result_t tresult
= ISC_R_SUCCESS
;
640 const char *key
= cfg_obj_asstring(vname
);
641 isc_symvalue_t symvalue
;
643 if (cfg_obj_isstring(vclassobj
)) {
646 DE_CONST(cfg_obj_asstring(vclassobj
), r
.base
);
647 r
.length
= strlen(r
.base
);
648 tresult
= dns_rdataclass_fromtext(&vclass
, &r
);
649 if (tresult
!= ISC_R_SUCCESS
)
650 cfg_obj_log(vclassobj
, logctx
, ISC_LOG_ERROR
,
651 "view '%s': invalid class %s",
652 cfg_obj_asstring(vname
), r
.base
);
654 if (tresult
== ISC_R_SUCCESS
&& symtab
!= NULL
) {
655 symvalue
.as_pointer
= view
;
656 tresult
= isc_symtab_define(symtab
, key
, vclass
,
658 isc_symexists_reject
);
659 if (tresult
== ISC_R_EXISTS
) {
660 cfg_obj_log(view
, logctx
, ISC_LOG_ERROR
,
661 "view '%s': already exists", key
);
663 } else if (result
!= ISC_R_SUCCESS
) {
665 } else if ((strcasecmp(key
, "_bind") == 0 &&
666 vclass
== dns_rdataclass_ch
) ||
667 (strcasecmp(key
, "_default") == 0 &&
668 vclass
== dns_rdataclass_in
)) {
669 cfg_obj_log(view
, logctx
, ISC_LOG_ERROR
,
670 "attempt to redefine builtin view "
672 result
= ISC_R_EXISTS
;
675 if (check_viewconf(config
, voptions
, logctx
, mctx
)
677 result
= ISC_R_FAILURE
;
680 isc_symtab_destroy(&symtab
);
682 if (views
!= NULL
&& options
!= NULL
) {
684 tresult
= cfg_map_get(options
, "cache-file", &obj
);
685 if (tresult
== ISC_R_SUCCESS
) {
686 cfg_obj_log(obj
, logctx
, ISC_LOG_ERROR
,
687 "'cache-file' cannot be a global "
688 "option if views are present");
689 result
= ISC_R_FAILURE
;
693 tresult
= cfg_map_get(config
, "acl", &acls
);
694 if (tresult
== ISC_R_SUCCESS
) {
699 for (elt
= cfg_list_first(acls
);
701 elt
= cfg_list_next(elt
)) {
702 cfg_obj_t
*acl
= cfg_listelt_value(elt
);
705 aclname
= cfg_obj_asstring(cfg_tuple_get(acl
, "name"));
707 i
< sizeof(builtin
) / sizeof(builtin
[0]);
709 if (strcasecmp(aclname
, builtin
[i
]) == 0) {
710 cfg_obj_log(acl
, logctx
, ISC_LOG_ERROR
,
711 "attempt to redefine "
714 result
= ISC_R_FAILURE
;
718 for (elt2
= cfg_list_next(elt
);
720 elt2
= cfg_list_next(elt2
)) {
721 cfg_obj_t
*acl2
= cfg_listelt_value(elt2
);
723 name
= cfg_obj_asstring(cfg_tuple_get(acl2
,
725 if (strcasecmp(aclname
, name
) == 0) {
726 cfg_obj_log(acl2
, logctx
, ISC_LOG_ERROR
,
727 "attempt to redefine "
729 result
= ISC_R_FAILURE
;