49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara/*
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * CDDL HEADER START
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara *
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * The contents of this file are subject to the terms of the
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * Common Development and Distribution License, Version 1.0 only
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * (the "License"). You may not use this file except in compliance
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * with the License.
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara *
8cf870d281dc8c242f083d14dfef05f24aa5fceeJnRouvignac * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
8cf870d281dc8c242f083d14dfef05f24aa5fceeJnRouvignac * or http://forgerock.org/license/CDDLv1.0.html.
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * See the License for the specific language governing permissions
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * and limitations under the License.
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara *
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * When distributing Covered Code, include this CDDL HEADER in each
8cf870d281dc8c242f083d14dfef05f24aa5fceeJnRouvignac * file and include the License file at legal-notices/CDDLv1_0.txt.
8cf870d281dc8c242f083d14dfef05f24aa5fceeJnRouvignac * If applicable, add the following below this CDDL HEADER, with the
8cf870d281dc8c242f083d14dfef05f24aa5fceeJnRouvignac * fields enclosed by brackets "[]" replaced with your own identifying
8cf870d281dc8c242f083d14dfef05f24aa5fceeJnRouvignac * information:
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * Portions Copyright [yyyy] [name of copyright owner]
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara *
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * CDDL HEADER END
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara *
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara *
617eca34ddbeeea84d0763be5acb799a36b2c57djvergara * Copyright 2008-2010 Sun Microsystems, Inc.
64c1a3c40117e62ddf3d2d6c09f6ebec51187829cjr * Portions Copyright 2012-2014 ForgeRock AS
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara */
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergarapackage org.opends.admin.ads.util;
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergaraimport java.io.IOException;
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergaraimport java.net.ConnectException;
b369c17aec493f598a0fefe8885418cd3db596e9jvergaraimport java.net.URI;
4e75d856e42d4ea01d4a4ed72534266c45b4a99djvergaraimport java.security.GeneralSecurityException;
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergaraimport java.util.HashSet;
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergaraimport java.util.Hashtable;
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergaraimport java.util.Set;
b369c17aec493f598a0fefe8885418cd3db596e9jvergaraimport java.util.logging.Level;
b369c17aec493f598a0fefe8885418cd3db596e9jvergaraimport java.util.logging.Logger;
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergaraimport javax.naming.CommunicationException;
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergaraimport javax.naming.Context;
239f425b7a5059eceffdb4fb3a80842f4d6ac7b2ludovicpimport javax.naming.NamingEnumeration;
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergaraimport javax.naming.NamingException;
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergaraimport javax.naming.directory.Attribute;
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergaraimport javax.naming.directory.Attributes;
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergaraimport javax.naming.directory.SearchControls;
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergaraimport javax.naming.directory.SearchResult;
d25372dc8e65a9ed019a88fdf659ca61313f1b31jcduffimport javax.naming.ldap.Control;
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergaraimport javax.naming.ldap.InitialLdapContext;
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergaraimport javax.naming.ldap.StartTlsRequest;
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergaraimport javax.naming.ldap.StartTlsResponse;
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergaraimport javax.net.ssl.HostnameVerifier;
1c296036a417944f7b568e510fa612f647f5a62flutoffimport javax.net.ssl.KeyManager;
4e75d856e42d4ea01d4a4ed72534266c45b4a99djvergaraimport javax.net.ssl.SSLHandshakeException;
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergaraimport javax.net.ssl.TrustManager;
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara
64c1a3c40117e62ddf3d2d6c09f6ebec51187829cjrimport org.opends.server.replication.plugin.EntryHistorical;
6206ed2d27885390956a5dc0be3271367f84b20bJnRouvignacimport org.opends.server.schema.SchemaConstants;
6206ed2d27885390956a5dc0be3271367f84b20bJnRouvignac
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara/**
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * Class providing some utilities to create LDAP connections using JNDI and
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * to manage entries retrieved using JNDI.
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara *
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara */
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergarapublic class ConnectionUtils
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara{
908fad360e5d610ebaef4e634787343eac17be6fjvergara private static final int DEFAULT_LDAP_CONNECT_TIMEOUT = 30000;
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara
b369c17aec493f598a0fefe8885418cd3db596e9jvergara private static final String STARTTLS_PROPERTY =
b369c17aec493f598a0fefe8885418cd3db596e9jvergara "org.opends.connectionutils.isstarttls";
b369c17aec493f598a0fefe8885418cd3db596e9jvergara
b369c17aec493f598a0fefe8885418cd3db596e9jvergara static private final Logger LOG =
b369c17aec493f598a0fefe8885418cd3db596e9jvergara Logger.getLogger(ConnectionUtils.class.getName());
b369c17aec493f598a0fefe8885418cd3db596e9jvergara
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara /**
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * Private constructor: this class cannot be instantiated.
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara */
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara private ConnectionUtils()
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara {
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara }
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara /**
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * Creates a clear LDAP connection and returns the corresponding LdapContext.
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * This methods uses the specified parameters to create a JNDI environment
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * hashtable and creates an InitialLdapContext instance.
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara *
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * @param ldapURL
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * the target LDAP URL
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * @param dn
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * passed as Context.SECURITY_PRINCIPAL if not null
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * @param pwd
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * passed as Context.SECURITY_CREDENTIALS if not null
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * @param timeout
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * passed as com.sun.jndi.ldap.connect.timeout if > 0
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * @param env
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * null or additional environment properties
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara *
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * @throws NamingException
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * the exception thrown when instantiating InitialLdapContext
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara *
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * @return the created InitialLdapContext.
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * @see javax.naming.Context
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * @see javax.naming.ldap.InitialLdapContext
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara */
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara public static InitialLdapContext createLdapContext(String ldapURL, String dn,
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara String pwd, int timeout, Hashtable<String, String> env)
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara throws NamingException
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara {
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara if (env != null)
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara { // We clone 'env' so that we can modify it freely
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara env = new Hashtable<String, String>(env);
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara } else
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara {
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara env = new Hashtable<String, String>();
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara }
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara env.put(Context.INITIAL_CONTEXT_FACTORY,
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara "com.sun.jndi.ldap.LdapCtxFactory");
64c1a3c40117e62ddf3d2d6c09f6ebec51187829cjr env.put("java.naming.ldap.attributes.binary",
64c1a3c40117e62ddf3d2d6c09f6ebec51187829cjr EntryHistorical.HISTORICAL_ATTRIBUTE_NAME);
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara env.put(Context.PROVIDER_URL, ldapURL);
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara if (timeout >= 1)
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara {
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara env.put("com.sun.jndi.ldap.connect.timeout", String.valueOf(timeout));
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara }
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara if (dn != null)
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara {
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara env.put(Context.SECURITY_PRINCIPAL, dn);
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara }
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara if (pwd != null)
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara {
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara env.put(Context.SECURITY_CREDENTIALS, pwd);
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara }
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara /* Contains the DirContext and the Exception if any */
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara final Object[] pair = new Object[]
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara { null, null };
617eca34ddbeeea84d0763be5acb799a36b2c57djvergara final Hashtable<String, String> fEnv = env;
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara Thread t = new Thread(new Runnable()
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara {
7d34d5efd6624b7e07f0adb2f78a163a953a5bd2ludo @Override
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara public void run()
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara {
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara try
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara {
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara pair[0] = new InitialLdapContext(fEnv, null);
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara } catch (NamingException ne)
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara {
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara pair[1] = ne;
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara } catch (Throwable t)
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara {
cd43bd05ce6da5cb1dff1d9a5ad2abf200f6257djvergara t.printStackTrace();
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara pair[1] = t;
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara }
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara }
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara });
bc5e0f71f2fc08541ad7c86b8fe04cdf6e67e6f6lutoff t.setDaemon(true);
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara return getInitialLdapContext(t, pair, timeout);
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara }
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara /**
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * Creates an LDAPS connection and returns the corresponding LdapContext.
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * This method uses the TrusteSocketFactory class so that the specified
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * trust manager gets called during the SSL handshake. If trust manager is
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * null, certificates are not verified during SSL handshake.
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara *
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * @param ldapsURL the target *LDAPS* URL.
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * @param dn passed as Context.SECURITY_PRINCIPAL if not null.
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * @param pwd passed as Context.SECURITY_CREDENTIALS if not null.
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * @param timeout passed as com.sun.jndi.ldap.connect.timeout if > 0.
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * @param env null or additional environment properties.
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * @param trustManager null or the trust manager to be invoked during SSL
7d34d5efd6624b7e07f0adb2f78a163a953a5bd2ludo * negotiation.
1c296036a417944f7b568e510fa612f647f5a62flutoff * @param keyManager null or the key manager to be invoked during SSL
7d34d5efd6624b7e07f0adb2f78a163a953a5bd2ludo * negotiation.
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * @return the established connection with the given parameters.
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara *
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * @throws NamingException the exception thrown when instantiating
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * InitialLdapContext.
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara *
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * @see javax.naming.Context
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * @see javax.naming.ldap.InitialLdapContext
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * @see TrustedSocketFactory
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara */
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara public static InitialLdapContext createLdapsContext(String ldapsURL,
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara String dn, String pwd, int timeout, Hashtable<String, String> env,
1c296036a417944f7b568e510fa612f647f5a62flutoff TrustManager trustManager, KeyManager keyManager) throws NamingException {
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara if (env != null)
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara { // We clone 'env' so that we can modify it freely
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara env = new Hashtable<String, String>(env);
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara } else
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara {
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara env = new Hashtable<String, String>();
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara }
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara env.put(Context.INITIAL_CONTEXT_FACTORY,
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara "com.sun.jndi.ldap.LdapCtxFactory");
64c1a3c40117e62ddf3d2d6c09f6ebec51187829cjr env.put("java.naming.ldap.attributes.binary",
64c1a3c40117e62ddf3d2d6c09f6ebec51187829cjr EntryHistorical.HISTORICAL_ATTRIBUTE_NAME);
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara env.put(Context.PROVIDER_URL, ldapsURL);
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara env.put("java.naming.ldap.factory.socket",
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara org.opends.admin.ads.util.TrustedSocketFactory.class.getName());
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara if (dn != null)
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara {
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara env.put(Context.SECURITY_PRINCIPAL, dn);
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara }
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara if (pwd != null)
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara {
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara env.put(Context.SECURITY_CREDENTIALS, pwd);
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara }
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara if (trustManager == null)
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara {
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara trustManager = new BlindTrustManager();
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara }
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara /* Contains the DirContext and the Exception if any */
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara final Object[] pair = new Object[] {null, null};
617eca34ddbeeea84d0763be5acb799a36b2c57djvergara final Hashtable<String, String> fEnv = env;
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara final TrustManager fTrustManager = trustManager;
aa1c5b5e91acfcbb567ce78e3e3efd7d22fc5492lutoff final KeyManager fKeyManager = keyManager;
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara Thread t = new Thread(new Runnable() {
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara public void run() {
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara try {
1c296036a417944f7b568e510fa612f647f5a62flutoff TrustedSocketFactory.setCurrentThreadTrustManager(fTrustManager,
aa1c5b5e91acfcbb567ce78e3e3efd7d22fc5492lutoff fKeyManager);
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara pair[0] = new InitialLdapContext(fEnv, null);
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara } catch (NamingException ne) {
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara pair[1] = ne;
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara } catch (RuntimeException re) {
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara pair[1] = re;
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara }
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara }
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara });
bc5e0f71f2fc08541ad7c86b8fe04cdf6e67e6f6lutoff t.setDaemon(true);
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara return getInitialLdapContext(t, pair, timeout);
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara }
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara
d25372dc8e65a9ed019a88fdf659ca61313f1b31jcduff /**
d25372dc8e65a9ed019a88fdf659ca61313f1b31jcduff * Clones the provided InitialLdapContext and returns a connection using
d25372dc8e65a9ed019a88fdf659ca61313f1b31jcduff * the same parameters.
7d34d5efd6624b7e07f0adb2f78a163a953a5bd2ludo * @param ctx the connection to be cloned.
b138eb36479de1170a91322a845ad9e977c3af56ludovicp * @param timeout the timeout to establish the connection in milliseconds.
b138eb36479de1170a91322a845ad9e977c3af56ludovicp * Use {@code 0} to express no timeout.
d25372dc8e65a9ed019a88fdf659ca61313f1b31jcduff * @param trustManager the trust manager to be used to connect.
d25372dc8e65a9ed019a88fdf659ca61313f1b31jcduff * @param keyManager the key manager to be used to connect.
d25372dc8e65a9ed019a88fdf659ca61313f1b31jcduff * @return the new InitialLdapContext connected to the server.
d25372dc8e65a9ed019a88fdf659ca61313f1b31jcduff * @throws NamingException if there was an error creating the new connection.
d25372dc8e65a9ed019a88fdf659ca61313f1b31jcduff */
d25372dc8e65a9ed019a88fdf659ca61313f1b31jcduff public static InitialLdapContext cloneInitialLdapContext(
d25372dc8e65a9ed019a88fdf659ca61313f1b31jcduff final InitialLdapContext ctx, int timeout, TrustManager trustManager,
d25372dc8e65a9ed019a88fdf659ca61313f1b31jcduff KeyManager keyManager) throws NamingException
d25372dc8e65a9ed019a88fdf659ca61313f1b31jcduff {
d25372dc8e65a9ed019a88fdf659ca61313f1b31jcduff Hashtable<?, ?> env = ctx.getEnvironment();
d25372dc8e65a9ed019a88fdf659ca61313f1b31jcduff Control[] ctls = ctx.getConnectControls();
d25372dc8e65a9ed019a88fdf659ca61313f1b31jcduff Control[] newCtls = null;
d25372dc8e65a9ed019a88fdf659ca61313f1b31jcduff if (ctls != null)
d25372dc8e65a9ed019a88fdf659ca61313f1b31jcduff {
d25372dc8e65a9ed019a88fdf659ca61313f1b31jcduff newCtls = new Control[ctls.length];
7d34d5efd6624b7e07f0adb2f78a163a953a5bd2ludo System.arraycopy(ctls, 0, newCtls, 0, ctls.length);
d25372dc8e65a9ed019a88fdf659ca61313f1b31jcduff }
d25372dc8e65a9ed019a88fdf659ca61313f1b31jcduff /* Contains the DirContext and the Exception if any */
d25372dc8e65a9ed019a88fdf659ca61313f1b31jcduff final Object[] pair = new Object[] {null, null};
617eca34ddbeeea84d0763be5acb799a36b2c57djvergara final Hashtable<?, ?> fEnv = env;
d25372dc8e65a9ed019a88fdf659ca61313f1b31jcduff final TrustManager fTrustManager = trustManager;
d25372dc8e65a9ed019a88fdf659ca61313f1b31jcduff final KeyManager fKeyManager = keyManager;
d25372dc8e65a9ed019a88fdf659ca61313f1b31jcduff final Control[] fNewCtls = newCtls;
d25372dc8e65a9ed019a88fdf659ca61313f1b31jcduff
d25372dc8e65a9ed019a88fdf659ca61313f1b31jcduff Thread t = new Thread(new Runnable() {
7d34d5efd6624b7e07f0adb2f78a163a953a5bd2ludo @Override
d25372dc8e65a9ed019a88fdf659ca61313f1b31jcduff public void run() {
d25372dc8e65a9ed019a88fdf659ca61313f1b31jcduff try {
d25372dc8e65a9ed019a88fdf659ca61313f1b31jcduff if (isSSL(ctx) || isStartTLS(ctx))
d25372dc8e65a9ed019a88fdf659ca61313f1b31jcduff {
d25372dc8e65a9ed019a88fdf659ca61313f1b31jcduff TrustedSocketFactory.setCurrentThreadTrustManager(fTrustManager,
d25372dc8e65a9ed019a88fdf659ca61313f1b31jcduff fKeyManager);
d25372dc8e65a9ed019a88fdf659ca61313f1b31jcduff }
d25372dc8e65a9ed019a88fdf659ca61313f1b31jcduff pair[0] = new InitialLdapContext(fEnv, fNewCtls);
d25372dc8e65a9ed019a88fdf659ca61313f1b31jcduff
d25372dc8e65a9ed019a88fdf659ca61313f1b31jcduff } catch (NamingException ne) {
d25372dc8e65a9ed019a88fdf659ca61313f1b31jcduff pair[1] = ne;
d25372dc8e65a9ed019a88fdf659ca61313f1b31jcduff
d25372dc8e65a9ed019a88fdf659ca61313f1b31jcduff } catch (RuntimeException re) {
d25372dc8e65a9ed019a88fdf659ca61313f1b31jcduff pair[1] = re;
d25372dc8e65a9ed019a88fdf659ca61313f1b31jcduff }
d25372dc8e65a9ed019a88fdf659ca61313f1b31jcduff }
d25372dc8e65a9ed019a88fdf659ca61313f1b31jcduff });
d25372dc8e65a9ed019a88fdf659ca61313f1b31jcduff return getInitialLdapContext(t, pair, timeout);
d25372dc8e65a9ed019a88fdf659ca61313f1b31jcduff }
d25372dc8e65a9ed019a88fdf659ca61313f1b31jcduff
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara /**
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * Creates an LDAP+StartTLS connection and returns the corresponding
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * LdapContext.
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * This method first creates an LdapContext with anonymous bind. Then it
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * requests a StartTlsRequest extended operation. The StartTlsResponse is
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * setup with the specified hostname verifier. Negotiation is done using a
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * TrustSocketFactory so that the specified TrustManager gets called during
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * the SSL handshake.
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * If trust manager is null, certificates are not checked during SSL
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * handshake.
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara *
5ef1a9f815af36a5c1c7a85a526e6887b68d920flutoff * @param ldapURL the target *LDAP* URL.
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * @param dn passed as Context.SECURITY_PRINCIPAL if not null.
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * @param pwd passed as Context.SECURITY_CREDENTIALS if not null.
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * @param timeout passed as com.sun.jndi.ldap.connect.timeout if > 0.
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * @param env null or additional environment properties.
06b934ca1d5196671ac1a5b507052035f003697blutoff * @param trustManager null or the trust manager to be invoked during SSL
7d34d5efd6624b7e07f0adb2f78a163a953a5bd2ludo * negotiation.
06b934ca1d5196671ac1a5b507052035f003697blutoff * @param keyManager null or the key manager to be invoked during SSL
7d34d5efd6624b7e07f0adb2f78a163a953a5bd2ludo * negotiation.
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * @param verifier null or the hostname verifier to be setup in the
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * StartTlsResponse.
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * @return the established connection with the given parameters.
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara *
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * @throws NamingException the exception thrown when instantiating
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * InitialLdapContext.
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara *
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * @see javax.naming.Context
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * @see javax.naming.ldap.InitialLdapContext
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * @see javax.naming.ldap.StartTlsRequest
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * @see javax.naming.ldap.StartTlsResponse
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * @see TrustedSocketFactory
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara */
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara
5ef1a9f815af36a5c1c7a85a526e6887b68d920flutoff public static InitialLdapContext createStartTLSContext(String ldapURL,
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara String dn, String pwd, int timeout, Hashtable<String, String> env,
06b934ca1d5196671ac1a5b507052035f003697blutoff TrustManager trustManager, KeyManager keyManager,
06b934ca1d5196671ac1a5b507052035f003697blutoff HostnameVerifier verifier)
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara throws NamingException
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara {
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara if (trustManager == null)
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara {
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara trustManager = new BlindTrustManager();
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara }
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara if (verifier == null) {
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara verifier = new BlindHostnameVerifier();
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara }
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara if (env != null)
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara { // We clone 'env' to modify it freely
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara env = new Hashtable<String, String>(env);
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara }
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara else
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara {
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara env = new Hashtable<String, String>();
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara }
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara env.put(Context.INITIAL_CONTEXT_FACTORY,
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara "com.sun.jndi.ldap.LdapCtxFactory");
64c1a3c40117e62ddf3d2d6c09f6ebec51187829cjr env.put("java.naming.ldap.attributes.binary",
64c1a3c40117e62ddf3d2d6c09f6ebec51187829cjr EntryHistorical.HISTORICAL_ATTRIBUTE_NAME);
5ef1a9f815af36a5c1c7a85a526e6887b68d920flutoff env.put(Context.PROVIDER_URL, ldapURL);
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara env.put(Context.SECURITY_AUTHENTICATION , "none");
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara /* Contains the DirContext and the Exception if any */
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara final Object[] pair = new Object[] {null, null};
617eca34ddbeeea84d0763be5acb799a36b2c57djvergara final Hashtable<?, ?> fEnv = env;
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara final String fDn = dn;
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara final String fPwd = pwd;
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara final TrustManager fTrustManager = trustManager;
06b934ca1d5196671ac1a5b507052035f003697blutoff final KeyManager fKeyManager = keyManager;
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara final HostnameVerifier fVerifier = verifier;
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara Thread t = new Thread(new Runnable() {
7d34d5efd6624b7e07f0adb2f78a163a953a5bd2ludo @Override
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara public void run() {
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara try {
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara StartTlsResponse tls;
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara InitialLdapContext result = new InitialLdapContext(fEnv, null);
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara tls = (StartTlsResponse) result.extendedOperation(
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara new StartTlsRequest());
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara tls.setHostnameVerifier(fVerifier);
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara try
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara {
06b934ca1d5196671ac1a5b507052035f003697blutoff tls.negotiate(new TrustedSocketFactory(fTrustManager,fKeyManager));
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara }
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara catch(IOException x) {
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara NamingException xx;
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara xx = new CommunicationException(
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara "Failed to negotiate Start TLS operation");
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara xx.initCause(x);
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara result.close();
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara throw xx;
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara }
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara
b369c17aec493f598a0fefe8885418cd3db596e9jvergara result.addToEnvironment(STARTTLS_PROPERTY, "true");
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara if (fDn != null)
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara {
b369c17aec493f598a0fefe8885418cd3db596e9jvergara
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara result.addToEnvironment(Context.SECURITY_AUTHENTICATION , "simple");
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara result.addToEnvironment(Context.SECURITY_PRINCIPAL, fDn);
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara if (fPwd != null)
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara {
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara result.addToEnvironment(Context.SECURITY_CREDENTIALS, fPwd);
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara }
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara result.reconnect(null);
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara }
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara pair[0] = result;
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara } catch (NamingException ne)
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara {
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara pair[1] = ne;
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara } catch (RuntimeException re)
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara {
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara pair[1] = re;
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara }
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara }
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara });
bc5e0f71f2fc08541ad7c86b8fe04cdf6e67e6f6lutoff t.setDaemon(true);
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara return getInitialLdapContext(t, pair, timeout);
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara }
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara
b369c17aec493f598a0fefe8885418cd3db596e9jvergara /**
b369c17aec493f598a0fefe8885418cd3db596e9jvergara * Returns the LDAP URL used in the provided InitialLdapContext.
b369c17aec493f598a0fefe8885418cd3db596e9jvergara * @param ctx the context to analyze.
b369c17aec493f598a0fefe8885418cd3db596e9jvergara * @return the LDAP URL used in the provided InitialLdapContext.
b369c17aec493f598a0fefe8885418cd3db596e9jvergara */
b369c17aec493f598a0fefe8885418cd3db596e9jvergara public static String getLdapUrl(InitialLdapContext ctx)
b369c17aec493f598a0fefe8885418cd3db596e9jvergara {
b369c17aec493f598a0fefe8885418cd3db596e9jvergara String s = null;
b369c17aec493f598a0fefe8885418cd3db596e9jvergara try
b369c17aec493f598a0fefe8885418cd3db596e9jvergara {
b369c17aec493f598a0fefe8885418cd3db596e9jvergara s = (String)ctx.getEnvironment().get(Context.PROVIDER_URL);
b369c17aec493f598a0fefe8885418cd3db596e9jvergara }
b369c17aec493f598a0fefe8885418cd3db596e9jvergara catch (NamingException ne)
b369c17aec493f598a0fefe8885418cd3db596e9jvergara {
b369c17aec493f598a0fefe8885418cd3db596e9jvergara // This is really strange. Seems like a bug somewhere.
b369c17aec493f598a0fefe8885418cd3db596e9jvergara LOG.log(Level.WARNING, "Naming exception getting environment of "+ctx,
b369c17aec493f598a0fefe8885418cd3db596e9jvergara ne);
b369c17aec493f598a0fefe8885418cd3db596e9jvergara }
b369c17aec493f598a0fefe8885418cd3db596e9jvergara return s;
b369c17aec493f598a0fefe8885418cd3db596e9jvergara }
b369c17aec493f598a0fefe8885418cd3db596e9jvergara
b369c17aec493f598a0fefe8885418cd3db596e9jvergara /**
b369c17aec493f598a0fefe8885418cd3db596e9jvergara * Returns the host name used in the provided InitialLdapContext.
b369c17aec493f598a0fefe8885418cd3db596e9jvergara * @param ctx the context to analyze.
b369c17aec493f598a0fefe8885418cd3db596e9jvergara * @return the host name used in the provided InitialLdapContext.
b369c17aec493f598a0fefe8885418cd3db596e9jvergara */
b369c17aec493f598a0fefe8885418cd3db596e9jvergara public static String getHostName(InitialLdapContext ctx)
b369c17aec493f598a0fefe8885418cd3db596e9jvergara {
b369c17aec493f598a0fefe8885418cd3db596e9jvergara String s = null;
b369c17aec493f598a0fefe8885418cd3db596e9jvergara try
b369c17aec493f598a0fefe8885418cd3db596e9jvergara {
b369c17aec493f598a0fefe8885418cd3db596e9jvergara URI ldapURL = new URI(getLdapUrl(ctx));
b369c17aec493f598a0fefe8885418cd3db596e9jvergara s = ldapURL.getHost();
b369c17aec493f598a0fefe8885418cd3db596e9jvergara }
b369c17aec493f598a0fefe8885418cd3db596e9jvergara catch (Throwable t)
b369c17aec493f598a0fefe8885418cd3db596e9jvergara {
b369c17aec493f598a0fefe8885418cd3db596e9jvergara // This is really strange. Seems like a bug somewhere.
b369c17aec493f598a0fefe8885418cd3db596e9jvergara LOG.log(Level.WARNING, "Error getting host: "+t, t);
b369c17aec493f598a0fefe8885418cd3db596e9jvergara }
b369c17aec493f598a0fefe8885418cd3db596e9jvergara return s;
b369c17aec493f598a0fefe8885418cd3db596e9jvergara }
b369c17aec493f598a0fefe8885418cd3db596e9jvergara
b369c17aec493f598a0fefe8885418cd3db596e9jvergara /**
b369c17aec493f598a0fefe8885418cd3db596e9jvergara * Returns the port number used in the provided InitialLdapContext.
b369c17aec493f598a0fefe8885418cd3db596e9jvergara * @param ctx the context to analyze.
b369c17aec493f598a0fefe8885418cd3db596e9jvergara * @return the port number used in the provided InitialLdapContext.
b369c17aec493f598a0fefe8885418cd3db596e9jvergara */
b369c17aec493f598a0fefe8885418cd3db596e9jvergara public static int getPort(InitialLdapContext ctx)
b369c17aec493f598a0fefe8885418cd3db596e9jvergara {
b369c17aec493f598a0fefe8885418cd3db596e9jvergara int port = -1;
b369c17aec493f598a0fefe8885418cd3db596e9jvergara try
b369c17aec493f598a0fefe8885418cd3db596e9jvergara {
b369c17aec493f598a0fefe8885418cd3db596e9jvergara URI ldapURL = new URI(getLdapUrl(ctx));
b369c17aec493f598a0fefe8885418cd3db596e9jvergara port = ldapURL.getPort();
b369c17aec493f598a0fefe8885418cd3db596e9jvergara }
b369c17aec493f598a0fefe8885418cd3db596e9jvergara catch (Throwable t)
b369c17aec493f598a0fefe8885418cd3db596e9jvergara {
b369c17aec493f598a0fefe8885418cd3db596e9jvergara // This is really strange. Seems like a bug somewhere.
b369c17aec493f598a0fefe8885418cd3db596e9jvergara LOG.log(Level.WARNING, "Error getting port: "+t, t);
b369c17aec493f598a0fefe8885418cd3db596e9jvergara }
b369c17aec493f598a0fefe8885418cd3db596e9jvergara return port;
b369c17aec493f598a0fefe8885418cd3db596e9jvergara }
b369c17aec493f598a0fefe8885418cd3db596e9jvergara
b369c17aec493f598a0fefe8885418cd3db596e9jvergara /**
b369c17aec493f598a0fefe8885418cd3db596e9jvergara * Returns the host port representation of the server to which this
b369c17aec493f598a0fefe8885418cd3db596e9jvergara * context is connected.
b369c17aec493f598a0fefe8885418cd3db596e9jvergara * @param ctx the context to analyze.
b369c17aec493f598a0fefe8885418cd3db596e9jvergara * @return the host port representation of the server to which this
b369c17aec493f598a0fefe8885418cd3db596e9jvergara * context is connected.
b369c17aec493f598a0fefe8885418cd3db596e9jvergara */
b369c17aec493f598a0fefe8885418cd3db596e9jvergara public static String getHostPort(InitialLdapContext ctx)
b369c17aec493f598a0fefe8885418cd3db596e9jvergara {
b369c17aec493f598a0fefe8885418cd3db596e9jvergara return getHostName(ctx)+":"+getPort(ctx);
b369c17aec493f598a0fefe8885418cd3db596e9jvergara }
b369c17aec493f598a0fefe8885418cd3db596e9jvergara
b369c17aec493f598a0fefe8885418cd3db596e9jvergara /**
b369c17aec493f598a0fefe8885418cd3db596e9jvergara * Returns the bind DN used in the provided InitialLdapContext.
b369c17aec493f598a0fefe8885418cd3db596e9jvergara * @param ctx the context to analyze.
b369c17aec493f598a0fefe8885418cd3db596e9jvergara * @return the bind DN used in the provided InitialLdapContext.
b369c17aec493f598a0fefe8885418cd3db596e9jvergara */
b369c17aec493f598a0fefe8885418cd3db596e9jvergara public static String getBindDN(InitialLdapContext ctx)
b369c17aec493f598a0fefe8885418cd3db596e9jvergara {
b369c17aec493f598a0fefe8885418cd3db596e9jvergara String bindDN = null;
b369c17aec493f598a0fefe8885418cd3db596e9jvergara try
b369c17aec493f598a0fefe8885418cd3db596e9jvergara {
b369c17aec493f598a0fefe8885418cd3db596e9jvergara bindDN = (String)ctx.getEnvironment().get(Context.SECURITY_PRINCIPAL);
b369c17aec493f598a0fefe8885418cd3db596e9jvergara }
b369c17aec493f598a0fefe8885418cd3db596e9jvergara catch (NamingException ne)
b369c17aec493f598a0fefe8885418cd3db596e9jvergara {
b369c17aec493f598a0fefe8885418cd3db596e9jvergara // This is really strange. Seems like a bug somewhere.
b369c17aec493f598a0fefe8885418cd3db596e9jvergara LOG.log(Level.WARNING, "Naming exception getting environment of "+ctx,
b369c17aec493f598a0fefe8885418cd3db596e9jvergara ne);
b369c17aec493f598a0fefe8885418cd3db596e9jvergara }
b369c17aec493f598a0fefe8885418cd3db596e9jvergara return bindDN;
b369c17aec493f598a0fefe8885418cd3db596e9jvergara }
b369c17aec493f598a0fefe8885418cd3db596e9jvergara
b369c17aec493f598a0fefe8885418cd3db596e9jvergara /**
b369c17aec493f598a0fefe8885418cd3db596e9jvergara * Returns the password used in the provided InitialLdapContext.
b369c17aec493f598a0fefe8885418cd3db596e9jvergara * @param ctx the context to analyze.
b369c17aec493f598a0fefe8885418cd3db596e9jvergara * @return the password used in the provided InitialLdapContext.
b369c17aec493f598a0fefe8885418cd3db596e9jvergara */
b369c17aec493f598a0fefe8885418cd3db596e9jvergara public static String getBindPassword(InitialLdapContext ctx)
b369c17aec493f598a0fefe8885418cd3db596e9jvergara {
b369c17aec493f598a0fefe8885418cd3db596e9jvergara String bindPwd = null;
b369c17aec493f598a0fefe8885418cd3db596e9jvergara try
b369c17aec493f598a0fefe8885418cd3db596e9jvergara {
b369c17aec493f598a0fefe8885418cd3db596e9jvergara bindPwd = (String)ctx.getEnvironment().get(Context.SECURITY_CREDENTIALS);
b369c17aec493f598a0fefe8885418cd3db596e9jvergara }
b369c17aec493f598a0fefe8885418cd3db596e9jvergara catch (NamingException ne)
b369c17aec493f598a0fefe8885418cd3db596e9jvergara {
b369c17aec493f598a0fefe8885418cd3db596e9jvergara // This is really strange. Seems like a bug somewhere.
b369c17aec493f598a0fefe8885418cd3db596e9jvergara LOG.log(Level.WARNING, "Naming exception getting environment of "+ctx,
b369c17aec493f598a0fefe8885418cd3db596e9jvergara ne);
b369c17aec493f598a0fefe8885418cd3db596e9jvergara }
b369c17aec493f598a0fefe8885418cd3db596e9jvergara return bindPwd;
b369c17aec493f598a0fefe8885418cd3db596e9jvergara }
b369c17aec493f598a0fefe8885418cd3db596e9jvergara
b369c17aec493f598a0fefe8885418cd3db596e9jvergara /**
b369c17aec493f598a0fefe8885418cd3db596e9jvergara * Tells whether we are using SSL in the provided InitialLdapContext.
b369c17aec493f598a0fefe8885418cd3db596e9jvergara * @param ctx the context to analyze.
b369c17aec493f598a0fefe8885418cd3db596e9jvergara * @return <CODE>true</CODE> if we are using SSL and <CODE>false</CODE>
b369c17aec493f598a0fefe8885418cd3db596e9jvergara * otherwise.
b369c17aec493f598a0fefe8885418cd3db596e9jvergara */
b369c17aec493f598a0fefe8885418cd3db596e9jvergara public static boolean isSSL(InitialLdapContext ctx)
b369c17aec493f598a0fefe8885418cd3db596e9jvergara {
b369c17aec493f598a0fefe8885418cd3db596e9jvergara boolean isSSL = false;
b369c17aec493f598a0fefe8885418cd3db596e9jvergara try
b369c17aec493f598a0fefe8885418cd3db596e9jvergara {
7d34d5efd6624b7e07f0adb2f78a163a953a5bd2ludo isSSL = getLdapUrl(ctx).toLowerCase().startsWith("ldaps");
b369c17aec493f598a0fefe8885418cd3db596e9jvergara }
b369c17aec493f598a0fefe8885418cd3db596e9jvergara catch (Throwable t)
b369c17aec493f598a0fefe8885418cd3db596e9jvergara {
b369c17aec493f598a0fefe8885418cd3db596e9jvergara // This is really strange. Seems like a bug somewhere.
b369c17aec493f598a0fefe8885418cd3db596e9jvergara LOG.log(Level.WARNING, "Error getting if is SSL "+t, t);
b369c17aec493f598a0fefe8885418cd3db596e9jvergara }
b369c17aec493f598a0fefe8885418cd3db596e9jvergara return isSSL;
b369c17aec493f598a0fefe8885418cd3db596e9jvergara }
b369c17aec493f598a0fefe8885418cd3db596e9jvergara
b369c17aec493f598a0fefe8885418cd3db596e9jvergara /**
b369c17aec493f598a0fefe8885418cd3db596e9jvergara * Tells whether we are using StartTLS in the provided InitialLdapContext.
b369c17aec493f598a0fefe8885418cd3db596e9jvergara * @param ctx the context to analyze.
b369c17aec493f598a0fefe8885418cd3db596e9jvergara * @return <CODE>true</CODE> if we are using StartTLS and <CODE>false</CODE>
b369c17aec493f598a0fefe8885418cd3db596e9jvergara * otherwise.
b369c17aec493f598a0fefe8885418cd3db596e9jvergara */
b369c17aec493f598a0fefe8885418cd3db596e9jvergara public static boolean isStartTLS(InitialLdapContext ctx)
b369c17aec493f598a0fefe8885418cd3db596e9jvergara {
b369c17aec493f598a0fefe8885418cd3db596e9jvergara boolean isStartTLS = false;
b369c17aec493f598a0fefe8885418cd3db596e9jvergara try
b369c17aec493f598a0fefe8885418cd3db596e9jvergara {
b369c17aec493f598a0fefe8885418cd3db596e9jvergara isStartTLS = "true".equalsIgnoreCase((String)ctx.getEnvironment().get(
b369c17aec493f598a0fefe8885418cd3db596e9jvergara STARTTLS_PROPERTY));
b369c17aec493f598a0fefe8885418cd3db596e9jvergara }
b369c17aec493f598a0fefe8885418cd3db596e9jvergara catch (NamingException ne)
b369c17aec493f598a0fefe8885418cd3db596e9jvergara {
b369c17aec493f598a0fefe8885418cd3db596e9jvergara // This is really strange. Seems like a bug somewhere.
b369c17aec493f598a0fefe8885418cd3db596e9jvergara LOG.log(Level.WARNING, "Naming exception getting environment of "+ctx,
b369c17aec493f598a0fefe8885418cd3db596e9jvergara ne);
b369c17aec493f598a0fefe8885418cd3db596e9jvergara }
b369c17aec493f598a0fefe8885418cd3db596e9jvergara return isStartTLS;
b369c17aec493f598a0fefe8885418cd3db596e9jvergara }
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara /**
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * Method used to know if we can connect as administrator in a server with a
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * given password and dn.
7d34d5efd6624b7e07f0adb2f78a163a953a5bd2ludo * @param ldapUrl the LDAP URL of the server.
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * @param dn the dn to be used.
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * @param pwd the password to be used.
b138eb36479de1170a91322a845ad9e977c3af56ludovicp * @param timeout the timeout to establish the connection in milliseconds.
b138eb36479de1170a91322a845ad9e977c3af56ludovicp * Use {@code 0} to express no timeout.
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * @return <CODE>true</CODE> if we can connect and read the configuration and
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * <CODE>false</CODE> otherwise.
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara */
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara public static boolean canConnectAsAdministrativeUser(String ldapUrl,
b138eb36479de1170a91322a845ad9e977c3af56ludovicp String dn, String pwd, int timeout)
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara {
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara boolean canConnectAsAdministrativeUser = false;
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara try
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara {
b369c17aec493f598a0fefe8885418cd3db596e9jvergara InitialLdapContext ctx;
b369c17aec493f598a0fefe8885418cd3db596e9jvergara if (ldapUrl.toLowerCase().startsWith("ldap:"))
b369c17aec493f598a0fefe8885418cd3db596e9jvergara {
b138eb36479de1170a91322a845ad9e977c3af56ludovicp ctx = createLdapContext(ldapUrl, dn, pwd, timeout,
b369c17aec493f598a0fefe8885418cd3db596e9jvergara null);
b369c17aec493f598a0fefe8885418cd3db596e9jvergara }
b369c17aec493f598a0fefe8885418cd3db596e9jvergara else
b369c17aec493f598a0fefe8885418cd3db596e9jvergara {
b138eb36479de1170a91322a845ad9e977c3af56ludovicp ctx = createLdapsContext(ldapUrl, dn, pwd, timeout,
b369c17aec493f598a0fefe8885418cd3db596e9jvergara null, null, null);
b369c17aec493f598a0fefe8885418cd3db596e9jvergara }
b369c17aec493f598a0fefe8885418cd3db596e9jvergara
b369c17aec493f598a0fefe8885418cd3db596e9jvergara canConnectAsAdministrativeUser = connectedAsAdministrativeUser(ctx);
b369c17aec493f598a0fefe8885418cd3db596e9jvergara } catch (NamingException ne)
b369c17aec493f598a0fefe8885418cd3db596e9jvergara {
b369c17aec493f598a0fefe8885418cd3db596e9jvergara // Nothing to do.
b369c17aec493f598a0fefe8885418cd3db596e9jvergara } catch (Throwable t)
b369c17aec493f598a0fefe8885418cd3db596e9jvergara {
b369c17aec493f598a0fefe8885418cd3db596e9jvergara throw new IllegalStateException("Unexpected throwable.", t);
b369c17aec493f598a0fefe8885418cd3db596e9jvergara }
b369c17aec493f598a0fefe8885418cd3db596e9jvergara return canConnectAsAdministrativeUser;
b369c17aec493f598a0fefe8885418cd3db596e9jvergara }
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara
b369c17aec493f598a0fefe8885418cd3db596e9jvergara /**
b369c17aec493f598a0fefe8885418cd3db596e9jvergara * Method used to know if we are connected as administrator in a server with a
b369c17aec493f598a0fefe8885418cd3db596e9jvergara * given InitialLdapContext.
b369c17aec493f598a0fefe8885418cd3db596e9jvergara * @param ctx the context.
b369c17aec493f598a0fefe8885418cd3db596e9jvergara * @return <CODE>true</CODE> if we are connected and read the configuration
b369c17aec493f598a0fefe8885418cd3db596e9jvergara * and <CODE>false</CODE> otherwise.
b369c17aec493f598a0fefe8885418cd3db596e9jvergara */
b369c17aec493f598a0fefe8885418cd3db596e9jvergara public static boolean connectedAsAdministrativeUser(InitialLdapContext ctx)
b369c17aec493f598a0fefe8885418cd3db596e9jvergara {
b369c17aec493f598a0fefe8885418cd3db596e9jvergara boolean connectedAsAdministrativeUser = false;
b369c17aec493f598a0fefe8885418cd3db596e9jvergara try
b369c17aec493f598a0fefe8885418cd3db596e9jvergara {
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara /*
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * Search for the config to check that it is the directory manager.
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara */
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara SearchControls searchControls = new SearchControls();
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara searchControls.setSearchScope(
b369c17aec493f598a0fefe8885418cd3db596e9jvergara SearchControls. OBJECT_SCOPE);
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara searchControls.setReturningAttributes(
6206ed2d27885390956a5dc0be3271367f84b20bJnRouvignac new String[] { SchemaConstants.NO_ATTRIBUTES });
239f425b7a5059eceffdb4fb3a80842f4d6ac7b2ludovicp NamingEnumeration<SearchResult> sr =
239f425b7a5059eceffdb4fb3a80842f4d6ac7b2ludovicp ctx.search("cn=config", "objectclass=*", searchControls);
239f425b7a5059eceffdb4fb3a80842f4d6ac7b2ludovicp try
239f425b7a5059eceffdb4fb3a80842f4d6ac7b2ludovicp {
239f425b7a5059eceffdb4fb3a80842f4d6ac7b2ludovicp while (sr.hasMore())
239f425b7a5059eceffdb4fb3a80842f4d6ac7b2ludovicp {
239f425b7a5059eceffdb4fb3a80842f4d6ac7b2ludovicp sr.next();
239f425b7a5059eceffdb4fb3a80842f4d6ac7b2ludovicp }
239f425b7a5059eceffdb4fb3a80842f4d6ac7b2ludovicp }
239f425b7a5059eceffdb4fb3a80842f4d6ac7b2ludovicp finally
239f425b7a5059eceffdb4fb3a80842f4d6ac7b2ludovicp {
7d34d5efd6624b7e07f0adb2f78a163a953a5bd2ludo try
7d34d5efd6624b7e07f0adb2f78a163a953a5bd2ludo {
7d34d5efd6624b7e07f0adb2f78a163a953a5bd2ludo sr.close();
7d34d5efd6624b7e07f0adb2f78a163a953a5bd2ludo }
7d34d5efd6624b7e07f0adb2f78a163a953a5bd2ludo catch(Exception ex)
7d34d5efd6624b7e07f0adb2f78a163a953a5bd2ludo {
7d34d5efd6624b7e07f0adb2f78a163a953a5bd2ludo LOG.log(Level.WARNING,
7d34d5efd6624b7e07f0adb2f78a163a953a5bd2ludo "Unexpected error closing enumeration on cn=Config entry", ex);
7d34d5efd6624b7e07f0adb2f78a163a953a5bd2ludo }
239f425b7a5059eceffdb4fb3a80842f4d6ac7b2ludovicp }
b369c17aec493f598a0fefe8885418cd3db596e9jvergara connectedAsAdministrativeUser = true;
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara } catch (NamingException ne)
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara {
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara // Nothing to do.
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara } catch (Throwable t)
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara {
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara throw new IllegalStateException("Unexpected throwable.", t);
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara }
b369c17aec493f598a0fefe8885418cd3db596e9jvergara return connectedAsAdministrativeUser;
1c296036a417944f7b568e510fa612f647f5a62flutoff }
1c296036a417944f7b568e510fa612f647f5a62flutoff
1c296036a417944f7b568e510fa612f647f5a62flutoff /**
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * This is just a commodity method used to try to get an InitialLdapContext.
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * @param t the Thread to be used to create the InitialLdapContext.
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * @param pair an Object[] array that contains the InitialLdapContext and the
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * Throwable if any occurred.
b138eb36479de1170a91322a845ad9e977c3af56ludovicp * @param timeout the timeout in milliseconds. If we do not get to create the
b138eb36479de1170a91322a845ad9e977c3af56ludovicp * connection before the timeout a CommunicationException will be thrown.
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * @return the created InitialLdapContext
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * @throws NamingException if something goes wrong during the creation.
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara */
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara private static InitialLdapContext getInitialLdapContext(Thread t,
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara Object[] pair, int timeout) throws NamingException
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara {
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara try
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara {
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara if (timeout > 0)
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara {
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara t.start();
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara t.join(timeout);
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara } else
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara {
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara t.run();
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara }
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara } catch (InterruptedException x)
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara {
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara // This might happen for problems in sockets
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara // so it does not necessarily imply a bug
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara }
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara boolean throwException = false;
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara if ((timeout > 0) && t.isAlive())
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara {
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara t.interrupt();
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara try
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara {
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara t.join(2000);
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara } catch (InterruptedException x)
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara {
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara // This might happen for problems in sockets
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara // so it does not necessarily imply a bug
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara }
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara throwException = true;
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara }
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara if ((pair[0] == null) && (pair[1] == null))
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara {
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara throwException = true;
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara }
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara if (throwException)
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara {
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara NamingException xx;
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara ConnectException x = new ConnectException("Connection timed out");
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara xx = new CommunicationException("Connection timed out");
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara xx.initCause(x);
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara throw xx;
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara }
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara if (pair[1] != null)
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara {
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara if (pair[1] instanceof NamingException)
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara {
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara throw (NamingException) pair[1];
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara } else if (pair[1] instanceof RuntimeException)
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara {
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara throw (RuntimeException) pair[1];
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara } else if (pair[1] instanceof Throwable)
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara {
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara throw new IllegalStateException("Unexpected throwable occurred",
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara (Throwable) pair[1]);
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara }
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara }
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara return (InitialLdapContext) pair[0];
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara }
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara /**
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * Returns the default LDAP timeout in milliseconds when we try to connect to
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * a server.
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * @return the default LDAP timeout in milliseconds when we try to connect to
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * a server.
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara */
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara public static int getDefaultLDAPTimeout()
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara {
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara return DEFAULT_LDAP_CONNECT_TIMEOUT;
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara }
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara /**
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * Returns the String that can be used to represent a given host name in a
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * LDAP URL.
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * This method must be used when we have IPv6 addresses (the address in the
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * LDAP URL must be enclosed with brackets).
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * @param host the host name.
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * @return the String that can be used to represent a given host name in a
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * LDAP URL.
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara */
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara public static String getHostNameForLdapUrl(String host)
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara {
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara if ((host != null) && host.indexOf(":") != -1)
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara {
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara // Assume an IPv6 address has been specified and adds the brackets
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara // for the URL.
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara host = host.trim();
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara if (!host.startsWith("["))
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara {
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara host = "["+host;
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara }
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara if (!host.endsWith("]"))
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara {
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara host = host + "]";
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara }
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara }
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara return host;
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara }
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara
4d7a9734afbc1f92d79b9d3bf092d56998c13bd7jvergara /**
4d7a9734afbc1f92d79b9d3bf092d56998c13bd7jvergara * Returns the LDAP URL for the provided parameters.
4d7a9734afbc1f92d79b9d3bf092d56998c13bd7jvergara * @param host the host name.
4d7a9734afbc1f92d79b9d3bf092d56998c13bd7jvergara * @param port the LDAP port.
4d7a9734afbc1f92d79b9d3bf092d56998c13bd7jvergara * @param useSSL whether to use SSL or not.
4d7a9734afbc1f92d79b9d3bf092d56998c13bd7jvergara * @return the LDAP URL for the provided parameters.
4d7a9734afbc1f92d79b9d3bf092d56998c13bd7jvergara */
4d7a9734afbc1f92d79b9d3bf092d56998c13bd7jvergara public static String getLDAPUrl(String host, int port, boolean useSSL)
4d7a9734afbc1f92d79b9d3bf092d56998c13bd7jvergara {
4d7a9734afbc1f92d79b9d3bf092d56998c13bd7jvergara String ldapUrl;
4d7a9734afbc1f92d79b9d3bf092d56998c13bd7jvergara host = getHostNameForLdapUrl(host);
4d7a9734afbc1f92d79b9d3bf092d56998c13bd7jvergara if (useSSL)
4d7a9734afbc1f92d79b9d3bf092d56998c13bd7jvergara {
4d7a9734afbc1f92d79b9d3bf092d56998c13bd7jvergara ldapUrl = "ldaps://"+host+":"+port;
4d7a9734afbc1f92d79b9d3bf092d56998c13bd7jvergara }
4d7a9734afbc1f92d79b9d3bf092d56998c13bd7jvergara else
4d7a9734afbc1f92d79b9d3bf092d56998c13bd7jvergara {
4d7a9734afbc1f92d79b9d3bf092d56998c13bd7jvergara ldapUrl = "ldap://"+host+":"+port;
4d7a9734afbc1f92d79b9d3bf092d56998c13bd7jvergara }
4d7a9734afbc1f92d79b9d3bf092d56998c13bd7jvergara return ldapUrl;
4d7a9734afbc1f92d79b9d3bf092d56998c13bd7jvergara }
4d7a9734afbc1f92d79b9d3bf092d56998c13bd7jvergara
4e75d856e42d4ea01d4a4ed72534266c45b4a99djvergara /**
4e75d856e42d4ea01d4a4ed72534266c45b4a99djvergara * Tells whether the provided Throwable was caused because of a problem with
4e75d856e42d4ea01d4a4ed72534266c45b4a99djvergara * a certificate while trying to establish a connection.
4e75d856e42d4ea01d4a4ed72534266c45b4a99djvergara * @param t the Throwable to analyze.
4e75d856e42d4ea01d4a4ed72534266c45b4a99djvergara * @return <CODE>true</CODE> if the provided Throwable was caused because of a
4e75d856e42d4ea01d4a4ed72534266c45b4a99djvergara * problem with a certificate while trying to establish a connection and
4e75d856e42d4ea01d4a4ed72534266c45b4a99djvergara * <CODE>false</CODE> otherwise.
4e75d856e42d4ea01d4a4ed72534266c45b4a99djvergara */
4e75d856e42d4ea01d4a4ed72534266c45b4a99djvergara public static boolean isCertificateException(Throwable t)
4e75d856e42d4ea01d4a4ed72534266c45b4a99djvergara {
4e75d856e42d4ea01d4a4ed72534266c45b4a99djvergara boolean returnValue = false;
4e75d856e42d4ea01d4a4ed72534266c45b4a99djvergara
4e75d856e42d4ea01d4a4ed72534266c45b4a99djvergara while (!returnValue && (t != null))
4e75d856e42d4ea01d4a4ed72534266c45b4a99djvergara {
4e75d856e42d4ea01d4a4ed72534266c45b4a99djvergara returnValue = (t instanceof SSLHandshakeException) ||
4e75d856e42d4ea01d4a4ed72534266c45b4a99djvergara (t instanceof GeneralSecurityException);
4e75d856e42d4ea01d4a4ed72534266c45b4a99djvergara t = t.getCause();
4e75d856e42d4ea01d4a4ed72534266c45b4a99djvergara }
4e75d856e42d4ea01d4a4ed72534266c45b4a99djvergara
4e75d856e42d4ea01d4a4ed72534266c45b4a99djvergara return returnValue;
4e75d856e42d4ea01d4a4ed72534266c45b4a99djvergara }
4e75d856e42d4ea01d4a4ed72534266c45b4a99djvergara
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara /**
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * Returns the String representation of the first value of an attribute in a
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * LDAP entry.
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * @param entry the entry.
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * @param attrName the attribute name.
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * @return the String representation of the first value of an attribute in a
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * LDAP entry.
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * @throws NamingException if there is an error processing the entry.
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara */
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara static public String getFirstValue(SearchResult entry, String attrName)
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara throws NamingException
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara {
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara String v = null;
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara Attributes attrs = entry.getAttributes();
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara if (attrs != null)
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara {
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara Attribute attr = attrs.get(attrName);
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara if ((attr != null) && (attr.size() > 0))
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara {
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara Object o = attr.get();
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara if (o instanceof String)
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara {
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara v = (String)o;
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara }
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara else
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara {
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara v = String.valueOf(o);
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara }
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara }
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara }
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara return v;
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara }
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara /**
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * Returns a Set with the String representation of the values of an attribute
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * in a LDAP entry. The returned Set will never be null.
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * @param entry the entry.
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * @param attrName the attribute name.
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * @return a Set with the String representation of the values of an attribute
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * in a LDAP entry.
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara * @throws NamingException if there is an error processing the entry.
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara */
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara static public Set<String> getValues(SearchResult entry, String attrName)
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara throws NamingException
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara {
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara Set<String> values = new HashSet<String>();
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara Attributes attrs = entry.getAttributes();
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara if (attrs != null)
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara {
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara Attribute attr = attrs.get(attrName);
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara if (attr != null)
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara {
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara for (int i=0; i<attr.size(); i++)
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara {
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara values.add((String)attr.get(i));
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara }
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara }
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara }
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara return values;
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara }
49ce6d7c2babc40f2ad8d9c44637088e865919f3jvergara}