File 0004-Autocreate-on-PROPFIND.patch of Package cyrus-imapd

From 26d7c35f3c674901c0691ea2ab388cbc818d9e9b Mon Sep 17 00:00:00 2001
From: Christian Mollekopf <mollekopf@apheleia-it.ch>
Date: Mon, 24 Oct 2022 21:37:34 +0200
Subject: [PATCH 4/4] Autocreate on PROPFIND

If we don't have existing calendar folders then dav_parse_req_target
fails, because it looks for the base calendar via mupdate.
The new codepath simply attempts to lookup the inbox instead and then
proxies the request to that backend, triggering the autocreate.
This requires that the inbox has been created before though.
---
 imap/http_dav.c | 35 ++++++++++++++++++++++++++++++++++-
 1 file changed, 34 insertions(+), 1 deletion(-)

diff --git a/imap/http_dav.c b/imap/http_dav.c
index bd73964f2..285d4b939 100644
--- a/imap/http_dav.c
+++ b/imap/http_dav.c
@@ -509,6 +509,28 @@ static unsigned long principal_allow_cb(struct request_target_t *tgt)
     return tgt->namespace->allow;
 }
 
+static struct backend *proxy_findinboxserver(const char *userid)
+{
+    mbentry_t *mbentry = NULL;
+    struct backend *s = NULL;
+
+    char *inbox = mboxname_user_mbox(userid, NULL);
+    int r = mboxlist_lookup(inbox, &mbentry, NULL);
+    free(inbox);
+
+    if (r) return NULL;
+
+    if (mbentry->mbtype & MBTYPE_REMOTE) {
+        s = proxy_findserver(mbentry->server, &http_protocol,
+                             httpd_userid, &backend_cached,
+                             NULL, NULL, httpd_in);
+    }
+
+    mboxlist_entry_free(&mbentry);
+
+    return s;
+}
+
 
 /* Parse request-target path in DAV principals namespace */
 static int principal_parse_path(const char *path, struct request_target_t *tgt,
@@ -6121,7 +6143,18 @@ EXPORTED int meth_propfind(struct transaction_t *txn, void *params)
     /* Parse the path */
     if (fparams->parse_path) {
         r = dav_parse_req_target(txn, fparams);
-        if (r) return r;
+        if (r) {
+
+            struct backend *be;
+            be = proxy_findinboxserver(txn->req_tgt.userid);
+            if (!be) {
+                syslog(LOG_ERR, "Could not find a backend");
+                return HTTP_UNAVAILABLE;
+            }
+            return http_pipe_req_resp(be, txn);
+
+            return r;
+        }
     }
 
     /* Make sure method is allowed */
-- 
2.37.3