diff --git a/server/src/main/java/com/cloud/user/AccountManagerImpl.java b/server/src/main/java/com/cloud/user/AccountManagerImpl.java
index c7ceb00cb575..8f5438cbd920 100644
--- a/server/src/main/java/com/cloud/user/AccountManagerImpl.java
+++ b/server/src/main/java/com/cloud/user/AccountManagerImpl.java
@@ -1459,6 +1459,8 @@ public UserAccount updateUser(UpdateUserCmd updateUserCmd) {
*
* - If 'password' is blank, we throw an {@link InvalidParameterValueException};
*
- If 'current password' is not provided and user is not an Admin, we throw an {@link InvalidParameterValueException};
+ *
- If the user whose password is being changed has a source equal to {@link User.Source#SAML2}, {@link User.Source#SAML2DISABLED} or {@link User.Source#LDAP},
+ * we throw an {@link InvalidParameterValueException};
*
- If a normal user is calling this method, we use {@link #validateCurrentPassword(UserVO, String)} to check if the provided old password matches the database one;
*
*
@@ -1473,6 +1475,12 @@ protected void validateUserPasswordAndUpdateIfNeeded(String newPassword, UserVO
throw new InvalidParameterValueException("Password cannot be empty or blank.");
}
+ User.Source userSource = user.getSource();
+ if (userSource == User.Source.SAML2 || userSource == User.Source.SAML2DISABLED || userSource == User.Source.LDAP) {
+ s_logger.warn(String.format("Unable to update the password for user [%d], as its source is [%s].", user.getId(), user.getSource().toString()));
+ throw new InvalidParameterValueException("CloudStack does not support updating passwords for SAML or LDAP users. Please contact your cloud administrator for assistance.");
+ }
+
passwordPolicy.verifyIfPasswordCompliesWithPasswordPolicies(newPassword, user.getUsername(), getAccount(user.getAccountId()).getDomainId());
Account callingAccount = getCurrentCallingAccount();
diff --git a/server/src/test/java/com/cloud/user/AccountManagerImplTest.java b/server/src/test/java/com/cloud/user/AccountManagerImplTest.java
index f0a5af2bd87e..fd30498927e1 100644
--- a/server/src/test/java/com/cloud/user/AccountManagerImplTest.java
+++ b/server/src/test/java/com/cloud/user/AccountManagerImplTest.java
@@ -745,6 +745,36 @@ public void validateUserPasswordAndUpdateIfNeededTestIfVerifyIfPasswordCompliesW
accountManagerImpl.validateUserPasswordAndUpdateIfNeeded(newPassword, userVoMock, currentPassword);
}
+ @Test(expected = InvalidParameterValueException.class)
+ public void validateUserPasswordAndUpdateIfNeededTestSaml2UserShouldNotBeAllowedToUpdateTheirPassword() {
+ String newPassword = "newPassword";
+ String currentPassword = "theCurrentPassword";
+
+ Mockito.when(userVoMock.getSource()).thenReturn(User.Source.SAML2);
+
+ accountManagerImpl.validateUserPasswordAndUpdateIfNeeded(newPassword, userVoMock, currentPassword);
+ }
+
+ @Test(expected = InvalidParameterValueException.class)
+ public void validateUserPasswordAndUpdateIfNeededTestSaml2DisabledUserShouldNotBeAllowedToUpdateTheirPassword() {
+ String newPassword = "newPassword";
+ String currentPassword = "theCurrentPassword";
+
+ Mockito.when(userVoMock.getSource()).thenReturn(User.Source.SAML2DISABLED);
+
+ accountManagerImpl.validateUserPasswordAndUpdateIfNeeded(newPassword, userVoMock, currentPassword);
+ }
+
+ @Test(expected = InvalidParameterValueException.class)
+ public void validateUserPasswordAndUpdateIfNeededTestLdapUserShouldNotBeAllowedToUpdateTheirPassword() {
+ String newPassword = "newPassword";
+ String currentPassword = "theCurrentPassword";
+
+ Mockito.when(userVoMock.getSource()).thenReturn(User.Source.LDAP);
+
+ accountManagerImpl.validateUserPasswordAndUpdateIfNeeded(newPassword, userVoMock, currentPassword);
+ }
+
private String configureUserMockAuthenticators(String newPassword) {
accountManagerImpl._userPasswordEncoders = new ArrayList<>();
UserAuthenticator authenticatorMock1 = Mockito.mock(UserAuthenticator.class);