see https://issues.apache.org/bugzilla/show_bug.cgi?id=44262

The docs for 2.0 say about AllowOverride Options:
(http://httpd.apache.org/docs/2.0/mod/core.html#allowoverride)
"
Options Allow use of the directives controlling specific directory
features (Options and XBitHack).
"

and for 2.2 (http://httpd.apache.org/docs/2.2/mod/core.html#allowoverride)
"
Options[=Option,...]Allow use of the directives controlling specific
directory features (Options and XBitHack). 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.
"

In 2.0 they don't specify which Options can be overwritten and in 2.2
=Option,.. is optional so I expect Options without =Option,... be
compatible with old AllowOverride Options.

The catch is that Option All isn't really all the options.
from includes/http_core.h
"
/** No directives */
#define OPT_NONE 0
/** Indexes directive */
#define OPT_INDEXES 1
/**  Includes directive */
#define OPT_INCLUDES 2
/**  FollowSymLinks directive */
#define OPT_SYM_LINKS 4
/**  ExecCGI directive */
#define OPT_EXECCGI 8
/**  directive unset */
#define OPT_UNSET 16
/**  IncludesNOEXEC directive */
#define OPT_INCNOEXEC 32
/** SymLinksIfOwnerMatch directive */
#define OPT_SYM_OWNER 64
/** MultiViews directive */
#define OPT_MULTI 128
/**  All directives */
#define OPT_ALL (OPT_INDEXES | OPT_INCLUDES | OPT_SYM_LINKS | OPT_EXECCGI)
"
so OPT_INCNOEXEC  OPT_SYM_OWNER OPT_MULTI are omitted from All.


in 2.2.x
AllowOverride Options=
allows everything including Multiviews and others

AllowOverride Options
allows only All and this is only OPT_INDEXES | OPT_INCLUDES |
OPT_SYM_LINKS | OPT_EXECCGI

The bug is in server/core.c:1286
l is the string after "Options=", in this case its just an empty string.

static const char *set_allow_opts(cmd_parms *cmd, allow_options_t *opts,
                                 const char *l)
{
   allow_options_t opt;
   int first = 1;

   char *w, *p = (char *) l;
   char *tok_state;

   while ((w = apr_strtok(p, ",", &tok_state)) != NULL) {

       if (first) {
           p = NULL;
           *opts = OPT_NONE;
           first = 0;
       }

       if (!strcasecmp(w, "Indexes")) {
           opt = OPT_INDEXES;
       }
       else if (!strcasecmp(w, "Includes")) {
           opt = OPT_INCLUDES;
       }
...
       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;
}

In case of Options= the while loop isn't executed and options are set to
   (*opts) &= (~OPT_UNSET);
which is previous options & 0xffffffff . Probably in case if OPT_UNSET is not 0.


opts by default are

server/core.c:99 static void *create_core_dir_config(apr_pool_t *a, char *dir)
...
conf->override_opts = OPT_UNSET | OPT_ALL | OPT_INCNOEXEC | OPT_SYM_OWNER
                         | OPT_MULTI;

and in server/core.c set_override()
..    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(k, "Options")) {
            // in case of Options=   v=""
           d->override |= OR_OPTIONS;
           if (v)
                //in case of "AllowOverride Options=" set_allow_opts() leavs
d->override_opts unchanged
               set_allow_opts(cmd, &(d->override_opts), v);
           else
                // in case of "AllowOverride Options" sets ONLY!!! OPT_ALL 
ommiting
OPT_MULTIVIEWS and others
               d->override_opts = OPT_ALL;

This is at least inconsistent, Options= should be a syntax error, or
OPT_NONE + warning.

In pre Options= releases (it bit me hard when I upgraded to 2.2.8 from
2.0.61) AllovOverride Options
allowed overriding any options not only those in OPT_ALL, and now
suddenly it stopped but allowed old behavior
if I set AllowOverride Options=. We might even call it an regression
because old correct config (new docs don't mention
any changes so I expect new versions to be compatible) stops to work.

I will produce a patch when it get's decided what to do with an empty
"Options=" (in docs defined as Options[=Option,] so there must be at
least 1 option set)

-- 
Michał Grzędzicki

Reply via email to