private PasswordData setTempUserPassword()
      throws ChaiUnavailableException, ImpossiblePasswordPolicyException,
          PwmUnrecoverableException {

    final boolean configAlwaysUseProxy =
        pwmApplication.getConfig().readSettingAsBoolean(PwmSetting.AD_USE_PROXY_FOR_FORGOTTEN);

    final ChaiProvider chaiProvider =
        pwmApplication.getProxyChaiProvider(userIdentity.getLdapProfileID());
    final ChaiUser chaiUser = ChaiFactory.createChaiUser(userIdentity.getUserDN(), chaiProvider);

    // try setting a random password on the account to authenticate.
    if (!configAlwaysUseProxy && requestedAuthType == AuthenticationType.AUTH_FROM_PUBLIC_MODULE) {
      log(PwmLogLevel.DEBUG, "attempting to set temporary random password");

      PwmPasswordPolicy passwordPolicy =
          PasswordUtility.readPasswordPolicyForUser(
              pwmApplication, sessionLabel, userIdentity, chaiUser, PwmConstants.DEFAULT_LOCALE);

      // create random password for user
      RandomPasswordGenerator.RandomGeneratorConfig randomGeneratorConfig =
          new RandomPasswordGenerator.RandomGeneratorConfig();
      randomGeneratorConfig.setSeedlistPhrases(RandomPasswordGenerator.DEFAULT_SEED_PHRASES);
      randomGeneratorConfig.setPasswordPolicy(passwordPolicy);

      final PasswordData currentPass =
          RandomPasswordGenerator.createRandomPassword(
              sessionLabel, randomGeneratorConfig, pwmApplication);

      try {
        final String oracleDS_PrePasswordAllowChangeTime =
            oraclePreTemporaryPwHandler(chaiProvider, chaiUser);

        // write the random password for the user.
        chaiUser.setPassword(currentPass.getStringValue());

        oraclePostTemporaryPwHandler(chaiProvider, chaiUser, oracleDS_PrePasswordAllowChangeTime);

        log(
            PwmLogLevel.INFO,
            "user "
                + userIdentity
                + " password has been set to random value to use for user authentication");
      } catch (ChaiOperationException e) {
        final String errorStr =
            "error setting random password for user " + userIdentity + " " + e.getMessage();
        log(PwmLogLevel.ERROR, errorStr);
        throw new PwmUnrecoverableException(
            new ErrorInformation(PwmError.ERROR_BAD_SESSION_PASSWORD, errorStr));
      }

      return currentPass;
    }
    return null;
  }
  private void handleCreateRequest(
      final PwmRequest pwmRequest, final GuestRegistrationBean guestRegistrationBean)
      throws PwmUnrecoverableException, ChaiUnavailableException, IOException, ServletException {
    final PwmSession pwmSession = pwmRequest.getPwmSession();
    final PwmApplication pwmApplication = pwmRequest.getPwmApplication();
    final LocalSessionStateBean ssBean = pwmSession.getSessionStateBean();
    final Configuration config = pwmApplication.getConfig();
    final Locale locale = ssBean.getLocale();

    final List<FormConfiguration> guestUserForm = config.readSettingAsForm(PwmSetting.GUEST_FORM);

    try {
      // read the values from the request
      final Map<FormConfiguration, String> formValues =
          FormUtility.readFormValuesFromRequest(pwmRequest, guestUserForm, locale);

      // read the expiration date from the request.
      final Date expirationDate = readExpirationFromRequest(pwmRequest);

      // see if the values meet form requirements.
      FormUtility.validateFormValues(config, formValues, locale);

      // read new user DN
      final String guestUserDN = determineUserDN(formValues, config);

      // read a chai provider to make the user
      final ChaiProvider provider = pwmSession.getSessionManager().getChaiProvider();

      // set up the user creation attributes
      final Map<String, String> createAttributes = new HashMap<>();
      for (final FormConfiguration formItem : formValues.keySet()) {
        LOGGER.debug(
            pwmSession,
            "Attribute from form: " + formItem.getName() + " = " + formValues.get(formItem));
        final String n = formItem.getName();
        final String v = formValues.get(formItem);
        if (n != null && n.length() > 0 && v != null && v.length() > 0) {
          createAttributes.put(n, v);
        }
      }

      // Write creator DN
      createAttributes.put(
          config.readSettingAsString(PwmSetting.GUEST_ADMIN_ATTRIBUTE),
          pwmSession.getUserInfoBean().getUserIdentity().getUserDN());

      // read the creation object classes.
      final Set<String> createObjectClasses =
          new HashSet<>(config.readSettingAsStringArray(PwmSetting.DEFAULT_OBJECT_CLASSES));

      provider.createEntry(guestUserDN, createObjectClasses, createAttributes);
      LOGGER.info(pwmSession, "created user object: " + guestUserDN);

      final ChaiUser theUser = ChaiFactory.createChaiUser(guestUserDN, provider);
      final UserIdentity userIdentity =
          new UserIdentity(
              guestUserDN, pwmSession.getUserInfoBean().getUserIdentity().getLdapProfileID());

      // write the expiration date:
      if (expirationDate != null) {
        final String expirationAttr =
            config.readSettingAsString(PwmSetting.GUEST_EXPIRATION_ATTRIBUTE);
        theUser.writeDateAttribute(expirationAttr, expirationDate);
      }

      final PwmPasswordPolicy passwordPolicy =
          PasswordUtility.readPasswordPolicyForUser(
              pwmApplication, pwmSession.getLabel(), userIdentity, theUser, locale);
      final PasswordData newPassword =
          RandomPasswordGenerator.createRandomPassword(
              pwmSession.getLabel(), passwordPolicy, pwmApplication);
      theUser.setPassword(newPassword.getStringValue());
      /*
      final UserInfoBean guestUserInfoBean = new UserInfoBean();
      final UserStatusReader userStatusReader = new UserStatusReader(pwmApplication);
      userStatusReader.populateUserInfoBean(
              pwmSession.getLabel(),
              guestUserInfoBean,
              pwmSession.getSessionStateBean().getLocale(),
              userIdentity,
              theUser.getChaiProvider()
      );
      */

      { // execute configured actions
        LOGGER.debug(pwmSession, "executing configured actions to user " + theUser.getEntryDN());
        final List<ActionConfiguration> actions =
            pwmApplication.getConfig().readSettingAsAction(PwmSetting.GUEST_WRITE_ATTRIBUTES);
        if (actions != null && !actions.isEmpty()) {
          final MacroMachine macroMachine = MacroMachine.forUser(pwmRequest, userIdentity);

          final ActionExecutor actionExecutor =
              new ActionExecutor.ActionExecutorSettings(pwmApplication, theUser)
                  .setExpandPwmMacros(true)
                  .setMacroMachine(macroMachine)
                  .createActionExecutor();

          actionExecutor.executeActions(actions, pwmSession);
        }
      }

      // everything good so forward to success page.
      this.sendGuestUserEmailConfirmation(pwmRequest, userIdentity);

      pwmApplication.getStatisticsManager().incrementValue(Statistic.NEW_USERS);

      pwmRequest.getPwmResponse().forwardToSuccessPage(Message.Success_CreateGuest);
    } catch (ChaiOperationException e) {
      final ErrorInformation info =
          new ErrorInformation(
              PwmError.ERROR_NEW_USER_FAILURE, "error creating user: " + e.getMessage());
      pwmRequest.setResponseError(info);
      LOGGER.warn(pwmSession, info);
      this.forwardToJSP(pwmRequest, guestRegistrationBean);
    } catch (PwmOperationalException e) {
      LOGGER.error(pwmSession, e.getErrorInformation().toDebugStr());
      pwmRequest.setResponseError(e.getErrorInformation());
      this.forwardToJSP(pwmRequest, guestRegistrationBean);
    }
  }
Beispiel #3
0
  public static void helpdeskSetUserPassword(
      final PwmSession pwmSession,
      final ChaiUser chaiUser,
      final UserIdentity userIdentity,
      final PwmApplication pwmApplication,
      final PasswordData newPassword)
      throws ChaiUnavailableException, PwmUnrecoverableException, PwmOperationalException {
    final SessionLabel sessionLabel = pwmSession.getLabel();

    if (!pwmSession.isAuthenticated()) {
      final String errorMsg = "attempt to helpdeskSetUserPassword, but user is not authenticated";
      final ErrorInformation errorInformation =
          new ErrorInformation(PwmError.ERROR_UNAUTHORIZED, errorMsg);
      throw new PwmOperationalException(errorInformation);
    }

    final HelpdeskProfile helpdeskProfile =
        pwmSession.getSessionManager().getHelpdeskProfile(pwmApplication);
    if (helpdeskProfile == null) {
      final String errorMsg =
          "attempt to helpdeskSetUserPassword, but user does not have helpdesk permission";
      final ErrorInformation errorInformation =
          new ErrorInformation(PwmError.ERROR_UNAUTHORIZED, errorMsg);
      throw new PwmOperationalException(errorInformation);
    }

    try {
      chaiUser.setPassword(newPassword.getStringValue());
    } catch (ChaiPasswordPolicyException e) {
      final String errorMsg =
          "error setting password for user '" + chaiUser.getEntryDN() + "'' " + e.toString();
      final PwmError pwmError = PwmError.forChaiError(e.getErrorCode());
      final ErrorInformation error =
          new ErrorInformation(
              pwmError == null ? PwmError.PASSWORD_UNKNOWN_VALIDATION : pwmError, errorMsg);
      throw new PwmOperationalException(error);
    } catch (ChaiOperationException e) {
      final String errorMsg =
          "error setting password for user '" + chaiUser.getEntryDN() + "'' " + e.getMessage();
      final PwmError pwmError =
          PwmError.forChaiError(e.getErrorCode()) == null
              ? PwmError.ERROR_UNKNOWN
              : PwmError.forChaiError(e.getErrorCode());
      final ErrorInformation error = new ErrorInformation(pwmError, errorMsg);
      throw new PwmOperationalException(error);
    }

    // at this point the password has been changed, so log it.
    LOGGER.info(
        sessionLabel,
        "user '"
            + pwmSession.getUserInfoBean().getUserIdentity()
            + "' successfully changed password for "
            + chaiUser.getEntryDN());

    // create a proxy user object for pwm to update/read the user.
    final ChaiUser proxiedUser = pwmApplication.getProxiedChaiUser(userIdentity);

    // mark the event log
    {
      final HelpdeskAuditRecord auditRecord =
          pwmApplication
              .getAuditManager()
              .createHelpdeskAuditRecord(
                  AuditEvent.HELPDESK_SET_PASSWORD,
                  pwmSession.getUserInfoBean().getUserIdentity(),
                  null,
                  userIdentity,
                  pwmSession.getSessionStateBean().getSrcAddress(),
                  pwmSession.getSessionStateBean().getSrcHostname());
      pwmApplication.getAuditManager().submit(auditRecord);
    }

    // update statistics
    pwmApplication.getStatisticsManager().updateEps(Statistic.EpsType.PASSWORD_CHANGES, 1);
    pwmApplication.getStatisticsManager().incrementValue(Statistic.HELPDESK_PASSWORD_SET);

    // create a uib for end user
    final UserInfoBean userInfoBean = new UserInfoBean();
    final UserStatusReader userStatusReader =
        new UserStatusReader(pwmApplication, pwmSession.getLabel());
    userStatusReader.populateUserInfoBean(
        userInfoBean,
        pwmSession.getSessionStateBean().getLocale(),
        userIdentity,
        proxiedUser.getChaiProvider());

    { // execute configured actions
      LOGGER.debug(
          sessionLabel,
          "executing changepassword and helpdesk post password change writeAttributes to user "
              + userIdentity);
      final List<ActionConfiguration> actions = new ArrayList<>();
      actions.addAll(
          pwmApplication
              .getConfig()
              .readSettingAsAction(PwmSetting.CHANGE_PASSWORD_WRITE_ATTRIBUTES));
      actions.addAll(
          helpdeskProfile.readSettingAsAction(
              PwmSetting.HELPDESK_POST_SET_PASSWORD_WRITE_ATTRIBUTES));
      if (!actions.isEmpty()) {

        final ActionExecutor actionExecutor =
            new ActionExecutor.ActionExecutorSettings(pwmApplication, userIdentity)
                .setMacroMachine(
                    MacroMachine.forUser(
                        pwmApplication,
                        pwmSession.getSessionStateBean().getLocale(),
                        sessionLabel,
                        userIdentity))
                .setExpandPwmMacros(true)
                .createActionExecutor();

        actionExecutor.executeActions(actions, pwmSession);
      }
    }

    final HelpdeskClearResponseMode settingClearResponses =
        HelpdeskClearResponseMode.valueOf(
            helpdeskProfile.readSettingAsString(PwmSetting.HELPDESK_CLEAR_RESPONSES));
    if (settingClearResponses == HelpdeskClearResponseMode.yes) {
      final String userGUID =
          LdapOperationsHelper.readLdapGuidValue(pwmApplication, sessionLabel, userIdentity, false);
      pwmApplication.getCrService().clearResponses(pwmSession, proxiedUser, userGUID);

      // mark the event log
      final HelpdeskAuditRecord auditRecord =
          pwmApplication
              .getAuditManager()
              .createHelpdeskAuditRecord(
                  AuditEvent.HELPDESK_CLEAR_RESPONSES,
                  pwmSession.getUserInfoBean().getUserIdentity(),
                  null,
                  userIdentity,
                  pwmSession.getSessionStateBean().getSrcAddress(),
                  pwmSession.getSessionStateBean().getSrcHostname());
      pwmApplication.getAuditManager().submit(auditRecord);
    }

    // send email notification
    sendChangePasswordHelpdeskEmailNotice(pwmSession, pwmApplication, userInfoBean);

    // expire if so configured
    if (helpdeskProfile.readSettingAsBoolean(PwmSetting.HELPDESK_FORCE_PW_EXPIRATION)) {
      LOGGER.trace(
          pwmSession, "preparing to expire password for user " + userIdentity.toDisplayString());
      try {
        proxiedUser.expirePassword();
      } catch (ChaiOperationException e) {
        LOGGER.warn(
            pwmSession,
            "error while forcing password expiration for user "
                + userIdentity.toDisplayString()
                + ", error: "
                + e.getMessage());
        e.printStackTrace();
      }
    }

    // send password
    final boolean sendPassword =
        helpdeskProfile.readSettingAsBoolean(PwmSetting.HELPDESK_SEND_PASSWORD);
    if (sendPassword) {
      final MessageSendMethod messageSendMethod;
      {
        final String profileID =
            ProfileUtility.discoverProfileIDforUser(
                pwmApplication, sessionLabel, userIdentity, ProfileType.ForgottenPassword);
        final ForgottenPasswordProfile forgottenPasswordProfile =
            pwmApplication.getConfig().getForgottenPasswordProfiles().get(profileID);
        messageSendMethod =
            forgottenPasswordProfile.readSettingAsEnum(
                PwmSetting.RECOVERY_SENDNEWPW_METHOD, MessageSendMethod.class);
      }
      final UserDataReader userDataReader = new LdapUserDataReader(userIdentity, chaiUser);
      final LoginInfoBean loginInfoBean = new LoginInfoBean();
      loginInfoBean.setUserCurrentPassword(newPassword);
      final MacroMachine macroMachine =
          new MacroMachine(
              pwmApplication, pwmSession.getLabel(), userInfoBean, loginInfoBean, userDataReader);
      PasswordUtility.sendNewPassword(
          userInfoBean,
          pwmApplication,
          macroMachine,
          newPassword,
          pwmSession.getSessionStateBean().getLocale(),
          messageSendMethod);
    }
  }
Beispiel #4
0
  /**
   * This is the entry point under which all password changes are managed. The following is the
   * general procedure when this method is invoked.
   *
   * <ul>
   *   <li>password is checked against PWM password requirement
   *   <li>ldap password set is attempted<br>
   *       <br>
   *       if successful:
   *       <ul>
   *         <li>uiBean is updated with old and new passwords
   *         <li>uiBean's password expire flag is set to false
   *         <li>any configured external methods are invoked
   *         <li>user email notification is sent
   *         <li>return true
   *       </ul>
   *       <br>
   *       if unsuccessful
   *       <ul>
   *         <li>ssBean is updated with appropriate error
   *         <li>return false
   *       </ul>
   * </ul>
   *
   * @param newPassword the new password that is being set.
   * @param pwmSession beanmanager for config and user info lookup
   * @throws com.novell.ldapchai.exception.ChaiUnavailableException if the ldap directory is not
   *     unavailable
   * @throws password.pwm.error.PwmUnrecoverableException if user is not authenticated
   */
  public static void setActorPassword(
      final PwmSession pwmSession,
      final PwmApplication pwmApplication,
      final PasswordData newPassword)
      throws ChaiUnavailableException, PwmUnrecoverableException, PwmOperationalException {
    final UserInfoBean uiBean = pwmSession.getUserInfoBean();

    if (!pwmSession
        .getSessionManager()
        .checkPermission(pwmApplication, Permission.CHANGE_PASSWORD)) {
      final String errorMsg =
          "attempt to setActorPassword, but user does not have password change permission";
      final ErrorInformation errorInformation =
          new ErrorInformation(PwmError.ERROR_UNAUTHORIZED, errorMsg);
      throw new PwmOperationalException(errorInformation);
    }

    // double check to make sure password meets PWM rule requirements.  This should
    // have been done before setActorPassword() is invoked, so it should be redundant
    // but we do it just in case.
    try {
      final PwmPasswordRuleValidator pwmPasswordRuleValidator =
          new PwmPasswordRuleValidator(pwmApplication, uiBean.getPasswordPolicy());
      pwmPasswordRuleValidator.testPassword(
          newPassword, null, uiBean, pwmSession.getSessionManager().getActor(pwmApplication));
    } catch (PwmDataValidationException e) {
      final String errorMsg =
          "attempt to setActorPassword, but password does not pass local policy validator";
      final ErrorInformation errorInformation =
          new ErrorInformation(e.getErrorInformation().getError(), errorMsg);
      throw new PwmOperationalException(errorInformation);
    }

    // retrieve the user's old password from the userInfoBean in the session
    final PasswordData oldPassword = pwmSession.getLoginInfoBean().getUserCurrentPassword();

    boolean setPasswordWithoutOld = false;
    if (oldPassword == null) {
      if (pwmSession
              .getSessionManager()
              .getActor(pwmApplication)
              .getChaiProvider()
              .getDirectoryVendor()
          == ChaiProvider.DIRECTORY_VENDOR.MICROSOFT_ACTIVE_DIRECTORY) {
        setPasswordWithoutOld = true;
      }
    }

    if (!setPasswordWithoutOld) {
      // Check to make sure we actually have an old password
      if (oldPassword == null) {
        final String errorMsg = "cannot set password for user, old password is not available";
        final ErrorInformation errorInformation =
            new ErrorInformation(PwmError.ERROR_WRONGPASSWORD, errorMsg);
        throw new PwmOperationalException(errorInformation);
      }
    }

    try {
      final ChaiProvider provider = pwmSession.getSessionManager().getChaiProvider();
      final ChaiUser theUser =
          ChaiFactory.createChaiUser(
              pwmSession.getUserInfoBean().getUserIdentity().getUserDN(), provider);
      final boolean boundAsSelf =
          theUser
              .getEntryDN()
              .equals(provider.getChaiConfiguration().getSetting(ChaiSetting.BIND_DN));
      LOGGER.trace(
          pwmSession,
          "preparing to setActorPassword for '"
              + theUser.getEntryDN()
              + "', bindAsSelf="
              + boundAsSelf
              + ", authType="
              + pwmSession.getLoginInfoBean().getType());
      if (setPasswordWithoutOld) {
        theUser.setPassword(newPassword.getStringValue(), true);
      } else {
        theUser.changePassword(oldPassword.getStringValue(), newPassword.getStringValue());
      }
    } catch (ChaiPasswordPolicyException e) {
      final String errorMsg =
          "error setting password for user '" + uiBean.getUserIdentity() + "'' " + e.toString();
      final PwmError pwmError = PwmError.forChaiError(e.getErrorCode());
      final ErrorInformation error =
          new ErrorInformation(
              pwmError == null ? PwmError.PASSWORD_UNKNOWN_VALIDATION : pwmError, errorMsg);
      throw new PwmOperationalException(error);
    } catch (ChaiOperationException e) {
      final String errorMsg =
          "error setting password for user '" + uiBean.getUserIdentity() + "'' " + e.getMessage();
      final PwmError pwmError =
          PwmError.forChaiError(e.getErrorCode()) == null
              ? PwmError.ERROR_UNKNOWN
              : PwmError.forChaiError(e.getErrorCode());
      final ErrorInformation error = new ErrorInformation(pwmError, errorMsg);
      throw new PwmOperationalException(error);
    }

    // at this point the password has been changed, so log it.
    LOGGER.info(
        pwmSession, "user '" + uiBean.getUserIdentity() + "' successfully changed password");

    // update the session state bean's password modified flag
    pwmSession.getSessionStateBean().setPasswordModified(true);

    // update the login info bean with the user's new password
    pwmSession.getLoginInfoBean().setUserCurrentPassword(newPassword);

    // close any outstanding ldap connections (since they cache the old password)
    pwmSession
        .getSessionManager()
        .updateUserPassword(pwmApplication, uiBean.getUserIdentity(), newPassword);

    // clear the "requires new password flag"
    uiBean.setRequiresNewPassword(false);

    // mark the auth type as authenticatePd now that we have the user's natural password.
    pwmSession.getLoginInfoBean().setType(AuthenticationType.AUTHENTICATED);

    // update the uibean's "password expired flag".
    final UserStatusReader userStatusReader =
        new UserStatusReader(pwmApplication, pwmSession.getLabel());
    uiBean.setPasswordState(
        userStatusReader.readPasswordStatus(
            pwmSession.getSessionManager().getActor(pwmApplication),
            uiBean.getPasswordPolicy(),
            uiBean,
            newPassword));

    // create a proxy user object for pwm to update/read the user.
    final ChaiUser proxiedUser = pwmSession.getSessionManager().getActor(pwmApplication);

    // update statistics
    {
      pwmApplication.getStatisticsManager().incrementValue(Statistic.PASSWORD_CHANGES);
      pwmApplication.getStatisticsManager().updateEps(Statistic.EpsType.PASSWORD_CHANGES, 1);
      final int passwordStrength =
          PasswordUtility.judgePasswordStrength(newPassword.getStringValue());
      pwmApplication
          .getStatisticsManager()
          .updateAverageValue(Statistic.AVG_PASSWORD_STRENGTH, passwordStrength);
    }

    // add the old password to the global history list (if the old password is known)
    if (oldPassword != null
        && pwmApplication
            .getConfig()
            .readSettingAsBoolean(PwmSetting.PASSWORD_SHAREDHISTORY_ENABLE)) {
      pwmApplication.getSharedHistoryManager().addWord(pwmSession, oldPassword.getStringValue());
    }

    // invoke post password change actions
    invokePostChangePasswordActions(pwmSession, newPassword.getStringValue());

    { // execute configured actions
      LOGGER.debug(pwmSession, "executing configured actions to user " + proxiedUser.getEntryDN());
      final List<ActionConfiguration> configValues =
          pwmApplication
              .getConfig()
              .readSettingAsAction(PwmSetting.CHANGE_PASSWORD_WRITE_ATTRIBUTES);
      if (configValues != null && !configValues.isEmpty()) {
        final LoginInfoBean clonedLoginInfoBean =
            JsonUtil.cloneUsingJson(pwmSession.getLoginInfoBean(), LoginInfoBean.class);
        clonedLoginInfoBean.setUserCurrentPassword(newPassword);

        final MacroMachine macroMachine =
            new MacroMachine(
                pwmApplication,
                pwmSession.getLabel(),
                pwmSession.getUserInfoBean(),
                clonedLoginInfoBean,
                pwmSession.getSessionManager().getUserDataReader(pwmApplication));

        final ActionExecutor actionExecutor =
            new ActionExecutor.ActionExecutorSettings(pwmApplication, uiBean.getUserIdentity())
                .setMacroMachine(macroMachine)
                .setExpandPwmMacros(true)
                .createActionExecutor();
        actionExecutor.executeActions(configValues, pwmSession);
      }
    }

    // update the current last password update field in ldap
    LdapOperationsHelper.updateLastPasswordUpdateAttribute(
        pwmApplication, pwmSession.getLabel(), uiBean.getUserIdentity());
  }