const char *dir;
int locktimeout;
int allow_depthinfinity;
+ ap_expr_info_t *allow_lockdiscovery;
} dav_dir_conf;
newconf->dir = DAV_INHERIT_VALUE(parent, child, dir);
newconf->allow_depthinfinity = DAV_INHERIT_VALUE(parent, child,
allow_depthinfinity);
+ newconf->allow_lockdiscovery = DAV_INHERIT_VALUE(parent, child,
+ allow_lockdiscovery);
return newconf;
}
return NULL;
}
+/*
+ * Command handler for the DAVLockDiscovery directive, which is TAKE1.
+ */
+static const char *dav_cmd_davlockdiscovery(cmd_parms *cmd, void *config,
+ const char *arg)
+{
+ dav_dir_conf *conf = (dav_dir_conf *)config;
+
+ if (strncasecmp(arg, "expr=", 5) == 0) {
+ const char *err;
+ if ((arg[5] == '\0'))
+ return "missing condition";
+ conf->allow_lockdiscovery = ap_expr_parse_cmd(cmd, &arg[5],
+ AP_EXPR_FLAG_DONT_VARY,
+ &err, NULL);
+ if (err)
+ return err;
+ } else {
+ return "error in condition clause";
+ }
+
+ return NULL;
+}
+
/*
* Command handler for DAVMinTimeout directive, which is TAKE1
*/
}
/* open the property database (readonly) for the resource */
- if ((err = dav_open_propdb(r, lockdb, resource, 1, NULL,
+ if ((err = dav_open_propdb(r, lockdb, resource, DAV_PROPDB_RO, NULL,
&propdb)) != NULL) {
if (lockdb != NULL)
(*lockdb->hooks->close_lockdb)(lockdb);
static dav_error * dav_propfind_walker(dav_walk_resource *wres, int calltype)
{
dav_walker_ctx *ctx = wres->walk_ctx;
+ dav_dir_conf *conf;
+ int flags = DAV_PROPDB_RO;
dav_error *err;
dav_propdb *propdb;
dav_get_props_result propstats = { 0 };
return NULL;
}
+ conf = ap_get_module_config(ctx->r->per_dir_config, &dav_module);
+ if (conf && conf->allow_lockdiscovery) {
+ const char *errstr = NULL;
+ int eval = ap_expr_exec(ctx->r, conf->allow_lockdiscovery, &errstr);
+ if (errstr) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, ctx->r, APLOGNO(00623)
+ "Failed to evaluate expression (%s) - ignoring",
+ errstr);
+ } else {
+ if (!eval)
+ flags |= DAV_PROPDB_DISABLE_LOCKDISCOVERY;
+ }
+ }
+
/*
** Note: ctx->doc can only be NULL for DAV_PROPFIND_IS_ALLPROP. Since
** dav_get_allprops() does not need to do namespace translation,
** the resource, however, since we are opening readonly.
*/
err = dav_popen_propdb(ctx->scratchpool,
- ctx->r, ctx->w.lockdb, wres->resource, 1,
+ ctx->r, ctx->w.lockdb, wres->resource, flags,
ctx->doc ? ctx->doc->namespaces : NULL, &propdb);
if (err != NULL) {
/* ### do something with err! */
return dav_handle_err(r, err, NULL);
}
- if ((err = dav_open_propdb(r, NULL, resource, 0, doc->namespaces,
+ if ((err = dav_open_propdb(r, NULL, resource,
+ DAV_PROPDB_NONE, doc->namespaces,
&propdb)) != NULL) {
/* undo any auto-checkout */
dav_auto_checkin(r, resource, 1 /*undo*/, 0 /*unlock*/, &av_info);
ACCESS_CONF|RSRC_CONF,
"allow Depth infinity PROPFIND requests"),
+ /* per directory/location, or per server */
+ AP_INIT_TAKE1("DAVLockDiscovery", dav_cmd_davlockdiscovery, NULL,
+ ACCESS_CONF|RSRC_CONF,
+ "allow lock discovery by PROPFIND requests"),
+
{ NULL }
};
dav_buffer wb_lock; /* work buffer for lockdiscovery property */
+ int flags; /* ro, disable lock discovery */
+
/* if we ever run a GET subreq, it will be stored here */
request_rec *subreq;
switch (propid) {
case DAV_PROPID_CORE_lockdiscovery:
+ if (propdb->flags & DAV_PROPDB_DISABLE_LOCKDISCOVERY) {
+ value = "";
+ break;
+ }
+
if (propdb->lockdb != NULL) {
dav_lock *locks;
DAV_DECLARE(dav_error *)dav_open_propdb(request_rec *r, dav_lockdb *lockdb,
const dav_resource *resource,
- int ro,
+ int flags,
apr_array_header_t * ns_xlate,
dav_propdb **p_propdb)
{
- return dav_popen_propdb(r->pool, r, lockdb, resource, ro, ns_xlate, p_propdb);
+ return dav_popen_propdb(r->pool, r, lockdb, resource,
+ flags, ns_xlate, p_propdb);
}
DAV_DECLARE(dav_error *)dav_popen_propdb(apr_pool_t *p,
request_rec *r, dav_lockdb *lockdb,
const dav_resource *resource,
- int ro,
+ int flags,
apr_array_header_t * ns_xlate,
dav_propdb **p_propdb)
{
propdb->lockdb = lockdb;
+ propdb->flags = flags;
+
/* always defer actual open, to avoid expense of accessing db
* when only live properties are involved
*/