< prev index next >
src/java.naming/share/classes/com/sun/jndi/ldap/LdapCtxFactory.java
Print this page
@@ -23,13 +23,18 @@
* questions.
*/
package com.sun.jndi.ldap;
+import java.lang.reflect.Constructor;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
import java.util.Hashtable;
+import java.util.List;
import java.util.Vector;
import java.util.Enumeration;
+import java.util.function.BiFunction;
import javax.naming.*;
import javax.naming.directory.*;
import javax.naming.spi.ObjectFactory;
import javax.naming.spi.InitialContextFactory;
@@ -156,60 +161,85 @@
"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);
+ throws NamingException
+ {
+ NamingException ne = new NamingException();
+ DirContext ctx;
+ try {
+ List<String> urls = getDnsUrls(url, env);
+ if (urls.size() == 0) {
+ String factory;
+ if (env.contains(LdapCtx.DNS_PROVIDER)) {
+ factory = (String) env.get(LdapCtx.DNS_PROVIDER);
+ } else {
+ factory = "com.sun.jndi.ldap.DefaultDnsProvider";
+ }
+ throw new NamingException(
+ factory + " was unable to resolve a valid ldap url");
+ }
+
+ for (String u : urls) {
+ LdapURL ldapUrl = new LdapURL(u);
String dn = ldapUrl.getDN();
String host = ldapUrl.getHost();
int port = ldapUrl.getPort();
- String[] hostports;
- String domainName = null;
+ ctx = new LdapCtx(dn, host, port, env, ldapUrl.useSsl());
+ // Record the URL that created the context
+ ((LdapCtx) ctx).setProviderUrl(u);
+ return ctx;
+ }
+ } catch (Exception e) {
+ ne.setRootCause(e);
+ }
+ throw ne;
+ }
+
+ @SuppressWarnings("unchecked")
+ private static List<String> getDnsUrls(String url, Hashtable<?,?> env)
+ throws Exception
+ {
+ BiFunction<String, Hashtable<?,?>, List<String>> dnsProvider = 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;
+ if (env.containsKey(LdapCtx.DNS_PROVIDER)) {
+ PrivilegedAction<ClassLoader> act =
+ Thread.currentThread()::getContextClassLoader;
+ ClassLoader cl = AccessController.doPrivileged(act);
+ Class<?> cls = Class.forName(
+ (String) env.get(LdapCtx.DNS_PROVIDER), true, cl);
+ Constructor<?> ctor = cls.getConstructor();
+ dnsProvider =
+ (BiFunction<String, Hashtable<?,?>, List<String>>) ctor.newInstance();
}
- ctx = getUsingURLs(newUrls, env);
- // Associate the derived domain name with the context
- ((LdapCtx)ctx).setDomainName(domainName);
- } else {
- ctx = new LdapCtx(dn, host, port, env, ldapUrl.useSsl());
- // Record the URL that created the context
- ((LdapCtx)ctx).setProviderUrl(url);
+ if (dnsProvider == null) {
+ dnsProvider = new DefaultLdapDnsProvider();
}
- return ctx;
+
+ return dnsProvider.apply(url, env);
}
/*
* 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 ne = new NamingException();
+ DirContext ctx;
+ for (String u : urls) {
try {
- return getUsingURL(urls[i], env);
+ ctx = getUsingURL(u, env);
+ LdapURL ldapUrl = new LdapURL(u);
+ // Associate the derived domain name with the context
+ ((LdapCtx) ctx).setDomainName(
+ ServiceLocator.mapDnToDomainName(ldapUrl.getDN()));
+ return ctx;
} catch (AuthenticationException e) {
throw e;
} catch (NamingException e) {
ne = e;
}
< prev index next >