< prev index next >
src/java.naming/share/classes/com/sun/jndi/ldap/LdapCtxFactory.java
Print this page
@@ -23,16 +23,15 @@
* questions.
*/
package com.sun.jndi.ldap;
-import java.util.Hashtable;
-import java.util.Vector;
-import java.util.Enumeration;
+import java.util.*;
import javax.naming.*;
import javax.naming.directory.*;
+import javax.naming.spi.ldap.LdapDnsProviderResult;
import javax.naming.spi.ObjectFactory;
import javax.naming.spi.InitialContextFactory;
import javax.naming.ldap.Control;
import com.sun.jndi.url.ldap.ldapURLContextFactory;
@@ -156,67 +155,98 @@
"argument must be an LDAP URL String or array of them");
}
}
private static DirContext getUsingURL(String url, Hashtable<?,?> env)
- throws NamingException {
- DirContext ctx = null;
- LdapURL ldapUrl = new LdapURL(url);
- String dn = ldapUrl.getDN();
- String host = ldapUrl.getHost();
- int port = ldapUrl.getPort();
- String[] hostports;
- String domainName = null;
-
- // handle a URL with no hostport (ldap:/// or ldaps:///)
- // locate the LDAP service using the URL's distinguished name
- if (host == null &&
- port == -1 &&
- dn != null &&
- (domainName = ServiceLocator.mapDnToDomainName(dn)) != null &&
- (hostports = ServiceLocator.getLdapService(domainName, env))
- != null) {
- // Generate new URLs that include the discovered hostports.
- // Reuse the original URL scheme.
- String scheme = ldapUrl.getScheme() + "://";
- String[] newUrls = new String[hostports.length];
- String query = ldapUrl.getQuery();
- String urlSuffix = ldapUrl.getPath() + (query != null ? query : "");
- for (int i = 0; i < hostports.length; i++) {
- newUrls[i] = scheme + hostports[i] + urlSuffix;
- }
- ctx = getUsingURLs(newUrls, env);
- // Associate the derived domain name with the context
- ((LdapCtx)ctx).setDomainName(domainName);
+ throws NamingException
+ {
+ try {
+ LdapDnsProviderResult r =
+ LdapDnsProviderService.getInstance().lookupEndpoints(url, env);
+ LdapCtx ctx = null;
+ NamingException lastException = null;
+
+ /*
+ * Prior to this change we had been assuming that the url.getDN()
+ * should be converted to a domain name via
+ * ServiceLocator.mapDnToDomainName(url.getDN())
+ *
+ * However this is incorrect as we can't assume that the supplied
+ * url.getDN() is the same as the dns domain for the directory
+ * server.
+ *
+ * This means that we depend on the dnsProvider to return both
+ * the list of urls of individual hosts from which we attempt to
+ * create an LdapCtx from *AND* the domain name that they serve
+ *
+ * In order to do this the dnsProvider must return an
+ * {@link LdapDnsProviderResult}.
+ *
+ */
+ for (String u : r.getEndpoints()) {
+ try {
+ ctx = getLdapCtxFromUrl(
+ r.getDomainName(), new LdapURL(u), env);
+ } catch (NamingException e) {
+ // try the next element
+ lastException = e;
+ }
+ }
+
+ if (lastException != null) {
+ throw lastException;
+ }
+
+ if (ctx == null) {
+ // we have resolved them, but they are not valid
+ throw new NamingException("Could not resolve a valid ldap host");
+ }
- } else {
- ctx = new LdapCtx(dn, host, port, env, ldapUrl.useSsl());
// Record the URL that created the context
- ((LdapCtx)ctx).setProviderUrl(url);
+ ctx.setProviderUrl(url);
+ return ctx;
+ } catch (NamingException e) {
+ // getDnsUrls(url, env) may throw a NamingException, which there is
+ // no need to wrap.
+ throw e;
+ } catch (Exception e) {
+ NamingException ex = new NamingException();
+ ex.setRootCause(e);
+ throw ex;
+ }
}
+
+ private static LdapCtx getLdapCtxFromUrl(String domain,
+ LdapURL url,
+ Hashtable<?,?> env)
+ throws NamingException
+ {
+ String dn = url.getDN();
+ String host = url.getHost();
+ int port = url.getPort();
+ LdapCtx ctx = new LdapCtx(dn, host, port, env, url.useSsl());
+ ctx.setDomainName(domain);
return ctx;
}
/*
* Try each URL until one of them succeeds.
* If all URLs fail, throw one of the exceptions arbitrarily.
* Not pretty, but potentially more informative than returning null.
*/
private static DirContext getUsingURLs(String[] urls, Hashtable<?,?> env)
- throws NamingException {
- NamingException ne = null;
- DirContext ctx = null;
- for (int i = 0; i < urls.length; i++) {
+ throws NamingException
+ {
+ NamingException ex = null;
+ for (String u : urls) {
try {
- return getUsingURL(urls[i], env);
- } catch (AuthenticationException e) {
- throw e;
+ return getUsingURL(u, env);
} catch (NamingException e) {
- ne = e;
+ ex = e;
}
}
- throw ne;
+ throw ex;
}
/**
* Used by Obj and obj/RemoteToAttrs too so must be public
*/
< prev index next >