TestModifyDNOperation.java revision 4f6891a8bd4d017a41b5f75748398ff59787501c
/*
* 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 legal-notices/CDDLv1_0.txt
* or http://forgerock.org/license/CDDLv1.0.html.
* 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 legal-notices/CDDLv1_0.txt.
* 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 2006-2010 Sun Microsystems, Inc.
* Portions Copyright 2011-2015 ForgeRock AS.
* Portions copyright 2013 Manuel Gaupp
*/
package org.opends.server.core;
import java.net.Socket;
import java.util.Collections;
import java.util.Hashtable;
import java.util.List;
import javax.naming.Context;
import javax.naming.InvalidNameException;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.opendj.ldap.ResultCode;
import org.opends.server.TestCaseUtils;
import org.opends.server.api.ClientConnection;
import org.opends.server.controls.ProxiedAuthV1Control;
import org.opends.server.controls.ProxiedAuthV2Control;
import org.opends.server.plugins.InvocationCounterPlugin;
import org.opends.server.plugins.ShortCircuitPlugin;
import org.opends.server.protocols.internal.InternalClientConnection;
import org.opends.server.protocols.ldap.*;
import org.opends.server.tools.LDAPModify;
import org.opends.server.tools.LDAPWriter;
import org.opends.server.types.*;
import org.opends.server.types.LockManager.DNLock;
import org.opends.server.util.ServerConstants;
import org.opends.server.util.StaticUtils;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import static org.testng.Assert.*;
@SuppressWarnings("javadoc")
public class TestModifyDNOperation extends OperationTestCase
{
private Entry entry;
private InternalClientConnection proxyUserConn;
@BeforeClass
public void setUp() throws Exception
{
TestCaseUtils.startServer();
TestCaseUtils.initializeTestBackend(true);
TestCaseUtils.clearJEBackend("userRoot");
// Add the example.com entry
TestCaseUtils.addEntry(
"dn: dc=example,dc=com",
"objectclass: top",
"objectclass: domain",
"dc: example",
"aci: (targetattr=\"*\")(version 3.0; acl \"Proxy Rights\"; " +
"allow(proxy) userdn=\"ldap:///uid=proxy.user,o=test\";)"
);
// Add the people entry
TestCaseUtils.addEntry(
"dn: ou=People,dc=example,dc=com",
"objectclass: top",
"objectclass: organizationalUnit",
"ou: People"
);
// Add a test entry.
entry = TestCaseUtils.addEntry(
"dn: uid=user.0,ou=People,dc=example,dc=com",
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"givenName: Aaccf",
"sn: Amar",
"cn: Aaccf Amar",
"initials: AQA",
"employeeNumber: 0",
"uid: user.0",
"mail: user.0@example.com",
"userPassword: password",
"telephoneNumber: 380-535-2354",
"homePhone: 707-626-3913",
"pager: 456-345-7750",
"mobile: 366-674-7274",
"street: 99262 Eleventh Street",
"l: Salem",
"st: NM",
"postalCode: 36530",
"postalAddress: Aaccf Amar$99262 Eleventh Street$Salem, NM 36530",
"description: This is the description for Aaccf Amar."
);
// Add a user capable of using the proxied authorization control.
TestCaseUtils.addEntry(
"dn: uid=proxy.user,o=test",
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: proxy.user",
"givenName: Proxy",
"sn: User",
"cn: Proxy User",
"userPassword: password",
"ds-privilege-name: bypass-acl",
"ds-privilege-name: proxied-auth");
proxyUserConn =
new InternalClientConnection(DN.valueOf("uid=proxy.user,o=test"));
}
/**
* Invokes a number of operation methods on the provided modify operation
* for which all processing has been completed. This method is used for
* tests that bypass the referential integrity plugin for whatever reason.
*
* @param modifyDNOperation The operation to be tested.
*/
private void
examineCompletedOPNoExtraPluginCounts(ModifyDNOperation modifyDNOperation)
{
assertTrue(modifyDNOperation.getProcessingStartTime() > 0);
assertTrue(modifyDNOperation.getProcessingStopTime() > 0);
assertTrue(modifyDNOperation.getProcessingTime() >= 0);
// assertEquals(InvocationCounterPlugin.getPreParseCount(), 1);
// assertEquals(InvocationCounterPlugin.getPreOperationCount(), 1);
// assertEquals(InvocationCounterPlugin.getPostOperationCount(), 1);
ensurePostReponseHasRun();
// assertEquals(InvocationCounterPlugin.getPostResponseCount(), 1);
}
/**
* Invokes a number of operation methods on the provided modify operation
* for which all processing has been completed. The counters
* postResponseCount and preParseCount are incremented twice when
* referential integrity plugin is enabled.
*
* @param modifyDNOperation The operation to be tested.
*/
private void examineCompletedOperation(ModifyDNOperation modifyDNOperation)
{
assertTrue(modifyDNOperation.getProcessingStartTime() > 0);
assertTrue(modifyDNOperation.getProcessingStopTime() > 0);
assertTrue(modifyDNOperation.getProcessingTime() >= 0);
// assertEquals(InvocationCounterPlugin.getPreParseCount(), 2);
// assertEquals(InvocationCounterPlugin.getPreOperationCount(), 1);
// assertEquals(InvocationCounterPlugin.getPostOperationCount(), 1);
ensurePostReponseHasRun();
// assertEquals(InvocationCounterPlugin.getPostResponseCount(), 2);
}
/**
* Invokes a number of operation methods on the provided modify operation
* for which the pre-operation plugin was not called.
*
* @param modifyDNOperation The operation to be tested.
*/
private void examineIncompleteOperation(ModifyDNOperation modifyDNOperation,
ResultCode resultCode)
{
assertEquals(modifyDNOperation.getResultCode(), resultCode);
assertTrue(modifyDNOperation.getErrorMessage().length() > 0);
assertTrue(modifyDNOperation.getProcessingStartTime() > 0);
assertTrue(modifyDNOperation.getProcessingStopTime() > 0);
assertTrue(modifyDNOperation.getProcessingTime() >= 0);
assertTrue(modifyDNOperation.getErrorMessage().length() > 0);
// assertEquals(InvocationCounterPlugin.getPreParseCount(), 1);
// assertEquals(InvocationCounterPlugin.getPreOperationCount(), 0);
// assertEquals(InvocationCounterPlugin.getPostOperationCount(), 1);
ensurePostReponseHasRun();
// assertEquals(InvocationCounterPlugin.getPostResponseCount(), 1);
}
/**
* Invokes a number of operation methods on the provided modify operation
* for which an error was found during parsing.
*
* @param modifyDNOperation The operation to be tested.
*/
private void examineUnparsedOperation(ModifyDNOperation modifyDNOperation,
ResultCode resultCode)
{
assertEquals(modifyDNOperation.getResultCode(), resultCode);
assertTrue(modifyDNOperation.getErrorMessage().length() > 0);
assertTrue(modifyDNOperation.getProcessingStartTime() > 0);
assertTrue(modifyDNOperation.getProcessingStopTime() > 0);
assertTrue(modifyDNOperation.getProcessingTime() >= 0);
assertTrue(modifyDNOperation.getErrorMessage().length() > 0);
// assertEquals(InvocationCounterPlugin.getPreParseCount(), 1);
// assertEquals(InvocationCounterPlugin.getPreOperationCount(), 0);
// assertEquals(InvocationCounterPlugin.getPostOperationCount(), 0);
ensurePostReponseHasRun();
// assertEquals(InvocationCounterPlugin.getPostResponseCount(), 1);
}
/** {@inheritDoc} */
@Override
protected Operation[] createTestOperations() throws Exception
{
return new ModifyDNOperationBasis[] {
newModifyDNOperation( ByteString.valueOf("cn=test,ou=test"),
ByteString.valueOf("cn=test2"), true,
ByteString.valueOf("dc=example,dc=com")),
newModifyDNOperation( DN.valueOf("cn=test,ou=test"),
RDN.decode("cn=test2"), true,
DN.valueOf("dc=example,dc=com"))
};
}
private ModifyDNOperationBasis newModifyDNOperation(DN rawEntryDN,
RDN newRDN, boolean deleteOldRDN, DN newSuperior)
{
final ClientConnection conn = InternalClientConnection.getRootConnection();
return new ModifyDNOperationBasis(conn, InternalClientConnection
.nextOperationID(), InternalClientConnection.nextMessageID(),
Collections.<Control> emptyList(), rawEntryDN, newRDN, deleteOldRDN,
newSuperior);
}
private ModifyDNOperationBasis newModifyDNOperation(ByteString rawEntryDN,
ByteString newRDN, boolean deleteOldRDN, ByteString newSuperior)
{
final ClientConnection conn = InternalClientConnection.getRootConnection();
return new ModifyDNOperationBasis(conn, InternalClientConnection
.nextOperationID(), InternalClientConnection.nextMessageID(),
Collections.<Control> emptyList(), rawEntryDN, newRDN, deleteOldRDN,
newSuperior);
}
private void assertSuccessAndEntryExists(ModifyDNOperation modifyDNOperation,
String entryDN, boolean user0Exists, boolean userTest0Exists)
throws DirectoryException
{
assertEquals(modifyDNOperation.getResultCode(), ResultCode.SUCCESS);
assertEquals(modifyDNOperation.getErrorMessage().length(), 0);
final Entry newEntry = DirectoryServer.getEntry(DN.valueOf(entryDN));
assertNotNull(newEntry);
final RDN rdn = newEntry.getName().rdn();
for (int i = 0; i < rdn.getNumValues(); i++)
{
AttributeType attribute = rdn.getAttributeType(i);
assertEquals(newEntry.hasValue(attribute, null, ByteString.valueOf("user.0")), user0Exists);
assertEquals(newEntry.hasValue(attribute, null, ByteString.valueOf("user.test0")), userTest0Exists);
}
}
@Test
public void testRawModify() throws Exception
{
InvocationCounterPlugin.resetAllCounters();
ModifyDNOperation modifyDNOperation = newModifyDNOperation(
ByteString.valueOf("uid=user.0,ou=People,dc=example,dc=com"),
ByteString.valueOf("uid=user.test0"), false,
null);
modifyDNOperation.run();
assertSuccessAndEntryExists(modifyDNOperation,
"uid=user.test0,ou=People,dc=example,dc=com", true, true);
examineCompletedOperation(modifyDNOperation);
InvocationCounterPlugin.resetAllCounters();
modifyDNOperation = newModifyDNOperation(
ByteString.valueOf("uid=user.test0,ou=People,dc=example,dc=com"),
ByteString.valueOf("uid=user.0"), true,
null);
modifyDNOperation.run();
assertSuccessAndEntryExists(modifyDNOperation,
"uid=user.0,ou=People,dc=example,dc=com", true, false);
examineCompletedOperation(modifyDNOperation);
}
@Test
public void testProcessedModify() throws Exception
{
InvocationCounterPlugin.resetAllCounters();
ModifyDNOperation modifyDNOperation = newModifyDNOperation(
DN.valueOf("uid=user.0,ou=People,dc=example,dc=com"),
RDN.decode("uid=user.test0"), false,
null);
modifyDNOperation.run();
assertSuccessAndEntryExists(modifyDNOperation,
"uid=user.test0,ou=People,dc=example,dc=com", true, true);
examineCompletedOperation(modifyDNOperation);
InvocationCounterPlugin.resetAllCounters();
modifyDNOperation = newModifyDNOperation(
DN.valueOf("uid=user.test0,ou=People,dc=example,dc=com"),
RDN.decode("uid=user.0"), true,
null);
modifyDNOperation.run();
assertSuccessAndEntryExists(modifyDNOperation,
"uid=user.0,ou=People,dc=example,dc=com", true, false);
examineCompletedOperation(modifyDNOperation);
}
/**
* Test if it's possible to modify an rdn to a value that matches the current value
* by changing the case of some characters.
*/
@Test
public void testModifySameDN() throws Exception
{
InvocationCounterPlugin.resetAllCounters();
ModifyDNOperation modifyDNOperation = newModifyDNOperation(
DN.valueOf("uid=user.0,ou=People,dc=example,dc=com"),
RDN.decode("uid=USER.0"), true,
null);
modifyDNOperation.run();
assertEquals(modifyDNOperation.getResultCode(),
ResultCode.SUCCESS);
assertEquals(modifyDNOperation.getErrorMessage().length(), 0);
Entry newEntry = DirectoryServer.getEntry(DN.valueOf(
"uid=user.0,ou=People,dc=example,dc=com"));
assertNotNull(newEntry);
assertEquals(newEntry.getName().toString(),
"uid=USER.0,ou=People,dc=example,dc=com");
AttributeType at = DirectoryServer.getAttributeTypeOrNull("uid");
List<Attribute> attrList = newEntry.getAttribute(at);
// There should be only one value for "uid"
assertEquals(attrList.size(),1);
// Because deleteOldRDN is true, the values from RDN and the entry have to be identical
ByteString valueFromEntry = attrList.get(0).iterator().next();
ByteString valueFromRDN = newEntry.getName().rdn().getAttributeValue(at);
assertEquals(valueFromEntry,valueFromRDN);
examineCompletedOperation(modifyDNOperation);
InvocationCounterPlugin.resetAllCounters();
modifyDNOperation = newModifyDNOperation(
DN.valueOf("uid=USER.0,ou=People,dc=example,dc=com"),
RDN.decode("uid=user.0"), true,
null);
modifyDNOperation.run();
assertEquals(modifyDNOperation.getResultCode(),
ResultCode.SUCCESS);
assertEquals(modifyDNOperation.getErrorMessage().length(), 0);
newEntry = DirectoryServer.getEntry(DN.valueOf(
"uid=user.0,ou=People,dc=example,dc=com"));
assertNotNull(newEntry);
examineCompletedOperation(modifyDNOperation);
}
/**
* Add another attribute to the RDN and change case of the existing value.
*/
@Test
public void testModifyDNchangeCaseAndAddValue() throws Exception
{
TestCaseUtils.addEntry(
"dn: uid=userid.0,ou=People,dc=example,dc=com",
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: userid.0",
"givenName: Babs",
"sn: Jensen",
"cn: Babs Jensen");
InvocationCounterPlugin.resetAllCounters();
ModifyDNOperation modifyDNOperation = newModifyDNOperation(
DN.valueOf("uid=userid.0,ou=People,dc=example,dc=com"),
RDN.decode("uid=UserID.0+cn=Test"), false,
null);
modifyDNOperation.run();
assertEquals(modifyDNOperation.getResultCode(),
ResultCode.SUCCESS);
assertEquals(modifyDNOperation.getErrorMessage().length(), 0);
Entry newEntry = DirectoryServer.getEntry(DN.valueOf(
"uid=userid.0+cn=test,ou=People,dc=example,dc=com"));
assertNotNull(newEntry);
assertEquals(newEntry.getName().toString(),
"uid=UserID.0+cn=Test,ou=People,dc=example,dc=com");
AttributeType at = DirectoryServer.getAttributeTypeOrNull("uid");
List<Attribute> attrList = newEntry.getAttribute(at);
// There should be only one value for "uid"
assertEquals(attrList.size(),1);
// Even though the value of the RDN changed, the representation of the entry's value should be preserved
ByteString valueFromEntry = attrList.get(0).iterator().next();
ByteString valueFromRDN = newEntry.getName().rdn().getAttributeValue(at);
assertEquals(valueFromEntry, valueFromRDN);
assertEquals(valueFromEntry, ByteString.valueOf("UserID.0"));
examineCompletedOperation(modifyDNOperation);
TestCaseUtils.deleteEntry(DN.valueOf("uid=UserID.0+cn=Test,ou=People,dc=example,dc=com"));
}
/**
* Add a value to the RDN which is already part of the entry, but with another string representation.
*/
@Test
public void testModifyDNchangeCaseOfExistingEntryValue() throws Exception
{
TestCaseUtils.addEntry(
"dn: uid=userid.0,ou=People,dc=example,dc=com",
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: userid.0",
"givenName: Babs",
"sn: Jensen",
"cn: Babs Jensen");
InvocationCounterPlugin.resetAllCounters();
ModifyDNOperation modifyDNOperation = newModifyDNOperation(
DN.valueOf("uid=userid.0,ou=People,dc=example,dc=com"),
RDN.decode("uid=userid.0+sn=JENSEN"), false,
null);
modifyDNOperation.run();
assertEquals(modifyDNOperation.getResultCode(),
ResultCode.SUCCESS);
assertEquals(modifyDNOperation.getErrorMessage().length(), 0);
Entry newEntry = DirectoryServer.getEntry(DN.valueOf(
"uid=userid.0+sn=jensen,ou=People,dc=example,dc=com"));
assertNotNull(newEntry);
assertEquals(newEntry.getName().toString(),
"uid=userid.0+sn=JENSEN,ou=People,dc=example,dc=com");
AttributeType at = DirectoryServer.getAttributeTypeOrNull("sn");
List<Attribute> attrList = newEntry.getAttribute(at);
// There should be only one value for "sn"
assertEquals(attrList.size(),1);
// Even though the representation of the sn value differs in the RDN,
// the representation of the entry's value should be preserved
ByteString valueFromEntry = attrList.get(0).iterator().next();
ByteString valueFromRDN = newEntry.getName().rdn().getAttributeValue(at);
assertEquals(valueFromEntry, valueFromRDN);
assertEquals(valueFromEntry, ByteString.valueOf("JENSEN"));
examineCompletedOperation(modifyDNOperation);
TestCaseUtils.deleteEntry(DN.valueOf("uid=userid.0+sn=Jensen,ou=People,dc=example,dc=com"));
}
@Test
public void testRawDeleteOldRDNModify() throws Exception
{
InvocationCounterPlugin.resetAllCounters();
ModifyDNOperation modifyDNOperation = newModifyDNOperation(
ByteString.valueOf("uid=user.0,ou=People,dc=example,dc=com"),
ByteString.valueOf("uid=user.test0"), true,
null);
modifyDNOperation.run();
assertSuccessAndEntryExists(modifyDNOperation,
"uid=user.test0,ou=People,dc=example,dc=com", false, true);
examineCompletedOperation(modifyDNOperation);
InvocationCounterPlugin.resetAllCounters();
modifyDNOperation = newModifyDNOperation(
ByteString.valueOf("uid=user.test0,ou=People,dc=example,dc=com"),
ByteString.valueOf("uid=user.0"), true,
null);
modifyDNOperation.run();
assertSuccessAndEntryExists(modifyDNOperation,
"uid=user.0,ou=People,dc=example,dc=com", true, false);
examineCompletedOperation(modifyDNOperation);
}
@Test
public void testProcessedDeleteOldRDNModify() throws Exception
{
InvocationCounterPlugin.resetAllCounters();
ModifyDNOperation modifyDNOperation = newModifyDNOperation(
DN.valueOf("uid=user.0,ou=People,dc=example,dc=com"),
RDN.decode("uid=user.test0"), true,
null);
modifyDNOperation.run();
CancelRequest cancelRequest = new CancelRequest(false,
LocalizableMessage.raw("testCancelBeforeStartup"));
CancelResult cancelResult = modifyDNOperation.cancel(cancelRequest);
assertEquals(cancelResult.getResultCode(), ResultCode.TOO_LATE);
assertSuccessAndEntryExists(modifyDNOperation,
"uid=user.test0,ou=People,dc=example,dc=com", false, true);
examineCompletedOperation(modifyDNOperation);
InvocationCounterPlugin.resetAllCounters();
modifyDNOperation = newModifyDNOperation(
DN.valueOf("uid=user.test0,ou=People,dc=example,dc=com"),
RDN.decode("uid=user.0"), true,
null);
modifyDNOperation.run();
assertSuccessAndEntryExists(modifyDNOperation,
"uid=user.0,ou=People,dc=example,dc=com", true, false);
examineCompletedOperation(modifyDNOperation);
}
@Test
public void testRawNewSuperiorModify() throws Exception
{
InvocationCounterPlugin.resetAllCounters();
ModifyDNOperation modifyDNOperation = newModifyDNOperation(
ByteString.valueOf("uid=user.0,ou=People,dc=example,dc=com"),
ByteString.valueOf("uid=user.test0"), true,
ByteString.valueOf("dc=example,dc=com"));
modifyDNOperation.run();
assertSuccessAndEntryExists(modifyDNOperation,
"uid=user.test0,dc=example,dc=com", false, true);
examineCompletedOPNoExtraPluginCounts(modifyDNOperation);
InvocationCounterPlugin.resetAllCounters();
modifyDNOperation = newModifyDNOperation(
ByteString.valueOf("uid=user.test0,dc=example,dc=com"),
ByteString.valueOf("uid=user.0"), true,
ByteString.valueOf("ou=People,dc=example,dc=com"));
modifyDNOperation.run();
assertSuccessAndEntryExists(modifyDNOperation,
"uid=user.0,ou=People,dc=example,dc=com", true, false);
examineCompletedOPNoExtraPluginCounts(modifyDNOperation);
}
@Test
public void testProcessedNewSuperiorModify() throws Exception
{
InvocationCounterPlugin.resetAllCounters();
ModifyDNOperation modifyDNOperation = newModifyDNOperation(
DN.valueOf("uid=user.0,ou=People,dc=example,dc=com"),
RDN.decode("uid=user.test0"), true,
DN.valueOf("dc=example,dc=com"));
modifyDNOperation.run();
assertSuccessAndEntryExists(modifyDNOperation,
"uid=user.test0,dc=example,dc=com", false, true);
examineCompletedOPNoExtraPluginCounts(modifyDNOperation);
InvocationCounterPlugin.resetAllCounters();
modifyDNOperation = newModifyDNOperation(
DN.valueOf("uid=user.test0,dc=example,dc=com"),
RDN.decode("uid=user.0"), true,
DN.valueOf("ou=People,dc=example,dc=com"));
modifyDNOperation.run();
assertSuccessAndEntryExists(modifyDNOperation,
"uid=user.0,ou=People,dc=example,dc=com", true, false);
examineCompletedOPNoExtraPluginCounts(modifyDNOperation);
}
@Test
public void testRawRDNModify() throws Exception
{
InvocationCounterPlugin.resetAllCounters();
ModifyDNOperation modifyDNOperation = newModifyDNOperation(
DN.valueOf("uid=user.0,ou=People,dc=example,dc=com"),
RDN.decode("cn=Aaccf Amar Test"), true,
DN.valueOf("dc=example,dc=com"));
modifyDNOperation.run();
assertEquals(modifyDNOperation.getResultCode(),
ResultCode.SUCCESS);
assertEquals(modifyDNOperation.getErrorMessage().length(), 0);
Entry newEntry = DirectoryServer.getEntry(DN.valueOf(
"cn=Aaccf Amar Test,dc=example,dc=com"));
assertNotNull(newEntry);
assertNull(DirectoryServer.getEntry(DN.valueOf("uid=user.0,ou=People,dc=example,dc=com")));
assertNull(newEntry.getAttribute("uid"));
for(Attribute attribute : newEntry.getAttribute("cn"))
{
assertTrue(attribute.contains(ByteString.valueOf("Aaccf Amar Test")));
assertTrue(attribute.contains(ByteString.valueOf("Aaccf Amar")));
}
examineCompletedOPNoExtraPluginCounts(modifyDNOperation);
InvocationCounterPlugin.resetAllCounters();
modifyDNOperation = newModifyDNOperation(
DN.valueOf("cn=Aaccf Amar Test,dc=example,dc=com"),
RDN.decode("uid=user.0"), false,
DN.valueOf("ou=People,dc=example,dc=com"));
modifyDNOperation.run();
assertEquals(modifyDNOperation.getResultCode(),
ResultCode.SUCCESS);
assertEquals(modifyDNOperation.getErrorMessage().length(), 0);
Entry newOldEntry = DirectoryServer.getEntry(DN.valueOf(
"uid=user.0,ou=People,dc=example,dc=com"));
assertNotNull(newOldEntry);
assertNull(DirectoryServer.getEntry(DN.valueOf("cn=Aaccf Amar Test,dc=example,dc=com")));
for(Attribute attribute : newOldEntry.getAttribute("cn"))
{
assertTrue(attribute.contains(ByteString.valueOf("Aaccf Amar Test")));
assertTrue(attribute.contains(ByteString.valueOf("Aaccf Amar")));
}
for(Attribute attribute : newOldEntry.getAttribute("uid"))
{
assertTrue(attribute.contains(ByteString.valueOf("user.0")));
}
examineCompletedOPNoExtraPluginCounts(modifyDNOperation);
}
@Test
public void testInvalidEntryModify() throws Exception
{
InvocationCounterPlugin.resetAllCounters();
ModifyDNOperation modifyDNOperation = newModifyDNOperation(
DN.valueOf("uid=user.invalid,ou=People,dc=example,dc=com"),
RDN.decode("uid=user.test0"), true,
DN.valueOf("dc=example,dc=com"));
modifyDNOperation.run();
examineIncompleteOperation(modifyDNOperation, ResultCode.NO_SUCH_OBJECT);
}
@Test
public void testInvalidRDNModify() throws Exception
{
InvocationCounterPlugin.resetAllCounters();
ModifyDNOperation modifyDNOperation = newModifyDNOperation(
DN.valueOf("uid=user.0,ou=People,dc=example,dc=com"),
RDN.decode("invalid=invalid"), true,
DN.valueOf("dc=example,dc=com"));
modifyDNOperation.run();
examineIncompleteOperation(modifyDNOperation,
ResultCode.OBJECTCLASS_VIOLATION);
}
@Test
public void testInvalidSuperiorModify() throws Exception
{
InvocationCounterPlugin.resetAllCounters();
ModifyDNOperation modifyDNOperation = newModifyDNOperation(
DN.valueOf("uid=user.0,ou=People,dc=example,dc=com"),
RDN.decode("uid=user.test0"), true,
DN.valueOf("dc=invalid,dc=com"));
modifyDNOperation.run();
examineIncompleteOperation(modifyDNOperation, ResultCode.NO_SUCH_OBJECT);
}
@Test
public void testRawNoSuchDNModify() throws Exception
{
InvocationCounterPlugin.resetAllCounters();
ModifyDNOperation modifyDNOperation = newModifyDNOperation(
ByteString.valueOf("invalid DN"),
ByteString.valueOf("uid=user.test0"), true,
ByteString.valueOf("dc=example,dc=com"));
modifyDNOperation.run();
examineUnparsedOperation(modifyDNOperation, ResultCode.INVALID_DN_SYNTAX);
}
@Test
public void testRawNoSuchRDNModify() throws Exception
{
InvocationCounterPlugin.resetAllCounters();
ModifyDNOperation modifyDNOperation = newModifyDNOperation(
ByteString.valueOf("uid=user.0,ou=People,dc=example,dc=com"),
ByteString.valueOf("invalid RDN"), true,
ByteString.valueOf("dc=example,dc=com"));
modifyDNOperation.run();
examineUnparsedOperation(modifyDNOperation, ResultCode.INVALID_DN_SYNTAX);
}
@Test
public void testRawInvalidSuperiorModify() throws Exception
{
InvocationCounterPlugin.resetAllCounters();
ModifyDNOperation modifyDNOperation = newModifyDNOperation(
ByteString.valueOf("uid=user.0,ou=People,dc=example,dc=com"),
ByteString.valueOf("uid=user.test0"), true,
ByteString.valueOf("invalid superior"));
modifyDNOperation.run();
examineUnparsedOperation(modifyDNOperation, ResultCode.INVALID_DN_SYNTAX);
}
@Test
public void testModifySuffix() throws Exception
{
InvocationCounterPlugin.resetAllCounters();
ModifyDNOperation modifyDNOperation = newModifyDNOperation(
DN.valueOf("dc=example,dc=com"),
RDN.decode("dc=exampletest"), true,
null);
modifyDNOperation.run();
examineIncompleteOperation(modifyDNOperation,
ResultCode.UNWILLING_TO_PERFORM);
}
@Test
public void testRawProxyAuthV1Modify() throws Exception
{
ProxiedAuthV1Control authV1Control = new ProxiedAuthV1Control(
ByteString.valueOf("cn=Directory Manager,cn=Root DNs,cn=config"));
List<Control> controls = Collections.<Control> singletonList(authV1Control);
InvocationCounterPlugin.resetAllCounters();
ModifyDNOperation modifyDNOperation =
new ModifyDNOperationBasis(proxyUserConn, InternalClientConnection.nextOperationID(),
InternalClientConnection.nextMessageID(), controls,
ByteString.valueOf("uid=user.0,ou=People,dc=example,dc=com"),
ByteString.valueOf("uid=user.test0"), false,
null);
modifyDNOperation.run();
assertSuccessAndEntryExists(modifyDNOperation,
"uid=user.test0,ou=People,dc=example,dc=com", true, true);
examineCompletedOperation(modifyDNOperation);
InvocationCounterPlugin.resetAllCounters();
modifyDNOperation =
new ModifyDNOperationBasis(proxyUserConn, InternalClientConnection.nextOperationID(),
InternalClientConnection.nextMessageID(), controls,
ByteString.valueOf("uid=user.test0,ou=People,dc=example,dc=com"),
ByteString.valueOf("uid=user.0"), true,
null);
modifyDNOperation.run();
assertSuccessAndEntryExists(modifyDNOperation,
"uid=user.0,ou=People,dc=example,dc=com", true, false);
examineCompletedOperation(modifyDNOperation);
}
@Test
public void testProcessedProxyAuthV1Modify() throws Exception
{
ProxiedAuthV1Control authV1Control = new ProxiedAuthV1Control(ByteString.valueOf(
"cn=Directory Manager,cn=Root DNs,cn=config"));
List<Control> controls = Collections.<Control> singletonList(authV1Control);
InvocationCounterPlugin.resetAllCounters();
ModifyDNOperation modifyDNOperation =
new ModifyDNOperationBasis(proxyUserConn, InternalClientConnection.nextOperationID(),
InternalClientConnection.nextMessageID(), controls,
DN.valueOf("uid=user.0,ou=People,dc=example,dc=com"),
RDN.decode("uid=user.test0"), false,
null);
modifyDNOperation.run();
assertSuccessAndEntryExists(modifyDNOperation,
"uid=user.test0,ou=People,dc=example,dc=com", true, true);
examineCompletedOperation(modifyDNOperation);
InvocationCounterPlugin.resetAllCounters();
modifyDNOperation =
new ModifyDNOperationBasis(proxyUserConn, InternalClientConnection.nextOperationID(),
InternalClientConnection.nextMessageID(),
controls,
DN.valueOf("uid=user.test0,ou=People,dc=example,dc=com"),
RDN.decode("uid=user.0"), true,
null);
modifyDNOperation.run();
assertSuccessAndEntryExists(modifyDNOperation,
"uid=user.0,ou=People,dc=example,dc=com", true, false);
examineCompletedOperation(modifyDNOperation);
}
@Test
public void testProcessedProxyAuthV1DeniedModify() throws Exception
{
ProxiedAuthV1Control authV1Control =
new ProxiedAuthV1Control(ByteString.valueOf("cn=nonexistent,o=test"));
List<Control> controls = Collections.<Control> singletonList(authV1Control);
InvocationCounterPlugin.resetAllCounters();
ModifyDNOperation modifyDNOperation =
new ModifyDNOperationBasis(proxyUserConn, InternalClientConnection.nextOperationID(),
InternalClientConnection.nextMessageID(), controls,
DN.valueOf("uid=user.0,ou=People,dc=example,dc=com"),
RDN.decode("uid=user.test0"), false,
null);
modifyDNOperation.run();
examineIncompleteOperation(modifyDNOperation,
ResultCode.AUTHORIZATION_DENIED);
}
@Test
public void testProcessedProxyAuthV2Modify() throws Exception
{
ProxiedAuthV2Control authV2Control =
new ProxiedAuthV2Control(ByteString.valueOf(
"dn:cn=Directory Manager,cn=Root DNs,cn=config"));
List<Control> controls = Collections.<Control> singletonList(authV2Control);
InvocationCounterPlugin.resetAllCounters();
ModifyDNOperation modifyDNOperation =
new ModifyDNOperationBasis(proxyUserConn, InternalClientConnection.nextOperationID(),
InternalClientConnection.nextMessageID(), controls,
DN.valueOf("uid=user.0,ou=People,dc=example,dc=com"),
RDN.decode("uid=user.test0"), false,
null);
modifyDNOperation.run();
assertSuccessAndEntryExists(modifyDNOperation,
"uid=user.test0,ou=People,dc=example,dc=com", true, true);
examineCompletedOperation(modifyDNOperation);
InvocationCounterPlugin.resetAllCounters();
modifyDNOperation =
new ModifyDNOperationBasis(proxyUserConn, InternalClientConnection.nextOperationID(),
InternalClientConnection.nextMessageID(), controls,
DN.valueOf("uid=user.test0,ou=People,dc=example,dc=com"),
RDN.decode("uid=user.0"), true,
null);
modifyDNOperation.run();
assertSuccessAndEntryExists(modifyDNOperation,
"uid=user.0,ou=People,dc=example,dc=com", true, false);
examineCompletedOperation(modifyDNOperation);
}
@Test
public void testProcessedProxyAuthV2DeniedModify() throws Exception
{
ProxiedAuthV2Control authV2Control = new ProxiedAuthV2Control(
ByteString.valueOf("dn:cn=nonexistent,o=test"));
List<Control> controls = Collections.<Control> singletonList(authV2Control);
InvocationCounterPlugin.resetAllCounters();
ModifyDNOperation modifyDNOperation =
new ModifyDNOperationBasis(proxyUserConn, InternalClientConnection.nextOperationID(),
InternalClientConnection.nextMessageID(), controls,
DN.valueOf("uid=user.0,ou=People,dc=example,dc=com"),
RDN.decode("uid=user.test0"), false,
null);
modifyDNOperation.run();
examineIncompleteOperation(modifyDNOperation,
ResultCode.AUTHORIZATION_DENIED);
}
@Test
public void testProcessedProxyAuthV2CriticalityModify() throws Exception
{
Control authV2Control =
new LDAPControl(ServerConstants.OID_PROXIED_AUTH_V2, false,
ByteString.valueOf("dn:cn=nonexistent,o=test"));
List<Control> controls = Collections.<Control> singletonList(authV2Control);
InvocationCounterPlugin.resetAllCounters();
ModifyDNOperation modifyDNOperation =
new ModifyDNOperationBasis(proxyUserConn, InternalClientConnection.nextOperationID(),
InternalClientConnection.nextMessageID(), controls,
DN.valueOf("uid=user.0,ou=People,dc=example,dc=com"),
RDN.decode("uid=user.test0"), false,
null);
modifyDNOperation.run();
examineIncompleteOperation(modifyDNOperation, ResultCode.PROTOCOL_ERROR);
}
@Test
public void testProcessedUnsupportedControlModify() throws Exception
{
LDAPControl assertControl =
new LDAPControl("1.1.1.1.1.1", true);
List<Control> controls = Collections.<Control> singletonList(assertControl);
InvocationCounterPlugin.resetAllCounters();
InternalClientConnection conn =
InternalClientConnection.getRootConnection();
ModifyDNOperation modifyDNOperation =
new ModifyDNOperationBasis(conn, InternalClientConnection.nextOperationID(), InternalClientConnection.nextMessageID(),
controls,
DN.valueOf("uid=user.0,ou=People,dc=example,dc=com"),
RDN.decode("uid=user.test0"), false,
null);
modifyDNOperation.run();
examineIncompleteOperation(modifyDNOperation,
ResultCode.UNAVAILABLE_CRITICAL_EXTENSION);
}
@Test
public void testShortCircuitModify() throws Exception
{
// Since we are going to be watching the post-response count, we need to
// wait for the server to become idle before kicking off the next request to
// ensure that any remaining post-response processing from the previous
// operation has completed.
assertTrue(DirectoryServer.getWorkQueue().waitUntilIdle(10000));
// Establish a connection to the server.
Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
InvocationCounterPlugin.resetAllCounters();
org.opends.server.tools.LDAPReader r = new org.opends.server.tools.LDAPReader(s);
LDAPWriter w = new LDAPWriter(s);
TestCaseUtils.configureSocket(s);
BindRequestProtocolOp bindRequest =
new BindRequestProtocolOp(
ByteString.valueOf("cn=Directory Manager"),
3, ByteString.valueOf("password"));
LDAPMessage bindMessage = new LDAPMessage(1, bindRequest);
w.writeMessage(bindMessage);
bindMessage = r.readMessage();
BindResponseProtocolOp bindResponse = bindMessage.getBindResponseProtocolOp();
assertEquals(bindResponse.getResultCode(), LDAPResultCode.SUCCESS);
assertTrue(DirectoryServer.getWorkQueue().waitUntilIdle(10000));
InvocationCounterPlugin.resetAllCounters();
ModifyDNRequestProtocolOp modifyRequest =
new ModifyDNRequestProtocolOp(
ByteString.valueOf(entry.getName().toString()),
ByteString.valueOf("uid=user.test0"), false);
LDAPMessage message = new LDAPMessage(2, modifyRequest,
ShortCircuitPlugin.createShortCircuitControlList(80, "PreOperation"));
w.writeMessage(message);
message = r.readMessage();
ModifyDNResponseProtocolOp modifyResponse =
message.getModifyDNResponseProtocolOp();
assertEquals(modifyResponse.getResultCode(), 80);
// assertEquals(InvocationCounterPlugin.waitForPostResponse(), 1);
StaticUtils.close(s);
}
@Test(groups = "slow")
public void testWriteLockModify() throws Exception
{
// We need the operation to be run in a separate thread because we are going
// to write lock the entry in the test case thread and check that the
// modify DN operation does not proceed.
// Establish a connection to the server.
Socket s = new Socket("127.0.0.1", TestCaseUtils.getServerLdapPort());
try
{
org.opends.server.tools.LDAPReader r = new org.opends.server.tools.LDAPReader(s);
LDAPWriter w = new LDAPWriter(s);
TestCaseUtils.configureSocket(s);
BindRequestProtocolOp bindRequest =
new BindRequestProtocolOp(
ByteString.valueOf("cn=Directory Manager"),
3, ByteString.valueOf("password"));
LDAPMessage message = new LDAPMessage(1, bindRequest);
w.writeMessage(message);
message = r.readMessage();
BindResponseProtocolOp bindResponse = message.getBindResponseProtocolOp();
assertEquals(bindResponse.getResultCode(), LDAPResultCode.SUCCESS);
// Since we are going to be watching the post-response count, we need to
// wait for the server to become idle before kicking off the next request
// to ensure that any remaining post-response processing from the previous
// operation has completed.
assertTrue(DirectoryServer.getWorkQueue().waitUntilIdle(10000));
final DNLock writeLock = DirectoryServer.getLockManager().tryWriteLockEntry(entry.getName());
assertNotNull(writeLock);
try
{
InvocationCounterPlugin.resetAllCounters();
//long modifyDNRequests = ldapStatistics.getModifyDNRequests();
//long modifyDNResponses = ldapStatistics.getModifyDNResponses();
ModifyDNRequestProtocolOp modifyRequest =
new ModifyDNRequestProtocolOp(
ByteString.valueOf(entry.getName().toString()),
ByteString.valueOf("uid=user.test0"), false);
message = new LDAPMessage(2, modifyRequest);
w.writeMessage(message);
message = r.readMessage();
ModifyDNResponseProtocolOp modifyResponse =
message.getModifyDNResponseProtocolOp();
assertEquals(modifyResponse.getResultCode(), LDAPResultCode.BUSY);
// assertEquals(InvocationCounterPlugin.getPreParseCount(), 1);
// assertEquals(InvocationCounterPlugin.getPreOperationCount(), 0);
// assertEquals(InvocationCounterPlugin.getPostOperationCount(), 0);
// // The post response might not have been called yet.
// assertEquals(InvocationCounterPlugin.waitForPostResponse(), 1);
// assertEquals(ldapStatistics.getModifyDNRequests(), modifyDNRequests+1);
// assertEquals(ldapStatistics.getModifyDNResponses(),
// modifyDNResponses+1);
} finally
{
writeLock.unlock();
}
} finally
{
StaticUtils.close(s);
}
}
/**
* Tests performing a modify DN operation in which the new RDN contains an
* attribute type marked OBSOLETE in the server schema.
*/
@Test
public void testModifyDNWithObsoleteAttribute()
throws Exception
{
TestCaseUtils.initializeTestBackend(true);
String path = TestCaseUtils.createTempFile(
"dn: cn=schema",
"changetype: modify",
"add: attributeTypes",
"attributeTypes: ( testmodifydnwithobsoleteattribute-oid " +
"NAME 'testModifyDNWithObsoleteAttribute' OBSOLETE " +
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE " +
"X-ORGIN 'SchemaBackendTestCase' )");
String attrName = "testmodifydnwithobsoleteattribute";
assertFalse(DirectoryServer.getSchema().hasAttributeType(attrName));
String[] args =
{
"-h", "127.0.0.1",
"-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
"-D", "cn=Directory Manager",
"-w", "password",
"-f", path
};
assertEquals(LDAPModify.mainModify(args, false, null, System.err), 0);
assertTrue(DirectoryServer.getSchema().hasAttributeType(attrName));
path = TestCaseUtils.createTempFile(
"dn: cn=oldrdn,o=test",
"changetype: add",
"objectClass: top",
"objectClass: device",
"objectClass: extensibleObject",
"cn: oldrdn",
"",
"dn: cn=oldrdn,o=test",
"changetype: moddn",
"newRDN: testModifyDNWithObsoleteAttribute=foo",
"deleteOldRDN: 0"
);
args = new String[]
{
"-h", "127.0.0.1",
"-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
"-D", "cn=Directory Manager",
"-w", "password",
"-f", path
};
assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
}
/**
* Tests a subtree rename operation to ensure that subordinate modify DN
* plugins will be invoked as expected.
*/
@Test
public void testSubordinateModifyDNPluginsForSubtreeRename()
throws Exception
{
try
{
InvocationCounterPlugin.resetAllCounters();
TestCaseUtils.clearJEBackend("userRoot", "dc=example,dc=com");
TestCaseUtils.addEntries(
"dn: ou=People,dc=example,dc=com",
"objectClass: top",
"objectClass: organizationalUnit",
"ou: People",
"",
"dn: uid=first.test,ou=People,dc=example,dc=com",
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: first.test",
"givenName: First",
"sn: Test",
"cn: First Test",
"userPassword: Password",
"ou: People",
"",
"dn: uid=second.test,ou=People,dc=example,dc=com",
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: second.test",
"givenName: Second",
"sn: Test",
"cn: Second Test",
"userPassword: Password");
assertTrue(DirectoryServer.entryExists(
DN.valueOf("uid=first.test,ou=People,dc=example,dc=com")));
assertFalse(DirectoryServer.entryExists(
DN.valueOf("uid=first.test,ou=Users,dc=example,dc=com")));
InternalClientConnection conn =
InternalClientConnection.getRootConnection();
ModifyDNOperation modifyDNOperation =
conn.processModifyDN("ou=People,dc=example,dc=com", "ou=Users",
true);
assertEquals(modifyDNOperation.getResultCode(), ResultCode.SUCCESS);
// assertEquals(InvocationCounterPlugin.getSubordinateModifyDNCount(), 2);
assertFalse(DirectoryServer.entryExists(
DN.valueOf("uid=first.test,ou=People,dc=example,dc=com")));
assertTrue(DirectoryServer.entryExists(
DN.valueOf("uid=first.test,ou=Users,dc=example,dc=com")));
}
finally
{
// Other tests in this class rely on a predefined structure, so we need to
// make sure to put it back to the way it should be.
setUp();
InvocationCounterPlugin.resetAllCounters();
}
}
/**
* Tests a subtree move operation to ensure that subordinate modify DN
* plugins will be invoked as expected.
*/
@Test
public void testSubordinateModifyDNPluginsForSubtreeMove()
throws Exception
{
try
{
InvocationCounterPlugin.resetAllCounters();
TestCaseUtils.clearJEBackend("userRoot", "dc=example,dc=com");
TestCaseUtils.addEntries(
"dn: ou=Org 1,dc=example,dc=com",
"objectClass: top",
"objectClass: organizationalUnit",
"ou: Org 1",
"",
"dn: ou=Org 2,dc=example,dc=com",
"objectClass: top",
"objectClass: organizationalUnit",
"ou: Org 2",
"",
"dn: ou=Org 1.1,ou=Org 1,dc=example,dc=com",
"objectClass: top",
"objectClass: organizationalUnit",
"ou: Org 1.1",
"",
"dn: uid=first.test,ou=Org 1.1,ou=Org 1,dc=example,dc=com",
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: first.test",
"givenName: First",
"sn: Test",
"cn: First Test",
"userPassword: Password",
"ou: Org 1.1",
"",
"dn: uid=second.test,ou=Org 1.1,ou=Org 1,dc=example,dc=com",
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: second.test",
"givenName: Second",
"sn: Test",
"cn: Second Test",
"userPassword: Password");
assertTrue(DirectoryServer.entryExists(
DN.valueOf("uid=first.test,ou=Org 1.1,ou=Org 1,dc=example,dc=com")));
assertFalse(DirectoryServer.entryExists(
DN.valueOf("uid=first.test,ou=Org 2.1,ou=Org 2,dc=example,dc=com")));
InternalClientConnection conn =
InternalClientConnection.getRootConnection();
ModifyDNOperation modifyDNOperation =
conn.processModifyDN("ou=Org 1.1,ou=Org 1,dc=example,dc=com",
"ou=Org 2.1", true,
"ou=Org 2,dc=example,dc=com");
assertEquals(modifyDNOperation.getResultCode(), ResultCode.SUCCESS);
// assertEquals(InvocationCounterPlugin.getSubordinateModifyDNCount(), 2);
assertFalse(DirectoryServer.entryExists(
DN.valueOf("uid=first.test,ou=Org 1.1,ou=Org 1,dc=example,dc=com")));
assertTrue(DirectoryServer.entryExists(
DN.valueOf("uid=first.test,ou=Org 2.1,ou=Org 2,dc=example,dc=com")));
}
finally
{
// Other tests in this class rely on a predefined structure, so we need to
// make sure to put it back to the way it should be.
setUp();
InvocationCounterPlugin.resetAllCounters();
}
}
@Test
public void testCancelBeforeStartup() throws Exception
{
InvocationCounterPlugin.resetAllCounters();
ModifyDNOperation modifyDNOperation = newModifyDNOperation(
DN.valueOf("uid=user.invalid,ou=People,dc=example,dc=com"),
RDN.decode("uid=user.test0"), true,
DN.valueOf("dc=example,dc=com"));
CancelRequest cancelRequest = new CancelRequest(false,
LocalizableMessage.raw("testCancelBeforeStartup"));
modifyDNOperation.abort(cancelRequest);
modifyDNOperation.run();
assertEquals(modifyDNOperation.getResultCode(), ResultCode.CANCELLED);
}
/**
* Tests whether an invalid rdn is allowed during an modrdn operation.
* This test uses a valid attribute type with an empty value.
*
* @throws Exception
*/
@Test(expectedExceptions=InvalidNameException.class)
public void testInvalidModRDN() throws Exception
{
Hashtable<String,String> env = new Hashtable<>();
env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory");
String url = "ldap://localhost:" + TestCaseUtils.getServerLdapPort()
+"/dc=example,dc=com";
env.put(Context.PROVIDER_URL,url);
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, "cn=directory manager");
env.put(Context.SECURITY_CREDENTIALS, "password");
env.put("java.naming.ldap.deleteRDN", "true"); // default is 'true'
/* Create the initial context */
DirContext ctx = new InitialDirContext(env);
try
{
ctx.rename("uid=user.0,ou=People,dc=example,dc=com",
"uid=,ou=People,dc=example,dc=com");
}
finally
{
/* Close the context when it's done */
ctx.close();
}
}
}