Search in sources :

Example 1 with PwmPasswordPolicy

use of password.pwm.config.profile.PwmPasswordPolicy in project pwm by pwm-project.

the class LDAPStatusChecker method doLdapTestUserCheck.

@SuppressWarnings("checkstyle:MethodLength")
public List<HealthRecord> doLdapTestUserCheck(final Configuration config, final LdapProfile ldapProfile, final PwmApplication pwmApplication) {
    String testUserDN = ldapProfile.readSettingAsString(PwmSetting.LDAP_TEST_USER_DN);
    String proxyUserDN = ldapProfile.readSettingAsString(PwmSetting.LDAP_PROXY_USER_DN);
    final PasswordData proxyUserPW = ldapProfile.readSettingAsPassword(PwmSetting.LDAP_PROXY_USER_PASSWORD);
    final List<HealthRecord> returnRecords = new ArrayList<>();
    if (testUserDN == null || testUserDN.length() < 1) {
        return returnRecords;
    }
    try {
        testUserDN = ldapProfile.readCanonicalDN(pwmApplication, testUserDN);
        proxyUserDN = ldapProfile.readCanonicalDN(pwmApplication, proxyUserDN);
    } catch (PwmUnrecoverableException e) {
        final String msgString = e.getMessage();
        LOGGER.trace(SessionLabel.HEALTH_SESSION_LABEL, "unexpected error while testing test user (during object creation): message=" + msgString + " debug info: " + JavaHelper.readHostileExceptionMessage(e));
        returnRecords.add(HealthRecord.forMessage(HealthMessage.LDAP_TestUserUnexpected, PwmSetting.LDAP_TEST_USER_DN.toMenuLocationDebug(ldapProfile.getIdentifier(), PwmConstants.DEFAULT_LOCALE), msgString));
        return returnRecords;
    }
    if (proxyUserDN.equalsIgnoreCase(testUserDN)) {
        returnRecords.add(HealthRecord.forMessage(HealthMessage.LDAP_ProxyTestSameUser, PwmSetting.LDAP_TEST_USER_DN.toMenuLocationDebug(ldapProfile.getIdentifier(), PwmConstants.DEFAULT_LOCALE), PwmSetting.LDAP_PROXY_USER_DN.toMenuLocationDebug(ldapProfile.getIdentifier(), PwmConstants.DEFAULT_LOCALE)));
        return returnRecords;
    }
    ChaiUser theUser = null;
    ChaiProvider chaiProvider = null;
    try {
        try {
            chaiProvider = LdapOperationsHelper.createChaiProvider(pwmApplication, SessionLabel.HEALTH_SESSION_LABEL, ldapProfile, config, proxyUserDN, proxyUserPW);
            theUser = chaiProvider.getEntryFactory().newChaiUser(testUserDN);
        } catch (ChaiUnavailableException e) {
            returnRecords.add(HealthRecord.forMessage(HealthMessage.LDAP_TestUserUnavailable, PwmSetting.LDAP_TEST_USER_DN.toMenuLocationDebug(ldapProfile.getIdentifier(), PwmConstants.DEFAULT_LOCALE), e.getMessage()));
            return returnRecords;
        } catch (Throwable e) {
            final String msgString = e.getMessage();
            LOGGER.trace(SessionLabel.HEALTH_SESSION_LABEL, "unexpected error while testing test user (during object creation): message=" + msgString + " debug info: " + JavaHelper.readHostileExceptionMessage(e));
            returnRecords.add(HealthRecord.forMessage(HealthMessage.LDAP_TestUserUnexpected, PwmSetting.LDAP_TEST_USER_DN.toMenuLocationDebug(ldapProfile.getIdentifier(), PwmConstants.DEFAULT_LOCALE), msgString));
            return returnRecords;
        }
        try {
            theUser.readObjectClass();
        } catch (ChaiException e) {
            returnRecords.add(HealthRecord.forMessage(HealthMessage.LDAP_TestUserError, PwmSetting.LDAP_TEST_USER_DN.toMenuLocationDebug(ldapProfile.getIdentifier(), PwmConstants.DEFAULT_LOCALE), e.getMessage()));
            return returnRecords;
        }
        LOGGER.trace(SessionLabel.HEALTH_SESSION_LABEL, "beginning process to check ldap test user password read/write operations for profile " + ldapProfile.getIdentifier());
        try {
            final boolean readPwdEnabled = pwmApplication.getConfig().readSettingAsBoolean(PwmSetting.EDIRECTORY_READ_USER_PWD) && theUser.getChaiProvider().getDirectoryVendor() == DirectoryVendor.EDIRECTORY;
            if (readPwdEnabled) {
                try {
                    theUser.readPassword();
                } catch (Exception e) {
                    LOGGER.debug(SessionLabel.HEALTH_SESSION_LABEL, "error reading user password from directory " + e.getMessage());
                    returnRecords.add(HealthRecord.forMessage(HealthMessage.LDAP_TestUserReadPwError, PwmSetting.EDIRECTORY_READ_USER_PWD.toMenuLocationDebug(null, PwmConstants.DEFAULT_LOCALE), PwmSetting.LDAP_TEST_USER_DN.toMenuLocationDebug(ldapProfile.getIdentifier(), PwmConstants.DEFAULT_LOCALE), e.getMessage()));
                    return returnRecords;
                }
            } else {
                final Locale locale = PwmConstants.DEFAULT_LOCALE;
                final UserIdentity userIdentity = new UserIdentity(testUserDN, ldapProfile.getIdentifier());
                final PwmPasswordPolicy passwordPolicy = PasswordUtility.readPasswordPolicyForUser(pwmApplication, null, userIdentity, theUser, locale);
                boolean doPasswordChange = true;
                final int minLifetimeSeconds = passwordPolicy.getRuleHelper().readIntValue(PwmPasswordRule.MinimumLifetime);
                if (minLifetimeSeconds > 0) {
                    final Instant pwdLastModified = PasswordUtility.determinePwdLastModified(pwmApplication, SessionLabel.HEALTH_SESSION_LABEL, userIdentity);
                    final PasswordStatus passwordStatus;
                    {
                        final UserInfo userInfo = UserInfoFactory.newUserInfo(pwmApplication, SessionLabel.HEALTH_SESSION_LABEL, locale, userIdentity, chaiProvider);
                        passwordStatus = userInfo.getPasswordStatus();
                    }
                    {
                        final boolean withinMinLifetime = PasswordUtility.isPasswordWithinMinimumLifetimeImpl(theUser, SessionLabel.HEALTH_SESSION_LABEL, passwordPolicy, pwdLastModified, passwordStatus);
                        if (withinMinLifetime) {
                            LOGGER.trace(SessionLabel.HEALTH_SESSION_LABEL, "skipping test user password set due to password being within minimum lifetime");
                            doPasswordChange = false;
                        }
                    }
                }
                if (doPasswordChange) {
                    final PasswordData newPassword = RandomPasswordGenerator.createRandomPassword(null, passwordPolicy, pwmApplication);
                    try {
                        theUser.setPassword(newPassword.getStringValue());
                        LOGGER.debug(SessionLabel.HEALTH_SESSION_LABEL, "set random password on test user " + userIdentity.toDisplayString());
                    } catch (ChaiException e) {
                        returnRecords.add(HealthRecord.forMessage(HealthMessage.LDAP_TestUserWritePwError, PwmSetting.LDAP_TEST_USER_DN.toMenuLocationDebug(ldapProfile.getIdentifier(), PwmConstants.DEFAULT_LOCALE), e.getMessage()));
                        return returnRecords;
                    }
                }
            }
        } catch (Exception e) {
            final String msg = "error setting test user password: " + JavaHelper.readHostileExceptionMessage(e);
            LOGGER.error(SessionLabel.HEALTH_SESSION_LABEL, msg, e);
            returnRecords.add(HealthRecord.forMessage(HealthMessage.LDAP_TestUserUnexpected, PwmSetting.LDAP_TEST_USER_DN.toMenuLocationDebug(ldapProfile.getIdentifier(), PwmConstants.DEFAULT_LOCALE), msg));
            return returnRecords;
        }
        try {
            final UserIdentity userIdentity = new UserIdentity(theUser.getEntryDN(), ldapProfile.getIdentifier());
            final UserInfo userInfo = UserInfoFactory.newUserInfo(pwmApplication, SessionLabel.HEALTH_SESSION_LABEL, PwmConstants.DEFAULT_LOCALE, userIdentity, chaiProvider);
            userInfo.getPasswordStatus();
            userInfo.getAccountExpirationTime();
            userInfo.getResponseInfoBean();
            userInfo.getPasswordPolicy();
            userInfo.getChallengeProfile();
            userInfo.getProfileIDs();
            userInfo.getOtpUserRecord();
            userInfo.getUserGuid();
            userInfo.getUsername();
            userInfo.getUserEmailAddress();
            userInfo.getUserSmsNumber();
        } catch (PwmUnrecoverableException e) {
            returnRecords.add(new HealthRecord(HealthStatus.WARN, makeLdapTopic(ldapProfile, config), "unable to read test user data: " + e.getMessage()));
            return returnRecords;
        }
    } finally {
        if (chaiProvider != null) {
            try {
                chaiProvider.close();
            } catch (Exception e) {
            // ignore
            }
        }
    }
    returnRecords.add(HealthRecord.forMessage(HealthMessage.LDAP_TestUserOK, ldapProfile.getDisplayName(PwmConstants.DEFAULT_LOCALE)));
    return returnRecords;
}
Also used : Locale(java.util.Locale) ChaiUnavailableException(com.novell.ldapchai.exception.ChaiUnavailableException) UserIdentity(password.pwm.bean.UserIdentity) Instant(java.time.Instant) ArrayList(java.util.ArrayList) PwmUnrecoverableException(password.pwm.error.PwmUnrecoverableException) UserInfo(password.pwm.ldap.UserInfo) PwmUnrecoverableException(password.pwm.error.PwmUnrecoverableException) ChaiException(com.novell.ldapchai.exception.ChaiException) ChaiUnavailableException(com.novell.ldapchai.exception.ChaiUnavailableException) MalformedURLException(java.net.MalformedURLException) UnknownHostException(java.net.UnknownHostException) ChaiUser(com.novell.ldapchai.ChaiUser) ChaiProvider(com.novell.ldapchai.provider.ChaiProvider) PasswordData(password.pwm.util.PasswordData) PwmPasswordPolicy(password.pwm.config.profile.PwmPasswordPolicy) PasswordStatus(password.pwm.bean.PasswordStatus) ChaiException(com.novell.ldapchai.exception.ChaiException)

Example 2 with PwmPasswordPolicy

use of password.pwm.config.profile.PwmPasswordPolicy in project pwm by pwm-project.

the class LDAPAuthenticationRequest method setTempUserPassword.

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 = chaiProvider.getEntryFactory().newChaiUser(userIdentity.getUserDN());
    // 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");
        final PwmPasswordPolicy passwordPolicy = PasswordUtility.readPasswordPolicyForUser(pwmApplication, sessionLabel, userIdentity, chaiUser, PwmConstants.DEFAULT_LOCALE);
        // create random password for user
        final RandomPasswordGenerator.RandomGeneratorConfig randomGeneratorConfig = RandomPasswordGenerator.RandomGeneratorConfig.builder().seedlistPhrases(RandomPasswordGenerator.DEFAULT_SEED_PHRASES).passwordPolicy(passwordPolicy).build();
        final PasswordData currentPass = RandomPasswordGenerator.createRandomPassword(sessionLabel, randomGeneratorConfig, pwmApplication);
        try {
            final String oracleDSPrePasswordAllowChangeTime = oraclePreTemporaryPwHandler(chaiProvider, chaiUser);
            // write the random password for the user.
            chaiUser.setPassword(currentPass.getStringValue());
            oraclePostTemporaryPwHandler(chaiProvider, chaiUser, oracleDSPrePasswordAllowChangeTime);
            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;
}
Also used : ErrorInformation(password.pwm.error.ErrorInformation) ChaiProvider(com.novell.ldapchai.provider.ChaiProvider) ChaiUser(com.novell.ldapchai.ChaiUser) PasswordData(password.pwm.util.PasswordData) PwmPasswordPolicy(password.pwm.config.profile.PwmPasswordPolicy) RandomPasswordGenerator(password.pwm.util.RandomPasswordGenerator) PwmUnrecoverableException(password.pwm.error.PwmUnrecoverableException) ChaiOperationException(com.novell.ldapchai.exception.ChaiOperationException)

Example 3 with PwmPasswordPolicy

use of password.pwm.config.profile.PwmPasswordPolicy in project pwm by pwm-project.

the class UserInfoReader method getPasswordStatus.

@Override
public PasswordStatus getPasswordStatus() throws PwmUnrecoverableException {
    final Configuration config = pwmApplication.getConfig();
    final PasswordStatus.PasswordStatusBuilder passwordStatusBuilder = PasswordStatus.builder();
    final String userDN = chaiUser.getEntryDN();
    final PwmPasswordPolicy passwordPolicy = selfCachedReference.getPasswordPolicy();
    final long startTime = System.currentTimeMillis();
    LOGGER.trace(sessionLabel, "beginning password status check process for " + userDN);
    // check if password meets existing policy.
    if (passwordPolicy.getRuleHelper().readBooleanValue(PwmPasswordRule.EnforceAtLogin)) {
        if (currentPassword != null) {
            try {
                final PwmPasswordRuleValidator passwordRuleValidator = new PwmPasswordRuleValidator(pwmApplication, passwordPolicy);
                passwordRuleValidator.testPassword(currentPassword, null, selfCachedReference, chaiUser);
            } catch (PwmDataValidationException | PwmUnrecoverableException e) {
                LOGGER.debug(sessionLabel, "user " + userDN + " password does not conform to current password policy (" + e.getMessage() + "), marking as requiring change.");
                passwordStatusBuilder.violatesPolicy(true);
            } catch (ChaiUnavailableException e) {
                throw PwmUnrecoverableException.fromChaiException(e);
            }
        }
    }
    boolean ldapPasswordExpired = false;
    try {
        ldapPasswordExpired = chaiUser.isPasswordExpired();
        if (ldapPasswordExpired) {
            LOGGER.trace(sessionLabel, "password for " + userDN + " appears to be expired");
        } else {
            LOGGER.trace(sessionLabel, "password for " + userDN + " does not appear to be expired");
        }
    } catch (ChaiOperationException e) {
        LOGGER.info(sessionLabel, "error reading LDAP attributes for " + userDN + " while reading isPasswordExpired(): " + e.getMessage());
    } catch (ChaiUnavailableException e) {
        throw PwmUnrecoverableException.fromChaiException(e);
    }
    final Instant ldapPasswordExpirationTime = selfCachedReference.getPasswordExpirationTime();
    boolean preExpired = false;
    if (ldapPasswordExpirationTime != null) {
        final TimeDuration expirationInterval = TimeDuration.fromCurrent(ldapPasswordExpirationTime);
        LOGGER.trace(sessionLabel, "read password expiration time: " + JavaHelper.toIsoDate(ldapPasswordExpirationTime) + ", " + expirationInterval.asCompactString() + " from now");
        final TimeDuration diff = TimeDuration.fromCurrent(ldapPasswordExpirationTime);
        // now check to see if the user's expire time is within the 'preExpireTime' setting.
        final long preExpireMs = config.readSettingAsLong(PwmSetting.PASSWORD_EXPIRE_PRE_TIME) * 1000;
        if (diff.getTotalMilliseconds() > 0 && diff.getTotalMilliseconds() < preExpireMs) {
            LOGGER.debug(sessionLabel, "user " + userDN + " password will expire within " + diff.asCompactString() + ", marking as pre-expired");
            preExpired = true;
        } else if (ldapPasswordExpired) {
            preExpired = true;
            LOGGER.debug(sessionLabel, "user " + userDN + " password is expired, marking as pre-expired.");
        }
        // now check to see if the user's expire time is within the 'preWarnTime' setting.
        final long preWarnMs = config.readSettingAsLong(PwmSetting.PASSWORD_EXPIRE_WARN_TIME) * 1000;
        // don't check if the 'preWarnTime' setting is zero or less than the expirePreTime
        if (!ldapPasswordExpired && !preExpired) {
            if (!(preWarnMs == 0 || preWarnMs < preExpireMs)) {
                if (diff.getTotalMilliseconds() > 0 && diff.getTotalMilliseconds() < preWarnMs) {
                    LOGGER.debug(sessionLabel, "user " + userDN + " password will expire within " + diff.asCompactString() + ", marking as within warn period");
                    passwordStatusBuilder.warnPeriod(true);
                }
            }
        }
        passwordStatusBuilder.preExpired(preExpired);
    }
    LOGGER.debug(sessionLabel, "completed user password status check for " + userDN + " " + passwordStatusBuilder + " (" + TimeDuration.fromCurrent(startTime).asCompactString() + ")");
    passwordStatusBuilder.expired(ldapPasswordExpired);
    return passwordStatusBuilder.build();
}
Also used : ChaiUnavailableException(com.novell.ldapchai.exception.ChaiUnavailableException) FormConfiguration(password.pwm.config.value.data.FormConfiguration) Configuration(password.pwm.config.Configuration) Instant(java.time.Instant) PwmUnrecoverableException(password.pwm.error.PwmUnrecoverableException) PwmPasswordRuleValidator(password.pwm.util.PwmPasswordRuleValidator) PwmDataValidationException(password.pwm.error.PwmDataValidationException) PwmPasswordPolicy(password.pwm.config.profile.PwmPasswordPolicy) PasswordStatus(password.pwm.bean.PasswordStatus) TimeDuration(password.pwm.util.java.TimeDuration) ChaiOperationException(com.novell.ldapchai.exception.ChaiOperationException)

Example 4 with PwmPasswordPolicy

use of password.pwm.config.profile.PwmPasswordPolicy in project pwm by pwm-project.

the class PasswordUtility method readPasswordPolicyForUser.

public static PwmPasswordPolicy readPasswordPolicyForUser(final PwmApplication pwmApplication, final SessionLabel pwmSession, final UserIdentity userIdentity, final ChaiUser theUser, final Locale locale) throws PwmUnrecoverableException {
    final Instant startTime = Instant.now();
    final PasswordPolicySource ppSource = PasswordPolicySource.valueOf(pwmApplication.getConfig().readSettingAsString(PwmSetting.PASSWORD_POLICY_SOURCE));
    final PwmPasswordPolicy returnPolicy;
    switch(ppSource) {
        case MERGE:
            final PwmPasswordPolicy pwmPolicy = determineConfiguredPolicyProfileForUser(pwmApplication, pwmSession, userIdentity, locale);
            final PwmPasswordPolicy userPolicy = readLdapPasswordPolicy(pwmApplication, theUser);
            LOGGER.trace(pwmSession, "read user policy for '" + theUser.getEntryDN() + "', policy: " + userPolicy.toString());
            returnPolicy = pwmPolicy.merge(userPolicy);
            LOGGER.debug(pwmSession, "merged user password policy of '" + theUser.getEntryDN() + "' with PWM configured policy: " + returnPolicy.toString());
            break;
        case LDAP:
            returnPolicy = readLdapPasswordPolicy(pwmApplication, theUser);
            LOGGER.debug(pwmSession, "discovered assigned password policy for " + theUser.getEntryDN() + " " + returnPolicy.toString());
            break;
        case PWM:
            returnPolicy = determineConfiguredPolicyProfileForUser(pwmApplication, pwmSession, userIdentity, locale);
            break;
        default:
            throw new IllegalStateException("unknown policy source defined: " + ppSource.name());
    }
    LOGGER.trace(pwmSession, "readPasswordPolicyForUser completed in " + TimeDuration.fromCurrent(startTime).asCompactString());
    return returnPolicy;
}
Also used : PwmPasswordPolicy(password.pwm.config.profile.PwmPasswordPolicy) Instant(java.time.Instant)

Example 5 with PwmPasswordPolicy

use of password.pwm.config.profile.PwmPasswordPolicy in project pwm by pwm-project.

the class PasswordUtility method determineConfiguredPolicyProfileForUser.

public static PwmPasswordPolicy determineConfiguredPolicyProfileForUser(final PwmApplication pwmApplication, final SessionLabel pwmSession, final UserIdentity userIdentity, final Locale locale) throws PwmUnrecoverableException {
    final List<String> profiles = pwmApplication.getConfig().getPasswordProfileIDs();
    if (profiles.isEmpty()) {
        throw new PwmUnrecoverableException(new ErrorInformation(PwmError.ERROR_NO_PROFILE_ASSIGNED, "no password profiles are configured"));
    }
    for (final String profile : profiles) {
        final PwmPasswordPolicy loopPolicy = pwmApplication.getConfig().getPasswordPolicy(profile, locale);
        final List<UserPermission> userPermissions = loopPolicy.getUserPermissions();
        LOGGER.debug(pwmSession, "testing password policy profile '" + profile + "'");
        try {
            final boolean match = LdapPermissionTester.testUserPermissions(pwmApplication, pwmSession, userIdentity, userPermissions);
            if (match) {
                return loopPolicy;
            }
        } catch (PwmUnrecoverableException e) {
            LOGGER.error(pwmSession, "unexpected error while testing password policy profile '" + profile + "', error: " + e.getMessage());
        }
    }
    throw new PwmUnrecoverableException(new ErrorInformation(PwmError.ERROR_NO_PROFILE_ASSIGNED, "no challenge profile is configured"));
}
Also used : ErrorInformation(password.pwm.error.ErrorInformation) PwmPasswordPolicy(password.pwm.config.profile.PwmPasswordPolicy) PwmUnrecoverableException(password.pwm.error.PwmUnrecoverableException) UserPermission(password.pwm.config.value.data.UserPermission)

Aggregations

PwmPasswordPolicy (password.pwm.config.profile.PwmPasswordPolicy)21 ErrorInformation (password.pwm.error.ErrorInformation)10 PwmUnrecoverableException (password.pwm.error.PwmUnrecoverableException)8 ChaiUser (com.novell.ldapchai.ChaiUser)7 PasswordData (password.pwm.util.PasswordData)7 Instant (java.time.Instant)6 ArrayList (java.util.ArrayList)6 ChaiOperationException (com.novell.ldapchai.exception.ChaiOperationException)5 List (java.util.List)5 Locale (java.util.Locale)5 UserIdentity (password.pwm.bean.UserIdentity)5 ChaiUnavailableException (com.novell.ldapchai.exception.ChaiUnavailableException)4 ChaiProvider (com.novell.ldapchai.provider.ChaiProvider)4 UserInfo (password.pwm.ldap.UserInfo)4 PwmApplication (password.pwm.PwmApplication)3 Configuration (password.pwm.config.Configuration)3 PwmException (password.pwm.error.PwmException)3 PwmOperationalException (password.pwm.error.PwmOperationalException)3 PwmSession (password.pwm.http.PwmSession)3 MacroMachine (password.pwm.util.macro.MacroMachine)3