Search in sources :

Example 1 with ChaiUnavailableException

use of com.novell.ldapchai.exception.ChaiUnavailableException in project ldapchai by ldapchai.

the class ApacheLdapProviderImpl method init.

@Override
public void init(final ChaiConfiguration chaiConfig, final ChaiProviderFactory providerFactory) throws ChaiUnavailableException {
    this.chaiConfig = chaiConfig;
    super.init(chaiConfig, providerFactory);
    // grab the first URL from the list.
    currentLdapUrl = chaiConfig.bindURLsAsList().get(0);
    final URI ldapURL = URI.create(currentLdapUrl);
    final LdapConnectionConfig ldapConnectionConfig = new LdapConnectionConfig();
    ldapConnectionConfig.setLdapHost(ldapURL.getHost());
    ldapConnectionConfig.setLdapPort(ldapURL.getPort());
    if (ldapURL.getScheme().equalsIgnoreCase("ldaps")) {
        ldapConnectionConfig.setUseSsl(true);
        final boolean usePromiscuousSSL = Boolean.parseBoolean(chaiConfig.getSetting(ChaiSetting.PROMISCUOUS_SSL));
        if (usePromiscuousSSL) {
            try {
                final PromiscuousTrustManager promiscuousTrustManager = new PromiscuousTrustManager();
                ldapConnectionConfig.setTrustManagers(promiscuousTrustManager);
            } catch (Exception e) {
                LOGGER.error("error creating promiscuous ssl ldap socket factory: " + e.getMessage());
            }
        } else if (chaiConfig.getTrustManager() != null) {
            try {
                final X509TrustManager[] trustManager = chaiConfig.getTrustManager();
                ldapConnectionConfig.setTrustManagers(trustManager);
            } catch (Exception e) {
                LOGGER.error("error creating configured ssl ldap socket factory: " + e.getMessage());
            }
        }
    }
    final LdapConnection newConnection;
    try {
        newConnection = new LdapNetworkConnection(ldapConnectionConfig);
        newConnection.connect();
        final String bindPassword = chaiConfig.getSetting(ChaiSetting.BIND_PASSWORD);
        final String bindDN = chaiConfig.getSetting(ChaiSetting.BIND_DN);
        newConnection.bind(bindDN, bindPassword);
    } catch (LdapException e) {
        final String message = e.getMessage();
        if (message.contains("Cannot connect on the server")) {
            throw new ChaiUnavailableException(message, ChaiError.COMMUNICATION, false, false);
        }
        throw ChaiUnavailableException.forErrorMessage(message);
    } catch (Exception e) {
        e.printStackTrace();
        final String message = e.getMessage();
        throw new ChaiUnavailableException(message, ChaiError.UNKNOWN, false, false);
    }
    connection = newConnection;
}
Also used : ChaiUnavailableException(com.novell.ldapchai.exception.ChaiUnavailableException) LdapConnectionConfig(org.apache.directory.ldap.client.api.LdapConnectionConfig) LdapNetworkConnection(org.apache.directory.ldap.client.api.LdapNetworkConnection) URI(java.net.URI) LdapException(org.apache.directory.api.ldap.model.exception.LdapException) ChaiUnavailableException(com.novell.ldapchai.exception.ChaiUnavailableException) CursorException(org.apache.directory.api.ldap.model.cursor.CursorException) ChaiOperationException(com.novell.ldapchai.exception.ChaiOperationException) IOException(java.io.IOException) LdapException(org.apache.directory.api.ldap.model.exception.LdapException) LdapConnection(org.apache.directory.ldap.client.api.LdapConnection)

Example 2 with ChaiUnavailableException

use of com.novell.ldapchai.exception.ChaiUnavailableException in project ldapchai by ldapchai.

the class ChaiProviderFactory method newProviderImpl.

ChaiProviderImplementor newProviderImpl(final ChaiConfiguration chaiConfiguration, final boolean failOverWrapperChild) throws ChaiUnavailableException {
    checkStatus();
    ChaiProviderImplementor providerImpl;
    try {
        final boolean enableFailover = "true".equalsIgnoreCase(chaiConfiguration.getSetting(ChaiSetting.FAILOVER_ENABLE));
        if (enableFailover && !failOverWrapperChild) {
            providerImpl = FailOverWrapper.forConfiguration(this, chaiConfiguration);
        } else {
            if (LOGGER.isTraceEnabled()) {
                final String debugMsg = "creating new jndi ldap connection to " + chaiConfiguration.getSetting(ChaiSetting.BIND_URLS) + " as " + chaiConfiguration.getSetting(ChaiSetting.BIND_DN);
                LOGGER.trace(debugMsg);
            }
            providerImpl = createConcreteProvider(this, chaiConfiguration, true);
        }
    } catch (Exception e) {
        final String errorMsg = "unable to create connection: " + e.getClass().getName() + ":" + e.getMessage();
        if (e instanceof ChaiException || e instanceof IOException) {
            LOGGER.debug(errorMsg);
        } else {
            LOGGER.debug(errorMsg, e);
        }
        throw new ChaiUnavailableException("unable to create connection: " + e.getMessage(), ChaiErrors.getErrorForMessage(e.getMessage()));
    }
    if (!failOverWrapperChild) {
        providerImpl = addProviderWrappers(providerImpl);
        getCentralService().registerProvider(providerImpl);
    }
    return providerImpl;
}
Also used : ChaiUnavailableException(com.novell.ldapchai.exception.ChaiUnavailableException) IOException(java.io.IOException) ChaiException(com.novell.ldapchai.exception.ChaiException) ChaiException(com.novell.ldapchai.exception.ChaiException) IOException(java.io.IOException) InvocationTargetException(java.lang.reflect.InvocationTargetException) ChaiUnavailableException(com.novell.ldapchai.exception.ChaiUnavailableException)

Example 3 with ChaiUnavailableException

use of com.novell.ldapchai.exception.ChaiUnavailableException in project ldapchai by ldapchai.

the class JNDIProviderImpl method compareStringAttribute.

@LdapOperation
public final boolean compareStringAttribute(final String entryDN, final String attributeName, final String value) throws ChaiUnavailableException, ChaiOperationException {
    activityPreCheck();
    getInputValidator().compareStringAttribute(entryDN, attributeName, value);
    final byte[] ba;
    try {
        ba = value.getBytes("UTF-8");
    } catch (UnsupportedEncodingException e) {
        throw new UnsupportedOperationException(e);
    }
    // Set up the search controls
    final SearchControls ctls = new SearchControls();
    // Return no attrs
    ctls.setReturningAttributes(new String[0]);
    // Search object only
    ctls.setSearchScope(SearchControls.OBJECT_SCOPE);
    final LdapContext ldapConnection = getLdapConnection();
    NamingEnumeration<SearchResult> answer = null;
    boolean result = false;
    try {
        answer = ldapConnection.search(addJndiEscape(entryDN), "(" + attributeName + "={0})", new Object[] { ba }, ctls);
        result = answer.hasMore();
    } catch (NamingException e) {
        convertNamingException(e);
    } finally {
        if (answer != null) {
            try {
                answer.close();
            } catch (Exception e) {
            /* action not required */
            }
        }
    }
    return result;
}
Also used : UnsupportedEncodingException(java.io.UnsupportedEncodingException) SearchControls(javax.naming.directory.SearchControls) SearchResult(javax.naming.directory.SearchResult) NamingException(javax.naming.NamingException) InitialLdapContext(javax.naming.ldap.InitialLdapContext) LdapContext(javax.naming.ldap.LdapContext) NamingException(javax.naming.NamingException) ChaiOperationException(com.novell.ldapchai.exception.ChaiOperationException) IOException(java.io.IOException) KeyManagementException(java.security.KeyManagementException) ServiceUnavailableException(javax.naming.ServiceUnavailableException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) ChaiUnavailableException(com.novell.ldapchai.exception.ChaiUnavailableException) CommunicationException(javax.naming.CommunicationException) SizeLimitExceededException(javax.naming.SizeLimitExceededException) UnsupportedEncodingException(java.io.UnsupportedEncodingException)

Example 4 with ChaiUnavailableException

use of com.novell.ldapchai.exception.ChaiUnavailableException in project ldapchai by ldapchai.

the class JNDIProviderImpl method replaceBinaryAttribute.

@LdapOperation
@ModifyOperation
public final void replaceBinaryAttribute(final String entryDN, final String attributeName, final byte[] oldValue, final byte[] newValue) throws ChaiUnavailableException, ChaiOperationException {
    activityPreCheck();
    getInputValidator().replaceBinaryAttribute(entryDN, attributeName, oldValue, newValue);
    final String jndiBinarySetting = "java.naming.ldap.attributes.binary";
    // Create the ModificationItem
    final ModificationItem[] modificationItem = new ModificationItem[2];
    {
        // Create a BasicAttribute for the old value.
        final BasicAttribute oldValueOperation = new BasicAttribute(attributeName, oldValue);
        // Populate the ModificationItem array with the removal of the old value.
        modificationItem[0] = new ModificationItem(DirContext.REMOVE_ATTRIBUTE, oldValueOperation);
        // Create a BasicAttribute for the new value.
        final BasicAttribute newValueOperation = new BasicAttribute(attributeName, newValue);
        // Populate the ModificationItem array with the removal of the old value.
        modificationItem[1] = new ModificationItem(DirContext.ADD_ATTRIBUTE, newValueOperation);
    }
    // get ldap connection
    final LdapContext ldapConnection = getLdapConnection();
    // Modify the Attributes.
    try {
        ldapConnection.modifyAttributes(addJndiEscape(entryDN), modificationItem);
        // inform jndi the attribute is binary.
        ldapConnection.addToEnvironment(jndiBinarySetting, attributeName);
    } catch (NamingException e) {
        convertNamingException(e);
    } finally {
        // clean up jndi environment
        try {
            ldapConnection.removeFromEnvironment(jndiBinarySetting);
        } catch (Exception e) {
        // doesnt matter
        }
    }
}
Also used : BasicAttribute(javax.naming.directory.BasicAttribute) ModificationItem(javax.naming.directory.ModificationItem) NamingException(javax.naming.NamingException) InitialLdapContext(javax.naming.ldap.InitialLdapContext) LdapContext(javax.naming.ldap.LdapContext) NamingException(javax.naming.NamingException) ChaiOperationException(com.novell.ldapchai.exception.ChaiOperationException) IOException(java.io.IOException) KeyManagementException(java.security.KeyManagementException) ServiceUnavailableException(javax.naming.ServiceUnavailableException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) ChaiUnavailableException(com.novell.ldapchai.exception.ChaiUnavailableException) CommunicationException(javax.naming.CommunicationException) SizeLimitExceededException(javax.naming.SizeLimitExceededException) UnsupportedEncodingException(java.io.UnsupportedEncodingException)

Example 5 with ChaiUnavailableException

use of com.novell.ldapchai.exception.ChaiUnavailableException 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 &lt; 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;
}
Also used : ChaiUnavailableException(com.novell.ldapchai.exception.ChaiUnavailableException) ChaiProvider(com.novell.ldapchai.provider.ChaiProvider) ChaiOperationException(com.novell.ldapchai.exception.ChaiOperationException) ChaiConfiguration(com.novell.ldapchai.provider.ChaiConfiguration) ChaiUnavailableException(com.novell.ldapchai.exception.ChaiUnavailableException) ChaiOperationException(com.novell.ldapchai.exception.ChaiOperationException)

Aggregations

ChaiUnavailableException (com.novell.ldapchai.exception.ChaiUnavailableException)76 PwmUnrecoverableException (password.pwm.error.PwmUnrecoverableException)51 ErrorInformation (password.pwm.error.ErrorInformation)37 ChaiOperationException (com.novell.ldapchai.exception.ChaiOperationException)32 PwmOperationalException (password.pwm.error.PwmOperationalException)25 IOException (java.io.IOException)22 ChaiUser (com.novell.ldapchai.ChaiUser)20 PwmException (password.pwm.error.PwmException)16 UserIdentity (password.pwm.bean.UserIdentity)15 ChaiProvider (com.novell.ldapchai.provider.ChaiProvider)13 PwmApplication (password.pwm.PwmApplication)12 LinkedHashMap (java.util.LinkedHashMap)11 ServletException (javax.servlet.ServletException)10 Configuration (password.pwm.config.Configuration)10 Instant (java.time.Instant)9 HashMap (java.util.HashMap)8 ArrayList (java.util.ArrayList)7 List (java.util.List)7 FormConfiguration (password.pwm.config.value.data.FormConfiguration)7 ChaiException (com.novell.ldapchai.exception.ChaiException)6