瀏覽代碼

fix issues with forgottenpw and helpdesk setting of random passwords for user.

Jason Rivard 7 年之前
父節點
當前提交
bb43f82006

+ 0 - 31
server/src/main/java/password/pwm/config/option/HelpdeskUIMode.java

@@ -1,31 +0,0 @@
-/*
- * Password Management Servlets (PWM)
- * http://www.pwm-project.org
- *
- * Copyright (c) 2006-2009 Novell, Inc.
- * Copyright (c) 2009-2017 The PWM Project
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-package password.pwm.config.option;
-
-public enum HelpdeskUIMode implements ConfigurationOption {
-    none,
-    type,
-    autogen,
-    both,
-    random,
-}

+ 5 - 96
server/src/main/java/password/pwm/http/servlet/forgottenpw/ForgottenPasswordServlet.java

@@ -51,7 +51,6 @@ import password.pwm.config.value.data.FormConfiguration;
 import password.pwm.error.ErrorInformation;
 import password.pwm.error.PwmDataValidationException;
 import password.pwm.error.PwmError;
-import password.pwm.error.PwmException;
 import password.pwm.error.PwmOperationalException;
 import password.pwm.error.PwmUnrecoverableException;
 import password.pwm.http.HttpMethod;
@@ -84,9 +83,7 @@ import password.pwm.svc.stats.StatisticsManager;
 import password.pwm.svc.token.TokenPayload;
 import password.pwm.svc.token.TokenType;
 import password.pwm.util.CaptchaUtility;
-import password.pwm.util.PasswordData;
 import password.pwm.util.PostChangePasswordAction;
-import password.pwm.util.RandomPasswordGenerator;
 import password.pwm.util.form.FormUtility;
 import password.pwm.util.java.JavaHelper;
 import password.pwm.util.java.JsonUtil;
@@ -213,15 +210,15 @@ public class ForgottenPasswordServlet extends ControlledPwmServlet {
         return ProcessStatus.Continue;
     }
 
-    private static ForgottenPasswordBean forgottenPasswordBean(final PwmRequest pwmRequest) throws PwmUnrecoverableException {
+    static ForgottenPasswordBean forgottenPasswordBean( final PwmRequest pwmRequest ) throws PwmUnrecoverableException {
         return pwmRequest.getPwmApplication().getSessionStateService().getBean(pwmRequest, ForgottenPasswordBean.class);
     }
 
-    private static void clearForgottenPasswordBean(final PwmRequest pwmRequest) throws PwmUnrecoverableException {
+    static void clearForgottenPasswordBean( final PwmRequest pwmRequest ) throws PwmUnrecoverableException {
         pwmRequest.getPwmApplication().getSessionStateService().clearBean(pwmRequest, ForgottenPasswordBean.class);
     }
 
-    private static ForgottenPasswordProfile forgottenPasswordProfile(final PwmRequest pwmRequest) throws PwmUnrecoverableException {
+    static ForgottenPasswordProfile forgottenPasswordProfile( final PwmRequest pwmRequest ) throws PwmUnrecoverableException {
         final ForgottenPasswordBean forgottenPasswordBean = forgottenPasswordBean(pwmRequest);
         return pwmRequest.getConfig().getForgottenPasswordProfiles().get(forgottenPasswordBean.getForgottenPasswordProfileID());
     }
@@ -896,7 +893,7 @@ public class ForgottenPasswordServlet extends ControlledPwmServlet {
 
         final RecoveryAction recoveryAction = ForgottenPasswordUtil.getRecoveryAction(config, forgottenPasswordBean);
         if (recoveryAction == RecoveryAction.SENDNEWPW || recoveryAction == RecoveryAction.SENDNEWPW_AND_EXPIRE) {
-            processSendNewPassword(pwmRequest);
+            ForgottenPasswordUtil.doActionSendNewPassword(pwmRequest);
             return;
         }
 
@@ -1005,94 +1002,6 @@ public class ForgottenPasswordServlet extends ControlledPwmServlet {
         }
     }
 
-    private static void processSendNewPassword(final PwmRequest pwmRequest)
-            throws ChaiUnavailableException, IOException, ServletException, PwmUnrecoverableException
-    {
-        final PwmApplication pwmApplication = pwmRequest.getPwmApplication();
-        final PwmSession pwmSession = pwmRequest.getPwmSession();
-        final ForgottenPasswordBean forgottenPasswordBean = forgottenPasswordBean(pwmRequest);
-        final ForgottenPasswordProfile forgottenPasswordProfile = forgottenPasswordProfile(pwmRequest);
-        final RecoveryAction recoveryAction = ForgottenPasswordUtil.getRecoveryAction(pwmApplication.getConfig(), forgottenPasswordBean);
-
-        LOGGER.trace(pwmRequest,"beginning process to send new password to user");
-
-        if (!forgottenPasswordBean.getProgress().isAllPassed()) {
-            return;
-        }
-
-        final UserIdentity userIdentity = forgottenPasswordBean.getUserIdentity();
-        final ChaiUser theUser = pwmRequest.getPwmApplication().getProxiedChaiUser(userIdentity);
-
-        try { // try unlocking user
-            theUser.unlockPassword();
-            LOGGER.trace(pwmRequest, "unlock account succeeded");
-        } catch (ChaiOperationException e) {
-            final String errorMsg = "unable to unlock user " + theUser.getEntryDN() + " error: " + e.getMessage();
-            final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_UNLOCK_FAILURE,errorMsg);
-            LOGGER.error(pwmRequest.getPwmSession(), errorInformation.toDebugStr());
-            pwmRequest.respondWithError(errorInformation);
-            return;
-        }
-
-        try {
-            /*
-            final SessionAuthenticator sessionAuthenticator = new SessionAuthenticator(
-                    pwmApplication,
-                    pwmSession,
-                    PwmAuthenticationSource.FORGOTTEN_PASSWORD
-            );
-            sessionAuthenticator.authUserWithUnknownPassword(userIdentity,AuthenticationType.AUTH_FROM_PUBLIC_MODULE);
-            */
-            pwmSession.getLoginInfoBean().setAuthenticated(true);
-            pwmSession.getLoginInfoBean().getAuthFlags().add(AuthenticationType.AUTH_FROM_PUBLIC_MODULE);
-            pwmSession.getLoginInfoBean().setUserIdentity(userIdentity);
-
-            LOGGER.info(pwmRequest, "user successfully supplied password recovery responses, emailing new password to: " + theUser.getEntryDN());
-
-            // add post change actions
-            addPostChangeAction(pwmRequest, userIdentity);
-
-            // create newpassword
-            final PasswordData newPassword = RandomPasswordGenerator.createRandomPassword(pwmSession, pwmApplication);
-
-            // set the password
-            LOGGER.trace(pwmRequest.getPwmSession(), "setting user password to system generated random value");
-            PasswordUtility.setActorPassword(pwmSession, pwmApplication, newPassword);
-
-            if (recoveryAction == RecoveryAction.SENDNEWPW_AND_EXPIRE) {
-                LOGGER.debug(pwmSession, "marking user password as expired");
-                theUser.expirePassword();
-            }
-
-            // mark the event log
-            pwmApplication.getAuditManager().submit(AuditEvent.RECOVER_PASSWORD, pwmSession.getUserInfo(), pwmSession);
-
-            final MessageSendMethod messageSendMethod = forgottenPasswordProfile.readSettingAsEnum(PwmSetting.RECOVERY_SENDNEWPW_METHOD,MessageSendMethod.class);
-
-            // send email or SMS
-            final String toAddress = PasswordUtility.sendNewPassword(
-                    pwmSession.getUserInfo(),
-                    pwmApplication,
-                    pwmSession.getSessionManager().getMacroMachine(pwmApplication),
-                    newPassword,
-                    pwmSession.getSessionStateBean().getLocale(),
-                    messageSendMethod
-            );
-
-            pwmRequest.getPwmResponse().forwardToSuccessPage(Message.Success_PasswordSend, toAddress);
-        } catch (PwmException e) {
-            LOGGER.warn(pwmSession,"unexpected error setting new password during recovery process for user: " + e.getMessage());
-            pwmRequest.respondWithError(e.getErrorInformation());
-        } catch (ChaiOperationException e) {
-            final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_UNKNOWN,"unexpected ldap error while processing recovery action " + recoveryAction + ", error: " + e.getMessage());
-            LOGGER.warn(pwmSession,errorInformation.toDebugStr());
-            pwmRequest.respondWithError(errorInformation);
-        } finally {
-            clearForgottenPasswordBean(pwmRequest);
-            pwmSession.unauthenticateUser(pwmRequest);
-            pwmSession.getSessionStateBean().setPasswordModified(false);
-        }
-    }
 
 
     private static List<FormConfiguration> figureAttributeForm(
@@ -1134,7 +1043,7 @@ public class ForgottenPasswordServlet extends ControlledPwmServlet {
         return returnList;
     }
 
-    private static void addPostChangeAction(
+    static void addPostChangeAction(
             final PwmRequest pwmRequest,
             final UserIdentity userIdentity
     )

+ 114 - 0
server/src/main/java/password/pwm/http/servlet/forgottenpw/ForgottenPasswordUtil.java

@@ -26,6 +26,8 @@ import com.novell.ldapchai.ChaiUser;
 import com.novell.ldapchai.cr.Challenge;
 import com.novell.ldapchai.cr.ChallengeSet;
 import com.novell.ldapchai.cr.ResponseSet;
+import com.novell.ldapchai.exception.ChaiException;
+import com.novell.ldapchai.exception.ChaiOperationException;
 import com.novell.ldapchai.exception.ChaiUnavailableException;
 import com.novell.ldapchai.exception.ChaiValidationException;
 import password.pwm.AppProperty;
@@ -43,18 +45,25 @@ import password.pwm.config.profile.ForgottenPasswordProfile;
 import password.pwm.config.value.data.FormConfiguration;
 import password.pwm.error.ErrorInformation;
 import password.pwm.error.PwmError;
+import password.pwm.error.PwmException;
 import password.pwm.error.PwmOperationalException;
 import password.pwm.error.PwmUnrecoverableException;
 import password.pwm.http.PwmRequest;
 import password.pwm.http.bean.ForgottenPasswordBean;
 import password.pwm.http.filter.AuthenticationFilter;
+import password.pwm.i18n.Message;
 import password.pwm.ldap.UserInfo;
 import password.pwm.ldap.UserInfoFactory;
+import password.pwm.svc.event.AuditEvent;
+import password.pwm.svc.event.AuditRecord;
+import password.pwm.svc.event.AuditRecordFactory;
 import password.pwm.svc.stats.Statistic;
 import password.pwm.svc.stats.StatisticsManager;
 import password.pwm.svc.token.TokenPayload;
 import password.pwm.svc.token.TokenService;
 import password.pwm.svc.token.TokenType;
+import password.pwm.util.PasswordData;
+import password.pwm.util.RandomPasswordGenerator;
 import password.pwm.util.java.JavaHelper;
 import password.pwm.util.java.StringUtil;
 import password.pwm.util.java.TimeDuration;
@@ -488,4 +497,109 @@ class ForgottenPasswordUtil {
         return displayDestAddress;
     }
 
+    static void doActionSendNewPassword( final PwmRequest pwmRequest)
+            throws ChaiUnavailableException, IOException, ServletException, PwmUnrecoverableException
+    {
+        final PwmApplication pwmApplication = pwmRequest.getPwmApplication();
+        final ForgottenPasswordBean forgottenPasswordBean = ForgottenPasswordServlet.forgottenPasswordBean(pwmRequest);
+        final ForgottenPasswordProfile forgottenPasswordProfile = ForgottenPasswordServlet.forgottenPasswordProfile(pwmRequest);
+        final RecoveryAction recoveryAction = ForgottenPasswordUtil.getRecoveryAction(pwmApplication.getConfig(), forgottenPasswordBean);
+
+        LOGGER.trace(pwmRequest,"beginning process to send new password to user");
+
+        if (!forgottenPasswordBean.getProgress().isAllPassed()) {
+            return;
+        }
+
+        final UserIdentity userIdentity = forgottenPasswordBean.getUserIdentity();
+        final ChaiUser theUser = pwmRequest.getPwmApplication().getProxiedChaiUser(userIdentity);
+
+        try {
+            // try unlocking user
+            theUser.unlockPassword();
+            LOGGER.trace(pwmRequest, "unlock account succeeded");
+        } catch (ChaiOperationException e) {
+            final String errorMsg = "unable to unlock user " + theUser.getEntryDN() + " error: " + e.getMessage();
+            final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_UNLOCK_FAILURE,errorMsg);
+            LOGGER.error(pwmRequest.getPwmSession(), errorInformation.toDebugStr());
+            pwmRequest.respondWithError(errorInformation);
+            return;
+        }
+
+        try {
+            final UserInfo userInfo = UserInfoFactory.newUserInfoUsingProxy(
+                    pwmApplication,
+                    pwmRequest.getSessionLabel(),
+                    userIdentity,
+                    pwmRequest.getLocale()
+            );
+
+            LOGGER.info(pwmRequest, "user successfully supplied password recovery responses, emailing new password to: " + theUser.getEntryDN());
+
+            // add post change actions
+            ForgottenPasswordServlet.addPostChangeAction(pwmRequest, userIdentity);
+
+            // create new password
+            final PasswordData newPassword = RandomPasswordGenerator.createRandomPassword(
+                    pwmRequest.getSessionLabel(),
+                    userInfo.getPasswordPolicy(),
+                    pwmApplication
+            );
+            LOGGER.trace(pwmRequest, "generated random password value based on password policy for "
+                    + userIdentity.toDisplayString());
+
+
+            // set the password
+            try {
+                theUser.setPassword(newPassword.getStringValue());
+                LOGGER.trace(pwmRequest, "set user " + userIdentity.toDisplayString()
+                        + " password to system generated random value");
+            } catch (ChaiException e) {
+                throw PwmUnrecoverableException.fromChaiException(e);
+            }
+
+            if (recoveryAction == RecoveryAction.SENDNEWPW_AND_EXPIRE) {
+                LOGGER.debug(pwmRequest, "marking user " + userIdentity.toDisplayString() + " password as expired");
+                theUser.expirePassword();
+            }
+
+            // mark the event log
+            {
+                final AuditRecord auditRecord = new AuditRecordFactory(pwmApplication).createUserAuditRecord(
+                        AuditEvent.RECOVER_PASSWORD,
+                        userIdentity,
+                        pwmRequest.getSessionLabel()
+                );
+                pwmApplication.getAuditManager().submit(auditRecord);
+            }
+
+            final MessageSendMethod messageSendMethod = forgottenPasswordProfile.readSettingAsEnum(PwmSetting.RECOVERY_SENDNEWPW_METHOD,MessageSendMethod.class);
+
+            // send email or SMS
+            final String toAddress = PasswordUtility.sendNewPassword(
+                    userInfo,
+                    pwmApplication,
+                    newPassword,
+                    pwmRequest.getLocale(),
+                    messageSendMethod
+            );
+
+            pwmRequest.getPwmResponse().forwardToSuccessPage( Message.Success_PasswordSend, toAddress);
+        } catch (PwmException e) {
+            LOGGER.warn(pwmRequest, "unexpected error setting new password during recovery process for user: " + e.getMessage());
+            pwmRequest.respondWithError(e.getErrorInformation());
+        } catch (ChaiOperationException e) {
+            final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_UNKNOWN,"unexpected ldap error while processing recovery action " + recoveryAction + ", error: " + e.getMessage());
+            LOGGER.warn(pwmRequest, errorInformation.toDebugStr());
+            pwmRequest.respondWithError(errorInformation);
+        } finally {
+            ForgottenPasswordServlet.clearForgottenPasswordBean(pwmRequest);
+
+            // the user should not be authenticated, this is a safety method
+            pwmRequest.getPwmSession().unauthenticateUser(pwmRequest);
+
+            // the password set flag should not have been set, this is a safety method
+            pwmRequest.getPwmSession().getSessionStateBean().setPasswordModified(false);
+        }
+    }
 }

+ 4 - 4
server/src/main/java/password/pwm/http/servlet/helpdesk/HelpdeskClientDataBean.java

@@ -23,7 +23,7 @@
 package password.pwm.http.servlet.helpdesk;
 
 import password.pwm.config.option.HelpdeskClearResponseMode;
-import password.pwm.config.option.HelpdeskUIMode;
+import password.pwm.config.option.HelpDeskUIMode;
 import password.pwm.config.option.IdentityVerificationMethod;
 import password.pwm.config.option.MessageSendMethod;
 
@@ -37,7 +37,7 @@ public class HelpdeskClientDataBean implements Serializable {
     private Map<String,String> helpdesk_search_columns = new HashMap<>();
     private boolean helpdesk_setting_maskPasswords;
     private HelpdeskClearResponseMode helpdesk_setting_clearResponses;
-    private HelpdeskUIMode helpdesk_setting_PwUiMode;
+    private HelpDeskUIMode helpdesk_setting_PwUiMode;
     private MessageSendMethod helpdesk_setting_tokenSendMethod;
     private Map<String, ActionInformation> actions = new HashMap<>();
     private Map<String, Collection<IdentityVerificationMethod>> verificationMethods = new HashMap<>();
@@ -67,11 +67,11 @@ public class HelpdeskClientDataBean implements Serializable {
         this.helpdesk_setting_clearResponses = helpdesk_setting_clearResponses;
     }
 
-    public HelpdeskUIMode getHelpdesk_setting_PwUiMode() {
+    public HelpDeskUIMode getHelpdesk_setting_PwUiMode() {
         return helpdesk_setting_PwUiMode;
     }
 
-    public void setHelpdesk_setting_PwUiMode(final HelpdeskUIMode helpdesk_setting_PwUiMode) {
+    public void setHelpdesk_setting_PwUiMode(final HelpDeskUIMode helpdesk_setting_PwUiMode) {
         this.helpdesk_setting_PwUiMode = helpdesk_setting_PwUiMode;
     }
 

+ 4 - 4
server/src/main/java/password/pwm/http/servlet/helpdesk/HelpdeskDetailInfoBean.java

@@ -35,7 +35,7 @@ import lombok.Setter;
 import password.pwm.bean.ResponseInfoBean;
 import password.pwm.bean.UserIdentity;
 import password.pwm.config.PwmSetting;
-import password.pwm.config.option.HelpdeskUIMode;
+import password.pwm.config.option.HelpDeskUIMode;
 import password.pwm.config.option.ViewStatusFields;
 import password.pwm.config.profile.HelpdeskProfile;
 import password.pwm.config.profile.PwmPasswordRule;
@@ -280,9 +280,9 @@ public class HelpdeskDetailInfoBean implements Serializable {
         buttons.add(StandardButton.back);
 
         {
-            final HelpdeskUIMode uiMode =
-                    helpdeskProfile.readSettingAsEnum(PwmSetting.HELPDESK_SET_PASSWORD_MODE, HelpdeskUIMode.class);
-            if (uiMode != HelpdeskUIMode.none) {
+            final HelpDeskUIMode uiMode =
+                    helpdeskProfile.readSettingAsEnum(PwmSetting.HELPDESK_SET_PASSWORD_MODE, HelpDeskUIMode.class);
+            if (uiMode != HelpDeskUIMode.none) {
                 buttons.add(StandardButton.changePassword);
             }
         }

+ 54 - 24
server/src/main/java/password/pwm/http/servlet/helpdesk/HelpdeskServlet.java

@@ -34,15 +34,16 @@ import password.pwm.PwmApplication;
 import password.pwm.PwmConstants;
 import password.pwm.bean.EmailItemBean;
 import password.pwm.bean.UserIdentity;
-import password.pwm.config.value.data.ActionConfiguration;
 import password.pwm.config.Configuration;
-import password.pwm.config.value.data.FormConfiguration;
 import password.pwm.config.PwmSetting;
 import password.pwm.config.option.HelpdeskClearResponseMode;
-import password.pwm.config.option.HelpdeskUIMode;
+import password.pwm.config.option.HelpDeskUIMode;
 import password.pwm.config.option.IdentityVerificationMethod;
 import password.pwm.config.option.MessageSendMethod;
 import password.pwm.config.profile.HelpdeskProfile;
+import password.pwm.config.profile.PwmPasswordPolicy;
+import password.pwm.config.value.data.ActionConfiguration;
+import password.pwm.config.value.data.FormConfiguration;
 import password.pwm.error.ErrorInformation;
 import password.pwm.error.PwmError;
 import password.pwm.error.PwmException;
@@ -211,7 +212,7 @@ public class HelpdeskServlet extends ControlledPwmServlet {
         { /// detail page
             returnValues.setHelpdesk_setting_maskPasswords(helpdeskProfile.readSettingAsBoolean(PwmSetting.HELPDESK_PASSWORD_MASKVALUE));
             returnValues.setHelpdesk_setting_clearResponses(helpdeskProfile.readSettingAsEnum(PwmSetting.HELPDESK_CLEAR_RESPONSES, HelpdeskClearResponseMode.class));
-            returnValues.setHelpdesk_setting_PwUiMode(helpdeskProfile.readSettingAsEnum(PwmSetting.HELPDESK_SET_PASSWORD_MODE, HelpdeskUIMode.class));
+            returnValues.setHelpdesk_setting_PwUiMode(helpdeskProfile.readSettingAsEnum(PwmSetting.HELPDESK_SET_PASSWORD_MODE, HelpDeskUIMode.class));
             returnValues.setHelpdesk_setting_tokenSendMethod(helpdeskProfile.readSettingAsEnum(PwmSetting.HELPDESK_TOKEN_SEND_METHOD, MessageSendMethod.class));
         }
         { //actions
@@ -739,17 +740,17 @@ public class HelpdeskServlet extends ControlledPwmServlet {
         try {
             TokenService.TokenSender.sendToken(
                     TokenService.TokenSendInfo.builder()
-                    .pwmApplication( pwmRequest.getPwmApplication() )
-                    .userInfo( userInfo )
-                    .macroMachine( macroMachine )
-                    .configuredEmailSetting( emailItemBean )
-                    .tokenSendMethod( tokenSendMethod )
-                    .emailAddress( destEmailAddress )
-                    .smsNumber( userInfo.getUserSmsNumber() )
-                    .smsMessage( smsMessage )
-                    .tokenKey( tokenKey )
-                    .sessionLabel( pwmRequest.getSessionLabel() )
-                    .build()
+                            .pwmApplication( pwmRequest.getPwmApplication() )
+                            .userInfo( userInfo )
+                            .macroMachine( macroMachine )
+                            .configuredEmailSetting( emailItemBean )
+                            .tokenSendMethod( tokenSendMethod )
+                            .emailAddress( destEmailAddress )
+                            .smsNumber( userInfo.getUserSmsNumber() )
+                            .smsMessage( smsMessage )
+                            .tokenKey( tokenKey )
+                            .sessionLabel( pwmRequest.getSessionLabel() )
+                            .build()
             );
         } catch (PwmException e) {
             LOGGER.error(pwmRequest, e.getErrorInformation());
@@ -1124,8 +1125,8 @@ public class HelpdeskServlet extends ControlledPwmServlet {
         );
 
         {
-            final HelpdeskUIMode mode = helpdeskProfile.readSettingAsEnum(PwmSetting.HELPDESK_SET_PASSWORD_MODE, HelpdeskUIMode.class);
-            if (mode == HelpdeskUIMode.none) {
+            final HelpDeskUIMode mode = helpdeskProfile.readSettingAsEnum(PwmSetting.HELPDESK_SET_PASSWORD_MODE, HelpDeskUIMode.class);
+            if (mode == HelpDeskUIMode.none) {
                 throw new PwmUnrecoverableException(new ErrorInformation(PwmError.ERROR_SECURITY_VIOLATION,"setting "
                         + PwmSetting.HELPDESK_SET_PASSWORD_MODE.toMenuLocationDebug(helpdeskProfile.getIdentifier(), pwmRequest.getLocale())
                         + " must not be set to none"));
@@ -1153,13 +1154,13 @@ public class HelpdeskServlet extends ControlledPwmServlet {
     @ActionHandler(action = "setPassword")
     private ProcessStatus processSetPasswordAction(final PwmRequest pwmRequest) throws IOException, PwmUnrecoverableException, ChaiUnavailableException
     {
+        final HelpdeskProfile helpdeskProfile = pwmRequest.getPwmSession().getSessionManager().getHelpdeskProfile(pwmRequest.getPwmApplication());
+
         final RestSetPasswordServer.JsonInputData jsonInput = JsonUtil.deserialize(
                 pwmRequest.readRequestBodyAsString(),
                 RestSetPasswordServer.JsonInputData.class
         );
 
-        final PasswordData newPassword = new PasswordData(jsonInput.getPassword());
-        final HelpdeskProfile helpdeskProfile = pwmRequest.getPwmSession().getSessionManager().getHelpdeskProfile(pwmRequest.getPwmApplication());
         final UserIdentity userIdentity = UserIdentity.fromKey(jsonInput.getUsername(),pwmRequest.getPwmApplication());
         final ChaiUser chaiUser = getChaiUser(pwmRequest, helpdeskProfile, userIdentity);
         final UserInfo userInfo = UserInfoFactory.newUserInfo(
@@ -1171,16 +1172,45 @@ public class HelpdeskServlet extends ControlledPwmServlet {
         );
 
         HelpdeskServletUtil.checkIfUserIdentityViewable(pwmRequest, helpdeskProfile, userIdentity);
+        final HelpDeskUIMode mode = helpdeskProfile.readSettingAsEnum(PwmSetting.HELPDESK_SET_PASSWORD_MODE, HelpDeskUIMode.class);
 
-        {
-            final HelpdeskUIMode mode = helpdeskProfile.readSettingAsEnum(PwmSetting.HELPDESK_CLEAR_RESPONSES, HelpdeskUIMode.class);
-            if (mode == HelpdeskUIMode.none) {
+        if (mode == HelpDeskUIMode.none) {
+            throw new PwmUnrecoverableException(new ErrorInformation(PwmError.ERROR_SECURITY_VIOLATION,"setting "
+                    + PwmSetting.HELPDESK_SET_PASSWORD_MODE.toMenuLocationDebug(helpdeskProfile.getIdentifier(), pwmRequest.getLocale())
+                    + " must not be set to none"));
+        }
+
+
+        final PasswordData newPassword;
+        if (jsonInput.getPassword() == null) {
+            if (mode != HelpDeskUIMode.random) {
                 throw new PwmUnrecoverableException(new ErrorInformation(PwmError.ERROR_SECURITY_VIOLATION,"setting "
-                        + PwmSetting.HELPDESK_CLEAR_RESPONSES.toMenuLocationDebug(helpdeskProfile.getIdentifier(), pwmRequest.getLocale())
-                        + " must not be set to none"));
+                        + PwmSetting.HELPDESK_SET_PASSWORD_MODE.toMenuLocationDebug(helpdeskProfile.getIdentifier(), pwmRequest.getLocale())
+                        + " is set to " + mode + " and no password is included in request"));
             }
+            final PwmPasswordPolicy passwordPolicy = PasswordUtility.readPasswordPolicyForUser(
+                    pwmRequest.getPwmApplication(),
+                    pwmRequest.getSessionLabel(),
+                    userIdentity,
+                    chaiUser,
+                    pwmRequest.getLocale()
+            );
+            newPassword = RandomPasswordGenerator.createRandomPassword(
+                    pwmRequest.getSessionLabel(),
+                    passwordPolicy,
+                    pwmRequest.getPwmApplication()
+            );
+        } else {
+            if (mode == HelpDeskUIMode.random) {
+                throw new PwmUnrecoverableException(new ErrorInformation(PwmError.ERROR_SECURITY_VIOLATION,"setting "
+                        + PwmSetting.HELPDESK_SET_PASSWORD_MODE.toMenuLocationDebug(helpdeskProfile.getIdentifier(), pwmRequest.getLocale())
+                        + " is set to autogen yet a password is included in request"));
+            }
+
+            newPassword = new PasswordData(jsonInput.getPassword());
         }
 
+
         try {
             PasswordUtility.helpdeskSetUserPassword(
                     pwmRequest.getPwmSession(),

+ 9 - 5
server/src/main/java/password/pwm/util/operations/PasswordUtility.java

@@ -109,7 +109,6 @@ public class PasswordUtility {
     public static String sendNewPassword(
             final UserInfo userInfo,
             final PwmApplication pwmApplication,
-            final MacroMachine macroMachine,
             final PasswordData newPassword,
             final Locale userLocale,
             final MessageSendMethod messageSendMethod
@@ -120,6 +119,15 @@ public class PasswordUtility {
         final String smsNumber = userInfo.getUserSmsNumber();
         String returnToAddress = emailAddress;
 
+        final MacroMachine macroMachine;
+        {
+            final LoginInfoBean loginInfoBean = new LoginInfoBean();
+            loginInfoBean.setUserCurrentPassword(newPassword);
+            loginInfoBean.setUserIdentity(userInfo.getUserIdentity());
+            macroMachine = MacroMachine.forUser(pwmApplication, null, userInfo, loginInfoBean);
+        }
+
+
         final ErrorInformation error;
         switch (messageSendMethod) {
             case SMSONLY:
@@ -532,13 +540,9 @@ public class PasswordUtility {
                 messageSendMethod = forgottenPasswordProfile.readSettingAsEnum(PwmSetting.RECOVERY_SENDNEWPW_METHOD, MessageSendMethod.class);
 
             }
-            final LoginInfoBean loginInfoBean = new LoginInfoBean();
-            loginInfoBean.setUserCurrentPassword(newPassword);
-            final MacroMachine macroMachine = new MacroMachine(pwmApplication, pwmSession.getLabel(), userInfo, loginInfoBean);
             PasswordUtility.sendNewPassword(
                     userInfo,
                     pwmApplication,
-                    macroMachine,
                     newPassword,
                     pwmSession.getSessionStateBean().getLocale(),
                     messageSendMethod