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

Matthew Swift
10.18.2015 c25504d1f9e2d02afb0f14093a0d16d6b6efb913
OPENDJ-1878: remove unnecessary entry read locks.

Some code was using read-locks before calling Backend.getEntry(DN), but read-locks are no longer required.
11 files modified
747 ■■■■■ changed files
opendj-server-legacy/src/main/java/org/opends/server/authorization/dseecompat/AciHandler.java 13 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/controls/ProxiedAuthV1Control.java 72 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/controls/ProxiedAuthV2Control.java 37 ●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/extensions/CRAMMD5SASLMechanismHandler.java 16 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/extensions/PlainSASLMechanismHandler.java 16 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/extensions/SASLContext.java 13 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/extensions/SubjectEqualsDNCertificateMapper.java 17 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/types/Entry.java 171 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/workflowelement/localbackend/LocalBackendBindOperation.java 311 ●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/workflowelement/localbackend/LocalBackendCompareOperation.java 22 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/test/java/org/opends/server/replication/ReplicationTestCase.java 59 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/authorization/dseecompat/AciHandler.java
@@ -30,8 +30,6 @@
import java.util.LinkedList;
import java.util.List;
import java.util.SortedSet;
import java.util.concurrent.locks.Lock;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.i18n.slf4j.LocalizedLogger;
import org.forgerock.opendj.config.server.ConfigException;
@@ -914,13 +912,6 @@
   */
  private boolean aciCheckSuperiorEntry(DN superiorDN, ModifyDNOperation op)
  {
    final Lock entryLock = LockManager.lockRead(superiorDN);
    if (entryLock == null)
    {
      logger.warn(WARN_ACI_HANDLER_CANNOT_LOCK_NEW_SUPERIOR_USER, superiorDN);
      return false;
    }
    try
    {
      Entry superiorEntry = DirectoryServer.getEntry(superiorDN);
@@ -936,10 +927,6 @@
    {
      return false;
    }
    finally
    {
      LockManager.unlock(superiorDN, entryLock);
    }
  }
opendj-server-legacy/src/main/java/org/opends/server/controls/ProxiedAuthV1Control.java
@@ -27,8 +27,6 @@
package org.opends.server.controls;
import java.io.IOException;
import java.util.concurrent.locks.Lock;
import org.forgerock.i18n.LocalizableMessage;
import org.opends.server.api.AuthenticationPolicyState;
import org.opends.server.core.DirectoryServer;
@@ -283,56 +281,42 @@
    }
    final Lock entryLock = LockManager.lockRead(authzDN);
    if (entryLock == null)
    Entry userEntry = DirectoryServer.getEntry(authzDN);
    if (userEntry == null)
    {
      throw new DirectoryException(ResultCode.BUSY,
          ERR_PROXYAUTH1_CANNOT_LOCK_USER.get(authzDN));
      // The requested user does not exist.
      LocalizableMessage message = ERR_PROXYAUTH1_NO_SUCH_USER.get(authzDN);
      throw new DirectoryException(ResultCode.AUTHORIZATION_DENIED, message);
    }
    try
    // FIXME -- We should provide some mechanism for enabling debug
    // processing.
    AuthenticationPolicyState state = AuthenticationPolicyState.forUser(
        userEntry, false);
    if (state.isDisabled())
    {
      Entry userEntry = DirectoryServer.getEntry(authzDN);
      if (userEntry == null)
      LocalizableMessage message = ERR_PROXYAUTH1_UNUSABLE_ACCOUNT.get(userEntry.getName());
      throw new DirectoryException(ResultCode.AUTHORIZATION_DENIED, message);
    }
    if (state.isPasswordPolicy())
    {
      PasswordPolicyState pwpState = (PasswordPolicyState) state;
      if (pwpState.isAccountExpired() ||
          pwpState.lockedDueToFailures() ||
          pwpState.lockedDueToIdleInterval() ||
          pwpState.lockedDueToMaximumResetAge() ||
          pwpState.isPasswordExpired())
      {
        // The requested user does not exist.
        LocalizableMessage message = ERR_PROXYAUTH1_NO_SUCH_USER.get(authzDN);
        LocalizableMessage message = ERR_PROXYAUTH1_UNUSABLE_ACCOUNT.get(authzDN);
        throw new DirectoryException(ResultCode.AUTHORIZATION_DENIED, message);
      }
      // FIXME -- We should provide some mechanism for enabling debug
      // processing.
      AuthenticationPolicyState state = AuthenticationPolicyState.forUser(
          userEntry, false);
      if (state.isDisabled())
      {
        LocalizableMessage message = ERR_PROXYAUTH1_UNUSABLE_ACCOUNT.get(userEntry.getName());
        throw new DirectoryException(ResultCode.AUTHORIZATION_DENIED, message);
      }
      if (state.isPasswordPolicy())
      {
        PasswordPolicyState pwpState = (PasswordPolicyState) state;
        if (pwpState.isAccountExpired() ||
            pwpState.lockedDueToFailures() ||
            pwpState.lockedDueToIdleInterval() ||
            pwpState.lockedDueToMaximumResetAge() ||
            pwpState.isPasswordExpired())
        {
          LocalizableMessage message = ERR_PROXYAUTH1_UNUSABLE_ACCOUNT.get(authzDN);
          throw new DirectoryException(ResultCode.AUTHORIZATION_DENIED, message);
        }
      }
      // If we've made it here, then the user is acceptable.
      return userEntry;
    }
    finally
    {
      LockManager.unlock(authzDN, entryLock);
    }
    // If we've made it here, then the user is acceptable.
    return userEntry;
  }
opendj-server-legacy/src/main/java/org/opends/server/controls/ProxiedAuthV2Control.java
@@ -27,8 +27,6 @@
package org.opends.server.controls;
import java.io.IOException;
import java.util.concurrent.locks.Lock;
import org.forgerock.i18n.LocalizableMessage;
import org.opends.server.api.AuthenticationPolicyState;
import org.opends.server.api.IdentityMapper;
@@ -236,35 +234,20 @@
          authzDN = actualDN;
        }
        final Lock entryLock = LockManager.lockRead(authzDN);
        if (entryLock == null)
        Entry userEntry = DirectoryServer.getEntry(authzDN);
        if (userEntry == null)
        {
          throw new DirectoryException(ResultCode.BUSY,
              ERR_PROXYAUTH2_CANNOT_LOCK_USER.get(authzDN));
          // The requested user does not exist.
          LocalizableMessage message = ERR_PROXYAUTH2_NO_SUCH_USER.get(lowerAuthzID);
          throw new DirectoryException(ResultCode.AUTHORIZATION_DENIED, message);
        }
        try
        {
          Entry userEntry = DirectoryServer.getEntry(authzDN);
          if (userEntry == null)
          {
            // The requested user does not exist.
            LocalizableMessage message = ERR_PROXYAUTH2_NO_SUCH_USER.get(lowerAuthzID);
            throw new DirectoryException(ResultCode.AUTHORIZATION_DENIED,
                                         message);
          }
        // FIXME -- We should provide some mechanism for enabling debug
        // processing.
        checkAccountIsUsable(userEntry);
          // FIXME -- We should provide some mechanism for enabling debug
          // processing.
          checkAccountIsUsable(userEntry);
          // If we've made it here, then the user is acceptable.
          return userEntry;
        }
        finally
        {
          LockManager.unlock(authzDN, entryLock);
        }
        // If we've made it here, then the user is acceptable.
        return userEntry;
      }
    }
    else if (lowerAuthzID.startsWith("u:"))
opendj-server-legacy/src/main/java/org/opends/server/extensions/CRAMMD5SASLMechanismHandler.java
@@ -31,8 +31,6 @@
import java.text.ParseException;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.locks.Lock;
import org.forgerock.i18n.LocalizableMessage;
import org.opends.server.admin.server.ConfigurationChangeListener;
import org.opends.server.admin.std.server.CramMD5SASLMechanismHandlerCfg;
@@ -318,16 +316,6 @@
        userDN = rootDN;
      }
      // Acquire a read lock on the user entry.  If this fails, then so will the
      // authentication.
      final Lock readLock = LockManager.lockRead(userDN);
      if (readLock == null)
      {
        bindOperation.setResultCode(ResultCode.BUSY);
        bindOperation.setAuthFailureReason(INFO_SASLCRAMMD5_CANNOT_LOCK_ENTRY.get(userDN));
        return;
      }
      try
      {
        userEntry = DirectoryServer.getEntry(userDN);
@@ -342,10 +330,6 @@
        bindOperation.setAuthFailureReason(message);
        return;
      }
      finally
      {
        LockManager.unlock(userDN, readLock);
      }
    }
    else
    {
opendj-server-legacy/src/main/java/org/opends/server/extensions/PlainSASLMechanismHandler.java
@@ -32,8 +32,6 @@
import static org.opends.server.util.StaticUtils.*;
import java.util.List;
import java.util.concurrent.locks.Lock;
import org.forgerock.i18n.LocalizableMessage;
import org.opends.server.admin.server.ConfigurationChangeListener;
import org.opends.server.admin.std.server.PlainSASLMechanismHandlerCfg;
@@ -229,16 +227,6 @@
        userDN = rootDN;
      }
      // Acquire a read lock on the user entry.  If this fails, then so will the
      // authentication.
      final Lock readLock = LockManager.lockRead(userDN);
      if (readLock == null)
      {
        bindOperation.setResultCode(ResultCode.BUSY);
        bindOperation.setAuthFailureReason(INFO_SASLPLAIN_CANNOT_LOCK_ENTRY.get(userDN));
        return;
      }
      try
      {
        userEntry = DirectoryServer.getEntry(userDN);
@@ -253,10 +241,6 @@
        bindOperation.setAuthFailureReason(message);
        return;
      }
      finally
      {
        LockManager.unlock(userDN, readLock);
      }
    }
    else
    {
opendj-server-legacy/src/main/java/org/opends/server/extensions/SASLContext.java
@@ -34,8 +34,6 @@
import java.security.PrivilegedExceptionAction;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.locks.Lock;
import javax.security.auth.Subject;
import javax.security.auth.callback.*;
import javax.security.auth.login.LoginContext;
@@ -861,13 +859,6 @@
   */
  private void getAuthEntry(final DN userDN)
  {
    final Lock readLock = LockManager.lockRead(userDN);
    if (readLock == null)
    {
      setCallbackMsg(INFO_SASL_CANNOT_LOCK_ENTRY.get(userDN));
      return;
    }
    try
    {
      authEntry = DirectoryServer.getEntry(userDN);
@@ -878,10 +869,6 @@
      setCallbackMsg(ERR_SASL_CANNOT_GET_ENTRY_BY_DN.get(
          userDN, SASL_MECHANISM_DIGEST_MD5, e.getMessageObject()));
    }
    finally
    {
      LockManager.unlock(userDN, readLock);
    }
  }
opendj-server-legacy/src/main/java/org/opends/server/extensions/SubjectEqualsDNCertificateMapper.java
@@ -30,8 +30,6 @@
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.concurrent.locks.Lock;
import javax.security.auth.x500.X500Principal;
import org.forgerock.i18n.LocalizableMessage;
@@ -140,16 +138,6 @@
      throw new DirectoryException(ResultCode.INVALID_CREDENTIALS, message);
    }
    // Acquire a read lock on the user entry.  If this fails, then so will the
    // certificate mapping.
    final Lock readLock = LockManager.lockRead(subjectDN);
    if (readLock == null)
    {
      throw new DirectoryException(ResultCode.BUSY, ERR_SEDCM_CANNOT_LOCK_ENTRY.get(subjectDN));
    }
    // Retrieve the entry with the specified DN from the directory.
    Entry userEntry;
    try
@@ -170,11 +158,6 @@
      LocalizableMessage message = ERR_SEDCM_CANNOT_GET_ENTRY.get(subjectDN, getExceptionMessage(e));
      throw new DirectoryException(ResultCode.INVALID_CREDENTIALS, message, e);
    }
    finally
    {
      LockManager.unlock(subjectDN, readLock);
    }
    if (userEntry == null)
    {
opendj-server-legacy/src/main/java/org/opends/server/types/Entry.java
@@ -29,8 +29,6 @@
import java.io.BufferedWriter;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.locks.Lock;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.i18n.LocalizableMessageBuilder;
import org.forgerock.i18n.LocalizedIllegalArgumentException;
@@ -2188,64 +2186,12 @@
        DN parentDN = dn.getParentDNInSuffix();
        if (parentDN != null)
        {
          // Get the parent entry and check its structural class.
          final Lock lock = LockManager.lockRead(parentDN);
          if (lock == null)
          try
          {
            LocalizableMessage message = ERR_ENTRY_SCHEMA_DSR_COULD_NOT_LOCK_PARENT.get(dn, parentDN);
            if (structuralPolicy == AcceptRejectWarn.REJECT)
            parentEntry = DirectoryServer.getEntry(parentDN);
            if (parentEntry == null)
            {
              invalidReason.append(message);
              return false;
            }
            else if (structuralPolicy == AcceptRejectWarn.WARN)
            {
              logger.error(message);
            }
          }
          else
          {
            try
            {
              parentEntry = DirectoryServer.getEntry(parentDN);
              if (parentEntry == null)
              {
                LocalizableMessage message = ERR_ENTRY_SCHEMA_DSR_NO_PARENT_ENTRY.get(dn, parentDN);
                if (structuralPolicy == AcceptRejectWarn.REJECT)
                {
                  invalidReason.append(message);
                  return false;
                }
                else if (structuralPolicy == AcceptRejectWarn.WARN)
                {
                  logger.error(message);
                }
              }
              else
              {
                boolean dsrValid =
                     validateDITStructureRule(ditStructureRule,
                                              structuralClass,
                                              parentEntry,
                                              structuralPolicy,
                                              invalidReason);
                if (! dsrValid)
                {
                  return false;
                }
              }
            }
            catch (Exception e)
            {
              logger.traceException(e);
              LocalizableMessage message =
                   ERR_ENTRY_SCHEMA_COULD_NOT_CHECK_DSR.get(
                           dn,
                           ditStructureRule.getNameOrRuleID(),
                           getExceptionMessage(e));
              LocalizableMessage message = ERR_ENTRY_SCHEMA_DSR_NO_PARENT_ENTRY.get(dn, parentDN);
              if (structuralPolicy == AcceptRejectWarn.REJECT)
              {
@@ -2257,9 +2203,38 @@
                logger.error(message);
              }
            }
            finally
            else
            {
              LockManager.unlock(parentDN, lock);
              boolean dsrValid =
                   validateDITStructureRule(ditStructureRule,
                                            structuralClass,
                                            parentEntry,
                                            structuralPolicy,
                                            invalidReason);
              if (! dsrValid)
              {
                return false;
              }
            }
          }
          catch (Exception e)
          {
            logger.traceException(e);
            LocalizableMessage message =
                 ERR_ENTRY_SCHEMA_COULD_NOT_CHECK_DSR.get(
                         dn,
                         ditStructureRule.getNameOrRuleID(),
                         getExceptionMessage(e));
            if (structuralPolicy == AcceptRejectWarn.REJECT)
            {
              invalidReason.append(message);
              return false;
            }
            else if (structuralPolicy == AcceptRejectWarn.WARN)
            {
              logger.error(message);
            }
          }
        }
@@ -2282,57 +2257,14 @@
        DN parentDN = getName().getParentDNInSuffix();
        if (parentDN != null)
        {
          // Get the parent entry and check its structural class.
          final Lock lock = LockManager.lockRead(parentDN);
          if (lock == null)
          try
          {
            LocalizableMessage message =
                ERR_ENTRY_SCHEMA_DSR_COULD_NOT_LOCK_PARENT.get(dn, parentDN);
            if (structuralPolicy == AcceptRejectWarn.REJECT)
            parentEntry = DirectoryServer.getEntry(parentDN);
            if (parentEntry == null)
            {
              invalidReason.append(message);
              return false;
            }
            else if (structuralPolicy == AcceptRejectWarn.WARN)
            {
              logger.error(message);
            }
          }
          else
          {
            try
            {
              parentEntry = DirectoryServer.getEntry(parentDN);
              if (parentEntry == null)
              {
                LocalizableMessage message =
                     ERR_ENTRY_SCHEMA_DSR_NO_PARENT_ENTRY.get(
                         dn, parentDN);
                if (structuralPolicy == AcceptRejectWarn.REJECT)
                {
                  invalidReason.append(message);
                  return false;
                }
                else if (structuralPolicy == AcceptRejectWarn.WARN)
                {
                  logger.error(message);
                }
              }
              else
              {
                parentExists = true;
                parentStructuralClass = parentEntry.getStructuralObjectClass();
              }
            }
            catch (Exception e)
            {
              logger.traceException(e);
              LocalizableMessage message =
                   ERR_ENTRY_SCHEMA_COULD_NOT_CHECK_PARENT_DSR.get(
                       dn, getExceptionMessage(e));
                   ERR_ENTRY_SCHEMA_DSR_NO_PARENT_ENTRY.get(
                       dn, parentDN);
              if (structuralPolicy == AcceptRejectWarn.REJECT)
              {
@@ -2344,9 +2276,28 @@
                logger.error(message);
              }
            }
            finally
            else
            {
              LockManager.unlock(parentDN, lock);
              parentExists = true;
              parentStructuralClass = parentEntry.getStructuralObjectClass();
            }
          }
          catch (Exception e)
          {
            logger.traceException(e);
            LocalizableMessage message =
                 ERR_ENTRY_SCHEMA_COULD_NOT_CHECK_PARENT_DSR.get(
                     dn, getExceptionMessage(e));
            if (structuralPolicy == AcceptRejectWarn.REJECT)
            {
              invalidReason.append(message);
              return false;
            }
            else if (structuralPolicy == AcceptRejectWarn.WARN)
            {
              logger.error(message);
            }
          }
        }
opendj-server-legacy/src/main/java/org/opends/server/workflowelement/localbackend/LocalBackendBindOperation.java
@@ -27,8 +27,6 @@
package org.opends.server.workflowelement.localbackend;
import java.util.List;
import java.util.concurrent.locks.Lock;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.i18n.LocalizableMessageDescriptor.Arg1;
import org.forgerock.i18n.LocalizableMessageDescriptor.Arg2;
@@ -67,7 +65,7 @@
  /**
   * The backend in which the bind operation should be processed.
   */
  protected Backend backend;
  protected Backend<?> backend;
  /**
   * Indicates whether the bind response should include the first warning
@@ -438,187 +436,170 @@
      bindDN = actualRootDN;
    }
    // Get the user entry based on the bind DN.  If it does not exist,
    // then fail.
    final Lock userLock = LockManager.lockRead(bindDN);
    if (userLock == null)
    {
      throw new DirectoryException(ResultCode.BUSY,
          ERR_BIND_OPERATION_CANNOT_LOCK_USER.get(bindDN));
    }
    Entry userEntry;
    try
    {
      Entry userEntry;
      try
      userEntry = backend.getEntry(bindDN);
    }
    catch (DirectoryException de)
    {
      logger.traceException(de);
      userEntry = null;
      if (de.getResultCode() == ResultCode.REFERRAL)
      {
        userEntry = backend.getEntry(bindDN);
        // Re-throw referral exceptions - these should be passed back
        // to the client.
        throw de;
      }
      catch (DirectoryException de)
      else
      {
        logger.traceException(de);
        userEntry = null;
        if (de.getResultCode() == ResultCode.REFERRAL)
        {
          // Re-throw referral exceptions - these should be passed back
          // to the client.
          throw de;
        }
        else
        {
          // Replace other exceptions in case they expose any sensitive
          // information.
          throw new DirectoryException(ResultCode.INVALID_CREDENTIALS,
              de.getMessageObject());
        }
        // Replace other exceptions in case they expose any sensitive
        // information.
        throw new DirectoryException(ResultCode.INVALID_CREDENTIALS,
            de.getMessageObject());
      }
    }
      if (userEntry == null)
    if (userEntry == null)
    {
      throw new DirectoryException(ResultCode.INVALID_CREDENTIALS,
                                   ERR_BIND_OPERATION_UNKNOWN_USER.get());
    }
    else
    {
      setUserEntryDN(userEntry.getName());
    }
    // Check to see if the user has a password. If not, then fail.
    // FIXME -- We need to have a way to enable/disable debugging.
    authPolicyState = AuthenticationPolicyState.forUser(userEntry, false);
    if (authPolicyState.isPasswordPolicy())
    {
      // Account is managed locally.
      PasswordPolicyState pwPolicyState =
        (PasswordPolicyState) authPolicyState;
      PasswordPolicy policy = pwPolicyState.getAuthenticationPolicy();
      AttributeType pwType = policy.getPasswordAttribute();
      List<Attribute> pwAttr = userEntry.getAttribute(pwType);
      if ((pwAttr == null) || (pwAttr.isEmpty()))
      {
        throw new DirectoryException(ResultCode.INVALID_CREDENTIALS,
                                     ERR_BIND_OPERATION_UNKNOWN_USER.get());
            ERR_BIND_OPERATION_NO_PASSWORD.get());
      }
      // Perform a number of password policy state checks for the
      // non-authenticated user.
      checkUnverifiedPasswordPolicyState(userEntry, null);
      // Invoke pre-operation plugins.
      if (!invokePreOpPlugins())
      {
        return false;
      }
      // Determine whether the provided password matches any of the stored
      // passwords for the user.
      if (pwPolicyState.passwordMatches(simplePassword))
      {
        setResultCode(ResultCode.SUCCESS);
        checkVerifiedPasswordPolicyState(userEntry, null);
        if (DirectoryServer.lockdownMode()
            && (!ClientConnection.hasPrivilege(userEntry,
                Privilege.BYPASS_LOCKDOWN)))
        {
          throw new DirectoryException(ResultCode.INVALID_CREDENTIALS,
              ERR_BIND_REJECTED_LOCKDOWN_MODE.get());
        }
        setAuthenticationInfo(new AuthenticationInfo(userEntry, getBindDN(),
            DirectoryServer.isRootDN(userEntry.getName())));
        // Set resource limits for the authenticated user.
        setResourceLimits(userEntry);
        // Perform any remaining processing for a successful simple
        // authentication.
        pwPolicyState.handleDeprecatedStorageSchemes(simplePassword);
        pwPolicyState.clearFailureLockout();
        if (isFirstWarning)
        {
          pwPolicyState.setWarnedTime();
          int numSeconds = pwPolicyState.getSecondsUntilExpiration();
          LocalizableMessage m = WARN_BIND_PASSWORD_EXPIRING
              .get(secondsToTimeString(numSeconds));
          pwPolicyState.generateAccountStatusNotification(
              AccountStatusNotificationType.PASSWORD_EXPIRING, userEntry, m,
              AccountStatusNotification.createProperties(pwPolicyState,
                  false, numSeconds, null, null));
        }
        if (isGraceLogin)
        {
          pwPolicyState.updateGraceLoginTimes();
        }
        pwPolicyState.setLastLoginTime();
      }
      else
      {
        setUserEntryDN(userEntry.getName());
      }
        setResultCode(ResultCode.INVALID_CREDENTIALS);
        setAuthFailureReason(ERR_BIND_OPERATION_WRONG_PASSWORD.get());
      // Check to see if the user has a password. If not, then fail.
      // FIXME -- We need to have a way to enable/disable debugging.
      authPolicyState = AuthenticationPolicyState.forUser(userEntry, false);
      if (authPolicyState.isPasswordPolicy())
      {
        // Account is managed locally.
        PasswordPolicyState pwPolicyState =
          (PasswordPolicyState) authPolicyState;
        PasswordPolicy policy = pwPolicyState.getAuthenticationPolicy();
        AttributeType pwType = policy.getPasswordAttribute();
        List<Attribute> pwAttr = userEntry.getAttribute(pwType);
        if ((pwAttr == null) || (pwAttr.isEmpty()))
        if (policy.getLockoutFailureCount() > 0)
        {
          throw new DirectoryException(ResultCode.INVALID_CREDENTIALS,
              ERR_BIND_OPERATION_NO_PASSWORD.get());
        }
        // Perform a number of password policy state checks for the
        // non-authenticated user.
        checkUnverifiedPasswordPolicyState(userEntry, null);
        // Invoke pre-operation plugins.
        if (!invokePreOpPlugins())
        {
          return false;
        }
        // Determine whether the provided password matches any of the stored
        // passwords for the user.
        if (pwPolicyState.passwordMatches(simplePassword))
        {
          setResultCode(ResultCode.SUCCESS);
          checkVerifiedPasswordPolicyState(userEntry, null);
          if (DirectoryServer.lockdownMode()
              && (!ClientConnection.hasPrivilege(userEntry,
                  Privilege.BYPASS_LOCKDOWN)))
          {
            throw new DirectoryException(ResultCode.INVALID_CREDENTIALS,
                ERR_BIND_REJECTED_LOCKDOWN_MODE.get());
          }
          setAuthenticationInfo(new AuthenticationInfo(userEntry, getBindDN(),
              DirectoryServer.isRootDN(userEntry.getName())));
          // Set resource limits for the authenticated user.
          setResourceLimits(userEntry);
          // Perform any remaining processing for a successful simple
          // authentication.
          pwPolicyState.handleDeprecatedStorageSchemes(simplePassword);
          pwPolicyState.clearFailureLockout();
          if (isFirstWarning)
          {
            pwPolicyState.setWarnedTime();
            int numSeconds = pwPolicyState.getSecondsUntilExpiration();
            LocalizableMessage m = WARN_BIND_PASSWORD_EXPIRING
                .get(secondsToTimeString(numSeconds));
            pwPolicyState.generateAccountStatusNotification(
                AccountStatusNotificationType.PASSWORD_EXPIRING, userEntry, m,
                AccountStatusNotification.createProperties(pwPolicyState,
                    false, numSeconds, null, null));
          }
          if (isGraceLogin)
          {
            pwPolicyState.updateGraceLoginTimes();
          }
          pwPolicyState.setLastLoginTime();
        }
        else
        {
          setResultCode(ResultCode.INVALID_CREDENTIALS);
          setAuthFailureReason(ERR_BIND_OPERATION_WRONG_PASSWORD.get());
          if (policy.getLockoutFailureCount() > 0)
          {
            generateAccountStatusNotificationForLockedBindAccount(userEntry,
                pwPolicyState);
          }
          generateAccountStatusNotificationForLockedBindAccount(userEntry,
              pwPolicyState);
        }
      }
      else
      {
        // Check to see if the user is administratively disabled or locked.
        if (authPolicyState.isDisabled())
        {
          throw new DirectoryException(ResultCode.INVALID_CREDENTIALS,
              ERR_BIND_OPERATION_ACCOUNT_DISABLED.get());
        }
        // Invoke pre-operation plugins.
        if (!invokePreOpPlugins())
        {
          return false;
        }
        if (authPolicyState.passwordMatches(simplePassword))
        {
          setResultCode(ResultCode.SUCCESS);
          if (DirectoryServer.lockdownMode()
              && (!ClientConnection.hasPrivilege(userEntry,
                  Privilege.BYPASS_LOCKDOWN)))
          {
            throw new DirectoryException(ResultCode.INVALID_CREDENTIALS,
                ERR_BIND_REJECTED_LOCKDOWN_MODE.get());
          }
          setAuthenticationInfo(new AuthenticationInfo(userEntry, getBindDN(),
              DirectoryServer.isRootDN(userEntry.getName())));
          // Set resource limits for the authenticated user.
          setResourceLimits(userEntry);
        }
        else
        {
          setResultCode(ResultCode.INVALID_CREDENTIALS);
          setAuthFailureReason(ERR_BIND_OPERATION_WRONG_PASSWORD.get());
        }
      }
      return true;
    }
    finally
    else
    {
      // No matter what, make sure to unlock the user's entry.
      LockManager.unlock(bindDN, userLock);
      // Check to see if the user is administratively disabled or locked.
      if (authPolicyState.isDisabled())
      {
        throw new DirectoryException(ResultCode.INVALID_CREDENTIALS,
            ERR_BIND_OPERATION_ACCOUNT_DISABLED.get());
      }
      // Invoke pre-operation plugins.
      if (!invokePreOpPlugins())
      {
        return false;
      }
      if (authPolicyState.passwordMatches(simplePassword))
      {
        setResultCode(ResultCode.SUCCESS);
        if (DirectoryServer.lockdownMode()
            && (!ClientConnection.hasPrivilege(userEntry,
                Privilege.BYPASS_LOCKDOWN)))
        {
          throw new DirectoryException(ResultCode.INVALID_CREDENTIALS,
              ERR_BIND_REJECTED_LOCKDOWN_MODE.get());
        }
        setAuthenticationInfo(new AuthenticationInfo(userEntry, getBindDN(),
            DirectoryServer.isRootDN(userEntry.getName())));
        // Set resource limits for the authenticated user.
        setResourceLimits(userEntry);
      }
      else
      {
        setResultCode(ResultCode.INVALID_CREDENTIALS);
        setAuthFailureReason(ERR_BIND_OPERATION_WRONG_PASSWORD.get());
      }
    }
    return true;
  }
opendj-server-legacy/src/main/java/org/opends/server/workflowelement/localbackend/LocalBackendCompareOperation.java
@@ -29,7 +29,6 @@
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.Lock;
import org.forgerock.i18n.LocalizableMessage;
import org.opends.server.api.Backend;
@@ -67,7 +66,7 @@
  /**
   * The backend in which the comparison is to be performed.
   */
  private Backend backend;
  private Backend<?> backend;
  /**
   * The client connection for this operation.
@@ -185,19 +184,8 @@
    // Check for a request to cancel this operation.
    checkIfCanceled(false);
    // Grab a read lock on the entry.
    final Lock readLock = LockManager.lockRead(entryDN);
    try
    {
      if (readLock == null)
      {
        setResultCode(ResultCode.BUSY);
        appendErrorMessage(ERR_COMPARE_CANNOT_LOCK_ENTRY.get(entryDN));
        return;
      }
      // Get the entry. If it does not exist, then fail.
      try
      {
@@ -318,16 +306,8 @@
    catch (DirectoryException de)
    {
      logger.traceException(de);
      setResponseData(de);
    }
    finally
    {
      if (readLock != null)
      {
        LockManager.unlock(entryDN, readLock);
      }
    }
  }
  private DirectoryException newDirectoryException(Entry entry,
opendj-server-legacy/src/test/java/org/opends/server/replication/ReplicationTestCase.java
@@ -539,28 +539,21 @@
    do
    {
      final Lock lock = LockManager.lockRead(dn);
      assertNotNull(lock, "could not lock entry " + dn);
      try
      final Entry newEntry = DirectoryServer.getEntry(dn);
      if (newEntry != null)
      {
        final Entry newEntry = DirectoryServer.getEntry(dn);
        if (newEntry != null)
        List<Attribute> tmpAttrList = newEntry.getAttribute(attrTypeStr);
        if ((tmpAttrList != null) && (!tmpAttrList.isEmpty()))
        {
          List<Attribute> tmpAttrList = newEntry.getAttribute(attrTypeStr);
          if ((tmpAttrList != null) && (!tmpAttrList.isEmpty()))
          {
            Attribute tmpAttr = tmpAttrList.get(0);
            found = tmpAttr.contains(ByteString.valueOf(valueString));
          }
          Attribute tmpAttr = tmpAttrList.get(0);
          found = tmpAttr.contains(ByteString.valueOf(valueString));
        }
      }
      finally
      {
        LockManager.unlock(dn, lock);
      }
      if (found != hasAttribute)
      {
        Thread.sleep(100);
      }
    } while ((--count > 0) && (found != hasAttribute));
    return found;
  }
@@ -584,19 +577,12 @@
      count--;
    }
    final Lock lock = LockManager.lockRead(dn);
    assertNotNull(lock, "could not lock entry " + dn);
    try
    Entry entry = DirectoryServer.getEntry(dn);
    if (entry != null)
    {
      Entry entry = DirectoryServer.getEntry(dn);
      if (entry != null)
        return entry.duplicate(true);
      return null;
      return entry.duplicate(true);
    }
    finally
    {
      LockManager.unlock(dn, lock);
    }
    return null;
  }
  /**
@@ -833,25 +819,16 @@
    {
      Thread.sleep(100);
      final Lock lock = LockManager.lockRead(dn);
      assertNotNull(lock, "could not lock entry " + dn);
      try
      Entry newEntry = DirectoryServer.getEntry(dn);
      if (newEntry != null)
      {
        Entry newEntry = DirectoryServer.getEntry(dn);
        if (newEntry != null)
        Attribute attribute = newEntry.getAttribute("entryuuid").get(0);
        for (ByteString val : attribute)
        {
          Attribute attribute = newEntry.getAttribute("entryuuid").get(0);
          for (ByteString val : attribute)
          {
            found = val.toString();
            break;
          }
          found = val.toString();
          break;
        }
      }
      finally
      {
        LockManager.unlock(dn, lock);
      }
      count --;
    }
    assertNotNull(found, "Entry: " + dn + " Could not be found.");