Hello all,

 A bug[1] in cyrus imapd was reported to me[2] by Patrick T. Tsang, that has
to do with renaming folder when using unix hierarchy separators, altnamespace and
virtual domains. The problem is illustrated in the following session:

. login [EMAIL PROTECTED] HiI'mAPassowd 
. OK User logged in
. list * *
* LIST (\Noinferiors) "/" "INBOX"
* LIST (\HasNoChildren) "/" "Drafts"
* LIST (\HasChildren) "/" "FolderA"
* LIST (\HasChildren) "/" "FolderA/FolderB"
* LIST (\HasNoChildren) "/" "FolderA/FolderB/FolderC"
* LIST (\HasNoChildren) "/" "Sent"
* LIST (\HasNoChildren) "/" "Templates"
* LIST (\HasNoChildren) "/" "Trash"
* LIST (\HasNoChildren) "/" "lala"
. OK Completed (0.000 secs 10 calls)
. rename FolderA/FolderB FolderA/FolderBB
* OK rename Other Users/arisg/FolderA/FolderB Other Users/arisg/FolderA/FolderBB
. OK Completed


 Actually there should be two things different IMHO. There shouldn't
be the Other Users part, and FolderA/FolderB/FolderC should also
be renamed in FolderA/FolderBB/FolderC.

 If I use the default domain and logon in to the machine I get:

. login arisg OupsDidICopyAPassword?
. OK User logged in
. list * *
* LIST (\Noinferiors) "/" "INBOX"
* LIST (\HasNoChildren) "/" "Drafts"
* LIST (\HasChildren) "/" "FolderA"
* LIST (\HasChildren) "/" "FolderA/FolderB"
* LIST (\HasNoChildren) "/" "FolderA/FolderB/FolderC"
* LIST (\HasNoChildren) "/" "Sent"
* LIST (\HasNoChildren) "/" "Templates"
* LIST (\HasNoChildren) "/" "Trash"
* LIST (\HasNoChildren) "/" "lala"
. OK Completed (0.000 secs 10 calls)
. rename FolderA/FolderB FolderA/FolderBB
* OK rename FolderA/FolderB FolderA/FolderBB
* OK rename FolderA/FolderB/FolderC FolderA/FolderBB/FolderC


  So i include a small patch that fixes this problem.

. login [EMAIL PROTECTED] OupsIThinkISawAPassowd
. OK User logged in
. list * *
* LIST (\Noinferiors) "/" "INBOX"
* LIST (\HasNoChildren) "/" "Drafts"
* LIST (\HasChildren) "/" "FolderA"
* LIST (\HasChildren) "/" "FolderA/FolderB"
* LIST (\HasNoChildren) "/" "FolderA/FolderB/FolderC"
* LIST (\HasNoChildren) "/" "Sent"
* LIST (\HasNoChildren) "/" "Templates"
* LIST (\HasNoChildren) "/" "Trash"
* LIST (\HasNoChildren) "/" "lala"
. OK Completed (0.000 secs 10 calls)
. rename FolderA/FolderB FolderA/FolderBB
* OK rename FolderA/FolderB FolderA/FolderBB
* OK rename FolderA/FolderB/FolderC FolderA/FolderBB/FolderC
. OK Completed



   This patch however was developped quite quickly in order
to solve the problem on a particular server, so the patch
is not tested extensively (Patrick didn't report any complains
so far, and everything is working as it is supposed to, nothing
else was broken with this patch till now). Actually
if anyone of the cyrus developers argues that the problem 
should be tackled in different place in the cyrus code .. 
probably i won't argue with that either.


   Best regards, 
    Aristotelis


[1] Actually, I don't know if this is a feature or not. Or
even if the configuration options used cause any problems

[2] Actually, Patrick thought that there was a problem with
the autocreation of folders so he sent me an email. I was able
to recreate the problem, so i just a quick look at it.
 

P.S> Thanks to Patrick for offering me the playground... eeerm
the testing environment :))) 


diff -Naur cyrus-imapd-2.2.6/imap/mboxlist.c 
cyrus-imapd-2.2.6.autocreate.patrick2.uncompiled/imap/mboxlist.c
--- cyrus-imapd-2.2.6/imap/mboxlist.c   2004-05-22 06:45:51.000000000 +0300
+++ cyrus-imapd-2.2.6.autocreate.patrick2.uncompiled/imap/mboxlist.c    2004-07-08 
14:54:57.000000000 +0300
@@ -1900,7 +1900,11 @@
        if (userid && (p = strrchr(userid, '@'))) {
            userlen = p - userid;
            domainlen = strlen(p); /* includes separator */
-           snprintf(domainpat, sizeof(domainpat), "%s!%s", p+1, pattern);
+           snprintf(domainpat, sizeof(domainpat), "%s!", p+1);
+           if(strchr(pattern,'!')) {
+               pattern+=domainlen;
+               strlcat(domainpat, pattern, sizeof(domainpat));
+           }
        }
        if ((p = strrchr(pattern, '@'))) {
            /* global admin specified [EMAIL PROTECTED] */
diff -Naur cyrus-imapd-2.2.6/imap/mboxname.c 
cyrus-imapd-2.2.6.autocreate.patrick2.uncompiled/imap/mboxname.c
--- cyrus-imapd-2.2.6/imap/mboxname.c   2004-05-22 06:45:51.000000000 +0300
+++ cyrus-imapd-2.2.6.autocreate.patrick2.uncompiled/imap/mboxname.c    2004-07-08 
14:54:44.000000000 +0300
@@ -369,6 +369,15 @@
 {
     char *domain;
 
+    char *user = NULL;
+
+    if((domain = strchr(userid,'@'))) {
+       user = xmalloc((domain-userid+1)*sizeof(char));
+       strlcpy(user, userid,(domain-userid+1));
+    }
+    else 
+       user = userid;
+
     /* Blank the result, just in case */
     result[0] = '\0';
 
@@ -376,7 +385,7 @@
     
     if (!userid) return IMAP_MAILBOX_BADNAME;
 
-    if (config_virtdomains && (domain = strchr(userid, '@')) &&
+    if (config_virtdomains && domain &&
        !strncmp(name, domain+1, strlen(domain)-1) &&
        name[strlen(domain)-1] == '!')
        name += strlen(domain);
@@ -391,13 +400,13 @@
     }
     /* paranoia - this shouldn't be needed */
     else if (!strncmp(name, "user.", 5) &&
-            !strncmp(name+5, userid, strlen(userid)) &&
-            (name[5+strlen(userid)] == '\0' ||
-             name[5+strlen(userid)] == '.')) {
-       if (name[5+strlen(userid)] == '\0')
+            !strncmp(name+5, user, strlen(user)) &&
+            (name[5+strlen(user)] == '\0' ||
+             name[5+strlen(user)] == '.')) {
+       if (name[5+strlen(user)] == '\0')
            strcpy(result, "INBOX");
        else
-           strcpy(result, name+5+strlen(userid)+1);
+           strcpy(result, name+5+strlen(user)+1);
     }
 
     /* Other Users namespace */
@@ -427,6 +436,9 @@
 
     /* Translate any separators in mailboxname */
     mboxname_hiersep_toexternal(namespace, result, 0);
+
+    if(user!=userid)
+       free(user);
     return 0;
 }
 

Reply via email to