From 2932826ed4d0c00eea2ceff19d65476593919821 Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Wed, 29 Jun 2011 17:49:33 +0000
Subject: [PATCH] Fix OPENDJ-216: Missing entries in searches when legacy (objectclass=ldapSubEntry) filter is used in Search filter.
---
opends/src/server/org/opends/server/core/SearchOperationBasis.java | 78 ++++++++++++++++++--------------------
1 files changed, 37 insertions(+), 41 deletions(-)
diff --git a/opends/src/server/org/opends/server/core/SearchOperationBasis.java b/opends/src/server/org/opends/server/core/SearchOperationBasis.java
index ace7465..c266177 100644
--- a/opends/src/server/org/opends/server/core/SearchOperationBasis.java
+++ b/opends/src/server/org/opends/server/core/SearchOperationBasis.java
@@ -89,8 +89,12 @@
// Indicates whether to only real attributes should be returned.
private boolean realAttributesOnly;
- // Indicates whether LDAP subentries should be returned.
- private boolean returnLDAPSubentries;
+ // Indicates whether only LDAP subentries should be returned.
+ private boolean returnSubentriesOnly;
+
+ // Indicates whether the filter references subentry or ldapSubentry object
+ // class.
+ private boolean filterIncludesSubentries;
// Indicates whether to include attribute types only or both types and values.
private boolean typesOnly;
@@ -246,7 +250,7 @@
clientAcceptsReferrals = true;
includeUsableControl = false;
responseSent = new AtomicBoolean(false);
- returnLDAPSubentries = false;
+ returnSubentriesOnly = false;
matchedValuesControl = null;
realAttributesOnly = false;
virtualAttributesOnly = false;
@@ -346,7 +350,7 @@
clientAcceptsReferrals = true;
includeUsableControl = false;
responseSent = new AtomicBoolean(false);
- returnLDAPSubentries = false;
+ returnSubentriesOnly = false;
matchedValuesControl = null;
}
@@ -517,6 +521,7 @@
if (filter == null)
{
filter = rawFilter.toSearchFilter();
+ filterIncludesSubentries = checkFilterForLDAPSubEntry(filter, 0);
}
}
catch (DirectoryException de)
@@ -612,27 +617,16 @@
// should be returned.
if (entry.isSubentry() || entry.isLDAPSubentry())
{
- if ((getScope() != SearchScope.BASE_OBJECT) &&
- (! isReturnLDAPSubentries()))
+ if ((getScope() != SearchScope.BASE_OBJECT)
+ && !filterIncludesSubentries
+ && !isReturnSubentriesOnly())
{
- // Check to see if the filter contains an equality element with the
- // objectclass attribute type and a value of "ldapSubentry". If so,
- // then we'll return it anyway. Technically, this isn't part of the
- // specification so we don't need to get carried away with really in
- // depth checks. Just do best effort for earlier draft compatibility.
- checkFilterForLDAPSubEntry(getFilter(), 0);
-
- if (! isReturnLDAPSubentries())
- {
- // We still shouldn't return it even based on the filter.
- // Just throw it away without doing anything.
- return true;
- }
+ return true;
}
}
else
{
- if (isReturnLDAPSubentries())
+ if (isReturnSubentriesOnly())
{
// Subentries are visible and normal entries are not.
return true;
@@ -1148,17 +1142,17 @@
/**
* {@inheritDoc}
*/
- public boolean isReturnLDAPSubentries()
+ public boolean isReturnSubentriesOnly()
{
- return returnLDAPSubentries;
+ return returnSubentriesOnly;
}
/**
* {@inheritDoc}
*/
- public void setReturnLDAPSubentries(boolean returnLDAPSubentries)
+ public void setReturnSubentriesOnly(boolean returnLDAPSubentries)
{
- this.returnLDAPSubentries = returnLDAPSubentries;
+ this.returnSubentriesOnly = returnLDAPSubentries;
}
/**
@@ -1464,19 +1458,22 @@
}
+
/**
- * Checks if the filter contains an equality element with the
- * objectclass attribute type and a value of "ldapSubentry"
- * and if so sets returnLDAPSubentries to <code>true</code>.
+ * Checks if the filter contains an equality element with the objectclass
+ * attribute type and a value of "ldapSubentry" and if so sets
+ * returnSubentriesOnly to <code>true</code>.
*
- * @param filter The complete filter being checked, of which
- * this filter may be a subset.
- * @param depth The current depth of the evaluation, which
- * is used to prevent infinite recursion due
- * to highly nested filters and eventually
- * running out of stack space.
+ * @param filter
+ * The complete filter being checked, of which this filter may be a
+ * subset.
+ * @param depth
+ * The current depth of the evaluation, which is used to prevent
+ * infinite recursion due to highly nested filters and eventually
+ * running out of stack space.
+ * @return {@code true} if the filter references the sub-entry object class.
*/
- private void checkFilterForLDAPSubEntry(SearchFilter filter, int depth)
+ private boolean checkFilterForLDAPSubEntry(SearchFilter filter, int depth)
{
// Paranoid check to avoid recursion deep enough to provoke
// the stack overflow. This should never happen because if
@@ -1488,7 +1485,7 @@
{
TRACER.debugError("Exceeded maximum filter depth");
}
- return;
+ return false;
}
switch (filter.getFilterType())
@@ -1503,7 +1500,7 @@
if (stringValueLC.equals(OC_LDAP_SUBENTRY_LC) ||
stringValueLC.equals(OC_SUBENTRY))
{
- setReturnLDAPSubentries(true);
+ return true;
}
}
break;
@@ -1511,15 +1508,14 @@
case OR:
for (SearchFilter f : filter.getFilterComponents())
{
- checkFilterForLDAPSubEntry(f, depth + 1);
-
- if (isReturnLDAPSubentries())
+ if (checkFilterForLDAPSubEntry(f, depth + 1))
{
- // No point in continuing.
- break;
+ return true;
}
}
break;
}
+
+ return false;
}
}
--
Gitblit v1.10.0