Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Authenticating from Java (Linux) to Active Directory using LDAP WITHOUT servername

Our developers use Java on Linux for various things (like checking membership of groups etc). It works - no problem with that!

The problem is that they have hardcoded the servernames of our Domain Controllers (LDAP-servers) in their code. So now when we need to replace them with newer DCs, they need to change the code.

Active Directory by nature is redundant. The domain name (example: domain.local) is a round-robin of all the DC:s available for our AD.

Is there any way for the developer to NOT specify Domain Controller server names but simply the Active Directory domain name and then their Linux server will find the DC:s available and use whichever one is up and running?

Examples/links appreciated. Thanks!

like image 875
Jonas B Avatar asked Jun 22 '10 09:06

Jonas B


2 Answers

Obviously, the server name should at least be configurable, not hard coded into the application.

However, you should be able to find the server by looking up a special DNS record, namely a SRV record for _ldap._tcp.DOMAINNAME. The linux servers have to be configured to use the same DNS server as your AD updates.

To determine whether this is feasible, run the command host -t srv _ldap._tcp.DOMAINNAME on your linux server

See also Querying the DNS service records to find the hostname and TCP/IP provides some info on how to look up SRV records in java, and https://community.oracle.com/blogs/kohsuke/2008/06/12/more-active-directory-integration-java

like image 138
nos Avatar answered Sep 21 '22 00:09

nos


We use the follow code that work on a large amount of systems:

/**
 * Detect the default LDAP server
 * @return server:port or null
 */
String getDefaultLdapHost() {
    try {
        Hashtable<String, String> env = new Hashtable();
        env.put( "java.naming.factory.initial", "com.sun.jndi.dns.DnsContextFactory" );
        DirContext dns = new InitialDirContext( env );

        InetAddress address = InetAddress.getLocalHost();
        String domain = address.getCanonicalHostName();

        if( domain.equals( address.getHostAddress() ) ) {
            //domain is a ip address
            domain = getDnsPtr( dns );
        }

        int idx = domain.indexOf( '.' );
        if( idx < 0 ) {
            //computer is not in a domain? We will look in the DNS self.
            domain = getDnsPtr( dns );
            idx = domain.indexOf( '.' );
            if( idx < 0 ) {
                //computer is not in a domain
                return null;
            }
        }
        domain = domain.substring( idx + 1 );

        Attributes attrs = dns.getAttributes( "_ldap._tcp." + domain, new String[] { "SRV" } );

        Attribute attr = attrs.getAll().nextElement();
        String srv = attr.get().toString();

        String[] parts = srv.split( " " );
        return parts[3] + ":" + parts[2];
    } catch( Exception ex ) {
        ex.printStackTrace();
        return null;
    }
}

/**
 * Look for a reverse PTR record on any available ip address
 * @param dns DNS context
 * @return the PTR value
 * @throws Exception if the PTR entry was not found
 */
private String getDnsPtr( DirContext dns ) throws Exception {
    Exception exception = null;
    Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
    while(interfaces.hasMoreElements()) {
        NetworkInterface nif = interfaces.nextElement();
        if( nif.isLoopback() ) {
            continue;
        }
        Enumeration<InetAddress> adresses = nif.getInetAddresses();
        while(adresses.hasMoreElements()) {
            InetAddress address = adresses.nextElement();
            if( address.isLoopbackAddress() || address instanceof Inet6Address) {
                continue;
            }
            String domain = address.getCanonicalHostName();
            if( !domain.equals( address.getHostAddress() ) && (domain.indexOf( '.' ) > 0) ) {
                return domain;
            }

            String ip = address.getHostAddress();
            String[] digits = ip.split( "\\." );
            StringBuilder builder = new StringBuilder();
            builder.append( digits[3] ).append( '.' );
            builder.append( digits[2] ).append( '.' );
            builder.append( digits[1] ).append( '.' );
            builder.append( digits[0] ).append( ".in-addr.arpa." );
            try {
                Attributes attrs = dns.getAttributes( builder.toString(), new String[] { "PTR" } );
                return attrs.get( "PTR" ).get().toString();
            } catch( Exception ex ) {
                exception = ex;
            }
        }
    }
    if( exception != null ) {
        throw exception;
    }
    throw new IllegalStateException("No network");
}
like image 26
Horcrux7 Avatar answered Sep 22 '22 00:09

Horcrux7