javaactive-directoryldapldapconnection

Search across all subdomains in a ldapContext in Java


I have established an LdapContext in Java, and am looking to perform searches against it. I'm connecting to an IP (ldap://1.1.1.20:389) with a root domain of dc=fake,dc=domain,dc=com. I'm looking to validate users on this server, but the users are spread out across several domains in the forest. I'm trying to query the root level to search all of the subdomains for a user.

I've found this tutorial, https://docs.oracle.com/javase/10/jmx/examples-lookup-ldap-client-java.htm#JSJMX-GUID-5BA2ADC5-5597-4F1D-BF53-F1A2C7DB6117, and have used it to try to search the root level by casting my LdapContext as a DirContext like they do in the tutorial.

ctx = new InitialLdapContext(env, null);
DirContext root = (DirContext) (ctx.lookup(""));

SearchControls searchControls = new SearchControls();
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
searchControls.setTimeLimit(30000);
ctx.setRequestControls(null);
NamingEnumeration<?> namingEnum = root.search("", "(CN=Bob Test)", searchControls);

while (namingEnum.hasMore())
{
    SearchResult result = (SearchResult) namingEnum.next();
    Attributes attrs = result.getAttributes();
    IDActive = true;            
}

This results in a PartialResultException. I am able to search specific locations, but I have no idea how to properly "trickle down" my search from the root so that it could validate a User in any sub domain. Thanks


Solution

  • If you need to search the whole AD forest, it should be as easy as connecting to the Global Catalog. It's as easy as changing the port you connect to (as long as there is no firewall blocking the connection):

    ldap://1.1.1.20:3268
    

    The Global Catalog uses the LDAP protocol too, but returns results from the whole forest instead of just the domain of the server. There are a couple caveats:

    1. You cannot make changes on the GC.
    2. Some attributes are not replicated to the GC (for example, accountExpires). So be aware that you can't get all the same data on the GC that you can via regular LDAP.

    If either of those are issues for you, you can get the distinguishedName from the GC, then use it to bind to the object via regular LDAP to either modify it or get the extra data you need.