summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Fritsch <sf@apache.org>2012-06-17 10:39:45 +0200
committerStefan Fritsch <sf@apache.org>2012-06-17 10:39:45 +0200
commitd49f5e293520f18d9716377fe3dcbd4a7d92154d (patch)
tree30bc7ed90569b644220320ff5b6ddb0e86eaac24
parentLog error if 'Require expr' fails (diff)
downloadapache2-d49f5e293520f18d9716377fe3dcbd4a7d92154d.tar.xz
apache2-d49f5e293520f18d9716377fe3dcbd4a7d92154d.zip
If an expression in "Require expr" returns denied and
references %{REMOTE_USER}, trigger authentication and retry PR: 52892 git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1351072 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--CHANGES4
-rw-r--r--docs/manual/mod/mod_authz_core.xml5
-rw-r--r--modules/aaa/mod_authz_core.c65
3 files changed, 56 insertions, 18 deletions
diff --git a/CHANGES b/CHANGES
index e43b479346..1dffc0fcd2 100644
--- a/CHANGES
+++ b/CHANGES
@@ -6,6 +6,10 @@ Changes with Apache 2.5.0
possible XSS for a site where untrusted users can upload files to
a location with MultiViews enabled. [Niels Heinen <heinenn google.com>]
+ *) mod_authz_core: If an expression in "Require expr" returns denied and
+ references %{REMOTE_USER}, trigger authentication and retry. PR 52892.
+ [Stefan Fritsch]
+
*) mod_lua: Add new directive LuaAuthzProvider to allow implementing an
authorization provider in lua. [Stefan Fritsch]
diff --git a/docs/manual/mod/mod_authz_core.xml b/docs/manual/mod/mod_authz_core.xml
index 07f6262d05..1f7a48d07e 100644
--- a/docs/manual/mod/mod_authz_core.xml
+++ b/docs/manual/mod/mod_authz_core.xml
@@ -224,6 +224,11 @@ SetEnvIf User-Agent ^KnockKnock/2\.0 let_me_in
<p>The syntax is described in the <a href="../expr.html">ap_expr</a>
documentation.</p>
+ <p>Normally, the expression is evaluated before authentication. However, if
+ the expression returns false and references the variable
+ <code>%{REMOTE_USER}</code>, authentication will be performed and
+ the expression will be re-evaluated.</p>
+
</section>
diff --git a/modules/aaa/mod_authz_core.c b/modules/aaa/mod_authz_core.c
index cf64265306..2aeda26681 100644
--- a/modules/aaa/mod_authz_core.c
+++ b/modules/aaa/mod_authz_core.c
@@ -1037,13 +1037,54 @@ static const authz_provider authz_method_provider =
&method_parse_config,
};
+/*
+ * expr authz provider
+ */
+
+#define REQUIRE_EXPR_NOTE "Require_expr_info"
+struct require_expr_info {
+ ap_expr_info_t *expr;
+ int want_user;
+};
+
+static int expr_lookup_fn(ap_expr_lookup_parms *parms)
+{
+ if (parms->type == AP_EXPR_FUNC_VAR
+ && strcasecmp(parms->name, "REMOTE_USER") == 0) {
+ struct require_expr_info *info;
+ apr_pool_userdata_get((void**)&info, REQUIRE_EXPR_NOTE, parms->ptemp);
+ AP_DEBUG_ASSERT(info != NULL);
+ info->want_user = 1;
+ }
+ return ap_expr_lookup_default(parms);
+}
+
+static const char *expr_parse_config(cmd_parms *cmd, const char *require_line,
+ const void **parsed_require_line)
+{
+ const char *expr_err = NULL;
+ struct require_expr_info *info = apr_pcalloc(cmd->pool, sizeof(*info));
+
+ apr_pool_userdata_setn(info, REQUIRE_EXPR_NOTE, apr_pool_cleanup_null,
+ cmd->temp_pool);
+ info->expr = ap_expr_parse_cmd(cmd, require_line, 0, &expr_err,
+ expr_lookup_fn);
+
+ if (expr_err)
+ return "Cannot parse expression in require line";
+
+ *parsed_require_line = info;
+
+ return NULL;
+}
+
static authz_status expr_check_authorization(request_rec *r,
const char *require_line,
const void *parsed_require_line)
{
const char *err = NULL;
- const ap_expr_info_t *expr = parsed_require_line;
- int rc = ap_expr_exec(r, expr, &err);
+ const struct require_expr_info *info = parsed_require_line;
+ int rc = ap_expr_exec(r, info->expr, &err);
if (rc < 0) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02320)
@@ -1052,28 +1093,16 @@ static authz_status expr_check_authorization(request_rec *r,
return AUTHZ_GENERAL_ERROR;
}
else if (rc == 0) {
- return AUTHZ_DENIED;
+ if (info->want_user)
+ return AUTHZ_DENIED_NO_USER;
+ else
+ return AUTHZ_DENIED;
}
else {
return AUTHZ_GRANTED;
}
}
-static const char *expr_parse_config(cmd_parms *cmd, const char *require_line,
- const void **parsed_require_line)
-{
- const char *expr_err = NULL;
- ap_expr_info_t *expr = ap_expr_parse_cmd(cmd, require_line, 0, &expr_err,
- NULL);
-
- if (expr_err)
- return "Cannot parse expression in require line";
-
- *parsed_require_line = expr;
-
- return NULL;
-}
-
static const authz_provider authz_expr_provider =
{
&expr_check_authorization,