< prev index next >

src/java.naming/share/classes/com/sun/jndi/ldap/LdapCtxFactory.java

Print this page




   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.jndi.ldap;
  27 



  28 import java.util.Hashtable;

  29 import java.util.Vector;
  30 import java.util.Enumeration;

  31 
  32 import javax.naming.*;
  33 import javax.naming.directory.*;
  34 import javax.naming.spi.ObjectFactory;
  35 import javax.naming.spi.InitialContextFactory;
  36 import javax.naming.ldap.Control;
  37 
  38 import com.sun.jndi.url.ldap.ldapURLContextFactory;
  39 
  40 final public class LdapCtxFactory implements ObjectFactory, InitialContextFactory {
  41     /**
  42      * The type of each address in an LDAP reference.
  43      */
  44     public final static String ADDRESS_TYPE = "URL";
  45 
  46     // ----------------- ObjectFactory interface --------------------
  47 
  48     public Object getObjectInstance(Object ref, Name name, Context nameCtx,
  49         Hashtable<?,?> env) throws Exception {
  50 


 141         System.arraycopy(urls, 0, urls2, 0, size);
 142         return urls2;
 143     }
 144 
 145     // ------------ Utilities used by other classes ----------------
 146 
 147     public static DirContext getLdapCtxInstance(Object urlInfo, Hashtable<?,?> env)
 148             throws NamingException {
 149 
 150         if (urlInfo instanceof String) {
 151             return getUsingURL((String)urlInfo, env);
 152         } else if (urlInfo instanceof String[]) {
 153             return getUsingURLs((String[])urlInfo, env);
 154         } else {
 155             throw new IllegalArgumentException(
 156                 "argument must be an LDAP URL String or array of them");
 157         }
 158     }
 159 
 160     private static DirContext getUsingURL(String url, Hashtable<?,?> env)
 161             throws NamingException {
 162         DirContext ctx = null;
 163         LdapURL ldapUrl = new LdapURL(url);
















 164         String dn = ldapUrl.getDN();
 165         String host = ldapUrl.getHost();
 166         int port = ldapUrl.getPort();
 167         String[] hostports;
 168         String domainName = null;














 169 
 170         // handle a URL with no hostport (ldap:/// or ldaps:///)
 171         // locate the LDAP service using the URL's distinguished name
 172         if (host == null &&
 173             port == -1 &&
 174             dn != null &&
 175             (domainName = ServiceLocator.mapDnToDomainName(dn)) != null &&
 176             (hostports = ServiceLocator.getLdapService(domainName, env))
 177                 != null) {
 178             // Generate new URLs that include the discovered hostports.
 179             // Reuse the original URL scheme.
 180             String scheme = ldapUrl.getScheme() + "://";
 181             String[] newUrls = new String[hostports.length];
 182             String query = ldapUrl.getQuery();
 183             String urlSuffix = ldapUrl.getPath() + (query != null ? query : "");
 184             for (int i = 0; i < hostports.length; i++) {
 185                 newUrls[i] = scheme + hostports[i] + urlSuffix;
 186             }
 187             ctx = getUsingURLs(newUrls, env);
 188             // Associate the derived domain name with the context
 189             ((LdapCtx)ctx).setDomainName(domainName);
 190 
 191         } else {
 192             ctx = new LdapCtx(dn, host, port, env, ldapUrl.useSsl());
 193             // Record the URL that created the context
 194             ((LdapCtx)ctx).setProviderUrl(url);
 195         }
 196         return ctx;

 197     }
 198 
 199     /*
 200      * Try each URL until one of them succeeds.
 201      * If all URLs fail, throw one of the exceptions arbitrarily.
 202      * Not pretty, but potentially more informative than returning null.
 203      */
 204     private static DirContext getUsingURLs(String[] urls, Hashtable<?,?> env)
 205             throws NamingException {
 206         NamingException ne = null;
 207         DirContext ctx = null;
 208         for (int i = 0; i < urls.length; i++) {

 209             try {
 210                 return getUsingURL(urls[i], env);





 211             } catch (AuthenticationException e) {
 212                 throw e;
 213             } catch (NamingException e) {
 214                 ne = e;
 215             }
 216         }
 217         throw ne;
 218     }
 219 
 220     /**
 221      * Used by Obj and obj/RemoteToAttrs too so must be public
 222      */
 223     public static Attribute createTypeNameAttr(Class<?> cl) {
 224         Vector<String> v = new Vector<>(10);
 225         String[] types = getTypeNames(cl, v);
 226         if (types.length > 0) {
 227             BasicAttribute tAttr =
 228                 new BasicAttribute(Obj.JAVA_ATTRIBUTES[Obj.TYPENAME]);
 229             for (int i = 0; i < types.length; i++) {
 230                 tAttr.add(types[i]);




   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.jndi.ldap;
  27 
  28 import java.lang.reflect.Constructor;
  29 import java.security.AccessController;
  30 import java.security.PrivilegedAction;
  31 import java.util.Hashtable;
  32 import java.util.List;
  33 import java.util.Vector;
  34 import java.util.Enumeration;
  35 import java.util.function.BiFunction;
  36 
  37 import javax.naming.*;
  38 import javax.naming.directory.*;
  39 import javax.naming.spi.ObjectFactory;
  40 import javax.naming.spi.InitialContextFactory;
  41 import javax.naming.ldap.Control;
  42 
  43 import com.sun.jndi.url.ldap.ldapURLContextFactory;
  44 
  45 final public class LdapCtxFactory implements ObjectFactory, InitialContextFactory {
  46     /**
  47      * The type of each address in an LDAP reference.
  48      */
  49     public final static String ADDRESS_TYPE = "URL";
  50 
  51     // ----------------- ObjectFactory interface --------------------
  52 
  53     public Object getObjectInstance(Object ref, Name name, Context nameCtx,
  54         Hashtable<?,?> env) throws Exception {
  55 


 146         System.arraycopy(urls, 0, urls2, 0, size);
 147         return urls2;
 148     }
 149 
 150     // ------------ Utilities used by other classes ----------------
 151 
 152     public static DirContext getLdapCtxInstance(Object urlInfo, Hashtable<?,?> env)
 153             throws NamingException {
 154 
 155         if (urlInfo instanceof String) {
 156             return getUsingURL((String)urlInfo, env);
 157         } else if (urlInfo instanceof String[]) {
 158             return getUsingURLs((String[])urlInfo, env);
 159         } else {
 160             throw new IllegalArgumentException(
 161                 "argument must be an LDAP URL String or array of them");
 162         }
 163     }
 164 
 165     private static DirContext getUsingURL(String url, Hashtable<?,?> env)
 166             throws NamingException
 167     {
 168         NamingException ne = new NamingException();
 169         DirContext ctx;
 170         try {
 171             List<String> urls = getDnsUrls(url, env);
 172             if (urls.size() == 0) {
 173                 String factory;
 174                 if (env.contains(LdapCtx.DNS_PROVIDER)) {
 175                     factory = (String) env.get(LdapCtx.DNS_PROVIDER);
 176                 } else {
 177                     factory = "com.sun.jndi.ldap.DefaultDnsProvider";
 178                 }
 179                 throw new NamingException(
 180                         factory + " was unable to resolve a valid ldap url");
 181             }
 182 
 183             for (String u : urls) {
 184                 LdapURL ldapUrl = new LdapURL(u);
 185                 String dn = ldapUrl.getDN();
 186                 String host = ldapUrl.getHost();
 187                 int port = ldapUrl.getPort();
 188                 ctx = new LdapCtx(dn, host, port, env, ldapUrl.useSsl());
 189                 // Record the URL that created the context
 190                 ((LdapCtx) ctx).setProviderUrl(u);
 191                 return ctx;
 192             }
 193         } catch (Exception e) {
 194             ne.setRootCause(e);
 195         }
 196         throw ne;
 197     }
 198 
 199     @SuppressWarnings("unchecked")
 200     private static List<String> getDnsUrls(String url, Hashtable<?,?> env)
 201             throws Exception
 202     {
 203         BiFunction<String, Hashtable<?,?>, List<String>> dnsProvider = null;
 204 
 205         if (env.containsKey(LdapCtx.DNS_PROVIDER)) {
 206             PrivilegedAction<ClassLoader> act =
 207                     Thread.currentThread()::getContextClassLoader;
 208             ClassLoader cl = AccessController.doPrivileged(act);
 209             Class<?> cls = Class.forName(
 210                     (String) env.get(LdapCtx.DNS_PROVIDER), true, cl);
 211             Constructor<?> ctor = cls.getConstructor();
 212             dnsProvider =
 213                     (BiFunction<String, Hashtable<?,?>, List<String>>) ctor.newInstance();







 214         }



 215 
 216         if (dnsProvider == null) {
 217             dnsProvider = new DefaultLdapDnsProvider();


 218         }
 219 
 220         return dnsProvider.apply(url, env);
 221     }
 222 
 223     /*
 224      * Try each URL until one of them succeeds.
 225      * If all URLs fail, throw one of the exceptions arbitrarily.
 226      * Not pretty, but potentially more informative than returning null.
 227      */
 228     private static DirContext getUsingURLs(String[] urls, Hashtable<?,?> env)
 229             throws NamingException
 230     {
 231         NamingException ne = new NamingException();
 232         DirContext ctx;
 233         for (String u : urls) {
 234             try {
 235                 ctx = getUsingURL(u, env);
 236                 LdapURL ldapUrl = new LdapURL(u);
 237                 // Associate the derived domain name with the context
 238                 ((LdapCtx) ctx).setDomainName(
 239                         ServiceLocator.mapDnToDomainName(ldapUrl.getDN()));
 240                 return ctx;
 241             } catch (AuthenticationException e) {
 242                 throw e;
 243             } catch (NamingException e) {
 244                 ne = e;
 245             }
 246         }
 247         throw ne;
 248     }
 249 
 250     /**
 251      * Used by Obj and obj/RemoteToAttrs too so must be public
 252      */
 253     public static Attribute createTypeNameAttr(Class<?> cl) {
 254         Vector<String> v = new Vector<>(10);
 255         String[] types = getTypeNames(cl, v);
 256         if (types.length > 0) {
 257             BasicAttribute tAttr =
 258                 new BasicAttribute(Obj.JAVA_ATTRIBUTES[Obj.TYPENAME]);
 259             for (int i = 0; i < types.length; i++) {
 260                 tAttr.add(types[i]);


< prev index next >