/**
   * Handles request control processing for this bind operation.
   *
   * @throws DirectoryException If there is a problem with any of the controls.
   */
  private void handleRequestControls() throws DirectoryException {
    LocalBackendWorkflowElement.removeAllDisallowedControls(bindDN, this);

    List<Control> requestControls = getRequestControls();
    if (requestControls != null && !requestControls.isEmpty()) {
      for (Control c : requestControls) {
        final String oid = c.getOID();

        if (OID_AUTHZID_REQUEST.equals(oid)) {
          returnAuthzID = true;
        } else if (OID_PASSWORD_POLICY_CONTROL.equals(oid)) {
          pwPolicyControlRequested = true;
        }

        // NYI -- Add support for additional controls.
        else if (c.isCritical()) {
          throw new DirectoryException(
              ResultCode.UNAVAILABLE_CRITICAL_EXTENSION,
              ERR_BIND_UNSUPPORTED_CRITICAL_CONTROL.get(oid));
        }
      }
    }
  }
  /**
   * Process this bind operation in a local backend.
   *
   * @param wfe The local backend work-flow element.
   */
  public void processLocalBind(LocalBackendWorkflowElement wfe) {
    this.backend = wfe.getBackend();

    // Initialize a number of variables for use during the bind processing.
    clientConnection = getClientConnection();
    returnAuthzID = false;
    executePostOpPlugins = false;
    sizeLimit = DirectoryServer.getSizeLimit();
    timeLimit = DirectoryServer.getTimeLimit();
    lookthroughLimit = DirectoryServer.getLookthroughLimit();
    idleTimeLimit = DirectoryServer.getIdleTimeLimit();
    bindDN = getBindDN();
    saslMechanism = getSASLMechanism();
    authPolicyState = null;
    pwPolicyErrorType = null;
    pwPolicyControlRequested = false;
    isGraceLogin = false;
    isFirstWarning = false;
    mustChangePassword = false;
    pwPolicyWarningType = null;
    pwPolicyWarningValue = -1;
    pluginConfigManager = DirectoryServer.getPluginConfigManager();

    processBind();

    // Update the user's account with any password policy changes that may be
    // required.
    try {
      if (authPolicyState != null) {
        authPolicyState.finalizeStateAfterBind();
      }
    } catch (DirectoryException de) {
      logger.traceException(de);

      setResponseData(de);
    }

    // Invoke the post-operation bind plugins.
    if (executePostOpPlugins) {
      PluginResult.PostOperation postOpResult =
          pluginConfigManager.invokePostOperationBindPlugins(this);
      if (!postOpResult.continueProcessing()) {
        setResultCode(postOpResult.getResultCode());
        appendErrorMessage(postOpResult.getErrorMessage());
        setMatchedDN(postOpResult.getMatchedDN());
        setReferralURLs(postOpResult.getReferralURLs());
      }
    }

    // Update the authentication information for the user.
    AuthenticationInfo authInfo = getAuthenticationInfo();
    if (getResultCode() == ResultCode.SUCCESS && authInfo != null) {
      clientConnection.setAuthenticationInfo(authInfo);
      clientConnection.setSizeLimit(sizeLimit);
      clientConnection.setTimeLimit(timeLimit);
      clientConnection.setIdleTimeLimit(idleTimeLimit);
      clientConnection.setLookthroughLimit(lookthroughLimit);
      clientConnection.setMustChangePassword(mustChangePassword);

      if (returnAuthzID) {
        addResponseControl(new AuthorizationIdentityResponseControl(authInfo.getAuthorizationDN()));
      }
    }

    // See if we need to send a password policy control to the client.  If so,
    // then add it to the response.
    if (getResultCode() == ResultCode.SUCCESS) {
      if (pwPolicyControlRequested) {
        PasswordPolicyResponseControl pwpControl =
            new PasswordPolicyResponseControl(
                pwPolicyWarningType, pwPolicyWarningValue, pwPolicyErrorType);
        addResponseControl(pwpControl);
      } else {
        if (pwPolicyErrorType == PasswordPolicyErrorType.PASSWORD_EXPIRED) {
          addResponseControl(new PasswordExpiredControl());
        } else if (pwPolicyWarningType == PasswordPolicyWarningType.TIME_BEFORE_EXPIRATION) {
          addResponseControl(new PasswordExpiringControl(pwPolicyWarningValue));
        } else if (mustChangePassword) {
          addResponseControl(new PasswordExpiredControl());
        }
      }
    } else {
      if (pwPolicyControlRequested) {
        PasswordPolicyResponseControl pwpControl =
            new PasswordPolicyResponseControl(
                pwPolicyWarningType, pwPolicyWarningValue, pwPolicyErrorType);
        addResponseControl(pwpControl);
      } else {
        if (pwPolicyErrorType == PasswordPolicyErrorType.PASSWORD_EXPIRED) {
          addResponseControl(new PasswordExpiredControl());
        }
      }
    }
  }
 /**
  * Creates a new operation that may be used to bind where the bound user entry is stored in a
  * local backend of the Directory Server.
  *
  * @param bind The operation to enhance.
  */
 public LocalBackendBindOperation(BindOperation bind) {
   super(bind);
   LocalBackendWorkflowElement.attachLocalOperation(bind, this);
 }