From e42dc413aa0397458248ceb336a667ee314632f0 Mon Sep 17 00:00:00 2001
From: Jean-Noel Rouvignac <jean-noel.rouvignac@forgerock.com>
Date: Fri, 06 Dec 2013 16:13:01 +0000
Subject: [PATCH] OPENDJ-1088 (CR-2677) Wrong error message and result code when deleting branch as a user with insufficient access rights

---
 opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendAddOperation.java      |   13 -
 opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyOperation.java   |   32 +---
 opendj-sdk/opends/src/server/org/opends/server/types/AbstractOperation.java                                    |   30 +---
 opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendBindOperation.java     |   25 +--
 opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendWorkflowElement.java   |   60 +++++----
 opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyDNOperation.java |   30 +---
 opendj-sdk/opends/src/server/org/opends/server/replication/plugin/MultimasterReplication.java                  |   17 +-
 opendj-sdk/opends/src/server/org/opends/server/workflowelement/externalchangelog/ECLSearchOperation.java       |    7 
 opendj-sdk/opends/src/server/org/opends/server/types/Operation.java                                            |   10 -
 opendj-sdk/opends/src/server/org/opends/server/types/operation/PreParseOperation.java                          |   22 ---
 opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendSearchOperation.java   |   22 ---
 opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendCompareOperation.java  |   10 -
 opendj-sdk/opends/src/server/org/opends/server/core/OperationWrapper.java                                      |    9 -
 opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendDeleteOperation.java   |   42 ++----
 opendj-sdk/opends/src/server/org/opends/server/core/ExtendedOperationBasis.java                                |    9 +
 15 files changed, 114 insertions(+), 224 deletions(-)

diff --git a/opendj-sdk/opends/src/server/org/opends/server/core/ExtendedOperationBasis.java b/opendj-sdk/opends/src/server/org/opends/server/core/ExtendedOperationBasis.java
index 7b09c0f..b872dae 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/core/ExtendedOperationBasis.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/core/ExtendedOperationBasis.java
@@ -33,6 +33,7 @@
 import static org.opends.server.util.ServerConstants.*;
 
 import java.util.ArrayList;
+import java.util.Iterator;
 import java.util.List;
 
 import org.opends.server.api.ClientConnection;
@@ -324,10 +325,12 @@
       // Look at the controls included in the request and ensure that all
       // critical controls are supported by the handler.
       List<Control> requestControls = getRequestControls();
-      if ((requestControls != null) && (! requestControls.isEmpty()))
+      if (requestControls != null && !requestControls.isEmpty())
       {
-        for (Control c : requestControls)
+        for (Iterator<Control> iter = requestControls.iterator(); iter
+            .hasNext();)
         {
+          final Control c = iter.next();
           try
           {
             if (!AccessControlConfigManager.getInstance()
@@ -345,7 +348,7 @@
               {
                 // We don't want to process this non-critical control, so
                 // remove it.
-                removeRequestControl(c);
+                iter.remove();
                 continue;
               }
             }
diff --git a/opendj-sdk/opends/src/server/org/opends/server/core/OperationWrapper.java b/opendj-sdk/opends/src/server/org/opends/server/core/OperationWrapper.java
index 421a00c..d30d750 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/core/OperationWrapper.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/core/OperationWrapper.java
@@ -406,15 +406,6 @@
    * {@inheritDoc}
    */
   @Override
-  public void removeRequestControl(Control control)
-  {
-    operation.removeRequestControl(control);
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
   public void removeResponseControl(Control control)
   {
     operation.removeResponseControl(control);
diff --git a/opendj-sdk/opends/src/server/org/opends/server/replication/plugin/MultimasterReplication.java b/opendj-sdk/opends/src/server/org/opends/server/replication/plugin/MultimasterReplication.java
index 158ca25..fa30a1d 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/replication/plugin/MultimasterReplication.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/replication/plugin/MultimasterReplication.java
@@ -128,8 +128,10 @@
          * running later do not generate CSN, solve conflicts and forward the
          * operation to the replication server.
          */
-        for (Control c : op.getRequestControls())
+        final List<Control> controls = op.getRequestControls();
+        for (Iterator<Control> iter = controls.iterator(); iter.hasNext();)
         {
+          Control c = iter.next();
           if (c.getOID().equals(OID_REPLICATION_REPAIR_CONTROL))
           {
             op.setSynchronizationOperation(true);
@@ -139,25 +141,20 @@
             processed and the local backend will fail if it finds a control that
             it does not know about and that is marked as critical.
             */
-            List<Control> controls = op.getRequestControls();
-            controls.remove(c);
+            iter.remove();
             return null;
           }
         }
     }
 
 
-    LDAPReplicationDomain domain;
+    LDAPReplicationDomain domain = null;
     DN temp = dn;
-    do
+    while (domain == null && temp != null)
     {
       domain = domains.get(temp);
       temp = temp.getParentDNInSuffix();
-      if (temp == null)
-      {
-        break;
-      }
-    } while (domain == null);
+    }
 
     return domain;
   }
diff --git a/opendj-sdk/opends/src/server/org/opends/server/types/AbstractOperation.java b/opendj-sdk/opends/src/server/org/opends/server/types/AbstractOperation.java
index 3c1b334..3aa6f55 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/types/AbstractOperation.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/types/AbstractOperation.java
@@ -308,13 +308,6 @@
 
   /** {@inheritDoc} */
   @Override
-  public final void removeRequestControl(Control control)
-  {
-    requestControls.remove(control);
-  }
-
-  /** {@inheritDoc} */
-  @Override
   public final ResultCode getResultCode()
   {
     return resultCode;
@@ -404,14 +397,11 @@
   @Override
   public List<AdditionalLogItem> getAdditionalLogItems()
   {
-    if (additionalLogItems == null)
-    {
-      return Collections.emptyList();
-    }
-    else
+    if (additionalLogItems != null)
     {
       return Collections.unmodifiableList(additionalLogItems);
     }
+    return Collections.emptyList();
   }
 
   /** {@inheritDoc} */
@@ -548,14 +538,11 @@
   @Override
   public final DN getAuthorizationDN()
   {
-    if (authorizationEntry == null)
-    {
-      return DN.nullDN();
-    }
-    else
+    if (authorizationEntry != null)
     {
       return authorizationEntry.getDN();
     }
+    return DN.nullDN();
   }
 
   /** {@inheritDoc} */
@@ -730,7 +717,7 @@
   @Override
   public final long getProcessingTime()
   {
-    return (processingStopTime - processingStartTime);
+    return processingStopTime - processingStartTime;
   }
 
   /** {@inheritDoc} */
@@ -739,12 +726,9 @@
   {
     if(useNanoTime)
     {
-      return (processingStopNanoTime - processingStartNanoTime);
+      return processingStopNanoTime - processingStartNanoTime;
     }
-    else
-    {
-      return -1;
-    }
+    return -1;
   }
 
   /** {@inheritDoc} */
diff --git a/opendj-sdk/opends/src/server/org/opends/server/types/Operation.java b/opendj-sdk/opends/src/server/org/opends/server/types/Operation.java
index 12da6d8..1cac91f 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/types/Operation.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/types/Operation.java
@@ -155,16 +155,6 @@
   public abstract void addRequestControl(Control control);
 
   /**
-   * Removes the provided control from the set of request controls for
-   * this operation.  This method may only be called by pre-parse
-   * plugins.
-   *
-   * @param  control  The control to remove from the set of request
-   *                  controls for this operation.
-   */
-  public abstract void removeRequestControl(Control control);
-
-  /**
    * Retrieves the set of controls to include in the response to the
    * client.  The contents of this list must not be altered.
    *
diff --git a/opendj-sdk/opends/src/server/org/opends/server/types/operation/PreParseOperation.java b/opendj-sdk/opends/src/server/org/opends/server/types/operation/PreParseOperation.java
index fc80a44..cecdc26 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/types/operation/PreParseOperation.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/types/operation/PreParseOperation.java
@@ -23,19 +23,16 @@
  *
  *
  *      Copyright 2006-2008 Sun Microsystems, Inc.
- *      Portions copyright 2011 ForgeRock AS.
+ *      Portions copyright 2011-2013 ForgeRock AS.
  */
 package org.opends.server.types.operation;
+
 import java.util.List;
 
 import org.opends.messages.Message;
-
-
-
-import org.opends.server.types.*;
-
 import org.opends.messages.MessageBuilder;
-
+import org.opends.server.types.AdditionalLogItem;
+import org.opends.server.types.Control;
 
 /**
  * This class defines a set of methods that are available for use by
@@ -63,17 +60,6 @@
 
 
   /**
-   * Removes the provided control from the set of request controls for
-   * this operation.
-   *
-   * @param  control  The control to remove from the set of request
-   *                  controls for this operation.
-   */
-  public void removeRequestControl(Control control);
-
-
-
-  /**
    * Adds the provided control to the set of controls to include in
    * the response to the client.
    *
diff --git a/opendj-sdk/opends/src/server/org/opends/server/workflowelement/externalchangelog/ECLSearchOperation.java b/opendj-sdk/opends/src/server/org/opends/server/workflowelement/externalchangelog/ECLSearchOperation.java
index b1b943f..f853a4b 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/workflowelement/externalchangelog/ECLSearchOperation.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/workflowelement/externalchangelog/ECLSearchOperation.java
@@ -373,9 +373,10 @@
     List<Control> requestControls  = getRequestControls();
     if (requestControls != null && !requestControls.isEmpty())
     {
-      for (Control c : requestControls)
+      for (Iterator<Control> iter = requestControls.iterator(); iter.hasNext();)
       {
-        String  oid = c.getOID();
+        final Control c = iter.next();
+        final String oid = c.getOID();
 
         if (!AccessControlConfigManager.getInstance().getAccessControlHandler()
             .isAllowed(baseDN, this, c))
@@ -388,7 +389,7 @@
                 ERR_CONTROL_INSUFFICIENT_ACCESS_RIGHTS.get(oid));
           }
           // We don't want to process this non-critical control, so remove it.
-          removeRequestControl(c);
+          iter.remove();
           continue;
         }
 
diff --git a/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendAddOperation.java b/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendAddOperation.java
index 006b9f5..76f71eb 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendAddOperation.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendAddOperation.java
@@ -1139,20 +1139,16 @@
    */
   private void processControls(DN parentDN) throws DirectoryException
   {
+    LocalBackendWorkflowElement.removeAllDisallowedControls(parentDN, this);
+
     List<Control> requestControls = getRequestControls();
-    if ((requestControls != null) && (! requestControls.isEmpty()))
+    if (requestControls != null && !requestControls.isEmpty())
     {
       for (int i=0; i < requestControls.size(); i++)
       {
         Control c   = requestControls.get(i);
         String  oid = c.getOID();
 
-        if (!LocalBackendWorkflowElement.isControlAllowed(parentDN, this, c))
-        {
-          // Skip disallowed non-critical controls.
-          continue;
-        }
-
         if (oid.equals(OID_LDAP_ASSERTION))
         {
           // RFC 4528 mandates support for Add operation basically
@@ -1233,8 +1229,7 @@
 
           // The requester must have the PROXIED_AUTH privilege in order to
           // be able to use this control.
-          if (! getClientConnection().hasPrivilege(Privilege.PROXIED_AUTH,
-                                                   this))
+          if (!getClientConnection().hasPrivilege(Privilege.PROXIED_AUTH, this))
           {
             throw new DirectoryException(ResultCode.AUTHORIZATION_DENIED,
                            ERR_PROXYAUTH_INSUFFICIENT_PRIVILEGES.get());
diff --git a/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendBindOperation.java b/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendBindOperation.java
index d3dacb6..94e9500 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendBindOperation.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendBindOperation.java
@@ -388,23 +388,18 @@
    * @throws  DirectoryException  If there is a problem with any of the
    *                              controls.
    */
-  private void handleRequestControls()
-          throws DirectoryException
+  private void handleRequestControls() throws DirectoryException
   {
+    LocalBackendWorkflowElement.removeAllDisallowedControls(bindDN, this);
+
     List<Control> requestControls = getRequestControls();
-    if ((requestControls != null) && (! requestControls.isEmpty()))
+    if (requestControls != null && !requestControls.isEmpty())
     {
       for (int i=0; i < requestControls.size(); i++)
       {
         Control c   = requestControls.get(i);
         String  oid = c.getOID();
 
-        if (!LocalBackendWorkflowElement.isControlAllowed(bindDN, this, c))
-        {
-          // Skip disallowed non-critical controls.
-          continue;
-        }
-
         if (oid.equals(OID_AUTHZID_REQUEST))
         {
           returnAuthzID = true;
@@ -415,7 +410,6 @@
         }
 
         // NYI -- Add support for additional controls.
-
         else if (c.isCritical())
         {
           throw new DirectoryException(
@@ -520,7 +514,6 @@
         PasswordPolicy policy = pwPolicyState.getAuthenticationPolicy();
 
         AttributeType pwType = policy.getPasswordAttribute();
-
         List<Attribute> pwAttr = userEntry.getAttribute(pwType);
         if ((pwAttr == null) || (pwAttr.isEmpty()))
         {
@@ -652,8 +645,7 @@
    * @throws  DirectoryException  If a problem occurs that should cause the bind
    *                              operation to fail.
    */
-  protected boolean processAnonymousSimpleBind()
-          throws DirectoryException
+  protected boolean processAnonymousSimpleBind() throws DirectoryException
   {
     // If the server is in lockdown mode, then fail.
     if (DirectoryServer.lockdownMode())
@@ -663,8 +655,8 @@
     }
 
     // If there is a bind DN, then see whether that is acceptable.
-    if (DirectoryServer.bindWithDNRequiresPassword() &&
-        ((bindDN != null) && (! bindDN.isNullDN())))
+    if (DirectoryServer.bindWithDNRequiresPassword()
+        && bindDN != null && !bindDN.isNullDN())
     {
       throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM,
                                    ERR_BIND_DN_BUT_NO_PASSWORD.get());
@@ -693,8 +685,7 @@
    * @throws  DirectoryException  If a problem occurs that should cause the bind
    *                              operation to fail.
    */
-  private boolean processSASLBind()
-          throws DirectoryException
+  private boolean processSASLBind() throws DirectoryException
   {
     // Get the appropriate authentication handler for this request based
     // on the SASL mechanism.  If there is none, then fail.
diff --git a/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendCompareOperation.java b/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendCompareOperation.java
index 3a30f8e..6d6db9a 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendCompareOperation.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendCompareOperation.java
@@ -393,19 +393,15 @@
    */
   private void handleRequestControls() throws DirectoryException
   {
+    LocalBackendWorkflowElement.removeAllDisallowedControls(entryDN, this);
+
     List<Control> requestControls = getRequestControls();
-    if ((requestControls != null) && (! requestControls.isEmpty()))
+    if (requestControls != null && !requestControls.isEmpty())
     {
       for (Control c : requestControls)
       {
         String  oid = c.getOID();
 
-        if (!LocalBackendWorkflowElement.isControlAllowed(entryDN, this, c))
-        {
-          // Skip disallowed non-critical controls.
-          continue;
-        }
-
         if (oid.equals(OID_LDAP_ASSERTION))
         {
           LDAPAssertionRequestControl assertControl =
diff --git a/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendDeleteOperation.java b/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendDeleteOperation.java
index 8aa8a09..cc2c9c1 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendDeleteOperation.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendDeleteOperation.java
@@ -440,22 +440,16 @@
    * @throws  DirectoryException  If a problem occurs that should cause the
    *                              operation to fail.
    */
-  private void handleRequestControls()
-          throws DirectoryException
+  private void handleRequestControls() throws DirectoryException
   {
+    LocalBackendWorkflowElement.removeAllDisallowedControls(entryDN, this);
+
     List<Control> requestControls = getRequestControls();
-    if ((requestControls != null) && (! requestControls.isEmpty()))
+    if (requestControls != null && !requestControls.isEmpty())
     {
       for (Control c : requestControls)
       {
-        String  oid = c.getOID();
-
-        if (!LocalBackendWorkflowElement.isControlAllowed(entryDN, this, c))
-        {
-          // Skip disallowed non-critical controls.
-          continue;
-        }
-
+        final String oid = c.getOID();
         if (oid.equals(OID_LDAP_ASSERTION))
         {
           LDAPAssertionRequestControl assertControl =
@@ -494,8 +488,7 @@
             if (!filter.matchesEntry(entry))
             {
               throw newDirectoryException(entry, ResultCode.ASSERTION_FAILED,
-                  ERR_DELETE_ASSERTION_FAILED.get(String
-                      .valueOf(entryDN)));
+                  ERR_DELETE_ASSERTION_FAILED.get(String.valueOf(entryDN)));
             }
           }
           catch (DirectoryException de)
@@ -595,15 +588,12 @@
   }
 
 
-
   /**
    * Handle conflict resolution.
    * @return  {@code true} if processing should continue for the operation, or
    *          {@code false} if not.
    */
   private boolean handleConflictResolution() {
-      boolean returnVal = true;
-
       for (SynchronizationProvider<?> provider :
           DirectoryServer.getSynchronizationProviders()) {
           try {
@@ -614,8 +604,7 @@
                       result.getResultCode(), result.getErrorMessage());
                   setMatchedDN(result.getMatchedDN());
                   setReferralURLs(result.getReferralURLs());
-                  returnVal = false;
-                  break;
+                  return false;
               }
           } catch (DirectoryException de) {
               if (debugEnabled()) {
@@ -625,11 +614,10 @@
                       getConnectionID(), getOperationID(),
                       getExceptionMessage(de)));
               setResponseData(de);
-              returnVal = false;
-              break;
+              return false;
           }
       }
-      return returnVal;
+      return true;
   }
 
   /**
@@ -648,7 +636,7 @@
               logError(ERR_DELETE_SYNCH_POSTOP_FAILED.get(getConnectionID(),
                       getOperationID(), getExceptionMessage(de)));
               setResponseData(de);
-              break;
+              return;
           }
       }
   }
@@ -659,8 +647,6 @@
    *          {@code false} if not.
    */
   private boolean processPreOperation() {
-      boolean returnVal = true;
-
       for (SynchronizationProvider<?> provider :
           DirectoryServer.getSynchronizationProviders()) {
           try {
@@ -671,8 +657,7 @@
                   appendErrorMessage(result.getErrorMessage());
                   setMatchedDN(result.getMatchedDN());
                   setReferralURLs(result.getReferralURLs());
-                  returnVal = false;
-                  break;
+                  return false;
               }
           } catch (DirectoryException de) {
               if (debugEnabled())
@@ -682,10 +667,9 @@
               logError(ERR_DELETE_SYNCH_PREOP_FAILED.get(getConnectionID(),
                       getOperationID(), getExceptionMessage(de)));
               setResponseData(de);
-              returnVal = false;
-              break;
+              return false;
           }
       }
-      return returnVal;
+      return true;
   }
 }
diff --git a/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyDNOperation.java b/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyDNOperation.java
index 7ed2707..cdc08e1 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyDNOperation.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyDNOperation.java
@@ -586,6 +586,8 @@
    */
   private void handleRequestControls() throws DirectoryException
   {
+    LocalBackendWorkflowElement.removeAllDisallowedControls(entryDN, this);
+
     List<Control> requestControls = getRequestControls();
     if ((requestControls != null) && (! requestControls.isEmpty()))
     {
@@ -594,12 +596,6 @@
         Control c   = requestControls.get(i);
         String  oid = c.getOID();
 
-        if (!LocalBackendWorkflowElement.isControlAllowed(entryDN, this, c))
-        {
-          // Skip disallowed non-critical controls.
-          continue;
-        }
-
         if (oid.equals(OID_LDAP_ASSERTION))
         {
           LDAPAssertionRequestControl assertControl =
@@ -939,8 +935,6 @@
    */
   private boolean handleConflictResolution()
   {
-      boolean returnVal = true;
-
       for (SynchronizationProvider<?> provider :
           DirectoryServer.getSynchronizationProviders()) {
           try {
@@ -951,8 +945,7 @@
                   appendErrorMessage(result.getErrorMessage());
                   setMatchedDN(result.getMatchedDN());
                   setReferralURLs(result.getReferralURLs());
-                  returnVal = false;
-                  break;
+                  return false;
               }
           } catch (DirectoryException de) {
               if (debugEnabled()) {
@@ -963,11 +956,10 @@
                       getExceptionMessage(de)));
 
               setResponseData(de);
-              returnVal = false;
-              break;
+              return false;
           }
       }
-      return returnVal;
+      return true;
   }
 
   /**
@@ -977,8 +969,6 @@
    */
   private boolean processPreOperation()
   {
-      boolean returnVal = true;
-
       for (SynchronizationProvider<?> provider :
           DirectoryServer.getSynchronizationProviders()) {
           try {
@@ -989,8 +979,7 @@
                   appendErrorMessage(result.getErrorMessage());
                   setMatchedDN(result.getMatchedDN());
                   setReferralURLs(result.getReferralURLs());
-                  returnVal = false;
-                  break;
+                  return false;
               }
           } catch (DirectoryException de) {
               if (debugEnabled()) {
@@ -999,11 +988,10 @@
               logError(ERR_MODDN_SYNCH_PREOP_FAILED.get(getConnectionID(),
                       getOperationID(), getExceptionMessage(de)));
               setResponseData(de);
-              returnVal = false;
-              break;
+              return false;
           }
       }
-      return returnVal;
+      return true;
   }
 
   /**
@@ -1022,7 +1010,7 @@
               logError(ERR_MODDN_SYNCH_POSTOP_FAILED.get(getConnectionID(),
                       getOperationID(), getExceptionMessage(de)));
               setResponseData(de);
-              break;
+              return;
           }
       }
   }
diff --git a/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyOperation.java b/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyOperation.java
index e63a8b4..d92669a 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyOperation.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyOperation.java
@@ -682,9 +682,10 @@
    * @throws  DirectoryException  If a problem is encountered with any of the
    *                              controls.
    */
-  protected void processRequestControls()
-          throws DirectoryException
+  protected void processRequestControls() throws DirectoryException
   {
+    LocalBackendWorkflowElement.removeAllDisallowedControls(entryDN, this);
+
     List<Control> requestControls = getRequestControls();
     if ((requestControls != null) && (! requestControls.isEmpty()))
     {
@@ -693,12 +694,6 @@
         Control c   = requestControls.get(i);
         String  oid = c.getOID();
 
-        if (!LocalBackendWorkflowElement.isControlAllowed(entryDN, this, c))
-        {
-          // Skip disallowed non-critical controls.
-          continue;
-        }
-
         if (oid.equals(OID_LDAP_ASSERTION))
         {
           LDAPAssertionRequestControl assertControl =
@@ -2081,8 +2076,6 @@
    *          {@code false} if not.
    */
   protected boolean handleConflictResolution() {
-      boolean returnVal = true;
-
       for (SynchronizationProvider<?> provider :
           DirectoryServer.getSynchronizationProviders()) {
           try {
@@ -2093,8 +2086,7 @@
                       result.getResultCode(), result.getErrorMessage());
                   setMatchedDN(result.getMatchedDN());
                   setReferralURLs(result.getReferralURLs());
-                  returnVal = false;
-                  break;
+                  return false;
               }
           } catch (DirectoryException de) {
               if (debugEnabled()) {
@@ -2104,11 +2096,10 @@
                       getConnectionID(), getOperationID(),
                       getExceptionMessage(de)));
               setResponseData(de);
-              returnVal = false;
-              break;
+              return false;
           }
       }
-      return returnVal;
+      return true;
   }
 
   /**
@@ -2117,7 +2108,6 @@
    *          {@code false} if not.
    */
   protected boolean processPreOperation() {
-      boolean returnVal = true;
       for (SynchronizationProvider<?> provider :
           DirectoryServer.getSynchronizationProviders()) {
           try {
@@ -2128,8 +2118,7 @@
                   appendErrorMessage(result.getErrorMessage());
                   setMatchedDN(result.getMatchedDN());
                   setReferralURLs(result.getReferralURLs());
-                  returnVal = false;
-                  break;
+                  return false;
               }
           } catch (DirectoryException de) {
               if (debugEnabled()) {
@@ -2138,11 +2127,10 @@
               logError(ERR_MODIFY_SYNCH_PREOP_FAILED.get(getConnectionID(),
                       getOperationID(), getExceptionMessage(de)));
               setResponseData(de);
-              returnVal = false;
-              break;
+              return false;
           }
       }
-      return returnVal;
+      return true;
   }
 
   /**
@@ -2160,7 +2148,7 @@
               logError(ERR_MODIFY_SYNCH_POSTOP_FAILED.get(getConnectionID(),
                       getOperationID(), getExceptionMessage(de)));
               setResponseData(de);
-              break;
+              return;
           }
       }
   }
diff --git a/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendSearchOperation.java b/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendSearchOperation.java
index 19035f9..599ea9b 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendSearchOperation.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendSearchOperation.java
@@ -32,17 +32,8 @@
 import org.opends.server.api.Backend;
 import org.opends.server.api.ClientConnection;
 import org.opends.server.api.plugin.PluginResult;
-import org.opends.server.controls.LDAPAssertionRequestControl;
-import org.opends.server.controls.MatchedValuesControl;
-import org.opends.server.controls.PersistentSearchControl;
-import org.opends.server.controls.ProxiedAuthV1Control;
-import org.opends.server.controls.ProxiedAuthV2Control;
-import org.opends.server.controls.SubentriesControl;
-import org.opends.server.core.AccessControlConfigManager;
-import org.opends.server.core.DirectoryServer;
-import org.opends.server.core.PersistentSearch;
-import org.opends.server.core.SearchOperationWrapper;
-import org.opends.server.core.SearchOperation;
+import org.opends.server.controls.*;
+import org.opends.server.core.*;
 import org.opends.server.loggers.debug.DebugTracer;
 import org.opends.server.types.*;
 import org.opends.server.types.operation.PostOperationSearchOperation;
@@ -342,6 +333,8 @@
    */
   private void handleRequestControls() throws DirectoryException
   {
+    LocalBackendWorkflowElement.removeAllDisallowedControls(baseDN, this);
+
     List<Control> requestControls  = getRequestControls();
     if ((requestControls != null) && (! requestControls.isEmpty()))
     {
@@ -350,19 +343,12 @@
         Control c   = requestControls.get(i);
         String  oid = c.getOID();
 
-        if (!LocalBackendWorkflowElement.isControlAllowed(baseDN, this, c))
-        {
-          // Skip disallowed non-critical controls.
-          continue;
-        }
-
         if (oid.equals(OID_LDAP_ASSERTION))
         {
           LDAPAssertionRequestControl assertControl =
                 getRequestControl(LDAPAssertionRequestControl.DECODER);
 
           SearchFilter assertionFilter;
-
           try
           {
             assertionFilter = assertControl.getSearchFilter();
diff --git a/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendWorkflowElement.java b/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendWorkflowElement.java
index 497fd6b..6f7e665 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendWorkflowElement.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendWorkflowElement.java
@@ -28,6 +28,7 @@
 package org.opends.server.workflowelement.localbackend;
 
 import java.util.ArrayList;
+import java.util.Iterator;
 import java.util.List;
 import java.util.TreeMap;
 import java.util.concurrent.CopyOnWriteArrayList;
@@ -324,42 +325,51 @@
 
 
   /**
-   * Determine whether or not the provided request control is permitted by the
-   * access control policy. If it is not allowed, then abort the operation if
-   * the control was critical, otherwise ignore it.
+   * Removes all the disallowed request controls from the provided operation.
+   * <p>
+   * As per RFC 4511 4.1.11, if a disallowed request control is critical, then a
+   * DirectoryException is thrown with unavailableCriticalExtension. Otherwise,
+   * if the disallowed request control is non critical, it is removed because we
+   * do not want the backend to process it.
    *
    * @param targetDN
-   *          The operation target DN.
+   *          the target DN on which the operation applies
    * @param op
-   *          The operation.
-   * @param control
-   *          The request control.
-   * @return {@code true} if access is allowed, or {@code false} if access is
-   *         not allowed, but the control is non-critical and should be ignored.
+   *          the operation currently processed
    * @throws DirectoryException
-   *           If access is not allowed and the control is critical.
+   *           If a disallowed request control is critical, thrown with
+   *           unavailableCriticalExtension. If an error occurred while
+   *           performing the access control check. For example, if an attribute
+   *           could not be decoded. Care must be taken not to expose any
+   *           potentially sensitive information in the exception.
    */
-  static boolean isControlAllowed(DN targetDN, Operation op, Control control)
+  static void removeAllDisallowedControls(DN targetDN, Operation op)
       throws DirectoryException
   {
-    if (!AccessControlConfigManager.getInstance().getAccessControlHandler()
-        .isAllowed(targetDN, op, control))
+    final List<Control> requestControls = op.getRequestControls();
+    if (requestControls != null && !requestControls.isEmpty())
     {
-      // As per RFC 4511 4.1.11.
-      if (control.isCritical())
+      for (Iterator<Control> iter = requestControls.iterator(); iter.hasNext();)
       {
-        throw new DirectoryException(ResultCode.UNAVAILABLE_CRITICAL_EXTENSION,
-            ERR_CONTROL_INSUFFICIENT_ACCESS_RIGHTS.get(control.getOID()));
-      }
-      else
-      {
-        // We do not want the backend to process this non-critical control, so
-        // remove it.
-        op.removeRequestControl(control);
-        return false;
+        final Control control = iter.next();
+
+        if (!AccessControlConfigManager.getInstance().getAccessControlHandler()
+            .isAllowed(targetDN, op, control))
+        {
+          // As per RFC 4511 4.1.11.
+          if (control.isCritical())
+          {
+            throw new DirectoryException(
+                ResultCode.UNAVAILABLE_CRITICAL_EXTENSION,
+                ERR_CONTROL_INSUFFICIENT_ACCESS_RIGHTS.get(control.getOID()));
+          }
+
+          // We do not want the backend to process this non-critical control, so
+          // remove it.
+          iter.remove();
+        }
       }
     }
-    return true;
   }
 
   /**

--
Gitblit v1.10.0