/*
|
* The contents of this file are subject to the terms of the Common Development and
|
* Distribution License (the License). You may not use this file except in compliance with the
|
* License.
|
*
|
* You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
|
* specific language governing permission and limitations under the License.
|
*
|
* When distributing Covered Software, include this CDDL Header Notice in each file and include
|
* the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
|
* Header, with the fields enclosed by brackets [] replaced by your own identifying
|
* information: "Portions Copyright [year] [name of copyright owner]".
|
*
|
* Copyright 2006-2008 Sun Microsystems, Inc.
|
* Portions Copyright 2010-2016 ForgeRock AS.
|
*/
|
package org.opends.server.protocols.ldap ;
|
|
import static org.forgerock.opendj.ldap.ModificationType.*;
|
import static org.forgerock.opendj.ldap.SearchScope.*;
|
import static org.forgerock.opendj.ldap.controls.GenericControl.*;
|
import static org.forgerock.opendj.ldap.requests.Requests.*;
|
import static org.opends.server.util.ServerConstants.*;
|
import static org.testng.Assert.*;
|
|
import java.io.EOFException;
|
import java.io.IOException;
|
import java.util.Arrays;
|
|
import org.forgerock.opendj.ldap.ByteString;
|
import org.forgerock.opendj.ldap.DN;
|
import org.forgerock.opendj.ldap.Filter;
|
import org.forgerock.opendj.ldap.requests.AddRequest;
|
import org.forgerock.opendj.ldap.requests.CompareRequest;
|
import org.forgerock.opendj.ldap.requests.DeleteRequest;
|
import org.forgerock.opendj.ldap.requests.ModifyDNRequest;
|
import org.forgerock.opendj.ldap.requests.ModifyRequest;
|
import org.forgerock.opendj.ldap.requests.Requests;
|
import org.forgerock.opendj.ldap.requests.SearchRequest;
|
import org.opends.server.TestCaseUtils;
|
import org.opends.server.tools.RemoteConnection;
|
import org.opends.server.types.Control;
|
import org.opends.server.types.LDAPException;
|
import org.testng.annotations.BeforeClass;
|
import org.testng.annotations.Test;
|
|
/**
|
* 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(true,
|
"dn: cn=LDAP Connection Handler,cn=Connection Handlers,cn=config",
|
"changetype: modify",
|
"replace: ds-cfg-allow-ldap-v2",
|
"ds-cfg-allow-ldap-v2: false");
|
|
try (RemoteConnection conn = new RemoteConnection("127.0.0.1", TestCaseUtils.getServerLdapPort()))
|
{
|
bindLdapV2(conn, "cn=Directory Manager", "password", LDAPResultCode.PROTOCOL_ERROR);
|
}
|
finally
|
{
|
TestCaseUtils.applyModifications(true,
|
"dn: cn=LDAP Connection Handler,cn=Connection Handlers,cn=config",
|
"changetype: modify",
|
"replace: ds-cfg-allow-ldap-v2",
|
"ds-cfg-allow-ldap-v2: true");
|
}
|
}
|
|
|
|
/**
|
* Tests to ensure that the server will reject an extended request from an
|
* LDAPv2 client.
|
*
|
* @throws Exception If an unexpected problem occurs.
|
*/
|
@Test(expectedExceptions = EOFException.class)
|
public void testRejectExtendedRequest() throws Exception
|
{
|
try (RemoteConnection conn = new RemoteConnection("127.0.0.1", TestCaseUtils.getServerLdapPort()))
|
{
|
bindLdapV2(conn, "cn=Directory Manager", "password");
|
conn.writeMessage(new ExtendedRequestProtocolOp(OID_START_TLS_REQUEST));
|
conn.readMessage();
|
}
|
}
|
|
|
|
/**
|
* 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
|
{
|
try (RemoteConnection conn = new RemoteConnection("127.0.0.1", TestCaseUtils.getServerLdapPort()))
|
{
|
bindLdapV2(conn, "cn=Directory Manager", "password");
|
|
AddRequest addRequest = Requests.newAddRequest("ou=People,o=test")
|
.addAttribute("objectClass", "organizationalUnit")
|
.addAttribute("ou", "People")
|
.addControl(newControl(OID_MANAGE_DSAIT_CONTROL, true));
|
|
LDAPMessage message = conn.add(addRequest, false);
|
AddResponseProtocolOp addResponse = message.getAddResponseProtocolOp();
|
assertEquals(addResponse.getResultCode(), LDAPResultCode.PROTOCOL_ERROR);
|
}
|
}
|
|
private void bindLdapV2(RemoteConnection conn, String bindDN, String bindPwd) throws IOException, LDAPException
|
{
|
bindLdapV2(conn, bindDN, bindPwd, LDAPResultCode.SUCCESS);
|
}
|
|
private void bindLdapV2(RemoteConnection conn, String bindDN, String bindPwd, int expectedRC, Control... controls)
|
throws IOException, LDAPException
|
{
|
conn.writeMessage(new BindRequestProtocolOp(ByteString.valueOfUtf8(bindDN), 2, ByteString.valueOfUtf8(bindPwd)),
|
Arrays.asList(controls));
|
|
LDAPMessage message = conn.readMessage();
|
BindResponseProtocolOp bindResponse = message.getBindResponseProtocolOp();
|
assertEquals(bindResponse.getResultCode(), expectedRC);
|
}
|
|
/**
|
* 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
|
{
|
try (RemoteConnection conn = new RemoteConnection("127.0.0.1", TestCaseUtils.getServerLdapPort()))
|
{
|
bindLdapV2(conn, "cn=Directory Manager", "password",
|
LDAPResultCode.PROTOCOL_ERROR, new LDAPControl(OID_MANAGE_DSAIT_CONTROL, true));
|
}
|
}
|
|
/**
|
* 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
|
{
|
try (RemoteConnection conn = new RemoteConnection("127.0.0.1", TestCaseUtils.getServerLdapPort()))
|
{
|
bindLdapV2(conn, "cn=Directory Manager", "password");
|
|
CompareRequest compareRequest = newCompareRequest("o=test", "o", "test")
|
.addControl(newControl(OID_MANAGE_DSAIT_CONTROL, true));
|
LDAPMessage message = conn.compare(compareRequest, false);
|
CompareResponseProtocolOp compareResponse = message.getCompareResponseProtocolOp();
|
assertEquals(compareResponse.getResultCode(), LDAPResultCode.PROTOCOL_ERROR);
|
}
|
}
|
|
|
|
/**
|
* 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
|
{
|
try (RemoteConnection conn = new RemoteConnection("127.0.0.1", TestCaseUtils.getServerLdapPort()))
|
{
|
bindLdapV2(conn, "cn=Directory Manager", "password");
|
|
DeleteRequest deleteRequest = newDeleteRequest("o=test")
|
.addControl(newControl(OID_MANAGE_DSAIT_CONTROL, true));
|
LDAPMessage message = conn.delete(deleteRequest, false);
|
DeleteResponseProtocolOp deleteResponse = message.getDeleteResponseProtocolOp();
|
assertEquals(deleteResponse.getResultCode(), LDAPResultCode.PROTOCOL_ERROR);
|
}
|
}
|
|
|
|
/**
|
* 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
|
{
|
try (RemoteConnection conn = new RemoteConnection("127.0.0.1", TestCaseUtils.getServerLdapPort()))
|
{
|
bindLdapV2(conn, "cn=Directory Manager", "password");
|
|
ModifyRequest modifyRequest = newModifyRequest("o=test")
|
.addModification(REPLACE, "description", "foo")
|
.addControl(newControl(OID_MANAGE_DSAIT_CONTROL, true));
|
LDAPMessage message = conn.modify(modifyRequest, false);
|
ModifyResponseProtocolOp modifyResponse = message.getModifyResponseProtocolOp();
|
assertEquals(modifyResponse.getResultCode(), LDAPResultCode.PROTOCOL_ERROR);
|
}
|
}
|
|
|
|
/**
|
* 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
|
{
|
try (RemoteConnection conn = new RemoteConnection("127.0.0.1", TestCaseUtils.getServerLdapPort()))
|
{
|
bindLdapV2(conn, "cn=Directory Manager", "password");
|
|
ModifyDNRequest modifyDNRequest = newModifyDNRequest("o=test", "cn=test")
|
.addControl(newControl(OID_MANAGE_DSAIT_CONTROL, true));
|
LDAPMessage message = conn.modifyDN(modifyDNRequest, false);
|
ModifyDNResponseProtocolOp modifyDNResponse = message.getModifyDNResponseProtocolOp();
|
assertEquals(modifyDNResponse.getResultCode(), LDAPResultCode.PROTOCOL_ERROR);
|
}
|
}
|
|
|
|
/**
|
* 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
|
{
|
try (RemoteConnection conn = new RemoteConnection("127.0.0.1", TestCaseUtils.getServerLdapPort()))
|
{
|
bindLdapV2(conn, "cn=Directory Manager", "password");
|
|
SearchRequest searchRequest = newSearchRequest(DN.rootDN(), BASE_OBJECT, Filter.objectClassPresent())
|
.addControl(newControl(OID_MANAGE_DSAIT_CONTROL, true));
|
conn.search(searchRequest);
|
LDAPMessage message = conn.readMessage();
|
SearchResultDoneProtocolOp searchDone = message.getSearchResultDoneProtocolOp();
|
assertEquals(searchDone.getResultCode(), LDAPResultCode.PROTOCOL_ERROR);
|
}
|
}
|
}
|