Commit 662f6d4d authored by Chris Darroch's avatar Chris Darroch
Browse files

Allow <Limit> and <LimitExcept> 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
parent fc14c453
Loading
Loading
Loading
Loading
+4 −0
Changes for CHANGES: 4 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -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]

+39 −10
Changes for docs/manual/mod/core.xml: 39 added lines, 10 removed lines.
Original line number Diff line number Diff line
@@ -1586,10 +1586,9 @@ requests on a persistent connection</description>
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 @@ methods</description>
    <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 @@ methods</description>
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
+26 −13
Changes for server/core.c: 26 added lines, 13 removed lines.
Original line number Diff line number Diff line
@@ -1042,9 +1042,11 @@ AP_DECLARE(const char *) ap_check_cmd_context(cmd_parms *cmd,
                           " 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 @@ 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) <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 @@ 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("<VirtualHost", virtualhost_section, NULL, RSRC_CONF,
  "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,