1*00b67f09SDavid van Moolenbroek /* $NetBSD: ssu.c,v 1.6 2014/12/10 04:37:58 christos Exp $ */
2*00b67f09SDavid van Moolenbroek
3*00b67f09SDavid van Moolenbroek /*
4*00b67f09SDavid van Moolenbroek * Copyright (C) 2004-2008, 2010, 2011, 2013, 2014 Internet Systems Consortium, Inc. ("ISC")
5*00b67f09SDavid van Moolenbroek * Copyright (C) 2000, 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 * Id: ssu.c,v 1.38 2011/01/06 23:47:00 tbox Exp
23*00b67f09SDavid van Moolenbroek * Principal Author: Brian Wellington
24*00b67f09SDavid van Moolenbroek */
25*00b67f09SDavid van Moolenbroek
26*00b67f09SDavid van Moolenbroek #include <config.h>
27*00b67f09SDavid van Moolenbroek
28*00b67f09SDavid van Moolenbroek #include <isc/magic.h>
29*00b67f09SDavid van Moolenbroek #include <isc/mem.h>
30*00b67f09SDavid van Moolenbroek #include <isc/netaddr.h>
31*00b67f09SDavid van Moolenbroek #include <isc/result.h>
32*00b67f09SDavid van Moolenbroek #include <isc/string.h>
33*00b67f09SDavid van Moolenbroek #include <isc/util.h>
34*00b67f09SDavid van Moolenbroek
35*00b67f09SDavid van Moolenbroek #include <dns/dlz.h>
36*00b67f09SDavid van Moolenbroek #include <dns/fixedname.h>
37*00b67f09SDavid van Moolenbroek #include <dns/name.h>
38*00b67f09SDavid van Moolenbroek #include <dns/ssu.h>
39*00b67f09SDavid van Moolenbroek
40*00b67f09SDavid van Moolenbroek #include <dst/gssapi.h>
41*00b67f09SDavid van Moolenbroek #include <dst/dst.h>
42*00b67f09SDavid van Moolenbroek
43*00b67f09SDavid van Moolenbroek #define SSUTABLEMAGIC ISC_MAGIC('S', 'S', 'U', 'T')
44*00b67f09SDavid van Moolenbroek #define VALID_SSUTABLE(table) ISC_MAGIC_VALID(table, SSUTABLEMAGIC)
45*00b67f09SDavid van Moolenbroek
46*00b67f09SDavid van Moolenbroek #define SSURULEMAGIC ISC_MAGIC('S', 'S', 'U', 'R')
47*00b67f09SDavid van Moolenbroek #define VALID_SSURULE(table) ISC_MAGIC_VALID(table, SSURULEMAGIC)
48*00b67f09SDavid van Moolenbroek
49*00b67f09SDavid van Moolenbroek struct dns_ssurule {
50*00b67f09SDavid van Moolenbroek unsigned int magic;
51*00b67f09SDavid van Moolenbroek isc_boolean_t grant; /*%< is this a grant or a deny? */
52*00b67f09SDavid van Moolenbroek unsigned int matchtype; /*%< which type of pattern match? */
53*00b67f09SDavid van Moolenbroek dns_name_t *identity; /*%< the identity to match */
54*00b67f09SDavid van Moolenbroek dns_name_t *name; /*%< the name being updated */
55*00b67f09SDavid van Moolenbroek unsigned int ntypes; /*%< number of data types covered */
56*00b67f09SDavid van Moolenbroek dns_rdatatype_t *types; /*%< the data types. Can include ANY, */
57*00b67f09SDavid van Moolenbroek /*%< defaults to all but SIG,SOA,NS if NULL */
58*00b67f09SDavid van Moolenbroek ISC_LINK(dns_ssurule_t) link;
59*00b67f09SDavid van Moolenbroek };
60*00b67f09SDavid van Moolenbroek
61*00b67f09SDavid van Moolenbroek struct dns_ssutable {
62*00b67f09SDavid van Moolenbroek unsigned int magic;
63*00b67f09SDavid van Moolenbroek isc_mem_t *mctx;
64*00b67f09SDavid van Moolenbroek unsigned int references;
65*00b67f09SDavid van Moolenbroek isc_mutex_t lock;
66*00b67f09SDavid van Moolenbroek dns_dlzdb_t *dlzdatabase;
67*00b67f09SDavid van Moolenbroek ISC_LIST(dns_ssurule_t) rules;
68*00b67f09SDavid van Moolenbroek };
69*00b67f09SDavid van Moolenbroek
70*00b67f09SDavid van Moolenbroek isc_result_t
dns_ssutable_create(isc_mem_t * mctx,dns_ssutable_t ** tablep)71*00b67f09SDavid van Moolenbroek dns_ssutable_create(isc_mem_t *mctx, dns_ssutable_t **tablep) {
72*00b67f09SDavid van Moolenbroek isc_result_t result;
73*00b67f09SDavid van Moolenbroek dns_ssutable_t *table;
74*00b67f09SDavid van Moolenbroek
75*00b67f09SDavid van Moolenbroek REQUIRE(tablep != NULL && *tablep == NULL);
76*00b67f09SDavid van Moolenbroek REQUIRE(mctx != NULL);
77*00b67f09SDavid van Moolenbroek
78*00b67f09SDavid van Moolenbroek table = isc_mem_get(mctx, sizeof(dns_ssutable_t));
79*00b67f09SDavid van Moolenbroek if (table == NULL)
80*00b67f09SDavid van Moolenbroek return (ISC_R_NOMEMORY);
81*00b67f09SDavid van Moolenbroek result = isc_mutex_init(&table->lock);
82*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS) {
83*00b67f09SDavid van Moolenbroek isc_mem_put(mctx, table, sizeof(dns_ssutable_t));
84*00b67f09SDavid van Moolenbroek return (result);
85*00b67f09SDavid van Moolenbroek }
86*00b67f09SDavid van Moolenbroek table->references = 1;
87*00b67f09SDavid van Moolenbroek table->mctx = NULL;
88*00b67f09SDavid van Moolenbroek isc_mem_attach(mctx, &table->mctx);
89*00b67f09SDavid van Moolenbroek ISC_LIST_INIT(table->rules);
90*00b67f09SDavid van Moolenbroek table->magic = SSUTABLEMAGIC;
91*00b67f09SDavid van Moolenbroek *tablep = table;
92*00b67f09SDavid van Moolenbroek return (ISC_R_SUCCESS);
93*00b67f09SDavid van Moolenbroek }
94*00b67f09SDavid van Moolenbroek
95*00b67f09SDavid van Moolenbroek static inline void
destroy(dns_ssutable_t * table)96*00b67f09SDavid van Moolenbroek destroy(dns_ssutable_t *table) {
97*00b67f09SDavid van Moolenbroek isc_mem_t *mctx;
98*00b67f09SDavid van Moolenbroek
99*00b67f09SDavid van Moolenbroek REQUIRE(VALID_SSUTABLE(table));
100*00b67f09SDavid van Moolenbroek
101*00b67f09SDavid van Moolenbroek mctx = table->mctx;
102*00b67f09SDavid van Moolenbroek while (!ISC_LIST_EMPTY(table->rules)) {
103*00b67f09SDavid van Moolenbroek dns_ssurule_t *rule = ISC_LIST_HEAD(table->rules);
104*00b67f09SDavid van Moolenbroek if (rule->identity != NULL) {
105*00b67f09SDavid van Moolenbroek dns_name_free(rule->identity, mctx);
106*00b67f09SDavid van Moolenbroek isc_mem_put(mctx, rule->identity, sizeof(dns_name_t));
107*00b67f09SDavid van Moolenbroek }
108*00b67f09SDavid van Moolenbroek if (rule->name != NULL) {
109*00b67f09SDavid van Moolenbroek dns_name_free(rule->name, mctx);
110*00b67f09SDavid van Moolenbroek isc_mem_put(mctx, rule->name, sizeof(dns_name_t));
111*00b67f09SDavid van Moolenbroek }
112*00b67f09SDavid van Moolenbroek if (rule->types != NULL)
113*00b67f09SDavid van Moolenbroek isc_mem_put(mctx, rule->types,
114*00b67f09SDavid van Moolenbroek rule->ntypes * sizeof(dns_rdatatype_t));
115*00b67f09SDavid van Moolenbroek ISC_LIST_UNLINK(table->rules, rule, link);
116*00b67f09SDavid van Moolenbroek rule->magic = 0;
117*00b67f09SDavid van Moolenbroek isc_mem_put(mctx, rule, sizeof(dns_ssurule_t));
118*00b67f09SDavid van Moolenbroek }
119*00b67f09SDavid van Moolenbroek DESTROYLOCK(&table->lock);
120*00b67f09SDavid van Moolenbroek table->magic = 0;
121*00b67f09SDavid van Moolenbroek isc_mem_putanddetach(&table->mctx, table, sizeof(dns_ssutable_t));
122*00b67f09SDavid van Moolenbroek }
123*00b67f09SDavid van Moolenbroek
124*00b67f09SDavid van Moolenbroek void
dns_ssutable_attach(dns_ssutable_t * source,dns_ssutable_t ** targetp)125*00b67f09SDavid van Moolenbroek dns_ssutable_attach(dns_ssutable_t *source, dns_ssutable_t **targetp) {
126*00b67f09SDavid van Moolenbroek REQUIRE(VALID_SSUTABLE(source));
127*00b67f09SDavid van Moolenbroek REQUIRE(targetp != NULL && *targetp == NULL);
128*00b67f09SDavid van Moolenbroek
129*00b67f09SDavid van Moolenbroek LOCK(&source->lock);
130*00b67f09SDavid van Moolenbroek
131*00b67f09SDavid van Moolenbroek INSIST(source->references > 0);
132*00b67f09SDavid van Moolenbroek source->references++;
133*00b67f09SDavid van Moolenbroek INSIST(source->references != 0);
134*00b67f09SDavid van Moolenbroek
135*00b67f09SDavid van Moolenbroek UNLOCK(&source->lock);
136*00b67f09SDavid van Moolenbroek
137*00b67f09SDavid van Moolenbroek *targetp = source;
138*00b67f09SDavid van Moolenbroek }
139*00b67f09SDavid van Moolenbroek
140*00b67f09SDavid van Moolenbroek void
dns_ssutable_detach(dns_ssutable_t ** tablep)141*00b67f09SDavid van Moolenbroek dns_ssutable_detach(dns_ssutable_t **tablep) {
142*00b67f09SDavid van Moolenbroek dns_ssutable_t *table;
143*00b67f09SDavid van Moolenbroek isc_boolean_t done = ISC_FALSE;
144*00b67f09SDavid van Moolenbroek
145*00b67f09SDavid van Moolenbroek REQUIRE(tablep != NULL);
146*00b67f09SDavid van Moolenbroek table = *tablep;
147*00b67f09SDavid van Moolenbroek REQUIRE(VALID_SSUTABLE(table));
148*00b67f09SDavid van Moolenbroek
149*00b67f09SDavid van Moolenbroek LOCK(&table->lock);
150*00b67f09SDavid van Moolenbroek
151*00b67f09SDavid van Moolenbroek INSIST(table->references > 0);
152*00b67f09SDavid van Moolenbroek if (--table->references == 0)
153*00b67f09SDavid van Moolenbroek done = ISC_TRUE;
154*00b67f09SDavid van Moolenbroek UNLOCK(&table->lock);
155*00b67f09SDavid van Moolenbroek
156*00b67f09SDavid van Moolenbroek *tablep = NULL;
157*00b67f09SDavid van Moolenbroek
158*00b67f09SDavid van Moolenbroek if (done)
159*00b67f09SDavid van Moolenbroek destroy(table);
160*00b67f09SDavid van Moolenbroek }
161*00b67f09SDavid van Moolenbroek
162*00b67f09SDavid van Moolenbroek isc_result_t
dns_ssutable_addrule(dns_ssutable_t * table,isc_boolean_t grant,dns_name_t * identity,unsigned int matchtype,dns_name_t * name,unsigned int ntypes,dns_rdatatype_t * types)163*00b67f09SDavid van Moolenbroek dns_ssutable_addrule(dns_ssutable_t *table, isc_boolean_t grant,
164*00b67f09SDavid van Moolenbroek dns_name_t *identity, unsigned int matchtype,
165*00b67f09SDavid van Moolenbroek dns_name_t *name, unsigned int ntypes,
166*00b67f09SDavid van Moolenbroek dns_rdatatype_t *types)
167*00b67f09SDavid van Moolenbroek {
168*00b67f09SDavid van Moolenbroek dns_ssurule_t *rule;
169*00b67f09SDavid van Moolenbroek isc_mem_t *mctx;
170*00b67f09SDavid van Moolenbroek isc_result_t result;
171*00b67f09SDavid van Moolenbroek
172*00b67f09SDavid van Moolenbroek REQUIRE(VALID_SSUTABLE(table));
173*00b67f09SDavid van Moolenbroek REQUIRE(dns_name_isabsolute(identity));
174*00b67f09SDavid van Moolenbroek REQUIRE(dns_name_isabsolute(name));
175*00b67f09SDavid van Moolenbroek REQUIRE(matchtype <= DNS_SSUMATCHTYPE_MAX);
176*00b67f09SDavid van Moolenbroek if (matchtype == DNS_SSUMATCHTYPE_WILDCARD)
177*00b67f09SDavid van Moolenbroek REQUIRE(dns_name_iswildcard(name));
178*00b67f09SDavid van Moolenbroek if (ntypes > 0)
179*00b67f09SDavid van Moolenbroek REQUIRE(types != NULL);
180*00b67f09SDavid van Moolenbroek
181*00b67f09SDavid van Moolenbroek mctx = table->mctx;
182*00b67f09SDavid van Moolenbroek rule = isc_mem_get(mctx, sizeof(dns_ssurule_t));
183*00b67f09SDavid van Moolenbroek if (rule == NULL)
184*00b67f09SDavid van Moolenbroek return (ISC_R_NOMEMORY);
185*00b67f09SDavid van Moolenbroek
186*00b67f09SDavid van Moolenbroek rule->identity = NULL;
187*00b67f09SDavid van Moolenbroek rule->name = NULL;
188*00b67f09SDavid van Moolenbroek rule->types = NULL;
189*00b67f09SDavid van Moolenbroek
190*00b67f09SDavid van Moolenbroek rule->grant = grant;
191*00b67f09SDavid van Moolenbroek
192*00b67f09SDavid van Moolenbroek rule->identity = isc_mem_get(mctx, sizeof(dns_name_t));
193*00b67f09SDavid van Moolenbroek if (rule->identity == NULL) {
194*00b67f09SDavid van Moolenbroek result = ISC_R_NOMEMORY;
195*00b67f09SDavid van Moolenbroek goto failure;
196*00b67f09SDavid van Moolenbroek }
197*00b67f09SDavid van Moolenbroek dns_name_init(rule->identity, NULL);
198*00b67f09SDavid van Moolenbroek result = dns_name_dup(identity, mctx, rule->identity);
199*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
200*00b67f09SDavid van Moolenbroek goto failure;
201*00b67f09SDavid van Moolenbroek
202*00b67f09SDavid van Moolenbroek rule->name = isc_mem_get(mctx, sizeof(dns_name_t));
203*00b67f09SDavid van Moolenbroek if (rule->name == NULL) {
204*00b67f09SDavid van Moolenbroek result = ISC_R_NOMEMORY;
205*00b67f09SDavid van Moolenbroek goto failure;
206*00b67f09SDavid van Moolenbroek }
207*00b67f09SDavid van Moolenbroek dns_name_init(rule->name, NULL);
208*00b67f09SDavid van Moolenbroek result = dns_name_dup(name, mctx, rule->name);
209*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
210*00b67f09SDavid van Moolenbroek goto failure;
211*00b67f09SDavid van Moolenbroek
212*00b67f09SDavid van Moolenbroek rule->matchtype = matchtype;
213*00b67f09SDavid van Moolenbroek
214*00b67f09SDavid van Moolenbroek rule->ntypes = ntypes;
215*00b67f09SDavid van Moolenbroek if (ntypes > 0) {
216*00b67f09SDavid van Moolenbroek rule->types = isc_mem_get(mctx,
217*00b67f09SDavid van Moolenbroek ntypes * sizeof(dns_rdatatype_t));
218*00b67f09SDavid van Moolenbroek if (rule->types == NULL) {
219*00b67f09SDavid van Moolenbroek result = ISC_R_NOMEMORY;
220*00b67f09SDavid van Moolenbroek goto failure;
221*00b67f09SDavid van Moolenbroek }
222*00b67f09SDavid van Moolenbroek memmove(rule->types, types, ntypes * sizeof(dns_rdatatype_t));
223*00b67f09SDavid van Moolenbroek } else
224*00b67f09SDavid van Moolenbroek rule->types = NULL;
225*00b67f09SDavid van Moolenbroek
226*00b67f09SDavid van Moolenbroek rule->magic = SSURULEMAGIC;
227*00b67f09SDavid van Moolenbroek ISC_LIST_INITANDAPPEND(table->rules, rule, link);
228*00b67f09SDavid van Moolenbroek
229*00b67f09SDavid van Moolenbroek return (ISC_R_SUCCESS);
230*00b67f09SDavid van Moolenbroek
231*00b67f09SDavid van Moolenbroek failure:
232*00b67f09SDavid van Moolenbroek if (rule->identity != NULL) {
233*00b67f09SDavid van Moolenbroek if (dns_name_dynamic(rule->identity))
234*00b67f09SDavid van Moolenbroek dns_name_free(rule->identity, mctx);
235*00b67f09SDavid van Moolenbroek isc_mem_put(mctx, rule->identity, sizeof(dns_name_t));
236*00b67f09SDavid van Moolenbroek }
237*00b67f09SDavid van Moolenbroek if (rule->name != NULL) {
238*00b67f09SDavid van Moolenbroek if (dns_name_dynamic(rule->name))
239*00b67f09SDavid van Moolenbroek dns_name_free(rule->name, mctx);
240*00b67f09SDavid van Moolenbroek isc_mem_put(mctx, rule->name, sizeof(dns_name_t));
241*00b67f09SDavid van Moolenbroek }
242*00b67f09SDavid van Moolenbroek if (rule->types != NULL)
243*00b67f09SDavid van Moolenbroek isc_mem_put(mctx, rule->types,
244*00b67f09SDavid van Moolenbroek ntypes * sizeof(dns_rdatatype_t));
245*00b67f09SDavid van Moolenbroek isc_mem_put(mctx, rule, sizeof(dns_ssurule_t));
246*00b67f09SDavid van Moolenbroek
247*00b67f09SDavid van Moolenbroek return (result);
248*00b67f09SDavid van Moolenbroek }
249*00b67f09SDavid van Moolenbroek
250*00b67f09SDavid van Moolenbroek static inline isc_boolean_t
isusertype(dns_rdatatype_t type)251*00b67f09SDavid van Moolenbroek isusertype(dns_rdatatype_t type) {
252*00b67f09SDavid van Moolenbroek return (ISC_TF(type != dns_rdatatype_ns &&
253*00b67f09SDavid van Moolenbroek type != dns_rdatatype_soa &&
254*00b67f09SDavid van Moolenbroek type != dns_rdatatype_rrsig));
255*00b67f09SDavid van Moolenbroek }
256*00b67f09SDavid van Moolenbroek
257*00b67f09SDavid van Moolenbroek static void
reverse_from_address(dns_name_t * tcpself,isc_netaddr_t * tcpaddr)258*00b67f09SDavid van Moolenbroek reverse_from_address(dns_name_t *tcpself, isc_netaddr_t *tcpaddr) {
259*00b67f09SDavid van Moolenbroek char buf[16 * 4 + sizeof("IP6.ARPA.")];
260*00b67f09SDavid van Moolenbroek isc_result_t result;
261*00b67f09SDavid van Moolenbroek unsigned char *ap;
262*00b67f09SDavid van Moolenbroek isc_buffer_t b;
263*00b67f09SDavid van Moolenbroek unsigned long l;
264*00b67f09SDavid van Moolenbroek
265*00b67f09SDavid van Moolenbroek switch (tcpaddr->family) {
266*00b67f09SDavid van Moolenbroek case AF_INET:
267*00b67f09SDavid van Moolenbroek l = ntohl(tcpaddr->type.in.s_addr);
268*00b67f09SDavid van Moolenbroek result = isc_string_printf(buf, sizeof(buf),
269*00b67f09SDavid van Moolenbroek "%lu.%lu.%lu.%lu.IN-ADDR.ARPA.",
270*00b67f09SDavid van Moolenbroek (l >> 0) & 0xff, (l >> 8) & 0xff,
271*00b67f09SDavid van Moolenbroek (l >> 16) & 0xff, (l >> 24) & 0xff);
272*00b67f09SDavid van Moolenbroek RUNTIME_CHECK(result == ISC_R_SUCCESS);
273*00b67f09SDavid van Moolenbroek break;
274*00b67f09SDavid van Moolenbroek case AF_INET6:
275*00b67f09SDavid van Moolenbroek ap = tcpaddr->type.in6.s6_addr;
276*00b67f09SDavid van Moolenbroek result = isc_string_printf(buf, sizeof(buf),
277*00b67f09SDavid van Moolenbroek "%x.%x.%x.%x.%x.%x.%x.%x."
278*00b67f09SDavid van Moolenbroek "%x.%x.%x.%x.%x.%x.%x.%x."
279*00b67f09SDavid van Moolenbroek "%x.%x.%x.%x.%x.%x.%x.%x."
280*00b67f09SDavid van Moolenbroek "%x.%x.%x.%x.%x.%x.%x.%x."
281*00b67f09SDavid van Moolenbroek "IP6.ARPA.",
282*00b67f09SDavid van Moolenbroek ap[15] & 0x0f, (ap[15] >> 4) & 0x0f,
283*00b67f09SDavid van Moolenbroek ap[14] & 0x0f, (ap[14] >> 4) & 0x0f,
284*00b67f09SDavid van Moolenbroek ap[13] & 0x0f, (ap[13] >> 4) & 0x0f,
285*00b67f09SDavid van Moolenbroek ap[12] & 0x0f, (ap[12] >> 4) & 0x0f,
286*00b67f09SDavid van Moolenbroek ap[11] & 0x0f, (ap[11] >> 4) & 0x0f,
287*00b67f09SDavid van Moolenbroek ap[10] & 0x0f, (ap[10] >> 4) & 0x0f,
288*00b67f09SDavid van Moolenbroek ap[9] & 0x0f, (ap[9] >> 4) & 0x0f,
289*00b67f09SDavid van Moolenbroek ap[8] & 0x0f, (ap[8] >> 4) & 0x0f,
290*00b67f09SDavid van Moolenbroek ap[7] & 0x0f, (ap[7] >> 4) & 0x0f,
291*00b67f09SDavid van Moolenbroek ap[6] & 0x0f, (ap[6] >> 4) & 0x0f,
292*00b67f09SDavid van Moolenbroek ap[5] & 0x0f, (ap[5] >> 4) & 0x0f,
293*00b67f09SDavid van Moolenbroek ap[4] & 0x0f, (ap[4] >> 4) & 0x0f,
294*00b67f09SDavid van Moolenbroek ap[3] & 0x0f, (ap[3] >> 4) & 0x0f,
295*00b67f09SDavid van Moolenbroek ap[2] & 0x0f, (ap[2] >> 4) & 0x0f,
296*00b67f09SDavid van Moolenbroek ap[1] & 0x0f, (ap[1] >> 4) & 0x0f,
297*00b67f09SDavid van Moolenbroek ap[0] & 0x0f, (ap[0] >> 4) & 0x0f);
298*00b67f09SDavid van Moolenbroek RUNTIME_CHECK(result == ISC_R_SUCCESS);
299*00b67f09SDavid van Moolenbroek break;
300*00b67f09SDavid van Moolenbroek default:
301*00b67f09SDavid van Moolenbroek INSIST(0);
302*00b67f09SDavid van Moolenbroek }
303*00b67f09SDavid van Moolenbroek isc_buffer_init(&b, buf, strlen(buf));
304*00b67f09SDavid van Moolenbroek isc_buffer_add(&b, strlen(buf));
305*00b67f09SDavid van Moolenbroek result = dns_name_fromtext(tcpself, &b, dns_rootname, 0, NULL);
306*00b67f09SDavid van Moolenbroek RUNTIME_CHECK(result == ISC_R_SUCCESS);
307*00b67f09SDavid van Moolenbroek }
308*00b67f09SDavid van Moolenbroek
309*00b67f09SDavid van Moolenbroek static void
stf_from_address(dns_name_t * stfself,isc_netaddr_t * tcpaddr)310*00b67f09SDavid van Moolenbroek stf_from_address(dns_name_t *stfself, isc_netaddr_t *tcpaddr) {
311*00b67f09SDavid van Moolenbroek char buf[sizeof("X.X.X.X.Y.Y.Y.Y.2.0.0.2.IP6.ARPA.")];
312*00b67f09SDavid van Moolenbroek isc_result_t result;
313*00b67f09SDavid van Moolenbroek unsigned char *ap;
314*00b67f09SDavid van Moolenbroek isc_buffer_t b;
315*00b67f09SDavid van Moolenbroek unsigned long l;
316*00b67f09SDavid van Moolenbroek
317*00b67f09SDavid van Moolenbroek switch(tcpaddr->family) {
318*00b67f09SDavid van Moolenbroek case AF_INET:
319*00b67f09SDavid van Moolenbroek l = ntohl(tcpaddr->type.in.s_addr);
320*00b67f09SDavid van Moolenbroek result = isc_string_printf(buf, sizeof(buf),
321*00b67f09SDavid van Moolenbroek "%lx.%lx.%lx.%lx.%lx.%lx.%lx.%lx"
322*00b67f09SDavid van Moolenbroek "2.0.0.2.IP6.ARPA.",
323*00b67f09SDavid van Moolenbroek l & 0xf, (l >> 4) & 0xf,
324*00b67f09SDavid van Moolenbroek (l >> 8) & 0xf, (l >> 12) & 0xf,
325*00b67f09SDavid van Moolenbroek (l >> 16) & 0xf, (l >> 20) & 0xf,
326*00b67f09SDavid van Moolenbroek (l >> 24) & 0xf, (l >> 28) & 0xf);
327*00b67f09SDavid van Moolenbroek RUNTIME_CHECK(result == ISC_R_SUCCESS);
328*00b67f09SDavid van Moolenbroek break;
329*00b67f09SDavid van Moolenbroek case AF_INET6:
330*00b67f09SDavid van Moolenbroek ap = tcpaddr->type.in6.s6_addr;
331*00b67f09SDavid van Moolenbroek result = isc_string_printf(buf, sizeof(buf),
332*00b67f09SDavid van Moolenbroek "%x.%x.%x.%x.%x.%x.%x.%x."
333*00b67f09SDavid van Moolenbroek "%x.%x.%x.%x.IP6.ARPA.",
334*00b67f09SDavid van Moolenbroek ap[5] & 0x0f, (ap[5] >> 4) & 0x0f,
335*00b67f09SDavid van Moolenbroek ap[4] & 0x0f, (ap[4] >> 4) & 0x0f,
336*00b67f09SDavid van Moolenbroek ap[3] & 0x0f, (ap[3] >> 4) & 0x0f,
337*00b67f09SDavid van Moolenbroek ap[2] & 0x0f, (ap[2] >> 4) & 0x0f,
338*00b67f09SDavid van Moolenbroek ap[1] & 0x0f, (ap[1] >> 4) & 0x0f,
339*00b67f09SDavid van Moolenbroek ap[0] & 0x0f, (ap[0] >> 4) & 0x0f);
340*00b67f09SDavid van Moolenbroek RUNTIME_CHECK(result == ISC_R_SUCCESS);
341*00b67f09SDavid van Moolenbroek break;
342*00b67f09SDavid van Moolenbroek default:
343*00b67f09SDavid van Moolenbroek INSIST(0);
344*00b67f09SDavid van Moolenbroek }
345*00b67f09SDavid van Moolenbroek isc_buffer_init(&b, buf, strlen(buf));
346*00b67f09SDavid van Moolenbroek isc_buffer_add(&b, strlen(buf));
347*00b67f09SDavid van Moolenbroek result = dns_name_fromtext(stfself, &b, dns_rootname, 0, NULL);
348*00b67f09SDavid van Moolenbroek RUNTIME_CHECK(result == ISC_R_SUCCESS);
349*00b67f09SDavid van Moolenbroek }
350*00b67f09SDavid van Moolenbroek
351*00b67f09SDavid van Moolenbroek isc_boolean_t
dns_ssutable_checkrules(dns_ssutable_t * table,dns_name_t * signer,dns_name_t * name,isc_netaddr_t * tcpaddr,dns_rdatatype_t type,const dst_key_t * key)352*00b67f09SDavid van Moolenbroek dns_ssutable_checkrules(dns_ssutable_t *table, dns_name_t *signer,
353*00b67f09SDavid van Moolenbroek dns_name_t *name, isc_netaddr_t *tcpaddr,
354*00b67f09SDavid van Moolenbroek dns_rdatatype_t type,
355*00b67f09SDavid van Moolenbroek const dst_key_t *key)
356*00b67f09SDavid van Moolenbroek {
357*00b67f09SDavid van Moolenbroek dns_ssurule_t *rule;
358*00b67f09SDavid van Moolenbroek unsigned int i;
359*00b67f09SDavid van Moolenbroek dns_fixedname_t fixed;
360*00b67f09SDavid van Moolenbroek dns_name_t *wildcard;
361*00b67f09SDavid van Moolenbroek dns_name_t *tcpself;
362*00b67f09SDavid van Moolenbroek dns_name_t *stfself;
363*00b67f09SDavid van Moolenbroek isc_result_t result;
364*00b67f09SDavid van Moolenbroek
365*00b67f09SDavid van Moolenbroek REQUIRE(VALID_SSUTABLE(table));
366*00b67f09SDavid van Moolenbroek REQUIRE(signer == NULL || dns_name_isabsolute(signer));
367*00b67f09SDavid van Moolenbroek REQUIRE(dns_name_isabsolute(name));
368*00b67f09SDavid van Moolenbroek
369*00b67f09SDavid van Moolenbroek if (signer == NULL && tcpaddr == NULL)
370*00b67f09SDavid van Moolenbroek return (ISC_FALSE);
371*00b67f09SDavid van Moolenbroek
372*00b67f09SDavid van Moolenbroek for (rule = ISC_LIST_HEAD(table->rules);
373*00b67f09SDavid van Moolenbroek rule != NULL;
374*00b67f09SDavid van Moolenbroek rule = ISC_LIST_NEXT(rule, link))
375*00b67f09SDavid van Moolenbroek {
376*00b67f09SDavid van Moolenbroek switch (rule->matchtype) {
377*00b67f09SDavid van Moolenbroek case DNS_SSUMATCHTYPE_NAME:
378*00b67f09SDavid van Moolenbroek case DNS_SSUMATCHTYPE_SUBDOMAIN:
379*00b67f09SDavid van Moolenbroek case DNS_SSUMATCHTYPE_WILDCARD:
380*00b67f09SDavid van Moolenbroek case DNS_SSUMATCHTYPE_SELF:
381*00b67f09SDavid van Moolenbroek case DNS_SSUMATCHTYPE_SELFSUB:
382*00b67f09SDavid van Moolenbroek case DNS_SSUMATCHTYPE_SELFWILD:
383*00b67f09SDavid van Moolenbroek if (signer == NULL)
384*00b67f09SDavid van Moolenbroek continue;
385*00b67f09SDavid van Moolenbroek if (dns_name_iswildcard(rule->identity)) {
386*00b67f09SDavid van Moolenbroek if (!dns_name_matcheswildcard(signer,
387*00b67f09SDavid van Moolenbroek rule->identity))
388*00b67f09SDavid van Moolenbroek continue;
389*00b67f09SDavid van Moolenbroek } else {
390*00b67f09SDavid van Moolenbroek if (!dns_name_equal(signer, rule->identity))
391*00b67f09SDavid van Moolenbroek continue;
392*00b67f09SDavid van Moolenbroek }
393*00b67f09SDavid van Moolenbroek break;
394*00b67f09SDavid van Moolenbroek case DNS_SSUMATCHTYPE_SELFKRB5:
395*00b67f09SDavid van Moolenbroek case DNS_SSUMATCHTYPE_SELFMS:
396*00b67f09SDavid van Moolenbroek case DNS_SSUMATCHTYPE_SUBDOMAINKRB5:
397*00b67f09SDavid van Moolenbroek case DNS_SSUMATCHTYPE_SUBDOMAINMS:
398*00b67f09SDavid van Moolenbroek if (signer == NULL)
399*00b67f09SDavid van Moolenbroek continue;
400*00b67f09SDavid van Moolenbroek break;
401*00b67f09SDavid van Moolenbroek case DNS_SSUMATCHTYPE_TCPSELF:
402*00b67f09SDavid van Moolenbroek case DNS_SSUMATCHTYPE_6TO4SELF:
403*00b67f09SDavid van Moolenbroek if (tcpaddr == NULL)
404*00b67f09SDavid van Moolenbroek continue;
405*00b67f09SDavid van Moolenbroek break;
406*00b67f09SDavid van Moolenbroek }
407*00b67f09SDavid van Moolenbroek
408*00b67f09SDavid van Moolenbroek switch (rule->matchtype) {
409*00b67f09SDavid van Moolenbroek case DNS_SSUMATCHTYPE_NAME:
410*00b67f09SDavid van Moolenbroek if (!dns_name_equal(name, rule->name))
411*00b67f09SDavid van Moolenbroek continue;
412*00b67f09SDavid van Moolenbroek break;
413*00b67f09SDavid van Moolenbroek case DNS_SSUMATCHTYPE_SUBDOMAIN:
414*00b67f09SDavid van Moolenbroek if (!dns_name_issubdomain(name, rule->name))
415*00b67f09SDavid van Moolenbroek continue;
416*00b67f09SDavid van Moolenbroek break;
417*00b67f09SDavid van Moolenbroek case DNS_SSUMATCHTYPE_WILDCARD:
418*00b67f09SDavid van Moolenbroek if (!dns_name_matcheswildcard(name, rule->name))
419*00b67f09SDavid van Moolenbroek continue;
420*00b67f09SDavid van Moolenbroek break;
421*00b67f09SDavid van Moolenbroek case DNS_SSUMATCHTYPE_SELF:
422*00b67f09SDavid van Moolenbroek if (!dns_name_equal(signer, name))
423*00b67f09SDavid van Moolenbroek continue;
424*00b67f09SDavid van Moolenbroek break;
425*00b67f09SDavid van Moolenbroek case DNS_SSUMATCHTYPE_SELFSUB:
426*00b67f09SDavid van Moolenbroek if (!dns_name_issubdomain(name, signer))
427*00b67f09SDavid van Moolenbroek continue;
428*00b67f09SDavid van Moolenbroek break;
429*00b67f09SDavid van Moolenbroek case DNS_SSUMATCHTYPE_SELFWILD:
430*00b67f09SDavid van Moolenbroek dns_fixedname_init(&fixed);
431*00b67f09SDavid van Moolenbroek wildcard = dns_fixedname_name(&fixed);
432*00b67f09SDavid van Moolenbroek result = dns_name_concatenate(dns_wildcardname, signer,
433*00b67f09SDavid van Moolenbroek wildcard, NULL);
434*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
435*00b67f09SDavid van Moolenbroek continue;
436*00b67f09SDavid van Moolenbroek if (!dns_name_matcheswildcard(name, wildcard))
437*00b67f09SDavid van Moolenbroek continue;
438*00b67f09SDavid van Moolenbroek break;
439*00b67f09SDavid van Moolenbroek case DNS_SSUMATCHTYPE_SELFKRB5:
440*00b67f09SDavid van Moolenbroek if (!dst_gssapi_identitymatchesrealmkrb5(signer, name,
441*00b67f09SDavid van Moolenbroek rule->identity))
442*00b67f09SDavid van Moolenbroek continue;
443*00b67f09SDavid van Moolenbroek break;
444*00b67f09SDavid van Moolenbroek case DNS_SSUMATCHTYPE_SELFMS:
445*00b67f09SDavid van Moolenbroek if (!dst_gssapi_identitymatchesrealmms(signer, name,
446*00b67f09SDavid van Moolenbroek rule->identity))
447*00b67f09SDavid van Moolenbroek continue;
448*00b67f09SDavid van Moolenbroek break;
449*00b67f09SDavid van Moolenbroek case DNS_SSUMATCHTYPE_SUBDOMAINKRB5:
450*00b67f09SDavid van Moolenbroek if (!dns_name_issubdomain(name, rule->name))
451*00b67f09SDavid van Moolenbroek continue;
452*00b67f09SDavid van Moolenbroek if (!dst_gssapi_identitymatchesrealmkrb5(signer, NULL,
453*00b67f09SDavid van Moolenbroek rule->identity))
454*00b67f09SDavid van Moolenbroek continue;
455*00b67f09SDavid van Moolenbroek break;
456*00b67f09SDavid van Moolenbroek case DNS_SSUMATCHTYPE_SUBDOMAINMS:
457*00b67f09SDavid van Moolenbroek if (!dns_name_issubdomain(name, rule->name))
458*00b67f09SDavid van Moolenbroek continue;
459*00b67f09SDavid van Moolenbroek if (!dst_gssapi_identitymatchesrealmms(signer, NULL,
460*00b67f09SDavid van Moolenbroek rule->identity))
461*00b67f09SDavid van Moolenbroek continue;
462*00b67f09SDavid van Moolenbroek break;
463*00b67f09SDavid van Moolenbroek case DNS_SSUMATCHTYPE_TCPSELF:
464*00b67f09SDavid van Moolenbroek dns_fixedname_init(&fixed);
465*00b67f09SDavid van Moolenbroek tcpself = dns_fixedname_name(&fixed);
466*00b67f09SDavid van Moolenbroek reverse_from_address(tcpself, tcpaddr);
467*00b67f09SDavid van Moolenbroek if (dns_name_iswildcard(rule->identity)) {
468*00b67f09SDavid van Moolenbroek if (!dns_name_matcheswildcard(tcpself,
469*00b67f09SDavid van Moolenbroek rule->identity))
470*00b67f09SDavid van Moolenbroek continue;
471*00b67f09SDavid van Moolenbroek } else {
472*00b67f09SDavid van Moolenbroek if (!dns_name_equal(tcpself, rule->identity))
473*00b67f09SDavid van Moolenbroek continue;
474*00b67f09SDavid van Moolenbroek }
475*00b67f09SDavid van Moolenbroek if (!dns_name_equal(tcpself, name))
476*00b67f09SDavid van Moolenbroek continue;
477*00b67f09SDavid van Moolenbroek break;
478*00b67f09SDavid van Moolenbroek case DNS_SSUMATCHTYPE_6TO4SELF:
479*00b67f09SDavid van Moolenbroek dns_fixedname_init(&fixed);
480*00b67f09SDavid van Moolenbroek stfself = dns_fixedname_name(&fixed);
481*00b67f09SDavid van Moolenbroek stf_from_address(stfself, tcpaddr);
482*00b67f09SDavid van Moolenbroek if (dns_name_iswildcard(rule->identity)) {
483*00b67f09SDavid van Moolenbroek if (!dns_name_matcheswildcard(stfself,
484*00b67f09SDavid van Moolenbroek rule->identity))
485*00b67f09SDavid van Moolenbroek continue;
486*00b67f09SDavid van Moolenbroek } else {
487*00b67f09SDavid van Moolenbroek if (!dns_name_equal(stfself, rule->identity))
488*00b67f09SDavid van Moolenbroek continue;
489*00b67f09SDavid van Moolenbroek }
490*00b67f09SDavid van Moolenbroek if (!dns_name_equal(stfself, name))
491*00b67f09SDavid van Moolenbroek continue;
492*00b67f09SDavid van Moolenbroek break;
493*00b67f09SDavid van Moolenbroek case DNS_SSUMATCHTYPE_EXTERNAL:
494*00b67f09SDavid van Moolenbroek if (!dns_ssu_external_match(rule->identity, signer,
495*00b67f09SDavid van Moolenbroek name, tcpaddr, type, key,
496*00b67f09SDavid van Moolenbroek table->mctx))
497*00b67f09SDavid van Moolenbroek continue;
498*00b67f09SDavid van Moolenbroek break;
499*00b67f09SDavid van Moolenbroek case DNS_SSUMATCHTYPE_DLZ:
500*00b67f09SDavid van Moolenbroek if (!dns_dlz_ssumatch(table->dlzdatabase, signer,
501*00b67f09SDavid van Moolenbroek name, tcpaddr, type, key))
502*00b67f09SDavid van Moolenbroek continue;
503*00b67f09SDavid van Moolenbroek break;
504*00b67f09SDavid van Moolenbroek }
505*00b67f09SDavid van Moolenbroek
506*00b67f09SDavid van Moolenbroek if (rule->ntypes == 0) {
507*00b67f09SDavid van Moolenbroek /*
508*00b67f09SDavid van Moolenbroek * If this is a DLZ rule, then the DLZ ssu
509*00b67f09SDavid van Moolenbroek * checks will have already checked
510*00b67f09SDavid van Moolenbroek * the type.
511*00b67f09SDavid van Moolenbroek */
512*00b67f09SDavid van Moolenbroek if (rule->matchtype != DNS_SSUMATCHTYPE_DLZ &&
513*00b67f09SDavid van Moolenbroek !isusertype(type))
514*00b67f09SDavid van Moolenbroek continue;
515*00b67f09SDavid van Moolenbroek } else {
516*00b67f09SDavid van Moolenbroek for (i = 0; i < rule->ntypes; i++) {
517*00b67f09SDavid van Moolenbroek if (rule->types[i] == dns_rdatatype_any ||
518*00b67f09SDavid van Moolenbroek rule->types[i] == type)
519*00b67f09SDavid van Moolenbroek break;
520*00b67f09SDavid van Moolenbroek }
521*00b67f09SDavid van Moolenbroek if (i == rule->ntypes)
522*00b67f09SDavid van Moolenbroek continue;
523*00b67f09SDavid van Moolenbroek }
524*00b67f09SDavid van Moolenbroek return (rule->grant);
525*00b67f09SDavid van Moolenbroek }
526*00b67f09SDavid van Moolenbroek
527*00b67f09SDavid van Moolenbroek return (ISC_FALSE);
528*00b67f09SDavid van Moolenbroek }
529*00b67f09SDavid van Moolenbroek
530*00b67f09SDavid van Moolenbroek isc_boolean_t
dns_ssurule_isgrant(const dns_ssurule_t * rule)531*00b67f09SDavid van Moolenbroek dns_ssurule_isgrant(const dns_ssurule_t *rule) {
532*00b67f09SDavid van Moolenbroek REQUIRE(VALID_SSURULE(rule));
533*00b67f09SDavid van Moolenbroek return (rule->grant);
534*00b67f09SDavid van Moolenbroek }
535*00b67f09SDavid van Moolenbroek
536*00b67f09SDavid van Moolenbroek dns_name_t *
dns_ssurule_identity(const dns_ssurule_t * rule)537*00b67f09SDavid van Moolenbroek dns_ssurule_identity(const dns_ssurule_t *rule) {
538*00b67f09SDavid van Moolenbroek REQUIRE(VALID_SSURULE(rule));
539*00b67f09SDavid van Moolenbroek return (rule->identity);
540*00b67f09SDavid van Moolenbroek }
541*00b67f09SDavid van Moolenbroek
542*00b67f09SDavid van Moolenbroek unsigned int
dns_ssurule_matchtype(const dns_ssurule_t * rule)543*00b67f09SDavid van Moolenbroek dns_ssurule_matchtype(const dns_ssurule_t *rule) {
544*00b67f09SDavid van Moolenbroek REQUIRE(VALID_SSURULE(rule));
545*00b67f09SDavid van Moolenbroek return (rule->matchtype);
546*00b67f09SDavid van Moolenbroek }
547*00b67f09SDavid van Moolenbroek
548*00b67f09SDavid van Moolenbroek dns_name_t *
dns_ssurule_name(const dns_ssurule_t * rule)549*00b67f09SDavid van Moolenbroek dns_ssurule_name(const dns_ssurule_t *rule) {
550*00b67f09SDavid van Moolenbroek REQUIRE(VALID_SSURULE(rule));
551*00b67f09SDavid van Moolenbroek return (rule->name);
552*00b67f09SDavid van Moolenbroek }
553*00b67f09SDavid van Moolenbroek
554*00b67f09SDavid van Moolenbroek unsigned int
dns_ssurule_types(const dns_ssurule_t * rule,dns_rdatatype_t ** types)555*00b67f09SDavid van Moolenbroek dns_ssurule_types(const dns_ssurule_t *rule, dns_rdatatype_t **types) {
556*00b67f09SDavid van Moolenbroek REQUIRE(VALID_SSURULE(rule));
557*00b67f09SDavid van Moolenbroek REQUIRE(types != NULL && *types != NULL);
558*00b67f09SDavid van Moolenbroek *types = rule->types;
559*00b67f09SDavid van Moolenbroek return (rule->ntypes);
560*00b67f09SDavid van Moolenbroek }
561*00b67f09SDavid van Moolenbroek
562*00b67f09SDavid van Moolenbroek isc_result_t
dns_ssutable_firstrule(const dns_ssutable_t * table,dns_ssurule_t ** rule)563*00b67f09SDavid van Moolenbroek dns_ssutable_firstrule(const dns_ssutable_t *table, dns_ssurule_t **rule) {
564*00b67f09SDavid van Moolenbroek REQUIRE(VALID_SSUTABLE(table));
565*00b67f09SDavid van Moolenbroek REQUIRE(rule != NULL && *rule == NULL);
566*00b67f09SDavid van Moolenbroek *rule = ISC_LIST_HEAD(table->rules);
567*00b67f09SDavid van Moolenbroek return (*rule != NULL ? ISC_R_SUCCESS : ISC_R_NOMORE);
568*00b67f09SDavid van Moolenbroek }
569*00b67f09SDavid van Moolenbroek
570*00b67f09SDavid van Moolenbroek isc_result_t
dns_ssutable_nextrule(dns_ssurule_t * rule,dns_ssurule_t ** nextrule)571*00b67f09SDavid van Moolenbroek dns_ssutable_nextrule(dns_ssurule_t *rule, dns_ssurule_t **nextrule) {
572*00b67f09SDavid van Moolenbroek REQUIRE(VALID_SSURULE(rule));
573*00b67f09SDavid van Moolenbroek REQUIRE(nextrule != NULL && *nextrule == NULL);
574*00b67f09SDavid van Moolenbroek *nextrule = ISC_LIST_NEXT(rule, link);
575*00b67f09SDavid van Moolenbroek return (*nextrule != NULL ? ISC_R_SUCCESS : ISC_R_NOMORE);
576*00b67f09SDavid van Moolenbroek }
577*00b67f09SDavid van Moolenbroek
578*00b67f09SDavid van Moolenbroek /*
579*00b67f09SDavid van Moolenbroek * Create a specialised SSU table that points at an external DLZ database
580*00b67f09SDavid van Moolenbroek */
581*00b67f09SDavid van Moolenbroek isc_result_t
dns_ssutable_createdlz(isc_mem_t * mctx,dns_ssutable_t ** tablep,dns_dlzdb_t * dlzdatabase)582*00b67f09SDavid van Moolenbroek dns_ssutable_createdlz(isc_mem_t *mctx, dns_ssutable_t **tablep,
583*00b67f09SDavid van Moolenbroek dns_dlzdb_t *dlzdatabase)
584*00b67f09SDavid van Moolenbroek {
585*00b67f09SDavid van Moolenbroek isc_result_t result;
586*00b67f09SDavid van Moolenbroek dns_ssurule_t *rule;
587*00b67f09SDavid van Moolenbroek dns_ssutable_t *table = NULL;
588*00b67f09SDavid van Moolenbroek
589*00b67f09SDavid van Moolenbroek REQUIRE(tablep != NULL && *tablep == NULL);
590*00b67f09SDavid van Moolenbroek
591*00b67f09SDavid van Moolenbroek result = dns_ssutable_create(mctx, &table);
592*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
593*00b67f09SDavid van Moolenbroek return (result);
594*00b67f09SDavid van Moolenbroek
595*00b67f09SDavid van Moolenbroek table->dlzdatabase = dlzdatabase;
596*00b67f09SDavid van Moolenbroek
597*00b67f09SDavid van Moolenbroek rule = isc_mem_get(table->mctx, sizeof(dns_ssurule_t));
598*00b67f09SDavid van Moolenbroek if (rule == NULL) {
599*00b67f09SDavid van Moolenbroek dns_ssutable_detach(&table);
600*00b67f09SDavid van Moolenbroek return (ISC_R_NOMEMORY);
601*00b67f09SDavid van Moolenbroek }
602*00b67f09SDavid van Moolenbroek
603*00b67f09SDavid van Moolenbroek rule->identity = NULL;
604*00b67f09SDavid van Moolenbroek rule->name = NULL;
605*00b67f09SDavid van Moolenbroek rule->types = NULL;
606*00b67f09SDavid van Moolenbroek rule->grant = ISC_TRUE;
607*00b67f09SDavid van Moolenbroek rule->matchtype = DNS_SSUMATCHTYPE_DLZ;
608*00b67f09SDavid van Moolenbroek rule->ntypes = 0;
609*00b67f09SDavid van Moolenbroek rule->types = NULL;
610*00b67f09SDavid van Moolenbroek rule->magic = SSURULEMAGIC;
611*00b67f09SDavid van Moolenbroek
612*00b67f09SDavid van Moolenbroek ISC_LIST_INITANDAPPEND(table->rules, rule, link);
613*00b67f09SDavid van Moolenbroek *tablep = table;
614*00b67f09SDavid van Moolenbroek return (ISC_R_SUCCESS);
615*00b67f09SDavid van Moolenbroek }
616