[jcifs] Re: jcifs.http.domainController
Oliver Schoett
os at sdm.de
Thu Sep 8 10:12:18 GMT 2005
Michael B Allen wrote:
>Actually, the FIRST thing you should do is write a very small simple test
>program like examples/ListDC.java to see that the _ldap._tcp.megacorp.com
>lookup actually works like the technet article claims.
>
>
Yes, it does work, but with JNDI rather than with
InetAddress.getAllByName. You must do a DNS lookup with type=SRV
(service lookup) rather than type=A (host lookup). If you have the
nslookup program (Windows XP seems to have it), you can easily test
this (all names and addresses faked):
$ nslookup
Standardserver: locadc3.megacorp.com
Address: 194.101.181.203
> set type=SRV
> _ldap._tcp.megacorp.com
Server: locadc3.megacorp.com
Address: 194.101.181.203
_ldap._tcp.megacorp.com SRV service location:
priority = 100
weight = 100
port = 389
svr hostname = locbdc3.megacorp.com
_ldap._tcp.megacorp.com SRV service location:
priority = 0
weight = 100
port = 389
svr hostname = locadc4.megacorp.com
_ldap._tcp.megacorp.com SRV service location:
priority = 100
weight = 100
port = 389
svr hostname = loccdc1.megacorp.com
_ldap._tcp.megacorp.com SRV service location:
priority = 100
weight = 100
port = 389
svr hostname = locddc2.megacorp.com
_ldap._tcp.megacorp.com SRV service location:
priority = 0
weight = 100
port = 389
svr hostname = locadc5.megacorp.com
_ldap._tcp.megacorp.com SRV service location:
priority = 100
weight = 100
port = 389
svr hostname = locedc2.megacorp.com
_ldap._tcp.megacorp.com SRV service location:
priority = 0
weight = 100
port = 389
svr hostname = locadc3.megacorp.com
locbdc3.megacorp.com internet address = 196.125.137.6
locadc4.megacorp.com internet address = 194.101.181.204
loccdc1.megacorp.com internet address = 214.67.170.16
locddc2.megacorp.com internet address = 214.66.240.34
locadc5.megacorp.com internet address = 194.101.181.205
locedc2.megacorp.com internet address = 191.95.170.5
locadc3.megacorp.com internet address = 194.101.181.203
Attached is a Java test program that shows JNDI results versus
InetAddress.getAllByName. The output (names faked) is
$ java ListDC megacorp.com
Searching DCs for megacorp.com
... with JNDI-DNS
SRV:
[java.lang.String] 100 100 389 loccdc1.megacorp.com.
[java.lang.String] 100 100 389 locddc2.megacorp.com.
[java.lang.String] 0 100 389 locadc5.megacorp.com.
[java.lang.String] 100 100 389 locedc2.megacorp.com.
[java.lang.String] 0 100 389 locadc3.megacorp.com.
[java.lang.String] 100 100 389 locbdc3.megacorp.com.
[java.lang.String] 0 100 389 locadc4.megacorp.com.
... with InetAddress.getAllByName
java.net.UnknownHostException: _ldap._tcp.megacorp.com: _ldap._tcp.megacorp.com
at java.net.InetAddress.getAllByName0(InetAddress.java:1011)
at java.net.InetAddress.getAllByName0(InetAddress.java:981)
at java.net.InetAddress.getAllByName(InetAddress.java:975)
at ListDC.main(ListDC.java:33)
Exception in thread "main"
Actually, there are precise rules in RFC 2782 on how to try servers
given the priorities and weights returned by this lookup: try servers
in strict order of ascending priorities; within a priority, pick
servers sequentially at random with probability roughly proportional
to their weight (servers with weight 0 are given a chance also).
Presumably the LDAP service provider for JNDI
(http://java.sun.com/j2se/1.4.2/docs/guide/jndi/jndi-ldap.html)
implements these rules already, but I have not found a way to extract
the list of servers from this JNDI service provider.
Regards,
Oliver Schoett
-------------- next part --------------
import java.util.Hashtable;
import java.net.InetAddress;
import javax.naming.*;
import javax.naming.directory.*;
public class ListDC {
public static void main( String argv[] ) throws Exception {
// http://java.sun.com/j2se/1.4.2/docs/guide/jndi/jndi-dns.html
Hashtable env = new Hashtable();
env.put( Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.dns.DnsContextFactory" );
env.put(Context.AUTHORITATIVE, "true");
DirContext ictx = new InitialDirContext(env);
final String[] srv = {"SRV"};
for (int i = 0; i < argv.length; i++ ) {
System.out.println("Searching DCs for " + argv[i]);
System.out.println("... with JNDI-DNS");
Attributes attrs = ictx.getAttributes(
"_ldap._tcp." + argv[i], srv);
printAttrs(attrs);
System.out.println("... with InetAddress.getAllByName");
InetAddress[]
list = InetAddress.getAllByName("_ldap._tcp." + argv[i]);
for( int j = 0; j < list.length; j++ ) {
System.out.println( list[j] );
}
}
}
// Copied nearly verbatim from
// http://java.sun.com/products/jndi/tutorial/basics/directory/src/GetattrsAll.java
public static void printAttrs(Attributes attrs) {
if (attrs == null) {
System.out.println("No attributes");
} else {
/* Print each attribute */
try {
for ( NamingEnumeration ae = attrs.getAll();
ae.hasMore();
// nix
) {
final Attribute attr = (Attribute)ae.next();
System.out.println(" " + attr.getID() + ":");
/* print each value */
for ( NamingEnumeration e = attr.getAll();
e.hasMore();
) {
Object a = e.next();
System.out.println( " [" + a.getClass().getName()
+ "] " + a );
}
}
} catch (NamingException e) {
e.printStackTrace();
}
}
}
}
More information about the jcifs
mailing list