# HG changeset patch
# User Olaf Wintermann <olaf.wintermann@gmail.com>
# Date 1667412610 -3600
# Node ID 6afaebf003ea86cf6ba90cea92292d8caeac3567
# Parent  a4e2ce073c0f64188baa66989d47c13e15d8a35e
implement ACL check for proppatch requests

diff -r a4e2ce073c0f -r 6afaebf003ea src/server/webdav/operation.c
--- a/src/server/webdav/operation.c	Wed Nov 02 18:38:40 2022 +0100
+++ b/src/server/webdav/operation.c	Wed Nov 02 19:10:10 2022 +0100
@@ -282,6 +282,36 @@
         return REQ_ABORTED;
     }
     
+    // check ACL
+    if(acl_evaluate(op->sn, op->rq, ACL_WRITE_XATTR)) {
+        // ACL check failed, either unauthorized or forbidden
+        // acl_evaluate() sets the http status code and may add
+        // response headers for authentication
+        if(op->rq->status_num == PROTOCOL_UNAUTHORIZED) {
+            return REQ_ABORTED; // return here to send an authenticate response
+        }
+        
+        // send multistatus response with status code 403 for each property
+        log_ereport(LOG_VERBOSE, "webdav-proppatch: access forbidden");
+        int ret = REQ_PROCEED;
+        WebdavPList *plist = op->proppatch->set;
+        for(int i=0;i<2;i++) {
+            while(plist) {
+                if(resource->addproperty(resource, plist->property, PROTOCOL_FORBIDDEN)) {
+                    ret = REQ_ABORTED;
+                    break; // OOM
+                }
+                plist = plist->next;
+            }
+            plist = op->proppatch->remove;
+        }
+        
+        if(resource->close(resource)) {
+            ret = REQ_ABORTED; // OOM
+        }
+        return ret;
+    }
+    
     VFSContext *ctx = NULL;
     VFSFile *file = NULL;