| 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 */  | 
 | 
 | 
 | 
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();  | 
 | 
        }  | 
 | 
    }  | 
 | 
}  |