processing is completed, avoiding orphaned callback pointers.
[Brett Gervasoni <brettg senseofsecurity.com>, 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]
<li><img alt="" src="../images/down.gif" /> <a href="#authldapdereferencealiases">AuthLDAPDereferenceAliases</a></li>
<li><img alt="" src="../images/down.gif" /> <a href="#authldapgroupattribute">AuthLDAPGroupAttribute</a></li>
<li><img alt="" src="../images/down.gif" /> <a href="#authldapgroupattributeisdn">AuthLDAPGroupAttributeIsDN</a></li>
+<li><img alt="" src="../images/down.gif" /> <a href="#authldapinitialbindasuser">AuthLDAPInitialBindAsUser</a></li>
+<li><img alt="" src="../images/down.gif" /> <a href="#authldapinitialbindpattern">AuthLDAPInitialBindPattern</a></li>
<li><img alt="" src="../images/down.gif" /> <a href="#authldapmaxsubgroupdepth">AuthLDAPMaxSubGroupDepth</a></li>
<li><img alt="" src="../images/down.gif" /> <a href="#authldapremoteuserattribute">AuthLDAPRemoteUserAttribute</a></li>
<li><img alt="" src="../images/down.gif" /> <a href="#authldapremoteuserisdn">AuthLDAPRemoteUserIsDN</a></li>
directive is not set, then <code class="module"><a href="../mod/mod_authnz_ldap.html">mod_authnz_ldap</a></code> will
check if the group has <code>bjenson</code> as a member.</p>
+</div>
+<div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
+<div class="directive-section"><h2><a name="AuthLDAPInitialBindAsUser" id="AuthLDAPInitialBindAsUser">AuthLDAPInitialBindAsUser</a> <a name="authldapinitialbindasuser" id="authldapinitialbindasuser">Directive</a></h2>
+<table class="directive">
+<tr><th><a href="directive-dict.html#Description">Description:</a></th><td>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</td></tr>
+<tr><th><a href="directive-dict.html#Syntax">Syntax:</a></th><td><code>AuthLDAPInitialBindAsUser <em>off|on</em></code></td></tr>
+<tr><th><a href="directive-dict.html#Default">Default:</a></th><td><code>AuthLDAPInitialBindAsUser off</code></td></tr>
+<tr><th><a href="directive-dict.html#Context">Context:</a></th><td>directory, .htaccess</td></tr>
+<tr><th><a href="directive-dict.html#Override">Override:</a></th><td>AuthConfig</td></tr>
+<tr><th><a href="directive-dict.html#Status">Status:</a></th><td>Extension</td></tr>
+<tr><th><a href="directive-dict.html#Module">Module:</a></th><td>mod_authnz_ldap</td></tr>
+<tr><th><a href="directive-dict.html#Compatibility">Compatibility:</a></th><td>Available in version 2.3.7 and later</td></tr>
+</table>
+ <p>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.</p>
+
+ <p> If the verbatim username can't directly bind, but needs some
+ cosmetic transformation, see <code class="directive"><a href="# authldapinitialbindpattern">
+ AuthLDAPInitialBindPattern</a></code>.</p>
+
+ <div class="note"><h3>Not available with authorization-only</h3>
+ This directive can only be used if this module authenticates the user, and
+ has no effect when this module is used exclusively for authorization.
+ </div>
+
+<h3>See also</h3>
+<ul>
+<li><code class="directive"><a href="../mod/mod_authnnz_ldap.html#authldapinitialbindpattern">AuthLDAPInitialBindPattern</a></code></li>
+<li><code class="directive"><a href="../mod/mod_authnnz_ldap.html#authldapbinddn">AuthLDAPBindDN</a></code></li>
+</ul>
+</div>
+<div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
+<div class="directive-section"><h2><a name="AuthLDAPInitialBindPattern" id="AuthLDAPInitialBindPattern">AuthLDAPInitialBindPattern</a> <a name="authldapinitialbindpattern" id="authldapinitialbindpattern">Directive</a></h2>
+<table class="directive">
+<tr><th><a href="directive-dict.html#Description">Description:</a></th><td>Specifies the transformation of the basic authentication username to be used when binding to the LDAP server
+to perform a DN lookup</td></tr>
+<tr><th><a href="directive-dict.html#Syntax">Syntax:</a></th><td><code>AuthLDAPInitialBindPattern<em><var>regex</var> <var>substitution</var></em></code></td></tr>
+<tr><th><a href="directive-dict.html#Default">Default:</a></th><td><code>AuthLDAPInitialBindPattern (.*) $1 (remote username used verbatim)</code></td></tr>
+<tr><th><a href="directive-dict.html#Context">Context:</a></th><td>directory, .htaccess</td></tr>
+<tr><th><a href="directive-dict.html#Override">Override:</a></th><td>AuthConfig</td></tr>
+<tr><th><a href="directive-dict.html#Status">Status:</a></th><td>Extension</td></tr>
+<tr><th><a href="directive-dict.html#Module">Module:</a></th><td>mod_authnz_ldap</td></tr>
+<tr><th><a href="directive-dict.html#Compatibility">Compatibility:</a></th><td>Available in version 2.3.7 and later</td></tr>
+</table>
+ <p>If <code class="directive"><a href="#authldapinitialbindasuser">AuthLDAPInitialBindAsUser</a></code> is set to
+ <em>ON</em>, the basic authentication username will be transformed according to the
+ regular expression and substituion arguments.</p>
+
+ <p> The regular expression argument is compared against the current basic authentication username.
+ The substitution argument may contain backreferences, but has no other variable interpolation.</p>
+
+ <div class="example"><p><code> AuthLDAPInitialBindPattern (.+) $1@example.com </code></p></div>
+ <div class="example"><p><code> AuthLDAPInitialBindPattern (.+) cn=$1,dc=example,dc=com</code></p></div>
+
+ <div class="note"><h3>Not available with authorization-only</h3>
+ This directive can only be used if this module authenticates the user, and
+ has no effect when this module is used exclusively for authorization.
+ </div>
+ <div class="note"><h3>debugging</h3>
+ The substituted DN is recorded in the environment variable
+ <em>LDAP_BINDASUSER</em>. If the regular expression does not match the input,
+ the verbatim username is used.
+ </div>
+
+<h3>See also</h3>
+<ul>
+<li><code class="directive"><a href="../mod/mod_authnnz_ldap.html#authldapinitialbindasuser">AuthLDAPInitialBindAsUser</a></code></li>
+<li><code class="directive"><a href="../mod/mod_authnnz_ldap.html#authldapbinddn">AuthLDAPBindDN</a></code></li>
+</ul>
</div>
<div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
<div class="directive-section"><h2><a name="AuthLDAPMaxSubGroupDepth" id="AuthLDAPMaxSubGroupDepth">AuthLDAPMaxSubGroupDepth</a> <a name="authldapmaxsubgroupdepth" id="authldapmaxsubgroupdepth">Directive</a></h2>
<seealso><directive module="mod_auth_basic">AuthBasicProvider</directive></seealso>
</directivesynopsis>
+<directivesynopsis>
+<name>AuthLDAPInitialBindAsUser</name>
+<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</description>
+<syntax>AuthLDAPInitialBindAsUser <em>off|on</em></syntax>
+<default>AuthLDAPInitialBindAsUser off</default>
+<contextlist><context>directory</context><context>.htaccess</context>
+</contextlist>
+<compatibility>Available in version 2.3.7 and later</compatibility>
+<override>AuthConfig</override>
+<usage>
+ <p>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.</p>
+
+ <p> If the verbatim username can't directly bind, but needs some
+ cosmetic transformation, see <directive module="mod_authnz_ldap">
+ AuthLDAPInitialBindPattern</directive>.</p>
+
+ <note><title>Not available with authorization-only</title>
+ This directive can only be used if this module authenticates the user, and
+ has no effect when this module is used exclusively for authorization.
+ </note>
+</usage>
+<seealso><directive module="mod_authnnz_ldap">AuthLDAPInitialBindPattern</directive></seealso>
+<seealso><directive module="mod_authnnz_ldap">AuthLDAPBindDN</directive></seealso>
+</directivesynopsis>
+
+<directivesynopsis>
+<name>AuthLDAPInitialBindPattern</name>
+<description>Specifies the transformation of the basic authentication username to be used when binding to the LDAP server
+to perform a DN lookup</description>
+<syntax>AuthLDAPInitialBindPattern<em><var>regex</var> <var>substitution</var></em></syntax>
+<default>AuthLDAPInitialBindPattern (.*) $1 (remote username used verbatim)</default>
+<contextlist><context>directory</context><context>.htaccess</context>
+</contextlist>
+<compatibility>Available in version 2.3.7 and later</compatibility>
+<override>AuthConfig</override>
+<usage>
+ <p>If <directive module="mod_authnz_ldap">AuthLDAPInitialBindAsUser</directive> is set to
+ <em>ON</em>, the basic authentication username will be transformed according to the
+ regular expression and substituion arguments.</p>
+
+ <p> The regular expression argument is compared against the current basic authentication username.
+ The substitution argument may contain backreferences, but has no other variable interpolation.</p>
+
+ <example> AuthLDAPInitialBindPattern (.+) $1@example.com </example>
+ <example> AuthLDAPInitialBindPattern (.+) cn=$1,dc=example,dc=com</example>
+
+ <note><title>Not available with authorization-only</title>
+ This directive can only be used if this module authenticates the user, and
+ has no effect when this module is used exclusively for authorization.
+ </note>
+ <note><title>debugging</title>
+ The substituted DN is recorded in the environment variable
+ <em>LDAP_BINDASUSER</em>. If the regular expression does not match the input,
+ the verbatim username is used.
+ </note>
+</usage>
+<seealso><directive module="mod_authnnz_ldap">AuthLDAPInitialBindAsUser</directive></seealso>
+<seealso><directive module="mod_authnnz_ldap">AuthLDAPBindDN</directive></seealso>
+</directivesynopsis>
+
<directivesynopsis>
<name>AuthLDAPBindDN</name>
<description>Optional DN to use in binding to the LDAP server</description>
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 {
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
* --------------------
/* 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,
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,
(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}
};