|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
|
|
package com.sun.jndi.ldap; |
|
|
|
import java.util.Hashtable; |
|
import java.util.Vector; |
|
import java.util.Enumeration; |
|
|
|
import javax.naming.*; |
|
import javax.naming.directory.*; |
|
import javax.naming.spi.ObjectFactory; |
|
import javax.naming.spi.InitialContextFactory; |
|
import javax.naming.ldap.Control; |
|
|
|
import com.sun.jndi.ldap.spi.LdapDnsProviderResult; |
|
import com.sun.jndi.url.ldap.ldapURLContextFactory; |
|
|
|
final public class LdapCtxFactory implements ObjectFactory, InitialContextFactory { |
|
|
|
|
|
*/ |
|
public final static String ADDRESS_TYPE = "URL"; |
|
|
|
// ----------------- ObjectFactory interface -------------------- |
|
|
|
public Object getObjectInstance(Object ref, Name name, Context nameCtx, |
|
Hashtable<?,?> env) throws Exception { |
|
|
|
if (!isLdapRef(ref)) { |
|
return null; |
|
} |
|
ObjectFactory factory = new ldapURLContextFactory(); |
|
String[] urls = getURLs((Reference)ref); |
|
return factory.getObjectInstance(urls, name, nameCtx, env); |
|
} |
|
|
|
// ----------------- InitialContext interface -------------------- |
|
|
|
public Context getInitialContext(Hashtable<?,?> envprops) |
|
throws NamingException { |
|
|
|
try { |
|
String providerUrl = (envprops != null) ? |
|
(String)envprops.get(Context.PROVIDER_URL) : null; |
|
|
|
|
|
if (providerUrl == null) { |
|
return new LdapCtx("", LdapCtx.DEFAULT_HOST, |
|
LdapCtx.DEFAULT_PORT, envprops, false); |
|
} |
|
|
|
|
|
String[] urls = LdapURL.fromList(providerUrl); |
|
|
|
if (urls.length == 0) { |
|
throw new ConfigurationException(Context.PROVIDER_URL + |
|
" property does not contain a URL"); |
|
} |
|
|
|
|
|
return getLdapCtxInstance(urls, envprops); |
|
|
|
} catch (LdapReferralException e) { |
|
|
|
if (envprops != null && |
|
"throw".equals(envprops.get(Context.REFERRAL))) { |
|
throw e; |
|
} |
|
|
|
Control[] bindCtls = (envprops != null)? |
|
(Control[])envprops.get(LdapCtx.BIND_CONTROLS) : null; |
|
|
|
return (LdapCtx)e.getReferralContext(envprops, bindCtls); |
|
} |
|
} |
|
|
|
|
|
|
|
*/ |
|
private static boolean isLdapRef(Object obj) { |
|
|
|
if (!(obj instanceof Reference)) { |
|
return false; |
|
} |
|
String thisClassName = LdapCtxFactory.class.getName(); |
|
Reference ref = (Reference)obj; |
|
|
|
return thisClassName.equals(ref.getFactoryClassName()); |
|
} |
|
|
|
|
|
|
|
*/ |
|
private static String[] getURLs(Reference ref) throws NamingException { |
|
|
|
int size = 0; |
|
String[] urls = new String[ref.size()]; |
|
|
|
Enumeration<RefAddr> addrs = ref.getAll(); |
|
while (addrs.hasMoreElements()) { |
|
RefAddr addr = addrs.nextElement(); |
|
|
|
if ((addr instanceof StringRefAddr) && |
|
addr.getType().equals(ADDRESS_TYPE)) { |
|
|
|
urls[size++] = (String)addr.getContent(); |
|
} |
|
} |
|
if (size == 0) { |
|
throw (new ConfigurationException( |
|
"Reference contains no valid addresses")); |
|
} |
|
|
|
|
|
if (size == ref.size()) { |
|
return urls; |
|
} |
|
String[] urls2 = new String[size]; |
|
System.arraycopy(urls, 0, urls2, 0, size); |
|
return urls2; |
|
} |
|
|
|
// ------------ Utilities used by other classes ---------------- |
|
|
|
public static DirContext getLdapCtxInstance(Object urlInfo, Hashtable<?,?> env) |
|
throws NamingException { |
|
|
|
if (urlInfo instanceof String) { |
|
return getUsingURL((String)urlInfo, env); |
|
} else if (urlInfo instanceof String[]) { |
|
return getUsingURLs((String[])urlInfo, env); |
|
} else { |
|
throw new IllegalArgumentException( |
|
"argument must be an LDAP URL String or array of them"); |
|
} |
|
} |
|
|
|
private static DirContext getUsingURL(String url, Hashtable<?,?> env) |
|
throws NamingException |
|
{ |
|
try { |
|
LdapDnsProviderResult r = |
|
LdapDnsProviderService.getInstance().lookupEndpoints(url, env); |
|
LdapCtx ctx; |
|
NamingException lastException = null; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
for (String u : r.getEndpoints()) { |
|
try { |
|
ctx = getLdapCtxFromUrl( |
|
r.getDomainName(), url, new LdapURL(u), env); |
|
return ctx; |
|
} catch (NamingException e) { |
|
|
|
lastException = e; |
|
} |
|
} |
|
|
|
if (lastException != null) { |
|
throw lastException; |
|
} |
|
|
|
// lookupEndpoints returned an LdapDnsProviderResult with an empty |
|
|
|
throw new NamingException("Could not resolve a valid ldap host"); |
|
} catch (NamingException e) { |
|
// lookupEndpoints(url, env) may throw a NamingException, which |
|
|
|
throw e; |
|
} catch (Exception e) { |
|
NamingException ex = new NamingException(); |
|
ex.setRootCause(e); |
|
throw ex; |
|
} |
|
} |
|
|
|
private static LdapCtx getLdapCtxFromUrl(String domain, |
|
String url, |
|
LdapURL u, |
|
Hashtable<?,?> env) |
|
throws NamingException |
|
{ |
|
String dn = u.getDN(); |
|
String host = u.getHost(); |
|
int port = u.getPort(); |
|
LdapCtx ctx = new LdapCtx(dn, host, port, env, u.useSsl()); |
|
ctx.setDomainName(domain); |
|
|
|
ctx.setProviderUrl(url); |
|
return ctx; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
private static DirContext getUsingURLs(String[] urls, Hashtable<?,?> env) |
|
throws NamingException |
|
{ |
|
NamingException ex = null; |
|
for (String u : urls) { |
|
try { |
|
return getUsingURL(u, env); |
|
} catch (NamingException e) { |
|
ex = e; |
|
} |
|
} |
|
throw ex; |
|
} |
|
|
|
|
|
|
|
*/ |
|
public static Attribute createTypeNameAttr(Class<?> cl) { |
|
Vector<String> v = new Vector<>(10); |
|
String[] types = getTypeNames(cl, v); |
|
if (types.length > 0) { |
|
BasicAttribute tAttr = |
|
new BasicAttribute(Obj.JAVA_ATTRIBUTES[Obj.TYPENAME]); |
|
for (int i = 0; i < types.length; i++) { |
|
tAttr.add(types[i]); |
|
} |
|
return tAttr; |
|
} |
|
return null; |
|
} |
|
|
|
private static String[] getTypeNames(Class<?> currentClass, Vector<String> v) { |
|
|
|
getClassesAux(currentClass, v); |
|
Class<?>[] members = currentClass.getInterfaces(); |
|
for (int i = 0; i < members.length; i++) { |
|
getClassesAux(members[i], v); |
|
} |
|
String[] ret = new String[v.size()]; |
|
int i = 0; |
|
|
|
for (String name : v) { |
|
ret[i++] = name; |
|
} |
|
return ret; |
|
} |
|
|
|
private static void getClassesAux(Class<?> currentClass, Vector<String> v) { |
|
if (!v.contains(currentClass.getName())) { |
|
v.addElement(currentClass.getName()); |
|
} |
|
currentClass = currentClass.getSuperclass(); |
|
|
|
while (currentClass != null) { |
|
getTypeNames(currentClass, v); |
|
currentClass = currentClass.getSuperclass(); |
|
} |
|
} |
|
} |