2 * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 1999-2001 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: aclconf.c,v 1.27.2.1 2004/03/09 06:09:17 marka Exp $ */
23 #include <isc/string.h> /* Required for HP/UX (and others?) */
27 #include <dns/fixedname.h>
30 #include <named/aclconf.h>
33 ns_aclconfctx_init(ns_aclconfctx_t
*ctx
) {
34 ISC_LIST_INIT(ctx
->named_acl_cache
);
38 ns_aclconfctx_destroy(ns_aclconfctx_t
*ctx
) {
39 dns_acl_t
*dacl
, *next
;
40 for (dacl
= ISC_LIST_HEAD(ctx
->named_acl_cache
);
44 next
= ISC_LIST_NEXT(dacl
, nextincache
);
45 dns_acl_detach(&dacl
);
50 * Find the definition of the named acl whose name is "name".
53 get_acl_def(cfg_obj_t
*cctx
, char *name
, cfg_obj_t
**ret
) {
55 cfg_obj_t
*acls
= NULL
;
58 result
= cfg_map_get(cctx
, "acl", &acls
);
59 if (result
!= ISC_R_SUCCESS
)
61 for (elt
= cfg_list_first(acls
);
63 elt
= cfg_list_next(elt
)) {
64 cfg_obj_t
*acl
= cfg_listelt_value(elt
);
65 const char *aclname
= cfg_obj_asstring(cfg_tuple_get(acl
, "name"));
66 if (strcasecmp(aclname
, name
) == 0) {
67 *ret
= cfg_tuple_get(acl
, "value");
68 return (ISC_R_SUCCESS
);
71 return (ISC_R_NOTFOUND
);
75 convert_named_acl(cfg_obj_t
*nameobj
, cfg_obj_t
*cctx
,
76 ns_aclconfctx_t
*ctx
, isc_mem_t
*mctx
,
80 cfg_obj_t
*cacl
= NULL
;
82 char *aclname
= cfg_obj_asstring(nameobj
);
84 /* Look for an already-converted version. */
85 for (dacl
= ISC_LIST_HEAD(ctx
->named_acl_cache
);
87 dacl
= ISC_LIST_NEXT(dacl
, nextincache
))
89 if (strcasecmp(aclname
, dacl
->name
) == 0) {
90 dns_acl_attach(dacl
, target
);
91 return (ISC_R_SUCCESS
);
94 /* Not yet converted. Convert now. */
95 result
= get_acl_def(cctx
, aclname
, &cacl
);
96 if (result
!= ISC_R_SUCCESS
) {
97 cfg_obj_log(nameobj
, dns_lctx
, ISC_LOG_WARNING
,
98 "undefined ACL '%s'", aclname
);
101 result
= ns_acl_fromconfig(cacl
, cctx
, ctx
, mctx
, &dacl
);
102 if (result
!= ISC_R_SUCCESS
)
104 dacl
->name
= isc_mem_strdup(dacl
->mctx
, aclname
);
105 if (dacl
->name
== NULL
)
106 return (ISC_R_NOMEMORY
);
107 ISC_LIST_APPEND(ctx
->named_acl_cache
, dacl
, nextincache
);
108 dns_acl_attach(dacl
, target
);
109 return (ISC_R_SUCCESS
);
113 convert_keyname(cfg_obj_t
*keyobj
, isc_mem_t
*mctx
, dns_name_t
*dnsname
) {
116 dns_fixedname_t fixname
;
118 const char *txtname
= cfg_obj_asstring(keyobj
);
120 keylen
= strlen(txtname
);
121 isc_buffer_init(&buf
, txtname
, keylen
);
122 isc_buffer_add(&buf
, keylen
);
123 dns_fixedname_init(&fixname
);
124 result
= dns_name_fromtext(dns_fixedname_name(&fixname
), &buf
,
125 dns_rootname
, ISC_FALSE
, NULL
);
126 if (result
!= ISC_R_SUCCESS
) {
127 cfg_obj_log(keyobj
, dns_lctx
, ISC_LOG_WARNING
,
128 "key name '%s' is not a valid domain name",
132 return (dns_name_dup(dns_fixedname_name(&fixname
), mctx
, dnsname
));
136 ns_acl_fromconfig(cfg_obj_t
*caml
,
138 ns_aclconfctx_t
*ctx
,
144 dns_acl_t
*dacl
= NULL
;
145 dns_aclelement_t
*de
;
148 REQUIRE(target
!= NULL
&& *target
== NULL
);
151 for (elt
= cfg_list_first(caml
);
153 elt
= cfg_list_next(elt
))
156 result
= dns_acl_create(mctx
, count
, &dacl
);
157 if (result
!= ISC_R_SUCCESS
)
161 for (elt
= cfg_list_first(caml
);
163 elt
= cfg_list_next(elt
))
165 cfg_obj_t
*ce
= cfg_listelt_value(elt
);
166 if (cfg_obj_istuple(ce
)) {
167 /* This must be a negated element. */
168 ce
= cfg_tuple_get(ce
, "value");
169 de
->negative
= ISC_TRUE
;
171 de
->negative
= ISC_FALSE
;
174 if (cfg_obj_isnetprefix(ce
)) {
176 de
->type
= dns_aclelementtype_ipprefix
;
178 cfg_obj_asnetprefix(ce
,
179 &de
->u
.ip_prefix
.address
,
180 &de
->u
.ip_prefix
.prefixlen
);
181 } else if (cfg_obj_istype(ce
, &cfg_type_keyref
)) {
183 de
->type
= dns_aclelementtype_keyname
;
184 dns_name_init(&de
->u
.keyname
, NULL
);
185 result
= convert_keyname(ce
, mctx
, &de
->u
.keyname
);
186 if (result
!= ISC_R_SUCCESS
)
188 } else if (cfg_obj_islist(ce
)) {
190 de
->type
= dns_aclelementtype_nestedacl
;
191 result
= ns_acl_fromconfig(ce
, cctx
, ctx
, mctx
,
193 if (result
!= ISC_R_SUCCESS
)
195 } else if (cfg_obj_isstring(ce
)) {
197 char *name
= cfg_obj_asstring(ce
);
198 if (strcasecmp(name
, "localhost") == 0) {
199 de
->type
= dns_aclelementtype_localhost
;
200 } else if (strcasecmp(name
, "localnets") == 0) {
201 de
->type
= dns_aclelementtype_localnets
;
202 } else if (strcasecmp(name
, "any") == 0) {
203 de
->type
= dns_aclelementtype_any
;
204 } else if (strcasecmp(name
, "none") == 0) {
205 de
->type
= dns_aclelementtype_any
;
206 de
->negative
= ISC_TF(! de
->negative
);
208 de
->type
= dns_aclelementtype_nestedacl
;
209 result
= convert_named_acl(ce
, cctx
, ctx
, mctx
,
211 if (result
!= ISC_R_SUCCESS
)
215 cfg_obj_log(ce
, dns_lctx
, ISC_LOG_WARNING
,
216 "address match list contains "
217 "unsupported element type");
218 result
= ISC_R_FAILURE
;
226 return (ISC_R_SUCCESS
);
229 dns_acl_detach(&dacl
);