]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
kdc: Track the pwdLastSet of expired UF_SMARTCARD_REQUIRED accounts
authorAndrew Bartlett <abartlet@samba.org>
Thu, 9 May 2024 04:24:31 +0000 (16:24 +1200)
committerAndrew Bartlett <abartlet@samba.org>
Mon, 10 Jun 2024 04:27:31 +0000 (04:27 +0000)
This is to gracefully deal with races and to avoid additional password
rollover in situations where the TGT lifetime is longer than the
maximum password lifetime.  This is not a sensible combination, so
we just avoid the extra DB write, and update it only once per AS-REQ
in this case.

Signed-off-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Jo Sutton <josutton@catalyst.net.nz>
source4/kdc/db-glue.c

index fb835588dcf8b800a0eca7c415eca002bff8c9f3..0ef1672c5c1088c0a76cf8cf5d3a9ceb3ac340ec 100644 (file)
@@ -2818,6 +2818,8 @@ static krb5_error_code samba_kdc_fetch_client(krb5_context context,
        krb5_error_code ret;
        struct ldb_message *msg = NULL;
        int tries = 0;
+       NTTIME pwd_last_set_last_loop = INT64_MAX;
+       bool pwd_last_set_last_loop_set = false;
 
        /*
         * We will try up to 3 times to rotate the expired or soon to
@@ -2832,6 +2834,7 @@ static krb5_error_code samba_kdc_fetch_client(krb5_context context,
         * expired.
         */
        while (tries++ <= 2) {
+               NTTIME pwd_last_set_this_loop;
                uint32_t attr_flags_computed;
 
                /*
@@ -2874,6 +2877,24 @@ static krb5_error_code samba_kdc_fetch_client(krb5_context context,
                        break;
                }
 
+               /*
+                * Find if the pwdLastSet has changed on an account
+                * that we are about to change the password for.  If
+                * we have both seen it and it has changed already, go
+                * with that, even if it would fail the tests.  As
+                * well as dealing with races, this will avoid a
+                * double-reset every loop if the TGT lifetime is
+                * longer than the expiry.
+                */
+               pwd_last_set_this_loop =
+                       ldb_msg_find_attr_as_int64(msg, "pwdLastSet", INT64_MAX);
+               if (pwd_last_set_last_loop_set &&
+                   pwd_last_set_last_loop != pwd_last_set_this_loop) {
+                       break;
+               }
+               pwd_last_set_last_loop = pwd_last_set_this_loop;
+               pwd_last_set_last_loop_set = true;
+
                attr_flags_computed
                        = ldb_msg_find_attr_as_uint(msg,
                                                    "msDS-User-Account-Control-Computed",