| | |
| | | */ |
| | | package org.opends.server.extensions; |
| | | |
| | | import java.util.HashSet; |
| | | import java.util.List; |
| | | import java.util.Set; |
| | | |
| | | import org.forgerock.i18n.slf4j.LocalizedLogger; |
| | | import org.forgerock.opendj.ldap.ByteString; |
| | |
| | | public void processSearch(VirtualAttributeRule rule, |
| | | SearchOperation searchOperation) |
| | | { |
| | | SearchFilter filter = searchOperation.getFilter(); |
| | | Group<?> group = extractGroup(rule.getAttributeType(), filter); |
| | | Group<?> group = extractGroup(rule.getAttributeType(), searchOperation.getFilter()); |
| | | if (group == null) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | DN baseDN = searchOperation.getBaseDN(); |
| | | SearchScope scope = searchOperation.getScope(); |
| | | try |
| | | { |
| | | MemberList memberList = group.getMembers(); |
| | | // Check for nested groups to see if we need to keep track of returned entries |
| | | List<DN> nestedGroupsDNs = group.getNestedGroupDNs(); |
| | | HashSet<String> returnedDNs = null; |
| | | if (!nestedGroupsDNs.isEmpty()) |
| | | { |
| | | returnedDNs = new HashSet<String>(); |
| | | } |
| | | if (!returnGroupMembers(searchOperation, group.getMembers(), returnedDNs)) |
| | | { |
| | | return; |
| | | } |
| | | // Now check members of nested groups |
| | | for (DN dn : nestedGroupsDNs) |
| | | { |
| | | group = DirectoryServer.getGroupManager().getGroupInstance(dn); |
| | | if (!returnGroupMembers(searchOperation, group.getMembers(), returnedDNs)) |
| | | { |
| | | return; |
| | | } |
| | | } |
| | | } |
| | | catch (DirectoryException de) |
| | | { |
| | | searchOperation.setResponseData(de); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * |
| | | * @param searchOperation the search operation being processed. |
| | | * @param memberList the list of members of the group being processed. |
| | | * @param returnedDNs a set to store the DNs of entries already returned, |
| | | * null if there's no need to track for entries. |
| | | * @return <CODE>true</CODE> if the caller should continue processing the |
| | | * search request and sending additional entries and references, or |
| | | * <CODE>false</CODE> if not for some reason (e.g., the size limit |
| | | * has been reached or the search has been abandoned). |
| | | * @throws DirectoryException If a problem occurs while attempting to send |
| | | * the entry to the client and the search should be terminated. |
| | | */ |
| | | private boolean returnGroupMembers(SearchOperation searchOperation, |
| | | MemberList memberList, Set<String> returnedDNs) |
| | | throws DirectoryException |
| | | { |
| | | DN baseDN = searchOperation.getBaseDN(); |
| | | SearchScope scope = searchOperation.getScope(); |
| | | SearchFilter filter = searchOperation.getFilter(); |
| | | while (memberList.hasMoreMembers()) |
| | | { |
| | | try |
| | |
| | | if (e.matchesBaseAndScope(baseDN, scope) && |
| | | filter.matchesEntry(e)) |
| | | { |
| | | searchOperation.returnEntry(e, null); |
| | | if (returnedDNs == null |
| | | || returnedDNs.add(e.getName().toNormalizedString())) |
| | | { |
| | | if (!searchOperation.returnEntry(e, null)) |
| | | { |
| | | return false; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | catch (Exception e) |
| | |
| | | logger.traceException(e); |
| | | } |
| | | } |
| | | } |
| | | catch (DirectoryException de) |
| | | { |
| | | searchOperation.setResponseData(de); |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | |