Permalink
Browse files

In case of authentication problem, do not try to fallback to other

domain controllers, to prevent locking the user out.
  • Loading branch information...
1 parent 4e24cbe commit 2b5d3bf4131a452bf529aab3db608715b2a66ba8 @kohsuke kohsuke committed May 8, 2012
@@ -357,6 +357,19 @@ public DirContext bind(String principalName, String password, List<SocketInfo> l
LdapContext context = bind(principalName, password, ldapServer, props);
LOGGER.fine("Bound to " + ldapServer);
return context;
+ } catch (javax.naming.AuthenticationException e) {
+ // if the authentication failed (as opposed to a communication problem with the server),
+ // don't retry, because if this is because of a wrong password, we can end up locking
+ // the user out by causing multiple failed attempts.
+ // error code 49 (LdapClient.LDAP_INVALID_CREDENTIALS) maps to this exception in LdapCtx.mapErrorCode
+ // see http://confluence.atlassian.com/display/CONFKB/LDAP+Error+Code+49 and http://www-01.ibm.com/support/docview.wss?uid=swg21290631
+ // for subcodes within this error.
+ // it seems like we can be clever about checking subcode to decide if we retry or not,
+ // but I'm erring on the safe side as I'm not sure how reliable the code is, and maybe
+ // servers can be configured to hide the distinction between "no such user" and "bad password"
+ // to reveal what user names are available.
+ LOGGER.log(Level.WARNING, "Failed to authenticate while binding to "+ldapServer, e);
+ throw new BadCredentialsException("Either no such user '"+principalName+"' or incorrect password",e);
} catch (NamingException e) {
LOGGER.log(Level.WARNING, "Failed to bind to "+ldapServer, e);
error = e; // retry
@@ -235,7 +235,7 @@ public UserDetails retrieveUser(String username, String password, String domainN
id = principalName.substring(0, principalName.indexOf('@'));
anonymousBind = password == NO_AUTHENTICATION;
try {
- // if we are just retrieving the user, trying using anonymous bind by empty password (see RFC 2829 5.1)
+ // if we are just retrieving the user, try using anonymous bind by empty password (see RFC 2829 5.1)
// but if that fails, that's not BadCredentialException but UserMayOrMayNotExistException
context = descriptor.bind(principalName, anonymousBind ? "" : password, ldapServers);
} catch (BadCredentialsException e) {

0 comments on commit 2b5d3bf

Please sign in to comment.