Bug#774128: cyrus-caldav: [PATCH] dav: Fails with virtual domain for non-default domain users

Daniel Dickinson debian at daniel.thecshore.com
Mon Dec 29 08:55:08 UTC 2014


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 <debian at 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, &param->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



More information about the Pkg-Cyrus-imapd-Debian-devel mailing list