From: Andrew Bartlett Date: Thu, 9 May 2024 04:24:31 +0000 (+1200) Subject: kdc: Track the pwdLastSet of expired UF_SMARTCARD_REQUIRED accounts X-Git-Tag: tdb-1.4.11~401 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=8afe27058b08ff30d2650bb4fec92f56fa418e6a;p=thirdparty%2Fsamba.git kdc: Track the pwdLastSet of expired UF_SMARTCARD_REQUIRED accounts 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 Reviewed-by: Jo Sutton --- diff --git a/source4/kdc/db-glue.c b/source4/kdc/db-glue.c index fb835588dcf..0ef1672c5c1 100644 --- a/source4/kdc/db-glue.c +++ b/source4/kdc/db-glue.c @@ -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",