use of com.novell.ldapchai.provider.ChaiConfiguration in project ldapchai by ldapchai.
the class ChaiUtility method testAttributeReplication.
/**
* <p>Test the replication of an attribute. It is left to the implementation to determine the means and criteria for
* this operation. Typically this method would be used just after a write operation in some type of time delayed loop.
* This method does not write any data to the directory.</p>
*
* <p>Typical implementations will do the following:</p>
* <ul>
* <li>issue {@link com.novell.ldapchai.ChaiEntry#readStringAttribute(String)} to read a value</li>
* <li>establish an LDAP connection to all known replicas</li>
* <li>issue {@link com.novell.ldapchai.ChaiEntry#compareStringAttribute(String, String)} to to each server directly</li>
* <li>return true if each server contacted has the same value, false if not</li>
* </ul>
*
* <p>Target servers that are unreachable or return errors are ignored, and do not influence the results. It is entirely
* possible that no matter how many times this method is called, false will always be returned, so the caller should
* take care not to repeat a test indefinitely.</p>
*
* <p>This operation is potentially expensive, as it may establish new LDAP level connections to each target server each
* time it is invoked.</p>
*
* <p>The following sample shows how this method might be used. There are a few important attributes of the sample:</p>
* <ul>
* <li>Multiple ldap servers are specified</li>
* <li>There is a pause time between each replication check (the test can be expensive)</li>
* <li>There is a timeout period (the test may never successfully complete)</li>
* </ul>
* <p><b>Example Usage:</b></p>
* <pre>
* // write a timestamp value to an attribute
* theUser.writeStringAttributes("description","testValue" + Instant.now().toString());
*
* // maximum time to wait for replication
* final int maximumWaitTime = 120 * 1000;
*
* // time between iterations
* final int pauseTime = 3 * 1000;
*
* // timestamp of beginning of wait
* final long startTime = System.currentTimeMillis();
*
* boolean replicated = false;
*
* // loop until
* while (System.currentTimeMillis() - startTime < maximumWaitTime) {
*
* // sleep between iterations
* try { Thread.sleep(pauseTime); } catch (InterruptedException e) {}
*
* // check if data replicated yet
* replicated = ChaiUtility.testAttributeReplication(theUser,"description",null);
*
* // break if data has replicated
* if (replicated) {
* break;
* }
* }
*
* // report success
* System.out.println("Attribute replication successful: " + replicated);
* </pre>
*
* @param chaiEntry A valid entry
* @param attribute A valid attribute on the entry
* @param value The value to test for. If {@code null}, a value is read from the active server
* @return true if the attribute is the same on all servers
* @throws ChaiOperationException If an error is encountered during the operation
* @throws ChaiUnavailableException If no directory servers are reachable
* @throws IllegalStateException If the underlying connection is not in an available state
*/
public static boolean testAttributeReplication(final ChaiEntry chaiEntry, final String attribute, final String value) throws ChaiOperationException, ChaiUnavailableException {
final String effectiveValue = (value == null || value.length() < 1) ? chaiEntry.readStringAttribute(attribute) : value;
if (effectiveValue == null) {
throw ChaiOperationException.forErrorMessage("unreadable to read test attribute from primary ChaiProvider");
}
final ChaiConfiguration chaiConfiguration = chaiEntry.getChaiProvider().getChaiConfiguration();
final List<String> ldapURLs = chaiConfiguration.bindURLsAsList();
LOGGER.trace("testAttributeReplication, will test the following ldap urls: " + ldapURLs);
int testCount = 0;
int successCount = 0;
final Collection<ChaiConfiguration> perReplicaProviders = splitConfigurationPerReplica(chaiEntry.getChaiProvider().getChaiConfiguration(), Collections.singletonMap(ChaiSetting.FAILOVER_CONNECT_RETRIES, "1"));
for (final ChaiConfiguration loopConfiguration : perReplicaProviders) {
ChaiProvider loopProvider = null;
try {
loopProvider = chaiEntry.getChaiProvider().getProviderFactory().newProvider(loopConfiguration);
if (loopProvider.compareStringAttribute(chaiEntry.getEntryDN(), attribute, effectiveValue)) {
successCount++;
}
testCount++;
} catch (ChaiUnavailableException e) {
// disregard
} catch (ChaiOperationException e) {
// disregard
} finally {
try {
if (loopProvider != null) {
loopProvider.close();
}
} catch (Exception e) {
// already closed, whatever.
}
}
}
if (LOGGER.isDebugEnabled()) {
final StringBuilder debugMsg = new StringBuilder();
debugMsg.append("testAttributeReplication for ").append(chaiEntry).append(":").append(attribute);
debugMsg.append(" ").append(testCount).append(" up,");
debugMsg.append(" ").append(ldapURLs.size() - testCount).append(" down,");
debugMsg.append(" ").append(successCount).append(" in sync");
LOGGER.debug(debugMsg);
}
return testCount > 0 && testCount == successCount;
}
use of com.novell.ldapchai.provider.ChaiConfiguration in project ldapchai by ldapchai.
the class FailOverTester method testSingleServerRestart.
public void testSingleServerRestart() throws Exception {
TestHelper.configureLogging();
final InetSocketAddress destinationAddress = figureDestSocketAddress();
final TcpProxy proxy1 = new TcpProxy(basePort + 1, destinationAddress);
proxy1.start();
final ChaiConfiguration testConfig = makeChaiConfig(figureUrlForProxy(proxy1));
final ChaiProvider testProvider = ChaiProviderFactory.createProvider(testConfig);
final ChaiEntry testContainer = TestHelper.createTestContainer(testProvider);
final ChaiUser testUser = TestHelper.createNewTestUser(testContainer);
TestHelper.doBasicNonDestructiveUserTest(testUser);
proxy1.stop();
TestHelper.pause(1000);
// test to make sure we get errors
boolean gotError = false;
try {
TestHelper.doBasicNonDestructiveUserTest(testUser);
} catch (ChaiUnavailableException e) {
System.out.println("got expected unavailable error: " + e.getMessage());
gotError = true;
}
Assert.assertTrue(gotError);
proxy1.start();
TestHelper.pause(1000);
TestHelper.doBasicNonDestructiveUserTest(testUser);
}
use of com.novell.ldapchai.provider.ChaiConfiguration in project ldapchai by ldapchai.
the class AdvancedConnection method main.
public static void main(final String[] args) {
// connection parameters
String ldapURL = "ldap://ldaphost:389";
String ldapBindDN = "cn=admin,ou=ou,o=o";
String ldapBindPW = "password";
// allocate a new ChaiConfiguration
ChaiConfiguration chaiConfig = ChaiConfiguration.builder(ldapURL, ldapBindDN, ldapBindPW).setSetting(ChaiSetting.CR_CHAI_STORAGE_ATTRIBUTE, "title").setSetting(ChaiSetting.WATCHDOG_ENABLE, "false").setSetting(ChaiSetting.PROMISCUOUS_SSL, "true").setSetting(ChaiSetting.EDIRECTORY_ENABLE_NMAS, "true").build();
try {
// create a ChaiProviderFactory;
ChaiProviderFactory chaiProviderFactory = ChaiProviderFactory.newProviderFactory();
// create a ChaiProvider
ChaiProvider provider = chaiProviderFactory.newProvider(chaiConfig);
// create a ChaiProvider
ChaiUser bindUser = provider.getEntryFactory().newChaiUser(ldapBindDN);
// read the user's last name.
String surname = bindUser.readStringAttribute(ChaiUser.ATTR_SURNAME);
// read the bind user's surname
System.out.println("surname = " + surname);
} catch (ChaiUnavailableException e) {
System.out.println("LDAP unreachable: " + e.getMessage());
} catch (ChaiOperationException e) {
System.out.println("LDAP error: " + e.getMessage());
}
}
use of com.novell.ldapchai.provider.ChaiConfiguration in project pwm by pwm-project.
the class LdapOperationsHelper method createChaiProvider.
public static ChaiProvider createChaiProvider(final PwmApplication pwmApplication, final SessionLabel sessionLabel, final Configuration config, final LdapProfile ldapProfile, final List<String> ldapURLs, final String userDN, final PasswordData userPassword) throws ChaiUnavailableException, PwmUnrecoverableException {
final ChaiConfiguration chaiConfig = createChaiConfiguration(config, ldapProfile, ldapURLs, userDN, userPassword);
LOGGER.trace(sessionLabel, "creating new ldap connection using config: " + chaiConfig.toString());
return pwmApplication.getLdapConnectionService().getChaiProviderFactory().newProvider(chaiConfig);
}
use of com.novell.ldapchai.provider.ChaiConfiguration in project pwm by pwm-project.
the class LdapOperationsHelper method createChaiConfiguration.
public static ChaiConfiguration createChaiConfiguration(final Configuration config, final LdapProfile ldapProfile, final List<String> ldapURLs, final String userDN, final PasswordData userPassword) throws PwmUnrecoverableException {
final ChaiConfiguration.ChaiConfigurationBuilder configBuilder = ChaiConfiguration.builder(ldapURLs, userDN, userPassword == null ? null : userPassword.getStringValue());
configBuilder.setSetting(ChaiSetting.PROMISCUOUS_SSL, config.readAppProperty(AppProperty.LDAP_PROMISCUOUS_ENABLE));
{
final boolean enableNmasExtensions = Boolean.parseBoolean(config.readAppProperty(AppProperty.LDAP_EXTENSIONS_NMAS_ENABLE));
configBuilder.setSetting(ChaiSetting.EDIRECTORY_ENABLE_NMAS, Boolean.toString(enableNmasExtensions));
}
configBuilder.setSetting(ChaiSetting.CR_CHAI_STORAGE_ATTRIBUTE, ldapProfile.readSettingAsString(PwmSetting.CHALLENGE_USER_ATTRIBUTE));
configBuilder.setSetting(ChaiSetting.CR_ALLOW_DUPLICATE_RESPONSES, Boolean.toString(config.readSettingAsBoolean(PwmSetting.CHALLENGE_ALLOW_DUPLICATE_RESPONSES)));
configBuilder.setSetting(ChaiSetting.CR_CASE_INSENSITIVE, Boolean.toString(config.readSettingAsBoolean(PwmSetting.CHALLENGE_CASE_INSENSITIVE)));
{
final String setting = config.readAppProperty(AppProperty.SECURITY_RESPONSES_HASH_ITERATIONS);
if (setting != null && setting.length() > 0) {
final int intValue = Integer.parseInt(setting);
configBuilder.setSetting(ChaiSetting.CR_CHAI_SALT_COUNT, Integer.toString(intValue));
}
}
// can cause issues with previous password authentication
configBuilder.setSetting(ChaiSetting.JNDI_ENABLE_POOL, "false");
configBuilder.setSetting(ChaiSetting.CR_DEFAULT_FORMAT_TYPE, Answer.FormatType.SHA1_SALT.toString());
final String storageMethodString = config.readSettingAsString(PwmSetting.CHALLENGE_STORAGE_HASHED);
try {
final Answer.FormatType formatType = Answer.FormatType.valueOf(storageMethodString);
configBuilder.setSetting(ChaiSetting.CR_DEFAULT_FORMAT_TYPE, formatType.toString());
} catch (Exception e) {
LOGGER.warn("unknown CR storage format type '" + storageMethodString + "' ");
}
final List<X509Certificate> ldapServerCerts = ldapProfile.readSettingAsCertificate(PwmSetting.LDAP_SERVER_CERTS);
if (ldapServerCerts != null && ldapServerCerts.size() > 0) {
final X509TrustManager tm = new X509Utils.CertMatchingTrustManager(config, ldapServerCerts);
configBuilder.setTrustManager(new X509TrustManager[] { tm });
}
final String idleTimeoutMsString = config.readAppProperty(AppProperty.LDAP_CONNECTION_TIMEOUT);
configBuilder.setSetting(ChaiSetting.LDAP_CONNECT_TIMEOUT, idleTimeoutMsString);
// set the watchdog idle timeout.
final int idleTimeoutMs = (int) config.readSettingAsLong(PwmSetting.LDAP_IDLE_TIMEOUT) * 1000;
if (idleTimeoutMs > 0) {
configBuilder.setSetting(ChaiSetting.WATCHDOG_ENABLE, "true");
configBuilder.setSetting(ChaiSetting.WATCHDOG_IDLE_TIMEOUT, idleTimeoutMsString);
} else {
configBuilder.setSetting(ChaiSetting.WATCHDOG_ENABLE, "false");
}
configBuilder.setSetting(ChaiSetting.LDAP_SEARCH_PAGING_ENABLE, config.readAppProperty(AppProperty.LDAP_SEARCH_PAGING_ENABLE));
configBuilder.setSetting(ChaiSetting.LDAP_SEARCH_PAGING_SIZE, config.readAppProperty(AppProperty.LDAP_SEARCH_PAGING_SIZE));
if (config.readSettingAsBoolean(PwmSetting.AD_ENFORCE_PW_HISTORY_ON_SET)) {
configBuilder.setSetting(ChaiSetting.AD_SET_POLICY_HINTS_ON_PW_SET, "true");
}
// write out any configured values;
final String rawValue = config.readAppProperty(AppProperty.LDAP_CHAI_SETTINGS);
final String[] rawValues = rawValue != null ? rawValue.split(AppProperty.VALUE_SEPARATOR) : new String[0];
final Map<String, String> configuredSettings = StringUtil.convertStringListToNameValuePair(Arrays.asList(rawValues), "=");
for (final Map.Entry<String, String> entry : configuredSettings.entrySet()) {
final String key = entry.getKey();
if (key != null && !key.isEmpty()) {
final ChaiSetting theSetting = ChaiSetting.forKey(key);
if (theSetting == null) {
LOGGER.warn("ignoring unknown chai setting '" + key + "'");
} else {
configBuilder.setSetting(theSetting, entry.getValue());
}
}
}
// set ldap referrals
configBuilder.setSetting(ChaiSetting.LDAP_FOLLOW_REFERRALS, String.valueOf(config.readSettingAsBoolean(PwmSetting.LDAP_FOLLOW_REFERRALS)));
// enable wire trace;
if (config.readSettingAsBoolean(PwmSetting.LDAP_ENABLE_WIRE_TRACE)) {
configBuilder.setSetting(ChaiSetting.WIRETRACE_ENABLE, "true");
}
return configBuilder.build();
}
Aggregations