You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by mi...@apache.org on 2014/04/25 13:14:36 UTC
svn commit: r1589993 - in /httpd/httpd/trunk: CHANGES docs/manual/expr.xml
docs/manual/mod/mod_authnz_ldap.xml modules/aaa/mod_authnz_ldap.c
Author: minfrin
Date: Fri Apr 25 11:14:36 2014
New Revision: 1589993
URL: http://svn.apache.org/r1589993
Log:
Add the ldap-search option to mod_authnz_ldap, allowing authorization
to be based on arbitrary expressions that do not include the username.
Modified:
httpd/httpd/trunk/CHANGES
httpd/httpd/trunk/docs/manual/expr.xml
httpd/httpd/trunk/docs/manual/mod/mod_authnz_ldap.xml
httpd/httpd/trunk/modules/aaa/mod_authnz_ldap.c
Modified: httpd/httpd/trunk/CHANGES
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/CHANGES?rev=1589993&r1=1589992&r2=1589993&view=diff
==============================================================================
--- httpd/httpd/trunk/CHANGES [utf-8] (original)
+++ httpd/httpd/trunk/CHANGES [utf-8] Fri Apr 25 11:14:36 2014
@@ -1,6 +1,10 @@
-*- coding: utf-8 -*-
Changes with Apache 2.5.0
+ *) Add the ldap-search option to mod_authnz_ldap, allowing authorization
+ to be based on arbitrary expressions that do not include the username.
+ [Graham Leggett]
+
*) Add the ldap function to the expression API, allowing LDAP filters and
distinguished names based on expressions to be escaped correctly to
guard against LDAP injection. [Graham Leggett]
Modified: httpd/httpd/trunk/docs/manual/expr.xml
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/docs/manual/expr.xml?rev=1589993&r1=1589992&r2=1589993&view=diff
==============================================================================
--- httpd/httpd/trunk/docs/manual/expr.xml (original)
+++ httpd/httpd/trunk/docs/manual/expr.xml Fri Apr 25 11:14:36 2014
@@ -55,6 +55,7 @@
<seealso><a href="mod/mod_authnz_ldap.html#reqdn">Require ldap-dn</a></seealso>
<seealso><a href="mod/mod_authnz_ldap.html#reqattribute">Require ldap-attribute</a></seealso>
<seealso><a href="mod/mod_authnz_ldap.html#reqfilter">Require ldap-filter</a></seealso>
+<seealso><a href="mod/mod_authnz_ldap.html#reqsearch">Require ldap-search</a></seealso>
<seealso><a href="mod/mod_authz_dbd.html#reqgroup">Require dbd-group</a></seealso>
<seealso><a href="mod/mod_authz_dbm.html#reqgroup">Require dbm-group</a></seealso>
<seealso><a href="mod/mod_authz_groupfile.html#reqgroup">Require group</a></seealso>
Modified: httpd/httpd/trunk/docs/manual/mod/mod_authnz_ldap.xml
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/docs/manual/mod/mod_authnz_ldap.xml?rev=1589993&r1=1589992&r2=1589993&view=diff
==============================================================================
--- httpd/httpd/trunk/docs/manual/mod/mod_authnz_ldap.xml (original)
+++ httpd/httpd/trunk/docs/manual/mod/mod_authnz_ldap.xml Fri Apr 25 11:14:36 2014
@@ -88,6 +88,7 @@ for HTTP Basic authentication.</descript
<li><a href="#reqdn">Require ldap-dn</a></li>
<li><a href="#reqattribute">Require ldap-attribute</a></li>
<li><a href="#reqfilter">Require ldap-filter</a></li>
+ <li><a href="#reqsearch">Require ldap-search</a></li>
</ul>
</li>
@@ -223,6 +224,11 @@ for HTTP Basic authentication.</descript
directive, and the search filter successfully finds a single user
object that matches the dn of the authenticated user.</li>
+ <li>Grant access if there is a <a href="#reqsearch">
+ <code>Require ldap-search</code></a>
+ directive, and the search filter successfully returns a single
+ matching object with any distinguished name.</li>
+
<li>otherwise, deny or decline access</li>
</ul>
@@ -508,6 +514,28 @@ AuthLDAPMaxSubGroupDepth 1
</section>
+<section id="reqsearch"><title>Require ldap-search</title>
+
+ <p>The <code>Require ldap-search</code> directive allows the
+ administrator to grant access based on a generic LDAP search filter using an
+ <a href="../expr.html">expression</a>. If there is exactly one match to the search filter,
+ regardless of the distinguished name, access is granted.</p>
+
+ <p>The following directive would grant access to URLs that match the given objects in the
+ LDAP server:</p>
+
+<highlight language="config">
+<LocationMatch ^/dav/(?<SITENAME>[^/]+)/>
+Require ldap-search (cn=%{ldap:%{unescape:%{env:MATCH_SITENAME}} Website)
+</LocationMatch>
+</highlight>
+
+ <p>Note: care must be taken to ensure that any expressions are properly escaped to guard
+ against LDAP injection. The <strong>ldap</strong> function can be used as per the example
+ above.</p>
+
+</section>
+
</section>
<section id="examples"><title>Examples</title>
Modified: httpd/httpd/trunk/modules/aaa/mod_authnz_ldap.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/aaa/mod_authnz_ldap.c?rev=1589993&r1=1589992&r2=1589993&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/aaa/mod_authnz_ldap.c (original)
+++ httpd/httpd/trunk/modules/aaa/mod_authnz_ldap.c Fri Apr 25 11:14:36 2014
@@ -367,15 +367,12 @@ static apr_status_t authnz_ldap_cleanup_
return APR_SUCCESS;
}
-static int set_request_vars(request_rec *r, enum auth_ldap_phase phase) {
+static int set_request_vars(request_rec *r, enum auth_ldap_phase phase, const char **vals) {
char *prefix = NULL;
int prefix_len;
int remote_user_attribute_set = 0;
- authn_ldap_request_t *req =
- (authn_ldap_request_t *)ap_get_module_config(r->request_config, &authnz_ldap_module);
authn_ldap_config_t *sec =
(authn_ldap_config_t *)ap_get_module_config(r->per_dir_config, &authnz_ldap_module);
- const char **vals = req->vals;
prefix = (phase == LDAP_AUTHN) ? AUTHN_PREFIX : sec->authz_prefix;
prefix_len = strlen(prefix);
@@ -599,7 +596,7 @@ static authn_status authn_ldap_check_pas
}
/* add environment variables */
- remote_user_attribute_set = set_request_vars(r, LDAP_AUTHN);
+ remote_user_attribute_set = set_request_vars(r, LDAP_AUTHN, req->vals);
/* sanity check */
if (sec->remote_user_attribute && !remote_user_attribute_set) {
@@ -725,7 +722,7 @@ static authz_status ldapuser_check_autho
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01703)
"auth_ldap authorize: require user: authorization "
"successful");
- set_request_vars(r, LDAP_AUTHZ);
+ set_request_vars(r, LDAP_AUTHZ, req->vals);
return AUTHZ_GRANTED;
}
default: {
@@ -747,7 +744,7 @@ static authz_status ldapuser_check_autho
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01705)
"auth_ldap authorize: "
"require user: authorization successful");
- set_request_vars(r, LDAP_AUTHZ);
+ set_request_vars(r, LDAP_AUTHZ, req->vals);
return AUTHZ_GRANTED;
}
default: {
@@ -934,7 +931,7 @@ static authz_status ldapgroup_check_auth
"[%s][%d - %s]",
ent[i].name, ldc->reason, result,
ldap_err2string(result));
- set_request_vars(r, LDAP_AUTHZ);
+ set_request_vars(r, LDAP_AUTHZ, req->vals);
return AUTHZ_GRANTED;
}
else {
@@ -973,7 +970,7 @@ static authz_status ldapgroup_check_auth
"(attribute %s) [%s][%d - %s]",
ent[i].name, ldc->reason, result,
ldap_err2string(result));
- set_request_vars(r, LDAP_AUTHZ);
+ set_request_vars(r, LDAP_AUTHZ, req->vals);
return AUTHZ_GRANTED;
}
else {
@@ -1095,7 +1092,7 @@ static authz_status ldapdn_check_authori
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01726)
"auth_ldap authorize: "
"require dn: authorization successful");
- set_request_vars(r, LDAP_AUTHZ);
+ set_request_vars(r, LDAP_AUTHZ, req->vals);
return AUTHZ_GRANTED;
}
default: {
@@ -1224,7 +1221,7 @@ static authz_status ldapattribute_check_
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01735)
"auth_ldap authorize: "
"require attribute: authorization successful");
- set_request_vars(r, LDAP_AUTHZ);
+ set_request_vars(r, LDAP_AUTHZ, req->vals);
return AUTHZ_GRANTED;
}
default: {
@@ -1369,7 +1366,7 @@ static authz_status ldapfilter_check_aut
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01745)
"auth_ldap authorize: require ldap-filter: "
"authorization successful");
- set_request_vars(r, LDAP_AUTHZ);
+ set_request_vars(r, LDAP_AUTHZ, req->vals);
return AUTHZ_GRANTED;
}
case LDAP_FILTER_ERROR: {
@@ -1396,6 +1393,80 @@ static authz_status ldapfilter_check_aut
return AUTHZ_DENIED;
}
+static authz_status ldapsearch_check_authorization(request_rec *r,
+ const char *require_args,
+ const void *parsed_require_args)
+{
+ int result = 0;
+ authn_ldap_config_t *sec =
+ (authn_ldap_config_t *)ap_get_module_config(r->per_dir_config, &authnz_ldap_module);
+
+ util_ldap_connection_t *ldc = NULL;
+
+ const char *err = NULL;
+ const ap_expr_info_t *expr = parsed_require_args;
+ const char *require;
+ const char *t;
+ const char *dn = NULL;
+
+ if (!sec->have_ldap_url) {
+ return AUTHZ_DENIED;
+ }
+
+ if (sec->host) {
+ ldc = get_connection_for_authz(r, LDAP_SEARCH);
+ apr_pool_cleanup_register(r->pool, ldc,
+ authnz_ldap_cleanup_connection_close,
+ apr_pool_cleanup_null);
+ }
+ else {
+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01738)
+ "auth_ldap authorize: no sec->host - weird...?");
+ return AUTHZ_DENIED;
+ }
+
+ require = ap_expr_str_exec(r, expr, &err);
+ if (err) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO()
+ "auth_ldap authorize: require ldap-search: Can't "
+ "evaluate require expression: %s", err);
+ return AUTHZ_DENIED;
+ }
+
+ t = require;
+
+ if (t[0]) {
+ const char **vals;
+
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO()
+ "auth_ldap authorize: checking filter %s", t);
+
+ /* Search for the user DN */
+ result = util_ldap_cache_getuserdn(r, ldc, sec->url, sec->basedn,
+ sec->scope, sec->attributes, t, &dn, &vals);
+
+ /* Make sure that the filtered search returned a single dn */
+ if (result == LDAP_SUCCESS && dn) {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO()
+ "auth_ldap authorize: require ldap-search: "
+ "authorization successful");
+ return AUTHZ_GRANTED;
+ }
+ else {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO()
+ "auth_ldap authorize: require ldap-search: "
+ "%s authorization failed [%s][%s]",
+ t, ldc->reason, ldap_err2string(result));
+ }
+ }
+
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO()
+ "auth_ldap authorize filter: authorization denied for "
+ "to %s", r->uri);
+
+ return AUTHZ_DENIED;
+}
+
static const char *ldap_parse_config(cmd_parms *cmd, const char *require_line,
const void **parsed_require_line)
{
@@ -1899,6 +1970,12 @@ static const authz_provider authz_ldapfi
&ldap_parse_config,
};
+static const authz_provider authz_ldapsearch_provider =
+{
+ &ldapsearch_check_authorization,
+ &ldap_parse_config,
+};
+
static void ImportULDAPOptFn(void)
{
util_ldap_connection_close = APR_RETRIEVE_OPTIONAL_FN(uldap_connection_close);
@@ -1939,6 +2016,10 @@ static void register_hooks(apr_pool_t *p
AUTHZ_PROVIDER_VERSION,
&authz_ldapfilter_provider,
AP_AUTH_INTERNAL_PER_CONF);
+ ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "ldap-search",
+ AUTHZ_PROVIDER_VERSION,
+ &authz_ldapsearch_provider,
+ AP_AUTH_INTERNAL_PER_CONF);
ap_hook_post_config(authnz_ldap_post_config,NULL,NULL,APR_HOOK_MIDDLE);
Re: svn commit: r1589993 - in /httpd/httpd/trunk: CHANGES docs/manual/expr.xml docs/manual/mod/mod_authnz_ldap.xml modules/aaa/mod_authnz_ldap.c
Posted by Yann Ylavic <yl...@gmail.com>.
On Fri, Apr 25, 2014 at 1:15 PM <mi...@apache.org> wrote:
>
> Author: minfrin
> Date: Fri Apr 25 11:14:36 2014
> New Revision: 1589993
>
> URL: http://svn.apache.org/r1589993
> Log:
> Add the ldap-search option to mod_authnz_ldap, allowing authorization
> to be based on arbitrary expressions that do not include the username.
[]
>
> --- httpd/httpd/trunk/docs/manual/mod/mod_authnz_ldap.xml (original)
> +++ httpd/httpd/trunk/docs/manual/mod/mod_authnz_ldap.xml Fri Apr 25 11:14:36 2014
[]
> @@ -508,6 +514,28 @@ AuthLDAPMaxSubGroupDepth 1
>
> </section>
>
> +<section id="reqsearch"><title>Require ldap-search</title>
> +
> + <p>The <code>Require ldap-search</code> directive allows the
> + administrator to grant access based on a generic LDAP search filter using an
> + <a href="../expr.html">expression</a>. If there is exactly one match to the search filter,
> + regardless of the distinguished name, access is granted.</p>
I get from this that there should be one match..
>
> --- httpd/httpd/trunk/modules/aaa/mod_authnz_ldap.c (original)
> +++ httpd/httpd/trunk/modules/aaa/mod_authnz_ldap.c Fri Apr 25 11:14:36 2014
[]
>
> +static authz_status ldapsearch_check_authorization(request_rec *r,
> + const char *require_args,
> + const void *parsed_require_args)
> +{
> + int result = 0;
> + authn_ldap_config_t *sec =
> + (authn_ldap_config_t *)ap_get_module_config(r->per_dir_config, &authnz_ldap_module);
> +
> + util_ldap_connection_t *ldc = NULL;
> +
> + const char *err = NULL;
> + const ap_expr_info_t *expr = parsed_require_args;
> + const char *require;
> + const char *t;
> + const char *dn = NULL;
> +
> + if (!sec->have_ldap_url) {
> + return AUTHZ_DENIED;
> + }
> +
> + if (sec->host) {
> + ldc = get_connection_for_authz(r, LDAP_SEARCH);
> + apr_pool_cleanup_register(r->pool, ldc,
> + authnz_ldap_cleanup_connection_close,
> + apr_pool_cleanup_null);
> + }
> + else {
> + ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01738)
> + "auth_ldap authorize: no sec->host - weird...?");
> + return AUTHZ_DENIED;
> + }
> +
> + require = ap_expr_str_exec(r, expr, &err);
> + if (err) {
> + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO()
> + "auth_ldap authorize: require ldap-search: Can't "
> + "evaluate require expression: %s", err);
> + return AUTHZ_DENIED;
> + }
> +
> + t = require;
> +
> + if (t[0]) {
> + const char **vals;
> +
> + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO()
> + "auth_ldap authorize: checking filter %s", t);
> +
> + /* Search for the user DN */
> + result = util_ldap_cache_getuserdn(r, ldc, sec->url, sec->basedn,
> + sec->scope, sec->attributes, t, &dn, &vals);
> +
> + /* Make sure that the filtered search returned a single dn */
And it's restated here..
> + if (result == LDAP_SUCCESS && dn) {
> + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO()
> + "auth_ldap authorize: require ldap-search: "
> + "authorization successful");
> + return AUTHZ_GRANTED;
I get that for "ldap-filter" (unlike for "ldap-search here) we'll do a
util_ldap_cache_comparedn() to (double) check the returned DN somehow
(sorry I don't really know how LDAP works), not here though because we
don't require a particular DN but just a single one.
But what makes sure that it's the case here?
> + }
> + else {
> + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO()
> + "auth_ldap authorize: require ldap-search: "
> + "%s authorization failed [%s][%s]",
> + t, ldc->reason, ldap_err2string(result));
> + }
> + }
> +
> + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO()
> + "auth_ldap authorize filter: authorization denied for "
> + "to %s", r->uri);
> +
> + return AUTHZ_DENIED;
> +}
Regards;
Yann.
Re: svn commit: r1589993 - in /httpd/httpd/trunk: CHANGES docs/manual/expr.xml docs/manual/mod/mod_authnz_ldap.xml modules/aaa/mod_authnz_ldap.c
Posted by Christophe JAILLET <ch...@wanadoo.fr>.
Le 18/11/2023 à 20:52, Yann Ylavic a écrit :
> On Wed, Apr 30, 2014 at 1:02 AM Yann Ylavic <yl...@gmail.com> wrote:
>>
>> On Tue, Apr 29, 2014 at 10:54 PM, Christophe JAILLET
>> <ch...@wanadoo.fr> wrote:
>>> Hi,
>>>
>>> doc does not build because of <SITENAME> below:
>>>
>>> CJ
>>>
>>> Le 25/04/2014 13:14, minfrin@apache.org a écrit :
>>>> +<highlight language="config">
>>>> +<LocationMatch ^/dav/(?<SITENAME>[^/]+)/>
>>>
>>> ^ There
>>>
>>
>> Hmm, won't LocationMatch itself be broken by the inner <>s ?
>
> Wow, fortunately I didn't hold my breath on this one :)
> Someone needs to answer to this former/younger/naive me though and
> since I'm on this commit again: look Yann, this match is double-quoted
> now so we should be fine!
>
In fact, at that time, another solution was provided in r1591113.
But what you propose above, should have worked as well, I guess. :).
CJ
Re: svn commit: r1589993 - in /httpd/httpd/trunk: CHANGES docs/manual/expr.xml docs/manual/mod/mod_authnz_ldap.xml modules/aaa/mod_authnz_ldap.c
Posted by Yann Ylavic <yl...@gmail.com>.
On Wed, Apr 30, 2014 at 1:02 AM Yann Ylavic <yl...@gmail.com> wrote:
>
> On Tue, Apr 29, 2014 at 10:54 PM, Christophe JAILLET
> <ch...@wanadoo.fr> wrote:
> > Hi,
> >
> > doc does not build because of <SITENAME> below:
> >
> > CJ
> >
> > Le 25/04/2014 13:14, minfrin@apache.org a écrit :
> >> +<highlight language="config">
> >> +<LocationMatch ^/dav/(?<SITENAME>[^/]+)/>
> >
> > ^ There
> >
>
> Hmm, won't LocationMatch itself be broken by the inner <>s ?
Wow, fortunately I didn't hold my breath on this one :)
Someone needs to answer to this former/younger/naive me though and
since I'm on this commit again: look Yann, this match is double-quoted
now so we should be fine!
Re: svn commit: r1589993 - in /httpd/httpd/trunk: CHANGES
docs/manual/expr.xml docs/manual/mod/mod_authnz_ldap.xml modules/aaa/mod_authnz_ldap.c
Posted by Yann Ylavic <yl...@gmail.com>.
On Tue, Apr 29, 2014 at 10:54 PM, Christophe JAILLET
<ch...@wanadoo.fr> wrote:
> Hi,
>
> doc does not build because of <SITENAME> below:
>
> CJ
>
> Le 25/04/2014 13:14, minfrin@apache.org a écrit :
>> +<highlight language="config">
>> +<LocationMatch ^/dav/(?<SITENAME>[^/]+)/>
>
> ^ There
>
Hmm, won't LocationMatch itself be broken by the inner <>s ?
Re: svn commit: r1589993 - in /httpd/httpd/trunk: CHANGES docs/manual/expr.xml
docs/manual/mod/mod_authnz_ldap.xml modules/aaa/mod_authnz_ldap.c
Posted by Christophe JAILLET <ch...@wanadoo.fr>.
Hi,
doc does not build because of <SITENAME> below:
CJ
Le 25/04/2014 13:14, minfrin@apache.org a écrit :
> Author: minfrin
> Date: Fri Apr 25 11:14:36 2014
> New Revision: 1589993
>
> URL: http://svn.apache.org/r1589993
> Log:
> Add the ldap-search option to mod_authnz_ldap, allowing authorization
> to be based on arbitrary expressions that do not include the username.
>
> Modified:
> httpd/httpd/trunk/CHANGES
> httpd/httpd/trunk/docs/manual/expr.xml
> httpd/httpd/trunk/docs/manual/mod/mod_authnz_ldap.xml
> httpd/httpd/trunk/modules/aaa/mod_authnz_ldap.c
>
> Modified: httpd/httpd/trunk/docs/manual/mod/mod_authnz_ldap.xml
> URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/docs/manual/mod/mod_authnz_ldap.xml?rev=1589993&r1=1589992&r2=1589993&view=diff
> ==============================================================================
> --- httpd/httpd/trunk/docs/manual/mod/mod_authnz_ldap.xml (original)
> +++ httpd/httpd/trunk/docs/manual/mod/mod_authnz_ldap.xml Fri Apr 25 11:14:36 2014
> @@ -508,6 +514,28 @@ AuthLDAPMaxSubGroupDepth 1
>
> </section>
>
> +<section id="reqsearch"><title>Require ldap-search</title>
> +
> + <p>The <code>Require ldap-search</code> directive allows the
> + administrator to grant access based on a generic LDAP search filter using an
> + <a href="../expr.html">expression</a>. If there is exactly one match to the search filter,
> + regardless of the distinguished name, access is granted.</p>
> +
> + <p>The following directive would grant access to URLs that match the given objects in the
> + LDAP server:</p>
> +
> +<highlight language="config">
> +<LocationMatch ^/dav/(?<SITENAME>[^/]+)/>
^ There
> +Require ldap-search (cn=%{ldap:%{unescape:%{env:MATCH_SITENAME}} Website)
> +</LocationMatch>
> +</highlight>
> +
> + <p>Note: care must be taken to ensure that any expressions are properly escaped to guard
> + against LDAP injection. The <strong>ldap</strong> function can be used as per the example
> + above.</p>
> +
> +</section>
> +
> </section>
>
> <section id="examples"><title>Examples</title>