< 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 
  51         if (!isLdapRef(ref)) {
  52             return null;
  53         }


 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]);
 231             }
 232             return tAttr;
 233         }
 234         return null;
 235     }
 236 
 237     private static String[] getTypeNames(Class<?> currentClass, Vector<String> v) {




   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.*;


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


 140         System.arraycopy(urls, 0, urls2, 0, size);
 141         return urls2;
 142     }
 143 
 144     // ------------ Utilities used by other classes ----------------
 145 
 146     public static DirContext getLdapCtxInstance(Object urlInfo, Hashtable<?,?> env)
 147             throws NamingException {
 148 
 149         if (urlInfo instanceof String) {
 150             return getUsingURL((String)urlInfo, env);
 151         } else if (urlInfo instanceof String[]) {
 152             return getUsingURLs((String[])urlInfo, env);
 153         } else {
 154             throw new IllegalArgumentException(
 155                 "argument must be an LDAP URL String or array of them");
 156         }
 157     }
 158 
 159     private static DirContext getUsingURL(String url, Hashtable<?,?> env)
 160             throws NamingException
 161     {
 162         try {
 163             LdapDnsProviderResult r =
 164                 LdapDnsProviderService.getInstance().lookupEndpoints(url, env);
 165             LdapCtx ctx = null;
 166             NamingException lastException = null;
 167 
 168             /*
 169              * Prior to this change we had been assuming that the url.getDN()
 170              * should be converted to a domain name via
 171              * ServiceLocator.mapDnToDomainName(url.getDN())
 172              *
 173              * However this is incorrect as we can't assume that the supplied
 174              * url.getDN() is the same as the dns domain for the directory
 175              * server.
 176              *
 177              * This means that we depend on the dnsProvider to return both
 178              * the list of urls of individual hosts from which we attempt to
 179              * create an LdapCtx from *AND* the domain name that they serve
 180              *
 181              * In order to do this the dnsProvider must return an
 182              * {@link LdapDnsProviderResult}.
 183              *
 184              */
 185             for (String u : r.getEndpoints()) {
 186                 try {
 187                     ctx = getLdapCtxFromUrl(
 188                             r.getDomainName(), new LdapURL(u), env);
 189                 } catch (NamingException e) {
 190                     // try the next element
 191                     lastException = e;
 192                 }
 193             }
 194 
 195             if (lastException != null) {
 196                 throw lastException;
 197             }
 198 
 199             if (ctx == null) {
 200                 // we have resolved them, but they are not valid
 201                 throw new NamingException("Could not resolve a valid ldap host");
 202             }
 203 


 204             // Record the URL that created the context
 205             ctx.setProviderUrl(url);
 206             return ctx;
 207         } catch (NamingException e) {
 208             // getDnsUrls(url, env) may throw a NamingException, which there is
 209             // no need to wrap.
 210             throw e;
 211         } catch (Exception e) {
 212             NamingException ex = new NamingException();
 213             ex.setRootCause(e);
 214             throw ex;
 215         }
 216     }
 217 
 218     private static LdapCtx getLdapCtxFromUrl(String domain,
 219                                              LdapURL url,
 220                                              Hashtable<?,?> env)
 221             throws NamingException
 222     {
 223         String dn = url.getDN();
 224         String host = url.getHost();
 225         int port = url.getPort();
 226         LdapCtx ctx = new LdapCtx(dn, host, port, env, url.useSsl());
 227         ctx.setDomainName(domain);
 228         return ctx;
 229     }
 230 
 231     /*
 232      * Try each URL until one of them succeeds.
 233      * If all URLs fail, throw one of the exceptions arbitrarily.
 234      * Not pretty, but potentially more informative than returning null.
 235      */
 236     private static DirContext getUsingURLs(String[] urls, Hashtable<?,?> env)
 237             throws NamingException
 238     {
 239         NamingException ex = null;
 240         for (String u : urls) {
 241             try {
 242                 return getUsingURL(u, env);


 243             } catch (NamingException e) {
 244                 ex = e;
 245             }
 246         }
 247         throw ex;
 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]);
 261             }
 262             return tAttr;
 263         }
 264         return null;
 265     }
 266 
 267     private static String[] getTypeNames(Class<?> currentClass, Vector<String> v) {


< prev index next >