matrix-org / matrix-synapse-ldap3

An LDAP3 auth provider for Synapse
Apache License 2.0
127 stars 46 forks source link

Cant login with LDAP after update #13

Closed muppeth closed 5 years ago

muppeth commented 7 years ago

Hi there, Today I updated synapse to version 0.18.5. I use debian8 package for both matrix-synapse and python-matrix-synapse-ldap3, however after update, I can't no longer authenticate. This is the traceback:

Traceback (most recent call last): File "/usr/lib/python2.7/dist-packages/synapse/http/server.py", line 116, in wrapped_request_handler yield request_handler(self, request, request_metrics) AttributeError: 'NoneType' object has no attribute 'bind'

Am I missing something?

mweinelt commented 7 years ago

I believe this was fixed in https://github.com/matrix-org/matrix-synapse-ldap3/commit/4b07b20b1135bdf7709debf3899ed077fd43ecda. Do you use a recent version?

muppeth commented 7 years ago

I just did apt-get upgrade this morning. package version: ii python-matrix-synapse-ldap3 0.1.1-1 all An LDAP3 auth provider for Synapse

Update: @mweinelt I just checked the commit and yes I'm using the current version. Though with the previous one it was working fine. (with small modifications from https://github.com/matrix-org/synapse/issues/1662 )

mweinelt commented 7 years ago

I believe the complete stacktrace is being hidden by twisted.

Can you set full_twisted_stacktraces: true and trigger the error again so we get the complete trace?

antil0pa commented 7 years ago

here:

Traceback (most recent call last):
  File "/usr/lib/python2.7/dist-packages/synapse/http/server.py", line 116, in wrapped_request_handler
    yield request_handler(self, request, request_metrics)
  File "/usr/lib/python2.7/dist-packages/twisted/internet/defer.py", line 1126, in _inlineCallbacks
    result = result.throwExceptionIntoGenerator(g)
  File "/usr/lib/python2.7/dist-packages/twisted/python/failure.py", line 389, in throwExceptionIntoGenerator
    return g.throw(self.type, self.value, self.tb)
  File "/usr/lib/python2.7/dist-packages/synapse/http/server.py", line 255, in _async_render
    callback_return = yield callback(request, **kwargs)
  File "/usr/lib/python2.7/dist-packages/twisted/internet/defer.py", line 1126, in _inlineCallbacks
    result = result.throwExceptionIntoGenerator(g)
  File "/usr/lib/python2.7/dist-packages/twisted/python/failure.py", line 389, in throwExceptionIntoGenerator
    return g.throw(self.type, self.value, self.tb)
  File "/usr/lib/python2.7/dist-packages/synapse/rest/client/v1/login.py", line 94, in on_POST
    result = yield self.do_password_login(login_submission)
  File "/usr/lib/python2.7/dist-packages/twisted/internet/defer.py", line 1126, in _inlineCallbacks
    result = result.throwExceptionIntoGenerator(g)
  File "/usr/lib/python2.7/dist-packages/twisted/python/failure.py", line 389, in throwExceptionIntoGenerator
    return g.throw(self.type, self.value, self.tb)
  File "/usr/lib/python2.7/dist-packages/synapse/rest/client/v1/login.py", line 137, in do_password_login
    password=login_submission["password"],
  File "/usr/lib/python2.7/dist-packages/twisted/internet/defer.py", line 1126, in _inlineCallbacks
    result = result.throwExceptionIntoGenerator(g)
  File "/usr/lib/python2.7/dist-packages/twisted/python/failure.py", line 389, in throwExceptionIntoGenerator
    return g.throw(self.type, self.value, self.tb)
  File "/usr/lib/python2.7/dist-packages/synapse/handlers/auth.py", line 491, in _check_password
    is_valid = yield provider.check_password(user_id, password)
  File "/usr/lib/python2.7/dist-packages/twisted/internet/defer.py", line 1128, in _inlineCallbacks
    result = g.send(result)
  File "/usr/local/lib/python2.7/dist-packages/ldap_auth_provider.py", line 106, in check_password
    server=server, localpart=localpart, password=password
  File "/usr/local/lib/python2.7/dist-packages/ldap_auth_provider.py", line 336, in _ldap_authenticated_search
    if not (yield threads.deferToThread(conn.bind)):
AttributeError: 'NoneType' object has no attribute 'bind'
mweinelt commented 7 years ago

@antil0pa That's probably 0.1.0, please update to 0.1.1.

muppeth commented 7 years ago

@mweinelt me and @antilopa are running the same server and as stated above, according to dpkg we are running 0.1.1 version ii python-matrix-synapse-ldap3 0.1.1-1 all An LDAP3 auth provider for Synapse

Is there any other way to check the version?

mweinelt commented 7 years ago

Thats weird, because in 0.1.1 line 336 is something else entirely.

$ python
>>> import ldap_auth_provider
>>> ldap_auth_provider.__version__
'0.1.1'
antil0pa commented 7 years ago

Same here:

>>> import ldap_auth_provider
>>> ldap_auth_provider.__version__
'0.1.1'
antil0pa commented 7 years ago

ldap_auto_provider.py is indeed different. odd. I wget the newer file version from the repo but the error remains.

mweinelt commented 7 years ago

Did you migrate your config to use the external module instead of the provider that shipped with synapse? https://github.com/matrix-org/matrix-synapse-ldap3/blob/master/README.rst

antil0pa commented 7 years ago

yes. The module was changed to "ldap_auth_provider.LdapAuthProvider" in homeserver.yaml config

Edit:

 password_providers:
      - module: "ldap_auth_provider.LdapAuthProvider"
4nd3r commented 7 years ago

I can also confirm, that external LDAP module config doesn't have any effect.

# cat /etc/debian_version
8.6
# dpkg -l | egrep 'synapse|ldap3'
ii  matrix-synapse                 0.18.5-1                         all          Reference Synapse Home Server
ii  python-ldap3                   0.9.9.3-1~bpo8+2                 all          Pure Python LDAP client library
ii  python-matrix-synapse-ldap3    0.1.1-1                          all          An LDAP3 auth provider for Synapse
antil0pa commented 7 years ago

As a workaround, we replaced ldap_auth_provider.py with the old version shipped with synapse. For now Ldap authentication works, hopefully we can figure out why the external module doesn't work.

antil0pa commented 7 years ago

in ldap_authprovider.py , line 168 (fetch metadata for account creation)_:

searchbase=self.ldap_base

requires that user will have rights to query all attributes under ldap_base. In our use case users do not have full permissions and can only query themselves, so no results are returned. We did a dirty fix and changed the query to this:

search_base="cn={ldap_user},{ldap_base}".format(
                         ldap_user=localpart,
                         ldap_base=self.ldap_base
                     ),

And that seems to fix the issue of new user registration for now. If there is a better way to get same results, please let me know.

mweinelt commented 7 years ago

It does not sound to me like you need to search for users then, or is your search base nested?

Wouldn't simple bind work in your case, or isn't it deterministic where your users are?

andersruneson commented 7 years ago

@muppeth Do you still have trouble with this or can this issue be closed?

muppeth commented 7 years ago

@andersruneson sorry for such long delay in my reply. The issue is still valid. It is due to my olcAccess setting for "ou" where users are stored is set to: by self read by * none

It means that users can't do a search in the whole ou, so either user has to lookup himself (like @antilopa suggested) or readonly/admin user (specified in the synapse config) has to do the search. Perhaps I could change the setting but so far it's the only application that would require it.

mweinelt commented 7 years ago

Reiterating on the question at hand:

Wouldn't simple bind work in your case, or isn't it deterministic where your users are?

andersruneson commented 7 years ago

@muppeth I don't really get how to set up for not using the admin/manager bind, could you please paste your config?

muppeth commented 7 years ago

@andersruneson I do use admin/manager account to bind to the ldap server. my synapse is set up properly. The problem is that during the phase of fetching metadata for the account creation (line 168), this search is done by the user that has been created.

search_base=self.ldap_base,
                    search_filter=query,
                    attributes=[
                        self.ldap_attributes['name'],
                        self.ldap_attributes['mail']

The problem is that my olcAccess prevents users from searching the entire search_base but only themselfs. The query above will exit with no results as the user cant query that directory. So we had to modify the query as posted by @antil0pa search_base="cn={ldap_user},{ldap_base}".format( ldap_user=localpart, ldap_base=self.ldap_base ),


So only then users can lookup the metadata information as the search base points to their account directly. This is probably not the prettiest way to do that, but we host multiple services using ldap authentication, and they all work well except for synapse.
I think that metadata search should be done by admin/manager account and not the user that's being authenticated.
swarnat commented 5 years ago

Sorry to pull this up from historyI We run into the exact same issue. Any change we got search_base as configuration option with some placeholders, like @antil0pa posted?

Because we are using an ansible controlled setup and docker based synapse, a file modification isn't as easy it normally is. I tried to temporarily manipulate the file in docker, so I know it's the reason.

I'm asking myself, why a user should need SEARCH capability, or which ideology is behind this decision. I'm just started to understand LDAP, so sorry for stupid question, but as long as a operation works without a permission, it shouldn't need the permission, which can probably open other problems.

richvdh commented 5 years ago

I'm pretty sure this bug was fixed way back in December 2016. People who are still seeing the same error message are probably seeing a different problem at a different point in the code: please post a full stacktrace in a new issue.