mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

Jean-Noel Rouvignac
25.21.2013 fe4d6b1f8ee49c858ca2644851377ba2402d9509
opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyOperation.java
@@ -70,8 +70,6 @@
   */
  private static final DebugTracer TRACER = getTracer();
  /**
   * The backend in which the target entry exists.
   */
@@ -295,40 +293,47 @@
    // Check for a request to cancel this operation.
    checkIfCanceled(false);
    BooleanHolder executePostOpPlugins = new BooleanHolder(false);
    processModify(executePostOpPlugins);
    // If the password policy request control was included, then make sure we
    // send the corresponding response control.
    if (pwPolicyControlRequested)
    try
    {
      addResponseControl(new PasswordPolicyResponseControl(null, 0,
                                                           pwpErrorType));
    }
      BooleanHolder executePostOpPlugins = new BooleanHolder(false);
      processModify(executePostOpPlugins);
    // Invoke the post-operation or post-synchronization modify plugins.
    PluginConfigManager pluginConfigManager =
        DirectoryServer.getPluginConfigManager();
    if (isSynchronizationOperation())
    {
      if (getResultCode() == ResultCode.SUCCESS)
      // If the password policy request control was included, then make sure we
      // send the corresponding response control.
      if (pwPolicyControlRequested)
      {
        pluginConfigManager.invokePostSynchronizationModifyPlugins(this);
        addResponseControl(new PasswordPolicyResponseControl(null, 0,
            pwpErrorType));
      }
      // Invoke the post-operation or post-synchronization modify plugins.
      PluginConfigManager pluginConfigManager =
          DirectoryServer.getPluginConfigManager();
      if (isSynchronizationOperation())
      {
        if (getResultCode() == ResultCode.SUCCESS)
        {
          pluginConfigManager.invokePostSynchronizationModifyPlugins(this);
        }
      }
      else if (executePostOpPlugins.value)
      {
        // FIXME -- Should this also be done while holding the locks?
        PluginResult.PostOperation postOpResult =
            pluginConfigManager.invokePostOperationModifyPlugins(this);
        if (!postOpResult.continueProcessing())
        {
          setResultCode(postOpResult.getResultCode());
          appendErrorMessage(postOpResult.getErrorMessage());
          setMatchedDN(postOpResult.getMatchedDN());
          setReferralURLs(postOpResult.getReferralURLs());
          return;
        }
      }
    }
    else if (executePostOpPlugins.value)
    finally
    {
      // FIXME -- Should this also be done while holding the locks?
      PluginResult.PostOperation postOpResult =
           pluginConfigManager.invokePostOperationModifyPlugins(this);
      if (!postOpResult.continueProcessing())
      {
        setResultCode(postOpResult.getResultCode());
        appendErrorMessage(postOpResult.getErrorMessage());
        setMatchedDN(postOpResult.getMatchedDN());
        setReferralURLs(postOpResult.getReferralURLs());
        return;
      }
      LocalBackendWorkflowElement.filterNonDisclosableMatchedDN(this);
    }
@@ -407,16 +412,16 @@
    // Acquire a write lock on the target entry.
    final Lock entryLock = LockManager.lockWrite(entryDN);
    if (entryLock == null)
    {
      setResultCode(ResultCode.BUSY);
      appendErrorMessage(ERR_MODIFY_CANNOT_LOCK_ENTRY.get(String
          .valueOf(entryDN)));
      return;
    }
    try
    {
      if (entryLock == null)
      {
        setResultCodeAndMessageNoInfoDisclosure(currentEntry, ResultCode.BUSY,
            ERR_MODIFY_CANNOT_LOCK_ENTRY.get(String.valueOf(entryDN)));
        return;
      }
      // Check for a request to cancel this operation.
      checkIfCanceled(false);
@@ -480,12 +485,9 @@
      // Create a duplicate of the entry and apply the changes to it.
      modifiedEntry = currentEntry.duplicate(false);
      if (!noOp)
      if (!noOp && !handleConflictResolution())
      {
        if (!handleConflictResolution())
        {
          return;
        }
        return;
      }
      handleSchemaProcessing();
@@ -505,9 +507,10 @@
        if (!AccessControlConfigManager.getInstance().getAccessControlHandler()
            .isAllowed(this))
        {
          setResultCode(ResultCode.INSUFFICIENT_ACCESS_RIGHTS);
          appendErrorMessage(ERR_MODIFY_AUTHZ_INSUFFICIENT_ACCESS_RIGHTS
              .get(String.valueOf(entryDN)));
          setResultCodeAndMessageNoInfoDisclosure(modifiedEntry,
              ResultCode.INSUFFICIENT_ACCESS_RIGHTS,
              ERR_MODIFY_AUTHZ_INSUFFICIENT_ACCESS_RIGHTS.get(String
                  .valueOf(entryDN)));
          return;
        }
      }
@@ -620,15 +623,33 @@
      }
      setResponseData(de);
      return;
    }
    finally
    {
      LockManager.unlock(entryDN, entryLock);
      if (entryLock != null)
      {
        LockManager.unlock(entryDN, entryLock);
      }
      processSynchPostOperationPlugins();
    }
  }
  private DirectoryException newDirectoryException(Entry entry,
      ResultCode resultCode, Message message) throws DirectoryException
  {
    return LocalBackendWorkflowElement.newDirectoryException(this, entry, null,
        resultCode, message, ResultCode.NO_SUCH_OBJECT,
        ERR_MODIFY_NO_SUCH_ENTRY.get(String.valueOf(entryDN)));
  }
  private void setResultCodeAndMessageNoInfoDisclosure(Entry entry,
      ResultCode realResultCode, Message realMessage) throws DirectoryException
  {
    LocalBackendWorkflowElement.setResultCodeAndMessageNoInfoDisclosure(this,
        entry, null, realResultCode, realMessage, ResultCode.NO_SUCH_OBJECT,
        ERR_MODIFY_NO_SUCH_ENTRY.get(String.valueOf(entryDN)));
  }
  private DN findMatchedDN(DN entryDN)
  {
    try
@@ -694,7 +715,7 @@
              TRACER.debugCaught(DebugLogLevel.ERROR, de);
            }
            throw new DirectoryException(de.getResultCode(),
            throw newDirectoryException(currentEntry, de.getResultCode(),
                           ERR_MODIFY_CANNOT_PROCESS_ASSERTION_FILTER.get(
                                String.valueOf(entryDN),
                                de.getMessageObject()));
@@ -714,9 +735,9 @@
          {
            if (!filter.matchesEntry(currentEntry))
            {
              throw new DirectoryException(ResultCode.ASSERTION_FAILED,
                  ERR_MODIFY_ASSERTION_FAILED.get(String
                      .valueOf(entryDN)));
              throw newDirectoryException(currentEntry,
                  ResultCode.ASSERTION_FAILED,
                  ERR_MODIFY_ASSERTION_FAILED.get(String.valueOf(entryDN)));
            }
          }
          catch (DirectoryException de)
@@ -731,7 +752,7 @@
              TRACER.debugCaught(DebugLogLevel.ERROR, de);
            }
            throw new DirectoryException(de.getResultCode(),
            throw newDirectoryException(currentEntry, de.getResultCode(),
                           ERR_MODIFY_CANNOT_PROCESS_ASSERTION_FILTER.get(
                                String.valueOf(entryDN),
                                de.getMessageObject()));
@@ -825,7 +846,7 @@
        {
          if ((backend == null) || (! backend.supportsControl(oid)))
          {
            throw new DirectoryException(
            throw newDirectoryException(currentEntry,
                           ResultCode.UNAVAILABLE_CRITICAL_EXTENSION,
                           ERR_MODIFY_UNSUPPORTED_CRITICAL_CONTROL.get(
                                String.valueOf(entryDN), oid));
@@ -858,8 +879,9 @@
        if (! (isInternalOperation() || isSynchronizationOperation() ||
                m.isInternal()))
        {
          throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
                  ERR_MODIFY_ATTR_IS_NO_USER_MOD.get(
          throw newDirectoryException(currentEntry,
              ResultCode.CONSTRAINT_VIOLATION,
              ERR_MODIFY_ATTR_IS_NO_USER_MOD.get(
                          String.valueOf(entryDN), a.getName()));
        }
      }
@@ -875,8 +897,9 @@
          if (! (isInternalOperation() || isSynchronizationOperation() ||
                  m.isInternal()))
          {
            throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
                    ERR_MODIFY_ATTR_IS_OBSOLETE.get(
            throw newDirectoryException(currentEntry,
                ResultCode.CONSTRAINT_VIOLATION,
                ERR_MODIFY_ATTR_IS_OBSOLETE.get(
                            String.valueOf(entryDN), a.getName()));
          }
        }
@@ -1379,7 +1402,7 @@
    // attribute.
    if (attr.isEmpty())
    {
      throw new DirectoryException(ResultCode.PROTOCOL_ERROR,
      throw newDirectoryException(currentEntry, ResultCode.PROTOCOL_ERROR,
          ERR_MODIFY_ADD_NO_VALUES.get(String.valueOf(entryDN),
              attr.getName()));
    }
@@ -1403,15 +1426,17 @@
            if (!syntax.isHumanReadable() || syntax.isBinary())
            {
              // Value is not human-readable
              throw new DirectoryException(ResultCode.INVALID_ATTRIBUTE_SYNTAX,
                ERR_MODIFY_ADD_INVALID_SYNTAX_NO_VALUE.get(
                    String.valueOf(entryDN), attr.getName(), invalidReason));
              throw newDirectoryException(currentEntry,
                  ResultCode.INVALID_ATTRIBUTE_SYNTAX,
                  ERR_MODIFY_ADD_INVALID_SYNTAX_NO_VALUE.get(
                      String.valueOf(entryDN), attr.getName(), invalidReason));
            }
            else
            {
              throw new DirectoryException(ResultCode.INVALID_ATTRIBUTE_SYNTAX,
                ERR_MODIFY_ADD_INVALID_SYNTAX.get(String.valueOf(entryDN), attr
                    .getName(), v.getValue().toString(), invalidReason));
              throw newDirectoryException(currentEntry,
                  ResultCode.INVALID_ATTRIBUTE_SYNTAX,
                  ERR_MODIFY_ADD_INVALID_SYNTAX.get(String.valueOf(entryDN),
                      attr.getName(), v.getValue().toString(), invalidReason));
            }
          }
        }
@@ -1455,16 +1480,16 @@
    // Add the provided attribute or merge an existing attribute with
    // the values of the new attribute. If there are any duplicates,
    // then fail.
    List<AttributeValue> duplicateValues =
      new LinkedList<AttributeValue>();
    List<AttributeValue> duplicateValues = new LinkedList<AttributeValue>();
    modifiedEntry.addAttribute(attr, duplicateValues);
    if (!duplicateValues.isEmpty() && !permissiveModify)
    {
      String duplicateValuesStr = collectionToString(duplicateValues, ", ");
      throw new DirectoryException(ResultCode.ATTRIBUTE_OR_VALUE_EXISTS,
          ERR_MODIFY_ADD_DUPLICATE_VALUE.get(String.valueOf(entryDN), attr
              .getName(), duplicateValuesStr));
      throw newDirectoryException(currentEntry,
          ResultCode.ATTRIBUTE_OR_VALUE_EXISTS,
          ERR_MODIFY_ADD_DUPLICATE_VALUE.get(
              String.valueOf(entryDN), attr.getName(), duplicateValuesStr));
    }
  }
@@ -1505,16 +1530,16 @@
      ObjectClass oc = DirectoryServer.getObjectClass(lowerName);
      if (oc == null)
      {
        Message message = ERR_ENTRY_ADD_UNKNOWN_OC.get(name, String
            .valueOf(entryDN));
        throw new DirectoryException(ResultCode.OBJECTCLASS_VIOLATION, message);
        throw newDirectoryException(currentEntry,
            ResultCode.OBJECTCLASS_VIOLATION,
            ERR_ENTRY_ADD_UNKNOWN_OC.get(name, String.valueOf(entryDN)));
      }
      if (oc.isObsolete())
      {
        Message message = ERR_ENTRY_ADD_OBSOLETE_OC.get(name, String
            .valueOf(entryDN));
        throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message);
        throw newDirectoryException(currentEntry,
            ResultCode.CONSTRAINT_VIOLATION,
            ERR_ENTRY_ADD_OBSOLETE_OC.get(name, String.valueOf(entryDN)));
      }
    }
  }
@@ -1551,10 +1576,10 @@
            (! modifiedEntry.hasValue(t, attr.getOptions(),
                                      rdn.getAttributeValue(t))))
        {
          throw new DirectoryException(ResultCode.NOT_ALLOWED_ON_RDN,
                                       ERR_MODIFY_DELETE_RDN_ATTR.get(
                                            String.valueOf(entryDN),
                                            attr.getName()));
          throw newDirectoryException(currentEntry,
              ResultCode.NOT_ALLOWED_ON_RDN,
              ERR_MODIFY_DELETE_RDN_ATTR.get(
                  String.valueOf(entryDN), attr.getName()));
        }
      }
      else
@@ -1563,10 +1588,10 @@
        {
          String missingValuesStr = collectionToString(missingValues, ", ");
          throw new DirectoryException(ResultCode.NO_SUCH_ATTRIBUTE,
                       ERR_MODIFY_DELETE_MISSING_VALUES.get(
                            String.valueOf(entryDN), attr.getName(),
                            missingValuesStr));
          throw newDirectoryException(currentEntry,
              ResultCode.NO_SUCH_ATTRIBUTE,
              ERR_MODIFY_DELETE_MISSING_VALUES.get(
                  String.valueOf(entryDN), attr.getName(), missingValuesStr));
        }
      }
    }
@@ -1574,7 +1599,7 @@
    {
      if (! permissiveModify)
      {
        throw new DirectoryException(ResultCode.NO_SUCH_ATTRIBUTE,
        throw newDirectoryException(currentEntry, ResultCode.NO_SUCH_ATTRIBUTE,
                     ERR_MODIFY_DELETE_NO_SUCH_ATTR.get(
                          String.valueOf(entryDN), attr.getName()));
      }
@@ -1615,15 +1640,17 @@
            if (!syntax.isHumanReadable() || syntax.isBinary())
            {
              // Value is not human-readable
              throw new DirectoryException(ResultCode.INVALID_ATTRIBUTE_SYNTAX,
                ERR_MODIFY_REPLACE_INVALID_SYNTAX_NO_VALUE.get(
                    String.valueOf(entryDN), attr.getName(), invalidReason));
              throw newDirectoryException(currentEntry,
                  ResultCode.INVALID_ATTRIBUTE_SYNTAX,
                  ERR_MODIFY_REPLACE_INVALID_SYNTAX_NO_VALUE.get(
                      String.valueOf(entryDN), attr.getName(), invalidReason));
            }
            else
            {
              throw new DirectoryException(ResultCode.INVALID_ATTRIBUTE_SYNTAX,
                ERR_MODIFY_REPLACE_INVALID_SYNTAX.get(String.valueOf(entryDN),
                    attr.getName(), v.getValue().toString(), invalidReason));
              throw newDirectoryException(currentEntry,
                  ResultCode.INVALID_ATTRIBUTE_SYNTAX,
                  ERR_MODIFY_REPLACE_INVALID_SYNTAX.get(String.valueOf(entryDN),
                      attr.getName(), v.getValue().toString(), invalidReason));
            }
          }
        }
@@ -1673,7 +1700,7 @@
        && (!modifiedEntry.hasValue(t, attr.getOptions(), rdn
            .getAttributeValue(t))))
    {
      throw new DirectoryException(ResultCode.NOT_ALLOWED_ON_RDN,
      throw newDirectoryException(modifiedEntry, ResultCode.NOT_ALLOWED_ON_RDN,
          ERR_MODIFY_DELETE_RDN_ATTR.get(String.valueOf(entryDN), attr
              .getName()));
    }
@@ -1699,7 +1726,7 @@
    RDN rdn = modifiedEntry.getDN().getRDN();
    if ((rdn != null) && rdn.hasAttributeType(t))
    {
      throw new DirectoryException(ResultCode.NOT_ALLOWED_ON_RDN,
      throw newDirectoryException(modifiedEntry, ResultCode.NOT_ALLOWED_ON_RDN,
          ERR_MODIFY_INCREMENT_RDN.get(String.valueOf(entryDN),
              attr.getName()));
    }
@@ -1708,14 +1735,14 @@
    // an integer.
    if (attr.isEmpty())
    {
      throw new DirectoryException(ResultCode.PROTOCOL_ERROR,
      throw newDirectoryException(modifiedEntry, ResultCode.PROTOCOL_ERROR,
          ERR_MODIFY_INCREMENT_REQUIRES_VALUE.get(String.valueOf(entryDN), attr
              .getName()));
    }
    if (attr.size() > 1)
    {
      throw new DirectoryException(ResultCode.PROTOCOL_ERROR,
      throw newDirectoryException(modifiedEntry, ResultCode.PROTOCOL_ERROR,
          ERR_MODIFY_INCREMENT_REQUIRES_SINGLE_VALUE.get(String
              .valueOf(entryDN), attr.getName()));
    }
@@ -1743,7 +1770,8 @@
    Attribute a = modifiedEntry.getExactAttribute(t, attr.getOptions());
    if (a == null)
    {
      throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
      throw newDirectoryException(modifiedEntry,
          ResultCode.CONSTRAINT_VIOLATION,
          ERR_MODIFY_INCREMENT_REQUIRES_EXISTING_VALUE.get(String
              .valueOf(entryDN), attr.getName()));
    }
@@ -2110,8 +2138,8 @@
              SynchronizationProviderResult result =
                  provider.handleConflictResolution(this);
              if (! result.continueProcessing()) {
                  setResultCode(result.getResultCode());
                  appendErrorMessage(result.getErrorMessage());
                  setResultCodeAndMessageNoInfoDisclosure(modifiedEntry,
                      result.getResultCode(), result.getErrorMessage());
                  setMatchedDN(result.getMatchedDN());
                  setReferralURLs(result.getReferralURLs());
                  returnVal = false;