-/* $OpenBSD: smtp_session.c,v 1.277 2016/06/23 11:56:19 eric Exp $ */
+/* $OpenBSD: smtp_session.c,v 1.278 2016/06/29 06:46:06 eric Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@poolp.org>
SF_BADINPUT = 0x0080,
SF_FILTERCONN = 0x0100,
SF_FILTERDATA = 0x0200,
+ SF_FILTERTX = 0x0400,
};
enum message_flags {
static void smtp_filter_connect(struct smtp_session *, struct sockaddr *);
static void smtp_filter_rset(struct smtp_session *);
static void smtp_filter_disconnect(struct smtp_session *);
-static void smtp_filter_commit(struct smtp_session *);
-static void smtp_filter_rollback(struct smtp_session *);
+static void smtp_filter_tx_begin(struct smtp_session *);
+static void smtp_filter_tx_commit(struct smtp_session *);
+static void smtp_filter_tx_rollback(struct smtp_session *);
static void smtp_filter_eom(struct smtp_session *);
static void smtp_filter_helo(struct smtp_session *);
static void smtp_filter_mail(struct smtp_session *);
break;
case LKA_PERMFAIL:
+ smtp_filter_tx_rollback(s);
smtp_reply(s, "%d %s", 530, "Sender rejected");
io_reload(&s->io);
break;
case LKA_TEMPFAIL:
+ smtp_filter_tx_rollback(s);
smtp_reply(s, "421 %s: Temporary Error",
esc_code(ESC_STATUS_TEMPFAIL, ESC_OTHER_MAIL_SYSTEM_STATUS));
io_reload(&s->io);
smtp_reply(s, "250 %s: Ok",
esc_code(ESC_STATUS_OK, ESC_OTHER_STATUS));
} else {
+ smtp_filter_tx_rollback(s);
smtp_reply(s, "421 %s: Temporary Error",
esc_code(ESC_STATUS_TEMPFAIL, ESC_OTHER_MAIL_SYSTEM_STATUS));
smtp_enter_state(s, STATE_QUIT);
m_end(&m);
s = tree_xpop(&wait_queue_commit, reqid);
if (!success) {
- smtp_filter_rollback(s);
+ smtp_filter_tx_rollback(s);
smtp_reply(s, "421 %s: Temporary failure",
esc_code(ESC_STATUS_TEMPFAIL, ESC_OTHER_MAIL_SYSTEM_STATUS));
smtp_enter_state(s, STATE_QUIT);
return;
}
- smtp_filter_commit(s);
+ smtp_filter_tx_commit(s);
smtp_reply(s, "250 %s: %08x Message accepted for delivery",
esc_code(ESC_STATUS_OK, ESC_OTHER_STATUS),
evpid_to_msgid(s->tx->evp.id));
case QUERY_MAIL:
if (status != FILTER_OK) {
- smtp_filter_rollback(s);
+ smtp_filter_tx_rollback(s);
code = code ? code : 530;
line = line ? line : "Sender rejected";
smtp_reply(s, "%d %s", code, line);
case QUERY_EOM:
if (status != FILTER_OK) {
tree_pop(&wait_filter_data, s->id);
- smtp_filter_rollback(s);
+ smtp_filter_tx_rollback(s);
smtp_queue_rollback(s);
code = code ? code : 530;
line = line ? line : "Message rejected";
tree_pop(&wait_filter_data, s->id);
- smtp_filter_rollback(s);
+ smtp_filter_tx_rollback(s);
smtp_queue_rollback(s);
if (s->tx->msgflags & MF_ERROR_SIZE)
if (args && smtp_parse_mail_args(s, args) == -1)
break;
+ smtp_filter_tx_begin(s);
smtp_filter_mail(s);
break;
/*
break;
}
- smtp_filter_rset(s);
-
+ if (s->flags & SF_FILTERTX)
+ smtp_filter_tx_rollback(s);
if (s->tx->evp.id)
smtp_queue_rollback(s);
+ smtp_filter_rset(s);
+
s->phase = PHASE_SETUP;
smtp_message_reset(s, 0);
smtp_reply(s, "250 %s: Reset state",
s->phase = PHASE_SETUP;
if (s->tx->msgflags & MF_ERROR) {
+ smtp_filter_tx_rollback(s);
smtp_queue_rollback(s);
if (s->tx->msgflags & MF_ERROR_SIZE)
smtp_reply(s, "554 %s %s: Transaction failed, message too big",
iobuf_clear(&s->tx->obuf);
}
+ if (s->flags & SF_FILTERTX)
+ smtp_filter_tx_rollback(s);
+
if (s->flags & SF_FILTERCONN)
smtp_filter_disconnect(s);
}
static void
-smtp_filter_commit(struct smtp_session *s)
+smtp_filter_tx_begin(struct smtp_session *s)
+{
+ s->flags |= SF_FILTERTX;
+ filter_event(s->id, EVENT_TX_BEGIN);
+}
+
+static void
+smtp_filter_tx_commit(struct smtp_session *s)
{
- filter_event(s->id, EVENT_COMMIT);
+ s->flags &= ~SF_FILTERTX;
+ filter_event(s->id, EVENT_TX_COMMIT);
}
static void
-smtp_filter_rollback(struct smtp_session *s)
+smtp_filter_tx_rollback(struct smtp_session *s)
{
- filter_event(s->id, EVENT_ROLLBACK);
+ s->flags &= ~SF_FILTERTX;
+ filter_event(s->id, EVENT_TX_ROLLBACK);
}
static void