<p>common structures for heartbeat modules (should this be public API?)</p>
</section>
+ <section id="ap_parse_htaccess">
+ <title>ap_parse_htaccess (changed)</title>
+ <p>The function signature for <code>ap_parse_htaccess</code> has been
+ changed. A <code>apr_table_t</code> of individual directives allowed
+ for override must now be passed (override remains).</p>
+ </section>
+
<section id="http_config">
<title>http_config (changed)</title>
<ul>
<directive type="section" module="core">Files</directive> sections.
</note>
- <p>When this directive is set to <code>None</code>, then
- <a href="#accessfilename">.htaccess</a> files are completely ignored.
- In this case, the server will not even attempt to read
- <code>.htaccess</code> files in the filesystem.</p>
+ <p>When this directive is set to <code>None</code> and <directive
+ module="core">AllowOverrideList</directive> is set to
+ <code>None</code> <a href="#accessfilename">.htaccess</a> files are
+ completely ignored. In this case, the server will not even attempt
+ to read <code>.htaccess</code> files in the filesystem.</p>
<p>When this directive is set to <code>All</code>, then any
directive which has the .htaccess <a
</note>
</usage>
+<directivesynopsis>
+<name>AllowOverrideList</name>
+<description>Individual directives that are allowed in
+<code>.htaccess</code> files</description>
+<syntax>AllowOverrideList None|<var>directive</var>
+[<var>directive-type</var>] ...</syntax>
+<default>AllowOverrideList None</default>
+<contextlist><context>directory</context></contextlist>
+
+<usage>
+ <p>When the server finds an <code>.htaccess</code> file (as
+ specified by <directive module="core">AccessFileName</directive>)
+ it needs to know which directives declared in that file can override
+ earlier configuration directives.</p>
+
+ <note><title>Only available in <Directory> sections</title>
+ <directive>AllowOverrideList</directive> is valid only in
+ <directive type="section" module="core">Directory</directive>
+ sections specified without regular expressions, not in <directive
+ type="section" module="core">Location</directive>, <directive
+ module="core" type="section">DirectoryMatch</directive> or
+ <directive type="section" module="core">Files</directive> sections.
+ </note>
+
+ <p>When this directive is set to <code>None</code> and <directive
+ module="core">AllowOverride</directive> is set to <code>None</code>,
+ then <a href="#accessfilename">.htaccess</a> files are completely
+ ignored. In this case, the server will not even attempt to read
+ <code>.htaccess</code> files in the filesystem.</p>
+
+ <p>Example:</p>
+
+ <example>
+ AllowOverride None
+ AllowOverrideList Redirect RedirectMatch
+ </example>
+
+ <p>In the example above only the <code>Redirect</code> and
+ <code>RedirectMatch</code> directives are allowed. All others will
+ cause an internal server error.</p>
+
+ <p>Example:</p>
+
+ <example>
+ AllowOverride AuthConfig
+ AllowOverrideList CookieTracking CookieName
+ </example>
+
+ <p>In the example above <directive module="core">AllowOverride
+ </directive> grants permission to the <code>AuthConfig</code>
+ directive grouping and <directive>AllowOverrideList</directive> grants
+ permission to only two directves from the <code>FileInfo</code> directive
+ grouping. All others will cause an internal server error.</p>
+</usage>
+
<seealso><directive module="core">AccessFileName</directive></seealso>
+<seealso><directive module="core">AllowOverride</directive></seealso>
<seealso><a href="../configuring.html">Configuration Files</a></seealso>
<seealso><a href="../howto/htaccess.html">.htaccess Files</a></seealso>
</directivesynopsis>
* rename AP_EXPR_FLAGS_* -> AP_EXPR_FLAG_*
* 20110702.1 (2.3.14-dev) Add ap_scan_script_header_err*_ex functions
* 20110723.0 (2.3.14-dev) Revert addition of ap_ldap*
+ * 20110724.0 (2.3.14-dev) Add override_list as parameter to ap_parse_htaccess
+ * Add member override_list to cmd_parms_struct,
+ * core_dir_config and htaccess_result
*/
#define MODULE_MAGIC_COOKIE 0x41503234UL /* "AP24" */
#ifndef MODULE_MAGIC_NUMBER_MAJOR
-#define MODULE_MAGIC_NUMBER_MAJOR 20110723
+#define MODULE_MAGIC_NUMBER_MAJOR 20110724
#endif
#define MODULE_MAGIC_NUMBER_MINOR 0 /* 0...n */
#include "util_cfgtree.h"
#include "ap_config.h"
+#include "apr_tables.h"
#ifdef __cplusplus
extern "C" {
int override;
/** Which allow-override-opts bits are set */
int override_opts;
+ /** Table of directives allowed per AllowOverrideList */
+ apr_table_t *override_list;
/** Which methods are <Limit>ed */
apr_int64_t limited;
/** methods which are limited */
* @param r The request currently being served
* @param override Which overrides are active
* @param override_opts Which allow-override-opts bits are set
+ * @param override_list Table of directives allowed for override
* @param path The path to the htaccess file
* @param access_name The list of possible names for .htaccess files
* int The status of the current request
request_rec *r,
int override,
int override_opts,
+ apr_table_t *override_list,
const char *path,
const char *access_name);
#include "apr_optional.h"
#include "util_filter.h"
#include "ap_expr.h"
+#include "apr_tables.h"
#include "http_config.h"
/** per-dir log config */
struct ap_logconf *log;
+ /** Table of directives allowed per AllowOverrideList */
+ apr_table_t *override_list;
+
} core_dir_config;
/* macro to implement off by default behaviour */
int override;
/** the override options allowed for the .htaccess file */
int override_opts;
+ /** Table of allowed directives for override */
+ apr_table_t *override_list;
/** the configuration directives */
struct ap_conf_vector_t *htaccess;
/** the next one, or NULL if no more; N.B. never change this */
static const char *invoke_cmd(const command_rec *cmd, cmd_parms *parms,
void *mconfig, const char *args)
{
+ int override_list_ok = 0;
char *w, *w2, *w3;
const char *errmsg = NULL;
- if ((parms->override & cmd->req_override) == 0)
+ /** Have we been provided a list of acceptable directives? */
+ if(parms->override_list != NULL)
+ if(apr_table_get(parms->override_list, cmd->name) != NULL)
+ override_list_ok = 1;
+
+ if ((parms->override & cmd->req_override) == 0 && !override_list_ok)
return apr_pstrcat(parms->pool, cmd->name, " not allowed here", NULL);
parms->info = cmd->cmd_data;
*/
static cmd_parms default_parms =
-{NULL, 0, 0, -1, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
+{NULL, 0, 0, NULL, -1, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
AP_DECLARE(char *) ap_server_root_relative(apr_pool_t *p, const char *file)
{
AP_CORE_DECLARE(int) ap_parse_htaccess(ap_conf_vector_t **result,
request_rec *r, int override,
- int override_opts,
+ int override_opts, apr_table_t *override_list,
const char *d, const char *access_name)
{
ap_configfile_t *f = NULL;
parms = default_parms;
parms.override = override;
parms.override_opts = override_opts;
+ parms.override_list = override_list;
parms.pool = r->pool;
parms.temp_pool = r->pool;
parms.server = r->server;
conf->override_opts = new->override_opts;
}
+ if (conf->override_list == NULL) {
+ conf->override_list = new->override_list;
+ }
+
if (conf->response_code_strings == NULL) {
conf->response_code_strings = new->response_code_strings;
}
return NULL;
}
+static const char *set_override_list(cmd_parms *cmd, void *d_, int argc, char *const argv[])
+{
+ core_dir_config *d = d_;
+ int i;
+
+ /* Throw a warning if we're in <Location> or <Files> */
+ if (ap_check_cmd_context(cmd, NOT_IN_LOCATION | NOT_IN_FILES)) {
+ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, cmd->server,
+ "Useless use of AllowOverrideList in line %d of %s.",
+ cmd->directive->line_num, cmd->directive->filename);
+ }
+
+ d->override_list = apr_table_make(cmd->pool, 1);
+
+ for (i=0;i<argc;i++){
+ if (!strcasecmp(argv[i], "None")) {
+ return NULL;
+ }
+ else {
+ const command_rec *result = NULL;
+ module *mod = ap_top_module;
+ result = ap_find_command_in_modules(argv[i], &mod);
+ if (result)
+ apr_table_set(d->override_list, argv[i], "1");
+ else
+ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, cmd->server,
+ "Discarding unrecognized directive `%s' in AllowOverrideList.",
+ argv[i]);
+ }
+ }
+
+ return NULL;
+}
+
static const char *set_options(cmd_parms *cmd, void *d_, const char *l)
{
core_dir_config *d = d_;
AP_INIT_RAW_ARGS("AllowOverride", set_override, NULL, ACCESS_CONF,
"Controls what groups of directives can be configured by per-directory "
"config files"),
+AP_INIT_TAKE_ARGV("AllowOverrideList", set_override_list, NULL, ACCESS_CONF,
+ "Controls what individual directives can be configured by per-directory "
+ "config files"),
AP_INIT_RAW_ARGS("Options", set_options, NULL, OR_OPTIONS,
"Set a number of attributes for a given directory"),
AP_INIT_TAKE1("DefaultType", set_default_type, NULL, OR_FILEINFO,
allow_options_t remove;
overrides_t override;
overrides_t override_opts;
+ apr_table_t *override_list;
} core_opts_t;
static void core_opts_merge(const ap_conf_vector_t *sec, core_opts_t *opts)
opts->override = this_dir->override;
opts->override_opts = this_dir->override_opts;
}
+
+ if (this_dir->override_list != NULL) {
+ opts->override_list = this_dir->override_list;
+ }
+
}
opts.remove = this_dir->opts_remove;
opts.override = this_dir->override;
opts.override_opts = this_dir->override_opts;
+ opts.override_list = this_dir->override_list;
/* Set aside path_info to merge back onto path_info later.
* If r->filename is a directory, we must remerge the path_info,
/* No htaccess in an incomplete root path,
* nor if it's disabled
*/
- if (seg < startseg || !opts.override) {
+ if (seg < startseg || (!opts.override && opts.override_list == NULL)) {
break;
}
+
res = ap_parse_htaccess(&htaccess_conf, r, opts.override,
- opts.override_opts,
+ opts.override_opts, opts.override_list,
apr_pstrdup(r->pool, r->filename),
sconf->access_name);
if (res) {