mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

Ludovic Poitou
07.48.2014 e715b881c02b3c8509be8afceb583143e1fc5583
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.
2 files modified
86 ■■■■■ changed files
opends/src/server/org/opends/server/extensions/IsMemberOfVirtualAttributeProvider.java 68 ●●●●● patch | view | raw | blame | history
opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/IsMemberOfVirtualAttributeProviderTestCase.java 18 ●●●●● patch | view | raw | blame | history
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);
        }
      }
    }
  }
  /**
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 =