Commit Graph

25 Commits

Author SHA1 Message Date
Sven Kieske 606164d828
fix small typo in BackendError class
Change-Id: I54e16e807527a6986d67c17ab85aac48ada3a380
Signed-off-by: Sven Kieske <kieske@osism.tech>
2023-07-03 15:53:32 +02:00
Takashi Kajinami 0a56650693 Remove usage of six library
... because now ldappool supports Python 3 only.

Change-Id: Ibeb60dbc81ef5b03f0732439ed07c2b672e78df5
2023-05-23 10:30:49 +02:00
Andreas Jaeger 30fac42e42 Update hacking for Python3
The repo is Python 3 now, so update hacking to version 3.0 which
supports Python 3.

Fix problems found.

Remove hacking and friends from lower-constraints, they are not needed
for installation.

Change-Id: I5f0adcc9fc321848ef93dafc9c2ee2d4061a1cbc
2020-04-02 15:14:57 +02:00
Nathan Kinder acc14fca3a Allow pool status to be printed as a table
This patch adds a __str__() method to the ConnectionManager class,
which allows for a nice readible table to be obtained that shows
the current state of the connection pool.  This can be very useful
for troubleshooting or monitoring issues related to connection
pooling.  The table will contain a row for each connection within
the pool, with columns showing the connection slot, connectivity
status, activity status, URI, connection lifetime, and bind DN.
The header row will also indicate the pool size and maximum
connection lifetime setting.

Note that this adds a dependency on the prettytable module.  This
new dependency seems worth it for the nice readible table format
it produces.

Change-Id: If0abfef405d05ecd499bdf6201ff465bd845957b
2018-11-02 06:43:16 -07:00
Nathan Kinder 3f0ea8533a Handle retry logic for timeouts with multiple LDAP servers
It is currently possible to specify multiple LDAP server URIs
for failover purposes when using LDAP connection pooling, as this
functionality is provided in the underlying python-ldap module.
Unfortunately, failover does not work properly if LDAP timeout
issue are encountered due to the way python-LDAP works.  If multiple
URLs are provided, the first URL that results in a successful TCP
connection is considered to be a successful LDAP connection.  If the
initial bind operation fails due to a timeout waiting for an LDAP
response from the server, it will never failover to additional
URIs.  It is easy to demonstrate this behavior by forcing an LDAP
server to hang (attach with gdb to halt the process), then using
that server as the first URI when creating a connection pool.

This patch adds proper failover logic to ldappool.  If multiple URIs
are provided, we split them and attempt to connect to them one-by-one
until we have either had a successful LDAP bind operation, or we have
exhausted the list of URIs.  The connection retry logic is processed
per-URI as well, meaning we will attempt to reconnect to the first
URI up to the requested retry limit, then we will failover to the
next URI and reset the retry count.

The ldap.TIMEOUT exception was not raised to the caller like some
of the other common LDAP exceptions we might encounter.  We should
raise the TIMEOUT exception instead of the more generic BackendError
exception to provide more detail to the calling code.

Change-Id: Iabc13363d2425e70a53163249e5389d336274533
2018-10-31 12:39:26 -07:00
Nathan Kinder a74cf70ff4 Improve connection retry logging
The logging around the connection retry logic logs an info level
message when it fails to connect to the server, but still has retry
attempts left.  Due to the way we increment the counter for the
number of connection attempts, we log this same message when the
final attempt has failed.  There is an error level log message in
the code that is never reached due to this.

This patch changes the location where we increment the connection
attempt counter, which results in the proper error message being
logged when we fail on the final attempt.  The retry wait is also
moved to be after the info level message, as it states that it is
about to wait before retrying.  The current logic of waiting before
logging the message doesn't actually match what the message says.
I also added a debug level log message that indicates what connection
attempt it is about to make to help troubleshoot the retry logic.

Change-Id: Ib05d510b8816b5e0670b92749412378a100667d0
2018-10-30 19:18:33 -07:00
Corey Bryant 7734b7f45d PY3: switch to using unicode text values
In Python 3, python-ldap no longer allows bytes for DN/RDN/field
names. Instead, text values are represented as str, the Unicode
text type.

This patch updates the code to adhere to this behavior.

More details about byte/str usage in python-ldap can be found at:
http://www.python-ldap.org/en/latest/bytes_mode.html#bytes-mode

Change-Id: I9ef10432229aaffe4ac9bd733d608098cdae3b9a
Partial-Bug: #1798184
2018-10-19 09:53:41 -04:00
Nick Wilburn 459000d7aa 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
2018-08-13 17:26:13 -07:00
Colleen Murphy 53565dfd97 Don't call start_tls_s() twice
pyldap's start_tls_s function calls ldap_start_tls_s[1] which, if called
twice, returns LDAP_LOCAL_ERROR which causes a LDAP queries to fail with
the traceback:

 Traceback (most recent call last):
   File "/usr/lib/python2.7/site-packages/ldappool/__init__.py", line 258, in _create_connector
     self._bind(conn, bind, passwd)
   File "/usr/lib/python2.7/site-packages/ldappool/__init__.py", line 227, in _bind
     conn.start_tls_s()
   File "/usr/lib64/python2.7/site-packages/ldap/ldapobject.py", line 1095, in start_tls_s
     res = self._apply_method_s(SimpleLDAPObject.start_tls_s,*args,**kwargs)
   File "/usr/lib64/python2.7/site-packages/ldap/ldapobject.py", line 1071, in _apply_method_s
     return func(self,*args,**kwargs)
   File "/usr/lib64/python2.7/site-packages/ldap/ldapobject.py", line 780, in start_tls_s
     return self._ldap_call(self._l.start_tls_s)
   File "/usr/lib64/python2.7/site-packages/ldap/ldapobject.py", line 263, in _ldap_call
     result = func(*args,**kwargs)
 LOCAL_ERROR: {'desc': u'Local error'}

This means that currently keystone's [ldap]/use_pool and [ldap]/use_tls
options are incompatible. This patch fixes the problem by removing the
unnecessary call.

[1] https://linux.die.net/man/3/ldap_start_tls_s

Change-Id: I6baff12bcbd3b110e62f4bcdfb97c561d7ee5fe9
2017-03-08 22:43:01 +01:00
Colleen Murphy 5d69b3fed7 Expose SERVER_DOWN if connection fails
Without this change, ldappool might fail to bind to an LDAP server for
any number of reasons, but eats most of them and instead raises its own
not-very-descriptive error. A network failure or the LDAP server being
down is useful information that a user might be able to do something
with (see this related patch[1]) so let's add that to the list of
exceptions ldappool raises directly.

[1] https://review.openstack.org/#/c/390948

Change-Id: Iebb58f9046707a044ed86d8ce940e4c230ffd2aa
2016-11-08 16:04:23 +01:00
Jenkins 902e47efa5 Merge "Raise an explicit BackendError on TLS failures" 2016-05-17 23:43:49 +00:00
Steve Martinelli 5f6748212b make ldappool py3 compatible
* properly utf8 encode password
* switch to pyldap, the drop in replacement for python-ldap

Change-Id: Ic0fc838b8e015d90c946c3d161d096afe0bb7a21
Depends-On: I9cf13a5be63a0abc964c5a6e29c92d16365d89d8
Depends-On: I330b9b8fd3b53a588f0a1ae0c7de16cf03adb3cd
2016-05-17 21:52:23 +00:00
Steve Martinelli cee42d218e use standard docstring convention for parameters
switch from using "Args" to "params" so the generated API docs
look cleaner.

Change-Id: I82b65638e7c758a0dda7d35a1255738ef8c9158a
2016-05-12 21:57:20 -07:00
Jenkins c05f1cf608 Merge "Use standard-library logging to record errors" 2016-05-13 04:02:25 +00:00
Charles Duffy 91f5cbc36f Use standard-library logging to record errors
This is a port of a pull request from the old ldappool repo [1]

ldappool frequently catches and ignores transient errors.
There's nothing generally wrong with this -- but if the user
chooses to give the ldappool module a DEBUG priority level,
they really ought to be able to see these. This change makes it
so (and logs final connection errors with the higher ERROR level).

[1] https://github.com/mozilla-services/ldappool/pull/9

Change-Id: I223584393e6010845a5e7eb6aa619a77f6aba84f
2016-05-12 20:45:32 -07:00
Lorenzo M. Catucci 61695772c5 Raise an explicit BackendError on TLS failures
This change is a port of an existing pull request for ldappool [1]

It simply raises a more appropriate error / stacktrace if unable
to bind.

[1] https://github.com/mozilla-services/ldappool/pull/3

Change-Id: I3a17160a76122a1e4d05112fc86e346dea5dd88b
2016-05-12 20:14:05 -07:00
Colleen Murphy b08b776fdc Fix pool_full race condition
Sometimes the main thread starts before the spawned thread, which means
that the thread that is supposed to hold open a connection starts after
the main thread has already successfully made a connection. This means
that the test for a successful connection attempt[1] was nearly useless
since the main thread would get the connection first and activate it[2]
no matter how long the spawned thread waited, and the test for a failed
connection attempt[3] would intermittently fail since is sometimes able
to get the connection before the busy-waiting worker thread does.
Adding a short sleep in the main thread ensures that the main thread
yields to the worker thread and it can grab the connection first so we
can actually test what happens in the main thread.

[1] http://git.openstack.org/cgit/openstack/ldappool/tree/ldappool/tests/test_ldappool.py#n183
[2] http://git.openstack.org/cgit/openstack/ldappool/tree/ldappool/__init__.py#n167
[3] http://git.openstack.org/cgit/openstack/ldappool/tree/ldappool/tests/test_ldappool.py#n193

Change-Id: Ic32ef931cd672907dd14d5ec6339a6d7d9a2018d
2016-05-12 19:16:28 -07:00
Steve Martinelli 96d81b06e2 add .gitreview and fix ldappool gate
the docs job wasn't passing, and no .gitreview file

Change-Id: Ida0d366d924e2bcfc1b4efc14411240ee70490ae
2016-05-12 13:50:05 -07:00
Morgan Fainberg ceca46e006 PEP8 fixes
Fix pep8 errors, add appropriate flake8 exceptions.
2016-05-12 09:20:06 -07:00
Tarek Ziade a8594620ac Merge pull request #5 from charles-dyfis-net/issues/4
UTF-8 encode passwd only when set (fixes: #4)
2013-04-22 13:27:26 -07:00
Charles Duffy b0f5bff824 Initialize conn in _create_connector (fixes: #7) 2013-04-22 15:22:13 -05:00
Charles Duffy 0e1da6275b #4: UTF-8 encode passwd only when set 2013-04-18 16:59:32 -05:00
Chris McDonough d1f800739f fix use_tls flag 2012-02-26 02:58:00 -05:00
Tarek Ziadé 74a7e54570 more docs 2011-10-28 17:37:49 +02:00
Tarek Ziadé 1e5494ac3f initial import of server-core's ldappool 2011-10-28 17:10:59 +02:00