From ff9755c40feeaf5a3208229d48b80b608ab7a68c Mon Sep 17 00:00:00 2001
From: jarnou <jarnou@localhost>
Date: Tue, 17 Jul 2007 08:14:43 +0000
Subject: [PATCH] This fix is the refactoring of the modrdn operation [issue 1180]
---
opends/src/server/org/opends/server/core/ModifyDNOperation.java | 2046 +---------------------------------------------------------
1 files changed, 36 insertions(+), 2,010 deletions(-)
diff --git a/opends/src/server/org/opends/server/core/ModifyDNOperation.java b/opends/src/server/org/opends/server/core/ModifyDNOperation.java
index 80db37b..d7b6e3b 100644
--- a/opends/src/server/org/opends/server/core/ModifyDNOperation.java
+++ b/opends/src/server/org/opends/server/core/ModifyDNOperation.java
@@ -26,231 +26,20 @@
*/
package org.opends.server.core;
-
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.LinkedHashSet;
-import java.util.LinkedList;
import java.util.List;
-import java.util.concurrent.locks.Lock;
-
-import org.opends.server.api.Backend;
-import org.opends.server.api.ChangeNotificationListener;
-import org.opends.server.api.ClientConnection;
-import org.opends.server.api.SynchronizationProvider;
-import org.opends.server.api.plugin.PostOperationPluginResult;
-import org.opends.server.api.plugin.PreOperationPluginResult;
-import org.opends.server.api.plugin.PreParsePluginResult;
-import org.opends.server.controls.LDAPAssertionRequestControl;
-import org.opends.server.controls.LDAPPreReadRequestControl;
-import org.opends.server.controls.LDAPPreReadResponseControl;
-import org.opends.server.controls.LDAPPostReadRequestControl;
-import org.opends.server.controls.LDAPPostReadResponseControl;
-import org.opends.server.controls.ProxiedAuthV1Control;
-import org.opends.server.controls.ProxiedAuthV2Control;
-import org.opends.server.protocols.asn1.ASN1OctetString;
-import org.opends.server.types.AbstractOperation;
-import org.opends.server.types.Attribute;
-import org.opends.server.types.AttributeType;
-import org.opends.server.types.AttributeValue;
import org.opends.server.types.ByteString;
-import org.opends.server.types.CancelledOperationException;
-import org.opends.server.types.CancelRequest;
-import org.opends.server.types.CancelResult;
-import org.opends.server.types.Control;
-import org.opends.server.types.DirectoryException;
-import org.opends.server.types.DisconnectReason;
import org.opends.server.types.DN;
import org.opends.server.types.Entry;
-import org.opends.server.types.ErrorLogCategory;
-import org.opends.server.types.ErrorLogSeverity;
-import org.opends.server.types.LDAPException;
-import org.opends.server.types.LockManager;
import org.opends.server.types.Modification;
-import org.opends.server.types.ModificationType;
-import org.opends.server.types.OperationType;
-import org.opends.server.types.Privilege;
+import org.opends.server.types.Operation;
import org.opends.server.types.RDN;
-import org.opends.server.types.ResultCode;
-import org.opends.server.types.SearchFilter;
-import org.opends.server.types.SearchResultEntry;
-import org.opends.server.types.SynchronizationProviderResult;
-import org.opends.server.types.operation.PostOperationModifyDNOperation;
-import org.opends.server.types.operation.PostResponseModifyDNOperation;
-import org.opends.server.types.operation.PreOperationModifyDNOperation;
-import org.opends.server.types.operation.PreParseModifyDNOperation;
-
-import static org.opends.server.core.CoreConstants.*;
-import static org.opends.server.loggers.AccessLogger.*;
-import org.opends.server.types.DebugLogLevel;
-import static org.opends.server.loggers.ErrorLogger.*;
-import static org.opends.server.loggers.debug.DebugLogger.*;
-
-import org.opends.server.loggers.debug.DebugLogger;
-import org.opends.server.loggers.debug.DebugTracer;
-import static org.opends.server.messages.CoreMessages.*;
-import static org.opends.server.messages.MessageHandler.*;
-import static org.opends.server.util.ServerConstants.*;
-import static org.opends.server.util.StaticUtils.*;
-
-
/**
- * This class defines an operation that may be used to alter the DN of an entry
- * in the Directory Server.
+ * This interface defines an operation used to move an entry in
+ * the Directory Server.
*/
-public class ModifyDNOperation
- extends AbstractOperation
- implements PreParseModifyDNOperation, PreOperationModifyDNOperation,
- PostOperationModifyDNOperation, PostResponseModifyDNOperation
+public interface ModifyDNOperation extends Operation
{
- /**
- * The tracer object for the debug logger.
- */
- private static final DebugTracer TRACER = DebugLogger.getTracer();
-
- // Indicates whether to delete the old RDN value from the entry.
- private boolean deleteOldRDN;
-
- // The raw, unprocessed current DN of the entry as included in the request
- // from the client.
- private ByteString rawEntryDN;
-
- // The raw, unprocessed newRDN as included in the request from the client.
- private ByteString rawNewRDN;
-
- // The raw, unprocessed newSuperior as included in the request from the
- // client.
- private ByteString rawNewSuperior;
-
- // The cancel request issued for this modify DN operation.
- private CancelRequest cancelRequest;
-
- // The current DN of the entry.
- private DN entryDN;
-
- // The new parent for the entry.
- private DN newSuperior;
-
- // The proxied authorization target DN for this operation.
- private DN proxiedAuthorizationDN;
-
- // The current entry, before it is renamed.
- private Entry currentEntry;
-
- // The new entry, as it will appear after it has been renamed.
- private Entry newEntry;
-
- // The set of response controls for this modify DN operation.
- private List<Control> responseControls;
-
- // The set of modifications applied to attributes in the entry in the course
- // of processing the modify DN.
- private List<Modification> modifications;
-
- // The change number that has been assigned to this operation.
- private long changeNumber;
-
- // The new RDN for the entry.
- private RDN newRDN;
-
-
-
- /**
- * Creates a new modify DN operation with the provided information.
- *
- * @param clientConnection The client connection with which this operation
- * is associated.
- * @param operationID The operation ID for this operation.
- * @param messageID The message ID of the request with which this
- * operation is associated.
- * @param requestControls The set of controls included in the request.
- * @param rawEntryDN The raw, unprocessed entry DN as included in the
- * client request.
- * @param rawNewRDN The raw, unprocessed newRDN as included in the
- * client request.
- * @param deleteOldRDN Indicates whether to delete the old RDN value
- * from the entry.
- * @param rawNewSuperior The raw, unprocessed newSuperior as included in
- * the client request.
- */
- public ModifyDNOperation(ClientConnection clientConnection, long operationID,
- int messageID, List<Control> requestControls,
- ByteString rawEntryDN, ByteString rawNewRDN,
- boolean deleteOldRDN, ByteString rawNewSuperior)
- {
- super(clientConnection, operationID, messageID, requestControls);
-
-
- this.rawEntryDN = rawEntryDN;
- this.rawNewRDN = rawNewRDN;
- this.deleteOldRDN = deleteOldRDN;
- this.rawNewSuperior = rawNewSuperior;
-
- entryDN = null;
- newRDN = null;
- newSuperior = null;
- responseControls = new ArrayList<Control>();
- cancelRequest = null;
- modifications = null;
- changeNumber = -1;
- currentEntry = null;
- newEntry = null;
- }
-
-
-
- /**
- * Creates a new modify DN operation with the provided information.
- *
- * @param clientConnection The client connection with which this operation
- * is associated.
- * @param operationID The operation ID for this operation.
- * @param messageID The message ID of the request with which this
- * operation is associated.
- * @param requestControls The set of controls included in the request.
- * @param entryDN The current entry DN for this modify DN
- * operation.
- * @param newRDN The new RDN for this modify DN operation.
- * @param deleteOldRDN Indicates whether to delete the old RDN value
- * from the entry.
- * @param newSuperior The newSuperior DN for this modify DN operation.
- */
- public ModifyDNOperation(ClientConnection clientConnection, long operationID,
- int messageID, List<Control> requestControls,
- DN entryDN, RDN newRDN, boolean deleteOldRDN,
- DN newSuperior)
- {
- super(clientConnection, operationID, messageID, requestControls);
-
-
- this.entryDN = entryDN;
- this.newRDN = newRDN;
- this.deleteOldRDN = deleteOldRDN;
- this.newSuperior = newSuperior;
-
- rawEntryDN = new ASN1OctetString(entryDN.toString());
- rawNewRDN = new ASN1OctetString(newRDN.toString());
-
- if (newSuperior == null)
- {
- rawNewSuperior = null;
- }
- else
- {
- rawNewSuperior = new ASN1OctetString(newSuperior.toString());
- }
-
- responseControls = new ArrayList<Control>();
- cancelRequest = null;
- modifications = null;
- changeNumber = -1;
- currentEntry = null;
- newEntry = null;
- }
-
-
/**
* Retrieves the raw, unprocessed entry DN as included in the client request.
@@ -259,12 +48,7 @@
*
* @return The raw, unprocessed entry DN as included in the client request.
*/
- public final ByteString getRawEntryDN()
- {
- return rawEntryDN;
- }
-
-
+ public ByteString getRawEntryDN();
/**
* Specifies the raw, unprocessed entry DN as included in the client request.
@@ -273,13 +57,7 @@
* @param rawEntryDN The raw, unprocessed entry DN as included in the client
* request.
*/
- public final void setRawEntryDN(ByteString rawEntryDN)
- {
- this.rawEntryDN = rawEntryDN;
-
- entryDN = null;
- }
-
+ public void setRawEntryDN(ByteString rawEntryDN);
/**
@@ -290,12 +68,7 @@
* @return The DN of the entry to rename, or <CODE>null</CODE> if the raw
* entry DN has not yet been processed.
*/
- public final DN getEntryDN()
- {
- return entryDN;
- }
-
-
+ public DN getEntryDN();
/**
* Retrieves the raw, unprocessed newRDN as included in the request from the
@@ -305,12 +78,7 @@
* @return The raw, unprocessed newRDN as included in the request from the
* client.
*/
- public final ByteString getRawNewRDN()
- {
- return rawNewRDN;
- }
-
-
+ public ByteString getRawNewRDN();
/**
* Specifies the raw, unprocessed newRDN as included in the request from the
@@ -320,14 +88,7 @@
* @param rawNewRDN The raw, unprocessed newRDN as included in the request
* from the client.
*/
- public final void setRawNewRDN(ByteString rawNewRDN)
- {
- this.rawNewRDN = rawNewRDN;
-
- newRDN = null;
- }
-
-
+ public void setRawNewRDN(ByteString rawNewRDN);
/**
* Retrieves the new RDN to use for the entry. This should not be called by
@@ -337,11 +98,7 @@
* @return The new RDN to use for the entry, or <CODE>null</CODE> if the raw
* newRDN has not yet been processed.
*/
- public final RDN getNewRDN()
- {
- return newRDN;
- }
-
+ public RDN getNewRDN();
/**
@@ -350,12 +107,7 @@
* @return <CODE>true</CODE> if the current RDN value should be removed from
* the entry, or <CODE>false</CODE> if not.
*/
- public final boolean deleteOldRDN()
- {
- return deleteOldRDN;
- }
-
-
+ public boolean deleteOldRDN();
/**
* Specifies whether the current RDN value should be removed from the entry.
@@ -363,12 +115,7 @@
* @param deleteOldRDN Specifies whether the current RDN value should be
* removed from the entry.
*/
- public final void setDeleteOldRDN(boolean deleteOldRDN)
- {
- this.deleteOldRDN = deleteOldRDN;
- }
-
-
+ public void setDeleteOldRDN(boolean deleteOldRDN);
/**
* Retrieves the raw, unprocessed newSuperior from the client request. This
@@ -378,12 +125,7 @@
* @return The raw, unprocessed newSuperior from the client request, or
* <CODE>null</CODE> if there is none.
*/
- public final ByteString getRawNewSuperior()
- {
- return rawNewSuperior;
- }
-
-
+ public ByteString getRawNewSuperior();
/**
* Specifies the raw, unprocessed newSuperior for this modify DN operation, as
@@ -393,14 +135,7 @@
* @param rawNewSuperior The raw, unprocessed newSuperior as provided in the
* request from the client.
*/
- public final void setRawNewSuperior(ByteString rawNewSuperior)
- {
- this.rawNewSuperior = rawNewSuperior;
-
- newSuperior = null;
- }
-
-
+ public void setRawNewSuperior(ByteString rawNewSuperior);
/**
* Retrieves the newSuperior DN for the entry. This should not be called by
@@ -412,12 +147,15 @@
* no newSuperior DN for this request or if the raw newSuperior has
* not yet been processed.
*/
- public final DN getNewSuperior()
- {
- return newSuperior;
- }
+ public DN getNewSuperior();
-
+ /**
+ * Retrieves the new DN for the entry.
+ *
+ * @return The new DN for the entry, or <CODE>null</CODE> if there is
+ * neither newRDN, nor entryDN for this request.
+ */
+ public DN getNewDN();
/**
* Retrieves the set of modifications applied to attributes of the target
@@ -436,12 +174,7 @@
* of the modify DN processing, or <CODE>null</CODE> if that
* information is not yet available (e.g., during pre-parse plugins).
*/
- public final List<Modification> getModifications()
- {
- return modifications;
- }
-
-
+ public List<Modification> getModifications();
/**
* Adds the provided modification to the set of modifications to be applied
@@ -451,12 +184,7 @@
* @param modification The modification to add to the set of modifications
* to apply to the entry.
*/
- public final void addModification(Modification modification)
- {
- modifications.add(modification);
- }
-
-
+ public void addModification(Modification modification);
/**
* Retrieves the current entry, before it is renamed. This will not be
@@ -466,11 +194,7 @@
* @return The current entry, or <CODE>null</CODE> if it is not yet
* available.
*/
- public final Entry getOriginalEntry()
- {
- return currentEntry;
- }
-
+ public Entry getOriginalEntry();
/**
@@ -481,10 +205,7 @@
* @return The updated entry, or <CODE>null</CODE> if it is not yet
* available.
*/
- public final Entry getUpdatedEntry()
- {
- return newEntry;
- }
+ public Entry getUpdatedEntry();
/**
* Retrieves the change number that has been assigned to this operation.
@@ -493,11 +214,7 @@
* if none has been assigned yet or if there is no applicable
* synchronization mechanism in place that uses change numbers.
*/
- public final long getChangeNumber()
- {
- return changeNumber;
- }
-
+ public long getChangeNumber();
/**
@@ -507,143 +224,7 @@
* @param changeNumber The change number that has been assigned to this
* operation by the synchronization mechanism.
*/
- public final void setChangeNumber(long changeNumber)
- {
- this.changeNumber = changeNumber;
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override()
- public final OperationType getOperationType()
- {
- // Note that no debugging will be done in this method because it is a likely
- // candidate for being called by the logging subsystem.
-
- return OperationType.MODIFY_DN;
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override()
- public final void disconnectClient(DisconnectReason disconnectReason,
- boolean sendNotification, String message,
- int messageID)
- {
- // Before calling clientConnection.disconnect, we need to mark this
- // operation as cancelled so that the attempt to cancel it later won't cause
- // an unnecessary delay.
- setCancelResult(CancelResult.CANCELED);
-
- clientConnection.disconnect(disconnectReason, sendNotification, message,
- messageID);
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override()
- public final String[][] getRequestLogElements()
- {
- // Note that no debugging will be done in this method because it is a likely
- // candidate for being called by the logging subsystem.
-
- String newSuperiorStr;
- if (rawNewSuperior == null)
- {
- newSuperiorStr = null;
- }
- else
- {
- newSuperiorStr = rawNewSuperior.stringValue();
- }
-
- return new String[][]
- {
- new String[] { LOG_ELEMENT_ENTRY_DN, String.valueOf(rawEntryDN) },
- new String[] { LOG_ELEMENT_NEW_RDN, String.valueOf(newRDN) },
- new String[] { LOG_ELEMENT_DELETE_OLD_RDN, String.valueOf(deleteOldRDN) },
- new String[] { LOG_ELEMENT_NEW_SUPERIOR, newSuperiorStr }
- };
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override()
- public final String[][] getResponseLogElements()
- {
- // Note that no debugging will be done in this method because it is a likely
- // candidate for being called by the logging subsystem.
-
- String resultCode = String.valueOf(getResultCode().getIntValue());
-
- String errorMessage;
- StringBuilder errorMessageBuffer = getErrorMessage();
- if (errorMessageBuffer == null)
- {
- errorMessage = null;
- }
- else
- {
- errorMessage = errorMessageBuffer.toString();
- }
-
- String matchedDNStr;
- DN matchedDN = getMatchedDN();
- if (matchedDN == null)
- {
- matchedDNStr = null;
- }
- else
- {
- matchedDNStr = matchedDN.toString();
- }
-
- String referrals;
- List<String> referralURLs = getReferralURLs();
- if ((referralURLs == null) || referralURLs.isEmpty())
- {
- referrals = null;
- }
- else
- {
- StringBuilder buffer = new StringBuilder();
- Iterator<String> iterator = referralURLs.iterator();
- buffer.append(iterator.next());
-
- while (iterator.hasNext())
- {
- buffer.append(", ");
- buffer.append(iterator.next());
- }
-
- referrals = buffer.toString();
- }
-
- String processingTime =
- String.valueOf(getProcessingTime());
-
- return new String[][]
- {
- new String[] { LOG_ELEMENT_RESULT_CODE, resultCode },
- new String[] { LOG_ELEMENT_ERROR_MESSAGE, errorMessage },
- new String[] { LOG_ELEMENT_MATCHED_DN, matchedDNStr },
- new String[] { LOG_ELEMENT_REFERRAL_URLS, referrals },
- new String[] { LOG_ELEMENT_PROCESSING_TIME, processingTime }
- };
- }
-
+ public void setChangeNumber(long changeNumber);
/**
@@ -654,1572 +235,17 @@
* authorization has been requested, or {@code null} if proxied
* authorization has not been requested.
*/
- public DN getProxiedAuthorizationDN()
- {
- return proxiedAuthorizationDN;
- }
-
+ public DN getProxiedAuthorizationDN();
/**
- * {@inheritDoc}
+ * Sets the proxied authorization DN for this operation if proxied
+ * authorization has been requested.
+ *
+ * @param dn The proxied authorization DN for this operation if proxied
+ * authorization has been requested, or {@code null} if proxied
+ * authorization has not been requested.
*/
- @Override()
- public final List<Control> getResponseControls()
- {
- return responseControls;
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override()
- public final void addResponseControl(Control control)
- {
- responseControls.add(control);
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override()
- public final void removeResponseControl(Control control)
- {
- responseControls.remove(control);
- }
-
-
-
- /**
- * Performs the work of actually processing this operation. This
- * should include all processing for the operation, including
- * invoking plugins, logging messages, performing access control,
- * managing synchronization, and any other work that might need to
- * be done in the course of processing.
- */
- public final void run()
- {
- setResultCode(ResultCode.UNDEFINED);
-
-
- // Get the plugin config manager that will be used for invoking plugins.
- PluginConfigManager pluginConfigManager =
- DirectoryServer.getPluginConfigManager();
- boolean skipPostOperation = false;
-
-
- // Start the processing timer.
- setProcessingStartTime();
-
-
- // Check for and handle a request to cancel this operation.
- if (cancelRequest != null)
- {
- indicateCancelled(cancelRequest);
- setProcessingStopTime();
- return;
- }
-
-
- // Create a labeled block of code that we can break out of if a problem is
- // detected.
-modifyDNProcessing:
- {
- // Invoke the pre-parse modify DN plugins.
- PreParsePluginResult preParseResult =
- pluginConfigManager.invokePreParseModifyDNPlugins(this);
- if (preParseResult.connectionTerminated())
- {
- // There's no point in continuing with anything. Log the request and
- // result and return.
- setResultCode(ResultCode.CANCELED);
-
- int msgID = MSGID_CANCELED_BY_PREPARSE_DISCONNECT;
- appendErrorMessage(getMessage(msgID));
-
- setProcessingStopTime();
-
- logModifyDNRequest(this);
- logModifyDNResponse(this);
- pluginConfigManager.invokePostResponseModifyDNPlugins(this);
- return;
- }
- else if (preParseResult.sendResponseImmediately())
- {
- skipPostOperation = true;
- logModifyDNRequest(this);
- break modifyDNProcessing;
- }
- else if (preParseResult.skipCoreProcessing())
- {
- skipPostOperation = false;
- break modifyDNProcessing;
- }
-
-
- // Log the modify DN request message.
- logModifyDNRequest(this);
-
-
- // Check for and handle a request to cancel this operation.
- if (cancelRequest != null)
- {
- indicateCancelled(cancelRequest);
- setProcessingStopTime();
- logModifyDNResponse(this);
- pluginConfigManager.invokePostResponseModifyDNPlugins(this);
- return;
- }
-
-
- // Process the entry DN, newRDN, and newSuperior elements from their raw
- // forms as provided by the client to the forms required for the rest of
- // the modify DN processing.
- try
- {
- if (entryDN == null)
- {
- entryDN = DN.decode(rawEntryDN);
- }
- }
- catch (DirectoryException de)
- {
- if (debugEnabled())
- {
- TRACER.debugCaught(DebugLogLevel.ERROR, de);
- }
-
- setResultCode(de.getResultCode());
- appendErrorMessage(de.getErrorMessage());
- skipPostOperation = true;
-
- break modifyDNProcessing;
- }
-
- try
- {
- if (newRDN == null)
- {
- newRDN = RDN.decode(rawNewRDN.stringValue());
- }
- }
- catch (DirectoryException de)
- {
- if (debugEnabled())
- {
- TRACER.debugCaught(DebugLogLevel.ERROR, de);
- }
-
- setResultCode(de.getResultCode());
- appendErrorMessage(de.getErrorMessage());
- skipPostOperation = true;
-
- break modifyDNProcessing;
- }
-
- if (rawNewSuperior == null)
- {
- newSuperior = null;
- }
- else
- {
- try
- {
- if (newSuperior == null)
- {
- newSuperior = DN.decode(rawNewSuperior);
- }
- }
- catch (DirectoryException de)
- {
- if (debugEnabled())
- {
- TRACER.debugCaught(DebugLogLevel.ERROR, de);
- }
-
- setResultCode(de.getResultCode());
- appendErrorMessage(de.getErrorMessage());
- skipPostOperation = true;
-
- break modifyDNProcessing;
- }
- }
-
-
- // Construct the new DN to use for the entry.
- DN parentDN;
- if (newSuperior == null)
- {
- parentDN = entryDN.getParentDNInSuffix();
- }
- else
- {
- parentDN = newSuperior;
- }
-
- if ((parentDN == null) || parentDN.isNullDN())
- {
- setResultCode(ResultCode.UNWILLING_TO_PERFORM);
- appendErrorMessage(getMessage(MSGID_MODDN_NO_PARENT,
- String.valueOf(entryDN)));
- break modifyDNProcessing;
- }
-
- DN newDN = parentDN.concat(newRDN);
-
- // Get the backend for the current entry, and the backend for the new
- // entry. If either is null, or if they are different, then fail.
- Backend currentBackend = DirectoryServer.getBackend(entryDN);
- if (currentBackend == null)
- {
- setResultCode(ResultCode.NO_SUCH_OBJECT);
- appendErrorMessage(getMessage(MSGID_MODDN_NO_BACKEND_FOR_CURRENT_ENTRY,
- String.valueOf(entryDN)));
- break modifyDNProcessing;
- }
-
- Backend newBackend = DirectoryServer.getBackend(newDN);
- if (newBackend == null)
- {
- setResultCode(ResultCode.NO_SUCH_OBJECT);
- appendErrorMessage(getMessage(MSGID_MODDN_NO_BACKEND_FOR_NEW_ENTRY,
- String.valueOf(entryDN),
- String.valueOf(newDN)));
- break modifyDNProcessing;
- }
- else if (! currentBackend.equals(newBackend))
- {
- setResultCode(ResultCode.UNWILLING_TO_PERFORM);
- appendErrorMessage(getMessage(MSGID_MODDN_DIFFERENT_BACKENDS,
- String.valueOf(entryDN),
- String.valueOf(newDN)));
- break modifyDNProcessing;
- }
-
-
- // Check for and handle a request to cancel this operation.
- if (cancelRequest != null)
- {
- indicateCancelled(cancelRequest);
- setProcessingStopTime();
- logModifyDNResponse(this);
- pluginConfigManager.invokePostResponseModifyDNPlugins(this);
- return;
- }
-
-
- // Acquire write locks for the current and new DN.
- Lock currentLock = null;
- for (int i=0; i < 3; i++)
- {
- currentLock = LockManager.lockWrite(entryDN);
- if (currentLock != null)
- {
- break;
- }
- }
-
- if (currentLock == null)
- {
- setResultCode(DirectoryServer.getServerErrorResultCode());
- appendErrorMessage(getMessage(MSGID_MODDN_CANNOT_LOCK_CURRENT_DN,
- String.valueOf(entryDN)));
-
- skipPostOperation = true;
- break modifyDNProcessing;
- }
-
- Lock newLock = null;
- try
- {
- for (int i=0; i < 3; i++)
- {
- newLock = LockManager.lockWrite(newDN);
- if (newLock != null)
- {
- break;
- }
- }
- }
- catch (Exception e)
- {
- if (debugEnabled())
- {
- TRACER.debugCaught(DebugLogLevel.ERROR, e);
- }
-
- LockManager.unlock(entryDN, currentLock);
-
- if (newLock != null)
- {
- LockManager.unlock(newDN, newLock);
- }
-
- setResultCode(DirectoryServer.getServerErrorResultCode());
- appendErrorMessage(getMessage(MSGID_MODDN_EXCEPTION_LOCKING_NEW_DN,
- String.valueOf(entryDN),
- String.valueOf(newDN),
- getExceptionMessage(e)));
-
- skipPostOperation = true;
- break modifyDNProcessing;
- }
-
- if (newLock == null)
- {
- LockManager.unlock(entryDN, currentLock);
-
- setResultCode(DirectoryServer.getServerErrorResultCode());
- appendErrorMessage(getMessage(MSGID_MODDN_CANNOT_LOCK_NEW_DN,
- String.valueOf(entryDN),
- String.valueOf(newDN)));
-
- skipPostOperation = true;
- break modifyDNProcessing;
- }
-
-
- try
- {
- // Check for and handle a request to cancel this operation.
- if (cancelRequest != null)
- {
- indicateCancelled(cancelRequest);
- setProcessingStopTime();
- logModifyDNResponse(this);
- pluginConfigManager.invokePostResponseModifyDNPlugins(this);
- return;
- }
-
-
- // Get the current entry from the appropriate backend. If it doesn't
- // exist, then fail.
- try
- {
- currentEntry = currentBackend.getEntry(entryDN);
- }
- catch (DirectoryException de)
- {
- if (debugEnabled())
- {
- TRACER.debugCaught(DebugLogLevel.ERROR, de);
- }
-
- setResultCode(de.getResultCode());
- appendErrorMessage(de.getErrorMessage());
- setMatchedDN(de.getMatchedDN());
- setReferralURLs(de.getReferralURLs());
-
- break modifyDNProcessing;
- }
-
- if (currentEntry == null)
- {
- // See if one of the entry's ancestors exists.
- parentDN = entryDN.getParentDNInSuffix();
- while (parentDN != null)
- {
- try
- {
- if (DirectoryServer.entryExists(parentDN))
- {
- setMatchedDN(parentDN);
- break;
- }
- }
- catch (Exception e)
- {
- if (debugEnabled())
- {
- TRACER.debugCaught(DebugLogLevel.ERROR, e);
- }
- break;
- }
-
- parentDN = parentDN.getParentDNInSuffix();
- }
-
- setResultCode(ResultCode.NO_SUCH_OBJECT);
- appendErrorMessage(getMessage(MSGID_MODDN_NO_CURRENT_ENTRY,
- String.valueOf(entryDN)));
-
- break modifyDNProcessing;
- }
-
-
- // Invoke any conflict resolution processing that might be needed by the
- // synchronization provider.
- for (SynchronizationProvider provider :
- DirectoryServer.getSynchronizationProviders())
- {
- try
- {
- SynchronizationProviderResult result =
- provider.handleConflictResolution(this);
- if (! result.continueOperationProcessing())
- {
- break modifyDNProcessing;
- }
- }
- catch (DirectoryException de)
- {
- if (debugEnabled())
- {
- TRACER.debugCaught(DebugLogLevel.ERROR, de);
- }
-
- logError(ErrorLogCategory.SYNCHRONIZATION,
- ErrorLogSeverity.SEVERE_ERROR,
- MSGID_MODDN_SYNCH_CONFLICT_RESOLUTION_FAILED,
- getConnectionID(), getOperationID(),
- getExceptionMessage(de));
-
- setResponseData(de);
- break modifyDNProcessing;
- }
- }
-
-
- // Check to see if there are any controls in the request. If so, then
- // see if there is any special processing required.
- boolean noOp = false;
- LDAPPreReadRequestControl preReadRequest = null;
- LDAPPostReadRequestControl postReadRequest = null;
- List<Control> requestControls = getRequestControls();
- if ((requestControls != null) && (! requestControls.isEmpty()))
- {
- for (int i=0; i < requestControls.size(); i++)
- {
- Control c = requestControls.get(i);
- String oid = c.getOID();
-
- if (oid.equals(OID_LDAP_ASSERTION))
- {
- LDAPAssertionRequestControl assertControl;
- if (c instanceof LDAPAssertionRequestControl)
- {
- assertControl = (LDAPAssertionRequestControl) c;
- }
- else
- {
- try
- {
- assertControl = LDAPAssertionRequestControl.decodeControl(c);
- requestControls.set(i, assertControl);
- }
- catch (LDAPException le)
- {
- if (debugEnabled())
- {
- TRACER.debugCaught(DebugLogLevel.ERROR, le);
- }
-
- setResultCode(ResultCode.valueOf(le.getResultCode()));
- appendErrorMessage(le.getMessage());
-
- break modifyDNProcessing;
- }
- }
-
- try
- {
- // FIXME -- We need to determine whether the current user has
- // permission to make this determination.
- SearchFilter filter = assertControl.getSearchFilter();
- if (! filter.matchesEntry(currentEntry))
- {
- setResultCode(ResultCode.ASSERTION_FAILED);
-
- appendErrorMessage(getMessage(MSGID_MODDN_ASSERTION_FAILED,
- String.valueOf(entryDN)));
-
- break modifyDNProcessing;
- }
- }
- catch (DirectoryException de)
- {
- if (debugEnabled())
- {
- TRACER.debugCaught(DebugLogLevel.ERROR, de);
- }
-
- setResultCode(ResultCode.PROTOCOL_ERROR);
-
- int msgID = MSGID_MODDN_CANNOT_PROCESS_ASSERTION_FILTER;
- appendErrorMessage(getMessage(msgID, String.valueOf(entryDN),
- de.getErrorMessage()));
-
- break modifyDNProcessing;
- }
- }
- else if (oid.equals(OID_LDAP_NOOP_OPENLDAP_ASSIGNED))
- {
- noOp = true;
- }
- else if (oid.equals(OID_LDAP_READENTRY_PREREAD))
- {
- if (c instanceof LDAPAssertionRequestControl)
- {
- preReadRequest = (LDAPPreReadRequestControl) c;
- }
- else
- {
- try
- {
- preReadRequest = LDAPPreReadRequestControl.decodeControl(c);
- requestControls.set(i, preReadRequest);
- }
- catch (LDAPException le)
- {
- if (debugEnabled())
- {
- TRACER.debugCaught(DebugLogLevel.ERROR, le);
- }
-
- setResultCode(ResultCode.valueOf(le.getResultCode()));
- appendErrorMessage(le.getMessage());
-
- break modifyDNProcessing;
- }
- }
- }
- else if (oid.equals(OID_LDAP_READENTRY_POSTREAD))
- {
- if (c instanceof LDAPAssertionRequestControl)
- {
- postReadRequest = (LDAPPostReadRequestControl) c;
- }
- else
- {
- try
- {
- postReadRequest = LDAPPostReadRequestControl.decodeControl(c);
- requestControls.set(i, postReadRequest);
- }
- catch (LDAPException le)
- {
- if (debugEnabled())
- {
- TRACER.debugCaught(DebugLogLevel.ERROR, le);
- }
-
- setResultCode(ResultCode.valueOf(le.getResultCode()));
- appendErrorMessage(le.getMessage());
-
- break modifyDNProcessing;
- }
- }
- }
- else if (oid.equals(OID_PROXIED_AUTH_V1))
- {
- // The requester must have the PROXIED_AUTH privilige in order to
- // be able to use this control.
- if (! clientConnection.hasPrivilege(Privilege.PROXIED_AUTH, this))
- {
- int msgID = MSGID_PROXYAUTH_INSUFFICIENT_PRIVILEGES;
- appendErrorMessage(getMessage(msgID));
- setResultCode(ResultCode.AUTHORIZATION_DENIED);
- break modifyDNProcessing;
- }
-
-
- ProxiedAuthV1Control proxyControl;
- if (c instanceof ProxiedAuthV1Control)
- {
- proxyControl = (ProxiedAuthV1Control) c;
- }
- else
- {
- try
- {
- proxyControl = ProxiedAuthV1Control.decodeControl(c);
- }
- catch (LDAPException le)
- {
- if (debugEnabled())
- {
- TRACER.debugCaught(DebugLogLevel.ERROR, le);
- }
-
- setResultCode(ResultCode.valueOf(le.getResultCode()));
- appendErrorMessage(le.getMessage());
-
- break modifyDNProcessing;
- }
- }
-
-
- Entry authorizationEntry;
- try
- {
- authorizationEntry = proxyControl.getAuthorizationEntry();
- }
- catch (DirectoryException de)
- {
- if (debugEnabled())
- {
- TRACER.debugCaught(DebugLogLevel.ERROR, de);
- }
-
- setResultCode(de.getResultCode());
- appendErrorMessage(de.getErrorMessage());
-
- break modifyDNProcessing;
- }
-
- if (AccessControlConfigManager.getInstance()
- .getAccessControlHandler().isProxiedAuthAllowed(this,
- authorizationEntry) == false) {
- setResultCode(ResultCode.INSUFFICIENT_ACCESS_RIGHTS);
-
- int msgID = MSGID_MODDN_AUTHZ_INSUFFICIENT_ACCESS_RIGHTS;
- appendErrorMessage(getMessage(msgID, String.valueOf(entryDN)));
-
- skipPostOperation = true;
- break modifyDNProcessing;
- }
- setAuthorizationEntry(authorizationEntry);
- if (authorizationEntry == null)
- {
- proxiedAuthorizationDN = DN.nullDN();
- }
- else
- {
- proxiedAuthorizationDN = authorizationEntry.getDN();
- }
- }
- else if (oid.equals(OID_PROXIED_AUTH_V2))
- {
- // The requester must have the PROXIED_AUTH privilige in order to
- // be able to use this control.
- if (! clientConnection.hasPrivilege(Privilege.PROXIED_AUTH, this))
- {
- int msgID = MSGID_PROXYAUTH_INSUFFICIENT_PRIVILEGES;
- appendErrorMessage(getMessage(msgID));
- setResultCode(ResultCode.AUTHORIZATION_DENIED);
- break modifyDNProcessing;
- }
-
-
- ProxiedAuthV2Control proxyControl;
- if (c instanceof ProxiedAuthV2Control)
- {
- proxyControl = (ProxiedAuthV2Control) c;
- }
- else
- {
- try
- {
- proxyControl = ProxiedAuthV2Control.decodeControl(c);
- }
- catch (LDAPException le)
- {
- if (debugEnabled())
- {
- TRACER.debugCaught(DebugLogLevel.ERROR, le);
- }
-
- setResultCode(ResultCode.valueOf(le.getResultCode()));
- appendErrorMessage(le.getMessage());
-
- break modifyDNProcessing;
- }
- }
-
-
- Entry authorizationEntry;
- try
- {
- authorizationEntry = proxyControl.getAuthorizationEntry();
- }
- catch (DirectoryException de)
- {
- if (debugEnabled())
- {
- TRACER.debugCaught(DebugLogLevel.ERROR, de);
- }
-
- setResultCode(de.getResultCode());
- appendErrorMessage(de.getErrorMessage());
-
- break modifyDNProcessing;
- }
- if (AccessControlConfigManager.getInstance()
- .getAccessControlHandler().isProxiedAuthAllowed(this,
- authorizationEntry) == false) {
- setResultCode(ResultCode.INSUFFICIENT_ACCESS_RIGHTS);
-
- int msgID = MSGID_MODDN_AUTHZ_INSUFFICIENT_ACCESS_RIGHTS;
- appendErrorMessage(getMessage(msgID, String.valueOf(entryDN)));
-
- skipPostOperation = true;
- break modifyDNProcessing;
- }
-
-
- setAuthorizationEntry(authorizationEntry);
- if (authorizationEntry == null)
- {
- proxiedAuthorizationDN = DN.nullDN();
- }
- else
- {
- proxiedAuthorizationDN = authorizationEntry.getDN();
- }
- }
-
- // NYI -- Add support for additional controls.
- else if (c.isCritical())
- {
- Backend backend = DirectoryServer.getBackend(entryDN);
- if ((backend == null) || (! backend.supportsControl(oid)))
- {
- setResultCode(ResultCode.UNAVAILABLE_CRITICAL_EXTENSION);
-
- int msgID = MSGID_MODDN_UNSUPPORTED_CRITICAL_CONTROL;
- appendErrorMessage(getMessage(msgID, String.valueOf(entryDN),
- oid));
-
- break modifyDNProcessing;
- }
- }
- }
- }
-
-
- // Check to see if the client has permission to perform the
- // modify DN.
-
- // FIXME: for now assume that this will check all permission
- // pertinent to the operation. This includes proxy authorization
- // and any other controls specified.
-
- // FIXME: earlier checks to see if the entry or new superior
- // already exists may have already exposed sensitive information
- // to the client.
- if (AccessControlConfigManager.getInstance()
- .getAccessControlHandler().isAllowed(this) == false) {
- setResultCode(ResultCode.INSUFFICIENT_ACCESS_RIGHTS);
-
- int msgID = MSGID_MODDN_AUTHZ_INSUFFICIENT_ACCESS_RIGHTS;
- appendErrorMessage(getMessage(msgID, String.valueOf(entryDN)));
-
- skipPostOperation = true;
- break modifyDNProcessing;
- }
-
- // Duplicate the entry and set its new DN. Also, create an empty list
- // to hold the attribute-level modifications.
- newEntry = currentEntry.duplicate(false);
- newEntry.setDN(newDN);
- modifications = new ArrayList<Modification>();
-
-
-
- // If we should delete the old RDN values from the entry, then do so.
- if (deleteOldRDN)
- {
- RDN currentRDN = entryDN.getRDN();
- int numValues = currentRDN.getNumValues();
- for (int i=0; i < numValues; i++)
- {
- LinkedHashSet<AttributeValue> valueSet =
- new LinkedHashSet<AttributeValue>(1);
- valueSet.add(currentRDN.getAttributeValue(i));
-
- Attribute a = new Attribute(currentRDN.getAttributeType(i),
- currentRDN.getAttributeName(i),
- valueSet);
-
- // If the associated attribute type is marked NO-USER-MODIFICATION,
- // then refuse the update.
- if (a.getAttributeType().isNoUserModification())
- {
- if (! (isInternalOperation() || isSynchronizationOperation()))
- {
- setResultCode(ResultCode.UNWILLING_TO_PERFORM);
-
- int msgID = MSGID_MODDN_OLD_RDN_ATTR_IS_NO_USER_MOD;
- appendErrorMessage(getMessage(msgID, String.valueOf(entryDN),
- a.getName()));
- break modifyDNProcessing;
- }
- }
-
- LinkedList<AttributeValue> missingValues =
- new LinkedList<AttributeValue>();
- newEntry.removeAttribute(a, missingValues);
-
- if (missingValues.isEmpty())
- {
- modifications.add(new Modification(ModificationType.DELETE, a));
- }
- }
- }
-
-
- // Add the new RDN values to the entry.
- int newRDNValues = newRDN.getNumValues();
- for (int i=0; i < newRDNValues; i++)
- {
- LinkedHashSet<AttributeValue> valueSet =
- new LinkedHashSet<AttributeValue>(1);
- valueSet.add(newRDN.getAttributeValue(i));
-
- Attribute a = new Attribute(newRDN.getAttributeType(i),
- newRDN.getAttributeName(i),
- valueSet);
-
- LinkedList<AttributeValue> duplicateValues =
- new LinkedList<AttributeValue>();
- newEntry.addAttribute(a, duplicateValues);
-
- if (duplicateValues.isEmpty())
- {
- // If the associated attribute type is marked NO-USER-MODIFICATION,
- // then refuse the update.
- if (a.getAttributeType().isNoUserModification())
- {
- if (! (isInternalOperation() || isSynchronizationOperation()))
- {
- setResultCode(ResultCode.UNWILLING_TO_PERFORM);
-
- int msgID = MSGID_MODDN_NEW_RDN_ATTR_IS_NO_USER_MOD;
- appendErrorMessage(getMessage(msgID, String.valueOf(entryDN),
- a.getName()));
- break modifyDNProcessing;
- }
- }
- else
- {
- modifications.add(new Modification(ModificationType.ADD, a));
- }
- }
- }
-
- // If the server is configured to check the schema and the
- // operation is not a synchronization operation,
- // make sure that the resulting entry is valid as per the server schema.
- if ((DirectoryServer.checkSchema()) &&
- (!isSynchronizationOperation()) )
- {
- StringBuilder invalidReason = new StringBuilder();
- if (! newEntry.conformsToSchema(null, false, true, true,
- invalidReason))
- {
- setResultCode(ResultCode.OBJECTCLASS_VIOLATION);
- appendErrorMessage(getMessage(MSGID_MODDN_VIOLATES_SCHEMA,
- String.valueOf(entryDN),
- String.valueOf(invalidReason)));
- break modifyDNProcessing;
- }
-
- for (int i=0; i < newRDNValues; i++)
- {
- AttributeType at = newRDN.getAttributeType(i);
- if (at.isObsolete())
- {
- setResultCode(ResultCode.CONSTRAINT_VIOLATION);
- appendErrorMessage(getMessage(MSGID_MODDN_NEWRDN_ATTR_IS_OBSOLETE,
- String.valueOf(entryDN),
- at.getNameOrOID()));
- break modifyDNProcessing;
- }
- }
- }
-
-
- // Check for and handle a request to cancel this operation.
- if (cancelRequest != null)
- {
- indicateCancelled(cancelRequest);
- setProcessingStopTime();
- logModifyDNResponse(this);
- pluginConfigManager.invokePostResponseModifyDNPlugins(this);
- return;
- }
-
-
- // Get a count of the current number of modifications. The
- // pre-operation plugins may alter this list, and we need to be able to
- // identify which changes were made after they're done.
- int modCount = modifications.size();
-
-
- // If the operation is not a synchronization operation,
- // Invoke the pre-operation modify DN plugins.
- if (!isSynchronizationOperation())
- {
- PreOperationPluginResult preOpResult =
- pluginConfigManager.invokePreOperationModifyDNPlugins(this);
- if (preOpResult.connectionTerminated())
- {
- // There's no point in continuing with anything. Log the request
- // and result and return.
- setResultCode(ResultCode.CANCELED);
-
- int msgID = MSGID_CANCELED_BY_PREOP_DISCONNECT;
- appendErrorMessage(getMessage(msgID));
-
- setProcessingStopTime();
- logModifyDNResponse(this);
- pluginConfigManager.invokePostResponseModifyDNPlugins(this);
- return;
- }
- else if (preOpResult.sendResponseImmediately())
- {
- skipPostOperation = true;
- break modifyDNProcessing;
- }
- else if (preOpResult.skipCoreProcessing())
- {
- skipPostOperation = false;
- break modifyDNProcessing;
- }
- }
-
-
- // Check to see if any of the pre-operation plugins made any changes to
- // the entry. If so, then apply them.
- if (modifications.size() > modCount)
- {
- for (int i=modCount; i < modifications.size(); i++)
- {
- Modification m = modifications.get(i);
- Attribute a = m.getAttribute();
-
- switch (m.getModificationType())
- {
- case ADD:
- LinkedList<AttributeValue> duplicateValues =
- new LinkedList<AttributeValue>();
- newEntry.addAttribute(a, duplicateValues);
- break;
- case DELETE:
- LinkedList<AttributeValue> missingValues =
- new LinkedList<AttributeValue>();
- newEntry.removeAttribute(a, missingValues);
- break;
- case REPLACE:
- duplicateValues = new LinkedList<AttributeValue>();
- newEntry.removeAttribute(a.getAttributeType(), a.getOptions());
- newEntry.addAttribute(a, duplicateValues);
- break;
- case INCREMENT:
- List<Attribute> attrList =
- newEntry.getAttribute(a.getAttributeType(),
- a.getOptions());
- if ((attrList == null) || attrList.isEmpty())
- {
- setResultCode(ResultCode.NO_SUCH_ATTRIBUTE);
-
- int msgID = MSGID_MODDN_PREOP_INCREMENT_NO_ATTR;
- appendErrorMessage(getMessage(msgID, String.valueOf(entryDN),
- a.getName()));
-
- break modifyDNProcessing;
- }
- else if (attrList.size() > 1)
- {
- setResultCode(ResultCode.CONSTRAINT_VIOLATION);
-
- int msgID = MSGID_MODDN_PREOP_INCREMENT_MULTIPLE_VALUES;
- appendErrorMessage(getMessage(msgID, String.valueOf(entryDN),
- a.getName()));
-
- break modifyDNProcessing;
- }
-
- LinkedHashSet<AttributeValue> values =
- attrList.get(0).getValues();
- if ((values == null) || values.isEmpty())
- {
- setResultCode(ResultCode.NO_SUCH_ATTRIBUTE);
-
- int msgID = MSGID_MODDN_PREOP_INCREMENT_NO_ATTR;
- appendErrorMessage(getMessage(msgID, String.valueOf(entryDN),
- a.getName()));
-
- break modifyDNProcessing;
- }
- else if (values.size() > 1)
- {
- setResultCode(ResultCode.CONSTRAINT_VIOLATION);
-
- int msgID = MSGID_MODDN_PREOP_INCREMENT_MULTIPLE_VALUES;
- appendErrorMessage(getMessage(msgID, String.valueOf(entryDN),
- a.getName()));
-
- break modifyDNProcessing;
- }
-
- long currentLongValue;
- try
- {
- AttributeValue v = values.iterator().next();
- currentLongValue = Long.parseLong(v.getStringValue());
- }
- catch (Exception e)
- {
- if (debugEnabled())
- {
- TRACER.debugCaught(DebugLogLevel.ERROR, e);
- }
-
- setResultCode(ResultCode.CONSTRAINT_VIOLATION);
-
- int msgID = MSGID_MODDN_PREOP_INCREMENT_VALUE_NOT_INTEGER;
- appendErrorMessage(getMessage(msgID, String.valueOf(entryDN),
- a.getName()));
-
- break modifyDNProcessing;
- }
-
- LinkedHashSet<AttributeValue> newValues = a.getValues();
- if ((newValues == null) || newValues.isEmpty())
- {
- setResultCode(ResultCode.CONSTRAINT_VIOLATION);
-
- int msgID = MSGID_MODDN_PREOP_INCREMENT_NO_AMOUNT;
- appendErrorMessage(getMessage(msgID, String.valueOf(entryDN),
- a.getName()));
-
- break modifyDNProcessing;
- }
- else if (newValues.size() > 1)
- {
- setResultCode(ResultCode.CONSTRAINT_VIOLATION);
-
- int msgID = MSGID_MODDN_PREOP_INCREMENT_MULTIPLE_AMOUNTS;
- appendErrorMessage(getMessage(msgID, String.valueOf(entryDN),
- a.getName()));
-
- break modifyDNProcessing;
- }
-
- long incrementAmount;
- try
- {
- AttributeValue v = values.iterator().next();
- incrementAmount = Long.parseLong(v.getStringValue());
- }
- catch (Exception e)
- {
- if (debugEnabled())
- {
- TRACER.debugCaught(DebugLogLevel.ERROR, e);
- }
-
- setResultCode(ResultCode.CONSTRAINT_VIOLATION);
-
- int msgID = MSGID_MODDN_PREOP_INCREMENT_AMOUNT_NOT_INTEGER;
- appendErrorMessage(getMessage(msgID, String.valueOf(entryDN),
- a.getName()));
-
- break modifyDNProcessing;
- }
-
- long newLongValue = currentLongValue + incrementAmount;
- ByteString newValueOS =
- new ASN1OctetString(String.valueOf(newLongValue));
-
- newValues = new LinkedHashSet<AttributeValue>(1);
- newValues.add(new AttributeValue(a.getAttributeType(),
- newValueOS));
-
- List<Attribute> newAttrList = new ArrayList<Attribute>(1);
- newAttrList.add(new Attribute(a.getAttributeType(),
- a.getName(), newValues));
- newEntry.putAttribute(a.getAttributeType(), newAttrList);
-
- break;
- }
- }
-
-
- // Make sure that the updated entry still conforms to the server
- // schema.
- if (DirectoryServer.checkSchema())
- {
- StringBuilder invalidReason = new StringBuilder();
- if (! newEntry.conformsToSchema(null, false, true, true,
- invalidReason))
- {
- setResultCode(ResultCode.OBJECTCLASS_VIOLATION);
-
- appendErrorMessage(getMessage(MSGID_MODDN_PREOP_VIOLATES_SCHEMA,
- String.valueOf(entryDN),
- String.valueOf(invalidReason)));
- break modifyDNProcessing;
- }
- }
- }
-
-
- // Check for and handle a request to cancel this operation.
- if (cancelRequest != null)
- {
- indicateCancelled(cancelRequest);
- setProcessingStopTime();
- logModifyDNResponse(this);
- pluginConfigManager.invokePostResponseModifyDNPlugins(this);
- return;
- }
-
-
- // Actually perform the modify DN operation. This should include taking
- // care of any synchronization that might be needed.
- try
- {
- // If it is not a private backend, then check to see if the server or
- // backend is operating in read-only mode.
- if (! currentBackend.isPrivateBackend())
- {
- switch (DirectoryServer.getWritabilityMode())
- {
- case DISABLED:
- setResultCode(ResultCode.UNWILLING_TO_PERFORM);
- appendErrorMessage(getMessage(MSGID_MODDN_SERVER_READONLY,
- String.valueOf(entryDN)));
- break modifyDNProcessing;
-
- case INTERNAL_ONLY:
- if (! (isInternalOperation() || isSynchronizationOperation()))
- {
- setResultCode(ResultCode.UNWILLING_TO_PERFORM);
- appendErrorMessage(getMessage(MSGID_MODDN_SERVER_READONLY,
- String.valueOf(entryDN)));
- break modifyDNProcessing;
- }
- }
-
- switch (currentBackend.getWritabilityMode())
- {
- case DISABLED:
- setResultCode(ResultCode.UNWILLING_TO_PERFORM);
- appendErrorMessage(getMessage(MSGID_MODDN_BACKEND_READONLY,
- String.valueOf(entryDN)));
- break modifyDNProcessing;
-
- case INTERNAL_ONLY:
- if (! (isInternalOperation() || isSynchronizationOperation()))
- {
- setResultCode(ResultCode.UNWILLING_TO_PERFORM);
- appendErrorMessage(getMessage(MSGID_MODDN_BACKEND_READONLY,
- String.valueOf(entryDN)));
- break modifyDNProcessing;
- }
- }
- }
-
-
- if (noOp)
- {
- appendErrorMessage(getMessage(MSGID_MODDN_NOOP));
-
- setResultCode(ResultCode.NO_OPERATION);
- }
- else
- {
- for (SynchronizationProvider provider :
- DirectoryServer.getSynchronizationProviders())
- {
- try
- {
- SynchronizationProviderResult result =
- provider.doPreOperation(this);
- if (! result.continueOperationProcessing())
- {
- break modifyDNProcessing;
- }
- }
- catch (DirectoryException de)
- {
- if (debugEnabled())
- {
- TRACER.debugCaught(DebugLogLevel.ERROR, de);
- }
-
- logError(ErrorLogCategory.SYNCHRONIZATION,
- ErrorLogSeverity.SEVERE_ERROR,
- MSGID_MODDN_SYNCH_PREOP_FAILED, getConnectionID(),
- getOperationID(), getExceptionMessage(de));
-
- setResponseData(de);
- break modifyDNProcessing;
- }
- }
-
- currentBackend.renameEntry(entryDN, newEntry, this);
- }
-
- if (preReadRequest != null)
- {
- Entry entry = currentEntry.duplicate(true);
-
- if (! preReadRequest.allowsAttribute(
- DirectoryServer.getObjectClassAttributeType()))
- {
- entry.removeAttribute(
- DirectoryServer.getObjectClassAttributeType());
- }
-
- if (! preReadRequest.returnAllUserAttributes())
- {
- Iterator<AttributeType> iterator =
- entry.getUserAttributes().keySet().iterator();
- while (iterator.hasNext())
- {
- AttributeType attrType = iterator.next();
- if (! preReadRequest.allowsAttribute(attrType))
- {
- iterator.remove();
- }
- }
- }
-
- if (! preReadRequest.returnAllOperationalAttributes())
- {
- Iterator<AttributeType> iterator =
- entry.getOperationalAttributes().keySet().iterator();
- while (iterator.hasNext())
- {
- AttributeType attrType = iterator.next();
- if (! preReadRequest.allowsAttribute(attrType))
- {
- iterator.remove();
- }
- }
- }
-
- // FIXME -- Check access controls on the entry to see if it should
- // be returned or if any attributes need to be stripped
- // out..
- SearchResultEntry searchEntry = new SearchResultEntry(entry);
- LDAPPreReadResponseControl responseControl =
- new LDAPPreReadResponseControl(preReadRequest.getOID(),
- preReadRequest.isCritical(),
- searchEntry);
-
- responseControls.add(responseControl);
- }
-
- if (postReadRequest != null)
- {
- Entry entry = newEntry.duplicate(true);
-
- if (! postReadRequest.allowsAttribute(
- DirectoryServer.getObjectClassAttributeType()))
- {
- entry.removeAttribute(
- DirectoryServer.getObjectClassAttributeType());
- }
-
- if (! postReadRequest.returnAllUserAttributes())
- {
- Iterator<AttributeType> iterator =
- entry.getUserAttributes().keySet().iterator();
- while (iterator.hasNext())
- {
- AttributeType attrType = iterator.next();
- if (! postReadRequest.allowsAttribute(attrType))
- {
- iterator.remove();
- }
- }
- }
-
- if (! postReadRequest.returnAllOperationalAttributes())
- {
- Iterator<AttributeType> iterator =
- entry.getOperationalAttributes().keySet().iterator();
- while (iterator.hasNext())
- {
- AttributeType attrType = iterator.next();
- if (! postReadRequest.allowsAttribute(attrType))
- {
- iterator.remove();
- }
- }
- }
-
- // FIXME -- Check access controls on the entry to see if it should
- // be returned or if any attributes need to be stripped
- // out..
- SearchResultEntry searchEntry = new SearchResultEntry(entry);
- LDAPPostReadResponseControl responseControl =
- new LDAPPostReadResponseControl(postReadRequest.getOID(),
- postReadRequest.isCritical(),
- searchEntry);
-
- responseControls.add(responseControl);
- }
-
-
- if (! noOp)
- {
- setResultCode(ResultCode.SUCCESS);
- }
- }
- catch (DirectoryException de)
- {
- if (debugEnabled())
- {
- TRACER.debugCaught(DebugLogLevel.ERROR, de);
- }
-
- setResultCode(de.getResultCode());
- appendErrorMessage(de.getErrorMessage());
- setMatchedDN(de.getMatchedDN());
- setReferralURLs(de.getReferralURLs());
-
- break modifyDNProcessing;
- }
- catch (CancelledOperationException coe)
- {
- if (debugEnabled())
- {
- TRACER.debugCaught(DebugLogLevel.ERROR, coe);
- }
-
- CancelResult cancelResult = coe.getCancelResult();
-
- setCancelResult(cancelResult);
- setResultCode(cancelResult.getResultCode());
-
- String message = coe.getMessage();
- if ((message != null) && (message.length() > 0))
- {
- appendErrorMessage(message);
- }
-
- break modifyDNProcessing;
- }
- }
- finally
- {
- LockManager.unlock(entryDN, currentLock);
- LockManager.unlock(newDN, newLock);
-
- for (SynchronizationProvider provider :
- DirectoryServer.getSynchronizationProviders())
- {
- try
- {
- provider.doPostOperation(this);
- }
- catch (DirectoryException de)
- {
- if (debugEnabled())
- {
- TRACER.debugCaught(DebugLogLevel.ERROR, de);
- }
-
- logError(ErrorLogCategory.SYNCHRONIZATION,
- ErrorLogSeverity.SEVERE_ERROR,
- MSGID_MODDN_SYNCH_POSTOP_FAILED, getConnectionID(),
- getOperationID(), getExceptionMessage(de));
-
- setResponseData(de);
- break;
- }
- }
- }
- }
-
-
- // Indicate that it is now too late to attempt to cancel the operation.
- setCancelResult(CancelResult.TOO_LATE);
-
-
- // Invoke the post-operation modify DN plugins.
- if (! skipPostOperation)
- {
- PostOperationPluginResult postOperationResult =
- pluginConfigManager.invokePostOperationModifyDNPlugins(this);
- if (postOperationResult.connectionTerminated())
- {
- setResultCode(ResultCode.CANCELED);
-
- int msgID = MSGID_CANCELED_BY_POSTOP_DISCONNECT;
- appendErrorMessage(getMessage(msgID));
-
- setProcessingStopTime();
- logModifyDNResponse(this);
- pluginConfigManager.invokePostResponseModifyDNPlugins(this);
- return;
- }
- }
-
-
- // Notify any change notification listeners that might be registered with
- // the server.
- if (getResultCode() == ResultCode.SUCCESS)
- {
- for (ChangeNotificationListener changeListener :
- DirectoryServer.getChangeNotificationListeners())
- {
- try
- {
- changeListener.handleModifyDNOperation(this, currentEntry, newEntry);
- }
- catch (Exception e)
- {
- if (debugEnabled())
- {
- TRACER.debugCaught(DebugLogLevel.ERROR, e);
- }
-
- int msgID = MSGID_MODDN_ERROR_NOTIFYING_CHANGE_LISTENER;
- String message = getMessage(msgID, getExceptionMessage(e));
- logError(ErrorLogCategory.CORE_SERVER, ErrorLogSeverity.SEVERE_ERROR,
- message, msgID);
- }
- }
- }
-
-
- // Stop the processing timer.
- setProcessingStopTime();
-
-
- // Send the modify DN response to the client.
- clientConnection.sendResponse(this);
-
-
- // Log the modify DN response.
- logModifyDNResponse(this);
-
-
- // Notify any persistent searches that might be registered with the server.
- if (getResultCode() == ResultCode.SUCCESS)
- {
- for (PersistentSearch persistentSearch :
- DirectoryServer.getPersistentSearches())
- {
- try
- {
- persistentSearch.processModifyDN(this, currentEntry, newEntry);
- }
- catch (Exception e)
- {
- if (debugEnabled())
- {
- TRACER.debugCaught(DebugLogLevel.ERROR, e);
- }
-
- int msgID = MSGID_MODDN_ERROR_NOTIFYING_PERSISTENT_SEARCH;
- String message = getMessage(msgID, String.valueOf(persistentSearch),
- getExceptionMessage(e));
- logError(ErrorLogCategory.CORE_SERVER, ErrorLogSeverity.SEVERE_ERROR,
- message, msgID);
-
- DirectoryServer.deregisterPersistentSearch(persistentSearch);
- }
- }
- }
-
-
- // Invoke the post-response modify DN plugins.
- pluginConfigManager.invokePostResponseModifyDNPlugins(this);
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override()
- public final CancelResult cancel(CancelRequest cancelRequest)
- {
- this.cancelRequest = cancelRequest;
-
- CancelResult cancelResult = getCancelResult();
- long stopWaitingTime = System.currentTimeMillis() + 5000;
- while ((cancelResult == null) &&
- (System.currentTimeMillis() < stopWaitingTime))
- {
- try
- {
- Thread.sleep(50);
- }
- catch (Exception e)
- {
- if (debugEnabled())
- {
- TRACER.debugCaught(DebugLogLevel.ERROR, e);
- }
- }
-
- cancelResult = getCancelResult();
- }
-
- if (cancelResult == null)
- {
- // This can happen in some rare cases (e.g., if a client disconnects and
- // there is still a lot of data to send to that client), and in this case
- // we'll prevent the cancel thread from blocking for a long period of
- // time.
- cancelResult = CancelResult.CANNOT_CANCEL;
- }
-
- return cancelResult;
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override()
- public final CancelRequest getCancelRequest()
- {
- return cancelRequest;
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override()
- public boolean setCancelRequest(CancelRequest cancelRequest)
- {
- this.cancelRequest = cancelRequest;
- return true;
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- @Override()
- public final void toString(StringBuilder buffer)
- {
- buffer.append("ModifyDNOperation(connID=");
- buffer.append(clientConnection.getConnectionID());
- buffer.append(", opID=");
- buffer.append(operationID);
- buffer.append(", dn=");
- buffer.append(rawEntryDN);
- buffer.append(", newRDN=");
- buffer.append(rawNewRDN);
- buffer.append(", deleteOldRDN=");
- buffer.append(deleteOldRDN);
-
- if (rawNewSuperior != null)
- {
- buffer.append(", newSuperior=");
- buffer.append(rawNewSuperior);
- }
-
- buffer.append(")");
- }
+ public void setProxiedAuthorizationDN(DN dn);
}
-
--
Gitblit v1.10.0