Example usage for javax.naming.directory Attribute getID

List of usage examples for javax.naming.directory Attribute getID

Introduction

In this page you can find the example usage for javax.naming.directory Attribute getID.

Prototype

String getID();

Source Link

Document

Retrieves the id of this attribute.

Usage

From source file:org.wso2.carbon.identity.agent.onprem.userstore.manager.ldap.LDAPUserStoreManager.java

/**
 * {@inheritDoc}//from  w  ww . j av a  2 s  .  co  m
 */
@Override
public String[] doGetUserListOfRole(String roleName, int maxItemLimit) throws UserStoreException {

    boolean debug = log.isDebugEnabled();
    List<String> userList = new ArrayList<String>();
    String[] names = new String[0];
    int givenMax = CommonConstants.MAX_USER_ROLE_LIST;
    int searchTime = CommonConstants.MAX_SEARCH_TIME;

    try {
        givenMax = Integer.parseInt(userStoreProperties.get(CommonConstants.PROPERTY_MAX_USER_LIST));
    } catch (Exception e) {
        givenMax = CommonConstants.MAX_USER_ROLE_LIST;
    }

    try {
        searchTime = Integer.parseInt(userStoreProperties.get(CommonConstants.PROPERTY_MAX_SEARCH_TIME));
    } catch (Exception e) {
        searchTime = CommonConstants.MAX_SEARCH_TIME;
    }

    if (maxItemLimit <= 0 || maxItemLimit > givenMax) {
        maxItemLimit = givenMax;
    }

    DirContext dirContext = null;
    NamingEnumeration<SearchResult> answer = null;
    try {
        SearchControls searchCtls = new SearchControls();
        searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
        searchCtls.setTimeLimit(searchTime);
        searchCtls.setCountLimit(maxItemLimit);

        String searchFilter = userStoreProperties.get(LDAPConstants.GROUP_NAME_LIST_FILTER);
        String roleNameProperty = userStoreProperties.get(LDAPConstants.GROUP_NAME_ATTRIBUTE);
        searchFilter = "(&" + searchFilter + "(" + roleNameProperty + "="
                + escapeSpecialCharactersForFilter(roleName) + "))";

        String membershipProperty = userStoreProperties.get(LDAPConstants.MEMBERSHIP_ATTRIBUTE);
        String returnedAtts[] = { membershipProperty };
        searchCtls.setReturningAttributes(returnedAtts);
        List<String> userDNList = new ArrayList<String>();

        SearchResult sr = null;
        dirContext = connectionSource.getContext();

        // handling multiple search bases
        String searchBases = userStoreProperties.get(LDAPConstants.GROUP_SEARCH_BASE);
        String[] roleSearchBaseArray = searchBases.split("#");
        for (String searchBase : roleSearchBaseArray) {
            if (debug) {
                log.debug("Searching role: " + roleName + " SearchBase: " + searchBase + " SearchFilter: "
                        + searchFilter);
            }
            try {
                // read the DN of users who are members of the group
                answer = dirContext.search(escapeDNForSearch(searchBase), searchFilter, searchCtls);
                int count = 0;
                if (answer.hasMore()) { // to check if there is a result
                    while (answer.hasMore()) { // to check if there are more than one group
                        if (count > 0) {
                            throw new UserStoreException("More than one group exist with name");
                        }
                        sr = answer.next();
                        count++;
                    }
                    break;
                }
            } catch (NamingException e) {
                // ignore
                if (log.isDebugEnabled()) {
                    log.debug(e);
                }
            }
        }

        if (debug) {
            log.debug("Found role: " + sr.getNameInNamespace());
        }

        // read the member attribute and get DNs of the users
        Attributes attributes = sr.getAttributes();
        if (attributes != null) {
            NamingEnumeration attributeEntry = null;
            for (attributeEntry = attributes.getAll(); attributeEntry.hasMore();) {
                Attribute valAttribute = (Attribute) attributeEntry.next();
                if (membershipProperty.equals(valAttribute.getID())) {
                    NamingEnumeration values = null;
                    for (values = valAttribute.getAll(); values.hasMore();) {
                        String value = values.next().toString();
                        if (userDNList.size() >= maxItemLimit) {
                            break;
                        }
                        userDNList.add(value);
                        if (debug) {
                            log.debug("Found attribute: " + membershipProperty + " value: " + value);
                        }
                    }
                }
            }
        }

        if (MEMBER_UID.equals(userStoreProperties.get(LDAPConstants.MEMBERSHIP_ATTRIBUTE))) {
            /* when the GroupEntryObjectClass is posixGroup, membership attribute is memberUid. We have to
               retrieve the DN using the memberUid.
               This procedure has to make an extra call to ldap. alternatively this can be done with a single ldap
               search using the memberUid and retrieving the display name and username. */
            List<String> userDNListNew = new ArrayList<>();

            for (String user : userDNList) {
                String userDN = getNameInSpaceForUserName(user);
                userDNListNew.add(userDN);
            }
            userDNList = userDNListNew;
        }

        // iterate over users' DN list and get userName and display name
        // attribute values
        String userNameProperty = userStoreProperties.get(LDAPConstants.USER_NAME_ATTRIBUTE);
        String displayNameAttribute = userStoreProperties.get(LDAPConstants.DISPLAY_NAME_ATTRIBUTE);
        String[] returnedAttributes = { userNameProperty, displayNameAttribute };

        for (String user : userDNList) {
            if (debug) {
                log.debug("Getting name attributes of: " + user);
            }
            Attributes userAttributes;
            try {
                // '\' and '"' characters need another level of escaping before searching
                userAttributes = dirContext.getAttributes(escapeDNForSearch(user), returnedAttributes);

                String displayName = null;
                String userName = null;
                if (userAttributes != null) {
                    Attribute userNameAttribute = userAttributes.get(userNameProperty);
                    if (userNameAttribute != null) {
                        userName = (String) userNameAttribute.get();
                        if (debug) {
                            log.debug("UserName: " + userName);
                        }
                    }
                    if (org.apache.commons.lang.StringUtils.isNotEmpty(displayNameAttribute)) {
                        Attribute displayAttribute = userAttributes.get(displayNameAttribute);
                        if (displayAttribute != null) {
                            displayName = (String) displayAttribute.get();
                        }
                        if (debug) {
                            log.debug("DisplayName: " + displayName);
                        }
                    }
                }

                // Username will be null in the special case where the
                // username attribute has changed to another
                // and having different userNameProperty than the current
                // user-mgt.xml
                if (userName != null) {
                    user = UserStoreUtils.getCombinedName(userName, displayName);
                    userList.add(user);
                    if (debug) {
                        log.debug(user + " is added to the result list");
                    }
                } else {
                    if (log.isDebugEnabled()) {
                        log.debug(
                                "User " + user + " doesn't have the user name property : " + userNameProperty);
                    }
                }

            } catch (NamingException e) {
                if (log.isDebugEnabled()) {
                    log.debug("Error in reading user information in the user store for the user " + user
                            + e.getMessage(), e);
                }
            }

        }
        names = userList.toArray(new String[userList.size()]);

    } catch (PartialResultException e) {
        // can be due to referrals in AD. so just ignore error
        String errorMessage = "Error in reading user information in the user store";
        if (isIgnorePartialResultException()) {
            if (log.isDebugEnabled()) {
                log.debug(errorMessage, e);
            }
        } else {
            throw new UserStoreException(errorMessage, e);
        }
    } catch (NamingException e) {
        String errorMessage = "Error in reading user information in the user store";
        if (log.isDebugEnabled()) {
            log.debug(errorMessage, e);
        }
        throw new UserStoreException(errorMessage, e);
    } finally {
        JNDIUtil.closeNamingEnumeration(answer);
        JNDIUtil.closeContext(dirContext);
    }
    return names;
}

From source file:org.apache.jmeter.protocol.ldap.sampler.LDAPExtSampler.java

private void writeSearchResult(final SearchResult sr, final XMLBuffer xmlb) throws NamingException {
    final Attributes attrs = sr.getAttributes();
    final int size = attrs.size();
    final ArrayList<Attribute> sortedAttrs = new ArrayList<>(size);

    xmlb.openTag("searchresult"); // $NON-NLS-1$
    xmlb.tag("dn", sr.getName()); // $NON-NLS-1$
    xmlb.tag("returnedattr", Integer.toString(size)); // $NON-NLS-1$
    xmlb.openTag("attributes"); // $NON-NLS-1$

    try {//from www  .j a va 2 s .c om
        for (NamingEnumeration<? extends Attribute> en = attrs.getAll(); en.hasMore();) {
            final Attribute attr = en.next();
            sortedAttrs.add(attr);
        }
        sortAttributes(sortedAttrs);
        for (final Attribute attr : sortedAttrs) {
            StringBuilder sb = new StringBuilder();
            if (attr.size() == 1) {
                sb.append(getWriteValue(attr.get()));
            } else {
                final ArrayList<String> sortedVals = new ArrayList<>(attr.size());
                boolean first = true;

                for (NamingEnumeration<?> ven = attr.getAll(); ven.hasMore();) {
                    final Object value = getWriteValue(ven.next());
                    sortedVals.add(value.toString());
                }

                Collections.sort(sortedVals);

                for (final String value : sortedVals) {
                    if (first) {
                        first = false;
                    } else {
                        sb.append(", "); // $NON-NLS-1$
                    }
                    sb.append(value);
                }
            }
            xmlb.tag(attr.getID(), sb);
        }
    } finally {
        xmlb.closeTag("attributes"); // $NON-NLS-1$
        xmlb.closeTag("searchresult"); // $NON-NLS-1$
    }
}

From source file:org.wso2.carbon.user.core.ldap.ReadWriteLDAPUserStoreManager.java

/**
 * Check whether this is the last/only user in this group.
 *
 * @param userDN//from ww  w  .j  a  v  a  2  s .c  om
 * @param groupEntry
 * @return groupContext
 */
@SuppressWarnings("rawtypes")
protected boolean isOnlyUserInRole(String userDN, SearchResult groupEntry) throws UserStoreException {
    boolean isOnlyUserInRole = false;
    try {
        Attributes groupAttributes = groupEntry.getAttributes();
        if (groupAttributes != null) {
            NamingEnumeration attributes = groupAttributes.getAll();
            while (attributes.hasMoreElements()) {
                Attribute memberAttribute = (Attribute) attributes.next();
                String memberAttributeName = realmConfig
                        .getUserStoreProperty(LDAPConstants.MEMBERSHIP_ATTRIBUTE);
                String attributeID = memberAttribute.getID();
                if (memberAttributeName.equals(attributeID)) {
                    if (memberAttribute.size() == 1 && userDN.equals(memberAttribute.get())) {
                        return true;
                    }
                }

            }

            attributes.close();

        }
    } catch (NamingException e) {
        String errorMessage = "Error occurred while looping through attributes set of group: "
                + groupEntry.getNameInNamespace();
        if (log.isDebugEnabled()) {
            log.debug(errorMessage, e);
        }
        throw new UserStoreException(errorMessage, e);
    }
    return isOnlyUserInRole;
}

From source file:org.wso2.carbon.user.core.ldap.ReadWriteLDAPUserStoreManager.java

/**
 * Check whether user is in the group by searching through its member attributes.
 *
 * @param userDN// www  .j a v a  2s.c om
 * @param groupEntry
 * @return
 * @throws UserStoreException
 */
protected boolean isUserInRole(String userDN, SearchResult groupEntry) throws UserStoreException {
    boolean isUserInRole = false;
    try {
        Attributes groupAttributes = groupEntry.getAttributes();
        if (groupAttributes != null) {
            // get group's returned attributes
            NamingEnumeration attributes = groupAttributes.getAll();
            // loop through attributes
            while (attributes.hasMoreElements()) {
                Attribute memberAttribute = (Attribute) attributes.next();
                String memberAttributeName = realmConfig
                        .getUserStoreProperty(LDAPConstants.MEMBERSHIP_ATTRIBUTE);
                if (memberAttributeName.equalsIgnoreCase(memberAttribute.getID())) {
                    // loop through attribute values
                    for (int i = 0; i < memberAttribute.size(); i++) {
                        if (userDN.equalsIgnoreCase((String) memberAttribute.get(i))) {
                            return true;
                        }
                    }
                }

            }

            attributes.close();
        }
    } catch (NamingException e) {
        String errorMessage = "Error occurred while looping through attributes set of group: "
                + groupEntry.getNameInNamespace();
        if (log.isDebugEnabled()) {
            log.debug(errorMessage, e);
        }
        throw new UserStoreException(errorMessage, e);
    }
    return isUserInRole;
}

From source file:no.feide.moria.directory.backend.JNDIBackend.java

/**
 * Retrieves a list of attributes from an element.
 * @param ldap//from   w  w  w.  j a v  a2s . c o  m
 *            A prepared LDAP context. Cannot be <code>null</code>.
 * @param rdn
 *            The relative DN (to the DN in the LDAP context
 *            <code>ldap</code>). Cannot be <code>null</code>.
 * @param attributes
 *            The requested attribute's names. Also indirectly referenced
 *            attributes on the form
 *            <code>someReferenceAttribute:someIndirectAttribute</code>,
 *            where the DN in the reference attribute
 *            <code>someReferenceAttribute</code> is followed to look up
 *            <code>someIndirectAttribute</code> from another element.
 * @return The requested attributes (<code>String</code> names and
 *         <code>String[]</code> values), if they did exist in the
 *         external backend. Otherwise returns those attributes that could
 *         actually be read, this may be an empty <code>HashMap</code>.
 *         Returns an empty <code>HashMap</code> if
 *         <code>attributes</code> is <code>null</code> or an empty
 *         array. Note that attribute values are mapped to
 *         <code>String</code> using ISO-8859-1.
 * @throws BackendException
 *             If unable to read the attributes from the backend.
 * @throws NullPointerException
 *             If <code>ldap</code> or <code>rdn</code> is
 *             <code>null</code>.
 * @see javax.naming.directory.InitialDirContext#getAttributes(java.lang.String,
 *      java.lang.String[])
 */
private HashMap<String, String[]> getAttributes(final InitialLdapContext ldap, final String rdn,
        final String[] attributes) throws BackendException {

    // Sanity checks.
    if (ldap == null)
        throw new NullPointerException("LDAP context cannot be NULL");
    if (rdn == null)
        throw new NullPointerException("RDN cannot be NULL");
    if ((attributes == null) || (attributes.length == 0))
        return new HashMap<String, String[]>();

    // Used to remember attributes to be read through references later on.
    Hashtable<String, Vector> attributeReferences = new Hashtable<String, Vector>();

    // Strip down request, resolving references and removing duplicates.
    Vector<String> strippedAttributeRequest = new Vector<String>();
    for (int i = 0; i < attributes.length; i++) {
        int indexOfSplitCharacter = attributes[i]
                .indexOf(DirectoryManagerBackend.ATTRIBUTE_REFERENCE_SEPARATOR);
        if (indexOfSplitCharacter == -1) {

            // A regular attribute request.
            if (!strippedAttributeRequest.contains(attributes[i]))
                strippedAttributeRequest.add(attributes[i]);

        } else {

            // A referenced attribute request.
            final String referencingAttribute = attributes[i].substring(0, indexOfSplitCharacter);
            if (!strippedAttributeRequest.contains(referencingAttribute))
                strippedAttributeRequest.add(referencingAttribute);

            // Add to list of attributes to be read through each reference.
            if (!attributeReferences.containsKey(referencingAttribute)) {

                // Add new reference.
                Vector<String> referencedAttribute = new Vector<String>();
                referencedAttribute.add(attributes[i].substring(indexOfSplitCharacter + 1));
                attributeReferences.put(referencingAttribute, referencedAttribute);

            } else {

                // Update existing reference.
                Vector<String> referencedAttribute = attributeReferences.get(referencingAttribute);
                if (!referencedAttribute.contains(attributes[i].substring(indexOfSplitCharacter + 1)))
                    referencedAttribute.add(attributes[i].substring(indexOfSplitCharacter + 1));

            }

        }

    }

    // The context provider URL and DN, for later logging.
    String url = "unknown backend";
    String dn = "unknown dn";

    // Get the attributes from an already initialized LDAP connection.
    Attributes rawAttributes = null;
    try {

        // Remember the URL and bind DN, for later logging.
        final Hashtable environment = ldap.getEnvironment();
        url = (String) environment.get(Context.PROVIDER_URL);
        dn = (String) environment.get(Context.SECURITY_PRINCIPAL);

        // Get the attributes.
        rawAttributes = ldap.getAttributes(rdn, strippedAttributeRequest.toArray(new String[] {}));

    } catch (NameNotFoundException e) {

        // Successful authentication but missing user element; no attributes
        // returned and the event is logged.
        log.logWarn("No LDAP element found (DN was '" + dn + "')", mySessionTicket);
        rawAttributes = new BasicAttributes();

    } catch (NamingException e) {
        String a = new String();
        for (int i = 0; i < attributes.length; i++)
            a = a + attributes[i] + ", ";
        throw new BackendException("Unable to read attribute(s) '" + a.substring(0, a.length() - 2) + "' from '"
                + rdn + "' on '" + url + "'", e);
    }

    // Translate retrieved attributes from Attributes to HashMap.
    HashMap<String, String[]> convertedAttributes = new HashMap<String, String[]>();
    for (int i = 0; i < attributes.length; i++) {

        // Did we get any attribute back at all?
        final String requestedAttribute = attributes[i];
        Attribute rawAttribute = rawAttributes.get(requestedAttribute);
        if (rawAttribute == null) {

            // Attribute was not returned.
            log.logDebug("Requested attribute '" + requestedAttribute + "' not found on '" + url + "'",
                    mySessionTicket);

        } else {

            // Map the attribute values to String[].
            ArrayList<String> convertedAttributeValues = new ArrayList<String>(rawAttribute.size());
            for (int j = 0; j < rawAttribute.size(); j++) {
                try {

                    // We either have a String or a byte[].
                    String convertedAttributeValue = null;
                    try {

                        // Encode String.
                        convertedAttributeValue = new String(((String) rawAttribute.get(j)).getBytes(),
                                DirectoryManagerBackend.ATTRIBUTE_VALUE_CHARSET);
                    } catch (ClassCastException e) {

                        // Encode byte[] to String.
                        convertedAttributeValue = new String(Base64.encodeBase64((byte[]) rawAttribute.get(j)),
                                DirectoryManagerBackend.ATTRIBUTE_VALUE_CHARSET);

                    }
                    convertedAttributeValues.add(convertedAttributeValue);

                } catch (NamingException e) {
                    throw new BackendException("Unable to read attribute value of '" + rawAttribute.getID()
                            + "' from '" + url + "'", e);
                } catch (UnsupportedEncodingException e) {
                    throw new BackendException(
                            "Unable to use " + DirectoryManagerBackend.ATTRIBUTE_VALUE_CHARSET + " encoding",
                            e);
                }
            }
            convertedAttributes.put(requestedAttribute, convertedAttributeValues.toArray(new String[] {}));

        }

    }

    // Follow references to look up any indirectly referenced attributes.
    Enumeration<String> keys = attributeReferences.keys();
    while (keys.hasMoreElements()) {

        // Do we have a reference? 
        final String referencingAttribute = keys.nextElement();
        final String[] referencingValues = convertedAttributes.get(referencingAttribute);
        if (referencingValues == null) {

            // No reference was found in this attribute.
            log.logDebug("Found no DN references in attribute '" + referencingAttribute + "'", mySessionTicket);

        } else {

            // One (or more) references was found in this attribute.
            if (referencingValues.length > 1)
                log.logDebug("Found " + referencingValues.length + " DN references in attribute '"
                        + referencingAttribute + "'; ignoring all but first", mySessionTicket);
            log.logDebug("Following reference '" + referencingValues[0] + "' found in '" + referencingAttribute
                    + "' to look up attribute(s) '" + attributeReferences.get(referencingAttribute).toString(),
                    mySessionTicket);
            String providerURL = null; // To be used later.
            try {

                // Follow the reference.
                providerURL = (String) ldap.getEnvironment().get(Context.PROVIDER_URL);
                providerURL = providerURL.substring(0, providerURL.lastIndexOf("/") + 1) + referencingValues[0];
                ldap.addToEnvironment(Context.PROVIDER_URL, providerURL);

            } catch (NamingException e) {
                throw new BackendException("Unable to update provider URL in LDAP environment", e);
            }

            // Add any referenced attributes returned.
            HashMap additionalAttributes = getAttributes(ldap, providerURL,
                    (String[]) attributeReferences.get(referencingAttribute).toArray(new String[] {}));
            Iterator i = additionalAttributes.keySet().iterator();
            while (i.hasNext()) {
                String attributeName = (String) i.next();
                convertedAttributes.put(referencingAttribute
                        + DirectoryManagerBackend.ATTRIBUTE_REFERENCE_SEPARATOR + attributeName,
                        (String[]) additionalAttributes.get(attributeName));
            }

        }

    }

    return convertedAttributes;

}

From source file:org.wso2.carbon.user.core.ldap.ReadOnlyLDAPUserStoreManager.java

/**
 * @param sr//from w  ww .j  a va 2s  .c  o m
 * @param groupAttributeName
 * @return
 */
private List<String> parseSearchResult(SearchResult sr, String groupAttributeName) {
    List<String> list = new ArrayList<String>();
    Attributes attrs = sr.getAttributes();

    if (attrs != null) {
        try {
            NamingEnumeration ae = null;
            for (ae = attrs.getAll(); ae.hasMore();) {
                Attribute attr = (Attribute) ae.next();
                if (groupAttributeName == null || groupAttributeName.equals(attr.getID())) {
                    NamingEnumeration e = null;
                    for (e = attr.getAll(); e.hasMore();) {
                        String value = e.next().toString();
                        int begin = value.indexOf("=") + 1;
                        int end = value.indexOf(",");
                        if (begin > -1 && end > -1) {
                            value = value.substring(begin, end);
                        }
                        list.add(value);
                    }
                    JNDIUtil.closeNamingEnumeration(e);
                }
            }
            JNDIUtil.closeNamingEnumeration(ae);
        } catch (NamingException e) {
            log.debug(e.getMessage(), e);
        }
    }
    return list;
}

From source file:org.wso2.carbon.user.core.ldap.ReadOnlyLDAPUserStoreManager.java

/**
 *
 *///from   w w  w. j a  v a 2s.co m
public String[] getUserListOfLDAPRole(RoleContext context, String filter) throws UserStoreException {

    boolean debug = log.isDebugEnabled();

    if (debug) {
        log.debug("Getting user list of role: " + context.getRoleName() + " with filter: " + filter);
    }

    List<String> userList = new ArrayList<String>();
    String[] names = new String[0];
    int givenMax = UserCoreConstants.MAX_USER_ROLE_LIST;
    int searchTime = UserCoreConstants.MAX_SEARCH_TIME;

    try {
        givenMax = Integer.parseInt(
                realmConfig.getUserStoreProperty(UserCoreConstants.RealmConfig.PROPERTY_MAX_USER_LIST));
    } catch (Exception e) {
        givenMax = UserCoreConstants.MAX_USER_ROLE_LIST;
    }

    try {
        searchTime = Integer.parseInt(
                realmConfig.getUserStoreProperty(UserCoreConstants.RealmConfig.PROPERTY_MAX_SEARCH_TIME));
    } catch (Exception e) {
        searchTime = UserCoreConstants.MAX_SEARCH_TIME;
    }

    DirContext dirContext = null;
    NamingEnumeration<SearchResult> answer = null;
    try {
        SearchControls searchCtls = new SearchControls();
        searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
        searchCtls.setTimeLimit(searchTime);
        searchCtls.setCountLimit(givenMax);

        String searchFilter = ((LDAPRoleContext) context).getListFilter();
        String roleNameProperty = ((LDAPRoleContext) context).getRoleNameProperty();
        searchFilter = "(&" + searchFilter + "(" + roleNameProperty + "="
                + escapeSpecialCharactersForFilter(context.getRoleName()) + "))";

        String membershipProperty = realmConfig.getUserStoreProperty(LDAPConstants.MEMBERSHIP_ATTRIBUTE);
        String returnedAtts[] = { membershipProperty };
        searchCtls.setReturningAttributes(returnedAtts);

        List<String> userDNList = new ArrayList<String>();

        SearchResult sr = null;
        dirContext = connectionSource.getContext();

        // with DN patterns
        if (((LDAPRoleContext) context).getRoleDNPatterns().size() > 0) {
            for (String pattern : ((LDAPRoleContext) context).getRoleDNPatterns()) {
                if (debug) {
                    log.debug("Using pattern: " + pattern);
                }
                pattern = MessageFormat.format(pattern.trim(),
                        escapeSpecialCharactersForDN(context.getRoleName()));
                try {
                    answer = dirContext.search(escapeDNForSearch(pattern), searchFilter, searchCtls);
                    if (answer.hasMore()) {
                        sr = (SearchResult) answer.next();
                        break;
                    }
                } catch (NamingException e) {
                    // ignore
                    if (log.isDebugEnabled()) {
                        log.debug(e);
                    }
                }
            }
        }

        if (sr == null) {
            // handling multiple search bases
            String searchBases = ((LDAPRoleContext) context).getSearchBase();
            String[] roleSearchBaseArray = searchBases.split("#");
            for (String searchBase : roleSearchBaseArray) {
                if (debug) {
                    log.debug("Searching role: " + context.getRoleName() + " SearchBase: " + searchBase
                            + " SearchFilter: " + searchFilter);
                }

                try {
                    // read the DN of users who are members of the group
                    answer = dirContext.search(escapeDNForSearch(searchBase), searchFilter, searchCtls);
                    int count = 0;
                    if (answer.hasMore()) { // to check if there is a result
                        while (answer.hasMore()) { // to check if there are more than one group
                            if (count > 0) {
                                throw new UserStoreException("More than one group exist with name");
                            }
                            sr = (SearchResult) answer.next();
                            count++;
                        }
                        break;
                    }
                } catch (NamingException e) {
                    // ignore
                    if (log.isDebugEnabled()) {
                        log.debug(e);
                    }
                }
            }
        }

        if (debug) {
            log.debug("Found role: " + sr.getNameInNamespace());
        }

        // read the member attribute and get DNs of the users
        Attributes attributes = sr.getAttributes();
        if (attributes != null) {
            NamingEnumeration attributeEntry = null;
            for (attributeEntry = attributes.getAll(); attributeEntry.hasMore();) {
                Attribute valAttribute = (Attribute) attributeEntry.next();
                if (membershipProperty == null || membershipProperty.equals(valAttribute.getID())) {
                    NamingEnumeration values = null;
                    for (values = valAttribute.getAll(); values.hasMore();) {
                        String value = values.next().toString();
                        userDNList.add(value);

                        if (debug) {
                            log.debug("Found attribute: " + membershipProperty + " value: " + value);
                        }
                    }
                }
            }
        }

        if (MEMBER_UID.equals(realmConfig.getUserStoreProperty(LDAPConstants.MEMBERSHIP_ATTRIBUTE))) {
            /* when the GroupEntryObjectClass is posixGroup, membership attribute is memberUid. We have to
               retrieve the DN using the memberUid.
               This procedure has to make an extra call to ldap. alternatively this can be done with a single ldap
               search using the memberUid and retrieving the display name and username. */
            List<String> userDNListNew = new ArrayList<>();

            for (String user : userDNList) {
                String userDN = getNameInSpaceForUserName(user);
                userDNListNew.add(userDN);
            }

            userDNList = userDNListNew;
        }

        // iterate over users' DN list and get userName and display name
        // attribute values

        String userNameProperty = realmConfig.getUserStoreProperty(LDAPConstants.USER_NAME_ATTRIBUTE);
        String displayNameAttribute = realmConfig.getUserStoreProperty(LDAPConstants.DISPLAY_NAME_ATTRIBUTE);
        String[] returnedAttributes = { userNameProperty, displayNameAttribute };

        for (String user : userDNList) {
            if (debug) {
                log.debug("Getting name attributes of: " + user);
            }

            Attributes userAttributes;
            try {
                // '\' and '"' characters need another level of escaping before searching
                userAttributes = dirContext.getAttributes(
                        user.replace("\\\\", "\\\\\\").replace("\\\"", "\\\\\""), returnedAttributes);

                String displayName = null;
                String userName = null;
                if (userAttributes != null) {
                    Attribute userNameAttribute = userAttributes.get(userNameProperty);
                    if (userNameAttribute != null) {
                        userName = (String) userNameAttribute.get();
                        if (debug) {
                            log.debug("UserName: " + userName);
                        }
                    }
                    if (displayNameAttribute != null) {
                        Attribute displayAttribute = userAttributes.get(displayNameAttribute);
                        if (displayAttribute != null) {
                            displayName = (String) displayAttribute.get();
                        }
                        if (debug) {
                            log.debug("DisplayName: " + displayName);
                        }
                    }
                }
                String domainName = realmConfig
                        .getUserStoreProperty(UserCoreConstants.RealmConfig.PROPERTY_DOMAIN_NAME);

                // Username will be null in the special case where the
                // username attribute has changed to another
                // and having different userNameProperty than the current
                // user-mgt.xml
                if (userName != null) {
                    user = UserCoreUtil.getCombinedName(domainName, userName, displayName);
                    userList.add(user);
                    if (debug) {
                        log.debug(user + " is added to the result list");
                    }
                }
                // Skip listing users which are not applicable to current
                // user-mgt.xml
                else {
                    if (log.isDebugEnabled()) {
                        log.debug(
                                "User " + user + " doesn't have the user name property : " + userNameProperty);
                    }
                }

            } catch (NamingException e) {
                if (log.isDebugEnabled()) {
                    log.debug("Error in reading user information in the user store for the user " + user
                            + e.getMessage(), e);
                }
            }

        }
        names = userList.toArray(new String[userList.size()]);

    } catch (PartialResultException e) {
        // can be due to referrals in AD. so just ignore error
        String errorMessage = "Error in reading user information in the user store for filter : " + filter;
        if (isIgnorePartialResultException()) {
            if (log.isDebugEnabled()) {
                log.debug(errorMessage, e);
            }
        } else {
            throw new UserStoreException(errorMessage, e);
        }
    } catch (NamingException e) {
        String errorMessage = "Error in reading user information in the user store for filter : " + filter;
        if (log.isDebugEnabled()) {
            log.debug(errorMessage, e);
        }
        throw new UserStoreException(errorMessage, e);
    } finally {
        JNDIUtil.closeNamingEnumeration(answer);
        JNDIUtil.closeContext(dirContext);
    }

    return names;
}

From source file:org.wso2.carbon.identity.agent.onprem.userstore.manager.ldap.LDAPUserStoreManager.java

/**
 * {@inheritDoc}/*from w  w  w .  j  av a  2 s  . c  o m*/
 */
public Map<String, String> getUserPropertyValues(String userName, String[] propertyNames)
        throws UserStoreException {

    String userAttributeSeparator = ",";
    String userDN = null;

    // read list of patterns from user-mgt.xml
    String patterns = userStoreProperties.get(LDAPConstants.USER_DN_PATTERN);

    if (patterns != null && !patterns.isEmpty()) {

        if (log.isDebugEnabled()) {
            log.debug("Using User DN Patterns " + patterns);
        }

        if (patterns.contains(CommonConstants.XML_PATTERN_SEPERATOR)) {
            userDN = getNameInSpaceForUserName(userName);
        } else {
            userDN = MessageFormat.format(patterns, escapeSpecialCharactersForDN(userName));
        }
    }

    Map<String, String> values = new HashMap<>();
    DirContext dirContext = this.connectionSource.getContext();
    String userSearchFilter = userStoreProperties.get(LDAPConstants.USER_NAME_SEARCH_FILTER);
    String searchFilter = userSearchFilter.replace("?", escapeSpecialCharactersForFilter(userName));

    NamingEnumeration<?> answer = null;
    NamingEnumeration<?> attrs = null;
    NamingEnumeration<?> allAttrs = null;
    try {
        if (userDN != null) {
            SearchControls searchCtls = new SearchControls();
            searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
            if (propertyNames[0].equals(CommonConstants.WILD_CARD_FILTER)) {
                propertyNames = null;
            }
            searchCtls.setReturningAttributes(propertyNames);

            try {
                answer = dirContext.search(escapeDNForSearch(userDN), searchFilter, searchCtls);
            } catch (PartialResultException e) {
                // can be due to referrals in AD. so just ignore error
                String errorMessage = "Error occurred while searching directory context for user : " + userDN
                        + " searchFilter : " + searchFilter;
                if (isIgnorePartialResultException()) {
                    if (log.isDebugEnabled()) {
                        log.debug(errorMessage, e);
                    }
                } else {
                    throw new UserStoreException(errorMessage, e);
                }
            } catch (NamingException e) {
                String errorMessage = "Error occurred while searching directory context for user : " + userDN
                        + " searchFilter : " + searchFilter;
                if (log.isDebugEnabled()) {
                    log.debug(errorMessage, e);
                }
                throw new UserStoreException(errorMessage, e);
            }
        } else {
            answer = this.searchForUser(searchFilter, propertyNames, dirContext);
        }
        assert answer != null;
        while (answer.hasMoreElements()) {
            SearchResult sr = (SearchResult) answer.next();
            Attributes attributes = sr.getAttributes();
            if (attributes != null) {
                for (allAttrs = attributes.getAll(); allAttrs.hasMore();) {
                    Attribute attribute = (Attribute) allAttrs.next();
                    if (attribute != null) {
                        StringBuilder attrBuffer = new StringBuilder();
                        for (attrs = attribute.getAll(); attrs.hasMore();) {
                            Object attObject = attrs.next();
                            String attr = null;
                            if (attObject instanceof String) {
                                attr = (String) attObject;
                            } else if (attObject instanceof byte[]) {
                                //if the attribute type is binary base64 encoded string will be returned
                                attr = new String(Base64.encodeBase64((byte[]) attObject), "UTF-8");
                            }

                            if (attr != null && attr.trim().length() > 0) {
                                String attrSeparator = userStoreProperties.get(MULTI_ATTRIBUTE_SEPARATOR);
                                if (attrSeparator != null && !attrSeparator.trim().isEmpty()) {
                                    userAttributeSeparator = attrSeparator;
                                }
                                attrBuffer.append(attr).append(userAttributeSeparator);
                            }
                            String value = attrBuffer.toString();

                            /*
                             * Length needs to be more than userAttributeSeparator.length() for a valid
                             * attribute, since we
                             * attach userAttributeSeparator
                             */
                            if (value.trim().length() > userAttributeSeparator.length()) {
                                value = value.substring(0, value.length() - userAttributeSeparator.length());
                                values.put(attribute.getID(), value);
                            }

                        }

                    }
                }
            }
        }

    } catch (NamingException e) {
        String errorMessage = "Error occurred while getting user property values for user : " + userName;
        if (log.isDebugEnabled()) {
            log.debug(errorMessage, e);
        }
        throw new UserStoreException(errorMessage, e);
    } catch (UnsupportedEncodingException e) {
        String errorMessage = "Error occurred while Base64 encoding property values for user : " + userName;
        if (log.isDebugEnabled()) {
            log.debug(errorMessage, e);
        }
        throw new UserStoreException(errorMessage, e);
    } finally {
        // close the naming enumeration and free up resource
        JNDIUtil.closeNamingEnumeration(attrs);
        JNDIUtil.closeNamingEnumeration(answer);
        // close directory context
        JNDIUtil.closeContext(dirContext);
    }
    return values;
}

From source file:de.acosix.alfresco.mtsupport.repo.auth.ldap.EnhancedLDAPUserRegistry.java

protected Collection<String> lookupGroupChildren(final SearchResult searchResult, final String gid,
        final boolean disjoint, final LdapName groupDistinguishedNamePrefix,
        final LdapName userDistinguishedNamePrefix) throws NamingException {
    final InitialDirContext ctx = this.ldapInitialContextFactory.getDefaultIntialDirContext();
    try {/*from  www  . ja va2 s.  c  o m*/
        LOGGER.debug("Processing group: {}, from source: {}", gid, searchResult.getNameInNamespace());

        final Collection<String> children = new HashSet<>();

        final Attributes attributes = searchResult.getAttributes();
        Attribute memAttribute = this.getRangeRestrictedAttribute(attributes, this.memberAttributeName);
        int nextStart = this.attributeBatchSize;

        while (memAttribute != null) {
            for (int i = 0; i < memAttribute.size(); i++) {
                final String attribute = (String) memAttribute.get(i);
                if (attribute != null && attribute.length() > 0) {
                    try {
                        // Attempt to parse the member attribute as a DN. If this fails we have a fallback
                        // in the catch block
                        final LdapName distinguishedNameForComparison = fixedLdapName(
                                attribute.toLowerCase(Locale.ENGLISH));
                        Attribute nameAttribute;

                        // If the user and group search bases are different we may be able to recognize user
                        // and group DNs without a secondary lookup
                        if (disjoint) {
                            final LdapName distinguishedName = fixedLdapName(attribute);
                            final Attributes nameAttributes = distinguishedName
                                    .getRdn(distinguishedName.size() - 1).toAttributes();

                            // Recognize user DNs
                            if (distinguishedNameForComparison.startsWith(userDistinguishedNamePrefix)
                                    && (nameAttribute = nameAttributes.get(this.userIdAttributeName)) != null) {
                                final Collection<String> attributeValues = this.mapAttribute(nameAttribute,
                                        String.class);
                                final String personName = attributeValues.iterator().next();
                                LOGGER.debug("User DN recognized: {}", personName);
                                children.add(personName);
                                continue;
                            }

                            // Recognize group DNs
                            if (distinguishedNameForComparison.startsWith(groupDistinguishedNamePrefix)
                                    && (nameAttribute = nameAttributes
                                            .get(this.groupIdAttributeName)) != null) {
                                final Collection<String> attributeValues = this.mapAttribute(nameAttribute,
                                        String.class);
                                final String groupName = attributeValues.iterator().next();
                                LOGGER.debug("Group DN recognized: {}{}", AuthorityType.GROUP.getPrefixString(),
                                        groupName);
                                children.add(AuthorityType.GROUP.getPrefixString() + groupName);
                                continue;
                            }
                        }

                        // If we can't determine the name and type from the DN alone, try a directory lookup
                        if (distinguishedNameForComparison.startsWith(userDistinguishedNamePrefix)
                                || distinguishedNameForComparison.startsWith(groupDistinguishedNamePrefix)) {
                            try {
                                final Attributes childAttributes = ctx.getAttributes(jndiName(attribute),
                                        new String[] { "objectclass", this.groupIdAttributeName,
                                                this.userIdAttributeName });
                                final Attribute objectClass = childAttributes.get("objectclass");
                                if (this.hasAttributeValue(objectClass, this.personType)) {
                                    nameAttribute = childAttributes.get(this.userIdAttributeName);
                                    if (nameAttribute == null) {
                                        if (this.errorOnMissingUID) {
                                            throw new AlfrescoRuntimeException(
                                                    "User missing user id attribute DN =" + attribute
                                                            + "  att = " + this.userIdAttributeName);
                                        } else {
                                            LOGGER.warn("User missing user id attribute DN =" + attribute
                                                    + "  att = " + this.userIdAttributeName);
                                            continue;
                                        }
                                    }

                                    final Collection<String> attributeValues = this.mapAttribute(nameAttribute,
                                            String.class);
                                    final String personName = attributeValues.iterator().next();

                                    LOGGER.debug("User DN recognized by directory lookup: {}", personName);
                                    children.add(personName);
                                    continue;
                                } else if (this.hasAttributeValue(objectClass, this.groupType)) {
                                    nameAttribute = childAttributes.get(this.groupIdAttributeName);
                                    if (nameAttribute == null) {
                                        if (this.errorOnMissingGID) {
                                            final Object[] params = { searchResult.getNameInNamespace(),
                                                    this.groupIdAttributeName };
                                            throw new AlfrescoRuntimeException(
                                                    "synchronization.err.ldap.get.group.id.missing", params);
                                        } else {
                                            LOGGER.warn("Missing GID on {}", childAttributes);
                                            continue;
                                        }
                                    }

                                    final Collection<String> attributeValues = this.mapAttribute(nameAttribute,
                                            String.class);
                                    final String groupName = attributeValues.iterator().next();
                                    LOGGER.debug("Group DN recognized by directory lookup: {}{}",
                                            AuthorityType.GROUP.getPrefixString(), groupName);
                                    children.add(AuthorityType.GROUP.getPrefixString() + groupName);
                                    continue;
                                }
                            } catch (final NamingException e) {
                                // Unresolvable name
                                if (this.errorOnMissingMembers) {
                                    final Object[] params = { gid, attribute, e.getLocalizedMessage() };
                                    throw new AlfrescoRuntimeException(
                                            "synchronization.err.ldap.group.member.missing.exception", params,
                                            e);
                                }
                                LOGGER.warn(
                                        "Failed to resolve member of group '{}, ' with distinguished name: {}",
                                        gid, attribute, e);
                                continue;
                            }
                        }
                        if (this.errorOnMissingMembers) {
                            final Object[] params = { gid, attribute };
                            throw new AlfrescoRuntimeException("synchronization.err.ldap.group.member.missing",
                                    params);
                        }
                        LOGGER.warn("Failed to resolve member of group '{}' with distinguished name: {}", gid,
                                attribute);
                    } catch (final InvalidNameException e) {
                        // The member attribute didn't parse as a DN. So assume we have a group class like
                        // posixGroup (FDS) that directly lists user names
                        LOGGER.debug("Member DN recognized as posixGroup: {}", attribute);
                        children.add(attribute);
                    }
                }
            }

            // If we are using attribute matching and we haven't got to the end (indicated by an asterisk),
            // fetch the next batch
            if (nextStart > 0
                    && !PATTERN_RANGE_END.matcher(memAttribute.getID().toLowerCase(Locale.ENGLISH)).find()) {
                final Attributes childAttributes = ctx.getAttributes(
                        jndiName(searchResult.getNameInNamespace()), new String[] { this.memberAttributeName
                                + ";range=" + nextStart + '-' + (nextStart + this.attributeBatchSize - 1) });
                memAttribute = this.getRangeRestrictedAttribute(childAttributes, this.memberAttributeName);
                nextStart += this.attributeBatchSize;
            } else {
                memAttribute = null;
            }
        }

        return children;
    } finally {
        this.commonAfterQueryCleanup(null, null, ctx);
    }
}

From source file:org.alfresco.repo.security.sync.ldap.LDAPUserRegistry.java

public Collection<NodeDescription> getGroups(Date modifiedSince) {
    // Work out whether the user and group trees are disjoint. This may allow us to optimize reverse DN
    // resolution.
    final LdapName groupDistinguishedNamePrefix;
    try {// w  w w.j av  a2s  .  c  om
        groupDistinguishedNamePrefix = fixedLdapName(this.groupSearchBase.toLowerCase());
    } catch (InvalidNameException e) {
        Object[] params = { this.groupSearchBase.toLowerCase(), e.getLocalizedMessage() };
        throw new AlfrescoRuntimeException("synchronization.err.ldap.search.base.invalid", params, e);
    }
    final LdapName userDistinguishedNamePrefix;
    try {
        userDistinguishedNamePrefix = fixedLdapName(this.userSearchBase.toLowerCase());
    } catch (InvalidNameException e) {
        Object[] params = { this.userSearchBase.toLowerCase(), e.getLocalizedMessage() };
        throw new AlfrescoRuntimeException("synchronization.err.ldap.search.base.invalid", params, e);
    }

    final boolean disjoint = !groupDistinguishedNamePrefix.startsWith(userDistinguishedNamePrefix)
            && !userDistinguishedNamePrefix.startsWith(groupDistinguishedNamePrefix);

    // Choose / generate the query
    String query;
    if (modifiedSince == null) {
        query = this.groupQuery;
    } else {
        query = MessageFormat.format(this.groupDifferentialQuery, this.timestampFormat.format(modifiedSince));
    }

    // Run the query and process the results
    final Map<String, NodeDescription> lookup = new TreeMap<String, NodeDescription>();
    processQuery(new AbstractSearchCallback() {
        // We get a whole new context to avoid interference with cookies from paged results
        private DirContext ctx = LDAPUserRegistry.this.ldapInitialContextFactory.getDefaultIntialDirContext();

        protected void doProcess(SearchResult result) throws NamingException, ParseException {
            Attributes attributes = result.getAttributes();
            Attribute gidAttribute = attributes.get(LDAPUserRegistry.this.groupIdAttributeName);
            if (gidAttribute == null) {
                if (LDAPUserRegistry.this.errorOnMissingGID) {
                    Object[] params = { result.getNameInNamespace(),
                            LDAPUserRegistry.this.groupIdAttributeName };
                    throw new AlfrescoRuntimeException("synchronization.err.ldap.get.group.id.missing", params);
                } else {
                    LDAPUserRegistry.logger.warn("Missing GID on " + attributes);
                    return;
                }
            }
            String groupShortName = gidAttribute.get(0).toString();
            String gid = "GROUP_" + groupShortName;

            NodeDescription group = lookup.get(gid);
            if (group == null) {
                // Apply the mapped properties to the node description
                group = mapToNode(LDAPUserRegistry.this.groupAttributeMapping,
                        LDAPUserRegistry.this.groupAttributeDefaults, result);

                // Make sure the "GROUP_" prefix is applied
                group.getProperties().put(ContentModel.PROP_AUTHORITY_NAME, gid);
                lookup.put(gid, group);
            } else if (LDAPUserRegistry.this.errorOnDuplicateGID) {
                throw new AlfrescoRuntimeException("Duplicate group id found for " + gid);
            } else {
                LDAPUserRegistry.logger.warn("Duplicate gid found for " + gid + " -> merging definitions");
            }

            Set<String> childAssocs = group.getChildAssociations();

            // Get the repeating (and possibly range restricted) member attribute
            Attribute memAttribute = getRangeRestrictedAttribute(attributes,
                    LDAPUserRegistry.this.memberAttributeName);
            int nextStart = LDAPUserRegistry.this.attributeBatchSize;
            if (LDAPUserRegistry.logger.isDebugEnabled()) {
                LDAPUserRegistry.logger
                        .debug("Processing group: " + gid + ", from source: " + group.getSourceId());
            }
            // Loop until we get to the end of the range
            while (memAttribute != null) {
                for (int i = 0; i < memAttribute.size(); i++) {
                    String attribute = (String) memAttribute.get(i);
                    if (attribute != null && attribute.length() > 0) {
                        try {
                            // Attempt to parse the member attribute as a DN. If this fails we have a fallback
                            // in the catch block
                            LdapName distinguishedNameForComparison = fixedLdapName(attribute.toLowerCase());
                            Attribute nameAttribute;

                            // If the user and group search bases are different we may be able to recognize user
                            // and group DNs without a secondary lookup
                            if (disjoint) {
                                LdapName distinguishedName = fixedLdapName(attribute);
                                Attributes nameAttributes = distinguishedName
                                        .getRdn(distinguishedName.size() - 1).toAttributes();

                                // Recognize user DNs
                                if (distinguishedNameForComparison.startsWith(userDistinguishedNamePrefix)
                                        && (nameAttribute = nameAttributes
                                                .get(LDAPUserRegistry.this.userIdAttributeName)) != null) {
                                    if (LDAPUserRegistry.logger.isDebugEnabled()) {
                                        LDAPUserRegistry.logger
                                                .debug("User DN recognized: " + nameAttribute.get());
                                    }
                                    childAssocs.add((String) nameAttribute.get());
                                    continue;
                                }

                                // Recognize group DNs
                                if (distinguishedNameForComparison.startsWith(groupDistinguishedNamePrefix)
                                        && (nameAttribute = nameAttributes
                                                .get(LDAPUserRegistry.this.groupIdAttributeName)) != null) {
                                    if (LDAPUserRegistry.logger.isDebugEnabled()) {
                                        LDAPUserRegistry.logger.debug(
                                                "Group DN recognized: " + "GROUP_" + nameAttribute.get());
                                    }
                                    childAssocs.add("GROUP_" + nameAttribute.get());
                                    continue;
                                }
                            }

                            // If we can't determine the name and type from the DN alone, try a directory lookup
                            if (distinguishedNameForComparison.startsWith(userDistinguishedNamePrefix)
                                    || distinguishedNameForComparison
                                            .startsWith(groupDistinguishedNamePrefix)) {
                                try {
                                    Attributes childAttributes = this.ctx.getAttributes(jndiName(attribute),
                                            new String[] { "objectclass",
                                                    LDAPUserRegistry.this.groupIdAttributeName,
                                                    LDAPUserRegistry.this.userIdAttributeName });
                                    Attribute objectClass = childAttributes.get("objectclass");
                                    if (hasAttributeValue(objectClass, LDAPUserRegistry.this.personType)) {
                                        nameAttribute = childAttributes
                                                .get(LDAPUserRegistry.this.userIdAttributeName);
                                        if (nameAttribute == null) {
                                            if (LDAPUserRegistry.this.errorOnMissingUID) {
                                                throw new AlfrescoRuntimeException(
                                                        "User missing user id attribute DN =" + attribute
                                                                + "  att = "
                                                                + LDAPUserRegistry.this.userIdAttributeName);
                                            } else {
                                                LDAPUserRegistry.logger
                                                        .warn("User missing user id attribute DN =" + attribute
                                                                + "  att = "
                                                                + LDAPUserRegistry.this.userIdAttributeName);
                                                continue;
                                            }
                                        }
                                        if (LDAPUserRegistry.logger.isDebugEnabled()) {
                                            LDAPUserRegistry.logger
                                                    .debug("User DN recognized by directory lookup: "
                                                            + nameAttribute.get());
                                        }
                                        childAssocs.add((String) nameAttribute.get());
                                        continue;
                                    } else if (hasAttributeValue(objectClass,
                                            LDAPUserRegistry.this.groupType)) {
                                        nameAttribute = childAttributes
                                                .get(LDAPUserRegistry.this.groupIdAttributeName);
                                        if (nameAttribute == null) {
                                            if (LDAPUserRegistry.this.errorOnMissingGID) {
                                                Object[] params = { result.getNameInNamespace(),
                                                        LDAPUserRegistry.this.groupIdAttributeName };
                                                throw new AlfrescoRuntimeException(
                                                        "synchronization.err.ldap.get.group.id.missing",
                                                        params);
                                            } else {
                                                LDAPUserRegistry.logger
                                                        .warn("Missing GID on " + childAttributes);
                                                continue;
                                            }
                                        }
                                        if (LDAPUserRegistry.logger.isDebugEnabled()) {
                                            LDAPUserRegistry.logger
                                                    .debug("Group DN recognized by directory lookup: "
                                                            + "GROUP_" + nameAttribute.get());
                                        }
                                        childAssocs.add("GROUP_" + nameAttribute.get());
                                        continue;
                                    }
                                } catch (NamingException e) {
                                    // Unresolvable name
                                    if (LDAPUserRegistry.this.errorOnMissingMembers) {
                                        Object[] params = { groupShortName, attribute,
                                                e.getLocalizedMessage() };
                                        throw new AlfrescoRuntimeException(
                                                "synchronization.err.ldap.group.member.missing.exception",
                                                params, e);
                                    }
                                    LDAPUserRegistry.logger.warn("Failed to resolve member of group '"
                                            + groupShortName + "' with distinguished name: " + attribute, e);
                                    continue;
                                }
                            }
                            if (LDAPUserRegistry.this.errorOnMissingMembers) {
                                Object[] params = { groupShortName, attribute };
                                throw new AlfrescoRuntimeException(
                                        "synchronization.err.ldap.group.member.missing", params);
                            }
                            LDAPUserRegistry.logger.warn("Failed to resolve member of group '" + groupShortName
                                    + "' with distinguished name: " + attribute);
                        } catch (InvalidNameException e) {
                            // The member attribute didn't parse as a DN. So assume we have a group class like
                            // posixGroup (FDS) that directly lists user names
                            if (LDAPUserRegistry.logger.isDebugEnabled()) {
                                LDAPUserRegistry.logger
                                        .debug("Member DN recognized as posixGroup: " + attribute);
                            }
                            childAssocs.add(attribute);
                        }
                    }
                }

                // If we are using attribute matching and we haven't got to the end (indicated by an asterisk),
                // fetch the next batch
                if (nextStart > 0 && !LDAPUserRegistry.PATTERN_RANGE_END
                        .matcher(memAttribute.getID().toLowerCase()).find()) {
                    Attributes childAttributes = this.ctx.getAttributes(jndiName(result.getNameInNamespace()),
                            new String[] { LDAPUserRegistry.this.memberAttributeName + ";range=" + nextStart
                                    + '-' + (nextStart + LDAPUserRegistry.this.attributeBatchSize - 1) });
                    memAttribute = getRangeRestrictedAttribute(childAttributes,
                            LDAPUserRegistry.this.memberAttributeName);
                    nextStart += LDAPUserRegistry.this.attributeBatchSize;
                } else {
                    memAttribute = null;
                }
            }
        }

        public void close() throws NamingException {
            this.ctx.close();
        }
    }, this.groupSearchBase, query, this.groupKeys.getFirst());

    if (LDAPUserRegistry.logger.isDebugEnabled()) {
        LDAPUserRegistry.logger.debug("Found " + lookup.size());
    }

    return lookup.values();
}