Issue #113: Authenticating with LDAP in an ActiveDirectory Tree with multiple Domains
|Reported by:||Ben La Monica|
|Created on:||2015-03-19 02:47|
|Updated on:||2015-09-09 17:00|
When using the ldap_auth module to authenticate users that reside in different domains, but are within the same tree, there is currently not a way to authenticate if the users are contained within different BaseDNs.
| -> Root of Tree - Host='example.com' BaseDN='DC=example,DC=com' \-----> Domain1 - Host='domain1.example.com' BaseDN='DC=domain1,DC=example,DC=com' \-----> Domain2 - Host='domain2.example.com' BaseDN='DC=domain2,DC=example,DC=com'
Authentication works for a user of domain1 if you specify the host of 'domain1.example.com' and a baseDN of DC=domain1,DC=example,DC=com. However, if a user in domain2 tries to authenticate, it fails. If you instead specify the host of 'example.com' with a BaseDN of 'DC=example,DC=com', none of the users will authenticate because the tree doesn't actually return the DN record for the user, but instead returns references to the domains contained within the tree that need to be queried.
In the code:
lobjects = server.search_ext_s(self.BASE_DN, self.SEARCH_SCOPE, filter_) ''' lobjects is: [(None, ['ldap://domain1.example.com/DC=domain1,DC=example,DC=com']), (None, ['ldap://domain2.example.com/DC=domain2,DC=example,DC=com'])]; instead of: [('DN=user1,OU=Accounts,DC=domain1,DC=example,DC=com', ['sAMAccountName' : 'user1'] ...)] '''
A possible solution to this would be to have a checkbox when configuring an LDAP domain to recursively query the domains when root returns only the domains of the tree instead of the user's DN. Alternatively, we could just detect this situation and perform the lookups.
Comment by Ben La Monica, on 2015-03-19 03:13
Comment by Ben La Monica, on 2015-03-19 03:14
I'm working on a pull-request, as I need this to work with my company's AD. Will submit it when ready.
Comment by Mads Kiilerich, on 2015-03-20 02:03
I don't understand ... is it one ldap tree or is it not? Is "root of tree" something special? Can you point to some documentation/description of that? What role do the 'host' names play? What will a recursive search to example.com of all users under DC=example,DC=com return?
Anyway, it feels like special support for this scenario perhaps would be too specific. It would perhaps be better if the "data model" for configuring authentication allowed for multiple "instantiation" of ldap with their own configuration ... and freedom to configure authentication and user info separately.
Comment by Ben La Monica, on 2015-03-20 02:59
Since I am not a network engineer, I use wikipedia for my definitions.
- A domain is defined as a logical group of network objects (computers, users, devices) that share the same active directory database.
- A tree is a collection of one or more domains and domain trees in a contiguous namespace, linked in a transitive trust hierarchy.
My company has dozens of domain controllers (replicated ldap databases) in each region. They are organized in a hierarchal manner by region (in a tree). Each ldap database has a BaseDN that is a subdomain of the global domain.
- Global (megacorp.com)
- North America (amrs.megacorp.com)
- Europe (emea.megacorp.com)
- Asia (asia.megacorp.com)
- South America (latam.megacorp.com)
Each of these domain names is actually NOT the ldap server hostname, but the key to looking up the hostname. If you perform a DNS lookup for SRV records for _ldap._tcp.amrs.megacorp.com, it will return a list of weighted hostnames to connect to.
When I configure Kallithea to query at the global level, I get back a list of referrals instead of the results of the query.
python-ldap (and openldap beneath it) have poor support for referrals and don't automatically forward the query along. Instead it just returns the referral urls in the attrs variable. I tried just enabling referral handling option for the ldap connection and it still didn't work.
There need to be two main enhancements for this to work:
Kallithea needs to support looking up the ldap servers using the DNS SRV records
Kallithea needs to handle referrals by forwarding the query to server represented by the url given to it.
Comment by Mads Kiilerich, on 2015-03-23 21:05
Ok, thanks for clarifying exactly what you setup is: a "meta" LDAP server that will return "referrals" to one of several "real" LDAP servers.
So from one point of view, the problem is that the meta server only return referrals, it doesn't forward the request and return the result. Making it do that could solve the problem.
Alternatively, you could have some kind of proxy ldap server in front of them; something that would follow the referrals and return the aggregated result.
It also sounds like a "good" solution to have this implemented in the client library - in the Python wrapper or in the native code. Referral support in Kallithea sounds a bit odd.
Comment by Thomas De Schampheleire, on 2015-08-06 20:18
@ben_la_monica Do you agree with the analysis of @kiilerix that fixing this in Kallithea is not conceptually correct? Shall we close this issue?
Comment by Ben La Monica, on 2015-08-07 02:29
No, I don't think you should close it. Large multi-national companies will have similar ldap setups. If the underlying library doesn't support this, then kallithea should find a different library that does, or should allow us to configure multiple ldap domains.
We use atlassian products which integrate easily with our active directory setup. Kallithea only supports connecting to one region at a time (and it was a beast to get configured correctly).
Unfortunately I've stopped evaluating kallithea for this reason since we have team members on 4 different continents and they were not all able to log in.
Comment by domruf, on 2015-09-09 17:00
@ben_la_monica we are talking about a Windows Active Directory environment right!? Would using kerberos authentication instead of LDAP be a possibility?