From a10a4e4f2f41447ab4e92c806fe1408a617bd22c Mon Sep 17 00:00:00 2001 From: Stefan Fritsch Date: Tue, 28 Sep 2010 21:33:44 +0000 Subject: [PATCH] This is just too easy to not do it: Add an 'expr' authz provider that allows 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 | 2 +- modules/aaa/mod_authz_core.c | 37 ++++++++++++++++++++++++++++++++++++ server/util_expr.c | 4 ++-- 3 files changed, 40 insertions(+), 3 deletions(-) diff --git a/include/ap_expr.h b/include/ap_expr.h index 2f27f0fe45..bc09f2da23 100644 --- a/include/ap_expr.h +++ b/include/ap_expr.h @@ -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); /** diff --git a/modules/aaa/mod_authz_core.c b/modules/aaa/mod_authz_core.c index aec854be0d..a2fd878855 100644 --- a/modules/aaa/mod_authz_core.c +++ b/modules/aaa/mod_authz_core.c @@ -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) = diff --git a/server/util_expr.c b/server/util_expr.c index 921b90b867..43e289f210 100644 --- a/server/util_expr.c +++ b/server/util_expr.c @@ -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) { -- 2.40.0