(untested)

ap_allow_options() is how applications, including our mod_include, access
the enabled options for a given request (other than evil apps which define
CORE_PRIVATE and locate the core_dir_config).  As this is a callable
function, it can map internal, hidden bitmaps as appropriate before
returning to the caller.

The attached patch uses new OPT_PVT_ flags internally for include-related
options (defined inside CORE_PRIVATE) but maps those onto the old
OPT_INCLUDES and OPT_INCNOEXEC flags inside the ap_allow_options() function.
Index: server/core.c
===================================================================
--- server/core.c       (revision 777698)
+++ server/core.c       (working copy)
@@ -245,11 +245,11 @@
         /* If Includes was enabled with exec in the base config, but
          * was enabled without exec in the new config, then disable
          * exec in the merged set. */
-        if (((base->opts & (OPT_INCLUDES|OPT_INC_WITH_EXEC))
-             == (OPT_INCLUDES|OPT_INC_WITH_EXEC))
-            && ((new->opts & (OPT_INCLUDES|OPT_INC_WITH_EXEC))
-                == OPT_INCLUDES)) {
-            conf->opts &= ~OPT_INC_WITH_EXEC;
+        if (((base->opts & (OPT_PVT_INCLUDES|OPT_PVT_INC_WITH_EXEC))
+             == (OPT_PVT_INCLUDES|OPT_PVT_INC_WITH_EXEC))
+            && ((new->opts & (OPT_PVT_INCLUDES|OPT_PVT_INC_WITH_EXEC))
+                == OPT_PVT_INCLUDES)) {
+            conf->opts &= ~OPT_PVT_INC_WITH_EXEC;
         }
     }
     else {
@@ -660,8 +660,17 @@
 {
     core_dir_config *conf =
       (core_dir_config *)ap_get_module_config(r->per_dir_config, &core_module);
+    int mapped_include_opts = 
+      conf->opts & ~(OPT_PVT_INCLUDES|OPT_PVT_INC_WITH_EXEC);
 
-    return conf->opts;
+    if (conf->opts & OPT_PVT_INCLUDES) {
+        mapped_include_opts |= OPT_INCLUDES;
+        if (!(conf->opts & OPT_PVT_INC_WITH_EXEC)) {
+            mapped_include_opts |= OPT_INCNOEXEC;
+        }
+    }
+
+    return mapped_include_opts;
 }
 
 AP_DECLARE(int) ap_allow_overrides(request_rec *r)
@@ -1312,10 +1321,10 @@
         else if (!strcasecmp(w, "Includes")) {
             /* If Includes is permitted, both Includes and
              * IncludesNOEXEC may be changed. */
-            opt = (OPT_INCLUDES | OPT_INC_WITH_EXEC);
+            opt = (OPT_PVT_INCLUDES | OPT_PVT_INC_WITH_EXEC);
         }
         else if (!strcasecmp(w, "IncludesNOEXEC")) {
-            opt = OPT_INCLUDES;
+            opt = OPT_PVT_INCLUDES;
         }
         else if (!strcasecmp(w, "FollowSymLinks")) {
             opt = OPT_SYM_LINKS;
@@ -1436,10 +1445,10 @@
             opt = OPT_INDEXES;
         }
         else if (!strcasecmp(w, "Includes")) {
-            opt = (OPT_INCLUDES | OPT_INC_WITH_EXEC);
+            opt = (OPT_PVT_INCLUDES | OPT_PVT_INC_WITH_EXEC);
         }
         else if (!strcasecmp(w, "IncludesNOEXEC")) {
-            opt = OPT_INCLUDES;
+            opt = OPT_PVT_INCLUDES;
         }
         else if (!strcasecmp(w, "FollowSymLinks")) {
             opt = OPT_SYM_LINKS;
Index: modules/filters/mod_include.c
===================================================================
--- modules/filters/mod_include.c       (revision 777698)
+++ modules/filters/mod_include.c       (working copy)
@@ -3565,7 +3565,7 @@
         intern->seen_eos = 0;
         intern->state = PARSE_PRE_HEAD;
         ctx->flags = (SSI_FLAG_PRINTING | SSI_FLAG_COND_TRUE);
-        if ((ap_allow_options(r) & OPT_INC_WITH_EXEC) == 0) {
+        if (ap_allow_options(r) & OPTINCNOEXEC) == 0) {
             ctx->flags |= SSI_FLAG_NO_EXEC;
         }
         intern->accessenable = conf->accessenable;
Index: include/http_core.h
===================================================================
--- include/http_core.h (revision 777698)
+++ include/http_core.h (working copy)
@@ -65,7 +65,7 @@
 #define OPT_NONE 0
 /** Indexes directive */
 #define OPT_INDEXES 1
-/** SSI is enabled without exec= permission  */
+/** Includes directive */
 #define OPT_INCLUDES 2
 /**  FollowSymLinks directive */
 #define OPT_SYM_LINKS 4
@@ -73,14 +73,14 @@
 #define OPT_EXECCGI 8
 /**  directive unset */
 #define OPT_UNSET 16
-/**  SSI exec= permission is permitted, iff OPT_INCLUDES is also set */
-#define OPT_INC_WITH_EXEC 32
+/**  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_INC_WITH_EXEC|OPT_SYM_LINKS|OPT_EXECCGI)
+#define OPT_ALL (OPT_INDEXES|OPT_INCLUDES|OPT_SYM_LINKS|OPT_EXECCGI)
 /** @} */
 
 /**
@@ -396,6 +396,16 @@
 typedef unsigned char allow_options_t;
 typedef unsigned char overrides_t;
 
+/* Include-related options are handled internally via these OPT_PVT_*
+ * options, but remapped by ap_allow_options(r) to the traditional
+ * OPT_INCNOEXEC or OPT_INCLUDES flags.
+ */
+/** SSI is enabled without exec= permission  */
+#define OPT_PVT_INCLUDES 2
+/**  SSI exec= permission is permitted, iff OPT_INCLUDES is also set */
+#define OPT_PVT_INC_WITH_EXEC 32
+#define OPT_PVT_ALL 
(OPT_INDEXES|OPT_PVT_INCLUDES|OPT_PVT_INC_WITH_EXEC|OPT_SYM_LINKS|OPT_EXECCGI)
+
 /*
  * Bits of info that go into making an ETag for a file
  * document.  Why a long?  Because char historically

Reply via email to