user1854496
user1854496

Reputation: 622

How to check if a user is in an LDAP group

Problem

I want to see if user "john" is in group "Calltaker". I can't seem to get the syntax right on my search filter to check for a specific user in a specific group. I can list all users in a group to verify the desired user is there.

Questions

  1. What is the right syntax for a ldap search filter to determine if a specific user is in a specific group(in Tivoli Access Manager)?
  2. What should I check on the returned LDAPEntry object given by that search string to see that the user is, or isn't, in the group?

Info

  1. john is defined in "cn=users,dc=ldap,dc=net"
  2. Calltaker is defined in "cn=groups,dc=ldap,dc=net"
  3. I'm querying against TAM's ldap, from java

Using the searchfilter to be "cn=Calltaker" I can print out the search results such that calling nextEntry.toString contains the list of users. See Example 1 below

Here's a few searchfilters I've tried that don't work (aka searchResults.next() throws an error):

(&(objectclass=groupOfUniqueName)(uniquemember=uid="+ username + ",cn=groups,dc=ldap,dc=net))
(&(objectclass=groupOfUniqueName)(uniquemember=uid="+ username + ",cn=users,dc=ldap,dc=net))
(uniquemember=uid="+ username + ",cn=users,dc=ldap,dc=net)

Example 1) only search group, using searchFilter="cn=Calltaker", verify it contains users:

System.out.println(nextEntry.toString()); //added newlines for readability
 nextEntry: 
 LDAPEntry: 
 cn=Calltaker,cn=groups,dc=ldap,dc=net; 
 LDAPAttributeSet: 
 LDAPAttribute: {type='objectclass', values='groupOfUniqueNames','top'} 
 LDAPAttribute: {type='uniquemember', 
  values=
     'uid=placeholder,cn=users,dc=ldap,dc=net',
     'secAuthority=default',
     'uid=john,cn=users,dc=ldap,dc=net',
     'uid=sally,cn=users,dc=ldap,dc=net', ....etc

Code:

public boolean isUserInGroup(username){
    boolean userInGroup = false;

    String loginDN = "uid=" + admin_username + "," + "cn=users,dc=ldap,dc=net";
    String searchBase = "cn=groups,dc=ldap,dc=net";
    int searchScope = LDAPConnection.SCOPE_SUB; 
    searchFilter = "(&(objectclass=ePerson)(uniquemember=uid="+ username + ",cn=users,dc=ldap,dc=net))";

    //Connect
    LDAPConnection lc = connect(hosts);
    lc.bind(LDAPConnection.LDAP_V3, loginDN, admin_password.getBytes("UTF8"));
    lc.getAuthenticationDN();

    LDAPSearchResults searchResults = lc.search(searchBase,
            searchScope, 
            searchFilter, 
            null,           // return all attributes
            false);         // return attrs and values

    while (searchResults.hasMore()) {
        LDAPEntry nextEntry = null;
        try {
            nextEntry = searchResults.next();
        } catch (LDAPException e) {
            // Exception is thrown, go for next entry
            if (e.getResultCode() == LDAPException.LDAP_TIMEOUT || e.getResultCode() == LDAPException.CONNECT_ERROR)
                break;
            else
                continue;
        }
        //TODO some check to verify nextEntry shows the user in the group
        userInGroup = true;
        LDAPAttributeSet attributeSet = nextEntry.getAttributeSet();
        Iterator<LDAPAttribute> allAttributes = attributeSet.iterator();
        while (allAttributes.hasNext()) {
            LDAPAttribute attribute = (LDAPAttribute) allAttributes.next();
            String attributeName = attribute.getName();
            System.out.println("found attribute '" + attributeName + "' with value '" + attribute.getStringValue() + "'");
        }
    }
    lc.disconnect();
return userInGroup;
}

** EDIT **

Implemented answer from EJP, changed searchBase to include group

Code that works:

private static final String admin_username = "foo";
private static final String[] hosts = new String[]{"foohost.net"};
public boolean isUserInGroup(String username, String group){
    boolean userInGroup = false;

    String loginDN = "uid=" + admin_username + "," + "cn=users,dc=ldap,dc=net";
    String searchBase = "cn=" + group + "," + "cn=groups,dc=ldap,dc=net";
    int searchScope = LDAPConnection.SCOPE_SUB; 
    searchFilter = "(&(objectclass=groupOfUniqueNames)(uniquemember=uid="+ username + ",cn=users,dc=ldap,dc=net))";

    //Connect
    LDAPConnection lc = connect(hosts);
    lc.bind(LDAPConnection.LDAP_V3, loginDN, admin_password.getBytes("UTF8"));
    lc.getAuthenticationDN();

    LDAPSearchResults searchResults = lc.search(searchBase,
            searchScope, 
            searchFilter, 
            null,           // return all attributes
            false);         // return attrs and values

    while (searchResults.hasMore()) {
        LDAPEntry nextEntry = null;
        try {
            nextEntry = searchResults.next();
        } catch (LDAPException e) {
            // Exception is thrown, go for next entry
            if (e.getResultCode() == LDAPException.LDAP_TIMEOUT || e.getResultCode() == LDAPException.CONNECT_ERROR)
                break;
            else
                continue;
        }
        //A result was found, therefore the user is in the group
        userInGroup = true;
    }
    lc.disconnect();
    return userInGroup;
}

Upvotes: 0

Views: 6925

Answers (1)

user207421
user207421

Reputation: 310860

What is the right syntax for a ldap search filter to determine if a specific user is in a specific group(in Tivoli Access Manager)?

Either of the filters you used, but the objectClass to search on is groupofUniqueNames (plural).

What should I check on the returned LDAPEntry object given by that search string to see that the user is, or isn't, in the group?

Nothing. He will be, otherwise the group won't be returned in the search. All you need to do is check that the search result is non-empty.

Here's a few searchfilters I've tried that don't work (aka searchResults.next() throws an error):

Throws what error?

(&(objectclass=groupOfUniqueName)(uniquemember=uid="+ username + ",cn=groups,dc=ldap,dc=net))

Nothing wrong with this except for groupOfUniqueName. You should use search filter arguments like {0} rather than building them into the search string.

(&(objectclass=groupOfUniqueName)(uniquemember=uid="+ username + ",cn=users,dc=ldap,dc=net))

This one will search the cn=users subtree for a group. It won't work unless you have groups under cn=users, which doesn't seem likely.

(uniquemember=uid="+ username + ",cn=users,dc=ldap,dc=net)

This will select non-groups. You don't want that: you need the objectClass part.

Upvotes: 1

Related Questions