From: Eric Covener
Date: Sat, 29 May 2010 20:19:10 +0000 (+0000)
Subject: mod_authnz_ldap: Allow the initial DN lookup to bind with a
X-Git-Tag: 2.3.6~84
X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d15983f1d14b675226bbd8bca61c5db24314ebf0;p=apache
mod_authnz_ldap: Allow the initial DN lookup to bind with a
transformation of the basic auth username.
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@949436 13f79535-47bb-0310-9956-ffa450edef68
---
diff --git a/CHANGES b/CHANGES
index ca7bc90031..a468fa732e 100644
--- a/CHANGES
+++ b/CHANGES
@@ -28,6 +28,11 @@ Changes with Apache 2.3.7
processing is completed, avoiding orphaned callback pointers.
[Brett Gervasoni , Jeff Trawick]
+ *) mod_authnz_ldap: Allow the initial DN search during authentication
+ to use the HTTP username/pass instead of an anonymous or hard-coded
+ LDAP id (AuthLDAPInitialBindAsUser, AuthLDAPInitialBindPattern).
+ [Eric Covener]
+
*) mod_authnz_ldap: Publish requested LDAP data with an AUTHORIZE_ prefix
when this module is used for authorization. See AuthLDAPAuthorizePrefix.
PR 45584 [Eric Covener]
diff --git a/docs/manual/mod/mod_authnz_ldap.html.en b/docs/manual/mod/mod_authnz_ldap.html.en
index 0a0f4df0a4..e4d8fe88bc 100644
--- a/docs/manual/mod/mod_authnz_ldap.html.en
+++ b/docs/manual/mod/mod_authnz_ldap.html.en
@@ -68,6 +68,8 @@ for HTTP Basic authentication.
AuthLDAPDereferenceAliases
AuthLDAPGroupAttribute
AuthLDAPGroupAttributeIsDN
+
AuthLDAPInitialBindAsUser
+
AuthLDAPInitialBindPattern
AuthLDAPMaxSubGroupDepth
AuthLDAPRemoteUserAttribute
AuthLDAPRemoteUserIsDN
@@ -950,6 +952,79 @@ group membership
directive is not set, then mod_authnz_ldap
will
check if the group has bjenson
as a member.
+
+
+
+
+Description: | Determines if the server does the initial DN lookup using the basic authentication users'
+own username, instead of anonymously or with hard-coded credentials for the server |
+Syntax: | AuthLDAPInitialBindAsUser off|on |
+Default: | AuthLDAPInitialBindAsUser off |
+Context: | directory, .htaccess |
+Override: | AuthConfig |
+Status: | Extension |
+Module: | mod_authnz_ldap |
+Compatibility: | Available in version 2.3.7 and later |
+
+
By default, the server either anonymously, or with a dedicated user and
+ password, converts the basic authentication username into an LDAP
+ distinguished name (DN). This directive forces the server to use the verbatim username
+ and password provided by the incoming user to perform the initial DN
+ search.
+
+
If the verbatim username can't directly bind, but needs some
+ cosmetic transformation, see
+ AuthLDAPInitialBindPattern
.
+
+
Not available with authorization-only
+ This directive can only be used if this module authenticates the user, and
+ has no effect when this module is used exclusively for authorization.
+
+
+
See also
+
+
+
+
+
+Description: | Specifies the transformation of the basic authentication username to be used when binding to the LDAP server
+to perform a DN lookup |
+Syntax: | AuthLDAPInitialBindPatternregex substitution |
+Default: | AuthLDAPInitialBindPattern (.*) $1 (remote username used verbatim) |
+Context: | directory, .htaccess |
+Override: | AuthConfig |
+Status: | Extension |
+Module: | mod_authnz_ldap |
+Compatibility: | Available in version 2.3.7 and later |
+
+
If AuthLDAPInitialBindAsUser
is set to
+ ON, the basic authentication username will be transformed according to the
+ regular expression and substituion arguments.
+
+
The regular expression argument is compared against the current basic authentication username.
+ The substitution argument may contain backreferences, but has no other variable interpolation.
+
+
AuthLDAPInitialBindPattern (.+) $1@example.com
+
AuthLDAPInitialBindPattern (.+) cn=$1,dc=example,dc=com
+
+
Not available with authorization-only
+ This directive can only be used if this module authenticates the user, and
+ has no effect when this module is used exclusively for authorization.
+
+
debugging
+ The substituted DN is recorded in the environment variable
+ LDAP_BINDASUSER. If the regular expression does not match the input,
+ the verbatim username is used.
+
+
+
See also
+

diff --git a/docs/manual/mod/mod_authnz_ldap.xml b/docs/manual/mod/mod_authnz_ldap.xml
index 7b931bced7..430cbb2367 100644
--- a/docs/manual/mod/mod_authnz_ldap.xml
+++ b/docs/manual/mod/mod_authnz_ldap.xml
@@ -804,6 +804,71 @@ authorization
AuthBasicProvider
+
+AuthLDAPInitialBindAsUser
+Determines if the server does the initial DN lookup using the basic authentication users'
+own username, instead of anonymously or with hard-coded credentials for the server
+AuthLDAPInitialBindAsUser off|on
+AuthLDAPInitialBindAsUser off
+directory.htaccess
+
+Available in version 2.3.7 and later
+AuthConfig
+
+ By default, the server either anonymously, or with a dedicated user and
+ password, converts the basic authentication username into an LDAP
+ distinguished name (DN). This directive forces the server to use the verbatim username
+ and password provided by the incoming user to perform the initial DN
+ search.
+
+ If the verbatim username can't directly bind, but needs some
+ cosmetic transformation, see
+ AuthLDAPInitialBindPattern.
+
+ Not available with authorization-only
+ This directive can only be used if this module authenticates the user, and
+ has no effect when this module is used exclusively for authorization.
+
+
+AuthLDAPInitialBindPattern
+AuthLDAPBindDN
+
+
+
+AuthLDAPInitialBindPattern
+Specifies the transformation of the basic authentication username to be used when binding to the LDAP server
+to perform a DN lookup
+AuthLDAPInitialBindPatternregex substitution
+AuthLDAPInitialBindPattern (.*) $1 (remote username used verbatim)
+directory.htaccess
+
+Available in version 2.3.7 and later
+AuthConfig
+
+ If AuthLDAPInitialBindAsUser is set to
+ ON, the basic authentication username will be transformed according to the
+ regular expression and substituion arguments.
+
+ The regular expression argument is compared against the current basic authentication username.
+ The substitution argument may contain backreferences, but has no other variable interpolation.
+
+ AuthLDAPInitialBindPattern (.+) $1@example.com
+ AuthLDAPInitialBindPattern (.+) cn=$1,dc=example,dc=com
+
+ Not available with authorization-only
+ This directive can only be used if this module authenticates the user, and
+ has no effect when this module is used exclusively for authorization.
+
+ debugging
+ The substituted DN is recorded in the environment variable
+ LDAP_BINDASUSER. If the regular expression does not match the input,
+ the verbatim username is used.
+
+
+AuthLDAPInitialBindAsUser
+AuthLDAPBindDN
+
+
AuthLDAPBindDN
Optional DN to use in binding to the LDAP server
diff --git a/modules/aaa/mod_authnz_ldap.c b/modules/aaa/mod_authnz_ldap.c
index 2678850a31..5409f81bea 100644
--- a/modules/aaa/mod_authnz_ldap.c
+++ b/modules/aaa/mod_authnz_ldap.c
@@ -80,6 +80,9 @@ typedef struct {
int secure; /* True if SSL connections are requested */
char *authz_prefix; /* Prefix for environment variables added during authz */
+ int initial_bind_as_user; /* true if we should try to bind (to lookup DN) directly with the basic auth username */
+ ap_regex_t *bind_regex; /* basic auth -> bind'able username regex */
+ const char *bind_subst; /* basic auth -> bind'able username substitution */
} authn_ldap_config_t;
typedef struct {
@@ -386,6 +389,28 @@ static int set_request_vars(request_rec *r, enum auth_ldap_phase phase) {
return remote_user_attribute_set;
}
+static const char *ldap_determine_binddn(request_rec *r, const char *user) {
+ authn_ldap_config_t *sec =
+ (authn_ldap_config_t *)ap_get_module_config(r->per_dir_config, &authnz_ldap_module);
+ const char *result = user;
+ ap_regmatch_t regm[AP_MAX_REG_MATCH];
+
+ if (NULL == user || NULL == sec || !sec->bind_regex || !sec->bind_subst) {
+ return result;
+ }
+
+ if (!ap_regexec(sec->bind_regex, user, AP_MAX_REG_MATCH, regm, 0)) {
+ char *substituted = ap_pregsub(r->pool, sec->bind_subst, user, AP_MAX_REG_MATCH, regm);
+ if (NULL != substituted) {
+ result = substituted;
+ }
+ }
+
+ apr_table_set(r->subprocess_env, "LDAP_BINDASUSER", result);
+
+ return result;
+}
+
/*
* Authentication Phase
* --------------------
@@ -431,9 +456,16 @@ start_over:
/* There is a good AuthLDAPURL, right? */
if (sec->host) {
+ const char *binddn = sec->binddn;
+ const char *bindpw = sec->bindpw;
+ if (sec->initial_bind_as_user) {
+ bindpw = password;
+ binddn = ldap_determine_binddn(r, user);
+ }
+
ldc = util_ldap_connection_find(r, sec->host, sec->port,
- sec->binddn, sec->bindpw, sec->deref,
- sec->secure);
+ binddn, bindpw,
+ sec->deref, sec->secure);
}
else {
ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r,
@@ -1456,6 +1488,24 @@ static const char *set_charset_config(cmd_parms *cmd, void *config, const char *
return NULL;
}
+static const char *set_bind_pattern(cmd_parms *cmd, void *_cfg, const char *exp, const char *subst)
+{
+ authn_ldap_config_t *sec = _cfg;
+ ap_regex_t *regexp;
+
+ regexp = ap_pregcomp(cmd->pool, exp, AP_REG_EXTENDED);
+
+ if (!regexp) {
+ return apr_pstrcat(cmd->pool, "AuthLDAPInitialBindPattern: cannot compile regular "
+ "expression '", exp, "'", NULL);
+ }
+
+ sec->bind_regex = regexp;
+ sec->bind_subst = apr_pstrdup(cmd->pool, subst);
+
+ return NULL;
+}
+
static const command_rec authnz_ldap_cmds[] =
{
AP_INIT_TAKE12("AuthLDAPURL", mod_auth_ldap_parse_url, NULL, OR_AUTHCFG,
@@ -1547,6 +1597,15 @@ static const command_rec authnz_ldap_cmds[] =
(void *)APR_OFFSETOF(authn_ldap_config_t, authz_prefix), OR_AUTHCFG,
"The prefix to add to environment variables set during "
"successful authorization, default '" AUTHZ_PREFIX "'"),
+
+ AP_INIT_FLAG("AuthLDAPInitialBindAsUser", ap_set_flag_slot,
+ (void *)APR_OFFSETOF(authn_ldap_config_t, initial_bind_as_user), OR_AUTHCFG,
+ "Set to 'on' to perform the initial DN lookup with the basic auth credentials "
+ "instead of anonymous or hard-coded credentials"),
+
+ AP_INIT_TAKE2("AuthLDAPInitialBindPattern", set_bind_pattern, NULL, OR_AUTHCFG,
+ "The regex and substitution to determine a username that can bind based on an HTTP basic auth username"),
+
{NULL}
};