diff options
author | Mustafa Kemal Gilor <mustafa.gilor@canonical.com> | 2022-12-05 17:33:47 +0300 |
---|---|---|
committer | Mustafa Kemal Gilor <mustafa.gilor@canonical.com> | 2023-02-24 07:08:05 +0000 |
commit | 7c96280555d1de5ef5e7e3b12362439669427e4e (patch) | |
tree | c7d14ad7f302cb8269015b12d0606d08b689b782 /keystone/identity/backends/ldap/common.py | |
parent | 164d9522b8a150892432dbaba681c95d91d9508c (diff) | |
download | keystone-7c96280555d1de5ef5e7e3b12362439669427e4e.tar.gz |
[PooledLDAPHandler] Ensure result3() invokes message.clean()stable/yoga
result3 does not invoke message.clean() when an exception is thrown
by `message.connection.result3()` call, causing pool connection
associated with the message to be marked active forever. This causes
a denial-of-service on ldappool.
The fix ensures message.clean() is invoked by wrapping the offending
call in try-except-finally and putting the message.clean() in finally
block.
Closes-Bug: #1998789
Change-Id: I59ebf0fa77391d49b2349e918fc55f96318c42a6
Signed-off-by: Mustafa Kemal Gilor <mustafa.gilor@canonical.com>
(cherry picked from commit ff632a81fb09e6d9f3298e494d53eb6df50269cf)
Diffstat (limited to 'keystone/identity/backends/ldap/common.py')
-rw-r--r-- | keystone/identity/backends/ldap/common.py | 21 |
1 files changed, 16 insertions, 5 deletions
diff --git a/keystone/identity/backends/ldap/common.py b/keystone/identity/backends/ldap/common.py index 1033a4efd..d9c07fd87 100644 --- a/keystone/identity/backends/ldap/common.py +++ b/keystone/identity/backends/ldap/common.py @@ -860,11 +860,22 @@ class PooledLDAPHandler(LDAPHandler): cleaned up when message.clean() is called. """ - results = message.connection.result3(message.id, all, timeout) - - # Now that we have the results from the LDAP server for the message, we - # don't need the the context manager used to create the connection. - message.clean() + # message.connection.result3 might throw an exception + # so the code must ensure that message.clean() is invoked + # regardless of the result3's result. Otherwise, the + # connection will be marked as active forever, which + # ultimately renders the pool unusable, causing a DoS. + try: + results = message.connection.result3(message.id, all, timeout) + except Exception: + # We don't want to ignore thrown + # exceptions, raise them + raise + finally: + # Now that we have the results from the LDAP server for + # the message, we don't need the the context manager used + # to create the connection. + message.clean() return results |