From: Xavi Hernandez Date: Thu, 25 Sep 2025 08:42:30 +0000 (+0200) Subject: s3/rpc_server/samr: fix CID 1509008 - time_t truncation X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ebff8568d2a64ee9fa88e7355e35e79ebeaa56be;p=thirdparty%2Fsamba.git s3/rpc_server/samr: fix CID 1509008 - time_t truncation The call to get_time_t_max() doesn't work as expected when time_t is a 64-bits type and the returned value is stored into a 32-bits unsigned integer. Truncating a 64-bits constant to a 32-bits number won't return, in general, the same value we would get if time_t were a 32-bits type. It's unsafe and could even return small numbers very far from the intended maximum. This patch completely avoids the need to use get_time_t_max() by assuming that when pwd_max_age is 0 or -1, it means no maximum age is defined, so the password never expires and we don't need to do any comparison. A small adjustment has also been made to avoid calling pdb_get_account_policy() if it's not necessary. Signed-off-by: Xavi Hernandez Reviewed-by: Douglas Bagnall Reviewed-by: Andreas Schneider Autobuild-User(master): Douglas Bagnall Autobuild-Date(master): Fri Sep 26 05:23:30 UTC 2025 on atb-devel-224 --- diff --git a/source3/rpc_server/samr/srv_samr_util.c b/source3/rpc_server/samr/srv_samr_util.c index fa35ce6a5de..ebf8b3127bc 100644 --- a/source3/rpc_server/samr/srv_samr_util.c +++ b/source3/rpc_server/samr/srv_samr_util.c @@ -639,24 +639,28 @@ void copy_id21_to_sam_passwd(const char *log_prefix, for example, to clear an autolocked acct. We must check to see if it's expired first. jmcd */ - uint32_t pwd_max_age = 0; time_t now = time(NULL); - - pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &pwd_max_age); - - if (pwd_max_age == (uint32_t)-1 || pwd_max_age == 0) { - pwd_max_age = get_time_t_max(); - } - - stored_time = pdb_get_pass_last_set_time(to); + bool expired = true; /* we will only *set* a pwdlastset date when a) the last pwdlastset time was 0 (user was forced to change password). b) the users password has not expired. gd. */ - if ((stored_time == 0) || - ((now - stored_time) > pwd_max_age)) { + stored_time = pdb_get_pass_last_set_time(to); + if (stored_time != 0) { + uint32_t pwd_max_age = 0; + + pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, + &pwd_max_age); + if ((pwd_max_age == (uint32_t)-1) || + (pwd_max_age == 0) || + (now <= (stored_time + pwd_max_age))) { + expired = false; + } + } + + if (expired) { pdb_set_pass_last_set_time(to, now, PDB_CHANGED); } }