]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
Extend method_precondition hook to be called during the PROPFIND
authorGraham Leggett <minfrin@apache.org>
Sun, 5 Jul 2020 11:52:06 +0000 (11:52 +0000)
committerGraham Leggett <minfrin@apache.org>
Sun, 5 Jul 2020 11:52:06 +0000 (11:52 +0000)
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

include/ap_mmn.h
modules/dav/main/mod_dav.c
modules/dav/main/mod_dav.h

index e1dade6f12c6aeb9c2ee8da240a1ee5dc8bd3d5c..55df1a064bc8ee868309b77a0b428834c53d5013 100644 (file)
  * 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 */
 
index bd6ad3c6e32f8a30723d8d00c4ff1e24580ac261..9b73867a72f4264c2fffd965c14f7c2da74ac25f 100644 (file)
@@ -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)
index 98b13af1bd26c320f3c095e90034c16013914ca2..31cd9819022928baa36d0f6aee1557f7a8b80b82 100644 (file)
@@ -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))