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;
}
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;
}
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();
}
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;
}
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"));
}
Aggregations