<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="https://wiki.twig.es/skins/common/feed.css?303"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>https://wiki.twig.es/index.php?action=history&amp;feed=atom&amp;title=Query_Active_Directory_%28ldaptest%29</id>
		<title>Query Active Directory (ldaptest) - Revision history</title>
		<link rel="self" type="application/atom+xml" href="https://wiki.twig.es/index.php?action=history&amp;feed=atom&amp;title=Query_Active_Directory_%28ldaptest%29"/>
		<link rel="alternate" type="text/html" href="https://wiki.twig.es/index.php?title=Query_Active_Directory_(ldaptest)&amp;action=history"/>
		<updated>2026-05-06T16:41:02Z</updated>
		<subtitle>Revision history for this page on the wiki</subtitle>
		<generator>MediaWiki 1.23.0</generator>

	<entry>
		<id>https://wiki.twig.es/index.php?title=Query_Active_Directory_(ldaptest)&amp;diff=1822&amp;oldid=prev</id>
		<title>George2: Created page with &quot;&lt;source lang=&quot;java&quot;&gt;  package ldaptest;  import java.util.Hashtable; import javax.naming.Context; import javax.naming.NamingEnumeration; import javax.naming.NamingException; i...&quot;</title>
		<link rel="alternate" type="text/html" href="https://wiki.twig.es/index.php?title=Query_Active_Directory_(ldaptest)&amp;diff=1822&amp;oldid=prev"/>
				<updated>2015-04-14T12:13:06Z</updated>
		
		<summary type="html">&lt;p&gt;Created page with &amp;quot;&amp;lt;source lang=&amp;quot;java&amp;quot;&amp;gt;  package ldaptest;  import java.util.Hashtable; import javax.naming.Context; import javax.naming.NamingEnumeration; import javax.naming.NamingException; i...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;&amp;lt;source lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
package ldaptest;&lt;br /&gt;
&lt;br /&gt;
import java.util.Hashtable;&lt;br /&gt;
import javax.naming.Context;&lt;br /&gt;
import javax.naming.NamingEnumeration;&lt;br /&gt;
import javax.naming.NamingException;&lt;br /&gt;
import javax.naming.directory.DirContext;&lt;br /&gt;
import javax.naming.directory.SearchControls;&lt;br /&gt;
import javax.naming.directory.SearchResult;&lt;br /&gt;
import javax.naming.ldap.InitialLdapContext;&lt;br /&gt;
import javax.naming.ldap.LdapContext;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Example code for retrieving a Users Primary Group&lt;br /&gt;
 * from Microsoft Active Directory via. its LDAP API&lt;br /&gt;
 * &lt;br /&gt;
 * @author Adam Retter &amp;lt;adam.retter@googlemail.com&amp;gt;&lt;br /&gt;
 */&lt;br /&gt;
public class LDAPTest {&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * @param args the command line arguments&lt;br /&gt;
     */&lt;br /&gt;
    public static void main(String[] args) throws NamingException {&lt;br /&gt;
        &lt;br /&gt;
        final String ldapAdServer = &amp;quot;ldap://ad.your-server.com:389&amp;quot;;&lt;br /&gt;
        final String ldapSearchBase = &amp;quot;dc=ad,dc=my-domain,dc=com&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
        final String ldapUsername = &amp;quot;myLdapUsername&amp;quot;;&lt;br /&gt;
        final String ldapPassword = &amp;quot;myLdapPassword&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
        final String ldapAccountToLookup = &amp;quot;myOtherLdapUsername&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
        Hashtable&amp;lt;String, Object&amp;gt; env = new Hashtable&amp;lt;String, Object&amp;gt;();&lt;br /&gt;
        env.put(Context.SECURITY_AUTHENTICATION, &amp;quot;simple&amp;quot;);&lt;br /&gt;
        if(ldapUsername != null) {&lt;br /&gt;
            env.put(Context.SECURITY_PRINCIPAL, ldapUsername);&lt;br /&gt;
        }&lt;br /&gt;
        if(ldapPassword != null) {&lt;br /&gt;
            env.put(Context.SECURITY_CREDENTIALS, ldapPassword);&lt;br /&gt;
        }&lt;br /&gt;
        env.put(Context.INITIAL_CONTEXT_FACTORY, &amp;quot;com.sun.jndi.ldap.LdapCtxFactory&amp;quot;);&lt;br /&gt;
        env.put(Context.PROVIDER_URL, ldapAdServer);&lt;br /&gt;
&lt;br /&gt;
        //ensures that objectSID attribute values&lt;br /&gt;
        //will be returned as a byte[] instead of a String&lt;br /&gt;
        env.put(&amp;quot;java.naming.ldap.attributes.binary&amp;quot;, &amp;quot;objectSID&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        // the following is helpful in debugging errors&lt;br /&gt;
        //env.put(&amp;quot;com.sun.jndi.ldap.trace.ber&amp;quot;, System.err);&lt;br /&gt;
        &lt;br /&gt;
        LdapContext ctx = new InitialLdapContext();&lt;br /&gt;
        &lt;br /&gt;
        LDAPTest ldap = new LDAPTest();&lt;br /&gt;
        &lt;br /&gt;
        //1) lookup the ldap account&lt;br /&gt;
        SearchResult srLdapUser = ldap.findAccountByAccountName(ctx, ldapSearchBase, ldapAccountToLookup);&lt;br /&gt;
        &lt;br /&gt;
        //2) get the SID of the users primary group&lt;br /&gt;
        String primaryGroupSID = ldap.getPrimaryGroupSID(srLdapUser);&lt;br /&gt;
        &lt;br /&gt;
        //3) get the users Primary Group&lt;br /&gt;
        String primaryGroupName = ldap.findGroupBySID(ctx, ldapSearchBase, primaryGroupSID);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    public SearchResult findAccountByAccountName(DirContext ctx, String ldapSearchBase, String accountName) throws NamingException {&lt;br /&gt;
&lt;br /&gt;
        String searchFilter = &amp;quot;(&amp;amp;(objectClass=user)(sAMAccountName=&amp;quot; + accountName + &amp;quot;))&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        SearchControls searchControls = new SearchControls();&lt;br /&gt;
        searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);&lt;br /&gt;
&lt;br /&gt;
        NamingEnumeration&amp;lt;SearchResult&amp;gt; results = ctx.search(ldapSearchBase, searchFilter, searchControls);&lt;br /&gt;
&lt;br /&gt;
        SearchResult searchResult = null;&lt;br /&gt;
        if(results.hasMoreElements()) {&lt;br /&gt;
             searchResult = (SearchResult) results.nextElement();&lt;br /&gt;
&lt;br /&gt;
            //make sure there is not another item available, there should be only 1 match&lt;br /&gt;
            if(results.hasMoreElements()) {&lt;br /&gt;
                System.err.println(&amp;quot;Matched multiple users for the accountName: &amp;quot; + accountName);&lt;br /&gt;
                return null;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        return searchResult;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    public String findGroupBySID(DirContext ctx, String ldapSearchBase, String sid) throws NamingException {&lt;br /&gt;
        &lt;br /&gt;
        String searchFilter = &amp;quot;(&amp;amp;(objectClass=group)(objectSid=&amp;quot; + sid + &amp;quot;))&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        SearchControls searchControls = new SearchControls();&lt;br /&gt;
        searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);&lt;br /&gt;
        &lt;br /&gt;
        NamingEnumeration&amp;lt;SearchResult&amp;gt; results = ctx.search(ldapSearchBase, searchFilter, searchControls);&lt;br /&gt;
&lt;br /&gt;
        if(results.hasMoreElements()) {&lt;br /&gt;
            SearchResult searchResult = (SearchResult) results.nextElement();&lt;br /&gt;
&lt;br /&gt;
            //make sure there is not another item available, there should be only 1 match&lt;br /&gt;
            if(results.hasMoreElements()) {&lt;br /&gt;
                System.err.println(&amp;quot;Matched multiple groups for the group with SID: &amp;quot; + sid);&lt;br /&gt;
                return null;&lt;br /&gt;
            } else {&lt;br /&gt;
                return (String)searchResult.getAttributes().get(&amp;quot;sAMAccountName&amp;quot;).get();&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        return null;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    public String getPrimaryGroupSID(SearchResult srLdapUser) throws NamingException {&lt;br /&gt;
        byte[] objectSID = (byte[])srLdapUser.getAttributes().get(&amp;quot;objectSid&amp;quot;).get();&lt;br /&gt;
        String strPrimaryGroupID = (String)srLdapUser.getAttributes().get(&amp;quot;primaryGroupID&amp;quot;).get();&lt;br /&gt;
        &lt;br /&gt;
        String strObjectSid = decodeSID(objectSID);&lt;br /&gt;
        &lt;br /&gt;
        return strObjectSid.substring(0, strObjectSid.lastIndexOf('-') + 1) + strPrimaryGroupID;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /**&lt;br /&gt;
     * The binary data is in the form:&lt;br /&gt;
     * byte[0] - revision level&lt;br /&gt;
     * byte[1] - count of sub-authorities&lt;br /&gt;
     * byte[2-7] - 48 bit authority (big-endian)&lt;br /&gt;
     * and then count x 32 bit sub authorities (little-endian)&lt;br /&gt;
     * &lt;br /&gt;
     * The String value is: S-Revision-Authority-SubAuthority[n]...&lt;br /&gt;
     * &lt;br /&gt;
     * Based on code from here - http://forums.oracle.com/forums/thread.jspa?threadID=1155740&amp;amp;tstart=0&lt;br /&gt;
     */&lt;br /&gt;
    public static String decodeSID(byte[] sid) {&lt;br /&gt;
        &lt;br /&gt;
        final StringBuilder strSid = new StringBuilder(&amp;quot;S-&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        // get version&lt;br /&gt;
        final int revision = sid[0];&lt;br /&gt;
        strSid.append(Integer.toString(revision));&lt;br /&gt;
        &lt;br /&gt;
        //next byte is the count of sub-authorities&lt;br /&gt;
        final int countSubAuths = sid[1] &amp;amp; 0xFF;&lt;br /&gt;
        &lt;br /&gt;
        //get the authority&lt;br /&gt;
        long authority = 0;&lt;br /&gt;
        //String rid = &amp;quot;&amp;quot;;&lt;br /&gt;
        for(int i = 2; i &amp;lt;= 7; i++) {&lt;br /&gt;
           authority |= ((long)sid[i]) &amp;lt;&amp;lt; (8 * (5 - (i - 2)));&lt;br /&gt;
        }&lt;br /&gt;
        strSid.append(&amp;quot;-&amp;quot;);&lt;br /&gt;
        strSid.append(Long.toHexString(authority));&lt;br /&gt;
        &lt;br /&gt;
        //iterate all the sub-auths&lt;br /&gt;
        int offset = 8;&lt;br /&gt;
        int size = 4; //4 bytes for each sub auth&lt;br /&gt;
        for(int j = 0; j &amp;lt; countSubAuths; j++) {&lt;br /&gt;
            long subAuthority = 0;&lt;br /&gt;
            for(int k = 0; k &amp;lt; size; k++) {&lt;br /&gt;
                subAuthority |= (long)(sid[offset + k] &amp;amp; 0xFF) &amp;lt;&amp;lt; (8 * k);&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
            strSid.append(&amp;quot;-&amp;quot;);&lt;br /&gt;
            strSid.append(subAuthority);&lt;br /&gt;
            &lt;br /&gt;
            offset += size;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        return strSid.toString();    &lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>George2</name></author>	</entry>

	</feed>