diff --git a/src/share/classes/com/sun/jndi/dns/DnsContextFactory.java b/src/share/classes/com/sun/jndi/dns/DnsContextFactory.java index c7a15dc6eec00a4ab44fe4f5795cd8a47e32b420..04cc04d5fbec73c730dfd3250d71754f18be5230 100644 --- a/src/share/classes/com/sun/jndi/dns/DnsContextFactory.java +++ b/src/share/classes/com/sun/jndi/dns/DnsContextFactory.java @@ -54,6 +54,7 @@ import sun.net.dns.ResolverConfiguration; // available since 1.4.1 public class DnsContextFactory implements InitialContextFactory { private static final String DEFAULT_URL = "dns:"; + private static final int DEFAULT_PORT = 53; public Context getInitialContext(Hashtable env) throws NamingException { @@ -89,7 +90,9 @@ public class DnsContextFactory implements InitialContextFactory { * Public for use by product test suite. */ public static boolean platformServersAvailable() { - return !ResolverConfiguration.open().nameservers().isEmpty(); + return !filterNameServers( + ResolverConfiguration.open().nameservers(), true + ).isEmpty(); } private static Context urlToContext(String url, Hashtable env) @@ -142,8 +145,8 @@ public class DnsContextFactory implements InitialContextFactory { // No server or port given, so look to underlying platform. // ResolverConfiguration does some limited caching, so the // following is reasonably efficient even if called rapid-fire. - List platformServers = - ResolverConfiguration.open().nameservers(); + List platformServers = filterNameServers( + ResolverConfiguration.open().nameservers(), false); if (!platformServers.isEmpty()) { servers.addAll(platformServers); continue; // on to next URL (if any, which is unlikely) @@ -214,4 +217,44 @@ public class DnsContextFactory implements InitialContextFactory { String url = (String) env.get(Context.PROVIDER_URL); return ((url != null) ? url : DEFAULT_URL); } + + /** + * Removes any DNS server that's not permitted to access + * @param input the input server[:port] list, must not be null + * @param oneIsEnough return output once there exists one ok + * @return the filtered list, all non-permitted input removed + */ + private static List filterNameServers(List input, boolean oneIsEnough) { + SecurityManager security = System.getSecurityManager(); + if (security == null || input == null || input.isEmpty()) { + return input; + } else { + List output = new ArrayList(); + for (Object o: input) { + if (o instanceof String) { + String platformServer = (String)o; + int colon = platformServer.indexOf(':', + platformServer.indexOf(']') + 1); + + int p = (colon < 0) + ? DEFAULT_PORT + : Integer.parseInt( + platformServer.substring(colon + 1)); + String s = (colon < 0) + ? platformServer + : platformServer.substring(0, colon); + try { + security.checkConnect(s, p); + output.add(platformServer); + if (oneIsEnough) { + return output; + } + } catch (SecurityException se) { + continue; + } + } + } + return output; + } + } }