8160768: Add capability to custom resolve host/domain names within the default JNDI LDAP provider
Reviewed-by: alanb, dfuchs, chegar, mchung, vtewari
This commit is contained in:
parent
b33edbf1ec
commit
d3ccf8a0ca
@ -0,0 +1,86 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation. Oracle designates this
|
||||||
|
* particular file as subject to the "Classpath" exception as provided
|
||||||
|
* by Oracle in the LICENSE file that accompanied this code.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.sun.jndi.ldap;
|
||||||
|
|
||||||
|
import javax.naming.NamingException;
|
||||||
|
import javax.naming.ldap.spi.LdapDnsProvider;
|
||||||
|
import javax.naming.ldap.spi.LdapDnsProviderResult;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public class DefaultLdapDnsProvider {
|
||||||
|
|
||||||
|
public Optional<LdapDnsProviderResult> lookupEndpoints(String url,
|
||||||
|
Map<?,?> env)
|
||||||
|
throws NamingException
|
||||||
|
{
|
||||||
|
if (url == null || env == null) {
|
||||||
|
throw new NullPointerException();
|
||||||
|
}
|
||||||
|
|
||||||
|
String domainName;
|
||||||
|
List<String> endpoints = new ArrayList<>();
|
||||||
|
LdapURL ldapUrl = new LdapURL(url);
|
||||||
|
String dn = ldapUrl.getDN();
|
||||||
|
String host = ldapUrl.getHost();
|
||||||
|
int port = ldapUrl.getPort();
|
||||||
|
String[] hostports;
|
||||||
|
|
||||||
|
// 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 query = ldapUrl.getQuery();
|
||||||
|
String urlSuffix = ldapUrl.getPath() + (query != null ? query : "");
|
||||||
|
for (String hostPort : hostports) {
|
||||||
|
// the hostports come from the DNS SRV records
|
||||||
|
// we assume the SRV record is scheme aware
|
||||||
|
endpoints.add(scheme + hostPort + urlSuffix);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// we don't have enough information to set the domain name
|
||||||
|
// correctly
|
||||||
|
domainName = "";
|
||||||
|
endpoints.add(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
LdapDnsProviderResult res = new LdapDnsProviderResult(domainName, endpoints);
|
||||||
|
if (res.getEndpoints().size() == 0 && res.getDomainName().isEmpty()) {
|
||||||
|
return Optional.empty();
|
||||||
|
} else {
|
||||||
|
return Optional.of(res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -31,6 +31,7 @@ import java.util.Enumeration;
|
|||||||
|
|
||||||
import javax.naming.*;
|
import javax.naming.*;
|
||||||
import javax.naming.directory.*;
|
import javax.naming.directory.*;
|
||||||
|
import javax.naming.ldap.spi.LdapDnsProviderResult;
|
||||||
import javax.naming.spi.ObjectFactory;
|
import javax.naming.spi.ObjectFactory;
|
||||||
import javax.naming.spi.InitialContextFactory;
|
import javax.naming.spi.InitialContextFactory;
|
||||||
import javax.naming.ldap.Control;
|
import javax.naming.ldap.Control;
|
||||||
@ -158,41 +159,73 @@ final public class LdapCtxFactory implements ObjectFactory, InitialContextFactor
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static DirContext getUsingURL(String url, Hashtable<?,?> env)
|
private static DirContext getUsingURL(String url, Hashtable<?,?> env)
|
||||||
throws NamingException {
|
throws NamingException
|
||||||
DirContext ctx = null;
|
{
|
||||||
LdapURL ldapUrl = new LdapURL(url);
|
try {
|
||||||
String dn = ldapUrl.getDN();
|
LdapDnsProviderResult r =
|
||||||
String host = ldapUrl.getHost();
|
LdapDnsProviderService.getInstance().lookupEndpoints(url, env);
|
||||||
int port = ldapUrl.getPort();
|
LdapCtx ctx;
|
||||||
String[] hostports;
|
NamingException lastException = null;
|
||||||
String domainName = null;
|
|
||||||
|
|
||||||
// handle a URL with no hostport (ldap:/// or ldaps:///)
|
/*
|
||||||
// locate the LDAP service using the URL's distinguished name
|
* Prior to this change we had been assuming that the url.getDN()
|
||||||
if (host == null &&
|
* should be converted to a domain name via
|
||||||
port == -1 &&
|
* ServiceLocator.mapDnToDomainName(url.getDN())
|
||||||
dn != null &&
|
*
|
||||||
(domainName = ServiceLocator.mapDnToDomainName(dn)) != null &&
|
* However this is incorrect as we can't assume that the supplied
|
||||||
(hostports = ServiceLocator.getLdapService(domainName, env))
|
* url.getDN() is the same as the dns domain for the directory
|
||||||
!= null) {
|
* server.
|
||||||
// Generate new URLs that include the discovered hostports.
|
*
|
||||||
// Reuse the original URL scheme.
|
* This means that we depend on the dnsProvider to return both
|
||||||
String scheme = ldapUrl.getScheme() + "://";
|
* the list of urls of individual hosts from which we attempt to
|
||||||
String[] newUrls = new String[hostports.length];
|
* create an LdapCtx from *AND* the domain name that they serve
|
||||||
String query = ldapUrl.getQuery();
|
*
|
||||||
String urlSuffix = ldapUrl.getPath() + (query != null ? query : "");
|
* In order to do this the dnsProvider must return an
|
||||||
for (int i = 0; i < hostports.length; i++) {
|
* {@link LdapDnsProviderResult}.
|
||||||
newUrls[i] = scheme + hostports[i] + urlSuffix;
|
*
|
||||||
|
*/
|
||||||
|
for (String u : r.getEndpoints()) {
|
||||||
|
try {
|
||||||
|
ctx = getLdapCtxFromUrl(
|
||||||
|
r.getDomainName(), url, new LdapURL(u), env);
|
||||||
|
return ctx;
|
||||||
|
} catch (NamingException e) {
|
||||||
|
// try the next element
|
||||||
|
lastException = e;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ctx = getUsingURLs(newUrls, env);
|
|
||||||
// Associate the derived domain name with the context
|
|
||||||
((LdapCtx)ctx).setDomainName(domainName);
|
|
||||||
|
|
||||||
} else {
|
if (lastException != null) {
|
||||||
ctx = new LdapCtx(dn, host, port, env, ldapUrl.useSsl());
|
throw lastException;
|
||||||
// Record the URL that created the context
|
}
|
||||||
((LdapCtx)ctx).setProviderUrl(url);
|
|
||||||
|
// lookupEndpoints returned an LdapDnsProviderResult with an empty
|
||||||
|
// list of endpoints
|
||||||
|
throw new NamingException("Could not resolve a valid ldap host");
|
||||||
|
} catch (NamingException e) {
|
||||||
|
// lookupEndpoints(url, env) may throw a NamingException, which
|
||||||
|
// there is no need to wrap.
|
||||||
|
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);
|
||||||
|
// Record the URL that created the context
|
||||||
|
ctx.setProviderUrl(url);
|
||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -202,19 +235,17 @@ final public class LdapCtxFactory implements ObjectFactory, InitialContextFactor
|
|||||||
* Not pretty, but potentially more informative than returning null.
|
* Not pretty, but potentially more informative than returning null.
|
||||||
*/
|
*/
|
||||||
private static DirContext getUsingURLs(String[] urls, Hashtable<?,?> env)
|
private static DirContext getUsingURLs(String[] urls, Hashtable<?,?> env)
|
||||||
throws NamingException {
|
throws NamingException
|
||||||
NamingException ne = null;
|
{
|
||||||
DirContext ctx = null;
|
NamingException ex = null;
|
||||||
for (int i = 0; i < urls.length; i++) {
|
for (String u : urls) {
|
||||||
try {
|
try {
|
||||||
return getUsingURL(urls[i], env);
|
return getUsingURL(u, env);
|
||||||
} catch (AuthenticationException e) {
|
|
||||||
throw e;
|
|
||||||
} catch (NamingException e) {
|
} catch (NamingException e) {
|
||||||
ne = e;
|
ex = e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw ne;
|
throw ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -0,0 +1,111 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation. Oracle designates this
|
||||||
|
* particular file as subject to the "Classpath" exception as provided
|
||||||
|
* by Oracle in the LICENSE file that accompanied this code.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.sun.jndi.ldap;
|
||||||
|
|
||||||
|
import java.security.AccessController;
|
||||||
|
import java.security.PrivilegedAction;
|
||||||
|
import java.util.*;
|
||||||
|
import javax.naming.NamingException;
|
||||||
|
import javax.naming.ldap.spi.LdapDnsProvider;
|
||||||
|
import javax.naming.ldap.spi.LdapDnsProviderResult;
|
||||||
|
import sun.security.util.SecurityConstants;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@code LdapDnsProviderService} is responsible for creating and providing
|
||||||
|
* access to the registered {@code LdapDnsProvider}s. The {@link ServiceLoader}
|
||||||
|
* is used to find and register any implementations of {@link LdapDnsProvider}.
|
||||||
|
*/
|
||||||
|
final class LdapDnsProviderService {
|
||||||
|
|
||||||
|
private static volatile LdapDnsProviderService service;
|
||||||
|
private static final Object LOCK = new int[0];
|
||||||
|
private final ServiceLoader<LdapDnsProvider> providers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance of LdapDnsProviderService
|
||||||
|
*/
|
||||||
|
private LdapDnsProviderService() {
|
||||||
|
SecurityManager sm = System.getSecurityManager();
|
||||||
|
if (sm == null) {
|
||||||
|
providers = ServiceLoader.load(
|
||||||
|
LdapDnsProvider.class,
|
||||||
|
ClassLoader.getSystemClassLoader());
|
||||||
|
} else {
|
||||||
|
final PrivilegedAction<ServiceLoader<LdapDnsProvider>> pa =
|
||||||
|
() -> ServiceLoader.load(
|
||||||
|
LdapDnsProvider.class,
|
||||||
|
ClassLoader.getSystemClassLoader());
|
||||||
|
|
||||||
|
providers = AccessController.doPrivileged(
|
||||||
|
pa,
|
||||||
|
null,
|
||||||
|
new RuntimePermission("ldapDnsProvider"),
|
||||||
|
SecurityConstants.GET_CLASSLOADER_PERMISSION);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the singleton static instance of LdapDnsProviderService.
|
||||||
|
*/
|
||||||
|
static LdapDnsProviderService getInstance() {
|
||||||
|
if (service != null) return service;
|
||||||
|
synchronized(LOCK) {
|
||||||
|
if (service != null) return service;
|
||||||
|
service = new LdapDnsProviderService();
|
||||||
|
}
|
||||||
|
return service;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve result from the first provider that successfully resolves
|
||||||
|
* the endpoints. If no results are found when calling installed
|
||||||
|
* subclasses of {@code LdapDnsProvider} then this method will fall back
|
||||||
|
* to the {@code DefaultLdapDnsProvider}.
|
||||||
|
*
|
||||||
|
* @throws NamingException if the {@code url} in not valid or an error
|
||||||
|
* occurred while performing the lookup.
|
||||||
|
*/
|
||||||
|
LdapDnsProviderResult lookupEndpoints(String url, Hashtable<?,?> env)
|
||||||
|
throws NamingException
|
||||||
|
{
|
||||||
|
Iterator<LdapDnsProvider> iterator = providers.iterator();
|
||||||
|
Hashtable<?, ?> envCopy = new Hashtable<>(env);
|
||||||
|
LdapDnsProviderResult result = null;
|
||||||
|
|
||||||
|
while (result == null && iterator.hasNext()) {
|
||||||
|
result = iterator.next().lookupEndpoints(url, envCopy)
|
||||||
|
.filter(r -> r.getEndpoints().size() > 0)
|
||||||
|
.orElse(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result == null) {
|
||||||
|
return new DefaultLdapDnsProvider().lookupEndpoints(url, env)
|
||||||
|
.orElse(new LdapDnsProviderResult("", List.of()));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -25,11 +25,7 @@
|
|||||||
|
|
||||||
package com.sun.jndi.ldap;
|
package com.sun.jndi.ldap;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.*;
|
||||||
import java.util.Hashtable;
|
|
||||||
import java.util.Random;
|
|
||||||
import java.util.StringTokenizer;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import javax.naming.*;
|
import javax.naming.*;
|
||||||
import javax.naming.directory.*;
|
import javax.naming.directory.*;
|
||||||
@ -103,6 +99,23 @@ class ServiceLocator {
|
|||||||
return (domain.length() != 0) ? domain.toString() : null;
|
return (domain.length() != 0) ? domain.toString() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Locates the LDAP service for a given domain.
|
||||||
|
* Queries DNS for a list of LDAP Service Location Records (SRV) for a
|
||||||
|
* given domain name.
|
||||||
|
*
|
||||||
|
* @param domainName A string domain name.
|
||||||
|
* @param environment The possibly null environment of the context.
|
||||||
|
* @return An ordered list of hostports for the LDAP service or null if
|
||||||
|
* the service has not been located.
|
||||||
|
*/
|
||||||
|
static String[] getLdapService(String domainName, Map<?,?> environment) {
|
||||||
|
if (environment instanceof Hashtable) {
|
||||||
|
return getLdapService(domainName, (Hashtable)environment);
|
||||||
|
}
|
||||||
|
return getLdapService(domainName, new Hashtable<>(environment));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Locates the LDAP service for a given domain.
|
* Locates the LDAP service for a given domain.
|
||||||
* Queries DNS for a list of LDAP Service Location Records (SRV) for a
|
* Queries DNS for a list of LDAP Service Location Records (SRV) for a
|
||||||
|
@ -27,7 +27,6 @@
|
|||||||
package javax.naming.directory;
|
package javax.naming.directory;
|
||||||
|
|
||||||
import java.util.Hashtable;
|
import java.util.Hashtable;
|
||||||
import javax.naming.spi.NamingManager;
|
|
||||||
import javax.naming.*;
|
import javax.naming.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -84,6 +83,36 @@ public class InitialDirContext extends InitialContext implements DirContext {
|
|||||||
* Environment properties are discussed in the
|
* Environment properties are discussed in the
|
||||||
* {@code javax.naming.InitialContext} class description.
|
* {@code javax.naming.InitialContext} class description.
|
||||||
*
|
*
|
||||||
|
* <p> If the {@code java.naming.provider.url} property of the supplied
|
||||||
|
* environment consists of a URL (or a list of URLs) using the ldap
|
||||||
|
* protocol the resulting {@link javax.naming.ldap.LdapContext} will use
|
||||||
|
* an LDAP server resolved by the configured {@link
|
||||||
|
* javax.naming.ldap.spi.LdapDnsProvider LdapDnsProviders}:
|
||||||
|
* <ol>
|
||||||
|
* <li>If this is the first {@code InitialDirContext} created with a
|
||||||
|
* {@code java.naming.provider.url} using the ldap protocol then the
|
||||||
|
* {@linkplain java.util.ServiceLoader ServiceLoader} mechanism is
|
||||||
|
* used to locate {@linkplain javax.naming.ldap.spi.LdapDnsProvider
|
||||||
|
* LdapDnsProvider} implementations using the system class loader.
|
||||||
|
* The order that providers are located is implementation specific
|
||||||
|
* and an implementation is free to cache the located providers.
|
||||||
|
* <li>The {@code lookupEndpoints} method of each provider, if instantiated,
|
||||||
|
* is invoked once with a combination of each of the URLs in the the
|
||||||
|
* {@code java.naming.provider.url} property and the environment until
|
||||||
|
* a provider returns non-empty or all providers have been exhausted.
|
||||||
|
* If none of the
|
||||||
|
* {@linkplain javax.naming.ldap.spi.LdapDnsProvider LdapDnsProviders}
|
||||||
|
* return a non-empty
|
||||||
|
* {@linkplain javax.naming.ldap.spi.LdapDnsProviderResult result} then
|
||||||
|
* the implementation will make a best-effort attempt to determine an
|
||||||
|
* endpoint. A
|
||||||
|
* {@linkplain java.util.ServiceConfigurationError ServiceConfigurationError},
|
||||||
|
* {@code Error} or {@code RuntimeException} thrown when loading or
|
||||||
|
* calling an {@linkplain javax.naming.ldap.spi.LdapDnsProvider
|
||||||
|
* LdapDnsProvider}, if encountered, will be propagated to the calling
|
||||||
|
* thread.
|
||||||
|
* </ol>
|
||||||
|
*
|
||||||
* <p> This constructor will not modify {@code environment}
|
* <p> This constructor will not modify {@code environment}
|
||||||
* or save a reference to it, but may save a clone.
|
* or save a reference to it, but may save a clone.
|
||||||
* Caller should not modify mutable keys and values in
|
* Caller should not modify mutable keys and values in
|
||||||
|
@ -0,0 +1,109 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation. Oracle designates this
|
||||||
|
* particular file as subject to the "Classpath" exception as provided
|
||||||
|
* by Oracle in the LICENSE file that accompanied this code.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package javax.naming.ldap.spi;
|
||||||
|
|
||||||
|
import javax.naming.Context;
|
||||||
|
import javax.naming.NamingException;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Service-provider class for DNS lookups when performing LDAP operations.
|
||||||
|
*
|
||||||
|
* <p> An LDAP DNS provider is a concrete subclass of this class that
|
||||||
|
* has a zero-argument constructor. LDAP DNS providers are located using the
|
||||||
|
* ServiceLoader facility, as specified by
|
||||||
|
* {@linkplain javax.naming.directory.InitialDirContext InitialDirectContext}.
|
||||||
|
*
|
||||||
|
* The
|
||||||
|
* {@link java.util.ServiceLoader ServiceLoader} is used to create and register
|
||||||
|
* implementations of {@code LdapDnsProvider}.
|
||||||
|
*
|
||||||
|
* <p> An LDAP DNS provider can be used in environments where the default
|
||||||
|
* DNS resolution mechanism is not sufficient to accurately pinpoint the
|
||||||
|
* correct LDAP servers needed to perform LDAP operations. For example, in an
|
||||||
|
* environment containing a mix of {@code ldap} and {@code ldaps} servers
|
||||||
|
* you may want the {@linkplain javax.naming.ldap.LdapContext LdapContext}
|
||||||
|
* to query {@code ldaps} servers only.
|
||||||
|
*
|
||||||
|
* @since 12
|
||||||
|
*/
|
||||||
|
public abstract class LdapDnsProvider {
|
||||||
|
|
||||||
|
// The {@code RuntimePermission("ldapDnsProvider")} is
|
||||||
|
// necessary to subclass and instantiate the {@code LdapDnsProvider} class.
|
||||||
|
private static final RuntimePermission DNSPROVIDER_PERMISSION =
|
||||||
|
new RuntimePermission("ldapDnsProvider");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance of {@code LdapDnsProvider}.
|
||||||
|
*
|
||||||
|
* @throws SecurityException if a security manager is present and its
|
||||||
|
* {@code checkPermission} method doesn't allow
|
||||||
|
* the {@code RuntimePermission("ldapDnsProvider")}.
|
||||||
|
*/
|
||||||
|
protected LdapDnsProvider() {
|
||||||
|
this(checkPermission());
|
||||||
|
}
|
||||||
|
|
||||||
|
private LdapDnsProvider(Void unused) {
|
||||||
|
// nothing to do.
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Void checkPermission() {
|
||||||
|
final SecurityManager sm = System.getSecurityManager();
|
||||||
|
if (sm != null) {
|
||||||
|
sm.checkPermission(DNSPROVIDER_PERMISSION);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lookup the endpoints and domain name for the given {@link Context}
|
||||||
|
* {@link Context#PROVIDER_URL provider URL} and environment. The resolved
|
||||||
|
* endpoints and domain name are returned as an
|
||||||
|
* {@link LdapDnsProviderResult}.
|
||||||
|
*
|
||||||
|
* <p> An endpoint is a {@code String} representation of an LDAP URL which
|
||||||
|
* points to an LDAP server to be used for LDAP operations. The syntax of
|
||||||
|
* an LDAP URL is defined by <a href="http://www.ietf.org/rfc/rfc2255.txt">
|
||||||
|
* <i>RFC 2255: The LDAP URL Format</i></a>.
|
||||||
|
*
|
||||||
|
* @param url The {@link Context} {@link Context#PROVIDER_URL provider URL}
|
||||||
|
* @param env The {@link Context} environment.
|
||||||
|
*
|
||||||
|
* @return an {@link LdapDnsProviderResult} or empty {@code Optional}
|
||||||
|
* if the lookup fails.
|
||||||
|
*
|
||||||
|
* @throws NamingException if the {@code url} is not valid or an error
|
||||||
|
* occurred while performing the lookup.
|
||||||
|
* @throws NullPointerException if either {@code url} or {@code env} are
|
||||||
|
* {@code null}.
|
||||||
|
*/
|
||||||
|
public abstract Optional<LdapDnsProviderResult> lookupEndpoints(
|
||||||
|
String url, Map<?,?> env) throws NamingException;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,87 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation. Oracle designates this
|
||||||
|
* particular file as subject to the "Classpath" exception as provided
|
||||||
|
* by Oracle in the LICENSE file that accompanied this code.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package javax.naming.ldap.spi;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The result of a DNS lookup for an LDAP URL.
|
||||||
|
*
|
||||||
|
* <p> This class is used by an {@link LdapDnsProvider} to return the result
|
||||||
|
* of a DNS lookup for a given LDAP URL. The result consists of a domain name
|
||||||
|
* and its associated ldap server endpoints.
|
||||||
|
*
|
||||||
|
* <p> A {@code null} {@code domainName} is equivalent to and represented
|
||||||
|
* by an empty string.
|
||||||
|
*
|
||||||
|
* @since 12
|
||||||
|
*/
|
||||||
|
public final class LdapDnsProviderResult {
|
||||||
|
|
||||||
|
private final String domainName;
|
||||||
|
private final List<String> endpoints;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct an LdapDnsProviderResult consisting of a resolved domain name
|
||||||
|
* and the ldap server endpoints that serve the domain.
|
||||||
|
*
|
||||||
|
* @param domainName the resolved domain name; can be null.
|
||||||
|
* @param endpoints the possibly empty list of resolved ldap server
|
||||||
|
* endpoints
|
||||||
|
*
|
||||||
|
* @throws NullPointerException if {@code endpoints} contains {@code null}
|
||||||
|
* elements.
|
||||||
|
* @throws ClassCastException if {@code endpoints} contains non-
|
||||||
|
* {@code String} elements.
|
||||||
|
*/
|
||||||
|
public LdapDnsProviderResult(String domainName, List<String> endpoints) {
|
||||||
|
this.domainName = (domainName == null) ? "" : domainName;
|
||||||
|
this.endpoints = List.copyOf(endpoints);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the domain name resolved from the ldap URL. This method returns
|
||||||
|
* the empty string if the {@code LdapDnsProviderResult} is created with a
|
||||||
|
* null domain name.
|
||||||
|
*
|
||||||
|
* @return the resolved domain name
|
||||||
|
*/
|
||||||
|
public String getDomainName() {
|
||||||
|
return domainName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the possibly empty list of individual server endpoints resolved
|
||||||
|
* from the ldap URL.
|
||||||
|
*
|
||||||
|
* @return a possibly empty unmodifiable {@link List} containing the
|
||||||
|
* resolved ldap server endpoints
|
||||||
|
*/
|
||||||
|
public List<String> getEndpoints() {
|
||||||
|
return endpoints;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -26,6 +26,10 @@
|
|||||||
/**
|
/**
|
||||||
* Defines the Java Naming and Directory Interface (JNDI) API.
|
* Defines the Java Naming and Directory Interface (JNDI) API.
|
||||||
*
|
*
|
||||||
|
* @provides javax.naming.ldap.spi.LdapDnsProvider
|
||||||
|
*
|
||||||
|
* @uses javax.naming.ldap.spi.LdapDnsProvider
|
||||||
|
*
|
||||||
* @moduleGraph
|
* @moduleGraph
|
||||||
* @since 9
|
* @since 9
|
||||||
*/
|
*/
|
||||||
@ -37,6 +41,7 @@ module java.naming {
|
|||||||
exports javax.naming.event;
|
exports javax.naming.event;
|
||||||
exports javax.naming.ldap;
|
exports javax.naming.ldap;
|
||||||
exports javax.naming.spi;
|
exports javax.naming.spi;
|
||||||
|
exports javax.naming.ldap.spi;
|
||||||
|
|
||||||
exports com.sun.jndi.toolkit.ctx to
|
exports com.sun.jndi.toolkit.ctx to
|
||||||
jdk.naming.dns;
|
jdk.naming.dns;
|
||||||
@ -46,6 +51,7 @@ module java.naming {
|
|||||||
|
|
||||||
uses javax.naming.ldap.StartTlsResponse;
|
uses javax.naming.ldap.StartTlsResponse;
|
||||||
uses javax.naming.spi.InitialContextFactory;
|
uses javax.naming.spi.InitialContextFactory;
|
||||||
|
uses javax.naming.ldap.spi.LdapDnsProvider;
|
||||||
|
|
||||||
provides java.security.Provider with
|
provides java.security.Provider with
|
||||||
sun.security.provider.certpath.ldap.JdkLDAP;
|
sun.security.provider.certpath.ldap.JdkLDAP;
|
||||||
|
231
test/jdk/com/sun/jndi/ldap/LdapDnsProviderTest.java
Normal file
231
test/jdk/com/sun/jndi/ldap/LdapDnsProviderTest.java
Normal file
@ -0,0 +1,231 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation. Oracle designates this
|
||||||
|
* particular file as subject to the "Classpath" exception as provided
|
||||||
|
* by Oracle in the LICENSE file that accompanied this code.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.security.Permission;
|
||||||
|
import java.util.Hashtable;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
import java.util.concurrent.FutureTask;
|
||||||
|
|
||||||
|
import javax.naming.Context;
|
||||||
|
import javax.naming.InitialContext;
|
||||||
|
import javax.naming.NamingException;
|
||||||
|
import javax.naming.directory.InitialDirContext;
|
||||||
|
import javax.naming.directory.SearchControls;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
* @bug 8160768
|
||||||
|
* @summary ctx provider tests for ldap
|
||||||
|
* @modules java.naming/com.sun.jndi.ldap
|
||||||
|
* @compile dnsprovider/TestDnsProvider.java
|
||||||
|
* @run main/othervm LdapDnsProviderTest
|
||||||
|
* @run main/othervm LdapDnsProviderTest nosm
|
||||||
|
* @run main/othervm LdapDnsProviderTest smnodns
|
||||||
|
* @run main/othervm LdapDnsProviderTest smdns
|
||||||
|
* @run main/othervm LdapDnsProviderTest nosmbaddns
|
||||||
|
*/
|
||||||
|
|
||||||
|
class DNSSecurityManager extends SecurityManager {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* run main/othervm LdapDnsProviderTest
|
||||||
|
|
||||||
|
* run main/othervm LdapDnsProviderTest nosm
|
||||||
|
* run main/othervm LdapDnsProviderTest smnodns
|
||||||
|
* run main/othervm LdapDnsProviderTest smdns
|
||||||
|
* run main/othervm LdapDnsProviderTest nosmbaddns
|
||||||
|
*/
|
||||||
|
|
||||||
|
private boolean dnsProvider = false;
|
||||||
|
|
||||||
|
public void setAllowDnsProvider(boolean allow) {
|
||||||
|
dnsProvider = allow;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void checkPermission(Permission p) {
|
||||||
|
if (p.getName().equals("ldapDnsProvider") && !dnsProvider) {
|
||||||
|
throw new SecurityException(p.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ProviderTest implements Callable<Boolean> {
|
||||||
|
|
||||||
|
private final String url;
|
||||||
|
private final String expected;
|
||||||
|
private final Hashtable<String, String> env = new Hashtable<>(11);
|
||||||
|
|
||||||
|
public ProviderTest(String url, String expected) {
|
||||||
|
this.url = url;
|
||||||
|
this.expected = expected;
|
||||||
|
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean shutItDown(InitialContext ctx) {
|
||||||
|
try {
|
||||||
|
if (ctx != null) ctx.close();
|
||||||
|
return true;
|
||||||
|
} catch (NamingException ex) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean call() {
|
||||||
|
boolean passed;
|
||||||
|
InitialContext ctx = null;
|
||||||
|
|
||||||
|
if (url != null) {
|
||||||
|
env.put(Context.PROVIDER_URL, url);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
ctx = new InitialDirContext(env);
|
||||||
|
SearchControls scl = new SearchControls();
|
||||||
|
scl.setSearchScope(SearchControls.SUBTREE_SCOPE);
|
||||||
|
((InitialDirContext)ctx).search(
|
||||||
|
"ou=People,o=Test", "(objectClass=*)", scl);
|
||||||
|
throw new RuntimeException("Search should not complete");
|
||||||
|
} catch (NamingException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
passed = e.toString().contains(expected);
|
||||||
|
} finally {
|
||||||
|
shutItDown(ctx);
|
||||||
|
}
|
||||||
|
return passed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class LdapDnsProviderTest {
|
||||||
|
|
||||||
|
private static final String TEST_CLASSES =
|
||||||
|
System.getProperty("test.classes", ".");
|
||||||
|
|
||||||
|
public static void writeFile(String content, File dstFile)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
try (FileOutputStream dst = new FileOutputStream(dstFile)) {
|
||||||
|
byte[] buf = content.getBytes();
|
||||||
|
dst.write(buf, 0, buf.length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void installServiceConfigurationFile(String content) {
|
||||||
|
String filename = "javax.naming.ldap.spi.LdapDnsProvider";
|
||||||
|
|
||||||
|
File dstDir = new File(TEST_CLASSES, "META-INF/services");
|
||||||
|
if (!dstDir.exists()) {
|
||||||
|
if (!dstDir.mkdirs()) {
|
||||||
|
throw new RuntimeException(
|
||||||
|
"could not create META-INF/services directory " + dstDir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
File dstFile = new File(dstDir, filename);
|
||||||
|
|
||||||
|
try {
|
||||||
|
writeFile(content, dstFile);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException("could not install " + dstFile, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
if (args.length > 0 && args[0].equals("nosm")) {
|
||||||
|
// no security manager, serviceloader
|
||||||
|
installServiceConfigurationFile("dnsprovider.TestDnsProvider");
|
||||||
|
runTest("ldap:///dc=example,dc=com", "yupyupyup:389");
|
||||||
|
} else if (args.length > 0 && args[0].equals("smnodns")) {
|
||||||
|
// security manager & serviceloader
|
||||||
|
installServiceConfigurationFile("dnsprovider.TestDnsProvider");
|
||||||
|
// install security manager
|
||||||
|
System.setSecurityManager(new DNSSecurityManager());
|
||||||
|
runTest("ldap:///dc=example,dc=com", "ServiceConfigurationError");
|
||||||
|
} else if (args.length > 0 && args[0].equals("smdns")) {
|
||||||
|
// security manager & serviceloader
|
||||||
|
DNSSecurityManager sm = new DNSSecurityManager();
|
||||||
|
installServiceConfigurationFile("dnsprovider.TestDnsProvider");
|
||||||
|
// install security manager
|
||||||
|
System.setSecurityManager(sm);
|
||||||
|
sm.setAllowDnsProvider(true);
|
||||||
|
runTest("ldap:///dc=example,dc=com", "yupyupyup:389");
|
||||||
|
} else if (args.length > 0 && args[0].equals("nosmbaddns")) {
|
||||||
|
// no security manager, no serviceloader
|
||||||
|
// DefaultLdapDnsProvider
|
||||||
|
installServiceConfigurationFile("dnsprovider.MissingDnsProvider");
|
||||||
|
// no SecurityManager
|
||||||
|
runTest("ldap:///dc=example,dc=com", "not found");
|
||||||
|
} else {
|
||||||
|
// no security manager, no serviceloader
|
||||||
|
// DefaultLdapDnsProvider
|
||||||
|
System.err.println("TEST_CLASSES:");
|
||||||
|
System.err.println(TEST_CLASSES);
|
||||||
|
File f = new File(
|
||||||
|
TEST_CLASSES, "META-INF/services/javax.naming.ldap.spi.LdapDnsProvider");
|
||||||
|
if (f.exists()) {
|
||||||
|
f.delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
// no SecurityManager
|
||||||
|
runTest("ldap:///dc=example,dc=com", "localhost:389");
|
||||||
|
runTest("ldap://localhost/dc=example,dc=com", "localhost:389");
|
||||||
|
runTest("ldap://localhost:111/dc=example,dc=com", "localhost:111");
|
||||||
|
runTest("ldaps://localhost:111/dc=example,dc=com", "localhost:111");
|
||||||
|
runTest("ldaps://localhost/dc=example,dc=com", "localhost:636");
|
||||||
|
runTest(null, "localhost:389");
|
||||||
|
runTest("", "ConfigurationException");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void runTest(String url, String expected) {
|
||||||
|
FutureTask<Boolean> future =
|
||||||
|
new FutureTask<>(
|
||||||
|
new ProviderTest(url, expected));
|
||||||
|
new Thread(future).start();
|
||||||
|
|
||||||
|
System.err.println("Testing: " + url + ", " + expected);
|
||||||
|
while (!future.isDone()) {
|
||||||
|
try {
|
||||||
|
if (!future.get()) {
|
||||||
|
System.err.println("Test failed");
|
||||||
|
throw new RuntimeException(
|
||||||
|
"Test failed, ProviderTest returned false");
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
if (!e.toString().contains(expected)) {
|
||||||
|
System.err.println("Test failed");
|
||||||
|
throw new RuntimeException(
|
||||||
|
"Test failed, unexpected result");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.err.println("Test passed");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
20
test/jdk/com/sun/jndi/ldap/dnsprovider/TestDnsProvider.java
Normal file
20
test/jdk/com/sun/jndi/ldap/dnsprovider/TestDnsProvider.java
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
package dnsprovider;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
import javax.naming.ldap.spi.LdapDnsProvider;
|
||||||
|
import javax.naming.ldap.spi.LdapDnsProviderResult;
|
||||||
|
|
||||||
|
public class TestDnsProvider extends LdapDnsProvider {
|
||||||
|
@Override
|
||||||
|
public Optional<LdapDnsProviderResult> lookupEndpoints(String url,
|
||||||
|
Map<?, ?> env)
|
||||||
|
{
|
||||||
|
List<String> endpoints = new ArrayList<>();
|
||||||
|
endpoints.add("ldap://yupyupyup:389");
|
||||||
|
return Optional.of(
|
||||||
|
new LdapDnsProviderResult("test.com", endpoints));
|
||||||
|
}
|
||||||
|
}
|
@ -6,4 +6,5 @@ grant codeBase "file:${test.classes}/*" {
|
|||||||
//permission java.net.SocketPermission "*:636", "connect";
|
//permission java.net.SocketPermission "*:636", "connect";
|
||||||
//permission javax.security.auth.AuthPermission "modifyPrincipals";
|
//permission javax.security.auth.AuthPermission "modifyPrincipals";
|
||||||
permission java.lang.RuntimePermission "accessClassInPackage.com.sun.jndi.ldap";
|
permission java.lang.RuntimePermission "accessClassInPackage.com.sun.jndi.ldap";
|
||||||
|
permission java.lang.RuntimePermission "ldapDnsProvider";
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user