This is an automated email from the ASF dual-hosted git repository. sureshanaparti pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/cloudstack.git
commit a8bd02f8ba8c6f995d69f1c20e9bd4fe6de2e438 Merge: 17ec4fc31c4 b74f21b9670 Author: Suresh Kumar Anaparti <[email protected]> AuthorDate: Thu Feb 26 11:12:20 2026 +0530 Merge branch '4.22' .github/workflows/merge-conflict-checker.yml | 4 +- .../cloud/agent/api/ModifyStoragePoolAnswer.java | 4 + .../src/main/java/com/cloud/user/UserVO.java | 2 +- .../main/java/com/cloud/user/dao/AccountDao.java | 2 - .../java/com/cloud/user/dao/AccountDaoImpl.java | 60 +-------- .../CitrixModifyStoragePoolCommandWrapper.java | 12 +- .../com/cloud/server/ManagementServerImpl.java | 31 +++-- .../com/cloud/template/TemplateManagerImpl.java | 14 ++- .../java/com/cloud/user/AccountManagerImpl.java | 134 ++++++++++----------- ...tBase.java => AccountManagentImplTestBase.java} | 8 +- .../com/cloud/user/AccountManagerImplTest.java | 112 ++++++++--------- .../AccountManagerImplVolumeDeleteEventTest.java | 2 +- ui/src/config/section/user.js | 4 + 13 files changed, 168 insertions(+), 221 deletions(-) diff --cc server/src/main/java/com/cloud/user/AccountManagerImpl.java index f0be13d858d,bfe6a1b0a47..09ef9fe8bec --- a/server/src/main/java/com/cloud/user/AccountManagerImpl.java +++ b/server/src/main/java/com/cloud/user/AccountManagerImpl.java @@@ -1607,41 -1574,10 +1596,41 @@@ public class AccountManagerImpl extend if (mandate2FA != null && mandate2FA) { user.setUser2faEnabled(true); } + validateAndUpdatePasswordChangeRequired(caller, updateUserCmd, user, account); _userDao.update(user.getId(), user); - return _userAccountDao.findById(user.getId()); + return userAccountDao.findById(user.getId()); } + private void validateAndUpdatePasswordChangeRequired(User caller, UpdateUserCmd updateUserCmd, UserVO user, Account account) { + if (updateUserCmd.isPasswordChangeRequired()) { + if (user.getState() != State.ENABLED || account.getState() != State.ENABLED) { + throw new CloudRuntimeException("CloudStack does not support enforcing password change for locked/disabled User or Account."); + } + + User.Source userSource = user.getSource(); + if (userSource == User.Source.SAML2 || userSource == User.Source.SAML2DISABLED || userSource == User.Source.LDAP) { + logger.warn("Enforcing password change is not permitted for source [{}].", user.getSource()); + throw new InvalidParameterValueException("CloudStack does not support enforcing password change for SAML or LDAP users."); + } + } + + boolean isCallerSameAsUser = user.getId() == caller.getId(); + boolean isPasswordResetRequired = updateUserCmd.isPasswordChangeRequired() && !isCallerSameAsUser; + // Admins only can enforce passwordChangeRequired for user + if (isRootAdmin(caller.getAccountId()) || isDomainAdmin(caller.getAccountId())) { + if (isPasswordResetRequired) { + _userDetailsDao.addDetail(user.getId(), PasswordChangeRequired, "true", false); + } + } + + if (StringUtils.isNotBlank(updateUserCmd.getPassword())) { + // Remove passwordChangeRequired if user updating own pwd or admin has not enforced it + if (isCallerSameAsUser || !isPasswordResetRequired) { + _userDetailsDao.removeDetail(user.getId(), PasswordChangeRequired); + } + } + } + @Override public void verifyCallerPrivilegeForUserOrAccountOperations(Account userAccount) { logger.debug(String.format("Verifying whether the caller has the correct privileges based on the user's role type and API permissions: %s", userAccount));
