]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
CVE-2019-14870: heimdal: enforce delegation_not_allowed in S4U2Self
authorIsaac Boukris <iboukris@gmail.com>
Mon, 28 Oct 2019 00:54:09 +0000 (02:54 +0200)
committerKarolin Seeger <kseeger@samba.org>
Fri, 29 Nov 2019 10:55:44 +0000 (11:55 +0100)
Signed-off-by: Isaac Boukris <iboukris@gmail.com>
selftest/knownfail.d/heimdal_not_delegated [deleted file]
source4/heimdal/kdc/krb5tgs.c

diff --git a/selftest/knownfail.d/heimdal_not_delegated b/selftest/knownfail.d/heimdal_not_delegated
deleted file mode 100644 (file)
index bfc382a..0000000
+++ /dev/null
@@ -1 +0,0 @@
-^samba4.blackbox.krb5.s4u
index ff7d93138c05d0a1995fae574144fd700754b4cd..ee3ac3d8f539ce602d53b819152c6a65aa432472 100644 (file)
@@ -1975,30 +1975,42 @@ server_lookup:
            if (ret)
                goto out;
 
+           ret = _kdc_db_fetch(context, config, tp, HDB_F_GET_CLIENT | flags,
+                               NULL, &s4u2self_impersonated_clientdb,
+                               &s4u2self_impersonated_client);
+           if (ret) {
+               const char *msg;
+
+               /*
+                * If the client belongs to the same realm as our krbtgt, it
+                * should exist in the local database.
+                *
+                */
+
+               if (ret == HDB_ERR_NOENTRY)
+                   ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN;
+               msg = krb5_get_error_message(context, ret);
+               kdc_log(context, config, 1,
+                       "S2U4Self principal to impersonate %s not found in database: %s",
+                       tpn, msg);
+               krb5_free_error_message(context, msg);
+               goto out;
+           }
+
+           /* Ignore pw_end attributes (as Windows does),
+            * since S4U2Self is not password authentication. */
+           free(s4u2self_impersonated_client->entry.pw_end);
+           s4u2self_impersonated_client->entry.pw_end = NULL;
+
+           ret = kdc_check_flags(context, config, s4u2self_impersonated_client, tpn,
+                                 NULL, NULL, FALSE);
+           if (ret)
+               goto out;
+
            /* If we were about to put a PAC into the ticket, we better fix it to be the right PAC */
            if(rspac.data) {
                krb5_pac p = NULL;
                krb5_data_free(&rspac);
-               ret = _kdc_db_fetch(context, config, tp, HDB_F_GET_CLIENT | flags,
-                                   NULL, &s4u2self_impersonated_clientdb, &s4u2self_impersonated_client);
-               if (ret) {
-                   const char *msg;
-
-                   /*
-                    * If the client belongs to the same realm as our krbtgt, it
-                    * should exist in the local database.
-                    *
-                    */
-
-                   if (ret == HDB_ERR_NOENTRY)
-                       ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN;
-                   msg = krb5_get_error_message(context, ret);
-                   kdc_log(context, config, 1,
-                           "S2U4Self principal to impersonate %s not found in database: %s",
-                           tpn, msg);
-                   krb5_free_error_message(context, msg);
-                   goto out;
-               }
                ret = _kdc_pac_generate(context, s4u2self_impersonated_client, NULL, &p);
                if (ret) {
                    kdc_log(context, config, 0, "PAC generation failed for -- %s",
@@ -2034,10 +2046,12 @@ server_lookup:
 
            /*
             * If the service isn't trusted for authentication to
-            * delegation, remove the forward flag.
+            * delegation or if the impersonate client is disallowed
+            * forwardable, remove the forwardable flag.
             */
 
-           if (client->entry.flags.trusted_for_delegation) {
+           if (client->entry.flags.trusted_for_delegation &&
+               s4u2self_impersonated_client->entry.flags.forwardable) {
                str = "[forwardable]";
            } else {
                b->kdc_options.forwardable = 0;