From 74aa5e09416351915266aa26f4d84f8c2b6e9b7e Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Wed, 14 Sep 2011 15:49:16 +0000
Subject: [PATCH] Fix OPENDJ-281: LDAP SDK sub-entry control is not compliant with RFC 3672
---
opendj-sdk/opendj3/opendj-ldap-sdk/src/main/resources/org/forgerock/opendj/ldap/core.properties | 7 ++-
opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/controls/SubentriesRequestControl.java | 104 +++++++++++++++++++++++++++++++++++++++++-----------
2 files changed, 87 insertions(+), 24 deletions(-)
diff --git a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/controls/SubentriesRequestControl.java b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/controls/SubentriesRequestControl.java
index d2b0ec2..cd49828 100644
--- a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/controls/SubentriesRequestControl.java
+++ b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/controls/SubentriesRequestControl.java
@@ -23,48 +23,57 @@
*
*
* Copyright 2010 Sun Microsystems, Inc.
+ * Portions copyright 2011 ForgeRock AS
*/
package org.forgerock.opendj.ldap.controls;
-import static org.forgerock.opendj.ldap.CoreMessages.ERR_SUBENTRIES_CONTROL_BAD_OID;
-import static org.forgerock.opendj.ldap.CoreMessages.ERR_SUBENTRIES_INVALID_CONTROL_VALUE;
+import static com.forgerock.opendj.util.StaticUtils.getExceptionMessage;
+import static org.forgerock.opendj.ldap.CoreMessages.*;
+
+import java.io.IOException;
import org.forgerock.i18n.LocalizableMessage;
+import org.forgerock.opendj.asn1.ASN1;
+import org.forgerock.opendj.asn1.ASN1Reader;
import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.opendj.ldap.DecodeException;
import org.forgerock.opendj.ldap.DecodeOptions;
+import com.forgerock.opendj.util.StaticUtils;
import com.forgerock.opendj.util.Validator;
/**
- * The sub-entries request control as defined in draft-ietf-ldup-subentry. This
- * control may be included in a search request to indicate that sub-entries
- * should be included in the search results.
+ * The sub-entries request control as defined in RFC 3672. This control may be
+ * included in a search request to indicate that sub-entries should be included
+ * in the search results.
* <p>
* In the absence of the sub-entries request control, sub-entries are not
* visible to search operations unless the target/base of the operation is a
- * sub-entry. In the presence of the sub-entry request control, only sub-entries
- * are visible.
+ * sub-entry. In the presence of the sub-entry request control, sub-entries are
+ * visible if and only if the control's value is {@code TRUE}.
*
- * @see <a
- * href="http://tools.ietf.org/html/draft-ietf-ldup-subentry">draft-ietf-ldup-subentry
- * - LDAP Subentry Schema </a>
+ * @see <a href="http://tools.ietf.org/html/rfc3672">RFC 3672 - Subentries in
+ * the Lightweight Directory Access Protocol </a>
*/
public final class SubentriesRequestControl implements Control
{
/**
* The OID for the sub-entries request control.
*/
- public static final String OID = "1.3.6.1.4.1.7628.5.101.1";
+ public static final String OID = "1.3.6.1.4.1.4203.1.10.1";
- private static final SubentriesRequestControl CRITICAL_INSTANCE = new SubentriesRequestControl(
- true);
- private static final SubentriesRequestControl NONCRITICAL_INSTANCE = new SubentriesRequestControl(
- false);
+ private static final SubentriesRequestControl CRITICAL_VISIBLE_INSTANCE =
+ new SubentriesRequestControl(true, true);
+ private static final SubentriesRequestControl NONCRITICAL_VISIBLE_INSTANCE =
+ new SubentriesRequestControl(false, true);
+ private static final SubentriesRequestControl CRITICAL_INVISIBLE_INSTANCE =
+ new SubentriesRequestControl(true, false);
+ private static final SubentriesRequestControl NONCRITICAL_INVISIBLE_INSTANCE =
+ new SubentriesRequestControl(false, false);
/**
* A decoder which can be used for decoding the sub-entries request control.
@@ -90,14 +99,30 @@
throw DecodeException.error(message);
}
- if (control.hasValue())
+ if (!control.hasValue())
{
- final LocalizableMessage message = ERR_SUBENTRIES_INVALID_CONTROL_VALUE
+ // The response control must always have a value.
+ final LocalizableMessage message = ERR_SUBENTRIES_NO_CONTROL_VALUE
.get();
throw DecodeException.error(message);
}
- return control.isCritical() ? CRITICAL_INSTANCE : NONCRITICAL_INSTANCE;
+ final ASN1Reader reader = ASN1.getReader(control.getValue());
+ final boolean visibility;
+ try
+ {
+ visibility = reader.readBoolean();
+ }
+ catch (final IOException e)
+ {
+ StaticUtils.DEBUG_LOG.throwing("SubentriesRequestControl.Decoder",
+ "decode", e);
+ final LocalizableMessage message = ERR_SUBENTRIES_CANNOT_DECODE_VALUE
+ .get(getExceptionMessage(e));
+ throw DecodeException.error(message);
+ }
+
+ return newControl(control.isCritical(), visibility);
}
@@ -111,28 +136,46 @@
/**
- * Creates a new sub-entries request control having the provided criticality.
+ * Creates a new sub-entries request control having the provided criticality
+ * and sub-entry visibility.
*
* @param isCritical
* {@code true} if it is unacceptable to perform the operation
* without applying the semantics of this control, or {@code false}
* if it can be ignored.
+ * @param visibility
+ * {@code true} if sub-entries should be included in the search
+ * results and normal entries excluded, or {@code false} if normal
+ * entries should be included and sub-entries excluded.
* @return The new control.
*/
- public static SubentriesRequestControl newControl(final boolean isCritical)
+ public static SubentriesRequestControl newControl(final boolean isCritical,
+ final boolean visibility)
{
- return isCritical ? CRITICAL_INSTANCE : NONCRITICAL_INSTANCE;
+ if (isCritical)
+ {
+ return visibility ? CRITICAL_VISIBLE_INSTANCE
+ : CRITICAL_INVISIBLE_INSTANCE;
+ }
+ else
+ {
+ return visibility ? NONCRITICAL_VISIBLE_INSTANCE
+ : NONCRITICAL_INVISIBLE_INSTANCE;
+ }
}
private final boolean isCritical;
+ private final boolean visibility;
- private SubentriesRequestControl(final boolean isCritical)
+ private SubentriesRequestControl(final boolean isCritical,
+ final boolean visibility)
{
this.isCritical = isCritical;
+ this.visibility = visibility;
}
@@ -158,6 +201,21 @@
/**
+ * Returns a boolean indicating whether or not sub-entries should be included
+ * in the search results.
+ *
+ * @return {@code true} if sub-entries should be included in the search results
+ * and normal entries excluded, or {@code false} if normal entries
+ * should be included and sub-entries excluded.
+ */
+ public boolean getVisibility()
+ {
+ return visibility;
+ }
+
+
+
+ /**
* {@inheritDoc}
*/
public boolean hasValue()
@@ -188,6 +246,8 @@
builder.append(getOID());
builder.append(", criticality=");
builder.append(isCritical());
+ builder.append(", visibility=");
+ builder.append(getVisibility());
builder.append(")");
return builder.toString();
}
diff --git a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/resources/org/forgerock/opendj/ldap/core.properties b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/resources/org/forgerock/opendj/ldap/core.properties
index 7eb1587..cf21f83 100755
--- a/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/resources/org/forgerock/opendj/ldap/core.properties
+++ b/opendj-sdk/opendj3/opendj-ldap-sdk/src/main/resources/org/forgerock/opendj/ldap/core.properties
@@ -1054,8 +1054,11 @@
ERR_SUBENTRIES_CONTROL_BAD_OID=Cannot decode the provided \
control as a sub-entries request control because it \
contained the OID '%s', when '%s' was expected
-ERR_SUBENTRIES_INVALID_CONTROL_VALUE=Cannot decode the provided \
- sub-entries control because it contains a value
+ERR_SUBENTRIES_NO_CONTROL_VALUE=Cannot decode the provided \
+ sub-entries control because it does not have a value
+ERR_SUBENTRIES_CANNOT_DECODE_VALUE=Cannot decode \
+ the provided sub-entries control because an error occurred while \
+ attempting to decode the value as an ASN.1 boolean: %s
ERR_WHOAMI_INVALID_AUTHZID_TYPE=The provided authorization ID '%s' \
does not begin with a valid authorization ID type 'dn:' or 'u:'
ERR_PERMISSIVE_MODIFY_CONTROL_BAD_OID=Cannot decode the provided \
--
Gitblit v1.10.0