Example #1
0
  private static Date determinePwdLastModified(
      final PwmApplication pwmApplication,
      final SessionLabel sessionLabel,
      final ChaiUser theUser,
      final UserIdentity userIdentity)
      throws ChaiUnavailableException, PwmUnrecoverableException {
    // fetch last password modification time from pwm last update attribute operation
    try {
      final Date chaiReadDate = theUser.readPasswordModificationDate();
      if (chaiReadDate != null) {
        LOGGER.trace(
            sessionLabel,
            "read last user password change timestamp (via chai) as: "
                + PwmConstants.DEFAULT_DATETIME_FORMAT.format(chaiReadDate));
        return chaiReadDate;
      }
    } catch (ChaiOperationException e) {
      LOGGER.error(
          sessionLabel,
          "unexpected error reading password last modified timestamp: " + e.getMessage());
    }

    final LdapProfile ldapProfile =
        pwmApplication.getConfig().getLdapProfiles().get(userIdentity.getLdapProfileID());
    final String pwmLastSetAttr =
        ldapProfile.readSettingAsString(PwmSetting.PASSWORD_LAST_UPDATE_ATTRIBUTE);
    if (pwmLastSetAttr != null && pwmLastSetAttr.length() > 0) {
      try {
        final Date pwmPwdLastModified = theUser.readDateAttribute(pwmLastSetAttr);
        LOGGER.trace(
            sessionLabel,
            "read pwmPasswordChangeTime as: "
                + (pwmPwdLastModified == null
                    ? "n/a"
                    : PwmConstants.DEFAULT_DATETIME_FORMAT.format(pwmPwdLastModified)));
        return pwmPwdLastModified;
      } catch (ChaiOperationException e) {
        LOGGER.error(
            sessionLabel,
            "error parsing password last modified PWM password value for user "
                + theUser.getEntryDN()
                + "; error: "
                + e.getMessage());
      }
    }

    LOGGER.debug(sessionLabel, "unable to determine time of user's last password modification");
    return null;
  }
Example #2
0
 public static Map<String, Date> readIndividualReplicaLastPasswordTimes(
     final PwmApplication pwmApplication,
     final SessionLabel sessionLabel,
     final UserIdentity userIdentity)
     throws PwmUnrecoverableException {
   final Map<String, Date> returnValue = new LinkedHashMap<>();
   final ChaiProvider chaiProvider =
       pwmApplication.getProxyChaiProvider(userIdentity.getLdapProfileID());
   final Collection<ChaiConfiguration> perReplicaConfigs =
       ChaiUtility.splitConfigurationPerReplica(
           chaiProvider.getChaiConfiguration(),
           Collections.singletonMap(ChaiSetting.FAILOVER_CONNECT_RETRIES, "1"));
   for (final ChaiConfiguration loopConfiguration : perReplicaConfigs) {
     final String loopReplicaUrl = loopConfiguration.getSetting(ChaiSetting.BIND_DN);
     ChaiProvider loopProvider = null;
     try {
       loopProvider = ChaiProviderFactory.createProvider(loopConfiguration);
       final Date lastModifiedDate =
           determinePwdLastModified(pwmApplication, sessionLabel, userIdentity);
       returnValue.put(loopReplicaUrl, lastModifiedDate);
     } catch (ChaiUnavailableException e) {
       LOGGER.error(sessionLabel, "unreachable server during replica password sync check");
       e.printStackTrace();
     } finally {
       if (loopProvider != null) {
         try {
           loopProvider.close();
         } catch (Exception e) {
           final String errorMsg =
               "error closing loopProvider to "
                   + loopReplicaUrl
                   + " while checking individual password sync status";
           LOGGER.error(sessionLabel, errorMsg);
         }
       }
     }
   }
   return returnValue;
 }
Example #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);
    }
  }