83 lines
3.9 KiB
C
83 lines
3.9 KiB
C
$NetBSD$
|
||
|
||
The CalDAV / CardDAV functionality of Cyrus IMAP supports the
|
||
auto-discovery mechanism, which is used by many clients to find out
|
||
the calendars and address books available for the respective user.
|
||
At the moment this does not work for shared calendars and address
|
||
books from other users.
|
||
|
||
There was a discussion on this topic on Github:
|
||
|
||
https://github.com/cyrusimap/cyrus-imapd/issues/2373
|
||
|
||
As part of the discussion, Дилян Палаузов provided a patch that
|
||
solves this problem. Unfortunately, it has not yet been included
|
||
in an official release because it may not yet be the complete solution
|
||
that covers all scenarios.
|
||
|
||
Anyway - the patch is included here because, in my opinion, sharing
|
||
calendars and address books is an essential functionality of a
|
||
groupware. Without this patch, this will not work on clients that only
|
||
offer auto-discovery - i.e. most mobile devices.
|
||
|
||
--- imap/http_dav.c.orig 2020-03-18 20:29:25.102243914 +0000
|
||
+++ imap/http_dav.c
|
||
@@ -5455,7 +5455,7 @@ int propfind_by_collection(const mbentry
|
||
|
||
if (!fctx->req_tgt->resource) {
|
||
len = make_collection_url(&writebuf, fctx->req_tgt->namespace->prefix,
|
||
- mboxname, fctx->req_tgt->userid, NULL);
|
||
+ mboxname, mbname_userid(mbname_from_intname(mboxname)), NULL);
|
||
|
||
/* copy it all back into place... in theory we should check against
|
||
* 'last' and make sure it doesn't change from the original request.
|
||
@@ -5483,6 +5483,12 @@ int propfind_by_collection(const mbentry
|
||
return r;
|
||
}
|
||
|
||
+static int wrapper_propfind_by_collection(struct findall_data *data, void* rock) {
|
||
+ if (!data || !data->mbentry) return 0;
|
||
+ struct propfind_ctx *fctx = (struct propfind_ctx *) rock;
|
||
+ if ((httpd_myrights(httpd_authstate, data->mbentry) & DACL_READ != DACL_READ)) return 0;
|
||
+ return propfind_by_collection(data->mbentry, fctx);
|
||
+}
|
||
|
||
/* Perform a PROPFIND request */
|
||
EXPORTED int meth_propfind(struct transaction_t *txn, void *params)
|
||
@@ -5746,12 +5752,13 @@ EXPORTED int meth_propfind(struct transa
|
||
else if (txn->req_tgt.mbentry) {
|
||
/* Add responses for all contained collections */
|
||
fctx.prefer &= ~PREFER_NOROOT;
|
||
- mboxlist_mboxtree(txn->req_tgt.mbentry->name,
|
||
- propfind_by_collection, &fctx,
|
||
- MBOXTREE_SKIP_ROOT);
|
||
|
||
switch (txn->req_tgt.namespace->id) {
|
||
case URL_NS_DRIVE:
|
||
+ mboxlist_mboxtree(txn->req_tgt.mbentry->name,
|
||
+ propfind_by_collection, &fctx,
|
||
+ MBOXTREE_SKIP_ROOT);
|
||
+
|
||
if (txn->req_tgt.flags == TGT_DRIVE_ROOT) {
|
||
/* Add a response for 'user' hierarchy */
|
||
buf_setcstr(&fctx.buf, txn->req_tgt.namespace->prefix);
|
||
@@ -5772,11 +5779,16 @@ EXPORTED int meth_propfind(struct transa
|
||
/* Fall through */
|
||
|
||
case URL_NS_ADDRESSBOOK:
|
||
+ {
|
||
/* Add responses for shared collections */
|
||
- mboxlist_usersubs(txn->req_tgt.userid,
|
||
- propfind_by_collection, &fctx,
|
||
- MBOXTREE_SKIP_PERSONAL);
|
||
+ const char *conf_str = txn->req_tgt.namespace->id == URL_NS_CALENDAR ?
|
||
+ config_getstring(IMAPOPT_CALENDARPREFIX) : config_getstring(IMAPOPT_ADDRESSBOOKPREFIX);
|
||
+ char *pat = malloc(5 + strlen(conf_str));
|
||
+ sprintf(pat, "*%s%c*", conf_str, httpd_namespace.hier_sep);
|
||
+ mboxlist_findall(&httpd_namespace, pat, httpd_userisadmin, txn->req_tgt.userid, httpd_authstate, wrapper_propfind_by_collection, &fctx);
|
||
+ free(pat);
|
||
break;
|
||
+ }
|
||
}
|
||
}
|