protected int authenticateRequired(
      long companyId,
      long userId,
      String emailAddress,
      String screenName,
      boolean allowOmniadmin,
      int failureCode)
      throws Exception {

    // Make exceptions for omniadmins so that if they break the LDAP
    // configuration, they can still login to fix the problem

    if (allowOmniadmin
        && (authenticateOmniadmin(companyId, emailAddress, screenName, userId) == SUCCESS)) {

      return SUCCESS;
    }

    LDAPAuthConfiguration ldapAuthConfiguration =
        _ldapAuthConfigurationProvider.getConfiguration(companyId);

    if (ldapAuthConfiguration.required()) {
      return failureCode;
    } else {
      return SUCCESS;
    }
  }
  protected int authenticate(
      long companyId, String emailAddress, String screenName, long userId, String password)
      throws Exception {

    LDAPAuthConfiguration ldapAuthConfiguration =
        _ldapAuthConfigurationProvider.getConfiguration(companyId);

    if (!ldapAuthConfiguration.enabled()) {
      if (_log.isDebugEnabled()) {
        _log.debug("Authenticator is not enabled");
      }

      return SUCCESS;
    }

    if (_log.isDebugEnabled()) {
      _log.debug("Authenticator is enabled");
    }

    int preferredLDAPServerResult =
        authenticateAgainstPreferredLDAPServer(
            companyId, emailAddress, screenName, userId, password);

    LDAPImportConfiguration ldapImportConfiguration =
        _ldapImportConfigurationProvider.getConfiguration(companyId);

    if (preferredLDAPServerResult == SUCCESS) {
      if (ldapImportConfiguration.importUserPasswordEnabled()) {
        return preferredLDAPServerResult;
      }

      return Authenticator.SKIP_LIFERAY_CHECK;
    }

    List<LDAPServerConfiguration> ldapServerConfigurations =
        _ldapServerConfigurationProvider.getConfigurations(companyId);

    for (LDAPServerConfiguration ldapServerConfiguration : ldapServerConfigurations) {

      int result =
          authenticate(
              ldapServerConfiguration.ldapServerId(),
              companyId,
              emailAddress,
              screenName,
              userId,
              password);

      if (result == SUCCESS) {
        if (ldapImportConfiguration.importUserPasswordEnabled()) {
          return result;
        }

        return Authenticator.SKIP_LIFERAY_CHECK;
      }
    }

    return authenticateRequired(companyId, userId, emailAddress, screenName, true, FAILURE);
  }
  protected LDAPAuthResult authenticate(
      LdapContext ctx, long companyId, Attributes attributes, String userDN, String password)
      throws Exception {

    LDAPAuthResult ldapAuthResult = null;

    // Check passwords by either doing a comparison between the passwords or
    // by binding to the LDAP server. If using LDAP password policies, bind
    // auth method must be used in order to get the result control codes.

    LDAPAuthConfiguration ldapAuthConfiguration =
        _ldapAuthConfigurationProvider.getConfiguration(companyId);

    String authMethod = ldapAuthConfiguration.method();

    SystemLDAPConfiguration systemLDAPConfiguration =
        _systemLDAPConfigurationProvider.getConfiguration(companyId);

    if (authMethod.equals(AUTH_METHOD_BIND)) {
      Hashtable<String, Object> env = (Hashtable<String, Object>) ctx.getEnvironment();

      env.put(Context.REFERRAL, systemLDAPConfiguration.referral());
      env.put(Context.SECURITY_CREDENTIALS, password);
      env.put(Context.SECURITY_PRINCIPAL, userDN);

      // Do not use pooling because principal changes

      env.put("com.sun.jndi.ldap.connect.pool", "false");

      ldapAuthResult = getFailedLDAPAuthResult(env);

      if (ldapAuthResult != null) {
        return ldapAuthResult;
      }

      ldapAuthResult = new LDAPAuthResult();

      InitialLdapContext initialLdapContext = null;

      try {
        initialLdapContext = new InitialLdapContext(env, null);

        // Get LDAP bind results

        Control[] responseControls = initialLdapContext.getResponseControls();

        ldapAuthResult.setAuthenticated(true);
        ldapAuthResult.setResponseControl(responseControls);
      } catch (Exception e) {
        if (_log.isDebugEnabled()) {
          _log.debug(
              "Failed to bind to the LDAP server with userDN "
                  + userDN
                  + " and password "
                  + password,
              e);
        }

        ldapAuthResult.setAuthenticated(false);
        ldapAuthResult.setErrorMessage(e.getMessage());

        setFailedLDAPAuthResult(env, ldapAuthResult);
      } finally {
        if (initialLdapContext != null) {
          initialLdapContext.close();
        }
      }
    } else if (authMethod.equals(AUTH_METHOD_PASSWORD_COMPARE)) {
      ldapAuthResult = new LDAPAuthResult();

      Attribute userPassword = attributes.get("userPassword");

      if (userPassword != null) {
        String ldapPassword = new String((byte[]) userPassword.get());

        String encryptedPassword = password;

        String algorithm = ldapAuthConfiguration.passwordEncryptionAlgorithm();

        if (Validator.isNotNull(algorithm)) {
          encryptedPassword = _passwordEncryptor.encrypt(algorithm, password, ldapPassword);
        }

        if (ldapPassword.equals(encryptedPassword)) {
          ldapAuthResult.setAuthenticated(true);
        } else {
          ldapAuthResult.setAuthenticated(false);

          if (_log.isDebugEnabled()) {
            _log.debug("Passwords do not match for userDN " + userDN);
          }
        }
      }
    }

    return ldapAuthResult;
  }