1
votes

I need to get group names for a userDN. I am trying this code but does not work properly as ctx.search() will return only one member for every group. I mean, even though some of my groups have multiple users as members (using member, not memberOf), the search() will return only one.

(I am using OpenLDAP as LDAP server)

In the end, my code will not return all groups for supplied userDN, as will not find all matches.

Thanks for any help.

    public Set<String> getLDAPGroupNames(String userDN) throws NamingException {
    Set<String> userRoleNames = new HashSet<>();
    if (isLDAPUserRepositoryEnabled()) {
        for (String roleName : getLDAPGroupNames()) {
            SearchControls constraints = new SearchControls();
            constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
            constraints.setReturningAttributes(new String[] { "member" });
            constraints.setCountLimit(100);
            // First input parameter is search bas, it can be "CN=Users,DC=YourDomain,DC=com"
            // Second Attribute can be uid=username
            LdapContext ctx = getLdapContext();
            try {
                NamingEnumeration<SearchResult> answer = ctx.search(ldapGroupContextDN, "cn=" + roleName, constraints);
                while (answer.hasMore()) {
                    NamingEnumeration<? extends Attribute> attributes = answer.next().getAttributes().getAll();// FIXME Only returns first of the member entry for the group.
                    while (attributes.hasMore()) {
                        Attribute attribute = attributes.next();
                        if (userDN.equalsIgnoreCase((String) attribute.get()))
                            userRoleNames.add(roleName);
                    }
                }
            } finally {
                ctx.close();
            }
        }
    } else
        throw new IllegalStateException("Can't return LDAP group names. No LDAP Context enabled.");
    return userRoleNames;
}
2

2 Answers

1
votes

I know this is an old question, but I had the same question and found a solution. I am including it here, so that others can benefit.

JNDI does handle multivalued attributes. I am using the following to gather all members of a group, rather than find the groups that a user belongs to. That is, userRoleNames has the users in the group, rather than the roles of the user. If you want the roles that a particular user has (ie. the groups that the user belongs to), then the solution noted by EJP can be used).

The solution is to change

 while (attributes.hasMore()) {
                    Attribute attribute = attributes.next();
                    if (userDN.equalsIgnoreCase((String) attribute.get()))
                        userRoleNames.add(roleName);
 }

to

 while (attributes.hasMore()) {
     Attribute attribute = attributes.next();
     if ("member".equalsIgnoreCase(attribute.getID())){
            for (NamingEnumeration<Object> e = (NamingEnumeration<Object>)attribute.getAll(); e.hasMore(); ){
                    Object v = e.next();
                    userRoleNames.add( v instanceof byte[]? new String((byte[])v):v.toString());
            }
        }                
}
0
votes

The filter should be "(&(cn={0})(member={1}))", with filter arguments {roleName, userDN}, and you should remove the part of your own code that checks the userDN. Then only the groups that have that user as a member will be returned, and all you have to do is save them.