Retry or failover when using TLS

If a connection failed during TLS initialization, a BackendError was
raised which exited the loop of retrying or moving on to the next
provided server. Instead raise the underlying ldap exception.

Change-Id: If28001a810800a5c91a6a2fe63e3ba3f92fdc049
This commit is contained in:
Jimmy McCrory 2023-05-05 07:54:39 -07:00
parent 17b532cd6e
commit d4b2f2b7b4
2 changed files with 41 additions and 4 deletions

View File

@ -214,10 +214,8 @@ class ConnectionManager(object):
if self.use_tls:
try:
conn.start_tls_s()
except Exception:
raise BackendError('Could not activate TLS on established '
'connection with %s' % self.uri,
backend=conn)
except Exception as exc:
raise exc
if bind is not None:
conn.simple_bind_s(bind, passwd)

View File

@ -96,11 +96,24 @@ def _bind_fails_invalid_credentials_failover(self, who='', cred='', **kw):
raise ldap.INVALID_CREDENTIALS('LDAP connection invalid')
def _bind_fails_tls_failover(self, who='', cred='', **kw):
if self._uri == 'ldap://GOOD':
self.connected = True
self.who = who
self.cred = cred
return 1
else:
raise ldappool.BackendError
def _start_tls_s(self):
# Raise a server down error if the URI is 'ldap://BAD'
if self.start_tls_already_called_flag:
raise ldap.LOCAL_ERROR
else:
self.start_tls_already_called_flag = True
if self._uri == 'ldap://BAD':
raise ldap.SERVER_DOWN('LDAP connection invalid')
class TestLDAPConnection(unittest.TestCase):
@ -323,3 +336,29 @@ class TestLDAPConnection(unittest.TestCase):
pass
else:
raise AssertionError()
def test_simple_bind_fails_tls_failover(self):
unbinds = []
def _unbind(self):
unbinds.append(1)
# the binding to any server other than 'ldap://GOOD' fails
# with ldap.SERVER_DOWN
ldappool.StateConnector.simple_bind_s = _bind_fails_tls_failover
ldappool.StateConnector.unbind_s = _unbind
uri = 'ldap://BAD,ldap://GOOD'
dn = 'uid=adminuser,ou=logins,dc=mozilla'
passwd = 'adminuser'
cm = ldappool.ConnectionManager(uri, dn, passwd, use_pool=True,
size=2, use_tls=True)
self.assertEqual(len(cm), 0)
try:
with cm.connection('dn', 'pass') as conn:
# Ensure we failed over to the second URI
self.assertTrue(conn.active)
self.assertEqual(conn._uri, 'ldap://GOOD')
pass
except Exception:
raise AssertionError()