use of password.pwm.error.PwmError in project pwm by pwm-project.
the class FormUtility method populateFormMapFromLdap.
public static Map<FormConfiguration, List<String>> populateFormMapFromLdap(final List<FormConfiguration> formFields, final SessionLabel sessionLabel, final UserInfo userInfo, final Flag... flags) throws PwmUnrecoverableException {
final boolean includeNulls = JavaHelper.enumArrayContainsValue(flags, Flag.ReturnEmptyValues);
final List<String> formFieldNames = FormConfiguration.convertToListOfNames(formFields);
LOGGER.trace(sessionLabel, "preparing to load form data from ldap for fields " + JsonUtil.serializeCollection(formFieldNames));
final Map<String, List<String>> dataFromLdap = new LinkedHashMap<>();
try {
for (final FormConfiguration formConfiguration : formFields) {
if (formConfiguration.getSource() == FormConfiguration.Source.ldap || formConfiguration.getSource() == null) {
final String attribute = formConfiguration.getName();
if (formConfiguration.isMultivalue()) {
final List<String> values = userInfo.readMultiStringAttribute(attribute);
if (includeNulls || (values != null && !values.isEmpty())) {
dataFromLdap.put(attribute, values);
}
} else {
final String value = userInfo.readStringAttribute(attribute);
if (includeNulls || (value != null)) {
dataFromLdap.put(attribute, Collections.singletonList(value));
}
}
}
}
} catch (Exception e) {
PwmError error = null;
if (e instanceof ChaiException) {
error = PwmError.forChaiError(((ChaiException) e).getErrorCode());
}
if (error == null || error == PwmError.ERROR_UNKNOWN) {
error = PwmError.ERROR_LDAP_DATA_ERROR;
}
final ErrorInformation errorInformation = new ErrorInformation(error, "error reading current profile values: " + e.getMessage());
LOGGER.error(sessionLabel, errorInformation.getDetailedErrorMsg());
throw new PwmUnrecoverableException(errorInformation);
}
final Map<FormConfiguration, List<String>> returnMap = new LinkedHashMap<>();
for (final FormConfiguration formItem : formFields) {
final String attrName = formItem.getName();
if (dataFromLdap.containsKey(attrName)) {
final List<String> values = new ArrayList<>();
for (final String value : dataFromLdap.get(attrName)) {
final String parsedValue = parseInputValueToFormValue(formItem, value);
values.add(parsedValue);
LOGGER.trace(sessionLabel, "loaded value for form item '" + attrName + "' with value=" + value);
}
returnMap.put(formItem, values);
}
}
return returnMap;
}
use of password.pwm.error.PwmError in project pwm by pwm-project.
the class RandomPasswordGenerator method modifyPasswordBasedOnErrors.
private static void modifyPasswordBasedOnErrors(final StringBuilder password, final List<ErrorInformation> errors, final SeedMachine seedMachine) {
if (password == null || errors == null || errors.isEmpty()) {
return;
}
final Set<PwmError> errorMessages = new HashSet<>();
for (final ErrorInformation errorInfo : errors) {
errorMessages.add(errorInfo.getError());
}
boolean touched = false;
if (errorMessages.contains(PwmError.PASSWORD_TOO_SHORT)) {
addRandChar(password, seedMachine.getAllChars());
touched = true;
}
if (errorMessages.contains(PwmError.PASSWORD_TOO_LONG)) {
password.deleteCharAt(RANDOM.nextInt(password.length()));
touched = true;
}
if (errorMessages.contains(PwmError.PASSWORD_FIRST_IS_NUMERIC) || errorMessages.contains(PwmError.PASSWORD_FIRST_IS_SPECIAL)) {
password.deleteCharAt(0);
touched = true;
}
if (errorMessages.contains(PwmError.PASSWORD_LAST_IS_NUMERIC) || errorMessages.contains(PwmError.PASSWORD_LAST_IS_SPECIAL)) {
password.deleteCharAt(password.length() - 1);
touched = true;
}
if (errorMessages.contains(PwmError.PASSWORD_NOT_ENOUGH_NUM)) {
addRandChar(password, seedMachine.getNumChars());
touched = true;
}
if (errorMessages.contains(PwmError.PASSWORD_NOT_ENOUGH_SPECIAL)) {
addRandChar(password, seedMachine.getSpecialChars());
touched = true;
}
if (errorMessages.contains(PwmError.PASSWORD_NOT_ENOUGH_UPPER)) {
addRandChar(password, seedMachine.getUpperChars());
touched = true;
}
if (errorMessages.contains(PwmError.PASSWORD_NOT_ENOUGH_LOWER)) {
addRandChar(password, seedMachine.getLowerChars());
touched = true;
}
PasswordCharCounter passwordCharCounter = new PasswordCharCounter(password.toString());
if (errorMessages.contains(PwmError.PASSWORD_TOO_MANY_NUMERIC) && passwordCharCounter.getNumericCharCount() > 0) {
deleteRandChar(password, passwordCharCounter.getNumericChars());
touched = true;
passwordCharCounter = new PasswordCharCounter(password.toString());
}
if (errorMessages.contains(PwmError.PASSWORD_TOO_MANY_SPECIAL) && passwordCharCounter.getSpecialCharsCount() > 0) {
deleteRandChar(password, passwordCharCounter.getSpecialChars());
touched = true;
passwordCharCounter = new PasswordCharCounter(password.toString());
}
if (errorMessages.contains(PwmError.PASSWORD_TOO_MANY_UPPER) && passwordCharCounter.getUpperCharCount() > 0) {
deleteRandChar(password, passwordCharCounter.getUpperChars());
touched = true;
passwordCharCounter = new PasswordCharCounter(password.toString());
}
if (errorMessages.contains(PwmError.PASSWORD_TOO_MANY_LOWER) && passwordCharCounter.getLowerCharCount() > 0) {
deleteRandChar(password, passwordCharCounter.getLowerChars());
touched = true;
}
if (errorMessages.contains(PwmError.PASSWORD_TOO_WEAK)) {
randomPasswordModifier(password, seedMachine);
touched = true;
}
if (!touched) {
// dunno whats wrong, try just deleting a RANDOM char, and hope a re-insert will add another.
randomPasswordModifier(password, seedMachine);
}
}
use of password.pwm.error.PwmError in project pwm by pwm-project.
the class PwmPasswordRuleValidator method testPassword.
public boolean testPassword(final PasswordData password, final PasswordData oldPassword, final UserInfo userInfo, final ChaiUser user) throws PwmDataValidationException, ChaiUnavailableException, PwmUnrecoverableException {
final List<ErrorInformation> errorResults = validate(password, oldPassword, userInfo);
if (!errorResults.isEmpty()) {
throw new PwmDataValidationException(errorResults.iterator().next());
}
if (user != null) {
try {
LOGGER.trace("calling chai directory password validation checker");
user.testPasswordPolicy(password.getStringValue());
} catch (UnsupportedOperationException e) {
LOGGER.trace("Unsupported operation was thrown while validating password: " + e.toString());
} catch (ChaiUnavailableException e) {
pwmApplication.getStatisticsManager().incrementValue(Statistic.LDAP_UNAVAILABLE_COUNT);
LOGGER.warn("ChaiUnavailableException was thrown while validating password: " + e.toString());
throw e;
} catch (ChaiPasswordPolicyException e) {
final ChaiError passwordError = e.getErrorCode();
final PwmError pwmError = PwmError.forChaiError(passwordError);
final ErrorInformation info = new ErrorInformation(pwmError == null ? PwmError.PASSWORD_UNKNOWN_VALIDATION : pwmError);
LOGGER.trace("ChaiPasswordPolicyException was thrown while validating password: " + e.toString());
errorResults.add(info);
}
}
if (!errorResults.isEmpty()) {
throw new PwmDataValidationException(errorResults.iterator().next());
}
return true;
}
use of password.pwm.error.PwmError in project pwm by pwm-project.
the class PasswordUtility method setPassword.
public static void setPassword(final PwmApplication pwmApplication, final SessionLabel sessionLabel, final ChaiProvider chaiProvider, final UserInfo userInfo, final PasswordData oldPassword, final PasswordData newPassword) throws PwmUnrecoverableException, PwmOperationalException {
final UserIdentity userIdentity = userInfo.getUserIdentity();
final Instant startTime = Instant.now();
final boolean bindIsSelf;
final String bindDN;
try {
final ChaiUser theUser = chaiProvider.getEntryFactory().newChaiUser(userIdentity.getUserDN());
final Locale locale = PwmConstants.DEFAULT_LOCALE;
final PwmPasswordPolicy passwordPolicy = PasswordUtility.readPasswordPolicyForUser(pwmApplication, sessionLabel, userIdentity, theUser, locale);
final PwmPasswordRuleValidator pwmPasswordRuleValidator = new PwmPasswordRuleValidator(pwmApplication, passwordPolicy);
pwmPasswordRuleValidator.testPassword(newPassword, null, userInfo, theUser);
} catch (ChaiUnavailableException e) {
throw PwmUnrecoverableException.fromChaiException(e);
} catch (PwmException e) {
throw new PwmUnrecoverableException(e.getErrorInformation());
}
try {
final ChaiUser theUser = chaiProvider.getEntryFactory().newChaiUser(userIdentity.getUserDN());
bindDN = chaiProvider.getChaiConfiguration().getSetting(ChaiSetting.BIND_DN);
bindIsSelf = userIdentity.canonicalEquals(new UserIdentity(bindDN, userIdentity.getLdapProfileID()), pwmApplication);
LOGGER.trace(sessionLabel, "preparing to setActorPassword for '" + theUser.getEntryDN() + "', using bind DN: " + bindDN);
final boolean settingEnableChange = Boolean.parseBoolean(pwmApplication.getConfig().readAppProperty(AppProperty.LDAP_PASSWORD_CHANGE_SELF_ENABLE));
if (settingEnableChange) {
if (oldPassword == null) {
theUser.setPassword(newPassword.getStringValue(), true);
} else {
theUser.changePassword(oldPassword.getStringValue(), newPassword.getStringValue());
}
} else {
LOGGER.debug(sessionLabel, "skipping actual ldap password change operation due to app property " + AppProperty.LDAP_PASSWORD_CHANGE_SELF_ENABLE.getKey() + "=false");
}
} catch (ChaiPasswordPolicyException e) {
final String errorMsg = "error setting password for user '" + userIdentity.toDisplayString() + "'' " + 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 '" + userIdentity.toDisplayString() + "'' " + 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);
} catch (ChaiUnavailableException e) {
throw PwmUnrecoverableException.fromChaiException(e);
}
// 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(sessionLabel, oldPassword.getStringValue());
}
// update stats
pwmApplication.getStatisticsManager().updateEps(EpsStatistic.PASSWORD_CHANGES, 1);
final int passwordStrength = PasswordUtility.judgePasswordStrength(pwmApplication.getConfig(), newPassword.getStringValue());
pwmApplication.getStatisticsManager().updateAverageValue(Statistic.AVG_PASSWORD_STRENGTH, passwordStrength);
// at this point the password has been changed, so log it.
final String msg = (bindIsSelf ? "user " + userIdentity.toDisplayString() + " has changed own password" : "password for user '" + userIdentity.toDisplayString() + "' has been changed by " + bindDN) + " (" + TimeDuration.fromCurrent(startTime).asCompactString() + ")";
LOGGER.info(sessionLabel, msg);
}
use of password.pwm.error.PwmError in project pwm by pwm-project.
the class LDAPStatusChecker method checkBasicLdapConnectivity.
public List<HealthRecord> checkBasicLdapConnectivity(final PwmApplication pwmApplication, final Configuration config, final LdapProfile ldapProfile, final boolean testContextlessRoot) {
final List<HealthRecord> returnRecords = new ArrayList<>();
ChaiProvider chaiProvider = null;
try {
final DirectoryVendor directoryVendor;
try {
final String proxyDN = ldapProfile.readSettingAsString(PwmSetting.LDAP_PROXY_USER_DN);
final PasswordData proxyPW = ldapProfile.readSettingAsPassword(PwmSetting.LDAP_PROXY_USER_PASSWORD);
if (proxyDN == null || proxyDN.length() < 1) {
return Collections.singletonList(new HealthRecord(HealthStatus.WARN, HealthTopic.LDAP, "Missing Proxy User DN"));
}
if (proxyPW == null) {
return Collections.singletonList(new HealthRecord(HealthStatus.WARN, HealthTopic.LDAP, "Missing Proxy User Password"));
}
chaiProvider = LdapOperationsHelper.createChaiProvider(pwmApplication, SessionLabel.HEALTH_SESSION_LABEL, ldapProfile, config, proxyDN, proxyPW);
final ChaiEntry adminEntry = chaiProvider.getEntryFactory().newChaiEntry(proxyDN);
adminEntry.exists();
directoryVendor = chaiProvider.getDirectoryVendor();
} catch (ChaiException e) {
final ChaiError chaiError = ChaiErrors.getErrorForMessage(e.getMessage());
final PwmError pwmError = PwmError.forChaiError(chaiError);
final StringBuilder errorString = new StringBuilder();
final String profileName = ldapProfile.getIdentifier();
errorString.append("error connecting to ldap directory (").append(profileName).append("), error: ").append(e.getMessage());
if (chaiError != null && chaiError != ChaiError.UNKNOWN) {
errorString.append(" (");
errorString.append(chaiError.toString());
if (pwmError != null && pwmError != PwmError.ERROR_UNKNOWN) {
errorString.append(" - ");
errorString.append(pwmError.getLocalizedMessage(PwmConstants.DEFAULT_LOCALE, pwmApplication.getConfig()));
}
errorString.append(")");
}
returnRecords.add(new HealthRecord(HealthStatus.WARN, makeLdapTopic(ldapProfile, config), errorString.toString()));
pwmApplication.getLdapConnectionService().setLastLdapFailure(ldapProfile, new ErrorInformation(PwmError.ERROR_DIRECTORY_UNAVAILABLE, errorString.toString()));
return returnRecords;
} catch (Exception e) {
final HealthRecord record = HealthRecord.forMessage(HealthMessage.LDAP_No_Connection, e.getMessage());
returnRecords.add(record);
pwmApplication.getLdapConnectionService().setLastLdapFailure(ldapProfile, new ErrorInformation(PwmError.ERROR_DIRECTORY_UNAVAILABLE, record.getDetail(PwmConstants.DEFAULT_LOCALE, pwmApplication.getConfig())));
return returnRecords;
}
if (directoryVendor != null && directoryVendor == DirectoryVendor.ACTIVE_DIRECTORY) {
returnRecords.addAll(checkAd(pwmApplication, config, ldapProfile));
}
if (testContextlessRoot) {
for (final String loopContext : ldapProfile.readSettingAsStringArray(PwmSetting.LDAP_CONTEXTLESS_ROOT)) {
try {
final ChaiEntry contextEntry = chaiProvider.getEntryFactory().newChaiEntry(loopContext);
final Set<String> objectClasses = contextEntry.readObjectClass();
if (objectClasses == null || objectClasses.isEmpty()) {
final String errorString = "ldap context setting '" + loopContext + "' is not valid";
returnRecords.add(new HealthRecord(HealthStatus.WARN, makeLdapTopic(ldapProfile, config), errorString));
}
} catch (Exception e) {
final String errorString = "ldap root context '" + loopContext + "' is not valid: " + e.getMessage();
returnRecords.add(new HealthRecord(HealthStatus.WARN, makeLdapTopic(ldapProfile, config), errorString));
}
}
}
} finally {
if (chaiProvider != null) {
try {
chaiProvider.close();
} catch (Exception e) {
/* ignore */
}
}
}
return returnRecords;
}
Aggregations