21

I've working LDAP authentication with the following setup

 AuthName            "whatever"
 AuthType            Basic
 AuthBasicProvider   ldap
 AuthLDAPUrl         "ldap://server/OU=SBSUsers,OU=Users,OU=MyBusiness,DC=company,DC=local?sAMAccountName?sub?(objectClass=*)"
 Require ldap-group  CN=MySpecificGroup,OU=Security Groups,OU=MyBusiness,DC=company,DC=local

This works, however I've to put all users I want to authenticate into MySpecificGroup. But on LDAP server I've configured that MySpecificGroup also contains the group MyOtherGroup with another list of users.

But those users in MyOtherGroup are not authenticated, I've to manually add them all to MySpecificGroup and basically can't use the nested grouping. I'm using Windows SBS 2003.

Is there a way to configure Apache LDAP to do this? Or is there a problem with possible infinite recursion and thus not allowed?

Bart De Vos
  • 17,761
  • 6
  • 62
  • 81
mark
  • 1,516
  • 4
  • 21
  • 33

4 Answers4

36

Besides AuthLDAPSubGroupDepth, that is available only in apache 2.4, it is possible, when using Microsoft AD LDAP, to do authorization using nested groups by using LDAP_MATCHING_RULE_IN_CHAIN matching rule. This is much faster than searching subgroups on the client, because it is done on the DC server with less queries over network.

Require ldap-filter memberof:1.2.840.113556.1.4.1941:=CN=Access to Apache,OU=My Organization Unit,DC=company,DC=com

The string 1.2.840.113556.1.4.1941 is an OID called LDAP_MATCHING_RULE_IN_CHAIN. This OID is assigned by Microsoft to be used with its LDAP implementation (part of Active Directory). You can not use it with other LDAP servers. The human redeable format is: iso(1).member_body(2).us(840).microsoft(113556).ad(1).as_schema(4).LDAP_MATCHING_RULE_IN_CHAIN(1941)

From Microsoft documentation:

This rule is limited to filters that apply to the DN. This is a special "extended" match operator that walks the chain of ancestry in objects all the way to the root until it finds a match.

See also:

Mircea Vutcovici
  • 16,706
  • 4
  • 52
  • 80
  • I'd upvote this 10x if I could. For folks running RHEL 5, this is a great solution. Compiling vendor source to get the latest features is not always a desirable solution! – Aaron Copley Nov 30 '12 at 21:50
  • I am glad it helped. I think this was the first documented usage of the LDAP_MATCHING_RULE_IN_CHAIN in apache. – Mircea Vutcovici Nov 30 '12 at 22:58
  • Is there a way to use `LDAP_MATCHING_RULE_IN_CHAIN` to retrieve recursive group membership and pass it as a header to a backend server (using the Apache as a reverse proxy)?? – Gershon Papi Aug 26 '18 at 08:53
  • `mod_authnz_ldap` doesn't provide this. However you can use `LDAP_MATCHING_RULE_IN_CHAIN` LDAP filter in your application. See: https://stackoverflow.com/a/34075052/290087 – Mircea Vutcovici Aug 26 '18 at 21:14
20

You need to set AuthLDAPSubGroupDepth to make this work. The integer you provide here specifies the maximum sub-group nesting depth that will be evaluated before the user search is discontinued.

Add this to your config:

AuthLDAPSubGroupDepth 1

More Info: here and here.

Drifter104
  • 3,693
  • 2
  • 22
  • 39
Bart De Vos
  • 17,761
  • 6
  • 62
  • 81
  • I'm running apache 2.2, it's mod_authnz_ldap hasn't AuthLDAPSubGroupDepth directive: http://httpd.apache.org/docs/2.2/mod/mod_authnz_ldap.html – Selivanov Pavel Nov 16 '11 at 10:48
  • So, why not update? – Bart De Vos Nov 16 '11 at 10:50
  • 2
    I'm running Debian Squeeze and I prefer using packages from stable distribution: well-tested, regular security updates. Apache 2.3 is still beta, it will appear in stable or stable-backports not soon. I've solved this problem by using `AuthnProviderAlias` for now. If nobody will offer solution for Apache 2.2, bounty is yours :) – Selivanov Pavel Nov 16 '11 at 11:42
  • given the new information of the groups being on different servers, I don't think this method will still work. – Jeff Strunk Nov 18 '11 at 13:43
  • Works like a charm on CentOS 6.3 with the default Apache 2.2.15 from the CentOS repo and in conjunction with MS Active Directory on Win Server 2008 R2. So easy and no fiddling with Active Directory handling under Linux. Thank you! –  Jan 18 '13 at 12:34
  • 3
    AuthLDAPSubGroupDepth doesn't exist in Apache HTTPd 2.4. AuthLDAPMaxSubGroupDepth is the correct directive to use. – Chris Harris Mar 17 '15 at 22:22
7

It looks like your only option in Apache 2.2 is to list every group that is included by your main authorized group.

Require ldap-group  CN=MySpecificGroup,OU=Security Groups,OU=MyBusiness,DC=company,DC=local
Require ldap-group  CN=MyOtherGroup,OU=Security Groups,OU=MyBusiness,DC=company,DC=local

This should be reasonable if your nested groups aren't too complicated.


Crossing AD Domains(using two LDAP servers)

You can set up OpenLDAP with the slapd_meta overlay running on your web server to proxy your authentication.

/etc/ldap/slapd.conf should look something like:

database meta
suffix   "DC=company,DC=local"
uri      "ldap://a.foo.com/OU=MyBusiness,DC=company,DC=local"
uri      "ldap://b.foo.com/OU=otherdomainsuffix,DC=company,DC=local"

Then, your mod_authnz_ldap stanza would look something like:

AuthName            "whatever"
AuthType            Basic
AuthBasicProvider   ldap
AuthLDAPUrl         "ldapi:///DC=company,DC=local?sAMAccountName?sub?(objectClass=*)"
Require ldap-group  CN=MySpecificGroup,OU=Security Groups,OU=MyBusiness,DC=company,DC=local
Require ldap-group  CN=MyOtherGroup,OU=Security Groups,OU=otherdomainsuffix,DC=company,DC=local

This will require some massaging to get it to work, but I think this is the general idea.

Jeff Strunk
  • 2,107
  • 1
  • 24
  • 29
  • 1
    Unfortunately this doesn't work when groups are in different AD domains(Domain1_DomainLocal_Group includes Domain2_Global_Group). It was the first thing I tried :) – Selivanov Pavel Nov 16 '11 at 18:57
  • Does that mean that one of the groups is on a different server? If that's true, I suspect AuthLDAPSubGroupDepth won't work for you either. – Jeff Strunk Nov 17 '11 at 23:35
  • Yes, two servers, two domains. I considered about integrating Linux box in AD and using PAM authentification, but mod-auth-pam is not supported since apache 2.0, mod-authnz-external + pwauth does not support groups. This all is sadly :( – Selivanov Pavel Nov 18 '11 at 09:14
  • 1
    Oh, I haven't notice that you updated answer. Using OpenLDAP slapd_meta may be solution, but it kills main point of this configuration: get user rights managed in one single point(Active Directory) by adding/deleting users from groups and including groups in each other. Here is my analogue solution with AuthnProviderAlias without additional OpenLDAP service: AuthLDAPURL ... AuthLDAPURL ... ... AuthBasicProvider first-ldap second-ldap – Selivanov Pavel Nov 18 '11 at 10:13
  • AuthnProviderAlias Looks like it should do the same thing as slapd-meta. To be clear, with slapd-meta you would not be managing any users and groups on the Web server's openldap instance. It would merely act as a proxy and allow you to search multiple directories. – Jeff Strunk Nov 18 '11 at 13:13
  • Yes. I will still have no centralized user management, and my infrastructure gets additional single point of failure(OpenLDAP server) and additional entity to monitor and backup. So we didn't find any way to completely integrate Apache with AD infrastructure. Thank you for spending your time for my question :) I'm really in mess about who should get the bounty :) – Selivanov Pavel Nov 18 '11 at 18:24
  • I think you misunderstand. I am suggesting you run OpenLDAP on your webservers. With slapd-meta, there is no data to backup. If that web server fails, it won't take out service for other servers. As for the bounty, I think your AuthnProviderAlias solution is the best. If you can award yourself the bounty, you should add an answer and do it. – Jeff Strunk Nov 18 '11 at 22:32
  • 1
    I'v decided to give bounty to Bart De Vos: this is not my question; for original question(without my own specific) his solution is simple and will work – Selivanov Pavel Nov 20 '11 at 18:36
  • Since RHEL 5 and RHEL6 still ship 2.2.x, this idea was perfect. It didn't occur to me immediately you can do multiple Require statements. – solarce Jan 02 '13 at 18:00
5

While the solution provided by @Mircea_Vutcovici worked for me, my only criticism is that people may get squeamish when they see bitwise operators in use.

For instance, I'll be handing over an Apache Bloodhound installation, that uses Apache HTTPd as the front end with AD group auth, to a group of fellow developers. They're going to have issues coming to grips with bitwise operators. Admins will not be as squeamish of course...I hope.

That being said, I have a solution that doesn't use the bitwise operator and that doesn't use multiple ldap-group definitions.

The following config works for me:

<Location /protected>
    # Using this to bind
    AuthLDAPURL "ldap://<MY_SERVER>:3268/<MY_SEARCH_BASE>?sAMAccountName?sub?(objectClass=user)"
    AuthLDAPBindDN "<MY_BIND_DN>"
    AuthLDAPBindPassword "<MY_PASSWORD>"
    LDAPReferrals Off

    AuthType Basic
    AuthName "USE YOUR AD ACCOUNT"
    AuthBasicProvider ldap
    Require ldap-group <MY_PARENT_GROUP>
    AuthLDAPMaxSubGroupDepth 1
    AuthLDAPSubgroupAttribute member
    AuthLDAPSubGroupClass group
    AuthLDAPGroupAttribute member
    AuthLDAPGroupAttributeIsDN on
</Location>

The critical part was the following config:

AuthLDAPSubGroupClass group

AuthLDAPMaxSubGroupDepth doesn't work by itself, nor when coupled with AuthLDAPSubgroupAttribute. It was only when I used AuthLDAPSubGroupClass that auth against sub groups started working...at least for me and my situation.

Chris Harris
  • 161
  • 1
  • 3