From 89e17a3d24aeccf07e9991970bb9c87f376a9c7b Mon Sep 17 00:00:00 2001 From: Chris Darroch Date: Fri, 31 Oct 2008 20:10:07 +0000 Subject: [PATCH] Allow and directives to nest, and constrain their use to conform with that of other access control and authorization directives. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@709551 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES | 4 ++++ docs/manual/mod/core.xml | 49 ++++++++++++++++++++++++++++++++-------- server/core.c | 43 +++++++++++++++++++++++------------ 3 files changed, 71 insertions(+), 25 deletions(-) diff --git a/CHANGES b/CHANGES index 2635bc0c0d2..1d1746d225c 100644 --- a/CHANGES +++ b/CHANGES @@ -2,6 +2,10 @@ Changes with Apache 2.3.0 [ When backported to 2.2.x, remove entry from this file ] + *) core: Allow and directives to nest, and + constrain their use to conform with that of other access control + and authorization directives. [Chris Darroch] + *) unixd: turn existing code into a module, and turn the set user/group and chroot into a child_init function. [Nick Kew] diff --git a/docs/manual/mod/core.xml b/docs/manual/mod/core.xml index fa2975257cf..f7bf8d10099 100644 --- a/docs/manual/mod/core.xml +++ b/docs/manual/mod/core.xml @@ -1586,10 +1586,9 @@ requests on a persistent connection methods <Limit method [method] ... > ... </Limit> -server configvirtual host -directory.htaccess +directory.htaccess -All +AuthConfig, Limit

Access controls are normally effective for @@ -1623,17 +1622,48 @@ methods LOCK, and UNLOCK. The method name is case-sensitive. If GET is used it will also restrict HEAD requests. The TRACE method - cannot be limited (see TraceEnable).

A LimitExcept section should always be - used in preference to a Limit section when restricting access, - since a Limit + section when restricting access, since a LimitExcept section provides protection against arbitrary methods. +

The Limit and + LimitExcept + directives may be nested. In this case, each successive level of + Limit or LimitExcept directives must + further restrict the set of methods to which access controls apply.

+ + When using + Limit or + LimitExcept directives with + the Require directive, + note that the first Require + to succeed authorizes the request, regardless of the presence of other + Require directives. + +

For example, given the following configuration, all users will + be authorized for POST requests, and the + Require group editors directive will be ignored + in all cases:

+ + + <LimitExcept GET> + + Require valid-user + + </LimitExcept>
+ <Limit POST> + + Require group editors + + </Limit> +
@@ -1643,10 +1673,9 @@ methods except the named ones <LimitExcept method [method] ... > ... </LimitExcept> -server configvirtual host -directory.htaccess +directory.htaccess -All +AuthConfig, Limit

LimitExcept and diff --git a/server/core.c b/server/core.c index a1c7c6dd654..79067fedbd7 100644 --- a/server/core.c +++ b/server/core.c @@ -646,7 +646,7 @@ AP_DECLARE(int) ap_allow_overrides(request_rec *r) } /* - * Optional function coming from mod_authn_core, used for + * Optional function coming from mod_authn_core, used for * retrieving the type of autorization */ static APR_OPTIONAL_FN_TYPE(authn_ap_auth_type) *authn_ap_auth_type; @@ -660,7 +660,7 @@ AP_DECLARE(const char *) ap_auth_type(request_rec *r) } /* - * Optional function coming from mod_authn_core, used for + * Optional function coming from mod_authn_core, used for * retrieving the authorization realm */ static APR_OPTIONAL_FN_TYPE(authn_ap_auth_name) *authn_ap_auth_name; @@ -1042,9 +1042,11 @@ AP_DECLARE(const char *) ap_check_cmd_context(cmd_parms *cmd, " cannot occur within section", NULL); } - if ((forbidden & NOT_IN_LIMIT) && cmd->limited != -1) { + if ((forbidden & (NOT_IN_LIMIT | NOT_IN_DIR_LOC_FILE)) + && cmd->limited != -1) { return apr_pstrcat(cmd->pool, cmd->cmd->name, gt, - " cannot occur within section", NULL); + " cannot occur within or " + "section", NULL); } if ((forbidden & NOT_IN_DIR_LOC_FILE) == NOT_IN_DIR_LOC_FILE) { @@ -1656,13 +1658,9 @@ AP_CORE_DECLARE_NONSTD(const char *) ap_limit_section(cmd_parms *cmd, const char *limited_methods; void *tog = cmd->cmd->cmd_data; apr_int64_t limited = 0; + apr_int64_t old_limited = cmd->limited; const char *errmsg; - const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT); - if (err != NULL) { - return err; - } - if (endp == NULL) { return unclosed_directive(cmd); } @@ -1696,11 +1694,23 @@ AP_CORE_DECLARE_NONSTD(const char *) ap_limit_section(cmd_parms *cmd, /* Killing two features with one function, * if (tog == NULL) , else */ - cmd->limited = tog ? ~limited : limited; + limited = tog ? ~limited : limited; + + if (!(old_limited & limited)) { + return apr_pstrcat(cmd->pool, cmd->cmd->name, + "> directive excludes all methods", NULL); + } + else if ((old_limited & limited) == old_limited) { + return apr_pstrcat(cmd->pool, cmd->cmd->name, + "> directive specifies methods already excluded", + NULL); + } + + cmd->limited &= limited; errmsg = ap_walk_config(cmd->directive->first_child, cmd, cmd->context); - cmd->limited = -1; + cmd->limited = old_limited; return errmsg; } @@ -1899,7 +1909,8 @@ static const char *filesection(cmd_parms *cmd, void *mconfig, const char *arg) const command_rec *thiscmd = cmd->cmd; core_dir_config *c = mconfig; ap_conf_vector_t *new_file_conf = ap_create_per_dir_config(cmd->pool); - const char *err = ap_check_cmd_context(cmd, NOT_IN_LOCATION); + const char *err = ap_check_cmd_context(cmd, + NOT_IN_LOCATION | NOT_IN_LIMIT); if (err != NULL) { return err; @@ -1979,7 +1990,8 @@ static const char *ifsection(cmd_parms *cmd, void *mconfig, const char *arg) const command_rec *thiscmd = cmd->cmd; core_dir_config *c = mconfig; ap_conf_vector_t *new_file_conf = ap_create_per_dir_config(cmd->pool); - const char *err = ap_check_cmd_context(cmd, NOT_IN_LOCATION); + const char *err = ap_check_cmd_context(cmd, + NOT_IN_LOCATION | NOT_IN_LIMIT); const char *condition; int expr_err = 0; @@ -3174,10 +3186,11 @@ AP_INIT_RAW_ARGS("