]> granicus.if.org Git - apache/commitdiff
Added 'AllowOverride Options=Indexes,MultiViews' to give an admin better
authorPaul Querna <pquerna@apache.org>
Wed, 14 Jul 2004 06:36:42 +0000 (06:36 +0000)
committerPaul Querna <pquerna@apache.org>
Wed, 14 Jul 2004 06:36:42 +0000 (06:36 +0000)
control over what options can be used in .htaccess files.

PR: 29310
Submitted by: Tom Alsberg <alsbergt-apache cs.huji.ac.il>

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

CHANGES
docs/manual/mod/core.xml
include/http_config.h
include/http_core.h
include/httpd.h
server/config.c
server/core.c
server/request.c

diff --git a/CHANGES b/CHANGES
index 6465d7a58191bff03e42b62a982af08ec4bda178..0d8da0ef2eb44949e5b0c8d252f63cbe9a2c5f2e 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -2,6 +2,10 @@ Changes with Apache 2.1.0-dev
 
   [Remove entries to the current 2.0 section below, when backported]
 
+  *) core: Add Options= syntax to AllowOverride to specify which options
+     may be overridden in .htaccess files. PR 29310.
+     [Tom Alsberg <alsbergt cs.huji.ac.il>, Paul Querna]
+
   *) ab: Handle long URLs with an error instead of an buffer overflow.
      PR 28204. [Erik Weide <erik.weidel mplus-technologies.de>, Paul Querna]
 
index b7a6173fafeb3d74c37292ff16063cf265493331..9f7731ed7b21e4ce9eea09171768b603a6c7a4ec 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0"?>
 <!DOCTYPE modulesynopsis SYSTEM "../style/modulesynopsis.dtd">
 <?xml-stylesheet type="text/xsl" href="../style/manual.en.xsl"?>
-<!-- $Revision: 1.88 $ -->
+<!-- $Revision: 1.89 $ -->
 
 <!--
  Copyright 2002-2004 The Apache Software Foundation
@@ -355,12 +355,15 @@ be passed through</description>
       module="mod_authz_host">Deny</directive> and <directive
       module="mod_authz_host">Order</directive>).</dd>
 
-      <dt>Options</dt>
+      <dt>Options[=<var>Option</var>,...]</dt>
 
       <dd>
       Allow use of the directives controlling specific directory
       features (<directive module="core">Options</directive> and
-      <directive module="mod_include">XBitHack</directive>).</dd>
+      <directive module="mod_include">XBitHack</directive>).
+      An equal sign may be given followed by a comma (but no spaces)
+      separated lists of options that may be set using the Options
+      command.</dd>
     </dl>
 
     <p>Example:</p>
index 31b6dd6502878522e458b396ec4d66761f71e2a2..41287de99ab80e5432cc01a121c5d693f1e86470 100644 (file)
@@ -291,6 +291,9 @@ struct cmd_parms_struct {
     struct ap_conf_vector_t *context;
     /** directive with syntax error */
     const ap_directive_t *err_directive;
+
+    /** Which allow-override-opts bits are set */
+    int override_opts;
 };
 
 /**
@@ -854,6 +857,7 @@ AP_CORE_DECLARE(ap_conf_vector_t*) ap_create_conn_config(apr_pool_t *p);
  */
 AP_CORE_DECLARE(int) ap_parse_htaccess(ap_conf_vector_t **result, 
                                        request_rec *r, int override,
+                                       int override_opts,
                                        const char *path, 
                                        const char *access_name);
 
index de82ac5adfe70bc5089ae0e1e3cb5aa19fa7d14e..d74a4cf5dda1b860492d014fe77a5b55f86f51fd 100644 (file)
@@ -412,6 +412,7 @@ typedef struct {
     allow_options_t opts_add;
     allow_options_t opts_remove;
     overrides_t override;
+    allow_options_t override_opts;
     
     /* MIME typing --- the core doesn't do anything at all with this,
      * but it does know what to slap on a request for a document which
index a9f03751ff8de148f924cf54d70365d493171ac5..b39208b76abaa14e9970c7a83d57ffd89395b674 100644 (file)
@@ -651,6 +651,8 @@ struct htaccess_result {
     const char *dir;
     /** the overrides allowed for the .htaccess file */
     int override;
+    /** the override options allowed for the .htaccess file */
+    int override_opts;
     /** the configuration directives */
     struct ap_conf_vector_t *htaccess;
     /** the next one, or NULL if no more; N.B. never change this */
index 79e5f7205da93d7b1eb7245398e5097ca47e6cfd..be64dea05e5334d81e416196e4b12cdd279ef1db 100644 (file)
@@ -1384,6 +1384,7 @@ static const char *process_command_config(server_rec *s,
     parms.temp_pool = ptemp;
     parms.server = s;
     parms.override = (RSRC_CONF | OR_ALL) & ~(OR_AUTHCFG | OR_LIMIT);
+    parms.override_opts = OPT_ALL | OPT_INCNOEXEC | OPT_SYM_OWNER | OPT_MULTI;
 
     parms.config_file = ap_pcfg_open_custom(p, "-c/-C directives",
                                             &arr_parms, NULL,
@@ -1490,6 +1491,7 @@ static const char *process_resource_config_nofnmatch(server_rec *s,
     parms.temp_pool = ptemp;
     parms.server = s;
     parms.override = (RSRC_CONF | OR_ALL) & ~(OR_AUTHCFG | OR_LIMIT);
+    parms.override_opts = OPT_ALL | OPT_INCNOEXEC | OPT_SYM_OWNER | OPT_MULTI;
 
     if (ap_pcfg_openfile(&cfp, p, fname) != APR_SUCCESS) {
         return apr_pstrcat(p, "Could not open document config file ",
@@ -1625,6 +1627,7 @@ AP_DECLARE(int) ap_process_config_tree(server_rec *s,
     parms.temp_pool = ptemp;
     parms.server = s;
     parms.override = (RSRC_CONF | OR_ALL) & ~(OR_AUTHCFG | OR_LIMIT);
+    parms.override_opts = OPT_ALL | OPT_INCNOEXEC | OPT_SYM_OWNER | OPT_MULTI;
     parms.limited = -1;
 
     errmsg = ap_walk_config(conftree, &parms, s->lookup_defaults);
@@ -1643,6 +1646,7 @@ AP_DECLARE(int) ap_process_config_tree(server_rec *s,
 
 AP_CORE_DECLARE(int) ap_parse_htaccess(ap_conf_vector_t **result,
                                        request_rec *r, int override,
+                                      int override_opts,
                                        const char *d, const char *access_name)
 {
     ap_configfile_t *f = NULL;
@@ -1663,6 +1667,7 @@ AP_CORE_DECLARE(int) ap_parse_htaccess(ap_conf_vector_t **result,
 
     parms = default_parms;
     parms.override = override;
+    parms.override_opts = override_opts;
     parms.pool = r->pool;
     parms.temp_pool = r->pool;
     parms.server = r->server;
@@ -1719,6 +1724,7 @@ AP_CORE_DECLARE(int) ap_parse_htaccess(ap_conf_vector_t **result,
     new = apr_palloc(r->pool, sizeof(struct htaccess_result));
     new->dir = parms.path;
     new->override = override;
+    new->override_opts = override_opts;
     new->htaccess = dc;
 
     /* add to head of list */
index 35eb37efb57eac3675eea31dc945453564c4eeea..074e3e5bcfb503f156ed51058304f1ad492d8ded 100644 (file)
@@ -108,6 +108,8 @@ static void *create_core_dir_config(apr_pool_t *a, char *dir)
     conf->opts = dir ? OPT_UNSET : OPT_UNSET|OPT_ALL;
     conf->opts_add = conf->opts_remove = OPT_NONE;
     conf->override = dir ? OR_UNSET : OR_UNSET|OR_ALL;
+    conf->override_opts = OPT_UNSET | OPT_ALL | OPT_INCNOEXEC | OPT_SYM_OWNER
+                        | OPT_MULTI;
 
     conf->content_md5 = 2;
     conf->accept_path_info = 3;
@@ -257,6 +259,10 @@ static void *merge_core_dir_configs(apr_pool_t *a, void *basev, void *newv)
         conf->override = new->override;
     }
 
+    if (!(new->override_opts & OPT_UNSET)) {
+       conf->override_opts = new->override_opts;
+    }
+
     if (new->ap_default_type) {
         conf->ap_default_type = new->ap_default_type;
     }
@@ -1220,10 +1226,72 @@ static const char *set_error_document(cmd_parms *cmd, void *conf_,
     return NULL;
 }
 
+static const char *set_allow_opts(cmd_parms *cmd, allow_options_t *opts,
+                                  const char *l)
+{
+    allow_options_t opt;
+    int first = 1;
+
+    char *p = (char *) l;
+
+    while (p && *p) {
+        char *w = strsep(&p, ",");
+
+        if (first) {
+            *opts = OPT_NONE;
+            first = 0;
+        }
+
+       if (!w)
+           continue;
+
+        if (!strcasecmp(w, "Indexes")) {
+            opt = OPT_INDEXES;
+        }
+        else if (!strcasecmp(w, "Includes")) {
+            opt = OPT_INCLUDES;
+        }
+        else if (!strcasecmp(w, "IncludesNOEXEC")) {
+            opt = (OPT_INCLUDES | OPT_INCNOEXEC);
+        }
+        else if (!strcasecmp(w, "FollowSymLinks")) {
+            opt = OPT_SYM_LINKS;
+        }
+        else if (!strcasecmp(w, "SymLinksIfOwnerMatch")) {
+            opt = OPT_SYM_OWNER;
+        }
+        else if (!strcasecmp(w, "ExecCGI")) {
+            opt = OPT_EXECCGI;
+        }
+        else if (!strcasecmp(w, "MultiViews")) {
+            opt = OPT_MULTI;
+        }
+        else if (!strcasecmp(w, "RunScripts")) { /* AI backcompat. Yuck */
+            opt = OPT_MULTI|OPT_EXECCGI;
+        }
+        else if (!strcasecmp(w, "None")) {
+            opt = OPT_NONE;
+        }
+        else if (!strcasecmp(w, "All")) {
+            opt = OPT_ALL;
+        }
+        else {
+            return apr_pstrcat(cmd->pool, "Illegal option ", w, NULL);
+        }
+
+        *opts |= opt;
+    }
+
+    (*opts) &= (~OPT_UNSET);
+
+    return NULL;
+}
+
 static const char *set_override(cmd_parms *cmd, void *d_, const char *l)
 {
     core_dir_config *d = d_;
     char *w;
+    char *k, *v;
 
     const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT);
     if (err != NULL) {
@@ -1240,11 +1308,22 @@ static const char *set_override(cmd_parms *cmd, void *d_, const char *l)
     d->override = OR_NONE;
     while (l[0]) {
         w = ap_getword_conf(cmd->pool, &l);
+
+       k = w;
+       v = strchr(k, '=');
+       if (v) {
+               *v++ = '\0';
+       }
+
         if (!strcasecmp(w, "Limit")) {
             d->override |= OR_LIMIT;
         }
-        else if (!strcasecmp(w, "Options")) {
+        else if (!strcasecmp(k, "Options")) {
             d->override |= OR_OPTIONS;
+           if (v) 
+                set_allow_opts(cmd, &(d->override_opts), v);
+           else
+               d->override_opts = OPT_ALL;
         }
         else if (!strcasecmp(w, "FileInfo")) {
             d->override |= OR_FILEINFO;
@@ -1305,7 +1384,7 @@ static const char *set_options(cmd_parms *cmd, void *d_, const char *l)
         else if (!strcasecmp(w, "SymLinksIfOwnerMatch")) {
             opt = OPT_SYM_OWNER;
         }
-        else if (!strcasecmp(w, "execCGI")) {
+        else if (!strcasecmp(w, "ExecCGI")) {
             opt = OPT_EXECCGI;
         }
         else if (!strcasecmp(w, "MultiViews")) {
@@ -1324,8 +1403,11 @@ static const char *set_options(cmd_parms *cmd, void *d_, const char *l)
             return apr_pstrcat(cmd->pool, "Illegal option ", w, NULL);
         }
 
-        /* we ensure the invariant (d->opts_add & d->opts_remove) == 0 */
-        if (action == '-') {
+       if (!(cmd->override_opts & opt) && opt != OPT_NONE) {
+           return apr_pstrcat(cmd->pool, "Option ", w, " not allowed here", NULL);
+        }
+        else if (action == '-') {
+            /* we ensure the invariant (d->opts_add & d->opts_remove) == 0 */
             d->opts_remove |= opt;
             d->opts_add &= ~opt;
             d->opts &= ~opt;
index c158dcbfa5d50a904c0626da38649cb1404b4a75..9d5ca67f9ecafab61f5a62c69fb81b554899d808 100644 (file)
@@ -418,6 +418,7 @@ typedef struct core_opts_t {
         allow_options_t add;
         allow_options_t remove;
         overrides_t override;
+        overrides_t override_opts;
 } core_opts_t;
 
 static void core_opts_merge(const ap_conf_vector_t *sec, core_opts_t *opts)
@@ -444,6 +445,9 @@ static void core_opts_merge(const ap_conf_vector_t *sec, core_opts_t *opts)
     if (!(this_dir->override & OR_UNSET)) {
         opts->override = this_dir->override;
     }
+    if (!(this_dir->override_opts & OR_UNSET)) {
+        opts->override_opts = this_dir->override_opts;
+    }
 }
 
 
@@ -821,6 +825,7 @@ AP_DECLARE(int) ap_directory_walk(request_rec *r)
                 }
 
                 res = ap_parse_htaccess(&htaccess_conf, r, opts.override,
+                                       opts.override_opts,
                                         apr_pstrdup(r->pool, r->filename),
                                         sconf->access_name);
                 if (res) {