From b117ed336a8744e6b2b7a8a531743ba58178d8a0 Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Wed, 27 Nov 2013 10:50:45 +0000
Subject: [PATCH] Factor out duplicate code and fix cut n paste bug in LocalBackendModifyOperation which was preventing sync operations from bypassing backend INTERNAL_ONLY mode.

---
 opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyOperation.java   |   53 ----------
 opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendWorkflowElement.java   |   60 ++++++++++++
 opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyDNOperation.java |   45 --------
 opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendDeleteOperation.java   |   42 --------
 opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendAddOperation.java      |   44 --------
 5 files changed, 68 insertions(+), 176 deletions(-)

diff --git a/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendAddOperation.java b/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendAddOperation.java
index cacf2bf..006b9f5 100644
--- a/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendAddOperation.java
+++ b/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendAddOperation.java
@@ -481,48 +481,8 @@
         }
       }
 
-      // If it is not a private backend, then check to see if the server or
-      // backend is operating in read-only mode.
-      if (!backend.isPrivateBackend())
-      {
-        switch (DirectoryServer.getWritabilityMode())
-        {
-        case DISABLED:
-          setResultCodeAndMessageNoInfoDisclosure(entryDN,
-              ResultCode.UNWILLING_TO_PERFORM,
-              ERR_ADD_SERVER_READONLY.get(String.valueOf(entryDN)));
-          return;
-
-        case INTERNAL_ONLY:
-          if (!(isInternalOperation() || isSynchronizationOperation()))
-          {
-            setResultCodeAndMessageNoInfoDisclosure(entryDN,
-                ResultCode.UNWILLING_TO_PERFORM,
-                ERR_ADD_SERVER_READONLY.get(String.valueOf(entryDN)));
-            return;
-          }
-          break;
-        }
-
-        switch (backend.getWritabilityMode())
-        {
-        case DISABLED:
-          setResultCodeAndMessageNoInfoDisclosure(entryDN,
-              ResultCode.UNWILLING_TO_PERFORM,
-              ERR_ADD_BACKEND_READONLY.get(String.valueOf(entryDN)));
-          return;
-
-        case INTERNAL_ONLY:
-          if (!(isInternalOperation() || isSynchronizationOperation()))
-          {
-            setResultCodeAndMessageNoInfoDisclosure(entryDN,
-                ResultCode.UNWILLING_TO_PERFORM,
-                ERR_ADD_BACKEND_READONLY.get(String.valueOf(entryDN)));
-            return;
-          }
-          break;
-        }
-      }
+      LocalBackendWorkflowElement.checkIfBackendIsWritable(backend, this,
+          entryDN, ERR_ADD_SERVER_READONLY, ERR_ADD_BACKEND_READONLY);
 
       if (noOp)
       {
diff --git a/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendDeleteOperation.java b/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendDeleteOperation.java
index e8c8095..8aa8a09 100644
--- a/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendDeleteOperation.java
+++ b/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendDeleteOperation.java
@@ -326,46 +326,8 @@
         return;
       }
 
-      // If it is not a private backend, then check to see if the server or
-      // backend is operating in read-only mode.
-      if (!backend.isPrivateBackend())
-      {
-        switch (DirectoryServer.getWritabilityMode())
-        {
-        case DISABLED:
-          setResultCodeAndMessageNoInfoDisclosure(entry,
-              ResultCode.UNWILLING_TO_PERFORM,
-              ERR_DELETE_SERVER_READONLY.get(String.valueOf(entryDN)));
-          return;
-
-        case INTERNAL_ONLY:
-          if (!(isInternalOperation() || isSynchronizationOperation()))
-          {
-            setResultCodeAndMessageNoInfoDisclosure(entry,
-                ResultCode.UNWILLING_TO_PERFORM,
-                ERR_DELETE_SERVER_READONLY.get(String.valueOf(entryDN)));
-            return;
-          }
-        }
-
-        switch (backend.getWritabilityMode())
-        {
-        case DISABLED:
-          setResultCodeAndMessageNoInfoDisclosure(entry,
-              ResultCode.UNWILLING_TO_PERFORM,
-              ERR_DELETE_BACKEND_READONLY.get(String.valueOf(entryDN)));
-          return;
-
-        case INTERNAL_ONLY:
-          if (!(isInternalOperation() || isSynchronizationOperation()))
-          {
-            setResultCodeAndMessageNoInfoDisclosure(entry,
-                ResultCode.UNWILLING_TO_PERFORM,
-                ERR_DELETE_BACKEND_READONLY.get(String.valueOf(entryDN)));
-            return;
-          }
-        }
-      }
+      LocalBackendWorkflowElement.checkIfBackendIsWritable(backend, this,
+          entryDN, ERR_DELETE_SERVER_READONLY, ERR_DELETE_BACKEND_READONLY);
 
       // The selected backend will have the responsibility of making sure that
       // the entry actually exists and does not have any children (or possibly
diff --git a/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyDNOperation.java b/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyDNOperation.java
index 06114da..7ed2707 100644
--- a/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyDNOperation.java
+++ b/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyDNOperation.java
@@ -484,49 +484,8 @@
         applyPreOpModifications(modifications, 0, false);
       }
 
-      // Actually perform the modify DN operation.
-      // This should include taking
-      // care of any synchronization that might be needed.
-      // 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(ERR_MODDN_SERVER_READONLY.get(String
-              .valueOf(entryDN)));
-          return;
-
-        case INTERNAL_ONLY:
-          if (!(isInternalOperation() || isSynchronizationOperation()))
-          {
-            setResultCode(ResultCode.UNWILLING_TO_PERFORM);
-            appendErrorMessage(ERR_MODDN_SERVER_READONLY.get(String
-                .valueOf(entryDN)));
-            return;
-          }
-        }
-
-        switch (currentBackend.getWritabilityMode())
-        {
-        case DISABLED:
-          setResultCode(ResultCode.UNWILLING_TO_PERFORM);
-          appendErrorMessage(ERR_MODDN_BACKEND_READONLY.get(String
-              .valueOf(entryDN)));
-          return;
-
-        case INTERNAL_ONLY:
-          if (!(isInternalOperation() || isSynchronizationOperation()))
-          {
-            setResultCode(ResultCode.UNWILLING_TO_PERFORM);
-            appendErrorMessage(ERR_MODDN_BACKEND_READONLY.get(String
-                .valueOf(entryDN)));
-            return;
-          }
-        }
-      }
+      LocalBackendWorkflowElement.checkIfBackendIsWritable(currentBackend,
+          this, entryDN, ERR_MODDN_SERVER_READONLY, ERR_MODDN_BACKEND_READONLY);
 
       if (noOp)
       {
diff --git a/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyOperation.java b/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyOperation.java
index 037df6e..e63a8b4 100644
--- a/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyOperation.java
+++ b/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyOperation.java
@@ -582,7 +582,8 @@
         return;
       }
 
-      checkWritability();
+      LocalBackendWorkflowElement.checkIfBackendIsWritable(backend, this,
+          entryDN, ERR_MODIFY_SERVER_READONLY, ERR_MODIFY_BACKEND_READONLY);
 
       if (noOp)
       {
@@ -1994,56 +1995,6 @@
 
 
   /**
-   * Checks to ensure that both the Directory Server and the backend are
-   * writable.
-   *
-   * @throws  DirectoryException  If the modify operation should not be allowed
-   *                              as a result of the writability check.
-   */
-  protected void checkWritability()
-          throws DirectoryException
-  {
-    // If it is not a private backend, then check to see if the server or
-    // backend is operating in read-only mode.
-    if (! backend.isPrivateBackend())
-    {
-      switch (DirectoryServer.getWritabilityMode())
-      {
-        case DISABLED:
-          throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM,
-                                       ERR_MODIFY_SERVER_READONLY.get(
-                                            String.valueOf(entryDN)));
-
-        case INTERNAL_ONLY:
-          if (! (isInternalOperation() || isSynchronizationOperation()))
-          {
-            throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM,
-                                         ERR_MODIFY_SERVER_READONLY.get(
-                                              String.valueOf(entryDN)));
-          }
-      }
-
-      switch (backend.getWritabilityMode())
-      {
-        case DISABLED:
-          throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM,
-                                       ERR_MODIFY_BACKEND_READONLY.get(
-                                            String.valueOf(entryDN)));
-
-        case INTERNAL_ONLY:
-          if (! isInternalOperation() || isSynchronizationOperation())
-          {
-            throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM,
-                                         ERR_MODIFY_BACKEND_READONLY.get(
-                                              String.valueOf(entryDN)));
-          }
-      }
-    }
-  }
-
-
-
-  /**
    * Handles any account status notifications that may be needed as a result of
    * modify processing.
    */
diff --git a/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendWorkflowElement.java b/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendWorkflowElement.java
index d71b152..efa37f3 100644
--- a/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendWorkflowElement.java
+++ b/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendWorkflowElement.java
@@ -33,6 +33,7 @@
 import java.util.concurrent.CopyOnWriteArrayList;
 
 import org.opends.messages.Message;
+import org.opends.messages.MessageDescriptor;
 import org.opends.server.admin.server.ConfigurationChangeListener;
 import org.opends.server.admin.server.ServerManagementContext;
 import org.opends.server.admin.std.server.BackendCfg;
@@ -801,5 +802,64 @@
   {
     return persistentSearches;
   }
+
+
+
+  /**
+   * Checks if an update operation can be performed against a backend. The
+   * operation will be rejected based on the server and backend writability
+   * modes.
+   *
+   * @param backend
+   *          The backend handling the update.
+   * @param op
+   *          The update operation.
+   * @param entryDN
+   *          The name of the entry being updated.
+   * @param serverMsg
+   *          The message to log if the update was rejected because the server
+   *          is read-only.
+   * @param backendMsg
+   *          The message to log if the update was rejected because the backend
+   *          is read-only.
+   * @throws DirectoryException
+   *           If the update operation has been rejected.
+   */
+  static void checkIfBackendIsWritable(Backend backend, Operation op,
+      DN entryDN, MessageDescriptor.Arg1<CharSequence> serverMsg,
+      MessageDescriptor.Arg1<CharSequence> backendMsg)
+      throws DirectoryException
+  {
+    if (!backend.isPrivateBackend())
+    {
+      switch (DirectoryServer.getWritabilityMode())
+      {
+      case DISABLED:
+        throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM,
+            serverMsg.get(String.valueOf(entryDN)));
+
+      case INTERNAL_ONLY:
+        if (!(op.isInternalOperation() || op.isSynchronizationOperation()))
+        {
+          throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM,
+              serverMsg.get(String.valueOf(entryDN)));
+        }
+      }
+
+      switch (backend.getWritabilityMode())
+      {
+      case DISABLED:
+        throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM,
+            backendMsg.get(String.valueOf(entryDN)));
+
+      case INTERNAL_ONLY:
+        if (!(op.isInternalOperation() || op.isSynchronizationOperation()))
+        {
+          throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM,
+              backendMsg.get(String.valueOf(entryDN)));
+        }
+      }
+    }
+  }
 }
 

--
Gitblit v1.10.0