From 50ff7430fecef89c60e6418bfb1cb1feec453570 Mon Sep 17 00:00:00 2001 From: Sofia Donato Ferreira Date: Mon, 19 Oct 2026 14:36:44 -0300 Subject: [PATCH] BUG: Allow all LDAP servers in ServerPool to attempt connection When using 'active=False', the ServerPool object returns only an index of a server to use (in this case, an index of a random server), without checking whether that server is currently active (reachable) [1]. This means that in a setup with two or more servers in the pool, if one or more of them are down (e.g. for maintenance), there's a random chance that server is picked, resulting in an error. Setting 'active' to an integer prevents that by making the pool loop through all servers to check which ones are available, but does not block the thread indefinitely as setting it to 'True' would. [1] - https://github.com/cannatag/ldap3/blob/c5be4b6f/ldap3/core/pooling.py#L95 Signed-off-by: Sofia Donato Ferreira --- src/bluesky_httpserver/authenticators.py | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/bluesky_httpserver/authenticators.py b/src/bluesky_httpserver/authenticators.py index 6f24887..1b7e2a0 100644 --- a/src/bluesky_httpserver/authenticators.py +++ b/src/bluesky_httpserver/authenticators.py @@ -1011,14 +1011,8 @@ async def resolve_username(self, username_supplied_by_user): def get_connection(self, userdn, password): import ldap3 - # NOTE: setting 'active=False' essentially disables exclusion of inactive servers from the pool. - # It probably does not matter if the pool contains only one server, but it could have implications - # when there are multiple servers in the pool. It is not clear what those implications are. - # But using the default 'activate=True' results in the thread being blocked indefinitely - # at the step of creating 'ldap3.Connection' regardless of timeouts in case all the servers are - # inactive (e.g. the pool has one server and it is unaccessible), which is unacceptable. - # Further investigation may be needed in the future. - server_pool = ldap3.ServerPool(None, ldap3.RANDOM, active=False) + # Try connecting to some server in the pool up to 3 times, before failing. + server_pool = ldap3.ServerPool(None, ldap3.RANDOM, active=3) for address in self.server_address_list: if re.search(r".+:\d+", address): # Port is found in the address