Annotation of src/external/mpl/bind/dist/lib/dns/ssu.c, Revision 1.6
1.2 christos 1: /* $NetBSD: ssu.c,v 1.1.1.8 2018/04/07 21:44:08 christos Exp $ */
1.1 christos 2:
3: /*
4: * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
5: *
1.6 ! christos 6: * SPDX-License-Identifier: MPL-2.0
! 7: *
1.1 christos 8: * This Source Code Form is subject to the terms of the Mozilla Public
9: * License, v. 2.0. If a copy of the MPL was not distributed with this
1.5 christos 10: * file, you can obtain one at https://mozilla.org/MPL/2.0/.
1.1 christos 11: *
12: * See the COPYRIGHT file distributed with this work for additional
13: * information regarding copyright ownership.
14: */
15:
16: /*! \file */
17:
1.3 christos 18: #include <stdbool.h>
19:
1.1 christos 20: #include <isc/magic.h>
21: #include <isc/mem.h>
22: #include <isc/netaddr.h>
1.3 christos 23: #include <isc/print.h>
1.4 christos 24: #include <isc/refcount.h>
1.1 christos 25: #include <isc/result.h>
26: #include <isc/string.h>
27: #include <isc/util.h>
28:
29: #include <dns/dlz.h>
30: #include <dns/fixedname.h>
31: #include <dns/name.h>
32: #include <dns/ssu.h>
33:
1.4 christos 34: #include <dst/dst.h>
1.1 christos 35: #include <dst/gssapi.h>
36:
1.4 christos 37: #define SSUTABLEMAGIC ISC_MAGIC('S', 'S', 'U', 'T')
38: #define VALID_SSUTABLE(table) ISC_MAGIC_VALID(table, SSUTABLEMAGIC)
1.1 christos 39:
1.4 christos 40: #define SSURULEMAGIC ISC_MAGIC('S', 'S', 'U', 'R')
41: #define VALID_SSURULE(table) ISC_MAGIC_VALID(table, SSURULEMAGIC)
1.1 christos 42:
43: struct dns_ssurule {
44: unsigned int magic;
1.4 christos 45: bool grant; /*%< is this a grant or a deny? */
46: dns_ssumatchtype_t matchtype; /*%< which type of pattern match?
47: * */
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 */
52: /* ANY. if NULL, defaults to all */
53: /* types except SIG, SOA, and NS */
1.1 christos 54: ISC_LINK(dns_ssurule_t) link;
55: };
56:
57: struct dns_ssutable {
58: unsigned int magic;
59: isc_mem_t *mctx;
1.4 christos 60: isc_refcount_t references;
1.1 christos 61: dns_dlzdb_t *dlzdatabase;
62: ISC_LIST(dns_ssurule_t) rules;
63: };
64:
65: isc_result_t
66: dns_ssutable_create(isc_mem_t *mctx, dns_ssutable_t **tablep) {
67: dns_ssutable_t *table;
68:
69: REQUIRE(tablep != NULL && *tablep == NULL);
70: REQUIRE(mctx != NULL);
71:
72: table = isc_mem_get(mctx, sizeof(dns_ssutable_t));
1.4 christos 73: isc_refcount_init(&table->references, 1);
1.1 christos 74: table->mctx = NULL;
75: isc_mem_attach(mctx, &table->mctx);
76: ISC_LIST_INIT(table->rules);
77: table->magic = SSUTABLEMAGIC;
78: *tablep = table;
79: return (ISC_R_SUCCESS);
80: }
81:
1.6 ! christos 82: static void
1.1 christos 83: destroy(dns_ssutable_t *table) {
84: isc_mem_t *mctx;
85:
86: REQUIRE(VALID_SSUTABLE(table));
87:
88: mctx = table->mctx;
89: while (!ISC_LIST_EMPTY(table->rules)) {
90: dns_ssurule_t *rule = ISC_LIST_HEAD(table->rules);
91: if (rule->identity != NULL) {
92: dns_name_free(rule->identity, mctx);
93: isc_mem_put(mctx, rule->identity, sizeof(dns_name_t));
94: }
95: if (rule->name != NULL) {
96: dns_name_free(rule->name, mctx);
97: isc_mem_put(mctx, rule->name, sizeof(dns_name_t));
98: }
1.4 christos 99: if (rule->types != NULL) {
1.1 christos 100: isc_mem_put(mctx, rule->types,
101: rule->ntypes * sizeof(dns_rdatatype_t));
1.4 christos 102: }
1.1 christos 103: ISC_LIST_UNLINK(table->rules, rule, link);
104: rule->magic = 0;
105: isc_mem_put(mctx, rule, sizeof(dns_ssurule_t));
106: }
1.4 christos 107: isc_refcount_destroy(&table->references);
1.1 christos 108: table->magic = 0;
109: isc_mem_putanddetach(&table->mctx, table, sizeof(dns_ssutable_t));
110: }
111:
112: void
113: dns_ssutable_attach(dns_ssutable_t *source, dns_ssutable_t **targetp) {
114: REQUIRE(VALID_SSUTABLE(source));
115: REQUIRE(targetp != NULL && *targetp == NULL);
116:
1.4 christos 117: isc_refcount_increment(&source->references);
1.1 christos 118:
119: *targetp = source;
120: }
121:
122: void
123: dns_ssutable_detach(dns_ssutable_t **tablep) {
124: dns_ssutable_t *table;
125:
126: REQUIRE(tablep != NULL);
127: table = *tablep;
1.4 christos 128: *tablep = NULL;
1.1 christos 129: REQUIRE(VALID_SSUTABLE(table));
130:
1.4 christos 131: if (isc_refcount_decrement(&table->references) == 1) {
1.1 christos 132: destroy(table);
1.4 christos 133: }
1.1 christos 134: }
135:
136: isc_result_t
1.3 christos 137: dns_ssutable_addrule(dns_ssutable_t *table, bool grant,
1.1 christos 138: const dns_name_t *identity, dns_ssumatchtype_t matchtype,
139: const dns_name_t *name, unsigned int ntypes,
1.4 christos 140: dns_rdatatype_t *types) {
1.1 christos 141: dns_ssurule_t *rule;
142: isc_mem_t *mctx;
143:
144: REQUIRE(VALID_SSUTABLE(table));
145: REQUIRE(dns_name_isabsolute(identity));
146: REQUIRE(dns_name_isabsolute(name));
147: REQUIRE(matchtype <= dns_ssumatchtype_max);
1.4 christos 148: if (matchtype == dns_ssumatchtype_wildcard) {
1.1 christos 149: REQUIRE(dns_name_iswildcard(name));
1.4 christos 150: }
151: if (ntypes > 0) {
1.1 christos 152: REQUIRE(types != NULL);
1.4 christos 153: }
1.1 christos 154:
155: mctx = table->mctx;
156: rule = isc_mem_get(mctx, sizeof(dns_ssurule_t));
157:
158: rule->identity = NULL;
159: rule->name = NULL;
160: rule->types = NULL;
161:
162: rule->grant = grant;
163:
164: rule->identity = isc_mem_get(mctx, sizeof(dns_name_t));
165: dns_name_init(rule->identity, NULL);
1.4 christos 166: dns_name_dup(identity, mctx, rule->identity);
1.1 christos 167:
168: rule->name = isc_mem_get(mctx, sizeof(dns_name_t));
169: dns_name_init(rule->name, NULL);
1.4 christos 170: dns_name_dup(name, mctx, rule->name);
1.1 christos 171:
172: rule->matchtype = matchtype;
173:
174: rule->ntypes = ntypes;
175: if (ntypes > 0) {
176: rule->types = isc_mem_get(mctx,
177: ntypes * sizeof(dns_rdatatype_t));
178: memmove(rule->types, types, ntypes * sizeof(dns_rdatatype_t));
1.4 christos 179: } else {
1.1 christos 180: rule->types = NULL;
1.4 christos 181: }
1.1 christos 182:
183: rule->magic = SSURULEMAGIC;
184: ISC_LIST_INITANDAPPEND(table->rules, rule, link);
185:
186: return (ISC_R_SUCCESS);
187: }
188:
1.6 ! christos 189: static bool
1.1 christos 190: isusertype(dns_rdatatype_t type) {
1.4 christos 191: return (type != dns_rdatatype_ns && type != dns_rdatatype_soa &&
1.3 christos 192: type != dns_rdatatype_rrsig);
1.1 christos 193: }
194:
195: static void
196: reverse_from_address(dns_name_t *tcpself, const isc_netaddr_t *tcpaddr) {
197: char buf[16 * 4 + sizeof("IP6.ARPA.")];
198: isc_result_t result;
199: const unsigned char *ap;
200: isc_buffer_t b;
201: unsigned long l;
202:
203: switch (tcpaddr->family) {
204: case AF_INET:
205: l = ntohl(tcpaddr->type.in.s_addr);
1.3 christos 206: result = snprintf(buf, sizeof(buf),
207: "%lu.%lu.%lu.%lu.IN-ADDR.ARPA.",
208: (l >> 0) & 0xff, (l >> 8) & 0xff,
209: (l >> 16) & 0xff, (l >> 24) & 0xff);
210: RUNTIME_CHECK(result < sizeof(buf));
1.1 christos 211: break;
212: case AF_INET6:
213: ap = tcpaddr->type.in6.s6_addr;
1.4 christos 214: result = snprintf(
215: buf, sizeof(buf),
216: "%x.%x.%x.%x.%x.%x.%x.%x."
217: "%x.%x.%x.%x.%x.%x.%x.%x."
218: "%x.%x.%x.%x.%x.%x.%x.%x."
219: "%x.%x.%x.%x.%x.%x.%x.%x."
220: "IP6.ARPA.",
221: ap[15] & 0x0f, (ap[15] >> 4) & 0x0f, ap[14] & 0x0f,
222: (ap[14] >> 4) & 0x0f, ap[13] & 0x0f,
223: (ap[13] >> 4) & 0x0f, ap[12] & 0x0f,
224: (ap[12] >> 4) & 0x0f, ap[11] & 0x0f,
225: (ap[11] >> 4) & 0x0f, ap[10] & 0x0f,
226: (ap[10] >> 4) & 0x0f, ap[9] & 0x0f, (ap[9] >> 4) & 0x0f,
227: ap[8] & 0x0f, (ap[8] >> 4) & 0x0f, ap[7] & 0x0f,
228: (ap[7] >> 4) & 0x0f, ap[6] & 0x0f, (ap[6] >> 4) & 0x0f,
229: ap[5] & 0x0f, (ap[5] >> 4) & 0x0f, ap[4] & 0x0f,
230: (ap[4] >> 4) & 0x0f, ap[3] & 0x0f, (ap[3] >> 4) & 0x0f,
231: ap[2] & 0x0f, (ap[2] >> 4) & 0x0f, ap[1] & 0x0f,
232: (ap[1] >> 4) & 0x0f, ap[0] & 0x0f, (ap[0] >> 4) & 0x0f);
1.3 christos 233: RUNTIME_CHECK(result < sizeof(buf));
1.1 christos 234: break;
235: default:
1.6 ! christos 236: UNREACHABLE();
1.1 christos 237: }
238: isc_buffer_init(&b, buf, strlen(buf));
239: isc_buffer_add(&b, strlen(buf));
240: result = dns_name_fromtext(tcpself, &b, dns_rootname, 0, NULL);
241: RUNTIME_CHECK(result == ISC_R_SUCCESS);
242: }
243:
244: static void
245: stf_from_address(dns_name_t *stfself, const isc_netaddr_t *tcpaddr) {
246: char buf[sizeof("X.X.X.X.Y.Y.Y.Y.2.0.0.2.IP6.ARPA.")];
247: isc_result_t result;
248: const unsigned char *ap;
249: isc_buffer_t b;
250: unsigned long l;
251:
1.4 christos 252: switch (tcpaddr->family) {
1.1 christos 253: case AF_INET:
254: l = ntohl(tcpaddr->type.in.s_addr);
1.3 christos 255: result = snprintf(buf, sizeof(buf),
256: "%lx.%lx.%lx.%lx.%lx.%lx.%lx.%lx"
257: "2.0.0.2.IP6.ARPA.",
1.4 christos 258: l & 0xf, (l >> 4) & 0xf, (l >> 8) & 0xf,
259: (l >> 12) & 0xf, (l >> 16) & 0xf,
260: (l >> 20) & 0xf, (l >> 24) & 0xf,
261: (l >> 28) & 0xf);
1.3 christos 262: RUNTIME_CHECK(result < sizeof(buf));
1.1 christos 263: break;
264: case AF_INET6:
265: ap = tcpaddr->type.in6.s6_addr;
1.4 christos 266: result = snprintf(
267: buf, sizeof(buf),
268: "%x.%x.%x.%x.%x.%x.%x.%x."
269: "%x.%x.%x.%x.IP6.ARPA.",
270: ap[5] & 0x0f, (ap[5] >> 4) & 0x0f, ap[4] & 0x0f,
271: (ap[4] >> 4) & 0x0f, ap[3] & 0x0f, (ap[3] >> 4) & 0x0f,
272: ap[2] & 0x0f, (ap[2] >> 4) & 0x0f, ap[1] & 0x0f,
273: (ap[1] >> 4) & 0x0f, ap[0] & 0x0f, (ap[0] >> 4) & 0x0f);
1.3 christos 274: RUNTIME_CHECK(result < sizeof(buf));
1.1 christos 275: break;
276: default:
1.6 ! christos 277: UNREACHABLE();
1.1 christos 278: }
279: isc_buffer_init(&b, buf, strlen(buf));
280: isc_buffer_add(&b, strlen(buf));
281: result = dns_name_fromtext(stfself, &b, dns_rootname, 0, NULL);
282: RUNTIME_CHECK(result == ISC_R_SUCCESS);
283: }
284:
1.3 christos 285: bool
1.1 christos 286: dns_ssutable_checkrules(dns_ssutable_t *table, const dns_name_t *signer,
1.3 christos 287: const dns_name_t *name, const isc_netaddr_t *addr,
1.4 christos 288: bool tcp, const dns_aclenv_t *env, dns_rdatatype_t type,
289: const dst_key_t *key) {
1.1 christos 290: dns_ssurule_t *rule;
291: unsigned int i;
292: dns_fixedname_t fixed;
293: dns_name_t *wildcard;
294: dns_name_t *tcpself;
295: dns_name_t *stfself;
296: isc_result_t result;
297: int match;
298:
299: REQUIRE(VALID_SSUTABLE(table));
300: REQUIRE(signer == NULL || dns_name_isabsolute(signer));
301: REQUIRE(dns_name_isabsolute(name));
302: REQUIRE(addr == NULL || env != NULL);
303:
1.4 christos 304: if (signer == NULL && addr == NULL) {
1.3 christos 305: return (false);
1.4 christos 306: }
1.1 christos 307:
1.4 christos 308: for (rule = ISC_LIST_HEAD(table->rules); rule != NULL;
1.1 christos 309: rule = ISC_LIST_NEXT(rule, link))
310: {
311: switch (rule->matchtype) {
312: case dns_ssumatchtype_name:
313: case dns_ssumatchtype_local:
314: case dns_ssumatchtype_subdomain:
315: case dns_ssumatchtype_wildcard:
316: case dns_ssumatchtype_self:
317: case dns_ssumatchtype_selfsub:
318: case dns_ssumatchtype_selfwild:
1.4 christos 319: if (signer == NULL) {
1.1 christos 320: continue;
1.4 christos 321: }
1.1 christos 322: if (dns_name_iswildcard(rule->identity)) {
323: if (!dns_name_matcheswildcard(signer,
1.4 christos 324: rule->identity)) {
1.1 christos 325: continue;
1.4 christos 326: }
1.1 christos 327: } else {
1.4 christos 328: if (!dns_name_equal(signer, rule->identity)) {
1.1 christos 329: continue;
1.4 christos 330: }
1.1 christos 331: }
332: break;
333: case dns_ssumatchtype_selfkrb5:
334: case dns_ssumatchtype_selfms:
1.3 christos 335: case dns_ssumatchtype_selfsubkrb5:
336: case dns_ssumatchtype_selfsubms:
1.1 christos 337: case dns_ssumatchtype_subdomainkrb5:
338: case dns_ssumatchtype_subdomainms:
1.4 christos 339: if (signer == NULL) {
1.1 christos 340: continue;
1.4 christos 341: }
1.1 christos 342: break;
343: case dns_ssumatchtype_tcpself:
344: case dns_ssumatchtype_6to4self:
1.4 christos 345: if (!tcp || addr == NULL) {
1.1 christos 346: continue;
1.4 christos 347: }
1.1 christos 348: break;
349: case dns_ssumatchtype_external:
350: case dns_ssumatchtype_dlz:
351: break;
352: }
353:
354: switch (rule->matchtype) {
355: case dns_ssumatchtype_name:
1.4 christos 356: if (!dns_name_equal(name, rule->name)) {
1.1 christos 357: continue;
1.4 christos 358: }
1.1 christos 359: break;
360: case dns_ssumatchtype_subdomain:
1.4 christos 361: if (!dns_name_issubdomain(name, rule->name)) {
1.1 christos 362: continue;
1.4 christos 363: }
1.1 christos 364: break;
365: case dns_ssumatchtype_local:
366: if (addr == NULL) {
367: continue;
368: }
369: if (!dns_name_issubdomain(name, rule->name)) {
370: continue;
371: }
1.4 christos 372: dns_acl_match(addr, NULL, env->localhost, NULL, &match,
373: NULL);
1.1 christos 374: if (match == 0) {
375: if (signer != NULL) {
376: isc_log_write(dns_lctx,
377: DNS_LOGCATEGORY_GENERAL,
378: DNS_LOGMODULE_SSU,
379: ISC_LOG_WARNING,
380: "update-policy local: "
381: "match on session "
382: "key not from "
383: "localhost");
384: }
385: continue;
386: }
387: break;
388: case dns_ssumatchtype_wildcard:
1.4 christos 389: if (!dns_name_matcheswildcard(name, rule->name)) {
1.1 christos 390: continue;
1.4 christos 391: }
1.1 christos 392: break;
393: case dns_ssumatchtype_self:
1.4 christos 394: if (!dns_name_equal(signer, name)) {
1.1 christos 395: continue;
1.4 christos 396: }
1.1 christos 397: break;
398: case dns_ssumatchtype_selfsub:
1.4 christos 399: if (!dns_name_issubdomain(name, signer)) {
1.1 christos 400: continue;
1.4 christos 401: }
1.1 christos 402: break;
403: case dns_ssumatchtype_selfwild:
404: wildcard = dns_fixedname_initname(&fixed);
405: result = dns_name_concatenate(dns_wildcardname, signer,
406: wildcard, NULL);
1.4 christos 407: if (result != ISC_R_SUCCESS) {
1.1 christos 408: continue;
1.4 christos 409: }
410: if (!dns_name_matcheswildcard(name, wildcard)) {
1.1 christos 411: continue;
1.4 christos 412: }
1.1 christos 413: break;
414: case dns_ssumatchtype_selfkrb5:
1.4 christos 415: if (dst_gssapi_identitymatchesrealmkrb5(
416: signer, name, rule->identity, false)) {
1.3 christos 417: break;
418: }
419: continue;
1.1 christos 420: case dns_ssumatchtype_selfms:
1.4 christos 421: if (dst_gssapi_identitymatchesrealmms(
422: signer, name, rule->identity, false)) {
1.3 christos 423: break;
424: }
425: continue;
426: case dns_ssumatchtype_selfsubkrb5:
1.4 christos 427: if (dst_gssapi_identitymatchesrealmkrb5(
428: signer, name, rule->identity, true)) {
1.3 christos 429: break;
430: }
431: continue;
432: case dns_ssumatchtype_selfsubms:
1.4 christos 433: if (dst_gssapi_identitymatchesrealmms(
434: signer, name, rule->identity, true)) {
1.3 christos 435: break;
1.4 christos 436: }
1.3 christos 437: continue;
1.1 christos 438: case dns_ssumatchtype_subdomainkrb5:
1.4 christos 439: if (!dns_name_issubdomain(name, rule->name)) {
1.1 christos 440: continue;
1.4 christos 441: }
442: if (dst_gssapi_identitymatchesrealmkrb5(
443: signer, NULL, rule->identity, false)) {
1.3 christos 444: break;
445: }
446: continue;
1.1 christos 447: case dns_ssumatchtype_subdomainms:
1.4 christos 448: if (!dns_name_issubdomain(name, rule->name)) {
1.1 christos 449: continue;
1.4 christos 450: }
451: if (dst_gssapi_identitymatchesrealmms(
452: signer, NULL, rule->identity, false)) {
1.3 christos 453: break;
454: }
455: continue;
1.1 christos 456: case dns_ssumatchtype_tcpself:
457: tcpself = dns_fixedname_initname(&fixed);
458: reverse_from_address(tcpself, addr);
459: if (dns_name_iswildcard(rule->identity)) {
460: if (!dns_name_matcheswildcard(tcpself,
1.4 christos 461: rule->identity)) {
1.1 christos 462: continue;
1.4 christos 463: }
1.1 christos 464: } else {
1.4 christos 465: if (!dns_name_equal(tcpself, rule->identity)) {
1.1 christos 466: continue;
1.4 christos 467: }
1.1 christos 468: }
1.4 christos 469: if (!dns_name_equal(tcpself, name)) {
1.1 christos 470: continue;
1.4 christos 471: }
1.1 christos 472: break;
473: case dns_ssumatchtype_6to4self:
474: stfself = dns_fixedname_initname(&fixed);
475: stf_from_address(stfself, addr);
476: if (dns_name_iswildcard(rule->identity)) {
477: if (!dns_name_matcheswildcard(stfself,
1.4 christos 478: rule->identity)) {
1.1 christos 479: continue;
1.4 christos 480: }
1.1 christos 481: } else {
1.4 christos 482: if (!dns_name_equal(stfself, rule->identity)) {
1.1 christos 483: continue;
1.4 christos 484: }
1.1 christos 485: }
1.4 christos 486: if (!dns_name_equal(stfself, name)) {
1.1 christos 487: continue;
1.4 christos 488: }
1.1 christos 489: break;
490: case dns_ssumatchtype_external:
491: if (!dns_ssu_external_match(rule->identity, signer,
492: name, addr, type, key,
493: table->mctx))
1.4 christos 494: {
1.1 christos 495: continue;
1.4 christos 496: }
1.1 christos 497: break;
498: case dns_ssumatchtype_dlz:
1.4 christos 499: if (!dns_dlz_ssumatch(table->dlzdatabase, signer, name,
500: addr, type, key)) {
1.1 christos 501: continue;
1.4 christos 502: }
1.1 christos 503: break;
504: }
505:
506: if (rule->ntypes == 0) {
507: /*
508: * If this is a DLZ rule, then the DLZ ssu
509: * checks will have already checked
510: * the type.
511: */
512: if (rule->matchtype != dns_ssumatchtype_dlz &&
1.4 christos 513: !isusertype(type)) {
1.1 christos 514: continue;
1.4 christos 515: }
1.1 christos 516: } else {
517: for (i = 0; i < rule->ntypes; i++) {
518: if (rule->types[i] == dns_rdatatype_any ||
1.4 christos 519: rule->types[i] == type) {
1.1 christos 520: break;
1.4 christos 521: }
1.1 christos 522: }
1.4 christos 523: if (i == rule->ntypes) {
1.1 christos 524: continue;
1.4 christos 525: }
1.1 christos 526: }
527: return (rule->grant);
528: }
529:
1.3 christos 530: return (false);
1.1 christos 531: }
532:
1.3 christos 533: bool
1.1 christos 534: dns_ssurule_isgrant(const dns_ssurule_t *rule) {
535: REQUIRE(VALID_SSURULE(rule));
536: return (rule->grant);
537: }
538:
539: dns_name_t *
540: dns_ssurule_identity(const dns_ssurule_t *rule) {
541: REQUIRE(VALID_SSURULE(rule));
542: return (rule->identity);
543: }
544:
545: unsigned int
546: dns_ssurule_matchtype(const dns_ssurule_t *rule) {
547: REQUIRE(VALID_SSURULE(rule));
548: return (rule->matchtype);
549: }
550:
551: dns_name_t *
552: dns_ssurule_name(const dns_ssurule_t *rule) {
553: REQUIRE(VALID_SSURULE(rule));
554: return (rule->name);
555: }
556:
557: unsigned int
558: dns_ssurule_types(const dns_ssurule_t *rule, dns_rdatatype_t **types) {
559: REQUIRE(VALID_SSURULE(rule));
560: REQUIRE(types != NULL && *types != NULL);
561: *types = rule->types;
562: return (rule->ntypes);
563: }
564:
565: isc_result_t
566: dns_ssutable_firstrule(const dns_ssutable_t *table, dns_ssurule_t **rule) {
567: REQUIRE(VALID_SSUTABLE(table));
568: REQUIRE(rule != NULL && *rule == NULL);
569: *rule = ISC_LIST_HEAD(table->rules);
570: return (*rule != NULL ? ISC_R_SUCCESS : ISC_R_NOMORE);
571: }
572:
573: isc_result_t
574: dns_ssutable_nextrule(dns_ssurule_t *rule, dns_ssurule_t **nextrule) {
575: REQUIRE(VALID_SSURULE(rule));
576: REQUIRE(nextrule != NULL && *nextrule == NULL);
577: *nextrule = ISC_LIST_NEXT(rule, link);
578: return (*nextrule != NULL ? ISC_R_SUCCESS : ISC_R_NOMORE);
579: }
580:
581: /*
582: * Create a specialised SSU table that points at an external DLZ database
583: */
584: isc_result_t
585: dns_ssutable_createdlz(isc_mem_t *mctx, dns_ssutable_t **tablep,
1.4 christos 586: dns_dlzdb_t *dlzdatabase) {
1.1 christos 587: isc_result_t result;
588: dns_ssurule_t *rule;
589: dns_ssutable_t *table = NULL;
590:
591: REQUIRE(tablep != NULL && *tablep == NULL);
592:
593: result = dns_ssutable_create(mctx, &table);
1.4 christos 594: if (result != ISC_R_SUCCESS) {
1.1 christos 595: return (result);
1.4 christos 596: }
1.1 christos 597:
598: table->dlzdatabase = dlzdatabase;
599:
600: rule = isc_mem_get(table->mctx, sizeof(dns_ssurule_t));
601:
602: rule->identity = NULL;
603: rule->name = NULL;
604: rule->types = NULL;
1.3 christos 605: rule->grant = true;
1.1 christos 606: rule->matchtype = dns_ssumatchtype_dlz;
607: rule->ntypes = 0;
608: rule->types = NULL;
609: rule->magic = SSURULEMAGIC;
610:
611: ISC_LIST_INITANDAPPEND(table->rules, rule, link);
612: *tablep = table;
613: return (ISC_R_SUCCESS);
614: }
615:
616: isc_result_t
617: dns_ssu_mtypefromstring(const char *str, dns_ssumatchtype_t *mtype) {
618: REQUIRE(str != NULL);
619: REQUIRE(mtype != NULL);
620:
621: if (strcasecmp(str, "name") == 0) {
622: *mtype = dns_ssumatchtype_name;
623: } else if (strcasecmp(str, "subdomain") == 0) {
624: *mtype = dns_ssumatchtype_subdomain;
625: } else if (strcasecmp(str, "wildcard") == 0) {
626: *mtype = dns_ssumatchtype_wildcard;
627: } else if (strcasecmp(str, "self") == 0) {
628: *mtype = dns_ssumatchtype_self;
629: } else if (strcasecmp(str, "selfsub") == 0) {
630: *mtype = dns_ssumatchtype_selfsub;
631: } else if (strcasecmp(str, "selfwild") == 0) {
632: *mtype = dns_ssumatchtype_selfwild;
633: } else if (strcasecmp(str, "ms-self") == 0) {
634: *mtype = dns_ssumatchtype_selfms;
1.3 christos 635: } else if (strcasecmp(str, "ms-selfsub") == 0) {
636: *mtype = dns_ssumatchtype_selfsubms;
1.1 christos 637: } else if (strcasecmp(str, "krb5-self") == 0) {
638: *mtype = dns_ssumatchtype_selfkrb5;
1.3 christos 639: } else if (strcasecmp(str, "krb5-selfsub") == 0) {
640: *mtype = dns_ssumatchtype_selfsubkrb5;
1.1 christos 641: } else if (strcasecmp(str, "ms-subdomain") == 0) {
642: *mtype = dns_ssumatchtype_subdomainms;
643: } else if (strcasecmp(str, "krb5-subdomain") == 0) {
644: *mtype = dns_ssumatchtype_subdomainkrb5;
645: } else if (strcasecmp(str, "tcp-self") == 0) {
646: *mtype = dns_ssumatchtype_tcpself;
647: } else if (strcasecmp(str, "6to4-self") == 0) {
648: *mtype = dns_ssumatchtype_6to4self;
649: } else if (strcasecmp(str, "zonesub") == 0) {
650: *mtype = dns_ssumatchtype_subdomain;
651: } else if (strcasecmp(str, "external") == 0) {
652: *mtype = dns_ssumatchtype_external;
653: } else {
654: return (ISC_R_NOTFOUND);
655: }
656: return (ISC_R_SUCCESS);
657: }
CVSweb <webmaster@jp.NetBSD.org>