use of com.novell.ldapchai.exception.ChaiOperationException in project pwm by pwm-project.
the class LdapXmlUserHistory method updateUserHistoryImpl.
private void updateUserHistoryImpl(final UserAuditRecord auditRecord) throws PwmUnrecoverableException, ChaiUnavailableException {
// user info
final UserIdentity userIdentity;
if (auditRecord instanceof HelpdeskAuditRecord && auditRecord.getType() == AuditEvent.Type.HELPDESK) {
final HelpdeskAuditRecord helpdeskAuditRecord = (HelpdeskAuditRecord) auditRecord;
userIdentity = new UserIdentity(helpdeskAuditRecord.getTargetDN(), helpdeskAuditRecord.getTargetLdapProfile());
} else {
userIdentity = new UserIdentity(auditRecord.getPerpetratorDN(), auditRecord.getPerpetratorLdapProfile());
}
final ChaiUser theUser = pwmApplication.getProxiedChaiUser(userIdentity);
// settings
final String corRecordIdentifer = COR_RECORD_ID;
final LdapProfile ldapProfile = userIdentity.getLdapProfile(pwmApplication.getConfig());
final String corAttribute = ldapProfile.readSettingAsString(PwmSetting.EVENTS_LDAP_ATTRIBUTE);
// quit if settings no good;
if (corAttribute == null || corAttribute.length() < 1) {
LOGGER.debug("no user event log attribute configured, skipping write of log data");
return;
}
// read current value;
final StoredHistory storedHistory;
final ConfigObjectRecord theCor;
final List corList;
try {
corList = ConfigObjectRecord.readRecordFromLDAP(theUser, corAttribute, corRecordIdentifer, null, null);
} catch (Exception e) {
final String errorMsg = "error reading LDAP user event history for user " + userIdentity.toDisplayString() + ", error: " + e.getMessage();
final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_UNKNOWN, errorMsg);
LOGGER.error(errorInformation.toDebugStr(), e);
throw new PwmUnrecoverableException(errorInformation, e);
}
try {
if (!corList.isEmpty()) {
theCor = (ConfigObjectRecord) corList.get(0);
} else {
theCor = ConfigObjectRecord.createNew(theUser, corAttribute, corRecordIdentifer, null, null);
}
storedHistory = StoredHistory.fromXml(theCor.getPayload());
} catch (Exception e) {
LOGGER.error("ldap error writing user event log: " + e.getMessage());
return;
}
// add next record to blob
final StoredEvent storedEvent = StoredEvent.fromAuditRecord(auditRecord);
storedHistory.addEvent(storedEvent);
// trim the blob.
final int maxUserEvents = (int) pwmApplication.getConfig().readSettingAsLong(PwmSetting.EVENTS_LDAP_MAX_EVENTS);
storedHistory.trim(maxUserEvents);
// write the blob.
try {
theCor.updatePayload(storedHistory.toXml());
} catch (ChaiOperationException e) {
LOGGER.error("ldap error writing user event log: " + e.getMessage());
}
}
use of com.novell.ldapchai.exception.ChaiOperationException 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.ChaiOperationException 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.ChaiOperationException in project pwm by pwm-project.
the class PasswordUtility method helpdeskSetUserPassword.
public static void helpdeskSetUserPassword(final PwmSession pwmSession, final ChaiUser chaiUser, final UserInfo userInfo, final PwmApplication pwmApplication, final PasswordData newPassword) throws ChaiUnavailableException, PwmUnrecoverableException, PwmOperationalException {
final SessionLabel sessionLabel = pwmSession.getLabel();
final UserIdentity userIdentity = userInfo.getUserIdentity();
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);
}
setPassword(pwmApplication, pwmSession.getLabel(), chaiUser.getChaiProvider(), userInfo, null, newPassword);
// 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 = new AuditRecordFactory(pwmApplication, pwmSession).createHelpdeskAuditRecord(AuditEvent.HELPDESK_SET_PASSWORD, pwmSession.getUserInfo().getUserIdentity(), null, userIdentity, pwmSession.getSessionStateBean().getSrcAddress(), pwmSession.getSessionStateBean().getSrcHostname());
pwmApplication.getAuditManager().submit(auditRecord);
}
// update statistics
pwmApplication.getStatisticsManager().incrementValue(Statistic.HELPDESK_PASSWORD_SET);
{
// 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 LoginInfoBean loginInfoBean = new LoginInfoBean();
loginInfoBean.setUserCurrentPassword(newPassword);
final MacroMachine macroMachine = MacroMachine.forUser(pwmApplication, sessionLabel, userInfo, loginInfoBean);
final ActionExecutor actionExecutor = new ActionExecutor.ActionExecutorSettings(pwmApplication, userIdentity).setMacroMachine(macroMachine).setExpandPwmMacros(true).createActionExecutor();
actionExecutor.executeActions(actions, pwmSession.getLabel());
}
}
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.getLabel(), userIdentity, proxiedUser, userGUID);
// mark the event log
final HelpdeskAuditRecord auditRecord = new AuditRecordFactory(pwmApplication, pwmSession).createHelpdeskAuditRecord(AuditEvent.HELPDESK_CLEAR_RESPONSES, pwmSession.getUserInfo().getUserIdentity(), null, userIdentity, pwmSession.getSessionStateBean().getSrcAddress(), pwmSession.getSessionStateBean().getSrcHostname());
pwmApplication.getAuditManager().submit(auditRecord);
}
// send email notification
sendChangePasswordHelpdeskEmailNotice(pwmSession, pwmApplication, userInfo);
// 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());
}
}
// 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);
}
PasswordUtility.sendNewPassword(userInfo, pwmApplication, newPassword, pwmSession.getSessionStateBean().getLocale(), messageSendMethod);
}
}
use of com.novell.ldapchai.exception.ChaiOperationException in project pwm by pwm-project.
the class PasswordUtility method determinePwdLastModified.
private static Instant 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 Instant chaiReadDate = theUser.readPasswordModificationDate();
if (chaiReadDate != null) {
LOGGER.trace(sessionLabel, "read last user password change timestamp (via chai) as: " + JavaHelper.toIsoDate(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 Instant pwmPwdLastModified = theUser.readDateAttribute(pwmLastSetAttr);
LOGGER.trace(sessionLabel, "read pwmPasswordChangeTime as: " + (pwmPwdLastModified == null ? "n/a" : JavaHelper.toIsoDate(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;
}
Aggregations