Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ldap aliases not being followed #890

Open
zeph opened this issue Sep 25, 2015 · 21 comments
Open

ldap aliases not being followed #890

zeph opened this issue Sep 25, 2015 · 21 comments

Comments

@zeph
Copy link

zeph commented Sep 25, 2015

hi, we spent some considerable time in reversing on how the rocketchat code is behaving against ldap and we have the perception that it is not following alias objects... therefore it attempts to use the resolved dn of the alias object (instead of the provided aliasedObjectName) and failing in binding to ldap

we'll try to provide a fix, this was just for sharing with you the results of our investigation

Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.

@ChristianKniep
Copy link

I am with @zeph on this, we changed our search to only return the real obj. Instead of using

{"filter": "uid=#{username}", "scope": "sub"}

we use

{"filter": "cn=#{username}", "scope": "sub"}

, which does not match the aliases. :)

@marceloschmidt
Copy link
Member

Thanks! We definitely need experts on LDAP on this one. We have close-to-zero knowledge, so if you guys could provide a fix for this, it would be awesome! Thanks!!

@Megatronic79
Copy link

@zeph can you describe the issue you are having? did you look at the ldap wiki where we added some examples?

https://github.com/RocketChat/Rocket.Chat/wiki/LDAP-Authentication

Ive managed to logon in Active Directory domain ok with either email addresss or sAMAccountName by just changing the search fitler accordingly.

@zeph
Copy link
Author

zeph commented Sep 28, 2015

@Megatronic79 we can't disclose too much... I'll try to describe it at my best

We were searching for a user based on its uid, if you apply the same search via ldapsearch you get 3 results... the main object, and 2 alias objects... instead of resolving fully the data as in the alias object, the code of RocketChat was using the dn of the alias as the next bind element for the authentication. A quick fix was to do the filter on something that was not available in an alias. Nevertheless... we are using OpenLDAP and I'd have preferred to standardize on using the uid instead of other fields.

@Megatronic79
Copy link

I see, im guessing this is unique to openLDAP then? the only alias attribute in AD will be the mail alias which is generally the sAMAccountName \ username as AD does technically have a uid?

Given that the aim is to have RC interface with multiple platforms we should extend on the following ticket that will allow custom search filters but also to change the user attribute based on their platform (such as uid, sAMAccountNam, mail, alias)

#737

EDIT: we did put a request in on that ticket to add a Logon Attribute: which would be the uid, mail etc..

@zeph
Copy link
Author

zeph commented Sep 28, 2015

@Megatronic79 no really, this is not unique to OpenLDAP... uid comes from the posix schemas, you'll have the same from Solaris Directory service. It is up to whoever implements a directory service to decide if they want to use aliases or memberships to define if a user has grants to specific structures of the organization's resources

@Megatronic79
Copy link

yeah sure, so I guess back to ticket 737 mentioned above that we need to make sure that the options to support any use case is available - as there are differences in a) how admins want to set this up and b) fundamental differences in directory platforms (in particular windows - 'NIX)

@Megatronic79
Copy link

@zeph - I just deployed a quick OpenLDAP instance to see if I can help out, ive set up some basic users, if I set this as the LDAP_Bind_search entry:

{"filter": "(&(objectClass=person)(uid=#{username}))", "scope": "sub", "userDN": "cn=admin,dc=somedomain,dc=com", "password": "somepass"}

The logon succeeds, Proxy user authenticates (admin in this test) against ldap, lookups the username passed via the UI as uid it finds it then logins with the DN of said user ok.

Is the issue we are having with groups? - I notice that openldap doesn't have the MemberOf entity natively but can be enabled?

@zeph
Copy link
Author

zeph commented Sep 28, 2015

objectClass: person excludes the aliases from the ldapsearch results, this would work too

@zeph
Copy link
Author

zeph commented Sep 28, 2015

in our case, as we allow anonymous reading of our ldap, the filter is as simple as reported by @ChristianKniep on top of this thread

@Megatronic79
Copy link

oh ok now I'm with you, no authentication stage, I think the assumption at the time was that there would be no anon searching for security reasons, we should check with @rodrigok what happens in this case where there is not initial authentication stage as it probably wasn't accounted for.

@rodrigok
Copy link
Member

If you don't need authentication before the LDAP search just remove the userDN and password:

{
    "filter": "(&(objectClass=person)(uid=#{username}))",
    "scope": "sub",
    "userDN": "cn=admin,dc=somedomain,dc=com", //<-remove
    "password": "somepass" //<-remove
}

result:

{ "filter": "(&(objectClass=person)(uid=#{username}))", "scope": "sub" }

@zeph
Copy link
Author

zeph commented Sep 29, 2015

@rodrigok thanks that is exactly how we are using it, and how @ChristianKniep commented on the second post of this thread... filtering on the objectClass=person in principle is good, it will avoid to step in the alias issue

but... in our organization we strongly use aliases, to decide who can access what and where... if we want to limit the access to RocketChat to a specific group of people we would create an organization unit, and create aliases under it, for each person that we want to access the service

therefore... thanks everybody for all the fantastic input, this is a great learning experience and confrontation between multiple integrations and environments, with different vendors and technologies... still, RocketChat is not handling the aliases correctly

the action stays on me to provide a patch, or to whoever finds the time first :)

@Megatronic79
Copy link

Looking forward to the patch.

I'm guessing without the MemborOf or GroupOfNames objects in openldap I think we would need two queries to the LDAP server? (OpenLDAP doesn't support nested or LDAP_MATCHING_RULE_IN_CHAIN for a single call)

As the Groups in openldap typically only stores the MemberUID we need to first check if the user exists in the group if so query again and grab the DN from the users object and authenticate with it else reject logon.

With AD this can be done in one query I suspect it has to be a two-step approach for other ldap servers but I'm still reading up on the differences openldap.

Either way let us know once you get some time to supply a patch and we'll test!

@zeph
Copy link
Author

zeph commented Sep 29, 2015

the current code is exactly doing 2 queries... how is it behaving on AD?

@Megatronic79
Copy link

Sorry let me rephrase that, the 1st query currently (for AD) is the authentication to allow a search the second is the lookup of group and user DN passed in the filter. (AD does the second part in one query)

If you use an LDAP server witch allows anon binds then yeah 2 would be all you need for that also (as no initial auth is required, one to lookup group if part of group, and two to get the user DN), but I'm guessing best practise is to not allow a anon binds in a business environment meaning this just goes up to 3 query's per logon.

@zeph
Copy link
Author

zeph commented Sep 29, 2015

uhmm... we did try (wrongly) initially to go for the authenticated setup... as I imagined you would have had a setup where the app would have compared the hashes on itself instead of leveraging ldap... there is when I found out that you instead used that query to do a first lookup of the end user, to then bind with his/her credentials...

tl;dr basically even if u go for anon setup, you always have a query first that lookups the DN of the user

...that is the query that sees the alias, the DN for the next query is already in the document, as aliasedObjectName, so there is no need of an extra query as u mentioned

@Megatronic79
Copy link

Ok, so aliasedObjectName is the Group Name the user is a member of then?

@zeph
Copy link
Author

zeph commented Sep 29, 2015

no... that field contains the DN of the user, to be used to bind in the next query

the alias object, containing that field, is placed in an organization unit OU (aka Group Name in ur terminology) and that defines the belonging of the user to such "group"

@Megatronic79
Copy link

ok. Sorry for the questions, but what's the equiv single query to this AD query in OpenLDAP ?

(&(objectCategory=person)(objectclass=user)(memberOf=CN=Acces,OU=Groups,DC=domain,DC=com)(sAMAccountName=firstname.surname))

This will return the users DN if the User exists in the directory with username = firstname.surname and is in group called access. (and matches the object criteria)

I'm unable to do the same using Apache directory studio connected to an OpenLDAP server due to the lack of memberOf - which works if I give openldap this support but obviously this isn't the best option, if I search on the memberuid it returns the DN of the group not the user? I'm probably missing something.

@rodrigok rodrigok mentioned this issue Feb 9, 2016
8 tasks
Shailesh351 pushed a commit to Shailesh351/Rocket.Chat that referenced this issue Aug 27, 2021
….17.1

[Upstream Catchup] Merge RC:master to develop_pwa (3.17.1)
@Teak-Rosewood
Copy link

hey! @rodrigok is this issue still open?

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

No branches or pull requests

7 participants