use of com.novell.ldapchai.exception.ChaiUnavailableException in project pwm by pwm-project.
the class UserInfoReader method readMultiStringAttributesImpl.
private Map<String, List<String>> readMultiStringAttributesImpl(final Collection<String> attributes) throws PwmUnrecoverableException {
if (chaiUser == null || attributes == null || attributes.isEmpty()) {
return Collections.emptyMap();
}
// figure out uncached attributes.
final Set<String> uncachedAttributes = new HashSet<>(attributes);
uncachedAttributes.removeAll(cacheMap.keySet());
// read uncached attributes into cache
if (!uncachedAttributes.isEmpty()) {
final Map<String, Map<String, List<String>>> results;
try {
results = chaiUser.getChaiProvider().searchMultiValues(chaiUser.getEntryDN(), "(objectclass=*)", uncachedAttributes, SearchScope.BASE);
} catch (ChaiOperationException e) {
final String msg = "ldap operational error while reading user data" + e.getMessage();
LOGGER.error(sessionLabel, msg);
throw new PwmUnrecoverableException(new ErrorInformation(PwmError.ERROR_LDAP_DATA_ERROR, msg));
} catch (ChaiUnavailableException e) {
throw PwmUnrecoverableException.fromChaiException(e);
}
if (results == null || results.size() != 1) {
final String msg = "ldap server did not return requested user entry " + chaiUser.getEntryDN() + " while attempting to read attribute data";
LOGGER.error(sessionLabel, msg);
throw new PwmUnrecoverableException(new ErrorInformation(PwmError.ERROR_LDAP_DATA_ERROR, msg));
}
final Map<String, List<String>> allAttributeValues = results.values().iterator().next();
for (final String attribute : uncachedAttributes) {
final List<String> attributeValues = allAttributeValues.get(attribute);
if (attributeValues == null) {
cacheMap.put(attribute, Collections.emptyList());
} else {
cacheMap.put(attribute, Collections.unmodifiableList(attributeValues));
}
}
}
// build result data from cache
final Map<String, List<String>> returnMap = new HashMap<>();
for (final String attribute : attributes) {
final List<String> cachedValue = cacheMap.get(attribute);
returnMap.put(attribute, cachedValue);
}
return Collections.unmodifiableMap(returnMap);
}
use of com.novell.ldapchai.exception.ChaiUnavailableException 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 com.novell.ldapchai.exception.ChaiUnavailableException in project pwm by pwm-project.
the class CrService method checkIfResponseConfigNeeded.
public boolean checkIfResponseConfigNeeded(final PwmApplication pwmApplication, final SessionLabel pwmSession, final UserIdentity userIdentity, final ChallengeSet challengeSet, final ResponseInfoBean responseInfoBean) throws ChaiUnavailableException, PwmUnrecoverableException {
LOGGER.trace(pwmSession, "beginning check to determine if responses need to be configured for user");
final Configuration config = pwmApplication.getConfig();
if (!config.readSettingAsBoolean(PwmSetting.CHALLENGE_ENABLE)) {
LOGGER.debug(pwmSession, "checkIfResponseConfigNeeded: response setup is disabled, so user is not required to setup responses");
return false;
}
if (!config.readSettingAsBoolean(PwmSetting.CHALLENGE_FORCE_SETUP)) {
LOGGER.debug(pwmSession, "checkIfResponseConfigNeeded: force response setup is disabled, so user is not required to setup responses");
return false;
}
if (!LdapPermissionTester.testUserPermissions(pwmApplication, pwmSession, userIdentity, config.readSettingAsUserPermission(PwmSetting.QUERY_MATCH_SETUP_RESPONSE))) {
LOGGER.debug(pwmSession, "checkIfResponseConfigNeeded: " + userIdentity + " does not have permission to setup responses");
return false;
}
if (!LdapPermissionTester.testUserPermissions(pwmApplication, pwmSession, userIdentity, config.readSettingAsUserPermission(PwmSetting.QUERY_MATCH_CHECK_RESPONSES))) {
LOGGER.debug(pwmSession, "checkIfResponseConfigNeeded: " + userIdentity + " is not eligible for checkIfResponseConfigNeeded due to query match");
return false;
}
// check to be sure there are actually challenges in the challenge set
if (challengeSet == null || challengeSet.getChallenges().isEmpty()) {
LOGGER.debug(pwmSession, "checkIfResponseConfigNeeded: no challenge sets configured for user " + userIdentity);
return false;
}
// ignore NMAS based CR set if so configured
if (responseInfoBean != null && (responseInfoBean.getDataStorageMethod() == DataStorageMethod.NMAS)) {
final boolean ignoreNmasCr = Boolean.parseBoolean(pwmApplication.getConfig().readAppProperty(AppProperty.NMAS_IGNORE_NMASCR_DURING_FORCECHECK));
if (ignoreNmasCr) {
LOGGER.debug(pwmSession, "checkIfResponseConfigNeeded: app property " + AppProperty.NMAS_IGNORE_NMASCR_DURING_FORCECHECK.getKey() + "=true and user's responses are in " + responseInfoBean.getDataStorageMethod() + " format, so forcing setup of new responses.");
return true;
}
}
try {
// check if responses exist
if (responseInfoBean == null) {
throw new Exception("no responses configured");
}
// check if responses meet the challenge set policy for the user
// usersResponses.meetsChallengeSetRequirements(challengeSet);
LOGGER.debug(pwmSession, "checkIfResponseConfigNeeded: " + userIdentity + " has good responses");
return false;
} catch (Exception e) {
LOGGER.debug(pwmSession, "checkIfResponseConfigNeeded: " + userIdentity + " does not have good responses: " + e.getMessage());
return true;
}
}
use of com.novell.ldapchai.exception.ChaiUnavailableException in project pwm by pwm-project.
the class PasswordUtility method readIndividualReplicaLastPasswordTimes.
public static Map<String, Instant> readIndividualReplicaLastPasswordTimes(final PwmApplication pwmApplication, final SessionLabel sessionLabel, final UserIdentity userIdentity) throws PwmUnrecoverableException {
final Map<String, Instant> 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 = pwmApplication.getLdapConnectionService().getChaiProviderFactory().newProvider(loopConfiguration);
final Instant 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;
}
use of com.novell.ldapchai.exception.ChaiUnavailableException in project pwm by pwm-project.
the class LdapCrOperator method clearResponses.
public void clearResponses(final UserIdentity userIdentity, final ChaiUser theUser, final String userGuid) throws PwmUnrecoverableException {
final LdapProfile ldapProfile = userIdentity.getLdapProfile(config);
final String ldapStorageAttribute = ldapProfile.readSettingAsString(PwmSetting.CHALLENGE_USER_ATTRIBUTE);
if (ldapStorageAttribute == null || ldapStorageAttribute.length() < 1) {
final String errorMsg = "ldap storage attribute is not configured, unable to clear user responses";
final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_INVALID_CONFIG, errorMsg);
throw new PwmUnrecoverableException(errorInformation);
}
try {
final String currentValue = theUser.readStringAttribute(ldapStorageAttribute);
if (currentValue != null && currentValue.length() > 0) {
theUser.deleteAttribute(ldapStorageAttribute, null);
}
LOGGER.info("cleared responses for user to chai-ldap format");
} catch (ChaiOperationException e) {
final String errorMsg;
if (e.getErrorCode() == ChaiError.NO_ACCESS) {
errorMsg = "permission error clearing responses to ldap attribute '" + ldapStorageAttribute + "', user does not appear to have correct permissions to clear responses: " + e.getMessage();
} else {
errorMsg = "error clearing responses to ldap attribute '" + ldapStorageAttribute + "': " + e.getMessage();
}
final ErrorInformation errorInfo = new ErrorInformation(PwmError.ERROR_WRITING_RESPONSES, errorMsg);
final PwmUnrecoverableException pwmOE = new PwmUnrecoverableException(errorInfo);
pwmOE.initCause(e);
throw pwmOE;
} catch (ChaiUnavailableException e) {
throw new PwmUnrecoverableException(new ErrorInformation(PwmError.ERROR_DIRECTORY_UNAVAILABLE, e.getMessage()));
}
}
Aggregations