From bc11734a34d63204bfcc6e9087e0664a9772fae3 Mon Sep 17 00:00:00 2001
From: Ludovic Poitou <ludovic.poitou@forgerock.com>
Date: Tue, 07 Oct 2014 21:25:21 +0000
Subject: [PATCH] Port to the DJ3 dev branch the fix for OPENDJ-1586 - Nested Groups fail to return indirect members with db's larger than 10 entries.
---
opendj3-server-dev/src/server/org/opends/server/extensions/IsMemberOfVirtualAttributeProvider.java | 82 ++++++++++++++++++++++++++++++++--------
opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/extensions/IsMemberOfVirtualAttributeProviderTestCase.java | 16 ++++---
2 files changed, 74 insertions(+), 24 deletions(-)
diff --git a/opendj3-server-dev/src/server/org/opends/server/extensions/IsMemberOfVirtualAttributeProvider.java b/opendj3-server-dev/src/server/org/opends/server/extensions/IsMemberOfVirtualAttributeProvider.java
index bb2870c..e69a4ad 100644
--- a/opendj3-server-dev/src/server/org/opends/server/extensions/IsMemberOfVirtualAttributeProvider.java
+++ b/opendj3-server-dev/src/server/org/opends/server/extensions/IsMemberOfVirtualAttributeProvider.java
@@ -26,7 +26,9 @@
*/
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;
@@ -248,32 +250,32 @@
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();
- while (memberList.hasMoreMembers())
+ // 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())
{
- try
+ 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))
{
- Entry e = memberList.nextMemberEntry();
- if (e.matchesBaseAndScope(baseDN, scope) &&
- filter.matchesEntry(e))
- {
- searchOperation.returnEntry(e, null);
- }
- }
- catch (Exception e)
- {
- logger.traceException(e);
+ return;
}
}
}
@@ -283,6 +285,52 @@
}
}
+ /**
+ *
+ * @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
+ {
+ Entry e = memberList.nextMemberEntry();
+ if (e.matchesBaseAndScope(baseDN, scope) &&
+ filter.matchesEntry(e))
+ {
+ if (returnedDNs == null
+ || returnedDNs.add(e.getName().toNormalizedString()))
+ {
+ if (!searchOperation.returnEntry(e, null))
+ {
+ return false;
+ }
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ logger.traceException(e);
+ }
+ }
+ return true;
+ }
+
/**
diff --git a/opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/extensions/IsMemberOfVirtualAttributeProviderTestCase.java b/opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/extensions/IsMemberOfVirtualAttributeProviderTestCase.java
index 011c23d..4d3afb7 100644
--- a/opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/extensions/IsMemberOfVirtualAttributeProviderTestCase.java
+++ b/opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/extensions/IsMemberOfVirtualAttributeProviderTestCase.java
@@ -942,28 +942,30 @@
builder.append("\nobjectClass: domain");
builder.append("\ndc: example");
- builder.append("\n\ndn: ou=People"+SUFFIX);
+ builder.append("\n\ndn: ou=People").append(SUFFIX);
builder.append("\nobjectClass: organizationalunit");
builder.append("\nou: People");
//Go beyond ALL ID threshold.
for(int i=0;i<4001;i++)
{
- builder.append("\n\ndn: cn=user." + i + ",ou=People"+SUFFIX);
+ builder.append("\n\ndn: cn=user.").append(i)
+ .append(",ou=People").append(SUFFIX);
builder.append("\nobjectclass: person");
- builder.append("\ncn: user." + i);
- builder.append("\nsn: " + i);
+ builder.append("\ncn: user.").append(i);
+ builder.append("\nsn: ").append(i);
}
//Add the group information.
- builder.append("\n\ndn: ou=Groups"+SUFFIX);
+ builder.append("\n\ndn: ou=Groups").append(SUFFIX);
builder.append("\nobjectclass: organizationalunit");
builder.append("\nou: Groups");
//Dynamic group.
- builder.append("\n\ndn: cn=MyDGrp,ou=Groups"+SUFFIX);
+ builder.append("\n\ndn: cn=MyDGrp,ou=Groups").append(SUFFIX);
builder.append("\nobjectClass: groupOfURLs");
builder.append("\ncn: MyDGrp");
- builder.append("\nmemberURL: ldap:///ou=people"+SUFFIX+"??sub?(objectclass=person)");
+ builder.append("\nmemberURL: ldap:///ou=people").append(SUFFIX)
+ .append("??sub?(objectclass=person)");
TestCaseUtils.addEntries(builder.toString());
//Verify the entry.
Entry e =
--
Gitblit v1.10.0