[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