2 * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 2000, 2001, 2003 Internet Software Consortium.
5 * Permission to use, copy, modify, and/or 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.
20 * $Id: ssu.c,v 1.31 2007/06/19 23:47:16 tbox Exp $
21 * Principal Author: Brian Wellington
26 #include <isc/magic.h>
28 #include <isc/result.h>
29 #include <isc/string.h> /* Required for HP/UX (and others?) */
32 #include <dns/fixedname.h>
36 #include <dst/gssapi.h>
38 #define SSUTABLEMAGIC ISC_MAGIC('S', 'S', 'U', 'T')
39 #define VALID_SSUTABLE(table) ISC_MAGIC_VALID(table, SSUTABLEMAGIC)
41 #define SSURULEMAGIC ISC_MAGIC('S', 'S', 'U', 'R')
42 #define VALID_SSURULE(table) ISC_MAGIC_VALID(table, SSURULEMAGIC)
46 isc_boolean_t grant
; /*%< is this a grant or a deny? */
47 unsigned int matchtype
; /*%< which type of pattern match? */
48 dns_name_t
*identity
; /*%< the identity to match */
49 dns_name_t
*name
; /*%< the name being updated */
50 unsigned int ntypes
; /*%< number of data types covered */
51 dns_rdatatype_t
*types
; /*%< the data types. Can include ANY, */
52 /*%< defaults to all but SIG,SOA,NS if NULL */
53 ISC_LINK(dns_ssurule_t
) link
;
59 unsigned int references
;
61 ISC_LIST(dns_ssurule_t
) rules
;
65 dns_ssutable_create(isc_mem_t
*mctx
, dns_ssutable_t
**tablep
) {
67 dns_ssutable_t
*table
;
69 REQUIRE(tablep
!= NULL
&& *tablep
== NULL
);
70 REQUIRE(mctx
!= NULL
);
72 table
= isc_mem_get(mctx
, sizeof(dns_ssutable_t
));
74 return (ISC_R_NOMEMORY
);
75 result
= isc_mutex_init(&table
->lock
);
76 if (result
!= ISC_R_SUCCESS
) {
77 isc_mem_put(mctx
, table
, sizeof(dns_ssutable_t
));
80 table
->references
= 1;
82 ISC_LIST_INIT(table
->rules
);
83 table
->magic
= SSUTABLEMAGIC
;
85 return (ISC_R_SUCCESS
);
89 destroy(dns_ssutable_t
*table
) {
92 REQUIRE(VALID_SSUTABLE(table
));
95 while (!ISC_LIST_EMPTY(table
->rules
)) {
96 dns_ssurule_t
*rule
= ISC_LIST_HEAD(table
->rules
);
97 if (rule
->identity
!= NULL
) {
98 dns_name_free(rule
->identity
, mctx
);
99 isc_mem_put(mctx
, rule
->identity
, sizeof(dns_name_t
));
101 if (rule
->name
!= NULL
) {
102 dns_name_free(rule
->name
, mctx
);
103 isc_mem_put(mctx
, rule
->name
, sizeof(dns_name_t
));
105 if (rule
->types
!= NULL
)
106 isc_mem_put(mctx
, rule
->types
,
107 rule
->ntypes
* sizeof(dns_rdatatype_t
));
108 ISC_LIST_UNLINK(table
->rules
, rule
, link
);
110 isc_mem_put(mctx
, rule
, sizeof(dns_ssurule_t
));
112 DESTROYLOCK(&table
->lock
);
114 isc_mem_put(mctx
, table
, sizeof(dns_ssutable_t
));
118 dns_ssutable_attach(dns_ssutable_t
*source
, dns_ssutable_t
**targetp
) {
119 REQUIRE(VALID_SSUTABLE(source
));
120 REQUIRE(targetp
!= NULL
&& *targetp
== NULL
);
124 INSIST(source
->references
> 0);
125 source
->references
++;
126 INSIST(source
->references
!= 0);
128 UNLOCK(&source
->lock
);
134 dns_ssutable_detach(dns_ssutable_t
**tablep
) {
135 dns_ssutable_t
*table
;
136 isc_boolean_t done
= ISC_FALSE
;
138 REQUIRE(tablep
!= NULL
);
140 REQUIRE(VALID_SSUTABLE(table
));
144 INSIST(table
->references
> 0);
145 if (--table
->references
== 0)
147 UNLOCK(&table
->lock
);
156 dns_ssutable_addrule(dns_ssutable_t
*table
, isc_boolean_t grant
,
157 dns_name_t
*identity
, unsigned int matchtype
,
158 dns_name_t
*name
, unsigned int ntypes
,
159 dns_rdatatype_t
*types
)
165 REQUIRE(VALID_SSUTABLE(table
));
166 REQUIRE(dns_name_isabsolute(identity
));
167 REQUIRE(dns_name_isabsolute(name
));
168 REQUIRE(matchtype
<= DNS_SSUMATCHTYPE_MAX
);
169 if (matchtype
== DNS_SSUMATCHTYPE_WILDCARD
)
170 REQUIRE(dns_name_iswildcard(name
));
172 REQUIRE(types
!= NULL
);
175 rule
= isc_mem_get(mctx
, sizeof(dns_ssurule_t
));
177 return (ISC_R_NOMEMORY
);
179 rule
->identity
= NULL
;
185 rule
->identity
= isc_mem_get(mctx
, sizeof(dns_name_t
));
186 if (rule
->identity
== NULL
) {
187 result
= ISC_R_NOMEMORY
;
190 dns_name_init(rule
->identity
, NULL
);
191 result
= dns_name_dup(identity
, mctx
, rule
->identity
);
192 if (result
!= ISC_R_SUCCESS
)
195 rule
->name
= isc_mem_get(mctx
, sizeof(dns_name_t
));
196 if (rule
->name
== NULL
) {
197 result
= ISC_R_NOMEMORY
;
200 dns_name_init(rule
->name
, NULL
);
201 result
= dns_name_dup(name
, mctx
, rule
->name
);
202 if (result
!= ISC_R_SUCCESS
)
205 rule
->matchtype
= matchtype
;
207 rule
->ntypes
= ntypes
;
209 rule
->types
= isc_mem_get(mctx
,
210 ntypes
* sizeof(dns_rdatatype_t
));
211 if (rule
->types
== NULL
) {
212 result
= ISC_R_NOMEMORY
;
215 memcpy(rule
->types
, types
, ntypes
* sizeof(dns_rdatatype_t
));
219 rule
->magic
= SSURULEMAGIC
;
220 ISC_LIST_INITANDAPPEND(table
->rules
, rule
, link
);
222 return (ISC_R_SUCCESS
);
225 if (rule
->identity
!= NULL
) {
226 if (dns_name_dynamic(rule
->identity
))
227 dns_name_free(rule
->identity
, mctx
);
228 isc_mem_put(mctx
, rule
->identity
, sizeof(dns_name_t
));
230 if (rule
->name
!= NULL
) {
231 if (dns_name_dynamic(rule
->name
))
232 dns_name_free(rule
->name
, mctx
);
233 isc_mem_put(mctx
, rule
->name
, sizeof(dns_name_t
));
235 if (rule
->types
!= NULL
)
236 isc_mem_put(mctx
, rule
->types
,
237 ntypes
* sizeof(dns_rdatatype_t
));
238 isc_mem_put(mctx
, rule
, sizeof(dns_ssurule_t
));
243 static inline isc_boolean_t
244 isusertype(dns_rdatatype_t type
) {
245 return (ISC_TF(type
!= dns_rdatatype_ns
&&
246 type
!= dns_rdatatype_soa
&&
247 type
!= dns_rdatatype_rrsig
));
251 dns_ssutable_checkrules(dns_ssutable_t
*table
, dns_name_t
*signer
,
252 dns_name_t
*name
, dns_rdatatype_t type
)
256 dns_fixedname_t fixed
;
257 dns_name_t
*wildcard
;
260 REQUIRE(VALID_SSUTABLE(table
));
261 REQUIRE(signer
== NULL
|| dns_name_isabsolute(signer
));
262 REQUIRE(dns_name_isabsolute(name
));
267 for (rule
= ISC_LIST_HEAD(table
->rules
);
269 rule
= ISC_LIST_NEXT(rule
, link
))
271 switch (rule
->matchtype
) {
272 case DNS_SSUMATCHTYPE_NAME
:
273 case DNS_SSUMATCHTYPE_SUBDOMAIN
:
274 case DNS_SSUMATCHTYPE_WILDCARD
:
275 case DNS_SSUMATCHTYPE_SELF
:
276 case DNS_SSUMATCHTYPE_SELFSUB
:
277 case DNS_SSUMATCHTYPE_SELFWILD
:
278 if (dns_name_iswildcard(rule
->identity
)) {
279 if (!dns_name_matcheswildcard(signer
,
284 if (!dns_name_equal(signer
, rule
->identity
))
290 switch (rule
->matchtype
) {
291 case DNS_SSUMATCHTYPE_NAME
:
292 if (!dns_name_equal(name
, rule
->name
))
295 case DNS_SSUMATCHTYPE_SUBDOMAIN
:
296 if (!dns_name_issubdomain(name
, rule
->name
))
299 case DNS_SSUMATCHTYPE_WILDCARD
:
300 if (!dns_name_matcheswildcard(name
, rule
->name
))
303 case DNS_SSUMATCHTYPE_SELF
:
304 if (!dns_name_equal(signer
, name
))
307 case DNS_SSUMATCHTYPE_SELFSUB
:
308 if (!dns_name_issubdomain(name
, signer
))
311 case DNS_SSUMATCHTYPE_SELFWILD
:
312 dns_fixedname_init(&fixed
);
313 wildcard
= dns_fixedname_name(&fixed
);
314 result
= dns_name_concatenate(dns_wildcardname
, signer
,
316 if (result
!= ISC_R_SUCCESS
)
318 if (!dns_name_matcheswildcard(name
, wildcard
))
321 case DNS_SSUMATCHTYPE_SELFKRB5
:
322 if (!dst_gssapi_identitymatchesrealmkrb5(signer
, name
,
326 case DNS_SSUMATCHTYPE_SELFMS
:
327 if (!dst_gssapi_identitymatchesrealmms(signer
, name
,
331 case DNS_SSUMATCHTYPE_SUBDOMAINKRB5
:
332 if (!dns_name_issubdomain(name
, rule
->name
))
334 if (!dst_gssapi_identitymatchesrealmkrb5(signer
, NULL
,
338 case DNS_SSUMATCHTYPE_SUBDOMAINMS
:
339 if (!dns_name_issubdomain(name
, rule
->name
))
341 if (!dst_gssapi_identitymatchesrealmms(signer
, NULL
,
347 if (rule
->ntypes
== 0) {
348 if (!isusertype(type
))
351 for (i
= 0; i
< rule
->ntypes
; i
++) {
352 if (rule
->types
[i
] == dns_rdatatype_any
||
353 rule
->types
[i
] == type
)
356 if (i
== rule
->ntypes
)
359 return (rule
->grant
);
366 dns_ssurule_isgrant(const dns_ssurule_t
*rule
) {
367 REQUIRE(VALID_SSURULE(rule
));
368 return (rule
->grant
);
372 dns_ssurule_identity(const dns_ssurule_t
*rule
) {
373 REQUIRE(VALID_SSURULE(rule
));
374 return (rule
->identity
);
378 dns_ssurule_matchtype(const dns_ssurule_t
*rule
) {
379 REQUIRE(VALID_SSURULE(rule
));
380 return (rule
->matchtype
);
384 dns_ssurule_name(const dns_ssurule_t
*rule
) {
385 REQUIRE(VALID_SSURULE(rule
));
390 dns_ssurule_types(const dns_ssurule_t
*rule
, dns_rdatatype_t
**types
) {
391 REQUIRE(VALID_SSURULE(rule
));
392 REQUIRE(types
!= NULL
&& *types
!= NULL
);
393 *types
= rule
->types
;
394 return (rule
->ntypes
);
398 dns_ssutable_firstrule(const dns_ssutable_t
*table
, dns_ssurule_t
**rule
) {
399 REQUIRE(VALID_SSUTABLE(table
));
400 REQUIRE(rule
!= NULL
&& *rule
== NULL
);
401 *rule
= ISC_LIST_HEAD(table
->rules
);
402 return (*rule
!= NULL
? ISC_R_SUCCESS
: ISC_R_NOMORE
);
406 dns_ssutable_nextrule(dns_ssurule_t
*rule
, dns_ssurule_t
**nextrule
) {
407 REQUIRE(VALID_SSURULE(rule
));
408 REQUIRE(nextrule
!= NULL
&& *nextrule
== NULL
);
409 *nextrule
= ISC_LIST_NEXT(rule
, link
);
410 return (*nextrule
!= NULL
? ISC_R_SUCCESS
: ISC_R_NOMORE
);