]> granicus.if.org Git - apache/commitdiff
If an expression in "Require expr" returns denied and
authorRainer Jung <rjung@apache.org>
Sun, 22 Jul 2012 11:44:23 +0000 (11:44 +0000)
committerRainer Jung <rjung@apache.org>
Sun, 22 Jul 2012 11:44:23 +0000 (11:44 +0000)
references %{REMOTE_USER}, trigger authentication and retry.
Log error if 'Require expr' fails.

PR: 52892

Backport of r1351071, r1351072 and r1351074 from trunk.

Submitted by: sf
Reviewed by: rjung, trawick
Backported by: rjung

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1364266 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
STATUS
docs/manual/mod/mod_authz_core.xml
modules/aaa/mod_authz_core.c

diff --git a/CHANGES b/CHANGES
index 2b2872254e14f59c91a6ada7b9b892962dac0a1f..499917ae013b3f81c49a1e0db36a0297615d6b05 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -8,6 +8,10 @@ Changes with Apache 2.4.3
      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]
+
   *) core: Always log if LimitRequestFieldSize triggers.  [Stefan Fritsch]
 
   *) mod_deflate: Skip compression if compression is enabled at SSL level.
diff --git a/STATUS b/STATUS
index 52d1be6e0f666dc183c911d3a4f692755e0b0912..dae1aece64daa79d30cdd0afc77431609f94749f 100644 (file)
--- a/STATUS
+++ b/STATUS
@@ -88,15 +88,6 @@ RELEASE SHOWSTOPPERS:
 PATCHES ACCEPTED TO BACKPORT FROM TRUNK:
   [ start all new proposals below, under PATCHES PROPOSED. ]
 
-   * mod_authz_core: Allow to use %{REMOTE_USER} in Require expr. Improve
-     logging.
-     PR: 52892
-     trunk patch: http://svn.apache.org/viewvc?view=revision&revision=1351071
-                  http://svn.apache.org/viewvc?view=revision&revision=1351072
-                  http://svn.apache.org/viewvc?view=revision&revision=1351074
-     2.4.x patch: trunk patch works (ex. CHANGES)
-     +1: sf, rjung, trawick
-
    * mpm_event: Fix MaxConnectionsPerChild
      trunk patch: http://svn.apache.org/viewvc?view=revision&revision=1343085
                   http://svn.apache.org/viewvc?view=revision&revision=1343087
index 84700a1a543744740dccac47ba1619aba7ab3615..70c71a0ac5a9305f157d4da06946e50a66da79e3 100644 (file)
@@ -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>
 
 
index dc116696aeda9bad6ee4e32eab17207416ecbac7..fee4b3dba43303b3de43280953f0cfa011edf587 100644 (file)
@@ -1031,36 +1031,74 @@ static const authz_provider authz_method_provider =
     &method_parse_config,
 };
 
-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);
+/*
+ * expr authz provider
+ */
 
-    if (rc <= 0)
-        /* XXX: real error handling? */
-        return AUTHZ_DENIED;
-    else
-        return AUTHZ_GRANTED;
+#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;
-    ap_expr_info_t *expr = ap_expr_parse_cmd(cmd, require_line, 0, &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";
+        return apr_pstrcat(cmd->temp_pool,
+                           "Cannot parse expression in require line: ",
+                           expr_err, NULL);
 
-    *parsed_require_line = expr;
+    *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 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)
+                      "Error evaluating expression in 'Require expr': %s",
+                      err);
+        return AUTHZ_GENERAL_ERROR;
+    }
+    else if (rc == 0) {
+        if (info->want_user)
+            return AUTHZ_DENIED_NO_USER;
+        else
+            return AUTHZ_DENIED;
+    }
+    else {
+        return AUTHZ_GRANTED;
+    }
+}
+
 static const authz_provider authz_expr_provider =
 {
     &expr_check_authorization,