Discussion:
LDAP authentication: non-anonymous bind
Lars Kruse
2010-01-25 12:00:09 UTC
Permalink
Hi,

the attached patch adds a second option for non-anonymous binds to the
authnz_ldap module. Please consider it for adoption.

The current situation:
The authnz_ldap module supports only one kind of non-anonymous bind to the ldap
server: by specifying the username ("binddn") and password ("bindpw") in an
apache config file. This is obviously not a very pretty thing, since you need
to take good care for file permissions (as an admin) and also users may feel a
little bit uncomfortable to put their plaintext login data into an htaccess
file.


Use cases where anonymous binds don't work:

1) The most common use case for non-anonymous binds is an Active Directory
server, that (by default) does not accept anonymous binds. Usually this is
solved by creating a specific ldap user with limited read access and putting
its credentials into the apache config file. See examples:
http://www.held-im-ruhestand.de/software/apache-ldap-active-directory-authentication
http://www.jejik.com/articles/2007/06/apache_and_subversion_authentication_with_microsoft_active_directory/

2) My specific use case are some servers, that provide various services (mail,
webspace, wikis, svn, ...) to different people. All accounts are managed in a
single LDAP database. Since privacy is important for our users, it is not
acceptable, that they can get a complete user list from the ldap server. Thus
the servers, that offer shell access or webspace to users may not bind to the
LDAP server anonymously and even authenticated users may only access their own
accounts within the ldap database.
In this setup we can't use the authnz_ldap module, since we need
authenticated binds, but we don't want our users to store their precious
credentials in a plain text file.

One way of solving this issue is already implemented in Muquit's "mod_auth_ldap"
(http://www.muquit.com/muquit/software/mod_auth_ldap/mod_auth_ldap_apache2.html).
There the respective option is called "AuthOnBind".

The patch, that I attached (not based on Muquit's code), allows the following:
- a user tries to log into an apache-served location, that requires
authentication
- the given credentials (username and password) are combined with the "basedn"
and "attrib" value (defined in "AuthLDAPUrl")
- the authnz_ldap module uses these credentials to bind to the server
(for authentication and authorization)

The above behaviour is triggered by a new configuration directive, that I named
"AuthLDAPAuthOnBind". It defaults to "off", thus nothing changes for current
configurations.
This new behaviour covers the two use cases described above (even though I did
not check it in an Active Directory setup).

The patch is currently in use in our setup (see use case (2) above) and it runs
without problems.

Regarding the code quality:
I am not used to the apache codebase, thus I am not sure, if I used the string
functions in the proper way (around line 387). Please comment, if I overlooked
something!

cheers,
Lars

PS: I just e-mailed a signed "Individual Contributor License Agreement" to
***@apache.org - I am not sure, if this is necessary - just to let you
know ...
Eric Covener
2010-01-26 02:44:56 UTC
Permalink
Post by Lars Kruse
This new behaviour covers the two use cases described above (even though I did
not check it in an Active Directory setup).
Patch is nice and simple, but it would be great if someone with AD
leanings could confirm that this combination of HTTP username,
attribute, and basedn is likely to result in something that can bind
in a typical AD install.
--
Eric Covener
***@gmail.com
Ryan Phillips
2010-01-26 04:29:28 UTC
Permalink
Post by Eric Covener
Post by Lars Kruse
This new behaviour covers the two use cases described above (even though I did
not check it in an Active Directory setup).
Patch is nice and simple, but it would be great if someone with AD
leanings could confirm that this combination of HTTP username,
attribute, and basedn is likely to result in something that can bind
in a typical AD install.
I've been working with LDAP and AD for a while now, and, AFAIK, there
are only two ways to bind to a Directory Server:

1. User's BindDN, and
2. User Principle Name

I don't believe the proposed method is portable to AD. In addition,
the modifications to the binddn are in the 'sec' variable which is an
authn_ldap_config_t structure created for the module and not for the
_request_.

Regards,
Ryan
Eric Covener
2010-01-26 13:04:49 UTC
Permalink
Post by Ryan Phillips
In addition,
the modifications to the binddn are in the 'sec' variable which is an
authn_ldap_config_t structure created for the module and not for the
_request_.
good catch, this is also a defect on one of the handful of patches in bugzilla!
--
Eric Covener
***@gmail.com
Graham Leggett
2010-01-26 12:06:34 UTC
Permalink
Post by Eric Covener
Post by Lars Kruse
This new behaviour covers the two use cases described above (even though I did
not check it in an Active Directory setup).
Patch is nice and simple, but it would be great if someone with AD
leanings could confirm that this combination of HTTP username,
attribute, and basedn is likely to result in something that can bind
in a typical AD install.
There are three possible scenarios for login:

- User provides username, auth_ldap server does a search within the
directory to find the DN corresponding to the username, and then
attempts to bind as that DN. If it succeeds, you're in. This usually
requires a DN of some kind to use to do the initial login to do the
original search. (AD works fine in this scenario, on condition you
have an account to bind and do the initial search with).

- User provides username, auth_ldap applies the username to an admin-
provided recipe of some kind to create the DN. This recipe needs to be
flexible enough to support various scenarios, such as the base URL for
the recipe being something other than the base URL for searches (think
group searches, a group might not have the same base DN as the person).

- User provides username, auth_ldap tries to bind directly with that
username without first converting it to a DN. This is how AD would work.

Ideally auth_ldap should support the above three methods, am I correct
in understanding that the patch implements the second option above? (I
don't have time to review it fully at the moment).

Regards,
Graham
--
Vadim Chekan
2010-01-29 06:12:38 UTC
Permalink
Post by Lars Kruse
Hi,
the attached patch adds a second option for non-anonymous binds to the
authnz_ldap module. Please consider it for adoption.
I've applied it to 2.2.14 today and tested on windows (AD).
It can't bind if the exact ldap folder is unknown.

Let's say we have users not in OU=Users, but in OU=Developers and OU=QA.
In order for developer to authenticate http would have to bind to AD
with search base "OU=Developers,dc=company,dc=com". But in order for QA
person, searach base should be different: "QA=Developers,dc=company,dc=com".

Let's say we do search by sAMAccountName. Then with current approach the
search base generate: "sAMAccountName=<user name>,dc=company,dc=com".
Such search base does not exist.

In order to search in subfolders, search base should be static, meaning
set in config file. And user name (variable part) should go into filter.
Then it will be possible to search in "dc=company,dc=com" including
subfolders by filter "(&(objectClass=user)(sAMAccountName=<user name>)"

I managed to make it working (dirty hack):
I bind with username as is (must be <user name>@organization.com), and
attribute in AuthLdapUrl should be set to "userPrincipalName".
So I changed the code:
- sec->binddn = apr_psprintf(r->pool, "%s=%s,%s", sec->attribute, user,
sec->basedn);
+ sec->binddn = apr_psprintf(r->pool, "%s", user);
Post by Lars Kruse
The authnz_ldap module supports only one kind of non-anonymous bind to the ldap
server: by specifying the username ("binddn") and password ("bindpw") in an
apache config file. This is obviously not a very pretty thing, since you need
to take good care for file permissions (as an admin) and also users may feel a
little bit uncomfortable to put their plaintext login data into an htaccess
file.
Now, if we are at it, can we discuss encryption? Authnz_ldap will
request AD in plain text. Not good. Without AuthLDAPAuthOnBind only
single pseudo-user account was compromised with in ON, everybody's
account will travel across the network in plain text, even if you
connect to https via ssl!

I played a little bit with Apache Directory Studio, and I could connect
to AD only in 2 cases.
No encryption; Simple Authentication (plain text)
No encryption; Digest-md5 (SASL)

Any chance we can leverage digest-md5 authentication method?
Othervise I would allow only ssl-emabled connection to AD. May be with
some option "enable plain text if you know what you are doing".

Vadim.

Loading...