fix ldappool bad password retry logic
This patch fixes a bug in ldappool which causes a bind attempt utilizing a bad password to be retried until the retry limit has been reached. Instead ldappool will now break out of the retry loop if the ldap connection try block catches a ldap.INVALID_PASSWORD exception. Previously ldappool would attempt to catch ldap.LDAPError which is the base exception class for all ldap errors in the python-ldap library. This is an issue because Keystone by default enables ldappool and configures the default retry value to be 3. An LDAP server with a password lockout threshold of 3 bad passwords will lock out a user after a single bad password attempt through Keystone. Change-Id: I2a9b850ce977260d4df1e9edf86417b8042a6fb8 Closes-Bug: #1785898
This commit is contained in:
parent
459e1b1399
commit
459000d7aa
|
@ -252,6 +252,11 @@ class ConnectionManager(object):
|
|||
conn.timeout = self.timeout
|
||||
self._bind(conn, bind, passwd)
|
||||
connected = True
|
||||
except ldap.INVALID_CREDENTIALS as error:
|
||||
exc = error
|
||||
log.error('Invalid credentials. Cancelling retry',
|
||||
exc_info=True)
|
||||
break
|
||||
except ldap.LDAPError as error:
|
||||
exc = error
|
||||
time.sleep(self.retry_delay)
|
||||
|
|
|
@ -55,6 +55,10 @@ def _bind_fails2(self, who='', cred='', **kw):
|
|||
raise ldap.SERVER_DOWN('LDAP connection invalid')
|
||||
|
||||
|
||||
def _bind_fails_invalid_credentials(self, who='', cred='', **kw):
|
||||
raise ldap.INVALID_CREDENTIALS('LDAP connection invalid')
|
||||
|
||||
|
||||
def _start_tls_s(self):
|
||||
if self.start_tls_already_called_flag:
|
||||
raise ldap.LOCAL_ERROR
|
||||
|
@ -157,3 +161,26 @@ class TestLDAPConnection(unittest.TestCase):
|
|||
pass
|
||||
else:
|
||||
raise AssertionError()
|
||||
|
||||
def test_simple_bind_fails_invalid_credentials(self):
|
||||
unbinds = []
|
||||
|
||||
def _unbind(self):
|
||||
unbinds.append(1)
|
||||
|
||||
# the binding fails with an LDAPError
|
||||
ldappool.StateConnector.simple_bind_s = _bind_fails_invalid_credentials
|
||||
ldappool.StateConnector.unbind_s = _unbind
|
||||
uri = ''
|
||||
dn = 'uid=adminuser,ou=logins,dc=mozilla'
|
||||
passwd = 'adminuser'
|
||||
cm = ldappool.ConnectionManager(uri, dn, passwd, use_pool=True, size=2)
|
||||
self.assertEqual(len(cm), 0)
|
||||
|
||||
try:
|
||||
with cm.connection('dn', 'pass'):
|
||||
pass
|
||||
except ldap.INVALID_CREDENTIALS:
|
||||
pass
|
||||
else:
|
||||
raise AssertionError()
|
||||
|
|
Loading…
Reference in New Issue