You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by ch...@apache.org on 2008/10/31 21:10:08 UTC

svn commit: r709551 - in /httpd/httpd/trunk: CHANGES docs/manual/mod/core.xml server/core.c

Author: chrisd
Date: Fri Oct 31 13:10:07 2008
New Revision: 709551

URL: http://svn.apache.org/viewvc?rev=709551&view=rev
Log:
Allow <Limit> and <LimitExcept> directives to nest, and
constrain their use to conform with that of other access control
and authorization directives.

Modified:
    httpd/httpd/trunk/CHANGES
    httpd/httpd/trunk/docs/manual/mod/core.xml
    httpd/httpd/trunk/server/core.c

Modified: httpd/httpd/trunk/CHANGES
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/CHANGES?rev=709551&r1=709550&r2=709551&view=diff
==============================================================================
--- httpd/httpd/trunk/CHANGES [utf-8] (original)
+++ httpd/httpd/trunk/CHANGES [utf-8] Fri Oct 31 13:10:07 2008
@@ -2,6 +2,10 @@
 Changes with Apache 2.3.0
 [ When backported to 2.2.x, remove entry from this file ]
 
+  *) core: Allow <Limit> and <LimitExcept> 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]
 

Modified: httpd/httpd/trunk/docs/manual/mod/core.xml
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/docs/manual/mod/core.xml?rev=709551&r1=709550&r2=709551&view=diff
==============================================================================
--- httpd/httpd/trunk/docs/manual/mod/core.xml (original)
+++ httpd/httpd/trunk/docs/manual/mod/core.xml Fri Oct 31 13:10:07 2008
@@ -1586,10 +1586,9 @@
 methods</description>
 <syntax>&lt;Limit <var>method</var> [<var>method</var>] ... &gt; ...
     &lt;/Limit&gt;</syntax>
-<contextlist><context>server config</context><context>virtual host</context>
-<context>directory</context><context>.htaccess</context>
+<contextlist><context>directory</context><context>.htaccess</context>
 </contextlist>
-<override>All</override>
+<override>AuthConfig, Limit</override>
 
 <usage>
     <p>Access controls are normally effective for
@@ -1623,17 +1622,48 @@
     <code>LOCK</code>, and <code>UNLOCK</code>. <strong>The method name is
     case-sensitive.</strong> If <code>GET</code> is used it will also
     restrict <code>HEAD</code> requests. The <code>TRACE</code> method
-    cannot be limited (see <directive type="section" module="core"
+    cannot be limited (see <directive module="core"
     >TraceEnable</directive>).</p>
 
     <note type="warning">A <directive type="section"
     module="core">LimitExcept</directive> section should always be
-    used in preference to a <directive type="section"
-    module="core">Limit</directive> section when restricting access,
-    since a <directive type="section"
+    used in preference to a <directive type="section">Limit</directive>
+    section when restricting access, since a <directive type="section"
     module="core">LimitExcept</directive> section provides protection
     against arbitrary methods.</note>
 
+    <p>The <directive type="section">Limit</directive> and
+    <directive type="section" module="core">LimitExcept</directive>
+    directives may be nested.  In this case, each successive level of
+    <directive type="section">Limit</directive> or <directive
+    type="section" module="core">LimitExcept</directive> directives must
+    further restrict the set of methods to which access controls apply.</p>
+
+    <note type="warning">When using
+    <directive type="section">Limit</directive> or
+    <directive type="section">LimitExcept</directive> directives with
+    the <directive module="mod_authz_core">Require</directive> directive,
+    note that the first <directive module="mod_authz_core">Require</directive>
+    to succeed authorizes the request, regardless of the presence of other
+    <directive module="mod_authz_core">Require</directive> directives.</note>
+
+    <p>For example, given the following configuration, all users will
+    be authorized for <code>POST</code> requests, and the
+    <code>Require group editors</code> directive will be ignored
+    in all cases:</p>
+
+    <example>
+      &lt;LimitExcept GET&gt;
+      <indent>
+        Require valid-user
+      </indent> 
+      &lt;/LimitExcept&gt;<br />
+      &lt;Limit POST&gt;
+      <indent>
+        Require group editors
+      </indent> 
+      &lt;/Limit&gt;
+    </example>
 </usage>
 </directivesynopsis>
 
@@ -1643,10 +1673,9 @@
 except the named ones</description>
 <syntax>&lt;LimitExcept <var>method</var> [<var>method</var>] ... &gt; ...
     &lt;/LimitExcept&gt;</syntax>
-<contextlist><context>server config</context><context>virtual host</context>
-<context>directory</context><context>.htaccess</context>
+<contextlist><context>directory</context><context>.htaccess</context>
 </contextlist>
-<override>All</override>
+<override>AuthConfig, Limit</override>
 
 <usage>
     <p><directive type="section">LimitExcept</directive> and

Modified: httpd/httpd/trunk/server/core.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/server/core.c?rev=709551&r1=709550&r2=709551&view=diff
==============================================================================
--- httpd/httpd/trunk/server/core.c (original)
+++ httpd/httpd/trunk/server/core.c Fri Oct 31 13:10:07 2008
@@ -646,7 +646,7 @@
 }
 
 /*
- * 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 @@
 }
 
 /*
- * 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 @@
                            " cannot occur within <VirtualHost> 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 <Limit> section", NULL);
+                           " cannot occur within <Limit> or <LimitExcept> "
+                           "section", NULL);
     }
 
     if ((forbidden & NOT_IN_DIR_LOC_FILE) == NOT_IN_DIR_LOC_FILE) {
@@ -1656,13 +1658,9 @@
     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 @@
     /* Killing two features with one function,
      * if (tog == NULL) <Limit>, else <LimitExcept>
      */
-    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 @@
     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 @@
     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 @@
   "more host addresses"),
 AP_INIT_RAW_ARGS("<Files", filesection, NULL, OR_ALL,
   "Container for directives affecting files matching specified patterns"),
-AP_INIT_RAW_ARGS("<Limit", ap_limit_section, NULL, OR_ALL,
+AP_INIT_RAW_ARGS("<Limit", ap_limit_section, NULL, OR_LIMIT | OR_AUTHCFG,
   "Container for authentication directives when accessed using specified HTTP "
   "methods"),
-AP_INIT_RAW_ARGS("<LimitExcept", ap_limit_section, (void*)1, OR_ALL,
+AP_INIT_RAW_ARGS("<LimitExcept", ap_limit_section, (void*)1,
+                 OR_LIMIT | OR_AUTHCFG,
   "Container for authentication directives to be applied when any HTTP "
   "method other than those specified is used to access the resource"),
 AP_INIT_TAKE1("<IfModule", start_ifmod, NULL, EXEC_ON_READ | OR_ALL,