Package: cyrus-caldav Version: 2.4.17+caldav~beta10-13~dfd2 Severity: normal Tags: patch
When cyrus is configured with virtual domains and you attempt to create/use calendars for users on domains other than the default domain, one gets a mailbox not found error due to the way the dav code constructs mailbox names for the calendars and addressbooks. The following patch fixes three such issues and gets virtual domains working for me. Description: Fix CalDAV/CardDAV with Virtual Domains Fix CalDAV/CardDAV when user is in a virtual domain so that the virtual domain gets used in the mailbox name. This fixes CalDAV failing to create/open mailbox for calendars when user is not in default or only domain. There were three issues. The first was that if you specify a domain in the calendar URI it is converted as if it it were a mailbox name instead of cyrus domain part (e.g. with '.' separator '.' in domain is converted to '^') of mailbox name. This second was that in calendar lookups for scheduling the userid part of the mailbox name got the domain part truncated due to '@' being replaced by NUL (string terminator) in calendar lookup function (caladdress_lookup). The third was that in some cases mailboxname creation functions didn't even consider the domain part of the userid and therefore didn't handle domain mailbox name construction correctly . Author: Daniel Dickinson <deb...@daniel.thecshore.com> --- The information above should follow the Patch Tagging Guidelines, please checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here are templates for supplementary fields that you might want to add: Origin: <vendor|upstream|other>, <url of original patch> Bug: <url in upstream bugtracker> Bug-Debian: https://bugs.debian.org/<bugnumber> Bug-Ubuntu: https://launchpad.net/bugs/<bugnumber> Forwarded: <no|not-needed|url proving that it has been forwarded> Reviewed-By: <name and email of someone who approved the patch> Last-Update: <YYYY-MM-DD> Index: cyrus-imapd-2.4-2.4.17+caldav~beta10.new/imap/http_caldav.c =================================================================== --- cyrus-imapd-2.4-2.4.17+caldav~beta10.new.orig/imap/http_caldav.c +++ cyrus-imapd-2.4-2.4.17+caldav~beta10.new/imap/http_caldav.c @@ -632,7 +632,7 @@ static void my_caldav_auth(const char *u /* Auto-provision calendars for 'userid' */ strlcpy(ident, userid, sizeof(ident)); - mboxname_hiersep_toexternal(&httpd_namespace, ident, 0); + //mboxname_hiersep_toexternal(&httpd_namespace, ident, 0); /* calendar-home-set */ r = mboxlist_lookup(mailboxname, &mbentry, NULL); @@ -761,6 +761,10 @@ static int caldav_parse_path(const char char *p; size_t len, siz; static const char *prefix = NULL; + char userid[MAX_MAILBOX_BUFFER]; + char userdomain[MAX_MAILBOX_BUFFER]; + char *domain_start; + int userlen, domainlen; /* Make a working copy of target path */ strlcpy(tgt->path, path, sizeof(tgt->path)); @@ -857,13 +861,19 @@ static int caldav_parse_path(const char p = tgt->mboxname; siz = MAX_MAILBOX_BUFFER; if (tgt->user) { - len = snprintf(p, siz, "user"); - p += len; - siz -= len; - if (tgt->userlen) { - len = snprintf(p, siz, ".%.*s", (int) tgt->userlen, tgt->user); - mboxname_hiersep_tointernal(&httpd_namespace, p+1, tgt->userlen); + domain_start = strchr(tgt->user, '@'); + if (domain_start != NULL) { + userlen = domain_start - tgt->user + 1; + domain_start++; + domainlen = tgt->userlen - userlen + 1; + strlcpy(userid, tgt->user, userlen); + strlcpy(userdomain, domain_start, domainlen); + len = snprintf(p, siz, "%.*s!user.%.*s", (int) domainlen, userdomain, (int) userlen, userid); + } else { + len = snprintf(p, siz, "user.%.*s", (int) tgt->userlen, tgt->user); + } + // mboxname_hiersep_tointernal(&httpd_namespace, p+1, tgt->userlen); p += len; siz -= len; } @@ -1918,7 +1928,7 @@ static int caldav_post(struct transactio if (!caladdress_lookup(organizer, &sparam) && !(sparam.flags & SCHEDTYPE_REMOTE)) { strlcpy(orgid, sparam.userid, sizeof(orgid)); - mboxname_hiersep_toexternal(&httpd_namespace, orgid, 0); + //mboxname_hiersep_toexternal(&httpd_namespace, orgid, 0); } } @@ -2134,7 +2144,7 @@ static int caldav_put(struct transaction char ext_userid[MAX_MAILBOX_NAME+1]; strlcpy(ext_userid, userid, sizeof(ext_userid)); - mboxname_hiersep_toexternal(&httpd_namespace, ext_userid, 0); + //mboxname_hiersep_toexternal(&httpd_namespace, ext_userid, 0); txn->error.precond = CALDAV_UNIQUE_OBJECT; assert(!buf_len(&txn->buf)); @@ -3909,7 +3919,7 @@ static int store_resource(struct transac strcmp(cdata->dav.resource, resource)) { /* CALDAV:no-uid-conflict */ char *owner = mboxname_to_userid(cdata->dav.mailbox); - mboxname_hiersep_toexternal(&httpd_namespace, owner, 0); + //mboxname_hiersep_toexternal(&httpd_namespace, owner, 0); txn->error.precond = CALDAV_UID_CONFLICT; assert(!buf_len(&txn->buf)); @@ -4096,9 +4106,12 @@ static int store_resource(struct transac int caladdress_lookup(const char *addr, struct sched_param *param) { - char *p; + char *p, *domain_start; int islocal = 1, found = 1; static char userid[MAX_MAILBOX_BUFFER]; + static char tmpuserid[MAX_MAILBOX_BUFFER]; + static char tmpuserdomain[MAX_MAILBOX_BUFFER]; + int userlen, domainlen, useridlen; memset(param, 0, sizeof(struct sched_param)); @@ -4110,7 +4123,8 @@ int caladdress_lookup(const char *addr, /* XXX Do LDAP/DB/socket lookup to see if user is local */ /* XXX Hack until real lookup stuff is written */ strlcpy(userid, p, sizeof(userid)); - if ((p = strchr(userid, '@')) && !(*p = '\0') && *++p) { + strlcpy(tmpuserid, p, sizeof(tmpuserid)); + if ((p = strchr(tmpuserid, '@')) && !(*p = '\0') && *++p) { struct strlist *domains = cua_domains; for (; domains && strcmp(p, domains->s); domains = domains->next); @@ -4132,9 +4146,19 @@ int caladdress_lookup(const char *addr, calendarprefix = config_getstring(IMAPOPT_CALENDARPREFIX); } - mboxname_hiersep_tointernal(&httpd_namespace, userid, 0); - snprintf(mailboxname, sizeof(mailboxname), - "user.%s.%s", param->userid, calendarprefix); + //mboxname_hiersep_tointernal(&httpd_namespace, userid, 0); + domain_start = strchr(userid, '@'); + if (domain_start != NULL) { + userlen = domain_start - userid + 1; + domain_start++; + useridlen = strcspn(userid, "/"); + domainlen = useridlen - userlen + 1; + strlcpy(tmpuserid, userid, userlen); + strlcpy(tmpuserdomain, domain_start, domainlen); + snprintf(mailboxname, sizeof(mailboxname), "%.*s!user.%.*s.%s", (int) domainlen, tmpuserdomain, (int) userlen, tmpuserid, calendarprefix); + } else { + snprintf(mailboxname, sizeof(mailboxname), "user.%s.%s", userid, calendarprefix); + } r = http_mlookup(mailboxname, ¶m->server, NULL, NULL); if (!r) { @@ -4441,6 +4465,10 @@ int sched_busytime_query(struct transact static const char *calendarprefix = NULL; icalcomponent *comp; char mailboxname[MAX_MAILBOX_BUFFER]; + char tmpuserid[MAX_MAILBOX_BUFFER]; + char tmpuserdomain[MAX_MAILBOX_BUFFER]; + char *domain_start; + int userlen, domainlen, useridlen; icalproperty *prop = NULL, *next; const char *uid = NULL, *organizer = NULL; struct sched_param sparam; @@ -4583,9 +4611,19 @@ int sched_busytime_query(struct transact /* Check ACL of ORGANIZER on attendee's Scheduling Inbox */ - snprintf(mailboxname, sizeof(mailboxname), - "user.%s.%s.Inbox", userid, calendarprefix); - + domain_start = strchr(userid, '@'); + if (domain_start != NULL) { + userlen = domain_start - userid + 1; + domain_start++; + useridlen = strcspn(userid, "/"); + domainlen = useridlen - userlen + 1; + strlcpy(tmpuserid, userid, userlen); + strlcpy(tmpuserdomain, domain_start, domainlen); + snprintf(mailboxname, sizeof(mailboxname), "%.*s!user.%.*s.%s.Inbox", (int) domainlen, tmpuserdomain, (int) userlen, tmpuserid, calendarprefix); + } else { + snprintf(mailboxname, sizeof(mailboxname), "user.%s.%s.Inbox", userid, calendarprefix); + } + if ((r = mboxlist_lookup(mailboxname, &mbentry, NULL))) { syslog(LOG_INFO, "mboxlist_lookup(%s) failed: %s", mailboxname, error_message(r)); @@ -4602,8 +4640,18 @@ int sched_busytime_query(struct transact else { /* Start query at attendee's calendar-home-set */ - snprintf(mailboxname, sizeof(mailboxname), - "user.%s.%s", userid, calendarprefix); + domain_start = strchr(userid, '@'); + if (domain_start != NULL) { + userlen = domain_start - userid + 1; + domain_start++; + useridlen = strcspn(userid, "/"); + domainlen = useridlen - userlen + 1; + strlcpy(tmpuserid, userid, userlen); + strlcpy(tmpuserdomain, domain_start, domainlen); + snprintf(mailboxname, sizeof(mailboxname), "%.*s!user.%.*s.%s.Inbox", (int) domainlen, tmpuserdomain, (int) userlen, tmpuserid, calendarprefix); + } else { + snprintf(mailboxname, sizeof(mailboxname), "user.%s.%s.Inbox", userid, calendarprefix); + } fctx.davdb = NULL; fctx.req_tgt->collection = NULL; Index: cyrus-imapd-2.4-2.4.17+caldav~beta10.new/imap/http_carddav.c =================================================================== --- cyrus-imapd-2.4-2.4.17+caldav~beta10.new.orig/imap/http_carddav.c +++ cyrus-imapd-2.4-2.4.17+caldav~beta10.new/imap/http_carddav.c @@ -369,7 +369,7 @@ static void my_carddav_auth(const char * /* Auto-provision an addressbook for 'userid' */ strlcpy(ident, userid, sizeof(ident)); - mboxname_hiersep_toexternal(&httpd_namespace, ident, 0); + //mboxname_hiersep_toexternal(&httpd_namespace, ident, 0); /* addressbook-home-set */ len += snprintf(mailboxname+len, MAX_MAILBOX_BUFFER - len, ".%s", @@ -461,6 +461,10 @@ static int carddav_parse_path(const char char *p; size_t len, siz; static const char *prefix = NULL; + char userid[MAX_MAILBOX_BUFFER]; + char userdomain[MAX_MAILBOX_BUFFER]; + char *domain_start; + int userlen, domainlen; /* Make a working copy of target path */ strlcpy(tgt->path, path, sizeof(tgt->path)); @@ -546,13 +550,19 @@ static int carddav_parse_path(const char p = tgt->mboxname; siz = MAX_MAILBOX_BUFFER; if (tgt->user) { - len = snprintf(p, siz, "user"); - p += len; - siz -= len; - if (tgt->userlen) { - len = snprintf(p, siz, ".%.*s", (int) tgt->userlen, tgt->user); - mboxname_hiersep_tointernal(&httpd_namespace, p+1, tgt->userlen); + domain_start = strchr(tgt->user, '@'); + if (domain_start != NULL) { + userlen = domain_start - tgt->user + 1; + domain_start++; + domainlen = tgt->userlen - userlen + 1; + strlcpy(userid, tgt->user, userlen); + strlcpy(userdomain, domain_start, domainlen); + len = snprintf(p, siz, "%.*s!user.%.*s", (int) domainlen, userdomain, (int) userlen, userid); + } else { + len = snprintf(p, siz, "user.%.*s", (int) tgt->userlen, tgt->user); + } + // mboxname_hiersep_tointernal(&httpd_namespace, p+1, tgt->userlen); p += len; siz -= len; } @@ -1034,7 +1044,7 @@ static int store_resource(struct transac strcmp(cdata->dav.resource, resource)) { /* CARDDAV:no-uid-conflict */ char *owner = mboxname_to_userid(cdata->dav.mailbox); - mboxname_hiersep_toexternal(&httpd_namespace, owner, 0); + //mboxname_hiersep_toexternal(&httpd_namespace, owner, 0); txn->error.precond = CARDDAV_UID_CONFLICT; assert(!buf_len(&txn->buf)); Index: cyrus-imapd-2.4-2.4.17+caldav~beta10.new/imap/http_dav.c =================================================================== --- cyrus-imapd-2.4-2.4.17+caldav~beta10.new.orig/imap/http_dav.c +++ cyrus-imapd-2.4-2.4.17+caldav~beta10.new/imap/http_dav.c @@ -4716,7 +4716,7 @@ static int principal_search(char *mboxna if (!(p = mboxname_isusermailbox(mboxname, 1))) return 0; strlcpy(userid, p, MAX_MAILBOX_NAME+1); - mboxname_hiersep_toexternal(&httpd_namespace, userid, 0); + //mboxname_hiersep_toexternal(&httpd_namespace, userid, 0); for (search_crit = (struct search_crit *) fctx->filter_crit; search_crit; search_crit = search_crit->next) { -- System Information: Debian Release: 8.0 APT prefers testing APT policy: (500, 'testing') Architecture: amd64 (x86_64) Kernel: Linux 3.16.0-4-amd64 (SMP w/5 CPU cores) Locale: LANG=en_CA.UTF-8, LC_CTYPE=en_CA.UTF-8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/dash Init: systemd (via /run/systemd/system) Versions of packages cyrus-caldav depends on: ii cyrus-common 2.4.17+caldav~beta10-13~dfd2 ii dpkg 1.17.22 ii libc6 2.19-13 ii libcomerr2 1.42.12-1 ii libdb5.3 5.3.28-7~deb8u1 ii libical1 1.0-1.1 ii libkrb5-3 1.12.1+dfsg-16 ii libsasl2-2 2.1.26.dfsg1-12 ii libsqlite3-0 3.8.7.1-1 ii libssl1.0.0 1.0.1j-1 ii libwrap0 7.6.q-25 ii libxml2 2.9.1+dfsg1-4 ii zlib1g 1:1.2.8.dfsg-2+b1 cyrus-caldav recommends no packages. cyrus-caldav suggests no packages. -- no debconf information -- To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org