]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
CVE-2022-2031 s4:kdc: Reject tickets during the last two minutes of their life
authorJoseph Sutton <josephsutton@catalyst.net.nz>
Mon, 30 May 2022 07:18:17 +0000 (19:18 +1200)
committerJule Anger <janger@samba.org>
Sun, 24 Jul 2022 09:42:02 +0000 (11:42 +0200)
For Heimdal, this now matches the behaviour of Windows. The object of
this requirement is to ensure we don't allow kpasswd tickets, not having
a lifetime of more than two minutes, to be passed off as TGTs.

An existing requirement for TGTs to contain a REQUESTER_SID PAC buffer
suffices to prevent kpasswd ticket misuse, so this is just an additional
precaution on top.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15047

Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
Reviewed-by: Andreas Schneider <asn@samba.org>
[jsutton@samba.org As we don't have access to the ticket or the request
 in the plugin, rewrote check directly in Heimdal KDC]

selftest/knownfail_heimdal_kdc
source4/heimdal/kdc/krb5tgs.c

index 387ccea3ba75ac01945b7c2dccaa453ef453cbea..afb9bcf1209985502c108b9bf06d6eb0de5737c8 100644 (file)
 # Kpasswd tests
 #
 ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_from_rodc.ad_dc
-^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_ticket_requester_sid_tgs.ad_dc
 ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_wrong_key.ad_dc
 ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_wrong_key_server.ad_dc
 ^samba.tests.krb5.kpasswd_tests.samba.tests.krb5.kpasswd_tests.KpasswdTests.test_kpasswd_wrong_key_service.ad_dc
index 38dba8493ae1cab2873f6ce81613681a4515d340..15be136496fa4471554b4ccc7d13236145c3f5e8 100644 (file)
@@ -33,6 +33,9 @@
 
 #include "kdc_locl.h"
 
+/* Awful hack to get access to 'struct samba_kdc_entry'. */
+#include "../../kdc/samba_kdc.h"
+
 /*
  * return the realm of a krbtgt-ticket or NULL
  */
@@ -130,6 +133,7 @@ check_PAC(krb5_context context,
 static krb5_error_code
 check_tgs_flags(krb5_context context,
                krb5_kdc_configuration *config,
+               const hdb_entry_ex *krbtgt_in,
                KDC_REQ_BODY *b, const EncTicketPart *tgt, EncTicketPart *et)
 {
     KDCOptions f = b->kdc_options;
@@ -244,6 +248,17 @@ check_tgs_flags(krb5_context context,
            et->endtime = min(*et->renew_till, et->endtime);
     }
 
+    if (tgt->endtime - kdc_time <= CHANGEPW_LIFETIME) {
+       /* Check that the ticket has not arrived across a trust. */
+       const struct samba_kdc_entry *skdc_entry = krbtgt_in->ctx;
+       if (!skdc_entry->is_trust) {
+           /* This may be a kpasswd ticket rather than a TGT, so don't accept it. */
+           kdc_log(context, config, 0,
+                   "Ticket is not a ticket-granting ticket");
+           return KRB5KRB_AP_ERR_TKT_EXPIRED;
+       }
+    }
+
 #if 0
     /* checks for excess flags */
     if(f.request_anonymous && !config->allow_anonymous){
@@ -510,6 +525,7 @@ tgs_make_reply(krb5_context context,
               hdb_entry_ex *client,
               krb5_principal client_principal,
                const char *tgt_realm,
+              const hdb_entry_ex *krbtgt_in,
               hdb_entry_ex *krbtgt,
               krb5_pac mspac,
               uint16_t rodc_id,
@@ -538,7 +554,7 @@ tgs_make_reply(krb5_context context,
     ALLOC(et.starttime);
     *et.starttime = kdc_time;
 
-    ret = check_tgs_flags(context, config, b, tgt, &et);
+    ret = check_tgs_flags(context, config, krbtgt_in, b, tgt, &et);
     if(ret)
        goto out;
 
@@ -2129,6 +2145,7 @@ server_lookup:
                         client,
                         cp,
                         tgt_realm,
+                        krbtgt,
                         krbtgt_out,
                         mspac,
                         rodc_id,