GUACAMOLE-937: Return null on bindAs() failures. Rely on caller to interpret and handle failures.

Throwing GuacamoleInvalidCredentialsException breaks separation of
concerns (bindAs() shouldn't assume that it's being used during login
and that credentials given are the Guacamole user's credentials), and
has unintended side effects (throwing subclasses of
GuacamoleUnauthorizedException causes implicit session invalidation).
diff --git a/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/AuthenticationProviderService.java b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/AuthenticationProviderService.java
index a9f39cf..c047b91 100644
--- a/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/AuthenticationProviderService.java
+++ b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/AuthenticationProviderService.java
@@ -204,6 +204,10 @@
         
         // Attempt bind
         LdapNetworkConnection ldapConnection = ldapService.bindAs(bindDn, password);
+        if (ldapConnection == null)
+            throw new GuacamoleInvalidCredentialsException("Invalid login.",
+                    CredentialsInfo.USERNAME_PASSWORD);
+
         try {
 
             // Retrieve group membership of the user that just authenticated
@@ -309,8 +313,16 @@
         // Bind using credentials associated with AuthenticatedUser
         Credentials credentials = authenticatedUser.getCredentials();
         if (authenticatedUser instanceof LDAPAuthenticatedUser) {
+
             Dn bindDn = ((LDAPAuthenticatedUser) authenticatedUser).getBindDn();
             LdapNetworkConnection ldapConnection = ldapService.bindAs(bindDn, credentials.getPassword());
+            if (ldapConnection == null) {
+                logger.debug("LDAP bind succeeded for \"{}\" during "
+                        + "authentication but failed during data retrieval.",
+                        authenticatedUser.getIdentifier());
+                throw new GuacamoleInvalidCredentialsException("Invalid login.",
+                        CredentialsInfo.USERNAME_PASSWORD);
+            }
 
             try {
 
diff --git a/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/LDAPConnectionService.java b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/LDAPConnectionService.java
index 7141a79..7e88f8a 100644
--- a/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/LDAPConnectionService.java
+++ b/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/LDAPConnectionService.java
@@ -144,13 +144,12 @@
             bindRequest.setDn(userDN);
             bindRequest.setCredentials(password);
             BindResponse bindResponse = ldapConnection.bind(bindRequest);
-            if (bindResponse.getLdapResult().getResultCode() == ResultCodeEnum.SUCCESS)
-                return ldapConnection;
-            
-            else
-                throw new GuacamoleInvalidCredentialsException("Error binding"
-                        + " to server: " + bindResponse.toString(),
-                        CredentialsInfo.USERNAME_PASSWORD);
+
+            if (bindResponse.getLdapResult().getResultCode() != ResultCodeEnum.SUCCESS) {
+                ldapConnection.close();
+                logger.debug("LDAP bind attempt failed: {}", bindResponse.toString());
+                return null;
+            }
 
         }
 
@@ -158,11 +157,11 @@
         catch (LdapException e) {
             ldapConnection.close();
             logger.debug("Unable to bind to LDAP server.", e);
-            throw new GuacamoleInvalidCredentialsException(
-                    "Unable to bind to the LDAP server.",
-                    CredentialsInfo.USERNAME_PASSWORD);
+            return null;
         }
 
+        return ldapConnection;
+
     }
     
     /**