ssu.c revision 1.6
118334Speter/* $NetBSD: ssu.c,v 1.6 2022/09/23 12:15:30 christos Exp $ */ 218334Speter 318334Speter/* 418334Speter * Copyright (C) Internet Systems Consortium, Inc. ("ISC") 518334Speter * 618334Speter * SPDX-License-Identifier: MPL-2.0 718334Speter * 818334Speter * This Source Code Form is subject to the terms of the Mozilla Public 918334Speter * License, v. 2.0. If a copy of the MPL was not distributed with this 1018334Speter * file, you can obtain one at https://mozilla.org/MPL/2.0/. 1118334Speter * 1218334Speter * See the COPYRIGHT file distributed with this work for additional 1318334Speter * information regarding copyright ownership. 1418334Speter */ 1518334Speter 1618334Speter/*! \file */ 1718334Speter 1818334Speter#include <stdbool.h> 1918334Speter 2018334Speter#include <isc/magic.h> 2118334Speter#include <isc/mem.h> 2218334Speter#include <isc/netaddr.h> 2318334Speter#include <isc/print.h> 2418334Speter#include <isc/refcount.h> 2518334Speter#include <isc/result.h> 2618334Speter#include <isc/string.h> 2718334Speter#include <isc/util.h> 2818334Speter 2918334Speter#include <dns/dlz.h> 3018334Speter#include <dns/fixedname.h> 3118334Speter#include <dns/name.h> 3218334Speter#include <dns/ssu.h> 3318334Speter 3418334Speter#include <dst/dst.h> 3518334Speter#include <dst/gssapi.h> 3618334Speter 3718334Speter#define SSUTABLEMAGIC ISC_MAGIC('S', 'S', 'U', 'T') 3818334Speter#define VALID_SSUTABLE(table) ISC_MAGIC_VALID(table, SSUTABLEMAGIC) 3918334Speter 4018334Speter#define SSURULEMAGIC ISC_MAGIC('S', 'S', 'U', 'R') 4118334Speter#define VALID_SSURULE(table) ISC_MAGIC_VALID(table, SSURULEMAGIC) 4218334Speter 4318334Speterstruct dns_ssurule { 4418334Speter unsigned int magic; 4518334Speter bool grant; /*%< is this a grant or a deny? */ 4618334Speter dns_ssumatchtype_t matchtype; /*%< which type of pattern match? 4718334Speter * */ 4818334Speter dns_name_t *identity; /*%< the identity to match */ 4918334Speter dns_name_t *name; /*%< the name being updated */ 5018334Speter unsigned int ntypes; /*%< number of data types covered */ 5118334Speter dns_rdatatype_t *types; /*%< the data types. Can include */ 5218334Speter /* ANY. if NULL, defaults to all */ 5318334Speter /* types except SIG, SOA, and NS */ 5418334Speter ISC_LINK(dns_ssurule_t) link; 5518334Speter}; 5618334Speter 5718334Speterstruct dns_ssutable { 5818334Speter unsigned int magic; 5918334Speter isc_mem_t *mctx; 6018334Speter isc_refcount_t references; 6118334Speter dns_dlzdb_t *dlzdatabase; 6218334Speter ISC_LIST(dns_ssurule_t) rules; 6318334Speter}; 6418334Speter 6518334Speterisc_result_t 6618334Speterdns_ssutable_create(isc_mem_t *mctx, dns_ssutable_t **tablep) { 6718334Speter dns_ssutable_t *table; 6818334Speter 6918334Speter REQUIRE(tablep != NULL && *tablep == NULL); 7018334Speter REQUIRE(mctx != NULL); 7118334Speter 7218334Speter table = isc_mem_get(mctx, sizeof(dns_ssutable_t)); 7318334Speter isc_refcount_init(&table->references, 1); 7418334Speter table->mctx = NULL; 7518334Speter isc_mem_attach(mctx, &table->mctx); 7618334Speter ISC_LIST_INIT(table->rules); 7718334Speter table->magic = SSUTABLEMAGIC; 7818334Speter *tablep = table; 7918334Speter return (ISC_R_SUCCESS); 8018334Speter} 8118334Speter 8218334Speterstatic void 8318334Speterdestroy(dns_ssutable_t *table) { 8418334Speter isc_mem_t *mctx; 8518334Speter 8618334Speter REQUIRE(VALID_SSUTABLE(table)); 8718334Speter 8818334Speter mctx = table->mctx; 8918334Speter while (!ISC_LIST_EMPTY(table->rules)) { 9018334Speter dns_ssurule_t *rule = ISC_LIST_HEAD(table->rules); 9118334Speter if (rule->identity != NULL) { 9218334Speter dns_name_free(rule->identity, mctx); 9318334Speter isc_mem_put(mctx, rule->identity, sizeof(dns_name_t)); 9418334Speter } 9518334Speter if (rule->name != NULL) { 9618334Speter dns_name_free(rule->name, mctx); 9718334Speter isc_mem_put(mctx, rule->name, sizeof(dns_name_t)); 9818334Speter } 9918334Speter if (rule->types != NULL) { 10018334Speter isc_mem_put(mctx, rule->types, 10118334Speter rule->ntypes * sizeof(dns_rdatatype_t)); 10218334Speter } 10318334Speter ISC_LIST_UNLINK(table->rules, rule, link); 10418334Speter rule->magic = 0; 10518334Speter isc_mem_put(mctx, rule, sizeof(dns_ssurule_t)); 10618334Speter } 10718334Speter isc_refcount_destroy(&table->references); 10818334Speter table->magic = 0; 10918334Speter isc_mem_putanddetach(&table->mctx, table, sizeof(dns_ssutable_t)); 11018334Speter} 11118334Speter 11218334Spetervoid 11318334Speterdns_ssutable_attach(dns_ssutable_t *source, dns_ssutable_t **targetp) { 11418334Speter REQUIRE(VALID_SSUTABLE(source)); 11518334Speter REQUIRE(targetp != NULL && *targetp == NULL); 11618334Speter 11718334Speter isc_refcount_increment(&source->references); 11818334Speter 11918334Speter *targetp = source; 12018334Speter} 12118334Speter 12218334Spetervoid 12318334Speterdns_ssutable_detach(dns_ssutable_t **tablep) { 12418334Speter dns_ssutable_t *table; 12518334Speter 12618334Speter REQUIRE(tablep != NULL); 12718334Speter table = *tablep; 12818334Speter *tablep = NULL; 12918334Speter REQUIRE(VALID_SSUTABLE(table)); 13018334Speter 13118334Speter if (isc_refcount_decrement(&table->references) == 1) { 13218334Speter destroy(table); 13318334Speter } 13418334Speter} 13518334Speter 13618334Speterisc_result_t 13718334Speterdns_ssutable_addrule(dns_ssutable_t *table, bool grant, 13818334Speter const dns_name_t *identity, dns_ssumatchtype_t matchtype, 13918334Speter const dns_name_t *name, unsigned int ntypes, 14018334Speter dns_rdatatype_t *types) { 14118334Speter dns_ssurule_t *rule; 14218334Speter isc_mem_t *mctx; 14318334Speter 14418334Speter REQUIRE(VALID_SSUTABLE(table)); 14518334Speter REQUIRE(dns_name_isabsolute(identity)); 14618334Speter REQUIRE(dns_name_isabsolute(name)); 14718334Speter REQUIRE(matchtype <= dns_ssumatchtype_max); 14818334Speter if (matchtype == dns_ssumatchtype_wildcard) { 14918334Speter REQUIRE(dns_name_iswildcard(name)); 15018334Speter } 15118334Speter if (ntypes > 0) { 15218334Speter REQUIRE(types != NULL); 15318334Speter } 15418334Speter 15518334Speter mctx = table->mctx; 15618334Speter rule = isc_mem_get(mctx, sizeof(dns_ssurule_t)); 15718334Speter 15818334Speter rule->identity = NULL; 15918334Speter rule->name = NULL; 16018334Speter rule->types = NULL; 16118334Speter 16218334Speter rule->grant = grant; 16318334Speter 16418334Speter rule->identity = isc_mem_get(mctx, sizeof(dns_name_t)); 16518334Speter dns_name_init(rule->identity, NULL); 16618334Speter dns_name_dup(identity, mctx, rule->identity); 16718334Speter 16818334Speter rule->name = isc_mem_get(mctx, sizeof(dns_name_t)); 16918334Speter dns_name_init(rule->name, NULL); 17018334Speter dns_name_dup(name, mctx, rule->name); 17118334Speter 17218334Speter rule->matchtype = matchtype; 17318334Speter 17418334Speter rule->ntypes = ntypes; 17518334Speter if (ntypes > 0) { 17618334Speter rule->types = isc_mem_get(mctx, 17718334Speter ntypes * sizeof(dns_rdatatype_t)); 17818334Speter memmove(rule->types, types, ntypes * sizeof(dns_rdatatype_t)); 17918334Speter } else { 18018334Speter rule->types = NULL; 181 } 182 183 rule->magic = SSURULEMAGIC; 184 ISC_LIST_INITANDAPPEND(table->rules, rule, link); 185 186 return (ISC_R_SUCCESS); 187} 188 189static bool 190isusertype(dns_rdatatype_t type) { 191 return (type != dns_rdatatype_ns && type != dns_rdatatype_soa && 192 type != dns_rdatatype_rrsig); 193} 194 195static void 196reverse_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); 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)); 211 break; 212 case AF_INET6: 213 ap = tcpaddr->type.in6.s6_addr; 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); 233 RUNTIME_CHECK(result < sizeof(buf)); 234 break; 235 default: 236 UNREACHABLE(); 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 244static void 245stf_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 252 switch (tcpaddr->family) { 253 case AF_INET: 254 l = ntohl(tcpaddr->type.in.s_addr); 255 result = snprintf(buf, sizeof(buf), 256 "%lx.%lx.%lx.%lx.%lx.%lx.%lx.%lx" 257 "2.0.0.2.IP6.ARPA.", 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); 262 RUNTIME_CHECK(result < sizeof(buf)); 263 break; 264 case AF_INET6: 265 ap = tcpaddr->type.in6.s6_addr; 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); 274 RUNTIME_CHECK(result < sizeof(buf)); 275 break; 276 default: 277 UNREACHABLE(); 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 285bool 286dns_ssutable_checkrules(dns_ssutable_t *table, const dns_name_t *signer, 287 const dns_name_t *name, const isc_netaddr_t *addr, 288 bool tcp, const dns_aclenv_t *env, dns_rdatatype_t type, 289 const dst_key_t *key) { 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 304 if (signer == NULL && addr == NULL) { 305 return (false); 306 } 307 308 for (rule = ISC_LIST_HEAD(table->rules); rule != NULL; 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: 319 if (signer == NULL) { 320 continue; 321 } 322 if (dns_name_iswildcard(rule->identity)) { 323 if (!dns_name_matcheswildcard(signer, 324 rule->identity)) { 325 continue; 326 } 327 } else { 328 if (!dns_name_equal(signer, rule->identity)) { 329 continue; 330 } 331 } 332 break; 333 case dns_ssumatchtype_selfkrb5: 334 case dns_ssumatchtype_selfms: 335 case dns_ssumatchtype_selfsubkrb5: 336 case dns_ssumatchtype_selfsubms: 337 case dns_ssumatchtype_subdomainkrb5: 338 case dns_ssumatchtype_subdomainms: 339 if (signer == NULL) { 340 continue; 341 } 342 break; 343 case dns_ssumatchtype_tcpself: 344 case dns_ssumatchtype_6to4self: 345 if (!tcp || addr == NULL) { 346 continue; 347 } 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: 356 if (!dns_name_equal(name, rule->name)) { 357 continue; 358 } 359 break; 360 case dns_ssumatchtype_subdomain: 361 if (!dns_name_issubdomain(name, rule->name)) { 362 continue; 363 } 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 } 372 dns_acl_match(addr, NULL, env->localhost, NULL, &match, 373 NULL); 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: 389 if (!dns_name_matcheswildcard(name, rule->name)) { 390 continue; 391 } 392 break; 393 case dns_ssumatchtype_self: 394 if (!dns_name_equal(signer, name)) { 395 continue; 396 } 397 break; 398 case dns_ssumatchtype_selfsub: 399 if (!dns_name_issubdomain(name, signer)) { 400 continue; 401 } 402 break; 403 case dns_ssumatchtype_selfwild: 404 wildcard = dns_fixedname_initname(&fixed); 405 result = dns_name_concatenate(dns_wildcardname, signer, 406 wildcard, NULL); 407 if (result != ISC_R_SUCCESS) { 408 continue; 409 } 410 if (!dns_name_matcheswildcard(name, wildcard)) { 411 continue; 412 } 413 break; 414 case dns_ssumatchtype_selfkrb5: 415 if (dst_gssapi_identitymatchesrealmkrb5( 416 signer, name, rule->identity, false)) { 417 break; 418 } 419 continue; 420 case dns_ssumatchtype_selfms: 421 if (dst_gssapi_identitymatchesrealmms( 422 signer, name, rule->identity, false)) { 423 break; 424 } 425 continue; 426 case dns_ssumatchtype_selfsubkrb5: 427 if (dst_gssapi_identitymatchesrealmkrb5( 428 signer, name, rule->identity, true)) { 429 break; 430 } 431 continue; 432 case dns_ssumatchtype_selfsubms: 433 if (dst_gssapi_identitymatchesrealmms( 434 signer, name, rule->identity, true)) { 435 break; 436 } 437 continue; 438 case dns_ssumatchtype_subdomainkrb5: 439 if (!dns_name_issubdomain(name, rule->name)) { 440 continue; 441 } 442 if (dst_gssapi_identitymatchesrealmkrb5( 443 signer, NULL, rule->identity, false)) { 444 break; 445 } 446 continue; 447 case dns_ssumatchtype_subdomainms: 448 if (!dns_name_issubdomain(name, rule->name)) { 449 continue; 450 } 451 if (dst_gssapi_identitymatchesrealmms( 452 signer, NULL, rule->identity, false)) { 453 break; 454 } 455 continue; 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, 461 rule->identity)) { 462 continue; 463 } 464 } else { 465 if (!dns_name_equal(tcpself, rule->identity)) { 466 continue; 467 } 468 } 469 if (!dns_name_equal(tcpself, name)) { 470 continue; 471 } 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, 478 rule->identity)) { 479 continue; 480 } 481 } else { 482 if (!dns_name_equal(stfself, rule->identity)) { 483 continue; 484 } 485 } 486 if (!dns_name_equal(stfself, name)) { 487 continue; 488 } 489 break; 490 case dns_ssumatchtype_external: 491 if (!dns_ssu_external_match(rule->identity, signer, 492 name, addr, type, key, 493 table->mctx)) 494 { 495 continue; 496 } 497 break; 498 case dns_ssumatchtype_dlz: 499 if (!dns_dlz_ssumatch(table->dlzdatabase, signer, name, 500 addr, type, key)) { 501 continue; 502 } 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 && 513 !isusertype(type)) { 514 continue; 515 } 516 } else { 517 for (i = 0; i < rule->ntypes; i++) { 518 if (rule->types[i] == dns_rdatatype_any || 519 rule->types[i] == type) { 520 break; 521 } 522 } 523 if (i == rule->ntypes) { 524 continue; 525 } 526 } 527 return (rule->grant); 528 } 529 530 return (false); 531} 532 533bool 534dns_ssurule_isgrant(const dns_ssurule_t *rule) { 535 REQUIRE(VALID_SSURULE(rule)); 536 return (rule->grant); 537} 538 539dns_name_t * 540dns_ssurule_identity(const dns_ssurule_t *rule) { 541 REQUIRE(VALID_SSURULE(rule)); 542 return (rule->identity); 543} 544 545unsigned int 546dns_ssurule_matchtype(const dns_ssurule_t *rule) { 547 REQUIRE(VALID_SSURULE(rule)); 548 return (rule->matchtype); 549} 550 551dns_name_t * 552dns_ssurule_name(const dns_ssurule_t *rule) { 553 REQUIRE(VALID_SSURULE(rule)); 554 return (rule->name); 555} 556 557unsigned int 558dns_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 565isc_result_t 566dns_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 573isc_result_t 574dns_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 */ 584isc_result_t 585dns_ssutable_createdlz(isc_mem_t *mctx, dns_ssutable_t **tablep, 586 dns_dlzdb_t *dlzdatabase) { 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); 594 if (result != ISC_R_SUCCESS) { 595 return (result); 596 } 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; 605 rule->grant = true; 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 616isc_result_t 617dns_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; 635 } else if (strcasecmp(str, "ms-selfsub") == 0) { 636 *mtype = dns_ssumatchtype_selfsubms; 637 } else if (strcasecmp(str, "krb5-self") == 0) { 638 *mtype = dns_ssumatchtype_selfkrb5; 639 } else if (strcasecmp(str, "krb5-selfsub") == 0) { 640 *mtype = dns_ssumatchtype_selfsubkrb5; 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} 658