Problems with lmtp delivery on 2.2.2-BETA

Matthew Hodgson matthew at mxtelecom.com
Wed Jan 7 14:44:14 EST 2004


Hi,

I've come across some problems delivering into Cyrus 2.2.2-BETA (fresh cvs)
via LMTP where local-parts of recipients contain quoted-string sections as per
RFC 822 when using virtual domains.  Specifically, Exim's ${quote:} function
turns a local part of +Folder.subfolder at domain.com to
"+Folder.subfolder"@domain.com - which lmtpd then rejects:

220 foobar LMTP Cyrus v2.2.2-BETA ready
LHLO foobar.mxtelecom.com
250-foobar
...
250 IGNOREQUOTA
MAIL FROM:<matthew at mxtelecom.com>
250 2.1.0 ok
RCPT TO:<"matthew"@mxtelecom.com>
550-Mailbox unknown.  Either there is no mailbox associated with this
550-name or you do not have authorization to see it.
550 5.1.1 User unknown

Looking at the process_recipient() code in lmtpengine.c, I'm not sure that the
quote-string parsing has been updated fully to reflect virtual domains - so
I've fiddled around and come up with a version based on the existing code, and
also a complete rewrite.  I enclose the latter as a patch here; it hasn't been
rigorously tested (at all), but has fixed my particular problem.  If anyone
has interest in the other version, just say - any feedback & flames appreciated.

cheers,

M.

______________________________________________________________
Matthew Hodgson   matthew at mxtelecom.com   Tel: +44 845 6667778
                   Systems Analyst, MX Telecom Ltd.

-------------- next part --------------
Index: lmtpengine.c
===================================================================
RCS file: /cvs/src/cyrus/imap/lmtpengine.c,v
retrieving revision 1.96
diff -u -r1.96 lmtpengine.c
--- lmtpengine.c        10 Nov 2003 16:42:14 -0000      1.96
+++ lmtpengine.c        7 Jan 2004 19:04:54 -0000
@@ -754,6 +754,7 @@
     char *dest;
     char *user;
     int r, sl;
+    int inusername, inquoted;
     address_data_t *ret = (address_data_t *) xmalloc(sizeof(address_data_t));
     int forcedowncase = config_getswitch(IMAPOPT_LMTP_DOWNCASE_RCPT);

@@ -781,40 +782,30 @@
        addr++;
     }

-    if (*addr == '\"') {
-       addr++;
-       while (*addr && *addr != '\"') {
-           if (*addr == '\\') addr++;
-           *dest++ = *addr++;
-       }
-    }
-    else {
-       if(forcedowncase) {
-           /* We should downcase the localpart up to the first + */
-           while(*addr != '@' && *addr != '>' && *addr != '+') {
-               if(*addr == '\\') addr++;
-               *dest++ = TOLOWER(*addr++);
-           }
-           if (*addr == '+') {
-             while(*addr != '@' && *addr != '>') {
-               if(*addr == '\\') addr++;
-               *dest++ = *addr++;
-             }
-           }
-           while ((config_virtdomains || *addr != '@') && *addr != '>') {
-               if(*addr == '\\') addr++;
-               *dest++ = TOLOWER(*addr++);
-           }
-       } else {
-         /* Now finish the remainder of the localpart */
-         while ((config_virtdomains || *addr != '@') && *addr != '>') {
-             if (*addr == '\\') addr++;
-             *dest++ = *addr++;
-         }
-       }
+    inusername = 1;
+    inquoted = 0;
+
+    while(*addr && (inquoted || ((config_virtdomains || *addr != '@') && *addr != '>'))) {
+        if (*addr == '\\' && inquoted) addr++;
+
+        if (*addr == '\"') {
+            inquoted = inquoted ? 0 : 1;
+            addr++;
+        }
+        if (*addr == '+' && inusername) {
+            inusername = 0;
+        }
+
+        if (forcedowncase && inusername) {
+            *dest++ = TOLOWER(*addr++);
+        }
+        else {
+            *dest++ = *addr++;
+        }
     }
+
     *dest = '\0';
-
+
     r = verify_user(user, ignorequota ? -1 : msg->size, msg->authstate);
     if (r) {
        /* we lost */




More information about the Info-cyrus mailing list