2 * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 2000, 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.
19 * $Id: ssu.c,v 1.22.206.3 2004/03/08 09:04:32 marka Exp $
20 * Principal Author: Brian Wellington
25 #include <isc/magic.h>
27 #include <isc/string.h> /* Required for HP/UX (and others?) */
33 #define SSUTABLEMAGIC ISC_MAGIC('S', 'S', 'U', 'T')
34 #define VALID_SSUTABLE(table) ISC_MAGIC_VALID(table, SSUTABLEMAGIC)
36 #define SSURULEMAGIC ISC_MAGIC('S', 'S', 'U', 'R')
37 #define VALID_SSURULE(table) ISC_MAGIC_VALID(table, SSURULEMAGIC)
41 isc_boolean_t grant
; /* is this a grant or a deny? */
42 unsigned int matchtype
; /* which type of pattern match? */
43 dns_name_t
*identity
; /* the identity to match */
44 dns_name_t
*name
; /* the name being updated */
45 unsigned int ntypes
; /* number of data types covered */
46 dns_rdatatype_t
*types
; /* the data types. Can include ANY, */
47 /* defaults to all but SIG,SOA,NS if NULL*/
48 ISC_LINK(dns_ssurule_t
) link
;
54 unsigned int references
;
56 ISC_LIST(dns_ssurule_t
) rules
;
60 dns_ssutable_create(isc_mem_t
*mctx
, dns_ssutable_t
**tablep
) {
62 dns_ssutable_t
*table
;
64 REQUIRE(tablep
!= NULL
&& *tablep
== NULL
);
65 REQUIRE(mctx
!= NULL
);
67 table
= isc_mem_get(mctx
, sizeof(dns_ssutable_t
));
69 return (ISC_R_NOMEMORY
);
70 result
= isc_mutex_init(&table
->lock
);
71 if (result
!= ISC_R_SUCCESS
) {
72 isc_mem_put(mctx
, table
, sizeof(dns_ssutable_t
));
75 table
->references
= 1;
77 ISC_LIST_INIT(table
->rules
);
78 table
->magic
= SSUTABLEMAGIC
;
80 return (ISC_R_SUCCESS
);
84 destroy(dns_ssutable_t
*table
) {
87 REQUIRE(VALID_SSUTABLE(table
));
90 while (!ISC_LIST_EMPTY(table
->rules
)) {
91 dns_ssurule_t
*rule
= ISC_LIST_HEAD(table
->rules
);
92 if (rule
->identity
!= NULL
) {
93 dns_name_free(rule
->identity
, mctx
);
94 isc_mem_put(mctx
, rule
->identity
, sizeof(dns_name_t
));
96 if (rule
->name
!= NULL
) {
97 dns_name_free(rule
->name
, mctx
);
98 isc_mem_put(mctx
, rule
->name
, sizeof(dns_name_t
));
100 if (rule
->types
!= NULL
)
101 isc_mem_put(mctx
, rule
->types
,
102 rule
->ntypes
* sizeof(dns_rdatatype_t
));
103 ISC_LIST_UNLINK(table
->rules
, rule
, link
);
105 isc_mem_put(mctx
, rule
, sizeof(dns_ssurule_t
));
107 DESTROYLOCK(&table
->lock
);
109 isc_mem_put(mctx
, table
, sizeof(dns_ssutable_t
));
113 dns_ssutable_attach(dns_ssutable_t
*source
, dns_ssutable_t
**targetp
) {
114 REQUIRE(VALID_SSUTABLE(source
));
115 REQUIRE(targetp
!= NULL
&& *targetp
== NULL
);
119 INSIST(source
->references
> 0);
120 source
->references
++;
121 INSIST(source
->references
!= 0);
123 UNLOCK(&source
->lock
);
129 dns_ssutable_detach(dns_ssutable_t
**tablep
) {
130 dns_ssutable_t
*table
;
131 isc_boolean_t done
= ISC_FALSE
;
133 REQUIRE(tablep
!= NULL
);
135 REQUIRE(VALID_SSUTABLE(table
));
139 INSIST(table
->references
> 0);
140 if (--table
->references
== 0)
142 UNLOCK(&table
->lock
);
151 dns_ssutable_addrule(dns_ssutable_t
*table
, isc_boolean_t grant
,
152 dns_name_t
*identity
, unsigned int matchtype
,
153 dns_name_t
*name
, unsigned int ntypes
,
154 dns_rdatatype_t
*types
)
160 REQUIRE(VALID_SSUTABLE(table
));
161 REQUIRE(dns_name_isabsolute(identity
));
162 REQUIRE(dns_name_isabsolute(name
));
163 REQUIRE(matchtype
<= DNS_SSUMATCHTYPE_SELF
);
164 if (matchtype
== DNS_SSUMATCHTYPE_WILDCARD
)
165 REQUIRE(dns_name_iswildcard(name
));
167 REQUIRE(types
!= NULL
);
170 rule
= isc_mem_get(mctx
, sizeof(dns_ssurule_t
));
172 return (ISC_R_NOMEMORY
);
174 rule
->identity
= NULL
;
180 rule
->identity
= isc_mem_get(mctx
, sizeof(dns_name_t
));
181 if (rule
->identity
== NULL
) {
182 result
= ISC_R_NOMEMORY
;
185 dns_name_init(rule
->identity
, NULL
);
186 result
= dns_name_dup(identity
, mctx
, rule
->identity
);
187 if (result
!= ISC_R_SUCCESS
)
190 rule
->name
= isc_mem_get(mctx
, sizeof(dns_name_t
));
191 if (rule
->name
== NULL
) {
192 result
= ISC_R_NOMEMORY
;
195 dns_name_init(rule
->name
, NULL
);
196 result
= dns_name_dup(name
, mctx
, rule
->name
);
197 if (result
!= ISC_R_SUCCESS
)
200 rule
->matchtype
= matchtype
;
202 rule
->ntypes
= ntypes
;
204 rule
->types
= isc_mem_get(mctx
,
205 ntypes
* sizeof(dns_rdatatype_t
));
206 if (rule
->types
== NULL
) {
207 result
= ISC_R_NOMEMORY
;
210 memcpy(rule
->types
, types
, ntypes
* sizeof(dns_rdatatype_t
));
215 rule
->magic
= SSURULEMAGIC
;
216 ISC_LIST_INITANDAPPEND(table
->rules
, rule
, link
);
218 return (ISC_R_SUCCESS
);
221 if (rule
->identity
!= NULL
) {
222 if (dns_name_dynamic(rule
->identity
))
223 dns_name_free(rule
->identity
, mctx
);
224 isc_mem_put(mctx
, rule
->identity
, sizeof(dns_name_t
));
226 if (rule
->name
!= NULL
) {
227 if (dns_name_dynamic(rule
->name
))
228 dns_name_free(rule
->name
, mctx
);
229 isc_mem_put(mctx
, rule
->name
, sizeof(dns_name_t
));
231 if (rule
->types
!= NULL
)
232 isc_mem_put(mctx
, rule
->types
,
233 ntypes
* sizeof(dns_rdatatype_t
));
234 isc_mem_put(mctx
, rule
, sizeof(dns_ssurule_t
));
239 static inline isc_boolean_t
240 isusertype(dns_rdatatype_t type
) {
241 return (ISC_TF(type
!= dns_rdatatype_ns
&&
242 type
!= dns_rdatatype_soa
&&
243 type
!= dns_rdatatype_rrsig
));
247 dns_ssutable_checkrules(dns_ssutable_t
*table
, dns_name_t
*signer
,
248 dns_name_t
*name
, dns_rdatatype_t type
)
253 REQUIRE(VALID_SSUTABLE(table
));
254 REQUIRE(signer
== NULL
|| dns_name_isabsolute(signer
));
255 REQUIRE(dns_name_isabsolute(name
));
259 rule
= ISC_LIST_HEAD(table
->rules
);
260 rule
= ISC_LIST_NEXT(rule
, link
);
261 for (rule
= ISC_LIST_HEAD(table
->rules
);
263 rule
= ISC_LIST_NEXT(rule
, link
))
265 if (dns_name_iswildcard(rule
->identity
)) {
266 if (!dns_name_matcheswildcard(signer
, rule
->identity
))
270 if (!dns_name_equal(signer
, rule
->identity
))
274 if (rule
->matchtype
== DNS_SSUMATCHTYPE_NAME
) {
275 if (!dns_name_equal(name
, rule
->name
))
278 else if (rule
->matchtype
== DNS_SSUMATCHTYPE_SUBDOMAIN
) {
279 if (!dns_name_issubdomain(name
, rule
->name
))
282 else if (rule
->matchtype
== DNS_SSUMATCHTYPE_WILDCARD
) {
283 if (!dns_name_matcheswildcard(name
, rule
->name
))
287 else if (rule
->matchtype
== DNS_SSUMATCHTYPE_SELF
) {
288 if (!dns_name_equal(signer
, name
))
292 if (rule
->ntypes
== 0) {
293 if (!isusertype(type
))
297 for (i
= 0; i
< rule
->ntypes
; i
++) {
298 if (rule
->types
[i
] == dns_rdatatype_any
||
299 rule
->types
[i
] == type
)
302 if (i
== rule
->ntypes
)
305 return (rule
->grant
);
312 dns_ssurule_isgrant(const dns_ssurule_t
*rule
) {
313 REQUIRE(VALID_SSURULE(rule
));
314 return (rule
->grant
);
318 dns_ssurule_identity(const dns_ssurule_t
*rule
) {
319 REQUIRE(VALID_SSURULE(rule
));
320 return (rule
->identity
);
324 dns_ssurule_matchtype(const dns_ssurule_t
*rule
) {
325 REQUIRE(VALID_SSURULE(rule
));
326 return (rule
->matchtype
);
330 dns_ssurule_name(const dns_ssurule_t
*rule
) {
331 REQUIRE(VALID_SSURULE(rule
));
336 dns_ssurule_types(const dns_ssurule_t
*rule
, dns_rdatatype_t
**types
) {
337 REQUIRE(VALID_SSURULE(rule
));
338 REQUIRE(types
!= NULL
&& *types
!= NULL
);
339 *types
= rule
->types
;
340 return (rule
->ntypes
);
344 dns_ssutable_firstrule(const dns_ssutable_t
*table
, dns_ssurule_t
**rule
) {
345 REQUIRE(VALID_SSUTABLE(table
));
346 REQUIRE(rule
!= NULL
&& *rule
== NULL
);
347 *rule
= ISC_LIST_HEAD(table
->rules
);
348 return (*rule
!= NULL
? ISC_R_SUCCESS
: ISC_R_NOMORE
);
352 dns_ssutable_nextrule(dns_ssurule_t
*rule
, dns_ssurule_t
**nextrule
) {
353 REQUIRE(VALID_SSURULE(rule
));
354 REQUIRE(nextrule
!= NULL
&& *nextrule
== NULL
);
355 *nextrule
= ISC_LIST_NEXT(rule
, link
);
356 return (*nextrule
!= NULL
? ISC_R_SUCCESS
: ISC_R_NOMORE
);