From e715b881c02b3c8509be8afceb583143e1fc5583 Mon Sep 17 00:00:00 2001
From: Ludovic Poitou <ludovic.poitou@forgerock.com>
Date: Tue, 07 Oct 2014 19:48:39 +0000
Subject: [PATCH] Fix for OPENDJ-1586: Changes in processSearch to iterate through nested groups members when a search is based on a filter of the isMemberOf attribute.

---
 opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/IsMemberOfVirtualAttributeProviderTestCase.java |   18 +++++----
 opends/src/server/org/opends/server/extensions/IsMemberOfVirtualAttributeProvider.java                                 |   68 +++++++++++++++++++++++----------
 2 files changed, 57 insertions(+), 29 deletions(-)

diff --git a/opends/src/server/org/opends/server/extensions/IsMemberOfVirtualAttributeProvider.java b/opends/src/server/org/opends/server/extensions/IsMemberOfVirtualAttributeProvider.java
index 346bf69..20ea755 100644
--- a/opends/src/server/org/opends/server/extensions/IsMemberOfVirtualAttributeProvider.java
+++ b/opends/src/server/org/opends/server/extensions/IsMemberOfVirtualAttributeProvider.java
@@ -22,7 +22,7 @@
  *
  *
  *      Copyright 2008-2009 Sun Microsystems, Inc.
- *      Portions copyright 2011-2013 ForgeRock AS
+ *      Portions copyright 2011-2014 ForgeRock AS
  */
 package org.opends.server.extensions;
 
@@ -303,29 +303,21 @@
       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
-        {
-          Entry e = memberList.nextMemberEntry();
-          if (e.matchesBaseAndScope(baseDN, scope) &&
-              filter.matchesEntry(e))
-          {
-            searchOperation.returnEntry(e, null);
-          }
-        }
-        catch (Exception e)
-        {
-          if (debugEnabled())
-          {
-            TRACER.debugCaught(DebugLogLevel.ERROR, e);
-          }
-        }
+        returnedDNs = new HashSet<String>();
+      }
+      returnGroupMembers(searchOperation, filter, group.getMembers(), returnedDNs);
+      // Now check members of nested groups
+      for (DN dn : nestedGroupsDNs)
+      {
+        group = DirectoryServer.getGroupManager().getGroupInstance(dn);
+        returnGroupMembers(searchOperation, filter, group.getMembers(), returnedDNs);
       }
     }
     catch (DirectoryException de)
@@ -334,6 +326,40 @@
     }
   }
 
+  private void returnGroupMembers(SearchOperation searchOperation, SearchFilter filter,
+                                  MemberList memberList, Set<String> returnedDNs)
+          throws DirectoryException
+  {
+    DN baseDN = searchOperation.getBaseDN();
+    SearchScope scope  = searchOperation.getScope();
+    while (memberList.hasMoreMembers())
+    {
+      try
+      {
+        Entry e = memberList.nextMemberEntry();
+        if (e.matchesBaseAndScope(baseDN, scope) &&
+            filter.matchesEntry(e))
+        {
+          if (returnedDNs == null
+              || returnedDNs.add(e.getDN().toNormalizedString()))
+          {
+            if (!searchOperation.returnEntry(e, null))
+            {
+              return;
+            }
+          }
+        }
+      }
+      catch (Exception e)
+      {
+        if (debugEnabled())
+        {
+          TRACER.debugCaught(DebugLogLevel.ERROR, e);
+        }
+      }
+    }
+  }
+
 
 
   /**
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/IsMemberOfVirtualAttributeProviderTestCase.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/IsMemberOfVirtualAttributeProviderTestCase.java
index 9d482b8..cc5f8e9 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/IsMemberOfVirtualAttributeProviderTestCase.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/IsMemberOfVirtualAttributeProviderTestCase.java
@@ -22,7 +22,7 @@
  *
  *
  *      Copyright 2008-2009 Sun Microsystems, Inc.
- *      Portions Copyright 2011-2012 ForgeRock AS
+ *      Portions Copyright 2011-2014 ForgeRock AS
  */
 package org.opends.server.extensions;
 
@@ -1309,28 +1309,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