use of password.pwm.config.profile.LdapProfile in project pwm by pwm-project.
the class LdapOtpOperator method readOtpUserConfiguration.
/**
* Read OTP secret and instantiate a OTP User Configuration object.
*/
@Override
public OTPUserRecord readOtpUserConfiguration(final UserIdentity userIdentity, final String userGUID) throws PwmUnrecoverableException {
final Configuration config = getPwmApplication().getConfig();
final LdapProfile ldapProfile = config.getLdapProfiles().get(userIdentity.getLdapProfileID());
final String ldapStorageAttribute = ldapProfile.readSettingAsString(PwmSetting.OTP_SECRET_LDAP_ATTRIBUTE);
if (ldapStorageAttribute == null || ldapStorageAttribute.length() < 1) {
final String errorMsg = "ldap storage attribute is not configured, unable to read OTP secret";
final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_INVALID_CONFIG, errorMsg);
throw new PwmUnrecoverableException(errorInformation);
}
OTPUserRecord otp = null;
try {
final ChaiUser theUser = pwmApplication.getProxiedChaiUser(userIdentity);
String value = theUser.readStringAttribute(ldapStorageAttribute);
if (config.readSettingAsBoolean(PwmSetting.OTP_SECRET_ENCRYPT)) {
value = decryptAttributeValue(value);
}
if (value != null) {
otp = decomposeOtpAttribute(value);
}
} catch (ChaiOperationException e) {
final String errorMsg = "unexpected LDAP error reading responses: " + e.getMessage();
final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_UNKNOWN, errorMsg);
throw new PwmUnrecoverableException(errorInformation);
} catch (ChaiUnavailableException e) {
final String errorMsg = "unexpected LDAP error reading responses: " + e.getMessage();
final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_UNKNOWN, errorMsg);
throw new PwmUnrecoverableException(errorInformation);
} catch (PwmOperationalException e) {
final String errorMsg = "unexpected error reading responses: " + e.getMessage();
final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_UNKNOWN, errorMsg);
throw new PwmUnrecoverableException(errorInformation);
}
return otp;
}
use of password.pwm.config.profile.LdapProfile in project pwm by pwm-project.
the class LdapOtpOperator method writeOtpUserConfiguration.
@Override
public void writeOtpUserConfiguration(final PwmSession pwmSession, final UserIdentity userIdentity, final String userGuid, final OTPUserRecord otpConfig) throws PwmUnrecoverableException {
final Configuration config = pwmApplication.getConfig();
final LdapProfile ldapProfile = config.getLdapProfiles().get(userIdentity.getLdapProfileID());
final String ldapStorageAttribute = ldapProfile.readSettingAsString(PwmSetting.OTP_SECRET_LDAP_ATTRIBUTE);
if (ldapStorageAttribute == null || ldapStorageAttribute.length() < 1) {
final String errorMsg = "ldap storage attribute is not configured, unable to write OTP secret";
final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_INVALID_CONFIG, errorMsg);
throw new PwmUnrecoverableException(errorInformation);
}
String value = composeOtpAttribute(otpConfig);
if (value == null || value.length() == 0) {
final String errorMsg = "Invalid value for OTP secret, unable to store";
final ErrorInformation errorInformation = new ErrorInformation(PwmError.ERROR_INVALID_CONFIG, errorMsg);
throw new PwmUnrecoverableException(errorInformation);
}
try {
if (config.readSettingAsBoolean(PwmSetting.OTP_SECRET_ENCRYPT)) {
value = encryptAttributeValue(value);
}
final ChaiUser theUser = pwmSession == null ? pwmApplication.getProxiedChaiUser(userIdentity) : pwmSession.getSessionManager().getActor(pwmApplication, userIdentity);
theUser.writeStringAttribute(ldapStorageAttribute, value);
LOGGER.info("saved OTP secret for user to chai-ldap format");
} catch (ChaiException ex) {
final String errorMsg;
if (ex.getErrorCode() == ChaiError.NO_ACCESS) {
errorMsg = "permission error writing OTP secret to ldap attribute '" + ldapStorageAttribute + "', user does not appear to have correct permissions to save OTP secret: " + ex.getMessage();
} else {
errorMsg = "error writing OTP secret to ldap attribute '" + ldapStorageAttribute + "': " + ex.getMessage();
}
final ErrorInformation errorInfo = new ErrorInformation(PwmError.ERROR_WRITING_OTP_SECRET, errorMsg);
final PwmUnrecoverableException pwmOE = new PwmUnrecoverableException(errorInfo);
pwmOE.initCause(ex);
throw pwmOE;
} catch (PwmOperationalException ex) {
final ErrorInformation errorInfo = new ErrorInformation(PwmError.ERROR_WRITING_OTP_SECRET, ex.getMessage());
final PwmUnrecoverableException pwmOE = new PwmUnrecoverableException(errorInfo);
pwmOE.initCause(ex);
throw pwmOE;
}
}
use of password.pwm.config.profile.LdapProfile in project pwm by pwm-project.
the class LDAPStatusChecker method checkVendorSameness.
private List<HealthRecord> checkVendorSameness(final PwmApplication pwmApplication) {
final Map<HealthMonitor.HealthMonitorFlag, Serializable> healthProperties = pwmApplication.getHealthMonitor().getHealthProperties();
if (healthProperties.containsKey(HealthMonitor.HealthMonitorFlag.LdapVendorSameCheck)) {
return (List<HealthRecord>) healthProperties.get(HealthMonitor.HealthMonitorFlag.LdapVendorSameCheck);
}
LOGGER.trace(SessionLabel.HEALTH_SESSION_LABEL, "beginning check for replica vendor sameness");
boolean errorReachingServer = false;
final Map<String, DirectoryVendor> replicaVendorMap = new HashMap<>();
try {
for (final LdapProfile ldapProfile : pwmApplication.getConfig().getLdapProfiles().values()) {
final ChaiConfiguration profileChaiConfiguration = LdapOperationsHelper.createChaiConfiguration(pwmApplication.getConfig(), ldapProfile);
final Collection<ChaiConfiguration> replicaConfigs = ChaiUtility.splitConfigurationPerReplica(profileChaiConfiguration, Collections.emptyMap());
for (final ChaiConfiguration chaiConfiguration : replicaConfigs) {
final ChaiProvider loopProvider = pwmApplication.getLdapConnectionService().getChaiProviderFactory().newProvider(chaiConfiguration);
replicaVendorMap.put(chaiConfiguration.getSetting(ChaiSetting.BIND_URLS), loopProvider.getDirectoryVendor());
}
}
} catch (Exception e) {
errorReachingServer = true;
LOGGER.error(SessionLabel.HEALTH_SESSION_LABEL, "error during replica vendor sameness check: " + e.getMessage());
}
final ArrayList<HealthRecord> healthRecords = new ArrayList<>();
final Set<DirectoryVendor> discoveredVendors = new HashSet<>(replicaVendorMap.values());
if (discoveredVendors.size() >= 2) {
final StringBuilder vendorMsg = new StringBuilder();
for (final Iterator<Map.Entry<String, DirectoryVendor>> iterator = replicaVendorMap.entrySet().iterator(); iterator.hasNext(); ) {
final Map.Entry<String, DirectoryVendor> entry = iterator.next();
final String key = entry.getKey();
vendorMsg.append(key).append("=").append(entry.getValue().toString());
if (iterator.hasNext()) {
vendorMsg.append(", ");
}
}
healthRecords.add(HealthRecord.forMessage(HealthMessage.LDAP_VendorsNotSame, vendorMsg.toString()));
// cache the error
healthProperties.put(HealthMonitor.HealthMonitorFlag.LdapVendorSameCheck, healthRecords);
LOGGER.warn(SessionLabel.HEALTH_SESSION_LABEL, "multiple ldap vendors found: " + vendorMsg.toString());
} else if (discoveredVendors.size() == 1) {
if (!errorReachingServer) {
// cache the no errors
healthProperties.put(HealthMonitor.HealthMonitorFlag.LdapVendorSameCheck, healthRecords);
}
}
return healthRecords;
}
use of password.pwm.config.profile.LdapProfile in project pwm by pwm-project.
the class LDAPStatusChecker method doHealthCheck.
public List<HealthRecord> doHealthCheck(final PwmApplication pwmApplication) {
final Configuration config = pwmApplication.getConfig();
final List<HealthRecord> returnRecords = new ArrayList<>();
final Map<String, LdapProfile> ldapProfiles = pwmApplication.getConfig().getLdapProfiles();
for (final Map.Entry<String, LdapProfile> entry : ldapProfiles.entrySet()) {
final String profileID = entry.getKey();
final List<HealthRecord> profileRecords = new ArrayList<>();
profileRecords.addAll(checkBasicLdapConnectivity(pwmApplication, config, entry.getValue(), true));
if (profileRecords.isEmpty()) {
profileRecords.addAll(checkLdapServerUrls(pwmApplication, config, ldapProfiles.get(profileID)));
}
if (profileRecords.isEmpty()) {
profileRecords.add(HealthRecord.forMessage(HealthMessage.LDAP_OK));
profileRecords.addAll(doLdapTestUserCheck(config, ldapProfiles.get(profileID), pwmApplication));
}
returnRecords.addAll(profileRecords);
}
for (final LdapProfile ldapProfile : pwmApplication.getLdapConnectionService().getLastLdapFailure().keySet()) {
final ErrorInformation errorInfo = pwmApplication.getLdapConnectionService().getLastLdapFailure().get(ldapProfile);
if (errorInfo != null) {
final TimeDuration errorAge = TimeDuration.fromCurrent(errorInfo.getDate());
final long cautionDurationMS = Long.parseLong(pwmApplication.getConfig().readAppProperty(AppProperty.HEALTH_LDAP_CAUTION_DURATION_MS));
if (errorAge.isShorterThan(cautionDurationMS)) {
final String ageString = errorAge.asLongString();
final String errorDate = JavaHelper.toIsoDate(errorInfo.getDate());
final String errorMsg = errorInfo.toDebugStr();
returnRecords.add(HealthRecord.forMessage(HealthMessage.LDAP_RecentlyUnreachable, ldapProfile.getDisplayName(PwmConstants.DEFAULT_LOCALE), ageString, errorDate, errorMsg));
}
}
}
if (config.getLdapProfiles() != null && !config.getLdapProfiles().isEmpty()) {
final List<String> urls = config.getLdapProfiles().values().iterator().next().readSettingAsStringArray(PwmSetting.LDAP_SERVER_URLS);
if (urls != null && !urls.isEmpty() && !StringUtil.isEmpty(urls.iterator().next())) {
returnRecords.addAll(checkVendorSameness(pwmApplication));
returnRecords.addAll(checkUserPermissionValues(pwmApplication));
returnRecords.addAll(checkLdapDNSyntaxValues(pwmApplication));
}
}
return returnRecords;
}
use of password.pwm.config.profile.LdapProfile in project pwm by pwm-project.
the class LDAPStatusChecker method checkAdPasswordPolicyApi.
private static List<HealthRecord> checkAdPasswordPolicyApi(final PwmApplication pwmApplication) {
final boolean passwordPolicyApiEnabled = pwmApplication.getConfig().readSettingAsBoolean(PwmSetting.AD_ENFORCE_PW_HISTORY_ON_SET);
if (!passwordPolicyApiEnabled) {
return Collections.emptyList();
}
if (pwmApplication.getHealthMonitor() != null) {
final Map<HealthMonitor.HealthMonitorFlag, Serializable> healthProperties = pwmApplication.getHealthMonitor().getHealthProperties();
if (healthProperties.containsKey(HealthMonitor.HealthMonitorFlag.AdPasswordPolicyApiCheck)) {
final List<HealthRecord> healthRecords = (List<HealthRecord>) healthProperties.get(HealthMonitor.HealthMonitorFlag.AdPasswordPolicyApiCheck);
return healthRecords;
}
}
LOGGER.trace(SessionLabel.HEALTH_SESSION_LABEL, "beginning check for ad api password policy (asn " + PwmConstants.LDAP_AD_PASSWORD_POLICY_CONTROL_ASN + ") support");
boolean errorReachingServer = false;
final ArrayList<HealthRecord> healthRecords = new ArrayList<>();
try {
for (final LdapProfile ldapProfile : pwmApplication.getConfig().getLdapProfiles().values()) {
final ChaiConfiguration profileChaiConfiguration = LdapOperationsHelper.createChaiConfiguration(pwmApplication.getConfig(), ldapProfile);
final Collection<ChaiConfiguration> replicaConfigs = ChaiUtility.splitConfigurationPerReplica(profileChaiConfiguration, Collections.emptyMap());
for (final ChaiConfiguration chaiConfiguration : replicaConfigs) {
final ChaiProvider loopProvider = pwmApplication.getLdapConnectionService().getChaiProviderFactory().newProvider(chaiConfiguration);
final ChaiEntry rootDSE = ChaiUtility.getRootDSE(loopProvider);
final Set<String> controls = rootDSE.readMultiStringAttribute("supportedControl");
final boolean asnSupported = controls.contains(PwmConstants.LDAP_AD_PASSWORD_POLICY_CONTROL_ASN);
if (!asnSupported) {
final String url = chaiConfiguration.getSetting(ChaiSetting.BIND_URLS);
final HealthRecord record = HealthRecord.forMessage(HealthMessage.LDAP_Ad_History_Asn_Missing, PwmSetting.AD_ENFORCE_PW_HISTORY_ON_SET.toMenuLocationDebug(null, PwmConstants.DEFAULT_LOCALE), url);
healthRecords.add(record);
LOGGER.warn(record.toDebugString(PwmConstants.DEFAULT_LOCALE, pwmApplication.getConfig()));
}
}
}
} catch (Exception e) {
errorReachingServer = true;
LOGGER.error(SessionLabel.HEALTH_SESSION_LABEL, "error during ad api password policy (asn " + PwmConstants.LDAP_AD_PASSWORD_POLICY_CONTROL_ASN + ") check: " + e.getMessage());
}
if (!errorReachingServer && pwmApplication.getHealthMonitor() != null) {
final Map<HealthMonitor.HealthMonitorFlag, Serializable> healthProperties = pwmApplication.getHealthMonitor().getHealthProperties();
healthProperties.put(HealthMonitor.HealthMonitorFlag.AdPasswordPolicyApiCheck, healthRecords);
}
return healthRecords;
}
Aggregations