From: Graham Leggett Date: Sun, 5 Jul 2020 11:52:06 +0000 (+0000) Subject: Extend method_precondition hook to be called during the PROPFIND X-Git-Tag: 2.5.0-alpha2-ci-test-only~1280 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ec6f9bc29de88ef8ae3d549bc7b379348d46a4eb;p=thirdparty%2Fapache%2Fhttpd.git Extend method_precondition hook to be called during the PROPFIND and LABEL walkers, once for each walked resource. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1879522 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/include/ap_mmn.h b/include/ap_mmn.h index e1dade6f12c..55df1a064bc 100644 --- a/include/ap_mmn.h +++ b/include/ap_mmn.h @@ -653,12 +653,13 @@ * 20200702.2 (2.5.1-dev) Add dav_get_resource(). * 20200703.0 (2.5.1-dev) Remove ap_md5digest(), ap_md5contextTo64(), * ContentDigest directive. + * 20200705.0 (2.5.1-dev) Update method_precondition hook. */ #define MODULE_MAGIC_COOKIE 0x41503235UL /* "AP25" */ #ifndef MODULE_MAGIC_NUMBER_MAJOR -#define MODULE_MAGIC_NUMBER_MAJOR 20200703 +#define MODULE_MAGIC_NUMBER_MAJOR 20200705 #endif #define MODULE_MAGIC_NUMBER_MINOR 0 /* 0...n */ diff --git a/modules/dav/main/mod_dav.c b/modules/dav/main/mod_dav.c index bd6ad3c6e32..9b73867a72f 100644 --- a/modules/dav/main/mod_dav.c +++ b/modules/dav/main/mod_dav.c @@ -2061,6 +2061,13 @@ static dav_error * dav_propfind_walker(dav_walk_resource *wres, int calltype) } #endif + /* check for any method preconditions */ + if (dav_run_method_precondition(ctx->r, NULL, wres->resource, ctx->doc, &err) != DECLINED + && err) { + apr_pool_clear(ctx->scratchpool); + return NULL; + } + /* ** Note: ctx->doc can only be NULL for DAV_PROPFIND_IS_ALLPROP. Since ** dav_get_allprops() does not need to do namespace translation, @@ -4114,6 +4121,9 @@ typedef struct dav_label_walker_ctx /* input: */ dav_walk_params w; + /* original request */ + request_rec *r; + /* label being manipulated */ const char *label; @@ -4133,13 +4143,19 @@ static dav_error * dav_label_walker(dav_walk_resource *wres, int calltype) dav_label_walker_ctx *ctx = wres->walk_ctx; dav_error *err = NULL; + /* check for any method preconditions */ + if (dav_run_method_precondition(ctx->r, NULL, wres->resource, NULL, &err) != DECLINED + && err) { + /* precondition failed, dropping through */ + } + /* Check the state of the resource: must be a version or * non-checkedout version selector */ /* ### need a general mechanism for reporting precondition violations * ### (should be returning XML document for 403/409 responses) */ - if (wres->resource->type != DAV_RESOURCE_TYPE_VERSION && + else if (wres->resource->type != DAV_RESOURCE_TYPE_VERSION && (wres->resource->type != DAV_RESOURCE_TYPE_REGULAR || !wres->resource->versioned)) { err = dav_new_error(ctx->w.pool, HTTP_CONFLICT, 0, 0, @@ -4261,6 +4277,7 @@ static int dav_method_label(request_rec *r) ctx.w.walk_ctx = &ctx; ctx.w.pool = r->pool; ctx.w.root = resource; + ctx.r = r; ctx.vsn_hooks = vsn_hooks; err = (*resource->hooks->walk)(&ctx.w, depth, &multi_status); @@ -5253,7 +5270,7 @@ APR_IMPLEMENT_EXTERNAL_HOOK_VOID(dav, DAV, gather_reports, APR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(dav, DAV, int, method_precondition, (request_rec *r, - dav_resource *src, dav_resource *dest, + dav_resource *src, const dav_resource *dest, const apr_xml_doc *doc, dav_error **err), (r, src, dest, doc, err), DECLINED) diff --git a/modules/dav/main/mod_dav.h b/modules/dav/main/mod_dav.h index 98b13af1bd2..31cd9819022 100644 --- a/modules/dav/main/mod_dav.h +++ b/modules/dav/main/mod_dav.h @@ -759,7 +759,7 @@ APR_DECLARE_EXTERNAL_HOOK(dav, DAV, void, gather_reports, ** the non-XML body of a request should register an input filter to do so ** within this hook. ** - ** Methods like PUT will supply a single src resource, and the dest will + ** Methods like PUT will supply a single src resource, and the dst will ** be NULL. ** ** Methods like COPY or MOVE will trigger this hook twice. The first @@ -767,10 +767,18 @@ APR_DECLARE_EXTERNAL_HOOK(dav, DAV, void, gather_reports, ** will supply a source and destination. This allows preconditions on the ** source resource to be verified before making an attempt to get the ** destination resource. + ** + ** Methods like PROPFIND and LABEL will trigger this hook initially for + ** the src resource, and then subsequently for each resource that has + ** been walked during processing, with the walked resource passed in dst, + ** and NULL passed in src. + ** + ** As a rule, the src resource originates from a request that has passed + ** through httpd's authn/authz hooks, while the dst resource has not. */ APR_DECLARE_EXTERNAL_HOOK(dav, DAV, int, method_precondition, (request_rec *r, - dav_resource *src, dav_resource *dst, + dav_resource *src, const dav_resource *dst, const apr_xml_doc *doc, dav_error **err))