summaryrefslogtreecommitdiff
path: root/usr.sbin/smtpd
diff options
context:
space:
mode:
authorGilles Chehade <gilles@cvs.openbsd.org>2011-05-16 21:05:53 +0000
committerGilles Chehade <gilles@cvs.openbsd.org>2011-05-16 21:05:53 +0000
commit5e214bf2f9e80611a8b62614bf245d0b6df10679 (patch)
tree902c5b4dfdb9664269ef442febf2685a0af86442 /usr.sbin/smtpd
parentad8f46c8f3c15f2ba7e47cdbdc8495a754b0bff9 (diff)
murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many parts of smtpd to be refactored and more specifically envelope expansion. in the process lots of code got simplified, and the envelope expansion code has been isolated to lka_session.c with some longstanding bugs fixed. Diff has been tested by many with no major regression reported. armani@ spotted a bug in a setup where a domain is listed a both primary and virtual, I will fix that in-tree as it's becoming painful to maintain this diff out.
Diffstat (limited to 'usr.sbin/smtpd')
-rw-r--r--usr.sbin/smtpd/aliases.c33
-rw-r--r--usr.sbin/smtpd/bounce.c20
-rw-r--r--usr.sbin/smtpd/forward.c6
-rw-r--r--usr.sbin/smtpd/lka.c556
-rw-r--r--usr.sbin/smtpd/lka_session.c629
-rw-r--r--usr.sbin/smtpd/mda.c68
-rw-r--r--usr.sbin/smtpd/mfa.c47
-rw-r--r--usr.sbin/smtpd/mta.c96
-rw-r--r--usr.sbin/smtpd/queue.c58
-rw-r--r--usr.sbin/smtpd/queue_backend.c20
-rw-r--r--usr.sbin/smtpd/queue_fsqueue.c61
-rw-r--r--usr.sbin/smtpd/queue_shared.c99
-rw-r--r--usr.sbin/smtpd/ramqueue.c45
-rw-r--r--usr.sbin/smtpd/ruleset.c22
-rw-r--r--usr.sbin/smtpd/runner.c86
-rw-r--r--usr.sbin/smtpd/smtp.c24
-rw-r--r--usr.sbin/smtpd/smtp_session.c77
-rw-r--r--usr.sbin/smtpd/smtpd.c4
-rw-r--r--usr.sbin/smtpd/smtpd.h218
-rw-r--r--usr.sbin/smtpd/smtpd/Makefile14
-rw-r--r--usr.sbin/smtpd/util.c94
21 files changed, 1201 insertions, 1076 deletions
diff --git a/usr.sbin/smtpd/aliases.c b/usr.sbin/smtpd/aliases.c
index 26b631d0f64..9695e5aea42 100644
--- a/usr.sbin/smtpd/aliases.c
+++ b/usr.sbin/smtpd/aliases.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: aliases.c,v 1.42 2011/05/01 12:57:11 eric Exp $ */
+/* $OpenBSD: aliases.c,v 1.43 2011/05/16 21:05:51 gilles Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
@@ -88,7 +88,7 @@ aliases_get(objid_t mapid, struct expandtree *expandtree, char *username)
nbaliases = 0;
RB_FOREACH(expnode, expandtree, &map_alias->expandtree) {
if (expnode->type == EXPAND_INCLUDE)
- nbaliases += aliases_expand_include(expandtree, expnode->u.filename);
+ nbaliases += aliases_expand_include(expandtree, expnode->u.buffer);
else {
expandtree_increment_node(expandtree, expnode);
nbaliases++;
@@ -128,7 +128,7 @@ aliases_vdomain_exists(objid_t mapid, char *hostname)
}
int
-aliases_virtual_exist(objid_t mapid, struct path *path)
+aliases_virtual_exist(objid_t mapid, struct mailaddr *maddr)
{
struct map *map;
struct map_virtual *map_virtual;
@@ -139,8 +139,8 @@ aliases_virtual_exist(objid_t mapid, struct path *path)
if (map == NULL)
return 0;
- if (! bsnprintf(buf, sizeof(buf), "%s@%s", path->user,
- path->domain))
+ if (! bsnprintf(buf, sizeof(buf), "%s@%s", maddr->user,
+ maddr->domain))
return 0;
lowercase(buf, buf, sizeof(buf));
@@ -161,7 +161,7 @@ aliases_virtual_exist(objid_t mapid, struct path *path)
int
aliases_virtual_get(objid_t mapid, struct expandtree *expandtree,
- struct path *path)
+ struct mailaddr *maddr)
{
struct map *map;
struct map_virtual *map_virtual;
@@ -174,8 +174,8 @@ aliases_virtual_get(objid_t mapid, struct expandtree *expandtree,
if (map == NULL)
return 0;
- if (! bsnprintf(buf, sizeof(buf), "%s@%s", path->user,
- path->domain))
+ if (! bsnprintf(buf, sizeof(buf), "%s@%s", maddr->user,
+ maddr->domain))
return 0;
lowercase(buf, buf, sizeof(buf));
@@ -191,7 +191,7 @@ aliases_virtual_get(objid_t mapid, struct expandtree *expandtree,
nbaliases = 0;
RB_FOREACH(expnode, expandtree, &map_virtual->expandtree) {
if (expnode->type == EXPAND_INCLUDE)
- nbaliases += aliases_expand_include(expandtree, expnode->u.filename);
+ nbaliases += aliases_expand_include(expandtree, expnode->u.buffer);
else {
expandtree_increment_node(expandtree, expnode);
nbaliases++;
@@ -280,10 +280,9 @@ alias_parse(struct expandnode *alias, char *line)
int
alias_is_filter(struct expandnode *alias, char *line, size_t len)
{
- if (strncmp(line, "\"|", 2) == 0 &&
- line[len - 1] == '"') {
- if (strlcpy(alias->u.filter, line, sizeof(alias->u.filter)) >=
- sizeof(alias->u.filter))
+ if (*line == '|') {
+ if (strlcpy(alias->u.buffer, line + 1,
+ sizeof(alias->u.buffer)) >= sizeof(alias->u.buffer))
return 0;
alias->type = EXPAND_FILTER;
return 1;
@@ -294,8 +293,8 @@ alias_is_filter(struct expandnode *alias, char *line, size_t len)
int
alias_is_username(struct expandnode *alias, char *line, size_t len)
{
- if (strlcpy(alias->u.username, line,
- sizeof(alias->u.username)) >= sizeof(alias->u.username))
+ if (strlcpy(alias->u.user, line,
+ sizeof(alias->u.user)) >= sizeof(alias->u.user))
return 0;
while (*line) {
@@ -356,8 +355,8 @@ alias_is_filename(struct expandnode *alias, char *line, size_t len)
if (*line != '/')
return 0;
- if (strlcpy(alias->u.filename, line,
- sizeof(alias->u.filename)) >= sizeof(alias->u.filename))
+ if (strlcpy(alias->u.buffer, line,
+ sizeof(alias->u.buffer)) >= sizeof(alias->u.buffer))
return 0;
alias->type = EXPAND_FILENAME;
return 1;
diff --git a/usr.sbin/smtpd/bounce.c b/usr.sbin/smtpd/bounce.c
index ff3bed8100b..9ad1b7130b8 100644
--- a/usr.sbin/smtpd/bounce.c
+++ b/usr.sbin/smtpd/bounce.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: bounce.c,v 1.31 2011/05/01 12:57:11 eric Exp $ */
+/* $OpenBSD: bounce.c,v 1.32 2011/05/16 21:05:51 gilles Exp $ */
/*
* Copyright (c) 2009 Gilles Chehade <gilles@openbsd.org>
@@ -54,7 +54,7 @@ bounce_session(int fd, struct envelope *m)
FILE *msgfp = NULL;
u_int32_t msgid;
- msgid = evpid_to_msgid(m->evpid);
+ msgid = evpid_to_msgid(m->delivery.id);
/* get message content */
if ((msgfd = queue_message_fd_r(Q_QUEUE, msgid)) == -1)
@@ -72,11 +72,11 @@ bounce_session(int fd, struct envelope *m)
client_ssl_optional(cc->pcb);
client_sender(cc->pcb, "");
- client_rcpt(cc->pcb, NULL, "%s@%s", m->sender.user,
- m->sender.domain);
+ client_rcpt(cc->pcb, NULL, "%s@%s", m->delivery.from.user,
+ m->delivery.from.domain);
/* Construct an appropriate reason line. */
- reason = m->session_errorline;
+ reason = m->delivery.errorline;
if (strlen(reason) > 4 && (*reason == '1' || *reason == '6'))
reason += 4;
@@ -100,9 +100,9 @@ bounce_session(int fd, struct envelope *m)
"Below is a copy of the original message:\n"
"\n",
env->sc_hostname,
- m->sender.user, m->sender.domain,
+ m->delivery.from.user, m->delivery.from.domain,
time_to_text(time(NULL)),
- m->recipient.user, m->recipient.domain,
+ m->delivery.rcpt.user, m->delivery.rcpt.domain,
reason);
/* setup event */
@@ -151,10 +151,10 @@ out:
queue_envelope_delete(Q_QUEUE, &cc->m);
else {
if (*ep == '5' || *ep == '6')
- cc->m.status = S_MESSAGE_PERMFAILURE;
+ cc->m.delivery.status = DS_PERMFAILURE;
else
- cc->m.status = S_MESSAGE_TEMPFAILURE;
- message_set_errormsg(&cc->m, "%s", ep);
+ cc->m.delivery.status = DS_TEMPFAILURE;
+ envelope_set_errormsg(&cc->m, "%s", ep);
queue_message_update(&cc->m);
}
diff --git a/usr.sbin/smtpd/forward.c b/usr.sbin/smtpd/forward.c
index 800a37de8ab..a8046cfad8b 100644
--- a/usr.sbin/smtpd/forward.c
+++ b/usr.sbin/smtpd/forward.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: forward.c,v 1.23 2010/11/28 14:35:58 gilles Exp $ */
+/* $OpenBSD: forward.c,v 1.24 2011/05/16 21:05:51 gilles Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
@@ -34,7 +34,7 @@
#include "log.h"
int
-forwards_get(int fd, struct expandtree *expandtree)
+forwards_get(int fd, struct expandtree *expandtree, char *as_user)
{
FILE *fp;
char *buf, *lbuf, *p, *cp;
@@ -94,6 +94,8 @@ forwards_get(int fd, struct expandtree *expandtree)
continue;
}
+ (void)strlcpy(expnode.as_user, as_user, sizeof(expnode.as_user));
+
expandtree_increment_node(expandtree, &expnode);
nbaliases++;
} while (*cp != '\0');
diff --git a/usr.sbin/smtpd/lka.c b/usr.sbin/smtpd/lka.c
index f36a783693e..581a72e86d3 100644
--- a/usr.sbin/smtpd/lka.c
+++ b/usr.sbin/smtpd/lka.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: lka.c,v 1.126 2011/05/01 12:57:11 eric Exp $ */
+/* $OpenBSD: lka.c,v 1.127 2011/05/16 21:05:51 gilles Exp $ */
/*
* Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org>
@@ -41,37 +41,23 @@
#include "smtpd.h"
#include "log.h"
-struct rule *ruleset_match(char *, struct path *, struct sockaddr_storage *);
+struct rule *ruleset_match(struct envelope *);
static void lka_imsg(struct imsgev *, struct imsg *);
static void lka_shutdown(void);
static void lka_sig_handler(int, short, void *);
-static void lka_expand_pickup(struct lkasession *);
-static int lka_expand_resume(struct lkasession *);
-static int lka_resolve_node(char *, struct path *, struct expandnode *);
-static int lka_verify_mail(struct path *);
-static int lka_resolve_path(struct lkasession *, struct path *);
-static struct lkasession *lka_session_init(struct submit_status *);
-static void lka_request_forwardfile(struct lkasession *, char *);
-static void lka_clear_expandtree(struct expandtree *);
-static void lka_clear_deliverylist(struct deliverylist *);
+static int lka_verify_mail(struct mailaddr *);
static int lka_encode_credentials(char *, size_t, struct map_secret *);
-static size_t lka_expand(char *, size_t, struct path *, struct path *);
-static void lka_rcpt_action(char *, struct path *);
-static void lka_session_destroy(struct lkasession *);
-static void lka_expansion_done(struct lkasession *);
-static void lka_session_fail(struct lkasession *, struct submit_status *);
+
+void lka_session(struct submit_status *);
+void lka_session_forward_reply(struct forward_req *, int);
static void
lka_imsg(struct imsgev *iev, struct imsg *imsg)
{
- struct lkasession skey;
struct submit_status *ss;
- struct forward_req *fwreq;
- struct lkasession *s;
struct secret *secret;
struct mapel *mapel;
struct rule *rule;
- struct path *path;
struct map *map;
void *tmp;
@@ -86,11 +72,11 @@ lka_imsg(struct imsgev *iev, struct imsg *imsg)
case IMSG_LKA_MAIL:
ss = imsg->data;
ss->code = 530;
- if (ss->u.path.user[0] == '\0' &&
- ss->u.path.domain[0] == '\0')
+ if (ss->u.maddr.user[0] == '\0' &&
+ ss->u.maddr.domain[0] == '\0')
ss->code = 250;
else
- if (lka_verify_mail(&ss->u.path))
+ if (lka_verify_mail(&ss->u.maddr))
ss->code = 250;
imsg_compose_event(iev, IMSG_LKA_MAIL, 0, 0, -1, ss,
sizeof *ss);
@@ -99,24 +85,21 @@ lka_imsg(struct imsgev *iev, struct imsg *imsg)
case IMSG_LKA_RULEMATCH:
ss = imsg->data;
ss->code = 530;
- rule = ruleset_match(ss->msg.tag, &ss->u.path, &ss->ss);
+ rule = ruleset_match(&ss->envelope);
if (rule) {
ss->code = 250;
- ss->u.path.rule = *rule;
+ ss->envelope.rule = *rule;
+ if (IS_RELAY(*rule))
+ ss->envelope.delivery.type = D_MTA;
+ else
+ ss->envelope.delivery.type = D_MDA;
}
imsg_compose_event(iev, IMSG_LKA_RULEMATCH, 0, 0, -1,
ss, sizeof *ss);
return;
case IMSG_LKA_RCPT:
- ss = imsg->data;
- ss->code = 250;
- path = &ss->u.path;
- s = lka_session_init(ss);
- if (! lka_resolve_path(s, path))
- lka_session_fail(s, ss);
- else
- lka_expand_pickup(s);
+ lka_session(imsg->data);
return;
}
}
@@ -205,46 +188,14 @@ lka_imsg(struct imsgev *iev, struct imsg *imsg)
env->sc_maps = env->sc_maps_reload;
return;
- case IMSG_PARENT_FORWARD_OPEN:
- fwreq = imsg->data;
- skey.id = fwreq->id;
- s = SPLAY_FIND(lkatree, &env->lka_sessions, &skey);
- if (s == NULL)
- fatalx("lka: session missing");
- s->pending--;
- strlcpy(s->path.pw_name, fwreq->pw_name,
- sizeof s->path.pw_name);
- s->path.flags |= F_PATH_FORWARDED;
-
- if (imsg->fd != -1) {
- /* opened .forward okay */
- if (! forwards_get(imsg->fd, &s->expandtree)) {
- s->ss.code = 530;
- s->flags |= F_ERROR;
- }
- close(imsg->fd);
- s->path.flags |= F_PATH_FORWARDED;
- lka_expand_pickup(s);
- } else {
- if (fwreq->status) {
- /* .forward not present */
- path = path_dup(&s->path);
- strlcpy(path->pw_name, fwreq->pw_name,
- sizeof path->pw_name);
- TAILQ_INSERT_TAIL(&s->deliverylist, path, entry);
- lka_expand_pickup(s);
- } else {
- /* opening .forward failed */
- s->ss.code = 530;
- s->flags |= F_ERROR;
- lka_expand_pickup(s);
- }
- }
- return;
-
case IMSG_CTL_VERBOSE:
log_verbose(*(int *)imsg->data);
return;
+
+ case IMSG_PARENT_FORWARD_OPEN:
+ lka_session_forward_reply(imsg->data, imsg->fd);
+ return;
+
}
}
@@ -348,423 +299,11 @@ lka(void)
}
int
-lka_verify_mail(struct path *path)
-{
- return 1;
-}
-
-size_t
-lka_expand(char *buf, size_t len, struct path *path, struct path *sender)
-{
- char *p, *pbuf;
- struct rule r;
- size_t ret, lret = 0;
- struct passwd *pw;
-
- bzero(r.r_value.buffer, MAX_RULEBUFFER_LEN);
- pbuf = r.r_value.buffer;
-
- ret = 0;
- for (p = path->rule.r_value.buffer; *p != '\0';
- ++p, len -= lret, pbuf += lret, ret += lret) {
- if (p == path->rule.r_value.buffer && *p == '~') {
- if (*(p + 1) == '/' || *(p + 1) == '\0') {
- pw = getpwnam(path->pw_name);
- if (pw == NULL)
- return 0;
-
- lret = strlcat(pbuf, pw->pw_dir, len);
- if (lret >= len)
- return 0;
- continue;
- }
-
- if (*(p + 1) != '/') {
- char username[MAXLOGNAME];
- char *delim;
-
- lret = strlcpy(username, p + 1,
- sizeof(username));
- if (lret >= sizeof(username))
- return 0;
-
- delim = strchr(username, '/');
- if (delim == NULL)
- goto copy;
- *delim = '\0';
-
- pw = getpwnam(username);
- if (pw == NULL)
- return 0;
-
- lret = strlcat(pbuf, pw->pw_dir, len);
- if (lret >= len)
- return 0;
- p += strlen(username);
- continue;
- }
- }
- if (*p == '%') {
- char *string, *tmp = p + 1;
- int digit = 0;
-
- if (isdigit((int)*tmp)) {
- digit = 1;
- tmp++;
- }
- switch (*tmp) {
- case 'U':
- string = sender->user;
- break;
- case 'D':
- string = sender->domain;
- break;
- case 'a':
- string = path->user;
- break;
- case 'u':
- string = path->pw_name;
- break;
- case 'd':
- string = path->domain;
- break;
- default:
- goto copy;
- }
-
- if (digit == 1) {
- size_t idx = *(tmp - 1) - '0';
-
- lret = 1;
- if (idx < strlen(string))
- *pbuf++ = string[idx];
- else { /* fail */
- return 0;
- }
-
- p += 2; /* loop only does ++ */
- continue;
- }
- lret = strlcat(pbuf, string, len);
- if (lret >= len)
- return 0;
- p++;
- continue;
- }
-copy:
- lret = 1;
- *pbuf = *p;
- }
-
- /* + 1 to include the NUL byte. */
- memcpy(path->rule.r_value.buffer, r.r_value.buffer, ret + 1);
-
- return ret;
-}
-
-int
-lka_resolve_node(char *tag, struct path *path, struct expandnode *expnode)
-{
- struct path psave = *path;
-
- bzero(path, sizeof(struct path));
-
- switch (expnode->type) {
- case EXPAND_USERNAME:
- log_debug("lka_resolve_node: node is local username: %s",
- expnode->u.username);
- if (strlcpy(path->pw_name, expnode->u.username,
- sizeof(path->pw_name)) >= sizeof(path->pw_name))
- return 0;
-
- if (strlcpy(path->user, expnode->u.username,
- sizeof(path->user)) >= sizeof(path->user))
- return 0;
-
- if (1 || psave.domain[0] == '\0') {
- if (strlcpy(path->domain, env->sc_hostname,
- sizeof(path->domain)) >= sizeof(path->domain))
- return 0;
- }
- else {
- strlcpy(path->domain, psave.domain,
- sizeof(psave.domain));
- }
-
- log_debug("lka_resolve_node: resolved to address: %s@%s",
- path->user, path->domain);
- lka_rcpt_action(tag, path);
- break;
-
- case EXPAND_FILENAME:
- log_debug("lka_resolve_node: node is filename: %s",
- expnode->u.filename);
- path->rule.r_action = A_FILENAME;
- strlcpy(path->u.filename, expnode->u.filename,
- sizeof(path->u.filename));
- break;
-
- case EXPAND_FILTER:
- log_debug("lka_resolve_node: node is filter: %s",
- expnode->u.filter);
- path->rule.r_action = A_EXT;
- strlcpy(path->rule.r_value.buffer, expnode->u.filter + 2,
- sizeof(path->rule.r_value.buffer));
- path->rule.r_value.buffer[strlen(path->rule.r_value.buffer) - 1] = '\0';
- break;
-
- case EXPAND_ADDRESS:
- log_debug("lka_resolve_node: node is address: %s@%s",
- expnode->u.mailaddr.user, expnode->u.mailaddr.domain);
-
- if (strlcpy(path->user, expnode->u.mailaddr.user,
- sizeof(path->user)) >= sizeof(path->user))
- return 0;
-
- if (strlcpy(path->domain, expnode->u.mailaddr.domain,
- sizeof(path->domain)) >= sizeof(path->domain))
- return 0;
-
- lka_rcpt_action(tag, path);
- break;
- case EXPAND_INVALID:
- case EXPAND_INCLUDE:
- fatalx("lka_resolve_node: unexpected type");
- break;
- }
-
- return 1;
-}
-
-void
-lka_expand_pickup(struct lkasession *lkasession)
-{
- int ret;
-
- /* we want to do five iterations of lka_expand_resume() but
- * we need to be interruptible in case lka_expand_resume()
- * has sent an imsg and expects an answer.
- */
- ret = 0;
- while (! (lkasession->flags & F_ERROR) &&
- ! lkasession->pending && lkasession->iterations < 5) {
- ++lkasession->iterations;
- ret = lka_expand_resume(lkasession);
- if (ret == -1) {
- lkasession->ss.code = 530;
- lkasession->flags |= F_ERROR;
- }
-
- if (lkasession->pending || ret <= 0)
- break;
- }
-
- if (lkasession->pending)
- return;
-
- lka_expansion_done(lkasession);
-}
-
-int
-lka_expand_resume(struct lkasession *lkasession)
+lka_verify_mail(struct mailaddr *maddr)
{
- u_int8_t done = 1;
- struct expandnode *expnode = NULL;
- struct path *lkasessionpath = NULL;
- struct path path, *pathp = NULL;
-
- lkasessionpath = &lkasession->path;
- RB_FOREACH(expnode, expandtree, &lkasession->expandtree) {
-
- /* this node has already been expanded, skip*/
- if (expnode->flags & F_EXPAND_DONE)
- continue;
- done = 0;
-
- /* convert node to path, then inherit flags from lkasession */
- if (! lka_resolve_node(lkasession->message.tag, &path, expnode))
- return -1;
- path.flags = lkasessionpath->flags;
-
- /* resolve path, eventually populating expandtree.
- * we need to dup because path may be added to the deliverylist.
- */
- pathp = path_dup(&path);
- if (! lka_resolve_path(lkasession, pathp))
- return -1;
-
- /* decrement refcount on this node and flag it as processed */
- expandtree_decrement_node(&lkasession->expandtree, expnode);
- expnode->flags |= F_EXPAND_DONE;
- }
-
- /* still not done after 5 iterations ? loop detected ... reject */
- if (!done && lkasession->iterations == 5) {
- return -1;
- }
-
- /* we're done expanding, no need for another iteration */
- if (RB_ROOT(&lkasession->expandtree) == NULL || done)
- return 0;
-
return 1;
}
-void
-lka_expansion_done(struct lkasession *lkasession)
-{
- struct envelope message;
- struct path *path;
-
- /* delivery list is empty OR expansion led to an error, reject */
- if (TAILQ_FIRST(&lkasession->deliverylist) == NULL ||
- lkasession->flags & F_ERROR) {
- imsg_compose_event(env->sc_ievs[PROC_MFA], IMSG_LKA_RCPT, 0, 0,
- -1, &lkasession->ss, sizeof(struct submit_status));
- goto done;
- }
-
- /* process the delivery list and submit envelopes to queue */
- message = lkasession->message;
- while ((path = TAILQ_FIRST(&lkasession->deliverylist)) != NULL) {
- lka_expand(path->rule.r_value.buffer,
- sizeof(path->rule.r_value.buffer), path, &message.sender);
- message.recipient = *path;
- queue_submit_envelope(&message);
-
- TAILQ_REMOVE(&lkasession->deliverylist, path, entry);
- free(path);
- }
- queue_commit_envelopes(&message);
-
-done:
- lka_clear_expandtree(&lkasession->expandtree);
- lka_clear_deliverylist(&lkasession->deliverylist);
- lka_session_destroy(lkasession);
-}
-
-int
-lka_resolve_path(struct lkasession *lkasession, struct path *path)
-{
- if (IS_RELAY(*path)) {
- path = path_dup(path);
- path->flags |= F_PATH_RELAY;
- TAILQ_INSERT_TAIL(&lkasession->deliverylist, path, entry);
- return 1;
- }
-
- switch (path->rule.r_condition.c_type) {
- case C_ALL:
- case C_NET:
- case C_DOM: {
- char username[MAX_LOCALPART_SIZE];
- char *sep;
- struct passwd *pw;
-
- lowercase(username, path->user, sizeof(username));
-
- sep = strchr(username, '+');
- if (sep != NULL)
- *sep = '\0';
-
- if (aliases_exist(path->rule.r_amap, username)) {
- path->flags |= F_PATH_ALIAS;
- if (! aliases_get(path->rule.r_amap,
- &lkasession->expandtree, path->user))
- return 0;
- return 1;
- }
-
- if (strlen(username) >= MAXLOGNAME)
- return 0;
-
- path->flags |= F_PATH_ACCOUNT;
- pw = getpwnam(username);
- if (pw == NULL)
- return 0;
-
- (void)strlcpy(path->pw_name, pw->pw_name,
- sizeof(path->pw_name));
-
- if (path->flags & F_PATH_FORWARDED)
- TAILQ_INSERT_TAIL(&lkasession->deliverylist, path, entry);
- else
- lka_request_forwardfile(lkasession, path->pw_name);
-
- return 1;
- }
- case C_VDOM: {
- if (aliases_virtual_exist(path->rule.r_condition.c_map, path)) {
- path->flags |= F_PATH_VIRTUAL;
- if (! aliases_virtual_get(path->rule.r_condition.c_map,
- &lkasession->expandtree, path))
- return 0;
- return 1;
- }
- break;
- }
- default:
- fatalx("lka_resolve_path: unexpected type");
- }
-
- return 0;
-}
-
-static void
-lka_rcpt_action(char *tag, struct path *path)
-{
- struct rule *r;
-
- if (path->domain[0] == '\0')
- (void)strlcpy(path->domain, env->sc_hostname,
- sizeof (path->domain));
-
- r = ruleset_match(tag, path, NULL);
- if (r == NULL) {
- path->rule.r_action = A_RELAY;
- return;
- }
-
- path->rule = *r;
-}
-
-int
-lkasession_cmp(struct lkasession *s1, struct lkasession *s2)
-{
- /*
- * do not return u_int64_t's
- */
- if (s1->id < s2->id)
- return (-1);
-
- if (s1->id > s2->id)
- return (1);
-
- return (0);
-}
-
-static void
-lka_clear_expandtree(struct expandtree *expandtree)
-{
- struct expandnode *expnode;
-
- while ((expnode = RB_ROOT(expandtree)) != NULL) {
- expandtree_remove_node(expandtree, expnode);
- free(expnode);
- }
-}
-
-static void
-lka_clear_deliverylist(struct deliverylist *deliverylist)
-{
- struct path *path;
-
- while ((path = TAILQ_FIRST(deliverylist)) != NULL) {
- TAILQ_REMOVE(deliverylist, path, entry);
- free(path);
- }
-}
-
static int
lka_encode_credentials(char *dst, size_t size, struct map_secret *map_secret)
{
@@ -783,54 +322,3 @@ lka_encode_credentials(char *dst, size_t size, struct map_secret *map_secret)
free(buf);
return 1;
}
-
-static struct lkasession *
-lka_session_init(struct submit_status *ss)
-{
- struct lkasession *lkasession;
-
- lkasession = calloc(1, sizeof(struct lkasession));
- if (lkasession == NULL)
- fatal("lka_session_init: calloc");
-
- lkasession->id = generate_uid();
- lkasession->path = ss->u.path;
- lkasession->message = ss->msg;
- lkasession->ss = *ss;
-
- RB_INIT(&lkasession->expandtree);
- TAILQ_INIT(&lkasession->deliverylist);
- SPLAY_INSERT(lkatree, &env->lka_sessions, lkasession);
-
- return lkasession;
-}
-
-static void
-lka_session_fail(struct lkasession *lkasession, struct submit_status *ss)
-{
- ss->code = 530;
- imsg_compose_event(env->sc_ievs[PROC_MFA], IMSG_LKA_RCPT, 0, 0, -1,
- ss, sizeof(*ss));
- lka_session_destroy(lkasession);
-}
-
-static void
-lka_session_destroy(struct lkasession *lkasession)
-{
- SPLAY_REMOVE(lkatree, &env->lka_sessions, lkasession);
- free(lkasession);
-}
-
-static void
-lka_request_forwardfile(struct lkasession *lkasession, char *username)
-{
- struct forward_req fwreq;
-
- fwreq.id = lkasession->id;
- (void)strlcpy(fwreq.pw_name, username, sizeof(fwreq.pw_name));
- imsg_compose_event(env->sc_ievs[PROC_PARENT], IMSG_PARENT_FORWARD_OPEN, 0, 0, -1,
- &fwreq, sizeof(fwreq));
- ++lkasession->pending;
-}
-
-SPLAY_GENERATE(lkatree, lkasession, nodes, lkasession_cmp);
diff --git a/usr.sbin/smtpd/lka_session.c b/usr.sbin/smtpd/lka_session.c
new file mode 100644
index 00000000000..c2ff1ff5eef
--- /dev/null
+++ b/usr.sbin/smtpd/lka_session.c
@@ -0,0 +1,629 @@
+/* $OpenBSD: lka_session.c,v 1.1 2011/05/16 21:05:51 gilles Exp $ */
+
+/*
+ * Copyright (c) 2011 Gilles Chehade <gilles@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/types.h>
+#include <sys/queue.h>
+#include <sys/tree.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/wait.h>
+
+#include <netinet/in.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <event.h>
+#include <imsg.h>
+#include <pwd.h>
+#include <resolv.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "smtpd.h"
+#include "log.h"
+
+void lka_session(struct submit_status *);
+void lka_session_forward_reply(struct forward_req *, int);
+
+struct lka_session *lka_session_init(struct submit_status *);
+struct lka_session *lka_session_find(u_int64_t);
+struct lka_session *lka_session_xfind(u_int64_t);
+void lka_session_fail(struct lka_session *);
+void lka_session_destroy(struct lka_session *);
+void lka_session_pickup(struct lka_session *, struct envelope *);
+int lka_session_envelope_expand(struct lka_session *, struct envelope *);
+int lka_session_resume(struct lka_session *, struct envelope *);
+void lka_session_done(struct lka_session *);
+size_t lka_session_expand_format(char *, size_t, struct envelope *);
+void lka_session_request_forwardfile(struct lka_session *,
+ struct envelope *, char *);
+void lka_session_deliver(struct lka_session *, struct envelope *);
+int lka_session_resolve_node(struct envelope *, struct expandnode *);
+int lka_session_rcpt_action(struct envelope *);
+struct rule *ruleset_match(struct envelope *);
+
+void
+lka_session(struct submit_status *ss)
+{
+ struct lka_session *lks;
+
+ lks = lka_session_init(ss);
+ if (! lka_session_envelope_expand(lks, &ss->envelope))
+ lka_session_fail(lks);
+ else
+ lka_session_pickup(lks, &ss->envelope);
+}
+
+int
+lka_session_envelope_expand(struct lka_session *lks, struct envelope *ep)
+{
+ struct passwd *pw;
+ char *user;
+ char *sep;
+ char username[MAX_LOCALPART_SIZE];
+
+ /* remote delivery, no need to process further */
+ if (ep->delivery.type == D_MTA) {
+ lka_session_deliver(lks, ep);
+ return 1;
+ }
+
+ switch (ep->rule.r_condition.c_type) {
+ case C_ALL:
+ case C_NET:
+ case C_DOM: {
+ if (ep->delivery.agent.mda.to.user[0] == '\0')
+ user = ep->delivery.rcpt.user;
+ else
+ user = ep->delivery.agent.mda.to.user;
+ lowercase(username, user, sizeof(username));
+
+ /* gilles+hackers@ -> gilles@ */
+ if ((sep = strchr(username, '+')) != NULL)
+ *sep = '\0';
+
+ if (aliases_exist(ep->rule.r_amap, username)) {
+ if (! aliases_get(ep->rule.r_amap,
+ &lks->expandtree, username)) {
+ return 0;
+ }
+ return 1;
+ }
+
+ if ((pw = getpwnam(username)) == NULL)
+ return 0;
+
+ (void)strlcpy(ep->delivery.agent.mda.as_user, pw->pw_name,
+ sizeof (ep->delivery.agent.mda.as_user));
+
+ ep->delivery.type = D_MDA;
+ switch (ep->rule.r_action) {
+ case A_MBOX:
+ ep->delivery.agent.mda.method = A_MBOX;
+ (void)strlcpy(ep->delivery.agent.mda.to.user, pw->pw_name,
+ sizeof (ep->delivery.agent.mda.to.user));
+ break;
+ case A_MAILDIR:
+ case A_FILENAME:
+ case A_EXT:
+ ep->delivery.agent.mda.method = ep->rule.r_action;
+ (void)strlcpy(ep->delivery.agent.mda.to.buffer,
+ ep->rule.r_value.buffer,
+ sizeof (ep->delivery.agent.mda.to.buffer));
+ break;
+ default:
+ fatalx("lka_session_envelope_expand: unexpected rule action");
+ return 0;
+ }
+ lka_session_request_forwardfile(lks, ep, pw->pw_name);
+ return 1;
+ }
+
+ case C_VDOM: {
+ if (aliases_virtual_exist(ep->rule.r_condition.c_map, &ep->delivery.rcpt)) {
+ if (! aliases_virtual_get(ep->rule.r_condition.c_map,
+ &lks->expandtree, &ep->delivery.rcpt))
+ return 0;
+ return 1;
+ }
+ return 0;
+ }
+
+ default:
+ fatalx("lka_session_envelope_expand: unexpected type");
+ return 0;
+ }
+
+ return 0;
+}
+
+void
+lka_session_forward_reply(struct forward_req *fwreq, int fd)
+{
+ struct lka_session *lks;
+ struct envelope *ep;
+
+ lks = lka_session_xfind(fwreq->id);
+ lks->pending--;
+
+ ep = &fwreq->envelope;
+ if (fd != -1) {
+ /* opened .forward okay */
+ if (! forwards_get(fd, &lks->expandtree, fwreq->as_user)) {
+ lks->ss.code = 530;
+ lks->flags |= F_ERROR;
+ }
+ close(fd);
+ lka_session_pickup(lks, ep);
+ return;
+ }
+
+ if (fwreq->status) {
+ /* .forward not present */
+ lka_session_deliver(lks, ep);
+ lka_session_pickup(lks, ep);
+ return;
+ }
+
+ /* opening .forward failed */
+ lks->ss.code = 530;
+ lks->flags |= F_ERROR;
+ lka_session_pickup(lks, ep);
+}
+
+struct lka_session *
+lka_session_init(struct submit_status *ss)
+{
+ struct lka_session *lks;
+
+ lks = calloc(1, sizeof(*lks));
+ if (lks == NULL)
+ fatal("lka_session_init: calloc");
+
+ lks->id = generate_uid();
+ lks->ss = *ss;
+ lks->ss.code = 250;
+
+ RB_INIT(&lks->expandtree);
+ TAILQ_INIT(&lks->deliverylist);
+ SPLAY_INSERT(lkatree, &env->lka_sessions, lks);
+
+ return lks;
+}
+
+void
+lka_session_pickup(struct lka_session *lks, struct envelope *ep)
+{
+ int ret;
+
+ /* we want to do five iterations of lka_session_resume() but
+ * we need to be interruptible in case lka_session_resume()
+ * has sent an imsg and expects an answer.
+ */
+ ret = 0;
+ while (! (lks->flags & F_ERROR) &&
+ ! lks->pending && lks->iterations < 5) {
+ ++lks->iterations;
+ ret = lka_session_resume(lks, ep);
+ if (ret == -1) {
+ lks->ss.code = 530;
+ lks->flags |= F_ERROR;
+ }
+
+ if (lks->pending || ret <= 0)
+ break;
+ }
+
+ if (lks->pending)
+ return;
+
+ lka_session_done(lks);
+}
+
+int
+lka_session_resume(struct lka_session *lks, struct envelope *ep)
+{
+ struct expandnode *xn;
+ u_int8_t done = 1;
+
+ RB_FOREACH(xn, expandtree, &lks->expandtree) {
+
+ /* this node has already been expanded, skip */
+ if (xn->flags & F_EXPAND_DONE)
+ continue;
+ done = 0;
+
+ switch (lka_session_resolve_node(ep, xn)) {
+ case 0:
+ if (! lka_session_envelope_expand(lks, ep))
+ return -1;
+ break;
+ case 1:
+ lka_session_deliver(lks, ep);
+ break;
+ default:
+ return -1;
+ }
+
+ /* decrement refcount on this node and flag it as processed */
+ expandtree_decrement_node(&lks->expandtree, xn);
+ xn->flags |= F_EXPAND_DONE;
+ }
+
+ /* still not done after 5 iterations ? loop detected ... reject */
+ if (!done && lks->iterations == 5)
+ return -1;
+
+ /* we're done expanding, no need for another iteration */
+ if (RB_ROOT(&lks->expandtree) == NULL || done)
+ return 0;
+
+ return 1;
+}
+
+void
+lka_session_done(struct lka_session *lks)
+{
+ struct envelope *ep;
+
+ /* delivery list is empty OR expansion led to an error, reject */
+ if (TAILQ_FIRST(&lks->deliverylist) == NULL) {
+ log_info("lka_session_done: expansion led to empty delivery list");
+ lks->flags |= F_ERROR;
+ }
+ if (lks->flags & F_ERROR)
+ goto done;
+
+ /* process the delivery list and submit envelopes to queue */
+ while ((ep = TAILQ_FIRST(&lks->deliverylist)) != NULL) {
+ queue_submit_envelope(ep);
+ TAILQ_REMOVE(&lks->deliverylist, ep, entry);
+ free(ep);
+ }
+ queue_commit_envelopes(&lks->ss.envelope);
+
+done:
+ if (lks->flags & F_ERROR) {
+ lks->ss.code = 530;
+ imsg_compose_event(env->sc_ievs[PROC_MFA], IMSG_LKA_RCPT, 0, 0,
+ -1, &lks->ss, sizeof(struct submit_status));
+ }
+ lka_session_destroy(lks);
+}
+
+struct lka_session *
+lka_session_find(u_int64_t id)
+{
+ struct lka_session key;
+
+ key.id = id;
+ return SPLAY_FIND(lkatree, &env->lka_sessions, &key);
+}
+
+struct lka_session *
+lka_session_xfind(u_int64_t id)
+{
+ struct lka_session *lks;
+
+ lks = lka_session_find(id);
+ if (lks == NULL)
+ fatalx("lka_session_xfind: lka session missing");
+
+ return lks;
+}
+
+void
+lka_session_fail(struct lka_session *lks)
+{
+ lks->ss.code = 530;
+ imsg_compose_event(env->sc_ievs[PROC_MFA], IMSG_LKA_RCPT, 0, 0, -1,
+ &lks->ss, sizeof(lks->ss));
+ lka_session_destroy(lks);
+}
+
+void
+lka_session_destroy(struct lka_session *lks)
+{
+ struct envelope *ep;
+ struct expandnode *xn;
+
+ while ((ep = TAILQ_FIRST(&lks->deliverylist)) != NULL) {
+ TAILQ_REMOVE(&lks->deliverylist, ep, entry);
+ free(ep);
+ }
+
+ while ((xn = RB_ROOT(&lks->expandtree)) != NULL) {
+ RB_REMOVE(expandtree, &lks->expandtree, xn);
+ free(xn);
+ }
+
+ SPLAY_REMOVE(lkatree, &env->lka_sessions, lks);
+ free(lks);
+}
+
+void
+lka_session_deliver(struct lka_session *lks, struct envelope *ep)
+{
+ struct envelope *new_ep;
+ struct delivery_mda *d_mda;
+
+ new_ep = calloc(1, sizeof (*ep));
+ if (new_ep == NULL)
+ fatal("lka_session_deliver: calloc");
+ *new_ep = *ep;
+ if (new_ep->delivery.type == D_MDA) {
+ d_mda = &new_ep->delivery.agent.mda;
+ if (d_mda->method == A_INVALID)
+ fatalx("lka_session_deliver: mda method == A_INVALID");
+
+ switch (d_mda->method) {
+ case A_MAILDIR:
+ case A_FILENAME:
+ case A_EXT: {
+ char *buf = d_mda->to.buffer;
+ size_t bufsz = sizeof(d_mda->to.buffer);
+ if (! lka_session_expand_format(buf, bufsz, new_ep))
+ lks->flags |= F_ERROR;
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ TAILQ_INSERT_TAIL(&lks->deliverylist, new_ep, entry);
+}
+
+int
+lka_session_resolve_node(struct envelope *ep, struct expandnode *xn)
+{
+ struct delivery *dlv;
+
+ dlv = &ep->delivery;
+ bzero(&dlv->agent, sizeof (dlv->agent));
+
+ switch (xn->type) {
+ case EXPAND_INVALID:
+ case EXPAND_INCLUDE:
+ fatalx("lka_session_resolve_node: unexpected type");
+ break;
+
+ case EXPAND_ADDRESS:
+ log_debug("lka_resolve_node: node is address: %s@%s",
+ xn->u.mailaddr.user, xn->u.mailaddr.domain);
+ dlv->rcpt = xn->u.mailaddr;
+
+ /* evaluation of ruleset assumes local source
+ * since we're expanding on already accepted
+ * source.
+ */
+ dlv->flags |= DF_INTERNAL;
+ if (! lka_session_rcpt_action(ep))
+ return -1;
+ return 0;
+
+ case EXPAND_USERNAME:
+ log_debug("lka_resolve_node: node is local username: %s",
+ xn->u.user);
+ dlv->type = D_MDA;
+ dlv->agent.mda.to = xn->u;
+
+ /* if expansion of a user results in same user ... deliver */
+ if (strcmp(xn->u.user, xn->as_user) == 0)
+ break;
+
+ /* otherwise rewrite delivery user with expansion result */
+ (void)strlcpy(dlv->agent.mda.to.user, xn->u.user,
+ sizeof (dlv->agent.mda.to.user));
+ (void)strlcpy(dlv->agent.mda.as_user, xn->u.user,
+ sizeof (dlv->agent.mda.as_user));
+ return 0;
+
+ case EXPAND_FILENAME:
+ log_debug("lka_resolve_node: node is filename: %s",
+ xn->u.buffer);
+ dlv->type = D_MDA;
+ dlv->agent.mda.to = xn->u;
+ dlv->agent.mda.method = A_FILENAME;
+ (void)strlcpy(dlv->agent.mda.as_user, xn->as_user,
+ sizeof (dlv->agent.mda.as_user));
+ break;
+
+ case EXPAND_FILTER:
+ log_debug("lka_resolve_node: node is filter: %s",
+ xn->u.buffer);
+ dlv->type = D_MDA;
+ dlv->agent.mda.to = xn->u;
+ dlv->agent.mda.method = A_EXT;
+ (void)strlcpy(dlv->agent.mda.as_user, xn->as_user,
+ sizeof (dlv->agent.mda.as_user));
+ break;
+ }
+
+ return 1;
+}
+
+size_t
+lka_session_expand_format(char *buf, size_t len, struct envelope *ep)
+{
+ char *p, *pbuf;
+ size_t ret, lret = 0;
+ struct passwd *pw;
+ char lbuffer[MAX_RULEBUFFER_LEN];
+ struct delivery *dlv = &ep->delivery;
+
+ bzero(lbuffer, sizeof (lbuffer));
+ pbuf = lbuffer;
+
+ ret = 0;
+ for (p = buf; *p != '\0';
+ ++p, len -= lret, pbuf += lret, ret += lret) {
+ if (p == buf && *p == '~') {
+ if (*(p + 1) == '/' || *(p + 1) == '\0') {
+ pw = getpwnam(dlv->agent.mda.as_user);
+ if (pw == NULL)
+ return 0;
+
+ lret = strlcat(pbuf, pw->pw_dir, len);
+ if (lret >= len)
+ return 0;
+ continue;
+ }
+
+ if (*(p + 1) != '/') {
+ char username[MAXLOGNAME];
+ char *delim;
+
+ lret = strlcpy(username, p + 1,
+ sizeof(username));
+ if (lret >= sizeof(username))
+ return 0;
+
+ delim = strchr(username, '/');
+ if (delim == NULL)
+ goto copy;
+ *delim = '\0';
+
+ pw = getpwnam(username);
+ if (pw == NULL)
+ return 0;
+
+ lret = strlcat(pbuf, pw->pw_dir, len);
+ if (lret >= len)
+ return 0;
+ p += strlen(username);
+ continue;
+ }
+ }
+ if (*p == '%') {
+ char *string, *tmp = p + 1;
+ int digit = 0;
+
+ if (isdigit((int)*tmp)) {
+ digit = 1;
+ tmp++;
+ }
+ switch (*tmp) {
+ case 'U':
+ string = dlv->from.user;
+ break;
+ case 'D':
+ string = dlv->from.domain;
+ break;
+ case 'a':
+ string = dlv->agent.mda.as_user;
+ break;
+ case 'u':
+ string = dlv->rcpt.domain;
+ break;
+ case 'd':
+ string = dlv->rcpt.domain;
+ break;
+ default:
+ goto copy;
+ }
+
+ if (digit == 1) {
+ size_t idx = *(tmp - 1) - '0';
+
+ lret = 1;
+ if (idx < strlen(string))
+ *pbuf++ = string[idx];
+ else { /* fail */
+ return 0;
+ }
+
+ p += 2; /* loop only does ++ */
+ continue;
+ }
+ lret = strlcat(pbuf, string, len);
+ if (lret >= len)
+ return 0;
+ p++;
+ continue;
+ }
+copy:
+ lret = 1;
+ *pbuf = *p;
+ }
+
+ /* + 1 to include the NUL byte. */
+ memcpy(buf, lbuffer, ret + 1);
+
+ return ret;
+}
+
+int
+lka_session_rcpt_action(struct envelope *ep)
+{
+ struct rule *r;
+
+ r = ruleset_match(ep);
+ if (r == NULL) {
+ ep->delivery.type = D_MTA;
+ return 0;
+ }
+
+ ep->rule = *r;
+ switch (ep->rule.r_action) {
+ case A_MBOX:
+ case A_MAILDIR:
+ case A_FILENAME:
+ case A_EXT:
+ ep->delivery.type = D_MDA;
+ break;
+ default:
+ ep->delivery.type = D_MTA;
+ }
+
+ return 1;
+}
+
+void
+lka_session_request_forwardfile(struct lka_session *lks,
+ struct envelope *ep, char *as_user)
+{
+ struct forward_req fwreq;
+
+ fwreq.id = lks->id;
+ fwreq.envelope = *ep;
+ (void)strlcpy(fwreq.as_user, as_user, sizeof(fwreq.as_user));
+ imsg_compose_event(env->sc_ievs[PROC_PARENT],
+ IMSG_PARENT_FORWARD_OPEN, 0, 0, -1, &fwreq, sizeof(fwreq));
+ ++lks->pending;
+}
+
+int
+lka_session_cmp(struct lka_session *s1, struct lka_session *s2)
+{
+ /*
+ * do not return u_int64_t's
+ */
+ if (s1->id < s2->id)
+ return -1;
+
+ if (s1->id > s2->id)
+ return 1;
+
+ return 0;
+}
+
+
+SPLAY_GENERATE(lkatree, lka_session, nodes, lka_session_cmp);
diff --git a/usr.sbin/smtpd/mda.c b/usr.sbin/smtpd/mda.c
index 012095d2bb1..9b581457411 100644
--- a/usr.sbin/smtpd/mda.c
+++ b/usr.sbin/smtpd/mda.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mda.c,v 1.55 2011/05/01 12:57:11 eric Exp $ */
+/* $OpenBSD: mda.c,v 1.56 2011/05/16 21:05:51 gilles Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
@@ -51,7 +51,9 @@ mda_imsg(struct imsgev *iev, struct imsg *imsg)
char output[128], *error, *parent_error;
struct deliver deliver;
struct mda_session *s;
- struct path *path;
+ struct delivery *d;
+ struct delivery_mda *d_mda;
+ struct mailaddr *maddr;
if (iev->proc == PROC_QUEUE) {
switch (imsg->hdr.type) {
@@ -62,7 +64,7 @@ mda_imsg(struct imsgev *iev, struct imsg *imsg)
fatal(NULL);
msgbuf_init(&s->w);
s->msg = *(struct envelope *)imsg->data;
- s->msg.status = S_MESSAGE_TEMPFAILURE;
+ s->msg.delivery.status = DS_TEMPFAILURE;
s->id = mda_id++;
s->datafp = fdopen(imsg->fd, "r");
if (s->datafp == NULL)
@@ -70,44 +72,46 @@ mda_imsg(struct imsgev *iev, struct imsg *imsg)
LIST_INSERT_HEAD(&env->mda_sessions, s, entry);
/* request parent to fork a helper process */
- path = &s->msg.recipient;
- switch (path->rule.r_action) {
+ d = &s->msg.delivery;
+ d_mda = &s->msg.delivery.agent.mda;
+ switch (d_mda->method) {
case A_EXT:
deliver.mode = A_EXT;
- strlcpy(deliver.user, path->pw_name,
- sizeof deliver.user);
- strlcpy(deliver.to, path->rule.r_value.buffer,
+ strlcpy(deliver.user, d_mda->as_user,
+ sizeof (deliver.user));
+ strlcpy(deliver.to, d_mda->to.buffer,
sizeof deliver.to);
break;
-
+
case A_MBOX:
deliver.mode = A_EXT;
strlcpy(deliver.user, "root",
- sizeof deliver.user);
- snprintf(deliver.to, sizeof deliver.to,
+ sizeof (deliver.user));
+ snprintf(deliver.to, sizeof (deliver.to),
"%s -f %s@%s %s", PATH_MAILLOCAL,
- s->msg.sender.user, s->msg.sender.domain,
- path->pw_name);
+ d->from.user,
+ d->from.domain,
+ d_mda->to.user);
break;
case A_MAILDIR:
deliver.mode = A_MAILDIR;
- strlcpy(deliver.user, path->pw_name,
+ strlcpy(deliver.user, d_mda->as_user,
sizeof deliver.user);
- strlcpy(deliver.to, path->rule.r_value.buffer,
+ strlcpy(deliver.to, d_mda->to.buffer,
sizeof deliver.to);
break;
case A_FILENAME:
deliver.mode = A_FILENAME;
- /* XXX: unconditional SMTPD_USER is wrong. */
- strlcpy(deliver.user, SMTPD_USER,
+ strlcpy(deliver.user, d_mda->as_user,
sizeof deliver.user);
- strlcpy(deliver.to, path->u.filename,
+ strlcpy(deliver.to, d_mda->to.buffer,
sizeof deliver.to);
break;
default:
+ log_debug("mda: unknown rule action: %d", d_mda->method);
fatalx("mda: unknown rule action");
}
@@ -189,10 +193,10 @@ mda_imsg(struct imsgev *iev, struct imsg *imsg)
/* update queue entry */
if (error == NULL)
- s->msg.status = S_MESSAGE_ACCEPTED;
+ s->msg.delivery.status = DS_ACCEPTED;
else
- strlcpy(s->msg.session_errorline, error,
- sizeof s->msg.session_errorline);
+ strlcpy(s->msg.delivery.errorline, error,
+ sizeof s->msg.delivery.errorline);
imsg_compose_event(env->sc_ievs[PROC_QUEUE],
IMSG_QUEUE_MESSAGE_UPDATE, 0, 0, -1, &s->msg,
sizeof s->msg);
@@ -203,18 +207,18 @@ mda_imsg(struct imsgev *iev, struct imsg *imsg)
* lka may need to be changed to present data in more
* unified way.
*/
- if (s->msg.recipient.rule.r_action == A_MAILDIR ||
- s->msg.recipient.rule.r_action == A_MBOX)
- path = &s->msg.recipient;
+ if (s->msg.rule.r_action == A_MAILDIR ||
+ s->msg.rule.r_action == A_MBOX)
+ maddr = &s->msg.delivery.rcpt;
else
- path = &s->msg.session_rcpt;
+ maddr = &s->msg.delivery.rcpt_orig;
/* log status */
if (error && asprintf(&error, "Error (%s)", error) < 0)
fatal("mda: asprintf");
log_info("%016llx: to=<%s@%s>, delay=%d, stat=%s",
- s->msg.evpid, path->user, path->domain,
- time(NULL) - s->msg.creation,
+ s->msg.delivery.id, maddr->user, maddr->domain,
+ time(NULL) - s->msg.delivery.creation,
error ? error : "Sent");
free(error);
@@ -331,14 +335,16 @@ mda_store(struct mda_session *s)
struct ibuf *buf;
int len;
- if (s->msg.sender.user[0] && s->msg.sender.domain[0])
+ if (s->msg.delivery.from.user[0] && s->msg.delivery.from.domain[0])
/* XXX: remove user provided Return-Path, if any */
len = asprintf(&p, "Return-Path: %s@%s\nDelivered-To: %s@%s\n",
- s->msg.sender.user, s->msg.sender.domain,
- s->msg.session_rcpt.user, s->msg.session_rcpt.domain);
+ s->msg.delivery.from.user, s->msg.delivery.from.domain,
+ s->msg.delivery.rcpt_orig.user,
+ s->msg.delivery.rcpt_orig.domain);
else
len = asprintf(&p, "Delivered-To: %s@%s\n",
- s->msg.session_rcpt.user, s->msg.session_rcpt.domain);
+ s->msg.delivery.rcpt_orig.user,
+ s->msg.delivery.rcpt_orig.domain);
if (len == -1)
fatal("mda_store: asprintf");
diff --git a/usr.sbin/smtpd/mfa.c b/usr.sbin/smtpd/mfa.c
index 945227f591f..a0ddf14cc20 100644
--- a/usr.sbin/smtpd/mfa.c
+++ b/usr.sbin/smtpd/mfa.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mfa.c,v 1.58 2011/05/01 12:57:11 eric Exp $ */
+/* $OpenBSD: mfa.c,v 1.59 2011/05/16 21:05:52 gilles Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
@@ -167,23 +167,23 @@ mfa(void)
}
void
-mfa_test_mail(struct envelope *m)
+mfa_test_mail(struct envelope *e)
{
struct submit_status ss;
- ss.id = m->id;
+ ss.id = e->session_id;
ss.code = 530;
- ss.u.path = m->sender;
+ ss.u.maddr = e->delivery.from;
- if (mfa_strip_source_route(ss.u.path.user, sizeof(ss.u.path.user)))
+ if (mfa_strip_source_route(ss.u.maddr.user, sizeof(ss.u.maddr.user)))
goto refuse;
- if (! valid_localpart(ss.u.path.user) ||
- ! valid_domainpart(ss.u.path.domain)) {
+ if (! valid_localpart(ss.u.maddr.user) ||
+ ! valid_domainpart(ss.u.maddr.domain)) {
/*
* "MAIL FROM:<>" is the exception we allow.
*/
- if (!(ss.u.path.user[0] == '\0' && ss.u.path.domain[0] == '\0'))
+ if (!(ss.u.maddr.user[0] == '\0' && ss.u.maddr.domain[0] == '\0'))
goto refuse;
}
@@ -202,27 +202,24 @@ accept:
}
static void
-mfa_test_rcpt(struct envelope *m)
+mfa_test_rcpt(struct envelope *e)
{
struct submit_status ss;
- ss.id = m->session_id;
+ ss.id = e->session_id;
ss.code = 530;
- ss.u.path = m->session_rcpt;
- ss.ss = m->session_ss;
- ss.msg = *m;
- ss.msg.recipient = m->session_rcpt;
- ss.flags = m->flags;
-
- mfa_strip_source_route(ss.u.path.user, sizeof(ss.u.path.user));
-
- if (! valid_localpart(ss.u.path.user) ||
- ! valid_domainpart(ss.u.path.domain))
+ ss.u.maddr = e->delivery.rcpt_orig;
+ ss.ss = e->delivery.ss;
+ ss.envelope = *e;
+ ss.envelope.delivery.rcpt = e->delivery.rcpt_orig;
+ ss.flags = e->delivery.flags;
+
+ mfa_strip_source_route(ss.u.maddr.user, sizeof(ss.u.maddr.user));
+
+ if (! valid_localpart(ss.u.maddr.user) ||
+ ! valid_domainpart(ss.u.maddr.domain))
goto refuse;
- if (ss.flags & F_MESSAGE_AUTHENTICATED)
- ss.u.path.flags |= F_PATH_AUTHENTICATED;
-
imsg_compose_event(env->sc_ievs[PROC_LKA], IMSG_LKA_RULEMATCH, 0, 0, -1,
&ss, sizeof(ss));
@@ -240,8 +237,8 @@ mfa_test_rcpt_resume(struct submit_status *ss) {
return;
}
- ss->msg.recipient = ss->u.path;
- ss->msg.expire = ss->msg.recipient.rule.r_qexpire;
+ ss->envelope.delivery.rcpt = ss->u.maddr;
+ ss->envelope.delivery.expire = ss->envelope.rule.r_qexpire;
imsg_compose_event(env->sc_ievs[PROC_LKA], IMSG_LKA_RCPT, 0, 0, -1,
ss, sizeof(*ss));
}
diff --git a/usr.sbin/smtpd/mta.c b/usr.sbin/smtpd/mta.c
index 07deac0507a..593ec150b89 100644
--- a/usr.sbin/smtpd/mta.c
+++ b/usr.sbin/smtpd/mta.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mta.c,v 1.105 2011/05/01 12:57:11 eric Exp $ */
+/* $OpenBSD: mta.c,v 1.106 2011/05/16 21:05:52 gilles Exp $ */
/*
* Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org>
@@ -58,7 +58,7 @@ mta_imsg(struct imsgev *iev, struct imsg *imsg)
struct ramqueue_batch *rq_batch;
struct mta_session *s;
struct mta_relay *relay;
- struct envelope *m;
+ struct envelope *e;
struct secret *secret;
struct dns *dns;
struct ssl *ssl;
@@ -96,6 +96,8 @@ mta_imsg(struct imsgev *iev, struct imsg *imsg)
}
/* use auth? */
+ log_debug("host: %s", rq_batch->rule.r_value.relayhost.hostname);
+ log_debug("flags: %d", rq_batch->rule.r_value.relayhost.flags);
if ((rq_batch->rule.r_value.relayhost.flags & F_SSL) &&
(rq_batch->rule.r_value.relayhost.flags & F_AUTH)) {
s->flags |= MTA_USE_AUTH;
@@ -126,21 +128,21 @@ mta_imsg(struct imsgev *iev, struct imsg *imsg)
case IMSG_BATCH_APPEND:
- m = imsg->data;
- s = mta_lookup(m->batch_id);
- m = malloc(sizeof *m);
- if (m == NULL)
+ e = imsg->data;
+ s = mta_lookup(e->batch_id);
+ e = malloc(sizeof *e);
+ if (e == NULL)
fatal(NULL);
- *m = *(struct envelope *)imsg->data;
- strlcpy(m->session_errorline, "000 init",
- sizeof(m->session_errorline));
+ *e = *(struct envelope *)imsg->data;
+ strlcpy(e->delivery.errorline, "000 init",
+ sizeof(e->delivery.errorline));
if (s->host == NULL) {
- s->host = strdup(m->recipient.domain);
+ s->host = strdup(e->delivery.rcpt.domain);
if (s->host == NULL)
fatal("strdup");
}
- TAILQ_INSERT_TAIL(&s->recipients, m, entry);
+ TAILQ_INSERT_TAIL(&s->recipients, e, entry);
return;
case IMSG_BATCH_CLOSE:
@@ -337,7 +339,7 @@ mta_enter_state(struct mta_session *s, int newstate, void *p)
struct secret secret;
struct mta_relay *relay;
struct sockaddr *sa;
- struct envelope *m;
+ struct envelope *e;
struct smtp_client *pcb;
int max_reuse;
@@ -475,17 +477,17 @@ mta_enter_state(struct mta_session *s, int newstate, void *p)
client_auth(pcb, s->secret);
/* set envelope sender */
- m = TAILQ_FIRST(&s->recipients);
- if (m->sender.user[0] && m->sender.domain[0])
- client_sender(pcb, "%s@%s", m->sender.user,
- m->sender.domain);
+ e = TAILQ_FIRST(&s->recipients);
+ if (e->delivery.from.user[0] && e->delivery.from.domain[0])
+ client_sender(pcb, "%s@%s", e->delivery.from.user,
+ e->delivery.from.domain);
else
client_sender(pcb, "");
/* set envelope recipients */
- TAILQ_FOREACH(m, &s->recipients, entry)
- client_rcpt(pcb, m, "%s@%s", m->recipient.user,
- m->recipient.domain);
+ TAILQ_FOREACH(e, &s->recipients, entry)
+ client_rcpt(pcb, e, "%s@%s", e->delivery.rcpt.user,
+ e->delivery.rcpt.domain);
s->pcb = pcb;
event_set(&s->ev, s->fd, EV_READ|EV_WRITE, mta_event, s);
@@ -498,8 +500,8 @@ mta_enter_state(struct mta_session *s, int newstate, void *p)
*/
/* update queue status */
- while ((m = TAILQ_FIRST(&s->recipients)))
- mta_message_done(s, m);
+ while ((e = TAILQ_FIRST(&s->recipients)))
+ mta_message_done(s, e);
imsg_compose_event(env->sc_ievs[PROC_QUEUE],
IMSG_BATCH_DONE, 0, 0, -1, NULL, 0);
@@ -648,7 +650,7 @@ static void
mta_status(struct mta_session *s, const char *fmt, ...)
{
char *status;
- struct envelope *m, *next;
+ struct envelope *e, *next;
va_list ap;
va_start(ap, fmt);
@@ -656,16 +658,16 @@ mta_status(struct mta_session *s, const char *fmt, ...)
fatal("vasprintf");
va_end(ap);
- for (m = TAILQ_FIRST(&s->recipients); m; m = next) {
- next = TAILQ_NEXT(m, entry);
+ for (e = TAILQ_FIRST(&s->recipients); e; e = next) {
+ next = TAILQ_NEXT(e, entry);
/* save new status */
- mta_message_status(m, status);
+ mta_message_status(e, status);
/* remove queue entry */
if (*status == '2' || *status == '5' || *status == '6') {
- mta_message_log(s, m);
- mta_message_done(s, m);
+ mta_message_log(s, e);
+ mta_message_done(s, e);
}
}
@@ -673,31 +675,31 @@ mta_status(struct mta_session *s, const char *fmt, ...)
}
static void
-mta_message_status(struct envelope *m, char *status)
+mta_message_status(struct envelope *e, char *status)
{
/*
* Previous delivery attempts might have assigned an errorline of
* higher status (eg. 5yz is of higher status than 4yz), so check
* this before deciding to overwrite existing status with a new one.
*/
- if (*status != '2' && strncmp(m->session_errorline, status, 3) > 0)
+ if (*status != '2' && strncmp(e->delivery.errorline, status, 3) > 0)
return;
/* change status */
- log_debug("mta: new status for %s@%s: %s", m->recipient.user,
- m->recipient.domain, status);
- strlcpy(m->session_errorline, status, sizeof(m->session_errorline));
+ log_debug("mta: new status for %s@%s: %s", e->delivery.rcpt.user,
+ e->delivery.rcpt.domain, status);
+ strlcpy(e->delivery.errorline, status, sizeof(e->delivery.errorline));
}
static void
-mta_message_log(struct mta_session *s, struct envelope *m)
+mta_message_log(struct mta_session *s, struct envelope *e)
{
struct mta_relay *relay = TAILQ_FIRST(&s->relays);
- char *status = m->session_errorline;
+ char *status = e->delivery.errorline;
log_info("%016llx: to=<%s@%s>, delay=%d, relay=%s [%s], stat=%s (%s)",
- m->evpid, m->recipient.user,
- m->recipient.domain, time(NULL) - m->creation,
+ e->delivery.id, e->delivery.rcpt.user,
+ e->delivery.rcpt.domain, time(NULL) - e->delivery.creation,
relay ? relay->fqdn : "(none)",
relay ? ss_to_text(&relay->sa) : "",
*status == '2' ? "Sent" :
@@ -707,24 +709,24 @@ mta_message_log(struct mta_session *s, struct envelope *m)
}
static void
-mta_message_done(struct mta_session *s, struct envelope *m)
+mta_message_done(struct mta_session *s, struct envelope *e)
{
- switch (m->session_errorline[0]) {
+ switch (e->delivery.errorline[0]) {
case '6':
case '5':
- m->status = S_MESSAGE_PERMFAILURE;
+ e->delivery.status = DS_PERMFAILURE;
break;
case '2':
- m->status = S_MESSAGE_ACCEPTED;
+ e->delivery.status = DS_ACCEPTED;
break;
default:
- m->status = S_MESSAGE_TEMPFAILURE;
+ e->delivery.status = DS_TEMPFAILURE;
break;
}
imsg_compose_event(env->sc_ievs[PROC_QUEUE],
- IMSG_QUEUE_MESSAGE_UPDATE, 0, 0, -1, m, sizeof(*m));
- TAILQ_REMOVE(&s->recipients, m, entry);
- free(m);
+ IMSG_QUEUE_MESSAGE_UPDATE, 0, 0, -1, e, sizeof(*e));
+ TAILQ_REMOVE(&s->recipients, e, entry);
+ free(e);
}
static void
@@ -737,12 +739,12 @@ static void
mta_request_datafd(struct mta_session *s)
{
struct ramqueue_batch rq_batch;
- struct envelope *m;
+ struct envelope *e;
- m = TAILQ_FIRST(&s->recipients);
+ e = TAILQ_FIRST(&s->recipients);
rq_batch.b_id = s->id;
- rq_batch.msgid = evpid_to_msgid(m->evpid);
+ rq_batch.msgid = evpid_to_msgid(e->delivery.id);
imsg_compose_event(env->sc_ievs[PROC_QUEUE], IMSG_QUEUE_MESSAGE_FD,
0, 0, -1, &rq_batch, sizeof(rq_batch));
}
diff --git a/usr.sbin/smtpd/queue.c b/usr.sbin/smtpd/queue.c
index 1326f8606ab..0362fc0a852 100644
--- a/usr.sbin/smtpd/queue.c
+++ b/usr.sbin/smtpd/queue.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: queue.c,v 1.103 2011/05/01 12:57:11 eric Exp $ */
+/* $OpenBSD: queue.c,v 1.104 2011/05/16 21:05:52 gilles Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
@@ -46,19 +46,19 @@ static void
queue_imsg(struct imsgev *iev, struct imsg *imsg)
{
struct submit_status ss;
- struct envelope *m;
+ struct envelope *e;
struct ramqueue_batch *rq_batch;
int fd, ret;
if (iev->proc == PROC_SMTP) {
- m = imsg->data;
+ e = imsg->data;
switch (imsg->hdr.type) {
case IMSG_QUEUE_CREATE_MESSAGE:
- ss.id = m->session_id;
+ ss.id = e->session_id;
ss.code = 250;
ss.u.msgid = 0;
- if (m->flags & F_MESSAGE_ENQUEUED)
+ if (e->delivery.flags & DF_ENQUEUED)
ret = queue_message_create(Q_ENQUEUE, &ss.u.msgid);
else
ret = queue_message_create(Q_INCOMING, &ss.u.msgid);
@@ -69,21 +69,21 @@ queue_imsg(struct imsgev *iev, struct imsg *imsg)
return;
case IMSG_QUEUE_REMOVE_MESSAGE:
- if (m->flags & F_MESSAGE_ENQUEUED)
- queue_message_purge(Q_ENQUEUE, evpid_to_msgid(m->evpid));
+ if (e->delivery.flags & DF_ENQUEUED)
+ queue_message_purge(Q_ENQUEUE, evpid_to_msgid(e->delivery.id));
else
- queue_message_purge(Q_INCOMING, evpid_to_msgid(m->evpid));
+ queue_message_purge(Q_INCOMING, evpid_to_msgid(e->delivery.id));
return;
case IMSG_QUEUE_COMMIT_MESSAGE:
- ss.id = m->session_id;
- if (m->flags & F_MESSAGE_ENQUEUED) {
- if (queue_message_commit(Q_ENQUEUE, evpid_to_msgid(m->evpid)))
+ ss.id = e->session_id;
+ if (e->delivery.flags & DF_ENQUEUED) {
+ if (queue_message_commit(Q_ENQUEUE, evpid_to_msgid(e->delivery.id)))
env->stats->queue.inserts_local++;
else
ss.code = 421;
} else {
- if (queue_message_commit(Q_INCOMING, evpid_to_msgid(m->evpid)))
+ if (queue_message_commit(Q_INCOMING, evpid_to_msgid(e->delivery.id)))
env->stats->queue.inserts_remote++;
else
ss.code = 421;
@@ -97,11 +97,11 @@ queue_imsg(struct imsgev *iev, struct imsg *imsg)
return;
case IMSG_QUEUE_MESSAGE_FILE:
- ss.id = m->session_id;
- if (m->flags & F_MESSAGE_ENQUEUED)
- fd = queue_message_fd_rw(Q_ENQUEUE, evpid_to_msgid(m->evpid));
+ ss.id = e->session_id;
+ if (e->delivery.flags & DF_ENQUEUED)
+ fd = queue_message_fd_rw(Q_ENQUEUE, evpid_to_msgid(e->delivery.id));
else
- fd = queue_message_fd_rw(Q_INCOMING, evpid_to_msgid(m->evpid));
+ fd = queue_message_fd_rw(Q_INCOMING, evpid_to_msgid(e->delivery.id));
if (fd == -1)
ss.code = 421;
imsg_compose_event(iev, IMSG_QUEUE_MESSAGE_FILE, 0, 0, fd,
@@ -115,23 +115,17 @@ queue_imsg(struct imsgev *iev, struct imsg *imsg)
}
if (iev->proc == PROC_LKA) {
- m = imsg->data;
+ e = imsg->data;
switch (imsg->hdr.type) {
case IMSG_QUEUE_SUBMIT_ENVELOPE:
- m->id = generate_uid();
- ss.id = m->session_id;
-
- if (IS_MAILBOX(m->recipient) || IS_EXT(m->recipient))
- m->type = T_MDA_MESSAGE;
- else
- m->type = T_MTA_MESSAGE;
+ ss.id = e->session_id;
/* Write to disk */
- if (m->flags & F_MESSAGE_ENQUEUED)
- ret = queue_envelope_create(Q_ENQUEUE, m);
+ if (e->delivery.flags & DF_ENQUEUED)
+ ret = queue_envelope_create(Q_ENQUEUE, e);
else
- ret = queue_envelope_create(Q_INCOMING, m);
+ ret = queue_envelope_create(Q_INCOMING, e);
if (ret == 0) {
ss.code = 421;
@@ -142,7 +136,7 @@ queue_imsg(struct imsgev *iev, struct imsg *imsg)
return;
case IMSG_QUEUE_COMMIT_ENVELOPES:
- ss.id = m->session_id;
+ ss.id = e->session_id;
ss.code = 250;
imsg_compose_event(env->sc_ievs[PROC_SMTP],
IMSG_QUEUE_COMMIT_ENVELOPES, 0, 0, -1, &ss,
@@ -340,17 +334,17 @@ queue_purge(enum queue_kind qkind, char *queuepath)
}
void
-queue_submit_envelope(struct envelope *m)
+queue_submit_envelope(struct envelope *ep)
{
imsg_compose_event(env->sc_ievs[PROC_QUEUE],
IMSG_QUEUE_SUBMIT_ENVELOPE, 0, 0, -1,
- m, sizeof(*m));
+ ep, sizeof(*ep));
}
void
-queue_commit_envelopes(struct envelope *m)
+queue_commit_envelopes(struct envelope *ep)
{
imsg_compose_event(env->sc_ievs[PROC_QUEUE],
IMSG_QUEUE_COMMIT_ENVELOPES, 0, 0, -1,
- m, sizeof(*m));
+ ep, sizeof(*ep));
}
diff --git a/usr.sbin/smtpd/queue_backend.c b/usr.sbin/smtpd/queue_backend.c
index a5f363838f2..d86033126ff 100644
--- a/usr.sbin/smtpd/queue_backend.c
+++ b/usr.sbin/smtpd/queue_backend.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: queue_backend.c,v 1.10 2011/05/01 12:57:11 eric Exp $ */
+/* $OpenBSD: queue_backend.c,v 1.11 2011/05/16 21:05:52 gilles Exp $ */
/*
* Copyright (c) 2011 Gilles Chehade <gilles@openbsd.org>
@@ -100,26 +100,26 @@ queue_message_fd_rw(enum queue_kind qkind, u_int32_t msgid)
}
int
-queue_envelope_create(enum queue_kind qkind, struct envelope *m)
+queue_envelope_create(enum queue_kind qkind, struct envelope *ep)
{
- return env->sc_queue->envelope(qkind, QOP_CREATE, m);
+ return env->sc_queue->envelope(qkind, QOP_CREATE, ep);
}
int
-queue_envelope_delete(enum queue_kind qkind, struct envelope *m)
+queue_envelope_delete(enum queue_kind qkind, struct envelope *ep)
{
- return env->sc_queue->envelope(qkind, QOP_DELETE, m);
+ return env->sc_queue->envelope(qkind, QOP_DELETE, ep);
}
int
-queue_envelope_load(enum queue_kind qkind, u_int64_t evpid, struct envelope *m)
+queue_envelope_load(enum queue_kind qkind, u_int64_t evpid, struct envelope *ep)
{
- m->evpid = evpid;
- return env->sc_queue->envelope(qkind, QOP_LOAD, m);
+ ep->delivery.id = evpid;
+ return env->sc_queue->envelope(qkind, QOP_LOAD, ep);
}
int
-queue_envelope_update(enum queue_kind qkind, struct envelope *m)
+queue_envelope_update(enum queue_kind qkind, struct envelope *ep)
{
- return env->sc_queue->envelope(qkind, QOP_UPDATE, m);
+ return env->sc_queue->envelope(qkind, QOP_UPDATE, ep);
}
diff --git a/usr.sbin/smtpd/queue_fsqueue.c b/usr.sbin/smtpd/queue_fsqueue.c
index 4b3f131ab34..2831782c1c9 100644
--- a/usr.sbin/smtpd/queue_fsqueue.c
+++ b/usr.sbin/smtpd/queue_fsqueue.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: queue_fsqueue.c,v 1.11 2011/05/01 12:57:11 eric Exp $ */
+/* $OpenBSD: queue_fsqueue.c,v 1.12 2011/05/16 21:05:52 gilles Exp $ */
/*
* Copyright (c) 2011 Gilles Chehade <gilles@openbsd.org>
@@ -91,7 +91,7 @@ fsqueue_hash(u_int32_t h)
}
static int
-fsqueue_envelope_create(enum queue_kind qkind, struct envelope *m)
+fsqueue_envelope_create(enum queue_kind qkind, struct envelope *ep)
{
char evpname[MAXPATHLEN];
FILE *fp;
@@ -105,7 +105,8 @@ again:
rnd = (u_int32_t)arc4random();
if (rnd == 0)
goto again;
- evpid = m->evpid | rnd;
+ evpid = ep->delivery.id | rnd;
+
if (! bsnprintf(evpname, sizeof(evpname), "%s/%08x%s/%016llx",
fsqueue_getpath(qkind),
@@ -126,15 +127,15 @@ again:
if (fp == NULL)
fatal("fsqueue_envelope_create: fdopen");
- m->creation = time(NULL);
- m->evpid = evpid;
+ ep->delivery.creation = time(NULL);
+ ep->delivery.id = evpid;
if (qkind == Q_BOUNCE) {
- m->lasttry = 0;
- m->retry = 0;
+ ep->delivery.lasttry = 0;
+ ep->delivery.retry = 0;
}
- if (fwrite(m, sizeof (*m), 1, fp) != 1) {
+ if (fwrite(ep, sizeof (*ep), 1, fp) != 1) {
if (errno == ENOSPC)
goto tempfail;
fatal("fsqueue_envelope_create: write");
@@ -154,23 +155,23 @@ tempfail:
fclose(fp);
else if (fd != -1)
close(fd);
- m->creation = 0;
- m->evpid = 0;
+ ep->delivery.creation = 0;
+ ep->delivery.id = 0;
return 0;
}
static int
-fsqueue_envelope_load(enum queue_kind qkind, struct envelope *m)
+fsqueue_envelope_load(enum queue_kind qkind, struct envelope *ep)
{
char pathname[MAXPATHLEN];
FILE *fp;
if (! bsnprintf(pathname, sizeof(pathname), "%s/%04x/%08x%s/%016llx",
fsqueue_getpath(qkind),
- fsqueue_hash(evpid_to_msgid(m->evpid)),
- evpid_to_msgid(m->evpid),
- PATH_ENVELOPES, m->evpid))
+ fsqueue_hash(evpid_to_msgid(ep->delivery.id)),
+ evpid_to_msgid(ep->delivery.id),
+ PATH_ENVELOPES, ep->delivery.id))
fatalx("fsqueue_envelope_load: snprintf");
fp = fopen(pathname, "r");
@@ -179,31 +180,31 @@ fsqueue_envelope_load(enum queue_kind qkind, struct envelope *m)
return 0;
fatal("fsqueue_envelope_load: fopen");
}
- if (fread(m, sizeof(*m), 1, fp) != 1)
+ if (fread(ep, sizeof (*ep), 1, fp) != 1)
fatal("fsqueue_envelope_load: fread");
fclose(fp);
return 1;
}
static int
-fsqueue_envelope_update(enum queue_kind qkind, struct envelope *m)
+fsqueue_envelope_update(enum queue_kind qkind, struct envelope *ep)
{
char temp[MAXPATHLEN];
char dest[MAXPATHLEN];
FILE *fp;
u_int64_t batch_id;
- batch_id = m->batch_id;
- m->batch_id = 0;
+ batch_id = ep->batch_id;
+ ep->batch_id = 0;
if (! bsnprintf(temp, sizeof(temp), "%s/envelope.tmp", PATH_QUEUE))
fatalx("fsqueue_envelope_update");
if (! bsnprintf(dest, sizeof(dest), "%s/%04x/%08x%s/%016llx",
fsqueue_getpath(qkind),
- fsqueue_hash(evpid_to_msgid(m->evpid)),
- evpid_to_msgid(m->evpid),
- PATH_ENVELOPES, m->evpid))
+ fsqueue_hash(evpid_to_msgid(ep->delivery.id)),
+ evpid_to_msgid(ep->delivery.id),
+ PATH_ENVELOPES, ep->delivery.id))
fatal("fsqueue_envelope_update: snprintf");
fp = fopen(temp, "w");
@@ -212,7 +213,7 @@ fsqueue_envelope_update(enum queue_kind qkind, struct envelope *m)
goto tempfail;
fatal("fsqueue_envelope_update: open");
}
- if (fwrite(m, sizeof(*m), 1, fp) != 1) {
+ if (fwrite(ep, sizeof (*ep), 1, fp) != 1) {
if (errno == ENOSPC)
goto tempfail;
fatal("fsqueue_envelope_update: fwrite");
@@ -226,7 +227,7 @@ fsqueue_envelope_update(enum queue_kind qkind, struct envelope *m)
fatal("fsqueue_envelope_update: rename");
}
- m->batch_id = batch_id;
+ ep->batch_id = batch_id;
return 1;
tempfail:
@@ -235,35 +236,35 @@ tempfail:
if (fp)
fclose(fp);
- m->batch_id = batch_id;
+ ep->batch_id = batch_id;
return 0;
}
static int
-fsqueue_envelope_delete(enum queue_kind qkind, struct envelope *m)
+fsqueue_envelope_delete(enum queue_kind qkind, struct envelope *ep)
{
char pathname[MAXPATHLEN];
u_int16_t hval;
- hval = fsqueue_hash(evpid_to_msgid(m->evpid));
+ hval = fsqueue_hash(evpid_to_msgid(ep->delivery.id));
if (! bsnprintf(pathname, sizeof(pathname), "%s/%04x/%08x%s/%016llx",
fsqueue_getpath(qkind),
hval,
- evpid_to_msgid(m->evpid),
+ evpid_to_msgid(ep->delivery.id),
PATH_ENVELOPES,
- m->evpid))
+ ep->delivery.id))
fatal("fsqueue_envelope_delete: snprintf");
if (unlink(pathname) == -1)
fatal("fsqueue_envelope_delete: unlink");
if (! bsnprintf(pathname, sizeof(pathname), "%s/%04x/%08x%s", PATH_QUEUE,
- hval, evpid_to_msgid(m->evpid), PATH_ENVELOPES))
+ hval, evpid_to_msgid(ep->delivery.id), PATH_ENVELOPES))
fatal("fsqueue_envelope_delete: snprintf");
if (rmdir(pathname) != -1)
- fsqueue_message_delete(qkind, evpid_to_msgid(m->evpid));
+ fsqueue_message_delete(qkind, evpid_to_msgid(ep->delivery.id));
return 1;
}
diff --git a/usr.sbin/smtpd/queue_shared.c b/usr.sbin/smtpd/queue_shared.c
index 541dbc2665c..b0bb2c6f8bc 100644
--- a/usr.sbin/smtpd/queue_shared.c
+++ b/usr.sbin/smtpd/queue_shared.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: queue_shared.c,v 1.48 2011/05/10 17:04:43 gilles Exp $ */
+/* $OpenBSD: queue_shared.c,v 1.49 2011/05/16 21:05:52 gilles Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
@@ -59,24 +59,24 @@ void display_envelope(struct envelope *, int);
void getflag(u_int *, int, char *, char *, size_t);
int
-bounce_record_message(struct envelope *m, struct envelope *bounce)
+bounce_record_message(struct envelope *e, struct envelope *bounce)
{
u_int32_t msgid;
- if (m->type == T_BOUNCE_MESSAGE) {
+ if (e->delivery.type == D_BOUNCE) {
log_debug("mailer daemons loop detected !");
return 0;
}
- *bounce = *m;
- bounce->type = T_BOUNCE_MESSAGE;
- bounce->status &= ~S_MESSAGE_PERMFAILURE;
+ *bounce = *e;
+ bounce->delivery.type = D_BOUNCE;
+ bounce->delivery.status &= ~DS_PERMFAILURE;
- msgid = evpid_to_msgid(m->evpid);
+ msgid = evpid_to_msgid(e->delivery.id);
if (! queue_message_create(Q_BOUNCE, &msgid))
return 0;
- bounce->evpid = msgid_to_evpid(msgid);
+ bounce->delivery.id = msgid_to_evpid(msgid);
if (! queue_envelope_create(Q_BOUNCE, bounce))
return 0;
@@ -84,32 +84,33 @@ bounce_record_message(struct envelope *m, struct envelope *bounce)
}
void
-queue_message_update(struct envelope *m)
+queue_message_update(struct envelope *e)
{
- m->flags &= ~F_MESSAGE_PROCESSING;
- m->status &= ~(S_MESSAGE_ACCEPTED|S_MESSAGE_REJECTED);
- m->batch_id = 0;
- m->retry++;
-
- if (m->status & S_MESSAGE_PERMFAILURE) {
- if (m->type != T_BOUNCE_MESSAGE &&
- m->sender.user[0] != '\0') {
+ e->batch_id = 0;
+ e->delivery.flags &= ~DF_PROCESSING;
+ e->delivery.status &= ~(DS_ACCEPTED|DS_REJECTED);
+ e->delivery.retry++;
+
+
+ if (e->delivery.status & DS_PERMFAILURE) {
+ if (e->delivery.type != D_BOUNCE &&
+ e->delivery.from.user[0] != '\0') {
struct envelope bounce;
- bounce_record_message(m, &bounce);
+ bounce_record_message(e, &bounce);
}
- queue_envelope_delete(Q_QUEUE, m);
+ queue_envelope_delete(Q_QUEUE, e);
return;
}
- if (m->status & S_MESSAGE_TEMPFAILURE) {
- m->status &= ~S_MESSAGE_TEMPFAILURE;
- queue_envelope_update(Q_QUEUE, m);
+ if (e->delivery.status & DS_TEMPFAILURE) {
+ e->delivery.status &= ~DS_TEMPFAILURE;
+ queue_envelope_update(Q_QUEUE, e);
return;
}
/* no error, remove envelope */
- queue_envelope_delete(Q_QUEUE, m);
+ queue_envelope_delete(Q_QUEUE, e);
}
struct qwalk *
@@ -278,49 +279,49 @@ show_queue(char *queuepath, int flags)
}
void
-display_envelope(struct envelope *m, int flags)
+display_envelope(struct envelope *e, int flags)
{
char status[128];
status[0] = '\0';
- getflag(&m->status, S_MESSAGE_TEMPFAILURE, "TEMPFAIL",
+ getflag(&e->delivery.status, DS_TEMPFAILURE, "TEMPFAIL",
status, sizeof(status));
- if (m->status)
- errx(1, "%016llx: unexpected status 0x%04x", m->evpid,
- m->status);
+ if (e->delivery.status)
+ errx(1, "%016llx: unexpected status 0x%04x", e->delivery.id,
+ e->delivery.status);
- getflag(&m->flags, F_MESSAGE_BOUNCE, "BOUNCE",
+ getflag(&e->delivery.flags, DF_BOUNCE, "BOUNCE",
status, sizeof(status));
- getflag(&m->flags, F_MESSAGE_AUTHENTICATED, "AUTH",
+ getflag(&e->delivery.flags, DF_AUTHENTICATED, "AUTH",
status, sizeof(status));
- getflag(&m->flags, F_MESSAGE_PROCESSING, "PROCESSING",
+ getflag(&e->delivery.flags, DF_PROCESSING, "PROCESSING",
status, sizeof(status));
- getflag(&m->flags, F_MESSAGE_SCHEDULED, "SCHEDULED",
+ getflag(&e->delivery.flags, DF_SCHEDULED, "SCHEDULED",
status, sizeof(status));
- getflag(&m->flags, F_MESSAGE_ENQUEUED, "ENQUEUED",
+ getflag(&e->delivery.flags, DF_ENQUEUED, "ENQUEUED",
status, sizeof(status));
- getflag(&m->flags, F_MESSAGE_FORCESCHEDULE, "SCHEDULED_MANUAL",
+ getflag(&e->delivery.flags, DF_FORCESCHEDULE, "SCHEDULED_MANUAL",
status, sizeof(status));
- if (m->flags)
- errx(1, "%016llx: unexpected flags 0x%04x", m->evpid,
- m->flags);
+ if (e->delivery.flags)
+ errx(1, "%016llx: unexpected flags 0x%04x", e->delivery.id,
+ e->delivery.flags);
if (status[0])
status[strlen(status) - 1] = '\0';
else
strlcpy(status, "-", sizeof(status));
- switch (m->type) {
- case T_MDA_MESSAGE:
+ switch (e->delivery.type) {
+ case D_MDA:
printf("MDA");
break;
- case T_MTA_MESSAGE:
+ case D_MTA:
printf("MTA");
break;
- case T_BOUNCE_MESSAGE:
+ case D_BOUNCE:
printf("BOUNCE");
break;
default:
@@ -328,16 +329,16 @@ display_envelope(struct envelope *m, int flags)
}
printf("|%016llx|%s|%s@%s|%s@%s|%d|%d|%u",
- m->evpid,
+ e->delivery.id,
status,
- m->sender.user, m->sender.domain,
- m->recipient.user, m->recipient.domain,
- m->lasttry,
- m->expire,
- m->retry);
+ e->delivery.from.user, e->delivery.from.domain,
+ e->delivery.rcpt.user, e->delivery.rcpt.domain,
+ e->delivery.lasttry,
+ e->delivery.expire,
+ e->delivery.retry);
- if (m->session_errorline[0] != '\0')
- printf("|%s", m->session_errorline);
+ if (e->delivery.errorline[0] != '\0')
+ printf("|%s", e->delivery.errorline);
printf("\n");
}
diff --git a/usr.sbin/smtpd/ramqueue.c b/usr.sbin/smtpd/ramqueue.c
index 301649a1727..11110853ddd 100644
--- a/usr.sbin/smtpd/ramqueue.c
+++ b/usr.sbin/smtpd/ramqueue.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ramqueue.c,v 1.7 2011/05/01 12:57:11 eric Exp $ */
+/* $OpenBSD: ramqueue.c,v 1.8 2011/05/16 21:05:52 gilles Exp $ */
/*
* Copyright (c) 2011 Gilles Chehade <gilles@openbsd.org>
@@ -174,9 +174,9 @@ ramqueue_insert(struct ramqueue *rqueue, struct envelope *envelope, time_t curtm
rq_evp = calloc(1, sizeof (*rq_evp));
if (rq_evp == NULL)
fatal("calloc");
- rq_evp->evpid = envelope->evpid;
+ rq_evp->evpid = envelope->delivery.id;
rq_evp->sched = ramqueue_next_schedule(envelope, curtm);
- rq_evp->host = ramqueue_get_host(rqueue, envelope->recipient.domain);
+ rq_evp->host = ramqueue_get_host(rqueue, envelope->delivery.rcpt.domain);
rq_evp->batch = ramqueue_get_batch(rqueue, rq_evp->host, envelope);
TAILQ_INSERT_TAIL(&rq_evp->batch->envelope_queue, rq_evp,
@@ -215,10 +215,10 @@ ramqueue_expire(struct envelope *envelope, time_t curtm)
{
struct envelope bounce;
- if (curtm - envelope->creation >= envelope->expire) {
- message_set_errormsg(envelope,
+ if (curtm - envelope->delivery.creation >= envelope->delivery.expire) {
+ envelope_set_errormsg(envelope,
"message expired after sitting in queue for %d days",
- envelope->expire / 60 / 60 / 24);
+ envelope->delivery.expire / 60 / 60 / 24);
bounce_record_message(envelope, &bounce);
ramqueue_insert(&env->sc_rqueue, &bounce, time(NULL));
queue_envelope_delete(Q_QUEUE, envelope);
@@ -232,31 +232,31 @@ ramqueue_next_schedule(struct envelope *envelope, time_t curtm)
{
time_t delay;
- if (envelope->lasttry == 0)
+ if (envelope->delivery.lasttry == 0)
return curtm;
delay = SMTPD_QUEUE_MAXINTERVAL;
-
- if (envelope->type == T_MDA_MESSAGE ||
- envelope->type == T_BOUNCE_MESSAGE) {
- if (envelope->retry < 5)
+
+ if (envelope->delivery.type == D_MDA ||
+ envelope->delivery.type == D_BOUNCE) {
+ if (envelope->delivery.retry < 5)
return curtm;
- if (envelope->retry < 15)
- delay = (envelope->retry * 60) + arc4random_uniform(60);
+ if (envelope->delivery.retry < 15)
+ delay = (envelope->delivery.retry * 60) + arc4random_uniform(60);
}
- if (envelope->type == T_MTA_MESSAGE) {
- if (envelope->retry < 3)
+ if (envelope->delivery.type == D_MDA) {
+ if (envelope->delivery.retry < 3)
delay = SMTPD_QUEUE_INTERVAL;
- else if (envelope->retry <= 7) {
- delay = SMTPD_QUEUE_INTERVAL * (1 << (envelope->retry - 3));
+ else if (envelope->delivery.retry <= 7) {
+ delay = SMTPD_QUEUE_INTERVAL * (1 << (envelope->delivery.retry - 3));
if (delay > SMTPD_QUEUE_MAXINTERVAL)
delay = SMTPD_QUEUE_MAXINTERVAL;
}
}
- if (curtm >= envelope->lasttry + delay)
+ if (curtm >= envelope->delivery.lasttry + delay)
return curtm;
return curtm + delay;
@@ -299,7 +299,7 @@ ramqueue_get_batch(struct ramqueue *rqueue, struct ramqueue_host *host,
struct ramqueue_batch *rq_batch;
TAILQ_FOREACH(rq_batch, &host->batch_queue, batch_entry) {
- if (rq_batch->msgid == (u_int32_t)(envelope->evpid >> 32))
+ if (rq_batch->msgid == (u_int32_t)(envelope->delivery.id >> 32))
return rq_batch;
}
@@ -307,9 +307,10 @@ ramqueue_get_batch(struct ramqueue *rqueue, struct ramqueue_host *host,
if (rq_batch == NULL)
fatal("calloc");
rq_batch->b_id = generate_uid();
- rq_batch->type = envelope->type;
- rq_batch->rule = envelope->recipient.rule;
- rq_batch->msgid = envelope->evpid >> 32;
+ rq_batch->rule = envelope->rule;
+ rq_batch->type = envelope->delivery.type;
+ rq_batch->msgid = envelope->delivery.id >> 32;
+
TAILQ_INIT(&rq_batch->envelope_queue);
TAILQ_INSERT_TAIL(&host->batch_queue, rq_batch, batch_entry);
diff --git a/usr.sbin/smtpd/ruleset.c b/usr.sbin/smtpd/ruleset.c
index 4ad1d60694e..8f86dface0d 100644
--- a/usr.sbin/smtpd/ruleset.c
+++ b/usr.sbin/smtpd/ruleset.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ruleset.c,v 1.17 2011/05/01 12:57:11 eric Exp $ */
+/* $OpenBSD: ruleset.c,v 1.18 2011/05/16 21:05:52 gilles Exp $ */
/*
* Copyright (c) 2009 Gilles Chehade <gilles@openbsd.org>
@@ -33,7 +33,7 @@
#include "log.h"
-struct rule *ruleset_match(char *tag, struct path *, struct sockaddr_storage *);
+struct rule *ruleset_match(struct envelope *);
static int ruleset_check_source(struct map *, struct sockaddr_storage *);
static int ruleset_match_mask(struct sockaddr_storage *, struct netaddr *);
@@ -42,19 +42,25 @@ static int ruleset_inet6_match(struct sockaddr_in6 *, struct netaddr *);
struct rule *
-ruleset_match(char *tag, struct path *path, struct sockaddr_storage *ss)
+ruleset_match(struct envelope *evp)
{
struct rule *r;
struct map *map;
struct mapel *me;
+ struct mailaddr *maddr = &evp->delivery.rcpt;
+ struct sockaddr_storage *ss = &evp->delivery.ss;
+
+ log_debug("flags: %d", evp->delivery.flags);
+ if (evp->delivery.flags & DF_INTERNAL)
+ ss = NULL;
TAILQ_FOREACH(r, env->sc_rules, r_entry) {
- if (r->r_tag[0] != '\0' && strcmp(r->r_tag, tag) != 0)
+ if (r->r_tag[0] != '\0' && strcmp(r->r_tag, evp->tag) != 0)
continue;
if (ss != NULL &&
- (!(path->flags & F_PATH_AUTHENTICATED) &&
+ (!(evp->delivery.flags & DF_AUTHENTICATED) &&
! ruleset_check_source(r->r_sources, ss)))
continue;
@@ -69,12 +75,12 @@ ruleset_match(char *tag, struct path *path, struct sockaddr_storage *ss)
switch (map->m_src) {
case S_NONE:
TAILQ_FOREACH(me, &map->m_contents, me_entry) {
- if (hostname_match(path->domain, me->me_key.med_string))
+ if (hostname_match(maddr->domain, me->me_key.med_string))
return r;
}
break;
case S_DB:
- if (map_lookup(map->m_id, path->domain, K_VIRTUAL) != NULL)
+ if (map_lookup(map->m_id, maddr->domain, K_VIRTUAL) != NULL)
return r;
break;
default:
@@ -84,7 +90,7 @@ ruleset_match(char *tag, struct path *path, struct sockaddr_storage *ss)
}
if (r->r_condition.c_type == C_VDOM)
- if (aliases_vdomain_exists(r->r_condition.c_map, path->domain))
+ if (aliases_vdomain_exists(r->r_condition.c_map, maddr->domain))
return r;
}
diff --git a/usr.sbin/smtpd/runner.c b/usr.sbin/smtpd/runner.c
index b382380a94a..cb9128a633c 100644
--- a/usr.sbin/smtpd/runner.c
+++ b/usr.sbin/smtpd/runner.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: runner.c,v 1.106 2011/05/01 12:57:11 eric Exp $ */
+/* $OpenBSD: runner.c,v 1.107 2011/05/16 21:05:52 gilles Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
@@ -68,27 +68,27 @@ u_int32_t filename_to_msgid(char *);
void
runner_imsg(struct imsgev *iev, struct imsg *imsg)
{
- struct envelope *m;
+ struct envelope *e;
switch (imsg->hdr.type) {
case IMSG_QUEUE_COMMIT_MESSAGE:
- m = imsg->data;
- runner_force_message_to_ramqueue(&env->sc_rqueue, m->evpid>>32);
+ e = imsg->data;
+ runner_force_message_to_ramqueue(&env->sc_rqueue, e->delivery.id>>32);
runner_reset_events();
return;
case IMSG_QUEUE_MESSAGE_UPDATE:
- m = imsg->data;
- m->retry++;
+ e = imsg->data;
+ e->delivery.retry++;
env->stats->runner.active--;
/* temporary failure, message remains in queue,
* gets reinserted in ramqueue
*/
- if (m->status & S_MESSAGE_TEMPFAILURE) {
- m->status &= ~S_MESSAGE_TEMPFAILURE;
- queue_envelope_update(Q_QUEUE, m);
- ramqueue_insert(&env->sc_rqueue, m, time(NULL));
+ if (e->delivery.status & DS_TEMPFAILURE) {
+ e->delivery.status &= ~DS_TEMPFAILURE;
+ queue_envelope_update(Q_QUEUE, e);
+ ramqueue_insert(&env->sc_rqueue, e, time(NULL));
runner_reset_events();
return;
}
@@ -96,12 +96,12 @@ runner_imsg(struct imsgev *iev, struct imsg *imsg)
/* permanent failure, eventually generate a
* bounce (and insert bounce in ramqueue).
*/
- if (m->status & S_MESSAGE_PERMFAILURE) {
+ if (e->delivery.status & DS_PERMFAILURE) {
struct envelope bounce;
- if (m->type != T_BOUNCE_MESSAGE &&
- m->sender.user[0] != '\0') {
- bounce_record_message(m, &bounce);
+ if (e->delivery.type != D_BOUNCE &&
+ e->delivery.from.user[0] != '\0') {
+ bounce_record_message(e, &bounce);
ramqueue_insert(&env->sc_rqueue, &bounce, time(NULL));
runner_reset_events();
}
@@ -110,7 +110,7 @@ runner_imsg(struct imsgev *iev, struct imsg *imsg)
/* successful delivery or permanent failure,
* remove envelope from queue.
*/
- queue_envelope_delete(Q_QUEUE, m);
+ queue_envelope_delete(Q_QUEUE, e);
return;
case IMSG_MDA_SESS_NEW:
@@ -126,11 +126,11 @@ runner_imsg(struct imsgev *iev, struct imsg *imsg)
return;
case IMSG_SMTP_ENQUEUE:
- m = imsg->data;
- if (imsg->fd < 0 || !bounce_session(imsg->fd, m)) {
- m->status = 0;
- queue_envelope_update(Q_QUEUE, m);
- ramqueue_insert(&env->sc_rqueue, m, time(NULL));
+ e = imsg->data;
+ if (imsg->fd < 0 || !bounce_session(imsg->fd, e)) {
+ e->delivery.status = 0;
+ queue_envelope_update(Q_QUEUE, e);
+ ramqueue_insert(&env->sc_rqueue, e, time(NULL));
runner_reset_events();
return;
}
@@ -355,21 +355,21 @@ runner_process_envelope(struct ramqueue_envelope *rq_evp, time_t curtm)
if (! queue_envelope_load(Q_QUEUE, rq_evp->evpid, &envelope))
return 0;
- if (envelope.type & T_MDA_MESSAGE) {
+ if (envelope.delivery.type & D_MDA) {
if (env->sc_opts & SMTPD_MDA_PAUSED)
return 0;
if (mda_av == 0)
return 0;
}
- if (envelope.type & T_MTA_MESSAGE) {
+ if (envelope.delivery.type & D_MTA) {
if (env->sc_opts & SMTPD_MTA_PAUSED)
return 0;
if (mta_av == 0)
return 0;
}
- if (envelope.type & T_BOUNCE_MESSAGE) {
+ if (envelope.delivery.type & D_BOUNCE) {
if (env->sc_opts & (SMTPD_MDA_PAUSED|SMTPD_MTA_PAUSED))
return 0;
if (bnc_av == 0)
@@ -379,7 +379,7 @@ runner_process_envelope(struct ramqueue_envelope *rq_evp, time_t curtm)
if (runner_check_loop(&envelope)) {
struct envelope bounce;
- message_set_errormsg(&envelope, "loop has been detected");
+ envelope_set_errormsg(&envelope, "loop has been detected");
bounce_record_message(&envelope, &bounce);
ramqueue_insert(&env->sc_rqueue, &bounce, time(NULL));
runner_setup_events();
@@ -387,10 +387,6 @@ runner_process_envelope(struct ramqueue_envelope *rq_evp, time_t curtm)
return 0;
}
- log_debug("dispatching host: %p, batch: %p, envelope: %p, %016llx",
- rq_evp->host,
- rq_evp->batch,
- rq_evp, rq_evp->evpid);
runner_process_batch(rq_evp, curtm);
return 1;
@@ -406,12 +402,12 @@ runner_process_batch(struct ramqueue_envelope *rq_evp, time_t curtm)
int fd;
switch (batch->type) {
- case T_BOUNCE_MESSAGE:
+ case D_BOUNCE:
while ((rq_evp = ramqueue_batch_first_envelope(batch))) {
if (! queue_envelope_load(Q_QUEUE, rq_evp->evpid,
&envelope))
return;
- envelope.lasttry = curtm;
+ envelope.delivery.lasttry = curtm;
imsg_compose_event(env->sc_ievs[PROC_QUEUE],
IMSG_SMTP_ENQUEUE, PROC_SMTP, 0, -1, &envelope,
sizeof envelope);
@@ -427,12 +423,12 @@ runner_process_batch(struct ramqueue_envelope *rq_evp, time_t curtm)
env->stats->runner.maxactive);
break;
- case T_MDA_MESSAGE:
+ case D_MDA:
rq_evp = ramqueue_batch_first_envelope(batch);
if (! queue_envelope_load(Q_QUEUE, rq_evp->evpid, &envelope))
return;
- envelope.lasttry = curtm;
+ envelope.delivery.lasttry = curtm;
fd = queue_message_fd_r(Q_QUEUE, rq_evp->evpid>>32);
imsg_compose_event(env->sc_ievs[PROC_QUEUE],
IMSG_MDA_SESS_NEW, PROC_MDA, 0, fd, &envelope,
@@ -449,7 +445,7 @@ runner_process_batch(struct ramqueue_envelope *rq_evp, time_t curtm)
env->stats->runner.maxactive);
break;
- case T_MTA_MESSAGE:
+ case D_MTA:
imsg_compose_event(env->sc_ievs[PROC_QUEUE],
IMSG_BATCH_CREATE, PROC_MTA, 0, -1, batch,
sizeof *batch);
@@ -457,7 +453,7 @@ runner_process_batch(struct ramqueue_envelope *rq_evp, time_t curtm)
if (! queue_envelope_load(Q_QUEUE, rq_evp->evpid,
&envelope))
return;
- envelope.lasttry = curtm;
+ envelope.delivery.lasttry = curtm;
envelope.batch_id = batch->b_id;
imsg_compose_event(env->sc_ievs[PROC_QUEUE],
IMSG_BATCH_APPEND, PROC_MTA, 0, -1, &envelope,
@@ -616,17 +612,17 @@ delroot:
}
int
-runner_check_loop(struct envelope *messagep)
+runner_check_loop(struct envelope *ep)
{
int fd;
FILE *fp;
char *buf, *lbuf;
size_t len;
- struct path chkpath;
+ struct mailaddr maddr;
int ret = 0;
int rcvcount = 0;
- fd = queue_message_fd_r(Q_QUEUE, messagep->evpid>>32);
+ fd = queue_message_fd_r(Q_QUEUE, ep->delivery.id>>32);
if ((fp = fdopen(fd, "r")) == NULL)
fatal("fdopen");
@@ -655,18 +651,18 @@ runner_check_loop(struct envelope *messagep)
}
else if (strncasecmp("Delivered-To: ", buf, 14) == 0) {
- struct path rcpt;
+ struct mailaddr rcpt;
- bzero(&chkpath, sizeof (struct path));
- if (! recipient_to_path(&chkpath, buf + 14))
+ bzero(&maddr, sizeof (struct mailaddr));
+ if (! email_to_mailaddr(&maddr, buf + 14))
continue;
- rcpt = messagep->recipient;
- if (messagep->type == T_BOUNCE_MESSAGE)
- rcpt = messagep->sender;
+ rcpt = ep->delivery.rcpt;
+ if (ep->delivery.type == D_BOUNCE)
+ rcpt = ep->delivery.from;
- if (strcasecmp(chkpath.user, rcpt.user) == 0 &&
- strcasecmp(chkpath.domain, rcpt.domain) == 0) {
+ if (strcasecmp(maddr.user, rcpt.user) == 0 &&
+ strcasecmp(maddr.domain, rcpt.domain) == 0) {
ret = 1;
break;
}
diff --git a/usr.sbin/smtpd/smtp.c b/usr.sbin/smtpd/smtp.c
index ecae30f9177..b3821026cf6 100644
--- a/usr.sbin/smtpd/smtp.c
+++ b/usr.sbin/smtpd/smtp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: smtp.c,v 1.85 2011/05/01 12:57:11 eric Exp $ */
+/* $OpenBSD: smtp.c,v 1.86 2011/05/16 21:05:52 gilles Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
@@ -70,8 +70,8 @@ smtp_imsg(struct imsgev *iev, struct imsg *imsg)
strlcpy(s->s_hostname,
dns->error ? "<unknown>" : dns->host,
sizeof s->s_hostname);
- strlcpy(s->s_msg.session_hostname, s->s_hostname,
- sizeof s->s_msg.session_hostname);
+ strlcpy(s->s_msg.delivery.hostname, s->s_hostname,
+ sizeof s->s_msg.delivery.hostname);
session_init(s->s_l, s);
return;
}
@@ -100,7 +100,7 @@ smtp_imsg(struct imsgev *iev, struct imsg *imsg)
s = session_lookup(ss->id);
if (s == NULL)
return;
- s->s_msg.evpid = (u_int64_t)ss->u.msgid << 32;
+ s->s_msg.delivery.id = (u_int64_t)ss->u.msgid << 32;
session_pickup(s, ss);
return;
@@ -129,7 +129,7 @@ smtp_imsg(struct imsgev *iev, struct imsg *imsg)
fatalx("smtp: session is gone");
if (s->s_flags & F_WRITEONLY)
/* session is write-only, must not destroy it. */
- s->s_msg.status |= S_MESSAGE_TEMPFAILURE;
+ s->s_msg.delivery.status |= DS_TEMPFAILURE;
else
fatalx("smtp: corrupt session");
return;
@@ -168,7 +168,7 @@ smtp_imsg(struct imsgev *iev, struct imsg *imsg)
*/
SPLAY_FOREACH(s, sessiontree, &env->sc_sessions) {
s->s_l = NULL;
- s->s_msg.status |= S_MESSAGE_TEMPFAILURE;
+ s->s_msg.delivery.status |= DS_TEMPFAILURE;
}
if (env->sc_listeners)
smtp_disable_events();
@@ -248,10 +248,10 @@ smtp_imsg(struct imsgev *iev, struct imsg *imsg)
return;
if (auth->success) {
s->s_flags |= F_AUTHENTICATED;
- s->s_msg.flags |= F_MESSAGE_AUTHENTICATED;
+ s->s_msg.delivery.flags |= DF_AUTHENTICATED;
} else {
s->s_flags &= ~F_AUTHENTICATED;
- s->s_msg.flags &= ~F_MESSAGE_AUTHENTICATED;
+ s->s_msg.delivery.flags &= ~DF_AUTHENTICATED;
}
session_pickup(s, NULL);
return;
@@ -479,18 +479,18 @@ smtp_enqueue(uid_t *euid)
s->s_fd = fd[0];
s->s_ss = sa;
- s->s_msg.flags |= F_MESSAGE_ENQUEUED;
+ s->s_msg.delivery.flags |= DF_ENQUEUED;
if (euid)
bsnprintf(s->s_hostname, sizeof(s->s_hostname), "%d@localhost",
*euid);
else {
strlcpy(s->s_hostname, "localhost", sizeof(s->s_hostname));
- s->s_msg.flags |= F_MESSAGE_BOUNCE;
+ s->s_msg.delivery.flags |= DF_BOUNCE;
}
- strlcpy(s->s_msg.session_hostname, s->s_hostname,
- sizeof(s->s_msg.session_hostname));
+ strlcpy(s->s_msg.delivery.hostname, s->s_hostname,
+ sizeof(s->s_msg.delivery.hostname));
session_init(l, s);
diff --git a/usr.sbin/smtpd/smtp_session.c b/usr.sbin/smtpd/smtp_session.c
index 20ba091ebcd..ba904a04ea4 100644
--- a/usr.sbin/smtpd/smtp_session.c
+++ b/usr.sbin/smtpd/smtp_session.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: smtp_session.c,v 1.141 2011/05/01 12:57:11 eric Exp $ */
+/* $OpenBSD: smtp_session.c,v 1.142 2011/05/16 21:05:52 gilles Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
@@ -67,7 +67,7 @@ static void session_error(struct bufferevent *, short event, void *);
static void session_command(struct session *, char *);
static char *session_readline(struct session *);
static void session_respond_delayed(int, short, void *);
-static int session_set_path(struct path *, char *);
+static int session_set_mailaddr(struct mailaddr *, char *);
static void session_imsg(struct session *, enum smtp_proc_type,
enum imsg_type, u_int32_t, pid_t, int, void *, u_int16_t);
@@ -323,8 +323,8 @@ session_rfc5321_helo_handler(struct session *s, char *args)
return 1;
}
- if (strlcpy(s->s_msg.session_helo, args, sizeof(s->s_msg.session_helo))
- >= sizeof(s->s_msg.session_helo)) {
+ if (strlcpy(s->s_msg.delivery.helo, args, sizeof(s->s_msg.delivery.helo))
+ >= sizeof(s->s_msg.delivery.helo)) {
session_respond(s, "501 Invalid domain name");
return 1;
}
@@ -346,8 +346,8 @@ session_rfc5321_ehlo_handler(struct session *s, char *args)
return 1;
}
- if (strlcpy(s->s_msg.session_helo, args, sizeof(s->s_msg.session_helo))
- >= sizeof(s->s_msg.session_helo)) {
+ if (strlcpy(s->s_msg.delivery.helo, args, sizeof(s->s_msg.delivery.helo))
+ >= sizeof(s->s_msg.delivery.helo)) {
session_respond(s, "501 Invalid domain name");
return 1;
}
@@ -408,7 +408,7 @@ session_rfc5321_mail_handler(struct session *s, char *args)
return 1;
}
- if (! session_set_path(&s->s_msg.sender, args)) {
+ if (! session_set_mailaddr(&s->s_msg.delivery.from, args)) {
/* No need to even transmit to MFA, path is invalid */
session_respond(s, "553 5.1.7 Sender address syntax error");
return 1;
@@ -416,9 +416,9 @@ session_rfc5321_mail_handler(struct session *s, char *args)
s->rcptcount = 0;
s->s_state = S_MAIL_MFA;
- s->s_msg.id = s->s_id;
s->s_msg.session_id = s->s_id;
- s->s_msg.session_ss = s->s_ss;
+ s->s_msg.delivery.id = 0;
+ s->s_msg.delivery.ss = s->s_ss;
log_debug("session_rfc5321_mail_handler: sending notification to mfa");
@@ -440,7 +440,7 @@ session_rfc5321_rcpt_handler(struct session *s, char *args)
return 1;
}
- if (! session_set_path(&s->s_msg.session_rcpt, args)) {
+ if (! session_set_mailaddr(&s->s_msg.delivery.rcpt_orig, args)) {
/* No need to even transmit to MFA, path is invalid */
session_respond(s, "553 5.1.3 Recipient address syntax error");
return 1;
@@ -601,7 +601,7 @@ session_pickup(struct session *s, struct submit_status *ss)
fatal("session_pickup: desynchronized");
if ((ss != NULL && ss->code == 421) ||
- (s->s_msg.status & S_MESSAGE_TEMPFAILURE)) {
+ (s->s_msg.delivery.status & DS_TEMPFAILURE)) {
session_respond(s, "421 Service temporarily unavailable");
env->stats->smtp.tempfail++;
s->s_flags |= F_QUIT;
@@ -640,7 +640,7 @@ session_pickup(struct session *s, struct submit_status *ss)
}
s->s_state = S_MAIL_QUEUE;
- s->s_msg.sender = ss->u.path;
+ s->s_msg.delivery.from = ss->u.maddr;
session_imsg(s, PROC_QUEUE, IMSG_QUEUE_CREATE_MESSAGE, 0, 0, -1,
&s->s_msg, sizeof(s->s_msg));
@@ -664,13 +664,14 @@ session_pickup(struct session *s, struct submit_status *ss)
else
s->s_state = S_RCPT;
session_respond(s, "%d 5.0.0 Recipient rejected: %s@%s", ss->code,
- s->s_msg.session_rcpt.user, s->s_msg.session_rcpt.domain);
+ s->s_msg.delivery.rcpt_orig.user,
+ s->s_msg.delivery.rcpt_orig.domain);
return;
}
s->s_state = S_RCPT;
s->rcptcount++;
- s->s_msg.recipient = ss->u.path;
+ s->s_msg.delivery.rcpt = ss->u.maddr;
session_respond(s, "%d 2.0.0 Recipient ok", ss->code);
break;
@@ -681,10 +682,10 @@ session_pickup(struct session *s, struct submit_status *ss)
" itself");
fprintf(s->datafp, "Received: from %s (%s [%s])\n",
- s->s_msg.session_helo, s->s_hostname, ss_to_text(&s->s_ss));
+ s->s_msg.delivery.helo, s->s_hostname, ss_to_text(&s->s_ss));
fprintf(s->datafp, "\tby %s (OpenSMTPD) with %sSMTP id %08x",
env->sc_hostname, s->s_flags & F_EHLO ? "E" : "",
- (u_int32_t)(s->s_msg.evpid >> 32));
+ (u_int32_t)(s->s_msg.delivery.id >> 32));
if (s->s_flags & F_SECURE) {
fprintf(s->datafp, "\n\t(version=%s cipher=%s bits=%d)",
@@ -694,8 +695,8 @@ session_pickup(struct session *s, struct submit_status *ss)
}
if (s->rcptcount == 1)
fprintf(s->datafp, "\n\tfor <%s@%s>; ",
- s->s_msg.session_rcpt.user,
- s->s_msg.session_rcpt.domain);
+ s->s_msg.delivery.rcpt_orig.user,
+ s->s_msg.delivery.rcpt_orig.domain);
else
fprintf(s->datafp, ";\n\t");
@@ -704,13 +705,13 @@ session_pickup(struct session *s, struct submit_status *ss)
case S_DONE:
session_respond(s, "250 2.0.0 %08x Message accepted for delivery",
- (u_int32_t)(s->s_msg.evpid >> 32));
+ (u_int32_t)(s->s_msg.delivery.id >> 32));
log_info("%08x: from=<%s%s%s>, size=%ld, nrcpts=%zd, proto=%s, "
"relay=%s [%s]",
- (u_int32_t)(s->s_msg.evpid >> 32),
- s->s_msg.sender.user,
- s->s_msg.sender.user[0] == '\0' ? "" : "@",
- s->s_msg.sender.domain,
+ (u_int32_t)(s->s_msg.delivery.id >> 32),
+ s->s_msg.delivery.from.user,
+ s->s_msg.delivery.from.user[0] == '\0' ? "" : "@",
+ s->s_msg.delivery.from.domain,
s->s_datalen,
s->rcptcount,
s->s_flags & F_EHLO ? "ESMTP" : "SMTP",
@@ -718,7 +719,7 @@ session_pickup(struct session *s, struct submit_status *ss)
ss_to_text(&s->s_ss));
s->s_state = S_HELO;
- s->s_msg.evpid = 0;
+ s->s_msg.delivery.id = 0;
bzero(&s->s_nresp, sizeof(s->s_nresp));
break;
@@ -773,14 +774,14 @@ session_read(struct bufferevent *bev, void *p)
switch (s->s_state) {
case S_AUTH_INIT:
- if (s->s_msg.status & S_MESSAGE_TEMPFAILURE)
+ if (s->s_msg.delivery.status & DS_TEMPFAILURE)
goto tempfail;
session_rfc4954_auth_plain(s, line);
break;
case S_AUTH_USERNAME:
case S_AUTH_PASSWORD:
- if (s->s_msg.status & S_MESSAGE_TEMPFAILURE)
+ if (s->s_msg.delivery.status & DS_TEMPFAILURE)
goto tempfail;
session_rfc4954_auth_login(s, line);
break;
@@ -789,7 +790,7 @@ session_read(struct bufferevent *bev, void *p)
case S_HELO:
case S_MAIL:
case S_RCPT:
- if (s->s_msg.status & S_MESSAGE_TEMPFAILURE)
+ if (s->s_msg.delivery.status & DS_TEMPFAILURE)
goto tempfail;
session_command(s, line);
break;
@@ -823,13 +824,13 @@ session_read_data(struct session *s, char *line)
if (strcmp(line, ".") == 0) {
s->s_datalen = ftell(s->datafp);
if (! safe_fclose(s->datafp))
- s->s_msg.status |= S_MESSAGE_TEMPFAILURE;
+ s->s_msg.delivery.status |= DS_TEMPFAILURE;
s->datafp = NULL;
- if (s->s_msg.status & S_MESSAGE_PERMFAILURE) {
+ if (s->s_msg.delivery.status & DS_PERMFAILURE) {
session_respond(s, "554 5.0.0 Transaction failed");
s->s_state = S_HELO;
- } else if (s->s_msg.status & S_MESSAGE_TEMPFAILURE) {
+ } else if (s->s_msg.delivery.status & DS_TEMPFAILURE) {
session_respond(s, "421 4.0.0 Temporary failure");
s->s_flags |= F_QUIT;
env->stats->smtp.tempfail++;
@@ -843,7 +844,7 @@ session_read_data(struct session *s, char *line)
}
/* Don't waste resources on message if it's going to bin anyway. */
- if (s->s_msg.status & (S_MESSAGE_PERMFAILURE|S_MESSAGE_TEMPFAILURE))
+ if (s->s_msg.delivery.status & (DS_PERMFAILURE|DS_TEMPFAILURE))
return;
/* "If the first character is a period and there are other characters
@@ -860,12 +861,12 @@ session_read_data(struct session *s, char *line)
datalen = ftell(s->datafp);
if (SIZE_MAX - datalen < len + 1 ||
datalen + len + 1 > env->sc_maxsize) {
- s->s_msg.status |= S_MESSAGE_PERMFAILURE;
+ s->s_msg.delivery.status |= DS_PERMFAILURE;
return;
}
if (fprintf(s->datafp, "%s\n", line) != (int)len + 1) {
- s->s_msg.status |= S_MESSAGE_TEMPFAILURE;
+ s->s_msg.delivery.status |= DS_TEMPFAILURE;
return;
}
@@ -973,7 +974,7 @@ session_destroy(struct session *s)
if (s->datafp != NULL)
fclose(s->datafp);
- if (s->s_msg.evpid != 0 && s->s_state != S_DONE)
+ if (s->s_msg.delivery.id != 0 && s->s_state != S_DONE)
imsg_compose_event(env->sc_ievs[PROC_QUEUE],
IMSG_QUEUE_REMOVE_MESSAGE, 0, 0, -1, &s->s_msg,
sizeof(s->s_msg));
@@ -1059,7 +1060,7 @@ session_cmp(struct session *s1, struct session *s2)
}
static int
-session_set_path(struct path *path, char *line)
+session_set_mailaddr(struct mailaddr *maddr, char *line)
{
size_t len;
@@ -1068,7 +1069,7 @@ session_set_path(struct path *path, char *line)
return 0;
line[len - 1] = '\0';
- return recipient_to_path(path, line + 1);
+ return email_to_mailaddr(maddr, line + 1);
}
void
@@ -1095,8 +1096,8 @@ session_respond(struct session *s, char *fmt, ...)
case '5':
case '4':
log_info("%08x: from=<%s@%s>, relay=%s [%s], stat=LocalError (%.*s)",
- (u_int32_t)(s->s_msg.evpid >> 32),
- s->s_msg.sender.user, s->s_msg.sender.domain,
+ (u_int32_t)(s->s_msg.delivery.id >> 32),
+ s->s_msg.delivery.from.user, s->s_msg.delivery.from.domain,
s->s_hostname, ss_to_text(&s->s_ss),
(int)EVBUFFER_LENGTH(EVBUFFER_OUTPUT(s->s_bev)) - n - 2,
EVBUFFER_DATA(EVBUFFER_OUTPUT(s->s_bev)));
diff --git a/usr.sbin/smtpd/smtpd.c b/usr.sbin/smtpd/smtpd.c
index c33acb4e183..38d932c1411 100644
--- a/usr.sbin/smtpd/smtpd.c
+++ b/usr.sbin/smtpd/smtpd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: smtpd.c,v 1.123 2011/05/04 20:45:30 eric Exp $ */
+/* $OpenBSD: smtpd.c,v 1.124 2011/05/16 21:05:52 gilles Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
@@ -109,7 +109,7 @@ parent_imsg(struct imsgev *iev, struct imsg *imsg)
switch (imsg->hdr.type) {
case IMSG_PARENT_FORWARD_OPEN:
fwreq = imsg->data;
- fd = parent_forward_open(fwreq->pw_name);
+ fd = parent_forward_open(fwreq->as_user);
fwreq->status = 0;
if (fd == -2) {
/* no ~/.forward, however it's optional. */
diff --git a/usr.sbin/smtpd/smtpd.h b/usr.sbin/smtpd/smtpd.h
index ccfd77bd79f..de48338db78 100644
--- a/usr.sbin/smtpd/smtpd.h
+++ b/usr.sbin/smtpd/smtpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: smtpd.h,v 1.221 2011/05/06 19:21:43 eric Exp $ */
+/* $OpenBSD: smtpd.h,v 1.222 2011/05/16 21:05:52 gilles Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
@@ -312,9 +312,9 @@ enum action_type {
A_EXT
};
-#define IS_MAILBOX(x) ((x).rule.r_action == A_MAILDIR || (x).rule.r_action == A_MBOX || (x).rule.r_action == A_FILENAME)
-#define IS_RELAY(x) ((x).rule.r_action == A_RELAY || (x).rule.r_action == A_RELAYVIA)
-#define IS_EXT(x) ((x).rule.r_action == A_EXT)
+#define IS_MAILBOX(x) ((x).r_action == A_MAILDIR || (x).r_action == A_MBOX || (x).r_action == A_FILENAME)
+#define IS_RELAY(x) ((x).r_action == A_RELAY || (x).r_action == A_RELAYVIA)
+#define IS_EXT(x) ((x).r_action == A_EXT)
struct rule {
TAILQ_ENTRY(rule) r_entry;
@@ -333,40 +333,93 @@ struct rule {
time_t r_qexpire;
};
-enum path_flags {
- F_PATH_ALIAS = 0x1,
- F_PATH_VIRTUAL = 0x2,
- F_PATH_EXPANDED = 0x4,
- F_PATH_NOFORWARD = 0x8,
- F_PATH_FORWARDED = 0x10,
- F_PATH_ACCOUNT = 0x20,
- F_PATH_AUTHENTICATED = 0x40,
- F_PATH_RELAY = 0x80,
-};
-
struct mailaddr {
char user[MAX_LOCALPART_SIZE];
char domain[MAX_DOMAINPART_SIZE];
};
-union path_data {
- char username[MAXLOGNAME];
- char filename[MAXPATHLEN];
- char filter[MAXPATHLEN];
+
+enum delivery_type {
+ D_INVALID = 0,
+ D_MDA,
+ D_MTA,
+ D_BOUNCE
+};
+
+/*
+enum delivery_method {
+ DM_INVALID = 0,
+ DM_RELAY,
+ DM_RELAYVIA,
+ DM_MAILDIR,
+ DM_MBOX,
+ DM_FILENAME,
+ DM_EXT
+};
+*/
+
+enum delivery_status {
+ DS_PERMFAILURE = 0x2,
+ DS_TEMPFAILURE = 0x4,
+ DS_REJECTED = 0x8,
+ DS_ACCEPTED = 0x10,
+ DS_RETRY = 0x20,
+ DS_EDNS = 0x40,
+ DS_ECONNECT = 0x80
+};
+
+enum delivery_flags {
+ DF_RESOLVED = 0x1,
+ DF_SCHEDULED = 0x2,
+ DF_PROCESSING = 0x4,
+ DF_AUTHENTICATED = 0x8,
+ DF_ENQUEUED = 0x10,
+ DF_FORCESCHEDULE = 0x20,
+ DF_BOUNCE = 0x40,
+ DF_INTERNAL = 0x80 /* internal expansion forward */
+};
+
+union delivery_data {
+ char user[MAXLOGNAME];
+ char buffer[MAX_RULEBUFFER_LEN];
struct mailaddr mailaddr;
};
-struct path {
- TAILQ_ENTRY(path) entry;
- struct rule rule;
- enum path_flags flags;
- u_int8_t forwardcnt;
- char user[MAX_LOCALPART_SIZE];
- char domain[MAX_DOMAINPART_SIZE];
- char pw_name[MAXLOGNAME];
- union path_data u;
+struct delivery_mda {
+ enum action_type method;
+ union delivery_data to;
+ char as_user[MAXLOGNAME];
+};
+
+struct delivery_mta {
+ struct relayhost relay;
+};
+
+struct delivery {
+ u_int64_t id;
+ enum delivery_type type;
+
+ char helo[MAXHOSTNAMELEN];
+ char hostname[MAXHOSTNAMELEN];
+ char errorline[MAX_LINE_SIZE];
+ struct sockaddr_storage ss;
+
+ struct mailaddr from;
+ struct mailaddr rcpt;
+ struct mailaddr rcpt_orig;
+
+ union delivery_method {
+ struct delivery_mda mda;
+ struct delivery_mta mta;
+ } agent;
+
+ time_t creation;
+ time_t lasttry;
+ time_t expire;
+ u_int8_t retry;
+ enum delivery_flags flags;
+ enum delivery_status status;
};
-TAILQ_HEAD(deliverylist, path);
enum expand_type {
EXPAND_INVALID,
@@ -387,65 +440,26 @@ struct expandnode {
size_t refcnt;
enum expand_flags flags;
enum expand_type type;
- union path_data u;
+ char as_user[MAXLOGNAME];
+ union delivery_data u;
};
RB_HEAD(expandtree, expandnode);
-enum message_type {
- T_MDA_MESSAGE = 0x1,
- T_MTA_MESSAGE = 0x2,
- T_BOUNCE_MESSAGE = 0x4
-};
-
-enum message_status {
- S_MESSAGE_PERMFAILURE = 0x2,
- S_MESSAGE_TEMPFAILURE = 0x4,
- S_MESSAGE_REJECTED = 0x8,
- S_MESSAGE_ACCEPTED = 0x10,
- S_MESSAGE_RETRY = 0x20,
- S_MESSAGE_EDNS = 0x40,
- S_MESSAGE_ECONNECT = 0x80
-};
-
-enum message_flags {
- F_MESSAGE_RESOLVED = 0x1,
- F_MESSAGE_SCHEDULED = 0x2,
- F_MESSAGE_PROCESSING = 0x4,
- F_MESSAGE_AUTHENTICATED = 0x8,
- F_MESSAGE_ENQUEUED = 0x10,
- F_MESSAGE_FORCESCHEDULE = 0x20,
- F_MESSAGE_BOUNCE = 0x40
-};
struct envelope {
- TAILQ_ENTRY(envelope) entry;
-
- enum message_type type;
-
- u_int64_t id;
- u_int64_t session_id;
- u_int64_t batch_id;
+ TAILQ_ENTRY(envelope) entry;
- char tag[MAX_TAG_SIZE];
-
- u_int64_t evpid;
- char session_helo[MAXHOSTNAMELEN];
- char session_hostname[MAXHOSTNAMELEN];
- char session_errorline[MAX_LINE_SIZE];
- struct sockaddr_storage session_ss;
- struct path session_rcpt;
+ char tag[MAX_TAG_SIZE];
+ struct rule rule;
- struct path sender;
- struct path recipient;
+ u_int64_t session_id;
+ u_int64_t batch_id;
- time_t creation;
- time_t lasttry;
- time_t expire;
- u_int8_t retry;
- enum message_flags flags;
- enum message_status status;
+ struct delivery delivery;
};
+TAILQ_HEAD(deliverylist, envelope);
+
enum child_type {
CHILD_INVALID,
@@ -569,7 +583,7 @@ struct ramqueue_host {
struct ramqueue_batch {
TAILQ_ENTRY(ramqueue_batch) batch_entry;
TAILQ_HEAD(,ramqueue_envelope) envelope_queue;
- enum message_type type;
+ enum delivery_type type;
u_int64_t h_id;
u_int64_t b_id;
u_int32_t msgid;
@@ -626,7 +640,7 @@ struct smtpd {
SPLAY_HEAD(msgtree, envelope) sc_messages;
SPLAY_HEAD(ssltree, ssl) *sc_ssl;
SPLAY_HEAD(childtree, child) children;
- SPLAY_HEAD(lkatree, lkasession) lka_sessions;
+ SPLAY_HEAD(lkatree, lka_session) lka_sessions;
SPLAY_HEAD(mtatree, mta_session) mta_sessions;
LIST_HEAD(mdalist, mda_session) mda_sessions;
@@ -729,20 +743,21 @@ struct submit_status {
u_int64_t id;
int code;
union submit_path {
- struct path path;
+ struct mailaddr maddr;
u_int32_t msgid;
u_int64_t evpid;
char errormsg[MAX_LINE_SIZE];
} u;
- enum message_flags flags;
+ enum delivery_flags flags;
struct sockaddr_storage ss;
- struct envelope msg;
+ struct envelope envelope;
};
struct forward_req {
u_int64_t id;
u_int8_t status;
- char pw_name[MAXLOGNAME];
+ char as_user[MAXLOGNAME];
+ struct envelope envelope;
};
struct dns {
@@ -783,23 +798,20 @@ struct rulematch {
struct submit_status ss;
};
-enum lkasession_flags {
+enum lka_session_flags {
F_ERROR = 0x1
};
-struct lkasession {
- SPLAY_ENTRY(lkasession) nodes;
+struct lka_session {
+ SPLAY_ENTRY(lka_session) nodes;
u_int64_t id;
- struct path path;
- struct deliverylist deliverylist;
-
+ struct deliverylist deliverylist;
struct expandtree expandtree;
u_int8_t iterations;
u_int32_t pending;
- enum lkasession_flags flags;
- struct envelope message;
+ enum lka_session_flags flags;
struct submit_status ss;
};
@@ -910,8 +922,8 @@ extern void (*imsg_callback)(struct imsgev *, struct imsg *);
int aliases_exist(objid_t, char *);
int aliases_get(objid_t, struct expandtree *, char *);
int aliases_vdomain_exists(objid_t, char *);
-int aliases_virtual_exist(objid_t, struct path *);
-int aliases_virtual_get(objid_t, struct expandtree *, struct path *);
+int aliases_virtual_exist(objid_t, struct mailaddr *);
+int aliases_virtual_get(objid_t, struct expandtree *, struct mailaddr *);
int alias_parse(struct expandnode *, char *);
@@ -969,13 +981,18 @@ RB_PROTOTYPE(expandtree, expandnode, nodes, expand_cmp);
/* forward.c */
-int forwards_get(int, struct expandtree *);
+int forwards_get(int, struct expandtree *, char *);
/* lka.c */
pid_t lka(void);
-int lkasession_cmp(struct lkasession *, struct lkasession *);
-SPLAY_PROTOTYPE(lkatree, lkasession, nodes, lkasession_cmp);
+int lka_session_cmp(struct lka_session *, struct lka_session *);
+SPLAY_PROTOTYPE(lkatree, lka_session, nodes, lka_session_cmp);
+
+/* lka_session.c */
+struct lka_session *lka_session_init(struct submit_status *);
+void lka_session_fail(struct lka_session *);
+void lka_session_destroy(struct lka_session *);
/* map.c */
@@ -1109,7 +1126,7 @@ int bsnprintf(char *, size_t, const char *, ...)
__attribute__ ((format (printf, 3, 4)));
int safe_fclose(FILE *);
int hostname_match(char *, char *);
-int recipient_to_path(struct path *, char *);
+int email_to_mailaddr(struct mailaddr *, char *);
int valid_localpart(char *);
int valid_domainpart(char *);
char *ss_to_text(struct sockaddr_storage *);
@@ -1118,10 +1135,9 @@ int valid_message_uid(char *);
char *time_to_text(time_t);
int secure_file(int, char *, struct passwd *, int);
void lowercase(char *, char *, size_t);
-void message_set_errormsg(struct envelope *, char *, ...);
-char *message_get_errormsg(struct envelope *);
+void envelope_set_errormsg(struct envelope *, char *, ...);
+char *envelope_get_errormsg(struct envelope *);
void sa_set_port(struct sockaddr *, int);
-struct path *path_dup(struct path *);
u_int64_t generate_uid(void);
void fdlimit(double);
int availdesc(void);
diff --git a/usr.sbin/smtpd/smtpd/Makefile b/usr.sbin/smtpd/smtpd/Makefile
index df5313662b0..b3a249c184e 100644
--- a/usr.sbin/smtpd/smtpd/Makefile
+++ b/usr.sbin/smtpd/smtpd/Makefile
@@ -1,14 +1,14 @@
-# $OpenBSD: Makefile,v 1.24 2011/04/14 17:06:43 gilles Exp $
+# $OpenBSD: Makefile,v 1.25 2011/05/16 21:05:52 gilles Exp $
PROG= smtpd
SRCS= aliases.c authenticate.c bounce.c client.c \
config.c control.c dns.c expand.c forward.c \
- lka.c log.c map.c map_backend.c map_parser.c mda.c \
- mfa.c mta.c parse.y queue.c queue_shared.c ruleset.c \
- runner.c smtp.c smtp_session.c smtpd.c ssl.c \
- ssl_privsep.c util.c asr.c print.c pack.c dname.c \
- res_random.c sockaddr.c ramqueue.c queue_backend.c \
- queue_fsqueue.c
+ lka.c lka_session.c log.c map.c map_backend.c \
+ map_parser.c mda.c mfa.c mta.c parse.y queue.c \
+ queue_shared.c ruleset.c runner.c smtp.c smtp_session.c \
+ smtpd.c ssl.c ssl_privsep.c util.c asr.c print.c pack.c \
+ dname.c res_random.c sockaddr.c ramqueue.c \
+ queue_backend.c queue_fsqueue.c
MAN= smtpd.8 smtpd.conf.5
BINDIR= /usr/sbin
diff --git a/usr.sbin/smtpd/util.c b/usr.sbin/smtpd/util.c
index b0dc7a31865..5bdebec267d 100644
--- a/usr.sbin/smtpd/util.c
+++ b/usr.sbin/smtpd/util.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: util.c,v 1.45 2011/05/14 11:04:42 gilles Exp $ */
+/* $OpenBSD: util.c,v 1.46 2011/05/16 21:05:52 gilles Exp $ */
/*
* Copyright (c) 2000,2001 Markus Friedl. All rights reserved.
@@ -110,40 +110,6 @@ hostname_match(char *hostname, char *pattern)
}
int
-recipient_to_path(struct path *path, char *recipient)
-{
- char *username;
- char *hostname;
-
- username = recipient;
- hostname = strrchr(username, '@');
-
- if (username[0] == '\0') {
- *path->user = '\0';
- *path->domain = '\0';
- return 1;
- }
-
- if (hostname == NULL) {
- if (strcasecmp(username, "postmaster") != 0)
- return 0;
- hostname = "localhost";
- } else {
- *hostname++ = '\0';
- }
-
- if (strlcpy(path->user, username, sizeof(path->user))
- >= sizeof(path->user))
- return 0;
-
- if (strlcpy(path->domain, hostname, sizeof(path->domain))
- >= sizeof(path->domain))
- return 0;
-
- return 1;
-}
-
-int
valid_localpart(char *s)
{
#define IS_ATEXT(c) (isalnum((int)(c)) || strchr("!#$%&'*+-/=?^_`{|}~", (c)))
@@ -186,6 +152,40 @@ nextsub:
return 1;
}
+int
+email_to_mailaddr(struct mailaddr *maddr, char *email)
+{
+ char *username;
+ char *hostname;
+
+ username = email;
+ hostname = strrchr(username, '@');
+
+ if (username[0] == '\0') {
+ *maddr->user = '\0';
+ *maddr->domain = '\0';
+ return 1;
+ }
+
+ if (hostname == NULL) {
+ if (strcasecmp(username, "postmaster") != 0)
+ return 0;
+ hostname = "localhost";
+ } else {
+ *hostname++ = '\0';
+ }
+
+ if (strlcpy(maddr->user, username, sizeof(maddr->user))
+ >= sizeof(maddr->user))
+ return 0;
+
+ if (strlcpy(maddr->domain, hostname, sizeof(maddr->domain))
+ >= sizeof(maddr->domain))
+ return 0;
+
+ return 1;
+}
+
char *
ss_to_text(struct sockaddr_storage *ss)
{
@@ -345,16 +345,16 @@ lowercase(char *buf, char *s, size_t len)
}
void
-message_set_errormsg(struct envelope *m, char *fmt, ...)
+envelope_set_errormsg(struct envelope *e, char *fmt, ...)
{
int ret;
va_list ap;
va_start(ap, fmt);
- ret = vsnprintf(m->session_errorline, MAX_LINE_SIZE, fmt, ap);
+ ret = vsnprintf(e->delivery.errorline, MAX_LINE_SIZE, fmt, ap);
if (ret >= MAX_LINE_SIZE)
- strlcpy(m->session_errorline + (MAX_LINE_SIZE - 4), "...", 4);
+ strlcpy(e->delivery.errorline + (MAX_LINE_SIZE - 4), "...", 4);
/* this should not happen */
if (ret == -1)
@@ -364,9 +364,9 @@ message_set_errormsg(struct envelope *m, char *fmt, ...)
}
char *
-message_get_errormsg(struct envelope *m)
+envelope_get_errormsg(struct envelope *e)
{
- return m->session_errorline;
+ return e->delivery.errorline;
}
void
@@ -395,20 +395,6 @@ sa_set_port(struct sockaddr *sa, int port)
freeaddrinfo(res);
}
-struct path *
-path_dup(struct path *path)
-{
- struct path *pathp;
-
- pathp = calloc(sizeof(struct path), 1);
- if (pathp == NULL)
- fatal("calloc");
-
- *pathp = *path;
-
- return pathp;
-}
-
u_int64_t
generate_uid(void)
{