]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
add krb5-selfsub and ms-selfsub
authorMark Andrews <marka@isc.org>
Thu, 30 Aug 2018 08:31:17 +0000 (18:31 +1000)
committerMark Andrews <marka@isc.org>
Mon, 10 Sep 2018 07:40:19 +0000 (17:40 +1000)
(cherry picked from commit fbeefd4990a53daabcbbc2130b39f0e7e1e6dd50)

doc/arm/Bv9ARM-book.xml
lib/bind9/check.c
lib/dns/gssapictx.c
lib/dns/include/dns/ssu.h
lib/dns/include/dst/gssapi.h
lib/dns/ssu.c
lib/isccfg/namedconf.c

index 4c4dd14b5e4e69aa624e5b44e574d56641c94096..baff8d364439132a0a46fe293b5f4a0e08654b57 100644 (file)
@@ -12573,12 +12573,13 @@ example.com. NS ns2.example.net.
              the rules are checked for each existing record type.
            </para>
            <para>
-             The <replaceable>ruletype</replaceable> field has 13
+             The <replaceable>ruletype</replaceable> field has 16
              values:
              <varname>name</varname>, <varname>subdomain</varname>,
              <varname>wildcard</varname>, <varname>self</varname>,
              <varname>selfsub</varname>, <varname>selfwild</varname>,
              <varname>krb5-self</varname>, <varname>ms-self</varname>,
+             <varname>krb5-selfsub</varname>, <varname>ms-selfsub</varname>,
              <varname>krb5-subdomain</varname>,
              <varname>ms-subdomain</varname>,
              <varname>tcp-self</varname>, <varname>6to4-self</varname>,
@@ -12737,6 +12738,20 @@ example.com. NS ns2.example.net.
                      </para>
                    </entry>
                  </row>
+                 <row rowsep="0">
+                   <entry colname="1">
+                     <para>
+                       <varname>ms-selfsub</varname>
+                     </para>
+                   </entry> <entry colname="2">
+                     <para>
+                       This is similar to <command>ms-self</command>
+                       except it also allows updates to any subdomain of
+                       the name specified in the Windows machine
+                       principal, not just to the name itself.
+                     </para>
+                   </entry>
+                 </row>
                  <row rowsep="0">
                    <entry colname="1">
                      <para>
@@ -12808,6 +12823,20 @@ example.com. NS ns2.example.net.
                      </para>
                    </entry>
                  </row>
+                 <row rowsep="0">
+                   <entry colname="1">
+                     <para>
+                       <varname>krb5-selfsub</varname>
+                     </para>
+                   </entry> <entry colname="2">
+                     <para>
+                       This is similar to <command>krb5-self</command>
+                       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.
+                     </para>
+                   </entry>
+                 </row>
                  <row rowsep="0">
                    <entry colname="1">
                      <para>
index d74b0380ffe00d818c27f444140518344e515b58..d32a5a17f153f1e34d81153e6134576346315baf 100644 (file)
@@ -1731,6 +1731,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 &&
index cac049867c9e0d41ddcd9b01f6ab6987e043d905..8bd99af343c03ed47d335e93b7b0e59b4e2512bc 100644 (file)
@@ -345,12 +345,13 @@ cleanup:
 }
 
 bool
-dst_gssapi_identitymatchesrealmkrb5(dns_name_t *signer, dns_name_t *name,
-                                   dns_name_t *realm)
+dst_gssapi_identitymatchesrealmkrb5(const dns_name_t *signer,
+                                   const dns_name_t *name,
+                                   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;
@@ -365,8 +366,6 @@ dst_gssapi_identitymatchesrealmkrb5(dns_name_t *signer, dns_name_t *name,
        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));
 
        /*
@@ -380,6 +379,10 @@ dst_gssapi_identitymatchesrealmkrb5(dns_name_t *signer, dns_name_t *name,
        *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
@@ -397,36 +400,44 @@ dst_gssapi_identitymatchesrealmkrb5(dns_name_t *signer, dns_name_t *name,
                return (false);
 
        /*
-        * 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);
-       } else {
-               if (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);
+               }
+               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
 }
 
 bool
-dst_gssapi_identitymatchesrealmms(dns_name_t *signer, dns_name_t *name,
-                                 dns_name_t *realm)
+dst_gssapi_identitymatchesrealmms(const dns_name_t *signer,
+                                 const dns_name_t *name,
+                                 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;
@@ -439,8 +450,6 @@ dst_gssapi_identitymatchesrealmms(dns_name_t *signer, dns_name_t *name,
        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));
 
        /*
@@ -474,36 +483,35 @@ dst_gssapi_identitymatchesrealmms(dns_name_t *signer, dns_name_t *name,
        *sname = '\0';
        sname = sbuf;
 
-       /*
-        * 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.
-        */
-       if (name != NULL) {
-               nname = strchr(nbuf, '.');
-               if (nname == NULL)
-                       return (false);
-               *nname++ = '\0';
+       if (strcmp(rname, rbuf) != 0) {
+               return (false);
        }
 
        /*
-        * Now, we do a simple comparison between the name and the realm.
+        * Now, we check that the realm matches (case sensitive) and that
+        * 'name' matches against 'machinename' qualified with '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);
-       }
+               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);
+               }
+               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
 }
index da6e3432bd8f0a68269e4662387368b0876d378c..402583c7d00252e8696446fc82897d8bcdf3684a 100644 (file)
@@ -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;
 
 #define DNS_SSUMATCHTYPE_NAME          dns_ssumatchtype_name
index 40257d479615e141372547eef50679235fcf9883..17a9f548a2e309eabc09fe7283be2cd01504b5fd 100644 (file)
@@ -187,8 +187,10 @@ gss_error_tostring(uint32_t major, uint32_t minor,
  */
 
 bool
-dst_gssapi_identitymatchesrealmkrb5(dns_name_t *signer, dns_name_t *name,
-                             dns_name_t *realm);
+dst_gssapi_identitymatchesrealmkrb5(const dns_name_t *signer,
+                                   const dns_name_t *name,
+                                   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
@@ -197,8 +199,10 @@ dst_gssapi_identitymatchesrealmkrb5(dns_name_t *signer, dns_name_t *name,
  */
 
 bool
-dst_gssapi_identitymatchesrealmms(dns_name_t *signer, dns_name_t *name,
-                           dns_name_t *realm);
+dst_gssapi_identitymatchesrealmms(const dns_name_t *signer,
+                                 const dns_name_t *name,
+                                 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
index 8aec053db6bfc0cd3d9f771d9fdd4858d05f221a..71ded66bbc0bcb2e3ac7a8c427840383b6f41044 100644 (file)
@@ -395,10 +395,12 @@ dns_ssutable_checkrules2(dns_ssutable_t *table, dns_name_t *signer,
                                        continue;
                        }
                        break;
-               case DNS_SSUMATCHTYPE_SELFKRB5:
-               case DNS_SSUMATCHTYPE_SELFMS:
-               case DNS_SSUMATCHTYPE_SUBDOMAINKRB5:
-               case DNS_SSUMATCHTYPE_SUBDOMAINMS:
+               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)
                                continue;
                        break;
@@ -462,30 +464,56 @@ dns_ssutable_checkrules2(dns_ssutable_t *table, dns_name_t *signer,
                        if (!dns_name_matcheswildcard(name, wildcard))
                                continue;
                        break;
-               case DNS_SSUMATCHTYPE_SELFKRB5:
-                       if (!dst_gssapi_identitymatchesrealmkrb5(signer, name,
-                                                              rule->identity))
-                               continue;
-                       break;
-               case DNS_SSUMATCHTYPE_SELFMS:
-                       if (!dst_gssapi_identitymatchesrealmms(signer, name,
-                                                              rule->identity))
-                               continue;
-                       break;
-               case DNS_SSUMATCHTYPE_SUBDOMAINKRB5:
+               case dns_ssumatchtype_selfkrb5:
+                       if (dst_gssapi_identitymatchesrealmkrb5(signer, name,
+                                                               rule->identity,
+                                                               false))
+                       {
+                               break;
+                       }
+                       continue;
+               case dns_ssumatchtype_selfms:
+                       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;
-               case DNS_SSUMATCHTYPE_SUBDOMAINMS:
+                       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);
@@ -658,8 +686,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) {
index 0a658c942b9bf75caf3f053050a2f63ea1705338..cd797a6b411baef1b1856f0ab0aa371abbad0210 100644 (file)
@@ -320,9 +320,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 = {