From 2d9c97d306084b1e3d4daf140508a09b26ebb1c8 Mon Sep 17 00:00:00 2001
From: abobrov <abobrov@localhost>
Date: Tue, 20 Oct 2009 15:57:03 +0000
Subject: [PATCH] - RFC 3672 Subentries Control implementation : make earlier drafts based implementation obsolete; keep ldapSubEntry OC search matching criteria for backward compatibility.
---
opendj-sdk/opends/src/server/org/opends/server/workflowelement/ndb/NDBSearchOperation.java | 5
opendj-sdk/opends/src/server/org/opends/server/tools/LDAPSearch.java | 14 ++
opendj-sdk/opends/src/server/org/opends/server/tools/LDAPToolUtils.java | 6 -
opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendSearchOperation.java | 5
opendj-sdk/opends/src/messages/messages/tools.properties | 2
opendj-sdk/opends/src/server/org/opends/server/controls/SubentriesControl.java | 164 ++++++++++++++++++++++++++++++++
opendj-sdk/opends/src/server/org/opends/server/tools/ToolConstants.java | 10 ++
opendj-sdk/opends/src/messages/messages/protocol.properties | 5 +
opendj-sdk/opends/src/server/org/opends/server/core/SearchOperationBasis.java | 37 ++++--
opendj-sdk/opends/src/server/org/opends/server/util/ServerConstants.java | 2
opendj-sdk/opends/src/server/org/opends/server/workflowelement/externalchangelog/ECLSearchOperation.java | 5
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/tools/LDAPSearchTestCase.java | 11 +-
12 files changed, 237 insertions(+), 29 deletions(-)
diff --git a/opendj-sdk/opends/src/messages/messages/protocol.properties b/opendj-sdk/opends/src/messages/messages/protocol.properties
index c3dc95d..28363e7 100644
--- a/opendj-sdk/opends/src/messages/messages/protocol.properties
+++ b/opendj-sdk/opends/src/messages/messages/protocol.properties
@@ -1364,6 +1364,11 @@
SEVERE_ERR_LDIF_CONNHANDLER_CANNOT_DELETE_456=An error occurred while the \
LDIF connection handler was attempting to delete processed file %s: %s
SEVERE_ERR_CONNHANDLER_ADDRESS_INUSE_457=Address already in use
+MILD_ERR_SUBENTRIES_NO_CONTROL_VALUE_458=Cannot decode the provided \
+ subentries control because it does not have a value
+MILD_ERR_SUBENTRIES_CANNOT_DECODE_VALUE_459=Cannot decode the provided \
+ subentries control because an error occurred while attempting \
+ to decode the control value: %s
INFO_SNMP_CONNHANDLER_DESCRIPTION_LISTEN_PORT_1458=SNMP port on \
which this connection handler accepts SNMP requests. Changes \
to this configuration attribute will not take effect until the connection \
diff --git a/opendj-sdk/opends/src/messages/messages/tools.properties b/opendj-sdk/opends/src/messages/messages/tools.properties
index 5406a92..88029ec 100644
--- a/opendj-sdk/opends/src/messages/messages/tools.properties
+++ b/opendj-sdk/opends/src/messages/messages/tools.properties
@@ -2534,3 +2534,5 @@
for index scratch files during index rebuilding
SEVERE_ERR_REBUILDINDEX_REBUILD_ALL_ERROR_1699=Index "-i" option cannot be \
specified with the "--rebuildAll" option
+INFO_DESCRIPTION_SUBENTRIES_1700=Use subentries control to specify that \
+ subentries are visible and normal entries are not
diff --git a/opendj-sdk/opends/src/server/org/opends/server/controls/SubentriesControl.java b/opendj-sdk/opends/src/server/org/opends/server/controls/SubentriesControl.java
new file mode 100644
index 0000000..7297330
--- /dev/null
+++ b/opendj-sdk/opends/src/server/org/opends/server/controls/SubentriesControl.java
@@ -0,0 +1,164 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ * Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ * Copyright 2009 Sun Microsystems, Inc.
+ */
+package org.opends.server.controls;
+import org.opends.messages.Message;
+
+import java.io.IOException;
+
+import org.opends.server.protocols.asn1.*;
+import org.opends.server.loggers.debug.DebugTracer;
+import org.opends.server.types.*;
+
+import static org.opends.messages.ProtocolMessages.*;
+import static org.opends.server.protocols.asn1.ASN1Constants.
+ UNIVERSAL_OCTET_STRING_TYPE;
+import static org.opends.server.loggers.debug.DebugLogger.*;
+import static org.opends.server.util.ServerConstants.*;
+import static org.opends.server.util.StaticUtils.*;
+
+/**
+ * This class implements Subentries Control as defined in RFC 3672. It makes
+ * it possible to control the visibility of entries and subentries which are
+ * within scope of specific operation.
+ */
+public class SubentriesControl
+ extends Control
+{
+ /**
+ * ControlDecoder implentation to decode this control from a ByteString.
+ */
+ private static final class Decoder
+ implements ControlDecoder<SubentriesControl>
+ {
+ /**
+ * {@inheritDoc}
+ */
+ public SubentriesControl decode(boolean isCritical, ByteString value)
+ throws DirectoryException
+ {
+ if (value == null)
+ {
+ Message message = ERR_SUBENTRIES_NO_CONTROL_VALUE.get();
+ throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message);
+ }
+
+ ASN1Reader reader = ASN1.getReader(value);
+ boolean visibility;
+ try
+ {
+ visibility = reader.readBoolean();
+ }
+ catch (Exception e)
+ {
+ if (debugEnabled())
+ {
+ TRACER.debugCaught(DebugLogLevel.ERROR, e);
+ }
+
+ Message message =
+ ERR_SUBENTRIES_CANNOT_DECODE_VALUE.get(getExceptionMessage(e));
+ throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message, e);
+ }
+
+ return new SubentriesControl(isCritical, visibility);
+ }
+
+ public String getOID()
+ {
+ return OID_LDAP_SUBENTRIES;
+ }
+
+ }
+
+ /**
+ * The Control Decoder that can be used to decode this control.
+ */
+ public static final ControlDecoder<SubentriesControl> DECODER =
+ new Decoder();
+
+ /**
+ * The tracer object for the debug logger.
+ */
+ private static final DebugTracer TRACER = getTracer();
+
+ // The visibility from the control value.
+ private boolean visibility = false;
+
+ /**
+ * Creates a new instance of the Subentries Control with the provided
+ * information.
+ *
+ * @param isCritical Indicates whether support for this control
+ * should be considered a critical part of the
+ * server processing.
+ * @param visibility The visibility flag from the control value.
+ */
+ public SubentriesControl(boolean isCritical, boolean visibility)
+ {
+ super(OID_LDAP_SUBENTRIES, isCritical);
+ this.visibility = visibility;
+ }
+
+ /**
+ * Writes this control's value to an ASN.1 writer. The value must be
+ * written as an ASN1OctetString.
+ *
+ * @param writer The ASN.1 writer to use.
+ * @throws IOException If a problem occurs while writing to the stream.
+ */
+ @Override
+ protected void writeValue(ASN1Writer writer) throws IOException
+ {
+ writer.writeStartSequence(UNIVERSAL_OCTET_STRING_TYPE);
+ writer.writeBoolean(visibility);
+ writer.writeEndSequence();
+ }
+
+ /**
+ * Retrieves the visibility for this Subentries Control.
+ *
+ * @return The visibility for this Subentries Control.
+ */
+ public boolean getVisibility()
+ {
+ return visibility;
+ }
+
+ /**
+ * Appends a string representation of this Subentries Control to the
+ * provided buffer.
+ *
+ * @param buffer The buffer to which the information should be appended.
+ */
+ @Override
+ public void toString(StringBuilder buffer)
+ {
+ buffer.append("SubentriesControl(visibility=\"");
+ buffer.append(Boolean.toString(visibility));
+ buffer.append("\")");
+ }
+}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/core/SearchOperationBasis.java b/opendj-sdk/opends/src/server/org/opends/server/core/SearchOperationBasis.java
index 13c5257..5a8d35f 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/core/SearchOperationBasis.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/core/SearchOperationBasis.java
@@ -609,26 +609,35 @@
// Determine whether the provided entry is a subentry and if so whether it
// should be returned.
- if ((getScope() != SearchScope.BASE_OBJECT) &&
- (! isReturnLDAPSubentries()) &&
- entry.isLDAPSubentry())
+ if (entry.isLDAPSubentry())
{
- // 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.
- checkFilterForLDAPSubEntry(getFilter(), 0);
-
- if (! isReturnLDAPSubentries())
+ if ((getScope() != SearchScope.BASE_OBJECT) &&
+ (! isReturnLDAPSubentries()))
{
- // We still shouldn't return it even based on the filter. Just throw it
- // away without doing anything.
+ // 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;
+ }
+ }
+ }
+ else
+ {
+ if (isReturnLDAPSubentries())
+ {
+ // Subentries are visible and normal entries are not.
return true;
}
}
-
// Determine whether to include the account usable control. If so, then
// create it now.
if (isIncludeUsableControl())
diff --git a/opendj-sdk/opends/src/server/org/opends/server/tools/LDAPSearch.java b/opendj-sdk/opends/src/server/org/opends/server/tools/LDAPSearch.java
index 9a79ba3..13b131a 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/tools/LDAPSearch.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/tools/LDAPSearch.java
@@ -712,6 +712,7 @@
StringArgument effectiveRightsAttrs = null;
StringArgument propertiesFileArgument = null;
BooleanArgument noPropertiesFileArgument = null;
+ BooleanArgument subEntriesArgument = null;
// Create the command-line argument parser for use with this program.
@@ -984,6 +985,12 @@
controlStr.setPropertyName("control");
argParser.addArgument(controlStr);
+ subEntriesArgument = new BooleanArgument("subEntries",
+ OPTION_SHORT_SUBENTRIES, OPTION_LONG_SUBENTRIES,
+ INFO_DESCRIPTION_SUBENTRIES.get());
+ useSSL.setPropertyName(OPTION_LONG_SUBENTRIES);
+ argParser.addArgument(subEntriesArgument);
+
effectiveRightsUser =
new StringArgument("effectiveRightsUser",
OPTION_SHORT_EFFECTIVERIGHTSUSER,
@@ -1599,6 +1606,13 @@
}
}
+ if (subEntriesArgument.isPresent())
+ {
+ Control subentriesControl =
+ new SubentriesControl(true, true);
+ searchOptions.getControls().add(subentriesControl);
+ }
+
// Set the connection options.
connectionOptions.setSASLExternal(saslExternal.isPresent());
if(saslOptions.isPresent())
diff --git a/opendj-sdk/opends/src/server/org/opends/server/tools/LDAPToolUtils.java b/opendj-sdk/opends/src/server/org/opends/server/tools/LDAPToolUtils.java
index 519b4c3..5cdcf93 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/tools/LDAPToolUtils.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/tools/LDAPToolUtils.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Copyright 2006-2008 Sun Microsystems, Inc.
+ * Copyright 2006-2009 Sun Microsystems, Inc.
*/
package org.opends.server.tools;
import org.opends.messages.Message;
@@ -95,10 +95,6 @@
{
controlOID = OID_LDAP_NOOP_OPENLDAP_ASSIGNED;
}
- else if (lowerOID.equals("subentries"))
- {
- controlOID = OID_LDAP_SUBENTRIES;
- }
else if (lowerOID.equals("managedsait"))
{
controlOID = OID_MANAGE_DSAIT_CONTROL;
diff --git a/opendj-sdk/opends/src/server/org/opends/server/tools/ToolConstants.java b/opendj-sdk/opends/src/server/org/opends/server/tools/ToolConstants.java
index 684598e..10323cd 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/tools/ToolConstants.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/tools/ToolConstants.java
@@ -597,6 +597,16 @@
public static final Character OPTION_SHORT_RECURRING_TASK = null;
/**
+ * Subentries control option long form.
+ */
+ public static final String OPTION_LONG_SUBENTRIES = "subEntries";
+
+ /**
+ * Subentries control option short form.
+ */
+ public static final Character OPTION_SHORT_SUBENTRIES = null;
+
+ /**
* The value for the long option propertiesFilePAth .
*/
public static final String OPTION_LONG_PROP_FILE_PATH = "propertiesFilePath";
diff --git a/opendj-sdk/opends/src/server/org/opends/server/util/ServerConstants.java b/opendj-sdk/opends/src/server/org/opends/server/util/ServerConstants.java
index 045ec23..b80e4c1 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/util/ServerConstants.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/util/ServerConstants.java
@@ -2065,7 +2065,7 @@
* The OID for the LDAP subentries control used to indicate that matching
* subentries should be returned.
*/
- public static final String OID_LDAP_SUBENTRIES = "1.3.6.1.4.1.7628.5.101.1";
+ public static final String OID_LDAP_SUBENTRIES = "1.3.6.1.4.1.4203.1.10.1";
diff --git a/opendj-sdk/opends/src/server/org/opends/server/workflowelement/externalchangelog/ECLSearchOperation.java b/opendj-sdk/opends/src/server/org/opends/server/workflowelement/externalchangelog/ECLSearchOperation.java
index c49158c..76bc2d9 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/workflowelement/externalchangelog/ECLSearchOperation.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/workflowelement/externalchangelog/ECLSearchOperation.java
@@ -59,6 +59,7 @@
import org.opends.server.controls.PersistentSearchControl;
import org.opends.server.controls.ProxiedAuthV1Control;
import org.opends.server.controls.ProxiedAuthV2Control;
+import org.opends.server.controls.SubentriesControl;
import org.opends.server.core.AccessControlConfigManager;
import org.opends.server.core.AddOperation;
import org.opends.server.core.DirectoryServer;
@@ -549,7 +550,9 @@
}
else if (oid.equals(OID_LDAP_SUBENTRIES))
{
- setReturnLDAPSubentries(true);
+ SubentriesControl subentriesControl =
+ getRequestControl(SubentriesControl.DECODER);
+ setReturnLDAPSubentries(subentriesControl.getVisibility());
}
else if (oid.equals(OID_MATCHED_VALUES))
{
diff --git a/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendSearchOperation.java b/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendSearchOperation.java
index 3413328..6e6a124 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendSearchOperation.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendSearchOperation.java
@@ -38,6 +38,7 @@
import org.opends.server.controls.PersistentSearchControl;
import org.opends.server.controls.ProxiedAuthV1Control;
import org.opends.server.controls.ProxiedAuthV2Control;
+import org.opends.server.controls.SubentriesControl;
import org.opends.server.core.AccessControlConfigManager;
import org.opends.server.core.DirectoryServer;
import org.opends.server.core.PersistentSearch;
@@ -500,7 +501,9 @@
}
else if (oid.equals(OID_LDAP_SUBENTRIES))
{
- setReturnLDAPSubentries(true);
+ SubentriesControl subentriesControl =
+ getRequestControl(SubentriesControl.DECODER);
+ setReturnLDAPSubentries(subentriesControl.getVisibility());
}
else if (oid.equals(OID_MATCHED_VALUES))
{
diff --git a/opendj-sdk/opends/src/server/org/opends/server/workflowelement/ndb/NDBSearchOperation.java b/opendj-sdk/opends/src/server/org/opends/server/workflowelement/ndb/NDBSearchOperation.java
index fcc42d3..6983c90 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/workflowelement/ndb/NDBSearchOperation.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/workflowelement/ndb/NDBSearchOperation.java
@@ -35,6 +35,7 @@
import org.opends.server.controls.MatchedValuesControl;
import org.opends.server.controls.ProxiedAuthV1Control;
import org.opends.server.controls.ProxiedAuthV2Control;
+import org.opends.server.controls.SubentriesControl;
import org.opends.server.core.AccessControlConfigManager;
import org.opends.server.core.DirectoryServer;
import org.opends.server.core.PluginConfigManager;
@@ -411,7 +412,9 @@
}
else if (oid.equals(OID_LDAP_SUBENTRIES))
{
- setReturnLDAPSubentries(true);
+ SubentriesControl subentriesControl =
+ getRequestControl(SubentriesControl.DECODER);
+ setReturnLDAPSubentries(subentriesControl.getVisibility());
}
else if (oid.equals(OID_MATCHED_VALUES))
{
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/tools/LDAPSearchTestCase.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/tools/LDAPSearchTestCase.java
index 6de452a..36754b7 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/tools/LDAPSearchTestCase.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/tools/LDAPSearchTestCase.java
@@ -1654,11 +1654,11 @@
"-s", "sub",
"--countEntries",
"--noPropertiesFile",
- "-J", OID_LDAP_SUBENTRIES + ":true",
+ "--subEntries",
"(objectClass=*)"
};
- assertEquals(LDAPSearch.mainSearch(args, false, true, null, System.err), 2);
+ assertEquals(LDAPSearch.mainSearch(args, false, true, null, System.err), 1);
args = new String[]
{
@@ -1666,15 +1666,14 @@
"-w", "password",
"-h", "127.0.0.1",
"-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
- "-b", "o=test",
- "-s", "sub",
+ "-b", "cn=test,o=test",
+ "-s", "base",
"--countEntries",
"--noPropertiesFile",
- "-J", "subentries:true",
"(objectClass=*)"
};
- assertEquals(LDAPSearch.mainSearch(args, false, true, null, System.err), 2);
+ assertEquals(LDAPSearch.mainSearch(args, false, true, null, System.err), 1);
}
--
Gitblit v1.10.0