private ChaiProvider makeProxyProvider()
     throws ChaiUnavailableException, PwmUnrecoverableException {
   final LdapProfile profile =
       pwmApplication.getConfig().getLdapProfiles().get(userIdentity.getLdapProfileID());
   final String proxyDN = profile.readSettingAsString(PwmSetting.LDAP_PROXY_USER_DN);
   final PasswordData proxyPassword =
       profile.readSettingAsPassword(PwmSetting.LDAP_PROXY_USER_PASSWORD);
   return LdapOperationsHelper.createChaiProvider(
       sessionLabel, profile, pwmApplication.getConfig(), proxyDN, proxyPassword);
 }
  private void testCredentials(final UserIdentity userIdentity, final PasswordData password)
      throws ChaiUnavailableException, PwmUnrecoverableException, PwmOperationalException {
    log(PwmLogLevel.TRACE, "beginning testCredentials process");

    if (userIdentity == null
        || userIdentity.getUserDN() == null
        || userIdentity.getUserDN().length() < 1) {
      final String errorMsg = "attempt to authenticate with null userDN";
      log(PwmLogLevel.DEBUG, errorMsg);
      throw new PwmOperationalException(
          new ErrorInformation(PwmError.ERROR_WRONGPASSWORD, errorMsg));
    }

    if (password == null) {
      final String errorMsg = "attempt to authenticate with null password";
      log(PwmLogLevel.DEBUG, errorMsg);
      throw new PwmOperationalException(
          new ErrorInformation(PwmError.ERROR_WRONGPASSWORD, errorMsg));
    }

    // try authenticating the user using a normal ldap BIND operation.
    log(PwmLogLevel.TRACE, "attempting authentication using ldap BIND");

    boolean bindSucceeded = false;
    try {
      // read a provider using the user's DN and password.
      userProvider =
          LdapOperationsHelper.createChaiProvider(
              sessionLabel,
              userIdentity.getLdapProfile(pwmApplication.getConfig()),
              pwmApplication.getConfig(),
              userIdentity.getUserDN(),
              password);

      // issue a read operation to trigger a bind.
      userProvider.readStringAttribute(
          userIdentity.getUserDN(), ChaiConstant.ATTR_LDAP_OBJECTCLASS);

      bindSucceeded = true;
    } catch (ChaiException e) {
      if (e.getErrorCode() != null && e.getErrorCode() == ChaiError.INTRUDER_LOCKOUT) {
        final String errorMsg =
            "intruder lockout detected for user "
                + userIdentity
                + " marking session as locked out: "
                + e.getMessage();
        final ErrorInformation errorInformation =
            new ErrorInformation(PwmError.ERROR_INTRUDER_LDAP, errorMsg);
        log(PwmLogLevel.WARN, errorInformation.toDebugStr());
        throw new PwmUnrecoverableException(errorInformation);
      }
      final PwmError pwmError = PwmError.forChaiError(e.getErrorCode());
      final ErrorInformation errorInformation;
      if (pwmError != null && PwmError.ERROR_UNKNOWN != pwmError) {
        errorInformation = new ErrorInformation(pwmError, e.getMessage());
      } else {
        errorInformation =
            new ErrorInformation(
                PwmError.ERROR_WRONGPASSWORD,
                "ldap error during password check: " + e.getMessage());
      }
      log(PwmLogLevel.DEBUG, errorInformation.toDebugStr());
      throw new PwmOperationalException(errorInformation);
    } finally {
      if (!bindSucceeded && userProvider != null) {
        try {
          userProvider.close();
          userProvider = null;
        } catch (Throwable e) {
          log(
              PwmLogLevel.ERROR,
              "unexpected error closing invalid ldap connection after failed login attempt: "
                  + e.getMessage());
        }
      }
    }
  }