From: gilles Date: Wed, 30 Apr 2014 09:17:29 +0000 (+0000) Subject: when using maildir, do not create automatically create folders to match tag X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=99bdd714228213b62a859456b53c064554caf865;p=openbsd when using maildir, do not create automatically create folders to match tag in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder if it already exists and deliver to the mail Maildir otherwise. ok eric@ and chl@ --- diff --git a/usr.sbin/smtpd/delivery_maildir.c b/usr.sbin/smtpd/delivery_maildir.c index 132d9574704..7dbf219d73d 100644 --- a/usr.sbin/smtpd/delivery_maildir.c +++ b/usr.sbin/smtpd/delivery_maildir.c @@ -1,4 +1,4 @@ -/* $OpenBSD: delivery_maildir.c,v 1.13 2014/04/19 17:31:35 gilles Exp $ */ +/* $OpenBSD: delivery_maildir.c,v 1.14 2014/04/30 09:17:29 gilles Exp $ */ /* * Copyright (c) 2011 Gilles Chehade @@ -42,28 +42,70 @@ extern char **environ; /* maildir backend */ static void delivery_maildir_open(struct deliver *); +static int maildir_tag(const struct mailaddr *, char *, size_t); struct delivery_backend delivery_backend_maildir = { 1, delivery_maildir_open }; +static int +mailaddr_tag(const struct mailaddr *maddr, char *dest, size_t len) +{ + char *tag; + char *sanitized; + + if ((tag = strchr(maddr->user, TAG_CHAR))) { + tag++; + while (*tag == '.') + tag++; + } + if (tag == NULL) + return 1; + + if (strlcpy(dest, tag, len) >= len) + return 0; + for (sanitized = dest; *sanitized; sanitized++) + if (strchr(MAILADDR_ESCAPE, *sanitized)) + *sanitized = ':'; + return 1; +} static void delivery_maildir_open(struct deliver *deliver) { - char tmp[SMTPD_MAXPATHLEN], new[SMTPD_MAXPATHLEN]; + char tmp[SMTPD_MAXPATHLEN], new[SMTPD_MAXPATHLEN], tag[SMTPD_MAXPATHLEN]; int ch, fd; FILE *fp; char *msg; int n; + const char *chd; + struct mailaddr maddr; + struct stat sb; #define error(m) { msg = m; goto err; } #define error2(m) { msg = m; goto err2; } setproctitle("maildir delivery"); + + memset(&maddr, 0, sizeof maddr); + if (! text_to_mailaddr(&maddr, deliver->dest)) + error("cannot parse destination address"); + + memset(tag, 0, sizeof tag); + if (! mailaddr_tag(&maddr, tag, sizeof tag)) + error("cannot extract tag from destination address"); + if (mkdirs(deliver->to, 0700) < 0 && errno != EEXIST) error("cannot mkdir maildir"); - if (chdir(deliver->to) < 0) + chd = deliver->to; + + if (tag[0]) { + (void)snprintf(tmp, sizeof tmp, "%s/.%s", deliver->to, tag); + if (stat(tmp, &sb) != -1) + chd = tmp; + } + + if (chdir(chd) < 0) error("cannot cd to maildir"); if (mkdir("cur", 0700) < 0 && errno != EEXIST) error("mkdir cur failed"); diff --git a/usr.sbin/smtpd/lka_session.c b/usr.sbin/smtpd/lka_session.c index 8b738685100..d3ab19e01ba 100644 --- a/usr.sbin/smtpd/lka_session.c +++ b/usr.sbin/smtpd/lka_session.c @@ -1,4 +1,4 @@ -/* $OpenBSD: lka_session.c,v 1.66 2014/04/19 12:55:23 gilles Exp $ */ +/* $OpenBSD: lka_session.c,v 1.67 2014/04/30 09:17:29 gilles Exp $ */ /* * Copyright (c) 2011 Gilles Chehade @@ -40,8 +40,6 @@ #include "smtpd.h" #include "log.h" -#define TAG_CHAR '+' /* gilles+tag@ */ - #define EXPAND_DEPTH 10 #define F_WAITING 0x01 @@ -70,7 +68,6 @@ static void lka_resume(struct lka_session *); static size_t lka_expand_format(char *, size_t, const struct envelope *, const struct userinfo *); static void mailaddr_to_username(const struct mailaddr *, char *, size_t); -static int mailaddr_tag(const struct mailaddr *, char *, size_t); static int mod_lowercase(char *, size_t); static int mod_uppercase(char *, size_t); @@ -85,8 +82,6 @@ struct modifiers { { "strip", mod_strip }, { "raw", NULL }, /* special case, must stay last */ }; -static const char *unsafe = MAILADDR_ESCAPE; - static int init; static struct tree sessions; @@ -479,7 +474,6 @@ lka_submit(struct lka_session *lks, struct rule *rule, struct expandnode *xn) struct envelope *ep; struct expandnode *xn2; int r; - char tag[EXPAND_BUFFER]; ep = xmemdup(&lks->envelope, sizeof *ep, "lka_submit"); ep->expire = rule->r_qexpire; @@ -548,24 +542,6 @@ lka_submit(struct lka_session *lks, struct rule *rule, struct expandnode *xn) ep->agent.mda.method = rule->r_action; (void)strlcpy(ep->agent.mda.buffer, rule->r_value.buffer, sizeof ep->agent.mda.buffer); - - memset(tag, 0, sizeof tag); - if (! mailaddr_tag(&ep->dest, tag, sizeof tag)) { - lks->error = LKA_PERMFAIL; - free(ep); - return; - } - if (rule->r_action == A_MAILDIR && tag[0]) { - (void)strlcat(ep->agent.mda.buffer, "/.", - sizeof(ep->agent.mda.buffer)); - if (strlcat(ep->agent.mda.buffer, tag, - sizeof(ep->agent.mda.buffer)) - >= sizeof(ep->agent.mda.buffer)) { - lks->error = LKA_TEMPFAIL; - free(ep); - return; - } - } } else fatalx("lka_deliver: bad node type"); @@ -712,7 +688,7 @@ lka_expand_token(char *dest, size_t len, const char *token, if (! raw && replace) for (i = 0; (size_t)i < strlen(tmp); ++i) - if (strchr(unsafe, tmp[i])) + if (strchr(MAILADDR_ESCAPE, tmp[i])) tmp[i] = ':'; /* expanded string is empty */ @@ -849,28 +825,6 @@ mailaddr_to_username(const struct mailaddr *maddr, char *dst, size_t len) *tag++ = '\0'; } -static int -mailaddr_tag(const struct mailaddr *maddr, char *dest, size_t len) -{ - char *tag; - char *sanitized; - - if ((tag = strchr(maddr->user, TAG_CHAR))) { - tag++; - while (*tag == '.') - tag++; - } - if (tag == NULL) - return 1; - - if (strlcpy(dest, tag, len) >= len) - return 0; - for (sanitized = dest; *sanitized; sanitized++) - if (strchr(unsafe, *sanitized)) - *sanitized = ':'; - return 1; -} - static int mod_lowercase(char *buf, size_t len) { diff --git a/usr.sbin/smtpd/mda.c b/usr.sbin/smtpd/mda.c index 5dd4bdc1d07..0eecd8767f4 100644 --- a/usr.sbin/smtpd/mda.c +++ b/usr.sbin/smtpd/mda.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mda.c,v 1.105 2014/04/19 17:42:18 gilles Exp $ */ +/* $OpenBSD: mda.c,v 1.106 2014/04/30 09:17:29 gilles Exp $ */ /* * Copyright (c) 2008 Gilles Chehade @@ -290,6 +290,8 @@ mda_imsg(struct mproc *p, struct imsg *imsg) deliver.userinfo = *userinfo; (void)strlcpy(deliver.user, userinfo->username, sizeof(deliver.user)); + (void)strlcpy(deliver.dest, e->dest, + sizeof(deliver.dest)); if (strlcpy(deliver.to, e->buffer, sizeof(deliver.to)) >= sizeof(deliver.to)) { diff --git a/usr.sbin/smtpd/smtpd-defines.h b/usr.sbin/smtpd/smtpd-defines.h index a3fa6754032..9838f91a9b1 100644 --- a/usr.sbin/smtpd/smtpd-defines.h +++ b/usr.sbin/smtpd/smtpd-defines.h @@ -1,4 +1,4 @@ -/* $OpenBSD: smtpd-defines.h,v 1.2 2013/12/05 10:06:32 eric Exp $ */ +/* $OpenBSD: smtpd-defines.h,v 1.3 2014/04/30 09:17:29 gilles Exp $ */ /* * Copyright (c) 2013 Gilles Chehade @@ -32,3 +32,5 @@ #define PATH_CHROOT "/var/empty" #define SMTPD_QUEUE_USER "_smtpq" #define PATH_SPOOL "/var/spool/smtpd" + +#define TAG_CHAR '+' diff --git a/usr.sbin/smtpd/smtpd.h b/usr.sbin/smtpd/smtpd.h index 8cba92068a5..606f62a0f4d 100644 --- a/usr.sbin/smtpd/smtpd.h +++ b/usr.sbin/smtpd/smtpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: smtpd.h,v 1.458 2014/04/30 08:23:43 reyk Exp $ */ +/* $OpenBSD: smtpd.h,v 1.459 2014/04/30 09:17:29 gilles Exp $ */ /* * Copyright (c) 2008 Gilles Chehade @@ -621,6 +621,7 @@ struct forward_req { struct deliver { char to[SMTPD_MAXPATHLEN]; char from[SMTPD_MAXPATHLEN]; + char dest[SMTPD_MAXLINESIZE]; char user[SMTPD_MAXLOGNAME]; short mode;