Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

Remiz
Copy link

@Remiz Remiz commented Jan 24, 2020

I ran into an issue where my ldap server was flooded with tons of open connections that would only close when I restart my web server. I traced it down to django-auth-library authentication & populate_user method, which does not properly unbind after retrieving what it needs on the server.

This fix should help with scalability for people having the same issue ("Too many open files..." error message).

Remiz added 3 commits January 24, 2020 17:09
I ran into an issue where my ldap server was flooded with tons of opened connection that would only close when I restarted my web server. I traced it down to django-auth-library authentication, which does not properly unbind after retrieving what it needs on the server.

This fix should help with scalability for people having the same issue ("Too many open files..." error message).
Also ensure that the populate_user request is properly unbind
@stettberger
Copy link

This is an important issue. Otherwise, my LDAP server won't react to any new connection requests and users stop being able to login into the server

@jdufresne
Copy link
Member

Can you please investigate the test failures and add a new one?

@Remiz
Copy link
Author

Remiz commented Apr 30, 2021

Sorry for the long silence. I looked into the test failure and I believe it's related to this issue within python-ldap: python-ldap/python-ldap#253
It doesn't look like it has been fixed yet. I personally use the changes I proposed on my project and never encountered the issue returned by the tests, so I'm not too sure why these are failing (maybe a threading issue).

@francoisfreitag
Copy link
Member

I believe tests expect to be able to reuse the connection from the LDAP user, but this change unbinds it.

From https://www.python-ldap.org/en/python-ldap-3.3.0/reference/ldap.html#ldap.LDAPObject.unbind_s:

Once called, the connection to the LDAP server is closed and the LDAP object is marked invalid. Further invocation of methods on the object will yield exceptions.

For example, test_simple_group_query uses the user created by the authenticate call to make an assertion on the user group membership.

alice = authenticate(username="alice", password="password")
query = LDAPGroupQuery("cn=alice_gon,ou=query_groups,o=test")
self.assertIs(query.resolve(alice.ldap_user), True)

The test failures indicate this change is preventing future loading of user properties (such as group membership) from the _LDAPUser. It seems like an unbind_s call would be welcome, but the suggested places would likely break a lot of projects using this library.


The way to go is to improve the current design of maintaining a (lazy) connection per _LDAPUser instance and never closing it.

IIUC, LDAP can repeatedly bind as different users. An idea could be to pool LDAP connections, and have all call sites perform a bind before executing their request. Currently, depending on configuration, the library can bind once to execute the search for the user, a second time with the user credentials (to authenticate the user) and a third time to load the user attributes.
Getting a connection for a connection pool would facilitate handling the lifecycle of these connections. The LDAP user would borrow a connection when it needs to (e.g. with LDAPConnection() as connection:) and release it when it does not need it. The connection pool would be in charge of keeping an upper bound on the number of active connections, reusing them and closing them.

@MarkGooding
Copy link

I (believe I) was having this issue, with django-auth-ldap getting SERVER_DOWN back from the server after logging in several users, and then preventing further login for a time period. I have implemented this change by subclassing the LDAPBackend and unbinding the ldap connection within that (to save having a separate branch of the LDAPBackend). However, I agree a reused connection pool would be a nicer solution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants