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 \ 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 opends/src/server/org/opends/server/controls/SubentriesControl.java
New file @@ -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("\")"); } } 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()) 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()) 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; 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"; 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"; 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)) { 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)) { 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)) { 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); }