cyrusimap / cyrus-imapd

Cyrus IMAP is an email, contacts and calendar server
http://cyrusimap.org
Other
544 stars 149 forks source link

[2.5.11] murder frontends fail with iOS 11 ... LIST .... (SPECIAL-USE STATUS....) #2179

Open MASHtm opened 7 years ago

MASHtm commented 7 years ago

I recently updated to 2.5.11. Now we have many complaints of users with iOS 11 devices.

I see that iOS sends

. LIST "" "*" RETURN (SPECIAL-USE STATUS (UNSEEN))

Backends return:

. LIST "" "*" RETURN (SPECIAL-USE STATUS (UNSEEN))
* LIST (\HasChildren) "." INBOX
* STATUS INBOX (UNSEEN 1)
* LIST (\HasChildren) "." INBOX.Archiv
* STATUS INBOX.Archiv (UNSEEN 0)
...

But the frontends return:

. LIST "" "*" RETURN (SPECIAL-USE STATUS (UNSEEN))
* LIST (\Noselect \HasChildren) "." INBOX
* LIST (\Noselect \HasChildren) "." INBOX.Archiv

and I see

Oct 19 13:05:58 joan Fimaps[10943]: IOERROR: opening index user.xxxx: Invalid mailbox name
Oct 19 13:05:58 joan Fimaps[10943]: IOERROR: opening index user.xxxx.Archiv: Invalid mailbox name

Obviously the frontend tried to open the mailbox on local storage.

Most interestingly I had no troubles with 2.5.9 with two other patches for XLIST (issue #41) and LIST (which I can't pinpoint currently) applied. I had to remove both since they didn't apply anymore.

MASHtm commented 7 years ago

So far I think that the first part of the patch for #41 also fixed the "LIST ...(SPECIAL-USE...)" cases... in detail I mean (modified for 2.5.11):

--- a/imap/imapd.c      2017-10-19 15:41:00.323482185 +0200
+++ b/imap/imapd.c      2017-10-19 16:04:48.715712523 +0200
@@ -6712,6 +6712,10 @@
 {
     clock_t start = clock();
     char mytime[100];
+    unsigned want_subscribed = (listargs->sel & LIST_SEL_SUBSCRIBED) ||
+                               (listargs->ret & LIST_RET_SUBSCRIBED);
+    unsigned want_specialuse = (listargs->sel & LIST_SEL_SPECIALUSE) ||
+                               (listargs->ret & LIST_RET_SPECIALUSE);

     if (listargs->sel & LIST_SEL_REMOTE) {
        if (!config_getswitch(IMAPOPT_PROXYD_DISABLE_MAILBOX_REFERRALS)) {
@@ -6729,8 +6733,7 @@
        /* special case: query top-level hierarchy separator */
        prot_printf(imapd_out, "* XLIST (\\Noselect) \"%c\" \"\"\r\n",
                    imapd_namespace.hier_sep);
-    } else if (((listargs->sel & LIST_SEL_SUBSCRIBED) ||
-               (listargs->ret & LIST_RET_SUBSCRIBED)) &&
+    } else if ((want_subscribed || want_specialuse) &&
               (backend_inbox || (backend_inbox = proxy_findinboxserver(imapd_userid)))) {
        /* remote inbox */

the rest

@@ -11940,10 +11943,11 @@
     }

     /* print tag, command and list selection options */
-    if (listargs->cmd & LIST_CMD_LSUB) {
+    if (listargs->cmd == LIST_CMD_LSUB) {
        prot_printf(backend_inbox->out, "%s Lsub ", tag);
     } else {
-       prot_printf(backend_inbox->out, "%s List ", tag);
+       prot_printf(backend_inbox->out, "%s %s ", tag,
+                    listargs->cmd == LIST_CMD_XLIST ? "Xlist" : "List");

        /* print list selection options */
        if (listargs->sel) {
@@ -11987,6 +11991,12 @@
                    "{%tu+}\r\n%s", strlen(listargs->pat.data[0]), listargs->pat.data[0]);
     }

+    /* don't accidentally promote a plain XLIST to an extended-LIST
+     * just because of its defaults */
+    if (listargs->cmd == LIST_CMD_XLIST) {
+       listargs->ret &= ~(LIST_RET_CHILDREN | LIST_RET_SPECIALUSE);
+    }
+
     /* print list return options */
     if (listargs->ret) {
        const char *return_opts[] = {

fixes #41 (XLIST) as good as for 2.5.9 and with all the limitations noted there.