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/src/server/org/opends/server/extensions/IsMemberOfVirtualAttributeProvider.java |   68 +++++++++++++++++++++++----------
 1 files changed, 47 insertions(+), 21 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);
+        }
+      }
+    }
+  }
+
 
 
   /**

--
Gitblit v1.10.0