| | |
| | | // 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; |
| | |
| | | clientAcceptsReferrals = true; |
| | | includeUsableControl = false; |
| | | responseSent = new AtomicBoolean(false); |
| | | returnLDAPSubentries = false; |
| | | returnSubentriesOnly = false; |
| | | matchedValuesControl = null; |
| | | realAttributesOnly = false; |
| | | virtualAttributesOnly = false; |
| | |
| | | clientAcceptsReferrals = true; |
| | | includeUsableControl = false; |
| | | responseSent = new AtomicBoolean(false); |
| | | returnLDAPSubentries = false; |
| | | returnSubentriesOnly = false; |
| | | matchedValuesControl = null; |
| | | } |
| | | |
| | |
| | | if (filter == null) |
| | | { |
| | | filter = rawFilter.toSearchFilter(); |
| | | filterIncludesSubentries = checkFilterForLDAPSubEntry(filter, 0); |
| | | } |
| | | } |
| | | catch (DirectoryException de) |
| | |
| | | // 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; |
| | |
| | | /** |
| | | * {@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; |
| | | } |
| | | |
| | | /** |
| | |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 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 |
| | |
| | | { |
| | | TRACER.debugError("Exceeded maximum filter depth"); |
| | | } |
| | | return; |
| | | return false; |
| | | } |
| | | |
| | | switch (filter.getFilterType()) |
| | |
| | | if (stringValueLC.equals(OC_LDAP_SUBENTRY_LC) || |
| | | stringValueLC.equals(OC_SUBENTRY)) |
| | | { |
| | | setReturnLDAPSubentries(true); |
| | | return true; |
| | | } |
| | | } |
| | | break; |
| | |
| | | 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; |
| | | } |
| | | } |