This is just too easy to not do it: Add an 'expr' authz provider that allows
authorStefan Fritsch <sf@apache.org>
Tue, 28 Sep 2010 21:33:44 +0000 (21:33 +0000)
committerStefan Fritsch <sf@apache.org>
Tue, 28 Sep 2010 21:33:44 +0000 (21:33 +0000)
arbitrary expressions in Require lines.

The main issue I wanted to fix was that the env provider only allows to
check for the existance of an envvar but not the contents.

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1002363 13f79535-47bb-0310-9956-ffa450edef68

include/ap_expr.h
modules/aaa/mod_authz_core.c
server/util_expr.c

index 2f27f0fe458983ec990413fc897d9626d673cf4a..bc09f2da23be1d7e333f5196bccc9e7b2171f830 100644 (file)
@@ -99,7 +99,7 @@ AP_DECLARE(ap_parse_node_t*) ap_expr_parse(apr_pool_t *pool, const char *expr,
  * @param eval_func Option evaluation function (e.g. -A filename)
  * @return the value the expression parsed to
  */
-AP_DECLARE(int) ap_expr_eval(request_rec *r, ap_parse_node_t *root,
+AP_DECLARE(int) ap_expr_eval(request_rec *r, const ap_parse_node_t *root,
                              int *was_error, backref_t **reptr,
                              string_func_t string_func, opt_func_t eval_func);
 /**
index aec854be0dd470b855349459cc7d4762d08ba948..a2fd878855ab5a67b39b3ff8f1a899c2001caad5 100644 (file)
@@ -37,6 +37,7 @@
 #include "http_request.h"
 #include "http_protocol.h"
 #include "ap_provider.h"
+#include "ap_expr.h"
 
 #include "mod_auth.h"
 
@@ -983,6 +984,39 @@ 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)
+{
+    int err = 0;
+    const ap_parse_node_t *expr = parsed_require_line;
+
+    if (ap_expr_eval(r, expr, &err, NULL, ap_expr_string, NULL))
+        return AUTHZ_GRANTED;
+    else
+        return AUTHZ_DENIED;
+}
+
+static const char *expr_parse_config(cmd_parms *cmd, const char *require_line,
+                                     const void **parsed_require_line)
+{
+    int expr_err = 0;
+    ap_parse_node_t *expr = ap_expr_parse(cmd->pool, require_line, &expr_err);
+
+    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,
+    &expr_parse_config,
+};
+
 
 static void register_hooks(apr_pool_t *p)
 {
@@ -1004,6 +1038,9 @@ static void register_hooks(apr_pool_t *p)
     ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "method",
                               AUTHZ_PROVIDER_VERSION,
                               &authz_method_provider, AP_AUTH_INTERNAL_PER_CONF);
+    ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "expr",
+                              AUTHZ_PROVIDER_VERSION,
+                              &authz_expr_provider, AP_AUTH_INTERNAL_PER_CONF);
 }
 
 AP_DECLARE_MODULE(authz_core) =
index 921b90b867ff8467fa3091ed7c6da29777267da3..43e289f210f8f03e64a46d8a19749e35400d6cab 100644 (file)
@@ -674,7 +674,7 @@ AP_DECLARE(ap_parse_node_t*) ap_expr_parse(apr_pool_t* pool, const char *expr,
 }
 
 static ap_parse_node_t *ap_expr_clone_tree(apr_pool_t *pool,
-                                           ap_parse_node_t *pnode,
+                                           const ap_parse_node_t *pnode,
                                            ap_parse_node_t *parent)
 {
     ap_parse_node_t *ret;
@@ -871,7 +871,7 @@ static int expr_eval(request_rec *r, ap_parse_node_t *root,
 
     return (root ? root->value : 0);
 }
-AP_DECLARE(int) ap_expr_eval(request_rec *r, ap_parse_node_t *root,
+AP_DECLARE(int) ap_expr_eval(request_rec *r, const ap_parse_node_t *root,
                              int *was_error, backref_t **reptr,
                              string_func_t string_func, opt_func_t eval_func)
 {