mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

neil_a_wilson
06.17.2007 37af0ef44fc0876889da39db3760521d451460cf
Update the server to reject requests from LDAPv2 clients if those requests
contain controls. Previously, the server would only strip out any response
controls, but this is likely to hide problems and/or create debugging
difficulty, so the requests will now be rejected and the associated connection
terminated.

OpenDS Issue Number: 1906
1 files added
2 files modified
705 ■■■■■ changed files
opends/src/server/org/opends/server/messages/ProtocolMessages.java 12 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/protocols/ldap/LDAPClientConnection.java 95 ●●●●● patch | view | raw | blame | history
opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/ldap/LDAPv2TestCase.java 598 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/messages/ProtocolMessages.java
@@ -4649,6 +4649,16 @@
  /**
   * The message ID for the message that will be used to indicate that an LDAPv2
   * client tried to send a request that included request controls.  This does
   * not take any arguments.
   */
  public static final int MSGID_LDAPV2_CONTROLS_NOT_ALLOWED =
       CATEGORY_MASK_PROTOCOL | SEVERITY_MASK_MILD_ERROR | 431;
  /**
   * Associates a set of generic messages with the message IDs defined in this
   * class.
   */
@@ -6055,6 +6065,8 @@
                    "extended operation request (LDAP message ID %d), which " +
                    "is not allowed for LDAPv2 clients.  The connection will " +
                    "be terminated");
    registerMessage(MSGID_LDAPV2_CONTROLS_NOT_ALLOWED,
                    "LDAPv2 clients are not allowed to use request controls");
opends/src/server/org/opends/server/protocols/ldap/LDAPClientConnection.java
@@ -108,7 +108,6 @@
  // The next operation ID that should be used for this connection.
  private AtomicLong nextOperationID;
@@ -1857,6 +1856,19 @@
  private boolean processAddRequest(LDAPMessage message,
                                    ArrayList<Control> controls)
  {
    if ((ldapVersion == 2) && (controls != null) && (! controls.isEmpty()))
    {
      // LDAPv2 clients aren't allowed to send controls.
      AddResponseProtocolOp responseOp =
           new AddResponseProtocolOp(LDAPResultCode.PROTOCOL_ERROR,
                    getMessage(MSGID_LDAPV2_CONTROLS_NOT_ALLOWED));
      sendLDAPMessage(securityProvider,
                      new LDAPMessage(message.getMessageID(), responseOp));
      disconnect(DisconnectReason.PROTOCOL_ERROR, false,
                 MSGID_LDAPV2_CONTROLS_NOT_ALLOWED);
      return false;
    }
    // Create the add operation and add it into the work queue.
    AddRequestProtocolOp protocolOp = message.getAddRequestProtocolOp();
    AddOperationBasis addOp =
@@ -1922,7 +1934,21 @@
                        getMessage(MSGID_LDAPV2_CLIENTS_NOT_ALLOWED));
          sendLDAPMessage(securityProvider,
                          new LDAPMessage(message.getMessageID(), responseOp));
          disconnect(DisconnectReason.PROTOCOL_ERROR, false, null, -1);
          disconnect(DisconnectReason.PROTOCOL_ERROR, false,
                     MSGID_LDAPV2_CLIENTS_NOT_ALLOWED);
          return false;
        }
        if ((controls != null) && (! controls.isEmpty()))
        {
          // LDAPv2 clients aren't allowed to send controls.
          BindResponseProtocolOp responseOp =
               new BindResponseProtocolOp(LDAPResultCode.PROTOCOL_ERROR,
                        getMessage(MSGID_LDAPV2_CONTROLS_NOT_ALLOWED));
          sendLDAPMessage(securityProvider,
                          new LDAPMessage(message.getMessageID(), responseOp));
          disconnect(DisconnectReason.PROTOCOL_ERROR, false,
                     MSGID_LDAPV2_CONTROLS_NOT_ALLOWED);
          return false;
        }
@@ -2016,6 +2042,19 @@
  private boolean processCompareRequest(LDAPMessage message,
                                        ArrayList<Control> controls)
  {
    if ((ldapVersion == 2) && (controls != null) && (! controls.isEmpty()))
    {
      // LDAPv2 clients aren't allowed to send controls.
      CompareResponseProtocolOp responseOp =
           new CompareResponseProtocolOp(LDAPResultCode.PROTOCOL_ERROR,
                    getMessage(MSGID_LDAPV2_CONTROLS_NOT_ALLOWED));
      sendLDAPMessage(securityProvider,
                      new LDAPMessage(message.getMessageID(), responseOp));
      disconnect(DisconnectReason.PROTOCOL_ERROR, false,
                 MSGID_LDAPV2_CONTROLS_NOT_ALLOWED);
      return false;
    }
    CompareRequestProtocolOp protocolOp = message.getCompareRequestProtocolOp();
    CompareOperation compareOp =
         new CompareOperation(this, nextOperationID.getAndIncrement(),
@@ -2066,6 +2105,19 @@
  private boolean processDeleteRequest(LDAPMessage message,
                                       ArrayList<Control> controls)
  {
    if ((ldapVersion == 2) && (controls != null) && (! controls.isEmpty()))
    {
      // LDAPv2 clients aren't allowed to send controls.
      DeleteResponseProtocolOp responseOp =
           new DeleteResponseProtocolOp(LDAPResultCode.PROTOCOL_ERROR,
                    getMessage(MSGID_LDAPV2_CONTROLS_NOT_ALLOWED));
      sendLDAPMessage(securityProvider,
                      new LDAPMessage(message.getMessageID(), responseOp));
      disconnect(DisconnectReason.PROTOCOL_ERROR, false,
                 MSGID_LDAPV2_CONTROLS_NOT_ALLOWED);
      return false;
    }
    DeleteRequestProtocolOp protocolOp = message.getDeleteRequestProtocolOp();
    DeleteOperationBasis deleteOp =
         new DeleteOperationBasis(this, nextOperationID.getAndIncrement(),
@@ -2184,6 +2236,19 @@
  private boolean processModifyRequest(LDAPMessage message,
                                       ArrayList<Control> controls)
  {
    if ((ldapVersion == 2) && (controls != null) && (! controls.isEmpty()))
    {
      // LDAPv2 clients aren't allowed to send controls.
      ModifyResponseProtocolOp responseOp =
           new ModifyResponseProtocolOp(LDAPResultCode.PROTOCOL_ERROR,
                    getMessage(MSGID_LDAPV2_CONTROLS_NOT_ALLOWED));
      sendLDAPMessage(securityProvider,
                      new LDAPMessage(message.getMessageID(), responseOp));
      disconnect(DisconnectReason.PROTOCOL_ERROR, false,
                 MSGID_LDAPV2_CONTROLS_NOT_ALLOWED);
      return false;
    }
    ModifyRequestProtocolOp protocolOp = message.getModifyRequestProtocolOp();
    ModifyOperationBasis modifyOp =
         new ModifyOperationBasis(this, nextOperationID.getAndIncrement(),
@@ -2232,6 +2297,19 @@
  private boolean processModifyDNRequest(LDAPMessage message,
                                         ArrayList<Control> controls)
  {
    if ((ldapVersion == 2) && (controls != null) && (! controls.isEmpty()))
    {
      // LDAPv2 clients aren't allowed to send controls.
      ModifyDNResponseProtocolOp responseOp =
           new ModifyDNResponseProtocolOp(LDAPResultCode.PROTOCOL_ERROR,
                    getMessage(MSGID_LDAPV2_CONTROLS_NOT_ALLOWED));
      sendLDAPMessage(securityProvider,
                      new LDAPMessage(message.getMessageID(), responseOp));
      disconnect(DisconnectReason.PROTOCOL_ERROR, false,
                 MSGID_LDAPV2_CONTROLS_NOT_ALLOWED);
      return false;
    }
    ModifyDNRequestProtocolOp protocolOp =
         message.getModifyDNRequestProtocolOp();
    ModifyDNOperation modifyDNOp =
@@ -2284,6 +2362,19 @@
  private boolean processSearchRequest(LDAPMessage message,
                                       ArrayList<Control> controls)
  {
    if ((ldapVersion == 2) && (controls != null) && (! controls.isEmpty()))
    {
      // LDAPv2 clients aren't allowed to send controls.
      SearchResultDoneProtocolOp responseOp =
           new SearchResultDoneProtocolOp(LDAPResultCode.PROTOCOL_ERROR,
                    getMessage(MSGID_LDAPV2_CONTROLS_NOT_ALLOWED));
      sendLDAPMessage(securityProvider,
                      new LDAPMessage(message.getMessageID(), responseOp));
      disconnect(DisconnectReason.PROTOCOL_ERROR, false,
                 MSGID_LDAPV2_CONTROLS_NOT_ALLOWED);
      return false;
    }
    SearchRequestProtocolOp protocolOp = message.getSearchRequestProtocolOp();
    SearchOperationBasis searchOp =
         new SearchOperationBasis(this, nextOperationID.getAndIncrement(),
opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/ldap/LDAPv2TestCase.java
New file
@@ -0,0 +1,598 @@
/*
 * 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
 *
 *
 *      Portions Copyright 2006-2007 Sun Microsystems, Inc.
 */
package org.opends.server.protocols.ldap ;
import java.net.Socket;
import java.util.ArrayList;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import org.opends.server.TestCaseUtils;
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.protocols.asn1.ASN1Reader;
import org.opends.server.protocols.asn1.ASN1Writer;
import org.opends.server.types.DereferencePolicy;
import org.opends.server.types.ModificationType;
import org.opends.server.types.RawAttribute;
import org.opends.server.types.RawModification;
import org.opends.server.types.SearchScope;
import static org.testng.Assert.*;
import static org.opends.server.util.ServerConstants.*;
/**
 * This class provides a number of tests to ensure that the server interacts
 * with LDAPv2 clients as expected.
 */
public class LDAPv2TestCase
       extends LdapTestCase
{
  /**
   * Ensure that the Directory Server is running.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @BeforeClass()
  public void startServer()
         throws Exception
  {
    TestCaseUtils.startServer();
    TestCaseUtils.initializeTestBackend(true);
  }
  /**
   * Tests to ensure that the server will reject an LDAPv2 bind request if
   * configured to do so.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testRejectBindRequest()
         throws Exception
  {
    TestCaseUtils.applyModifications(
      "dn: cn=LDAP Connection Handler,cn=Connection Handlers,cn=config",
      "changetype: modify",
      "replace: ds-cfg-allow-ldapv2",
      "ds-cfg-allow-ldapv2: false");
    Socket     s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
    ASN1Reader r = new ASN1Reader(s);
    ASN1Writer w = new ASN1Writer(s);
    try
    {
      BindRequestProtocolOp bindRequest =
           new BindRequestProtocolOp(
                    new ASN1OctetString("cn=Directory Manager"), 2,
                    new ASN1OctetString("password"));
      LDAPMessage message = new LDAPMessage(1, bindRequest);
      w.writeElement(message.encode());
      message = LDAPMessage.decode(r.readElement().decodeAsSequence());
      BindResponseProtocolOp bindResponse = message.getBindResponseProtocolOp();
      assertEquals(bindResponse.getResultCode(),
                   LDAPResultCode.INAPPROPRIATE_AUTHENTICATION);
    }
    finally
    {
      TestCaseUtils.applyModifications(
        "dn: cn=LDAP Connection Handler,cn=Connection Handlers,cn=config",
        "changetype: modify",
        "replace: ds-cfg-allow-ldapv2",
        "ds-cfg-allow-ldapv2: true");
      try
      {
        r.close();
      } catch (Exception e) {}
      try
      {
        w.close();
      } catch (Exception e) {}
      try
      {
        s.close();
      } catch (Exception e) {}
    }
  }
  /**
   * Tests to ensure that the server will reject an extended request from an
   * LDAPv2 client.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testRejectExtendedRequest()
         throws Exception
  {
    Socket     s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
    ASN1Reader r = new ASN1Reader(s);
    ASN1Writer w = new ASN1Writer(s);
    try
    {
      BindRequestProtocolOp bindRequest =
           new BindRequestProtocolOp(
                    new ASN1OctetString("cn=Directory Manager"), 2,
                    new ASN1OctetString("password"));
      LDAPMessage message = new LDAPMessage(1, bindRequest);
      w.writeElement(message.encode());
      message = LDAPMessage.decode(r.readElement().decodeAsSequence());
      BindResponseProtocolOp bindResponse = message.getBindResponseProtocolOp();
      assertEquals(bindResponse.getResultCode(), 0);
      ExtendedRequestProtocolOp extendedRequest =
           new ExtendedRequestProtocolOp(OID_START_TLS_REQUEST);
      message = new LDAPMessage(2, extendedRequest);
      w.writeElement(message.encode());
      assertNull(r.readElement());
    }
    finally
    {
      try
      {
        r.close();
      } catch (Exception e) {}
      try
      {
        w.close();
      } catch (Exception e) {}
      try
      {
        s.close();
      } catch (Exception e) {}
    }
  }
  /**
   * Tests to ensure that the server will reject an LDAPv2 add request if it
   * contains any controls.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testRejectAddControls()
         throws Exception
  {
    Socket     s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
    ASN1Reader r = new ASN1Reader(s);
    ASN1Writer w = new ASN1Writer(s);
    try
    {
      BindRequestProtocolOp bindRequest =
           new BindRequestProtocolOp(
                    new ASN1OctetString("cn=Directory Manager"), 2,
                    new ASN1OctetString("password"));
      LDAPMessage message = new LDAPMessage(1, bindRequest);
      w.writeElement(message.encode());
      message = LDAPMessage.decode(r.readElement().decodeAsSequence());
      BindResponseProtocolOp bindResponse = message.getBindResponseProtocolOp();
      assertEquals(bindResponse.getResultCode(), 0);
      ArrayList<RawAttribute> addAttrs = new ArrayList<RawAttribute>();
      addAttrs.add(RawAttribute.create("objectClass", "organizationalUnit"));
      addAttrs.add(RawAttribute.create("ou", "People"));
      AddRequestProtocolOp addRequest =
           new AddRequestProtocolOp(new ASN1OctetString("ou=People,o=test"),
                                    addAttrs);
      ArrayList<LDAPControl> controls = new ArrayList<LDAPControl>(1);
      controls.add(new LDAPControl(OID_MANAGE_DSAIT_CONTROL, true));
      message = new LDAPMessage(2, addRequest, controls);
      w.writeElement(message.encode());
      message = LDAPMessage.decode(r.readElement().decodeAsSequence());
      AddResponseProtocolOp addResponse = message.getAddResponseProtocolOp();
      assertEquals(addResponse.getResultCode(), LDAPResultCode.PROTOCOL_ERROR);
    }
    finally
    {
      try
      {
        r.close();
      } catch (Exception e) {}
      try
      {
        w.close();
      } catch (Exception e) {}
      try
      {
        s.close();
      } catch (Exception e) {}
    }
  }
  /**
   * Tests to ensure that the server will reject an LDAPv2 bind request if it
   * contains any controls and LDAPv2 binds are allowed.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testRejectBindControls()
         throws Exception
  {
    Socket     s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
    ASN1Reader r = new ASN1Reader(s);
    ASN1Writer w = new ASN1Writer(s);
    try
    {
      BindRequestProtocolOp bindRequest =
           new BindRequestProtocolOp(
                    new ASN1OctetString("cn=Directory Manager"), 2,
                    new ASN1OctetString("password"));
      ArrayList<LDAPControl> controls = new ArrayList<LDAPControl>(1);
      controls.add(new LDAPControl(OID_MANAGE_DSAIT_CONTROL, true));
      LDAPMessage message = new LDAPMessage(1, bindRequest, controls);
      w.writeElement(message.encode());
      message = LDAPMessage.decode(r.readElement().decodeAsSequence());
      BindResponseProtocolOp bindResponse = message.getBindResponseProtocolOp();
      assertEquals(bindResponse.getResultCode(), LDAPResultCode.PROTOCOL_ERROR);
    }
    finally
    {
      try
      {
        r.close();
      } catch (Exception e) {}
      try
      {
        w.close();
      } catch (Exception e) {}
      try
      {
        s.close();
      } catch (Exception e) {}
    }
  }
  /**
   * Tests to ensure that the server will reject an LDAPv2 compare request if it
   * contains any controls.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testRejectCompareControls()
         throws Exception
  {
    Socket     s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
    ASN1Reader r = new ASN1Reader(s);
    ASN1Writer w = new ASN1Writer(s);
    try
    {
      BindRequestProtocolOp bindRequest =
           new BindRequestProtocolOp(
                    new ASN1OctetString("cn=Directory Manager"), 2,
                    new ASN1OctetString("password"));
      LDAPMessage message = new LDAPMessage(1, bindRequest);
      w.writeElement(message.encode());
      message = LDAPMessage.decode(r.readElement().decodeAsSequence());
      BindResponseProtocolOp bindResponse = message.getBindResponseProtocolOp();
      assertEquals(bindResponse.getResultCode(), 0);
      CompareRequestProtocolOp compareRequest =
           new CompareRequestProtocolOp(new ASN1OctetString("o=test"),
                                        "o", new ASN1OctetString("test"));
      ArrayList<LDAPControl> controls = new ArrayList<LDAPControl>(1);
      controls.add(new LDAPControl(OID_MANAGE_DSAIT_CONTROL, true));
      message = new LDAPMessage(2, compareRequest, controls);
      w.writeElement(message.encode());
      message = LDAPMessage.decode(r.readElement().decodeAsSequence());
      CompareResponseProtocolOp compareResponse =
           message.getCompareResponseProtocolOp();
      assertEquals(compareResponse.getResultCode(),
                   LDAPResultCode.PROTOCOL_ERROR);
    }
    finally
    {
      try
      {
        r.close();
      } catch (Exception e) {}
      try
      {
        w.close();
      } catch (Exception e) {}
      try
      {
        s.close();
      } catch (Exception e) {}
    }
  }
  /**
   * Tests to ensure that the server will reject an LDAPv2 delete request if it
   * contains any controls.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testRejectDeleteControls()
         throws Exception
  {
    Socket     s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
    ASN1Reader r = new ASN1Reader(s);
    ASN1Writer w = new ASN1Writer(s);
    try
    {
      BindRequestProtocolOp bindRequest =
           new BindRequestProtocolOp(
                    new ASN1OctetString("cn=Directory Manager"), 2,
                    new ASN1OctetString("password"));
      LDAPMessage message = new LDAPMessage(1, bindRequest);
      w.writeElement(message.encode());
      message = LDAPMessage.decode(r.readElement().decodeAsSequence());
      BindResponseProtocolOp bindResponse = message.getBindResponseProtocolOp();
      assertEquals(bindResponse.getResultCode(), 0);
      DeleteRequestProtocolOp deleteRequest =
           new DeleteRequestProtocolOp(new ASN1OctetString("o=test"));
      ArrayList<LDAPControl> controls = new ArrayList<LDAPControl>(1);
      controls.add(new LDAPControl(OID_MANAGE_DSAIT_CONTROL, true));
      message = new LDAPMessage(2, deleteRequest, controls);
      w.writeElement(message.encode());
      message = LDAPMessage.decode(r.readElement().decodeAsSequence());
      DeleteResponseProtocolOp deleteResponse =
           message.getDeleteResponseProtocolOp();
      assertEquals(deleteResponse.getResultCode(),
                   LDAPResultCode.PROTOCOL_ERROR);
    }
    finally
    {
      try
      {
        r.close();
      } catch (Exception e) {}
      try
      {
        w.close();
      } catch (Exception e) {}
      try
      {
        s.close();
      } catch (Exception e) {}
    }
  }
  /**
   * Tests to ensure that the server will reject an LDAPv2 modify request if it
   * contains any controls.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testRejectModifyControls()
         throws Exception
  {
    Socket     s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
    ASN1Reader r = new ASN1Reader(s);
    ASN1Writer w = new ASN1Writer(s);
    try
    {
      BindRequestProtocolOp bindRequest =
           new BindRequestProtocolOp(
                    new ASN1OctetString("cn=Directory Manager"), 2,
                    new ASN1OctetString("password"));
      LDAPMessage message = new LDAPMessage(1, bindRequest);
      w.writeElement(message.encode());
      message = LDAPMessage.decode(r.readElement().decodeAsSequence());
      BindResponseProtocolOp bindResponse = message.getBindResponseProtocolOp();
      assertEquals(bindResponse.getResultCode(), 0);
      ArrayList<RawModification> mods = new ArrayList<RawModification>();
      mods.add(RawModification.create(ModificationType.REPLACE,
                                      "description", "foo"));
      ModifyRequestProtocolOp modifyRequest =
           new ModifyRequestProtocolOp(new ASN1OctetString("o=test"), mods);
      ArrayList<LDAPControl> controls = new ArrayList<LDAPControl>(1);
      controls.add(new LDAPControl(OID_MANAGE_DSAIT_CONTROL, true));
      message = new LDAPMessage(2, modifyRequest, controls);
      w.writeElement(message.encode());
      message = LDAPMessage.decode(r.readElement().decodeAsSequence());
      ModifyResponseProtocolOp modifyResponse =
           message.getModifyResponseProtocolOp();
      assertEquals(modifyResponse.getResultCode(),
                   LDAPResultCode.PROTOCOL_ERROR);
    }
    finally
    {
      try
      {
        r.close();
      } catch (Exception e) {}
      try
      {
        w.close();
      } catch (Exception e) {}
      try
      {
        s.close();
      } catch (Exception e) {}
    }
  }
  /**
   * Tests to ensure that the server will reject an LDAPv2 modify DN request if
   * it contains any controls.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testRejectModifyDNControls()
         throws Exception
  {
    Socket     s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
    ASN1Reader r = new ASN1Reader(s);
    ASN1Writer w = new ASN1Writer(s);
    try
    {
      BindRequestProtocolOp bindRequest =
           new BindRequestProtocolOp(
                    new ASN1OctetString("cn=Directory Manager"), 2,
                    new ASN1OctetString("password"));
      LDAPMessage message = new LDAPMessage(1, bindRequest);
      w.writeElement(message.encode());
      message = LDAPMessage.decode(r.readElement().decodeAsSequence());
      BindResponseProtocolOp bindResponse = message.getBindResponseProtocolOp();
      assertEquals(bindResponse.getResultCode(), 0);
      ModifyDNRequestProtocolOp modifyDNRequest =
           new ModifyDNRequestProtocolOp(new ASN1OctetString("o=test"),
                                         new ASN1OctetString("cn=test"), false);
      ArrayList<LDAPControl> controls = new ArrayList<LDAPControl>(1);
      controls.add(new LDAPControl(OID_MANAGE_DSAIT_CONTROL, true));
      message = new LDAPMessage(2, modifyDNRequest, controls);
      w.writeElement(message.encode());
      message = LDAPMessage.decode(r.readElement().decodeAsSequence());
      ModifyDNResponseProtocolOp modifyDNResponse =
           message.getModifyDNResponseProtocolOp();
      assertEquals(modifyDNResponse.getResultCode(),
                   LDAPResultCode.PROTOCOL_ERROR);
    }
    finally
    {
      try
      {
        r.close();
      } catch (Exception e) {}
      try
      {
        w.close();
      } catch (Exception e) {}
      try
      {
        s.close();
      } catch (Exception e) {}
    }
  }
  /**
   * Tests to ensure that the server will reject an LDAPv2 search request if it
   * contains any controls.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testRejectSearchControls()
         throws Exception
  {
    Socket     s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
    ASN1Reader r = new ASN1Reader(s);
    ASN1Writer w = new ASN1Writer(s);
    try
    {
      BindRequestProtocolOp bindRequest =
           new BindRequestProtocolOp(
                    new ASN1OctetString("cn=Directory Manager"), 2,
                    new ASN1OctetString("password"));
      LDAPMessage message = new LDAPMessage(1, bindRequest);
      w.writeElement(message.encode());
      message = LDAPMessage.decode(r.readElement().decodeAsSequence());
      BindResponseProtocolOp bindResponse = message.getBindResponseProtocolOp();
      assertEquals(bindResponse.getResultCode(), 0);
      SearchRequestProtocolOp searchRequest =
           new SearchRequestProtocolOp(new ASN1OctetString(),
                    SearchScope.BASE_OBJECT,
                    DereferencePolicy.NEVER_DEREF_ALIASES, 0, 0, false,
                    LDAPFilter.decode("(objectClass=*)"), null);
      ArrayList<LDAPControl> controls = new ArrayList<LDAPControl>(1);
      controls.add(new LDAPControl(OID_MANAGE_DSAIT_CONTROL, true));
      message = new LDAPMessage(2, searchRequest, controls);
      w.writeElement(message.encode());
      message = LDAPMessage.decode(r.readElement().decodeAsSequence());
      SearchResultDoneProtocolOp searchDone =
           message.getSearchResultDoneProtocolOp();
      assertEquals(searchDone.getResultCode(), LDAPResultCode.PROTOCOL_ERROR);
    }
    finally
    {
      try
      {
        r.close();
      } catch (Exception e) {}
      try
      {
        w.close();
      } catch (Exception e) {}
      try
      {
        s.close();
      } catch (Exception e) {}
    }
  }
}