diff --git a/doc/arm/Bv9ARM-book.xml b/doc/arm/Bv9ARM-book.xml index 453b7a43bd..af15b64982 100644 --- a/doc/arm/Bv9ARM-book.xml +++ b/doc/arm/Bv9ARM-book.xml @@ -12719,12 +12719,13 @@ example.com. NS ns2.example.net. the rules are checked for each existing record type. - The ruletype field has 13 + The ruletype field has 16 values: name, subdomain, wildcard, self, selfsub, selfwild, krb5-self, ms-self, + krb5-selfsub, ms-selfsub, krb5-subdomain, ms-subdomain, tcp-self, 6to4-self, @@ -12883,6 +12884,20 @@ example.com. NS ns2.example.net. + + + + ms-selfsub + + + + This is similar to ms-self + except it also allows updates to any subdomain of + the name specified in the Windows machine + principal, not just to the name itself. + + + @@ -12954,6 +12969,20 @@ example.com. NS ns2.example.net. + + + + krb5-selfsub + + + + This is similar to krb5-self + except it also allows updates to any subdomain of + the name specified in the 'machine' part of the + Kerberos principal, not just to the name itself. + + + diff --git a/lib/bind9/check.c b/lib/bind9/check.c index 2e5de8e1e9..451bfbeeac 100644 --- a/lib/bind9/check.c +++ b/lib/bind9/check.c @@ -1830,6 +1830,8 @@ check_update_policy(const cfg_obj_t *policy, isc_log_t *logctx) { break; case dns_ssumatchtype_selfkrb5: case dns_ssumatchtype_selfms: + case dns_ssumatchtype_selfsubkrb5: + case dns_ssumatchtype_selfsubms: case dns_ssumatchtype_tcpself: case dns_ssumatchtype_6to4self: if (tresult == ISC_R_SUCCESS && diff --git a/lib/dns/gssapictx.c b/lib/dns/gssapictx.c index bca9d3646b..6a6b2e3ab5 100644 --- a/lib/dns/gssapictx.c +++ b/lib/dns/gssapictx.c @@ -347,11 +347,11 @@ cleanup: bool dst_gssapi_identitymatchesrealmkrb5(const dns_name_t *signer, const dns_name_t *name, - const dns_name_t *realm) + const dns_name_t *realm, + bool subdomain) { #ifdef GSSAPI char sbuf[DNS_NAME_FORMATSIZE]; - char nbuf[DNS_NAME_FORMATSIZE]; char rbuf[DNS_NAME_FORMATSIZE]; char *sname; char *rname; @@ -366,8 +366,6 @@ dst_gssapi_identitymatchesrealmkrb5(const dns_name_t *signer, result = dns_name_toprincipal(signer, &buffer); RUNTIME_CHECK(result == ISC_R_SUCCESS); isc_buffer_putuint8(&buffer, 0); - if (name != NULL) - dns_name_format(name, nbuf, sizeof(nbuf)); dns_name_format(realm, rbuf, sizeof(rbuf)); /* @@ -382,6 +380,10 @@ dst_gssapi_identitymatchesrealmkrb5(const dns_name_t *signer, *rname = '\0'; rname++; + if (strcmp(rname, rbuf) != 0) { + return (false); + } + /* * Find the host portion of the signer's name. We do this by * searching for the first / character. We then check to make @@ -401,24 +403,30 @@ dst_gssapi_identitymatchesrealmkrb5(const dns_name_t *signer, } /* - * Now, we do a simple comparison between the name and the realm. + * If name is non NULL check that it matches against the + * machine name as expected. */ if (name != NULL) { - if ((strcasecmp(sname, nbuf) == 0) - && (strcmp(rname, rbuf) == 0)) { - return (true); + dns_fixedname_t fixed; + dns_name_t *machine; + + machine = dns_fixedname_initname(&fixed); + result = dns_name_fromstring(machine, sname, 0, NULL); + if (result != ISC_R_SUCCESS) { + return (false); } - } else { - if (strcmp(rname, rbuf) == 0) { - return (true); + if (subdomain) { + return (dns_name_issubdomain(name, machine)); } + return (dns_name_equal(name, machine)); } - return (false); + return (true); #else UNUSED(signer); UNUSED(name); UNUSED(realm); + UNUSED(subdomain); return (false); #endif } @@ -426,14 +434,13 @@ dst_gssapi_identitymatchesrealmkrb5(const dns_name_t *signer, bool dst_gssapi_identitymatchesrealmms(const dns_name_t *signer, const dns_name_t *name, - const dns_name_t *realm) + const dns_name_t *realm, + bool subdomain) { #ifdef GSSAPI char sbuf[DNS_NAME_FORMATSIZE]; - char nbuf[DNS_NAME_FORMATSIZE]; char rbuf[DNS_NAME_FORMATSIZE]; char *sname; - char *nname; char *rname; isc_buffer_t buffer; isc_result_t result; @@ -446,8 +453,6 @@ dst_gssapi_identitymatchesrealmms(const dns_name_t *signer, result = dns_name_toprincipal(signer, &buffer); RUNTIME_CHECK(result == ISC_R_SUCCESS); isc_buffer_putuint8(&buffer, 0); - if (name != NULL) - dns_name_format(name, nbuf, sizeof(nbuf)); dns_name_format(realm, rbuf, sizeof(rbuf)); /* @@ -484,39 +489,35 @@ dst_gssapi_identitymatchesrealmms(const dns_name_t *signer, *sname = '\0'; sname = sbuf; + if (strcmp(rname, rbuf) != 0) { + return (false); + } + /* - * Find the first . in the target name, and make it the end of - * the string. The rest of the name has to match the realm. + * Now, we check that the realm matches (case sensitive) and that + * 'name' matches against 'machinename' qualified with 'realm'. */ if (name != NULL) { - nname = strchr(nbuf, '.'); - if (nname == NULL) { + dns_fixedname_t fixed; + dns_name_t *machine; + + machine = dns_fixedname_initname(&fixed); + result = dns_name_fromstring2(machine, sbuf, realm, 0, NULL); + if (result != ISC_R_SUCCESS) { return (false); } - *nname++ = '\0'; + if (subdomain) { + return (dns_name_issubdomain(name, machine)); + } + return (dns_name_equal(name, machine)); } - /* - * Now, we do a simple comparison between the name and the realm. - */ - if (name != NULL) { - if ((strcasecmp(sname, nbuf) == 0) - && (strcmp(rname, rbuf) == 0) - && (strcasecmp(nname, rbuf) == 0)) { - return (true); - } - } else { - if (strcmp(rname, rbuf) == 0) { - return (true); - } - } - - - return (false); + return (true); #else UNUSED(signer); UNUSED(name); UNUSED(realm); + UNUSED(subdomain); return (false); #endif } diff --git a/lib/dns/include/dns/ssu.h b/lib/dns/include/dns/ssu.h index 6bb15ede0f..a4167c0900 100644 --- a/lib/dns/include/dns/ssu.h +++ b/lib/dns/include/dns/ssu.h @@ -39,9 +39,11 @@ typedef enum { dns_ssumatchtype_6to4self = 11, dns_ssumatchtype_external = 12, dns_ssumatchtype_local = 13, - dns_ssumatchtype_max = 13, /* max value */ + dns_ssumatchtype_selfsubms = 14, + dns_ssumatchtype_selfsubkrb5 = 15, + dns_ssumatchtype_max = 15, /* max value */ - dns_ssumatchtype_dlz = 14 /* intentionally higher than _max */ + dns_ssumatchtype_dlz = 16 /* intentionally higher than _max */ } dns_ssumatchtype_t; isc_result_t diff --git a/lib/dns/include/dst/gssapi.h b/lib/dns/include/dst/gssapi.h index e08dee2801..8ce6c30459 100644 --- a/lib/dns/include/dst/gssapi.h +++ b/lib/dns/include/dst/gssapi.h @@ -189,7 +189,8 @@ gss_error_tostring(uint32_t major, uint32_t minor, bool dst_gssapi_identitymatchesrealmkrb5(const dns_name_t *signer, const dns_name_t *name, - const dns_name_t *realm); + const dns_name_t *realm, + bool subdomain); /* * Compare a "signer" (in the format of a Kerberos-format Kerberos5 * principal: host/example.com@EXAMPLE.COM) to the realm name stored @@ -200,7 +201,8 @@ dst_gssapi_identitymatchesrealmkrb5(const dns_name_t *signer, bool dst_gssapi_identitymatchesrealmms(const dns_name_t *signer, const dns_name_t *name, - const dns_name_t *realm); + const dns_name_t *realm, + bool subdomain); /* * Compare a "signer" (in the format of a Kerberos-format Kerberos5 * principal: host/example.com@EXAMPLE.COM) to the realm name stored diff --git a/lib/dns/ssu.c b/lib/dns/ssu.c index 7cd664c75e..8767e0ab1a 100644 --- a/lib/dns/ssu.c +++ b/lib/dns/ssu.c @@ -388,6 +388,8 @@ dns_ssutable_checkrules(dns_ssutable_t *table, const dns_name_t *signer, break; case dns_ssumatchtype_selfkrb5: case dns_ssumatchtype_selfms: + case dns_ssumatchtype_selfsubkrb5: + case dns_ssumatchtype_selfsubms: case dns_ssumatchtype_subdomainkrb5: case dns_ssumatchtype_subdomainms: if (signer == NULL) @@ -457,29 +459,55 @@ dns_ssutable_checkrules(dns_ssutable_t *table, const dns_name_t *signer, continue; break; case dns_ssumatchtype_selfkrb5: - if (!dst_gssapi_identitymatchesrealmkrb5(signer, name, - rule->identity)) - continue; - break; + if (dst_gssapi_identitymatchesrealmkrb5(signer, name, + rule->identity, + false)) + { + break; + } + continue; case dns_ssumatchtype_selfms: - if (!dst_gssapi_identitymatchesrealmms(signer, name, - rule->identity)) - continue; - break; + if (dst_gssapi_identitymatchesrealmms(signer, name, + rule->identity, + false)) + { + break; + } + continue; + case dns_ssumatchtype_selfsubkrb5: + if (dst_gssapi_identitymatchesrealmkrb5(signer, name, + rule->identity, + true)) + { + break; + } + continue; + case dns_ssumatchtype_selfsubms: + if (dst_gssapi_identitymatchesrealmms(signer, name, + rule->identity, + true)) + break; + continue; case dns_ssumatchtype_subdomainkrb5: if (!dns_name_issubdomain(name, rule->name)) continue; - if (!dst_gssapi_identitymatchesrealmkrb5(signer, NULL, - rule->identity)) - continue; - break; + if (dst_gssapi_identitymatchesrealmkrb5(signer, NULL, + rule->identity, + false)) + { + break; + } + continue; case dns_ssumatchtype_subdomainms: if (!dns_name_issubdomain(name, rule->name)) continue; - if (!dst_gssapi_identitymatchesrealmms(signer, NULL, - rule->identity)) - continue; - break; + if (dst_gssapi_identitymatchesrealmms(signer, NULL, + rule->identity, + false)) + { + break; + } + continue; case dns_ssumatchtype_tcpself: tcpself = dns_fixedname_initname(&fixed); reverse_from_address(tcpself, addr); @@ -652,8 +680,12 @@ dns_ssu_mtypefromstring(const char *str, dns_ssumatchtype_t *mtype) { *mtype = dns_ssumatchtype_selfwild; } else if (strcasecmp(str, "ms-self") == 0) { *mtype = dns_ssumatchtype_selfms; + } else if (strcasecmp(str, "ms-selfsub") == 0) { + *mtype = dns_ssumatchtype_selfsubms; } else if (strcasecmp(str, "krb5-self") == 0) { *mtype = dns_ssumatchtype_selfkrb5; + } else if (strcasecmp(str, "krb5-selfsub") == 0) { + *mtype = dns_ssumatchtype_selfsubkrb5; } else if (strcasecmp(str, "ms-subdomain") == 0) { *mtype = dns_ssumatchtype_subdomainms; } else if (strcasecmp(str, "krb5-subdomain") == 0) { diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c index 3f6336d898..c6b1072d88 100644 --- a/lib/isccfg/namedconf.c +++ b/lib/isccfg/namedconf.c @@ -323,9 +323,10 @@ doc_matchname(cfg_printer_t *pctx, const cfg_type_t *type) { } static const char *matchtype_enums[] = { - "6to4-self", "external", "krb5-self", "krb5-subdomain", "ms-self", - "ms-subdomain", "name", "self", "selfsub", "selfwild", "subdomain", - "tcp-self", "wildcard", "zonesub", NULL + "6to4-self", "external", "krb5-self", "krb5-selfsub", + "krb5-subdomain", "ms-self", "ms-selfsub", "ms-subdomain", + "name", "self", "selfsub", "selfwild", "subdomain", "tcp-self", + "wildcard", "zonesub", NULL }; static cfg_type_t cfg_type_matchtype = {