-/* $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 <gilles@poolp.org>
/* 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");
-/* $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 <gilles@poolp.org>
#include "smtpd.h"
#include "log.h"
-#define TAG_CHAR '+' /* gilles+tag@ */
-
#define EXPAND_DEPTH 10
#define F_WAITING 0x01
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);
{ "strip", mod_strip },
{ "raw", NULL }, /* special case, must stay last */
};
-static const char *unsafe = MAILADDR_ESCAPE;
-
static int init;
static struct tree sessions;
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;
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");
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 */
*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)
{
-/* $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 <gilles@poolp.org>
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)) {
-/* $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 <gilles@poolp.org>
#define PATH_CHROOT "/var/empty"
#define SMTPD_QUEUE_USER "_smtpq"
#define PATH_SPOOL "/var/spool/smtpd"
+
+#define TAG_CHAR '+'
-/* $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 <gilles@poolp.org>
struct deliver {
char to[SMTPD_MAXPATHLEN];
char from[SMTPD_MAXPATHLEN];
+ char dest[SMTPD_MAXLINESIZE];
char user[SMTPD_MAXLOGNAME];
short mode;