LDAP Java Client

package de.zf.pada.server.util;

import java.util.Hashtable;

import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;

public class LdapClient
{
  private static final String LDAP_AD_SERVER = "ldap://<server>";

  private static final String LDAP_SEARCH_BASE = "DC=,DC=";

  public static void main(String[] args)
  {
    final String user = "<user>";
    final DirContext ctx = connect("\\" + user, "<pass>");
    SearchResult r = lookup(ctx, user);
    String grp = getGroup(ctx, r);
    System.out.println("user: " + user + ", group: " + grp);
    disconnect(ctx);
  }

  public static SearchResult lookup(DirContext ctx, String acc)
  {
    String f = "(&(objectClass=user)(sAMAccountName=" + acc + "))";

    SearchControls sc = new SearchControls();
    sc.setSearchScope(SearchControls.SUBTREE_SCOPE);

    try
    {
      NamingEnumeration results = ctx.search(LDAP_SEARCH_BASE, f, sc);
      SearchResult searchResult = null;
      if (results.hasMoreElements())
      {
        searchResult = (SearchResult) results.nextElement();

        if (results.hasMoreElements())
        {
          System.err.println("Matched multiple users for the account: " + acc);
          return null;
        }
      }
      return searchResult;
    } catch (Exception e)
    {
      System.err.println("LDAP search failed: " + e);
      e.printStackTrace();
      return null;
    }

  }

  public static String getGroup(DirContext ctx, SearchResult srLdapUser)
  {
    if (srLdapUser != null)
    {
      try
      {
        final byte[] objSIDBytes = (byte[]) srLdapUser.getAttributes().get("objectSid").get();
        final String grpID = (String) srLdapUser.getAttributes().get("primaryGroupID").get();
        final String objSID = decodeSID(objSIDBytes);
        final String grpSID = objSID.substring(0, objSID.lastIndexOf('-') + 1) + grpID;

        final String f = "(&(objectClass=group)(objectSid=" + grpSID + "))";
        final SearchControls sc = new SearchControls();
        sc.setSearchScope(SearchControls.SUBTREE_SCOPE);
        final NamingEnumeration results = ctx.search(LDAP_SEARCH_BASE, f, sc);

        if (results.hasMoreElements())
        {
          SearchResult searchResult = (SearchResult) results.nextElement();

          if (results.hasMoreElements())
          {
            System.err.println("Matched multiple groups for the group with SID: " + grpSID);
          } else
          {
            return (String) searchResult.getAttributes().get("sAMAccountName").get();
          }
        }
      } catch (Exception e)
      {
        System.err.println("Failed to get group: " + e);
        e.printStackTrace();
      }
    }
    return null;
  }

  private static String decodeSID(byte[] sid)
  {

    final StringBuilder strSid = new StringBuilder("S-");
    final int revision = sid[0];
    strSid.append(Integer.toString(revision));

    final int countSubAuths = sid[1] & 0xFF;

    long authority = 0;
    for (int i = 2; i <= 7; i++)
    {
      authority |= ((long) sid[i]) << (8 * (5 - (i - 2)));
    }
    strSid.append("-");
    strSid.append(Long.toHexString(authority));

    int offset = 8;
    int size = 4;
    for (int j = 0; j < countSubAuths; j++)
    {
      long subAuthority = 0;
      for (int k = 0; k < size; k++)
      {
        subAuthority |= (long) (sid[offset + k] & 0xFF) << (8 * k);
      }

      strSid.append("-");
      strSid.append(subAuthority);

      offset += size;
    }

    return strSid.toString();
  }

  public static boolean disconnect(final DirContext ctx)
  {
    if (ctx != null)
    {
      try
      {
        ctx.close();
        return true;
      } catch (NamingException e)
      {
      }
    }
    return false;
  }

  public static DirContext connect(final String ldapUser, final String ldapPass)
  {
    try
    {
      final Hashtable<String, String> env = new Hashtable<String, String>();
      env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
      env.put(Context.PROVIDER_URL, LDAP_AD_SERVER);
      env.put(Context.SECURITY_AUTHENTICATION, "simple");
      env.put("java.naming.ldap.attributes.binary", "objectSID");
      env.put(Context.SECURITY_PRINCIPAL, ldapUser);
      env.put(Context.SECURITY_CREDENTIALS, ldapPass);
      return new InitialDirContext(env);
    } catch (Exception e)
    {
      e.printStackTrace();
      return null;
    }
  }
}
Advertisements