From: Stephan Bosch Date: Sun, 7 Oct 2018 16:37:48 +0000 (+0200) Subject: lib-smtp: server: Record the associated server command in the recipient object. X-Git-Tag: 2.3.9~1208 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0a8512c6141e0432c7b52f21efda3ece06d125fb;p=thirdparty%2Fdovecot%2Fcore.git lib-smtp: server: Record the associated server command in the recipient object. This avoids the need to do that in application code. --- diff --git a/src/lib-smtp/smtp-server-cmd-data.c b/src/lib-smtp/smtp-server-cmd-data.c index 3087b34b2d..4bf6bf4110 100644 --- a/src/lib-smtp/smtp-server-cmd-data.c +++ b/src/lib-smtp/smtp-server-cmd-data.c @@ -333,6 +333,7 @@ cmd_data_next(struct smtp_server_cmd_ctx *cmd, struct cmd_data_context *data_cmd) { struct smtp_server_connection *conn = cmd->conn; + struct smtp_server_transaction *trans = conn->state.trans; const struct smtp_server_callbacks *callbacks = conn->callbacks; struct smtp_server_command *command = cmd->cmd; int ret; @@ -342,6 +343,7 @@ cmd_data_next(struct smtp_server_cmd_ctx *cmd, i_assert(data_cmd != NULL); i_assert(conn->state.pending_mail_cmds == 0 && conn->state.pending_rcpt_cmds == 0); + i_assert(trans != NULL); smtp_server_command_debug(cmd, "Command is next to be replied"); @@ -350,12 +352,16 @@ cmd_data_next(struct smtp_server_cmd_ctx *cmd, if (!smtp_server_connection_data_check_state(cmd)) return; - /* LMTP 'DATA' and 'BDAT LAST' commands need to send one reply - per recipient - */ - if (data_cmd->chunk_last && conn->set.protocol == SMTP_PROTOCOL_LMTP) { - smtp_server_command_set_reply_count(command, - array_count(&conn->state.trans->rcpt_to)); + if (data_cmd->chunk_last) { + /* This is the last chunk */ + smtp_server_transaction_last_data(trans, cmd); + + /* LMTP 'DATA' and 'BDAT LAST' commands need to send more than + one reply per recipient */ + if (conn->set.protocol == SMTP_PROTOCOL_LMTP) { + smtp_server_command_set_reply_count(command, + array_count(&trans->rcpt_to)); + } } smtp_server_connection_set_state(conn, SMTP_SERVER_STATE_DATA); diff --git a/src/lib-smtp/smtp-server-cmd-rcpt.c b/src/lib-smtp/smtp-server-cmd-rcpt.c index 21afee42d5..df76a0d32d 100644 --- a/src/lib-smtp/smtp-server-cmd-rcpt.c +++ b/src/lib-smtp/smtp-server-cmd-rcpt.c @@ -157,7 +157,7 @@ void smtp_server_cmd_rcpt(struct smtp_server_cmd_ctx *cmd, return; } - rcpt = smtp_server_recipient_create(conn, path); + rcpt = smtp_server_recipient_create(cmd, path); rcpt_data = p_new(cmd->pool, struct smtp_server_cmd_rcpt, 1); rcpt_data->rcpt = rcpt; diff --git a/src/lib-smtp/smtp-server-private.h b/src/lib-smtp/smtp-server-private.h index f537a9bbea..af8a447fa7 100644 --- a/src/lib-smtp/smtp-server-private.h +++ b/src/lib-smtp/smtp-server-private.h @@ -370,11 +370,13 @@ void smtp_server_connection_set_proxy_data(struct smtp_server_connection *conn, */ struct smtp_server_recipient * -smtp_server_recipient_create(struct smtp_server_connection *conn, +smtp_server_recipient_create(struct smtp_server_cmd_ctx *cmd, const struct smtp_address *rcpt_to); void smtp_server_recipient_destroy(struct smtp_server_recipient **_rcpt); void smtp_server_recipient_approved(struct smtp_server_recipient *rcpt); +void smtp_server_recipient_last_data(struct smtp_server_recipient *rcpt, + struct smtp_server_cmd_ctx *cmd); /* * Transaction @@ -393,6 +395,10 @@ bool smtp_server_transaction_has_rcpt(struct smtp_server_transaction *trans); unsigned int smtp_server_transaction_rcpt_count(struct smtp_server_transaction *trans); + +void smtp_server_transaction_last_data(struct smtp_server_transaction *trans, + struct smtp_server_cmd_ctx *cmd); + /* * Server */ diff --git a/src/lib-smtp/smtp-server-recipient.c b/src/lib-smtp/smtp-server-recipient.c index 8e384c4cec..6d99e603ec 100644 --- a/src/lib-smtp/smtp-server-recipient.c +++ b/src/lib-smtp/smtp-server-recipient.c @@ -11,7 +11,7 @@ smtp_server_recipient_call_hooks(struct smtp_server_recipient *rcpt, enum smtp_server_recipient_hook_type type); struct smtp_server_recipient * -smtp_server_recipient_create(struct smtp_server_connection *conn, +smtp_server_recipient_create(struct smtp_server_cmd_ctx *cmd, const struct smtp_address *rcpt_to) { struct smtp_server_recipient_private *prcpt; @@ -20,7 +20,8 @@ smtp_server_recipient_create(struct smtp_server_connection *conn, pool = pool_alloconly_create("smtp server recipient", 512); prcpt = p_new(pool, struct smtp_server_recipient_private, 1); prcpt->rcpt.pool = pool; - prcpt->rcpt.conn = conn; + prcpt->rcpt.conn = cmd->conn; + prcpt->rcpt.cmd = cmd; prcpt->rcpt.path = smtp_address_clone(pool, rcpt_to); return &prcpt->rcpt; @@ -47,12 +48,20 @@ void smtp_server_recipient_approved(struct smtp_server_recipient *rcpt) i_assert(trans != NULL); + rcpt->cmd = NULL; smtp_server_transaction_add_rcpt(trans, rcpt); smtp_server_recipient_call_hooks( rcpt, SMTP_SERVER_RECIPIENT_HOOK_APPROVED); } +void smtp_server_recipient_last_data(struct smtp_server_recipient *rcpt, + struct smtp_server_cmd_ctx *cmd) +{ + i_assert(rcpt->cmd == NULL); + rcpt->cmd = cmd; +} + #undef smtp_server_recipient_add_hook void smtp_server_recipient_add_hook(struct smtp_server_recipient *rcpt, enum smtp_server_recipient_hook_type type, diff --git a/src/lib-smtp/smtp-server-transaction.c b/src/lib-smtp/smtp-server-transaction.c index 3613626de5..08227c7659 100644 --- a/src/lib-smtp/smtp-server-transaction.c +++ b/src/lib-smtp/smtp-server-transaction.c @@ -103,6 +103,18 @@ smtp_server_transaction_rcpt_count(struct smtp_server_transaction *trans) return array_count(&trans->rcpt_to); } +void smtp_server_transaction_last_data(struct smtp_server_transaction *trans, + struct smtp_server_cmd_ctx *cmd) +{ + struct smtp_server_recipient *const *rcptp; + + trans->cmd = cmd; + + i_assert(array_is_created(&trans->rcpt_to)); + array_foreach(&trans->rcpt_to, rcptp) + smtp_server_recipient_last_data(*rcptp, cmd); +} + void smtp_server_transaction_fail_data(struct smtp_server_transaction *trans, struct smtp_server_cmd_ctx *data_cmd, unsigned int status, const char *enh_code, diff --git a/src/lib-smtp/smtp-server.h b/src/lib-smtp/smtp-server.h index 32abb883d1..e632ab40f3 100644 --- a/src/lib-smtp/smtp-server.h +++ b/src/lib-smtp/smtp-server.h @@ -69,6 +69,10 @@ struct smtp_server_recipient { struct smtp_address *path; struct smtp_params_rcpt params; + /* The associated RCPT or DATA command (whichever applies). This is NULL + when no command is active. */ + struct smtp_server_cmd_ctx *cmd; + /* The index in the list of approved recipients */ unsigned int index; @@ -109,6 +113,11 @@ struct smtp_server_transaction { struct smtp_params_mail params; ARRAY_TYPE(smtp_server_recipient) rcpt_to; + /* The associated DATA command. This is NULL until the last DATA/BDAT + command is issued. + */ + struct smtp_server_cmd_ctx *cmd; + void *context; }; diff --git a/src/lmtp/lmtp-common.c b/src/lmtp/lmtp-common.c index 1bd143bfb1..f3a2154049 100644 --- a/src/lmtp/lmtp-common.c +++ b/src/lmtp/lmtp-common.c @@ -7,20 +7,13 @@ void lmtp_recipient_init(struct lmtp_recipient *lrcpt, struct client *client, enum lmtp_recipient_type type, - struct smtp_server_cmd_ctx *cmd, struct smtp_server_recipient *rcpt) { lrcpt->client = client; lrcpt->type = type; - lrcpt->rcpt_cmd = cmd; lrcpt->rcpt = rcpt; } -void lmtp_recipient_finish(struct lmtp_recipient *lrcpt) -{ - lrcpt->rcpt_cmd = NULL; -} - struct lmtp_recipient * lmtp_recipient_find_duplicate(struct lmtp_recipient *lrcpt, struct smtp_server_transaction *trans) diff --git a/src/lmtp/lmtp-common.h b/src/lmtp/lmtp-common.h index 5325f73d17..80922f327a 100644 --- a/src/lmtp/lmtp-common.h +++ b/src/lmtp/lmtp-common.h @@ -16,18 +16,13 @@ struct lmtp_recipient { struct client *client; struct smtp_server_recipient *rcpt; enum lmtp_recipient_type type; - - struct smtp_server_cmd_ctx *rcpt_cmd; }; void lmtp_recipient_init(struct lmtp_recipient *lrcpt, struct client *client, enum lmtp_recipient_type type, - struct smtp_server_cmd_ctx *cmd, struct smtp_server_recipient *rcpt); -void lmtp_recipient_finish(struct lmtp_recipient *lrcpt); - struct lmtp_recipient * lmtp_recipient_find_duplicate(struct lmtp_recipient *lrcpt, struct smtp_server_transaction *trans); diff --git a/src/lmtp/lmtp-local.c b/src/lmtp/lmtp-local.c index 4e8e68272b..6c81bee588 100644 --- a/src/lmtp/lmtp-local.c +++ b/src/lmtp/lmtp-local.c @@ -176,7 +176,7 @@ lmtp_local_rcpt_check_quota(struct lmtp_local_recipient *llrcpt) { struct client *client = llrcpt->rcpt.client; struct smtp_server_recipient *rcpt = llrcpt->rcpt.rcpt; - struct smtp_server_cmd_ctx *cmd = llrcpt->rcpt.rcpt_cmd; + struct smtp_server_cmd_ctx *cmd = rcpt->cmd; struct smtp_address *address = rcpt->path; struct mail_user *user; struct mail_namespace *ns; @@ -241,8 +241,6 @@ lmtp_local_rcpt_approved(struct smtp_server_recipient *rcpt, { struct client *client = llrcpt->rcpt.client; - lmtp_recipient_finish(&llrcpt->rcpt); - /* resolve duplicate recipient */ llrcpt->duplicate = (struct lmtp_local_recipient *) lmtp_recipient_find_duplicate(&llrcpt->rcpt, rcpt->trans); @@ -256,7 +254,8 @@ lmtp_local_rcpt_approved(struct smtp_server_recipient *rcpt, static bool lmtp_local_rcpt_anvil_finish(struct lmtp_local_recipient *llrcpt) { - struct smtp_server_cmd_ctx *cmd = llrcpt->rcpt.rcpt_cmd; + struct smtp_server_recipient *rcpt = llrcpt->rcpt.rcpt; + struct smtp_server_cmd_ctx *cmd = rcpt->cmd; int ret; if ((ret = lmtp_local_rcpt_check_quota(llrcpt)) < 0) @@ -271,9 +270,9 @@ lmtp_local_rcpt_anvil_cb(const char *reply, void *context) { struct lmtp_local_recipient *llrcpt = (struct lmtp_local_recipient *)context; - struct smtp_server_cmd_ctx *cmd = llrcpt->rcpt.rcpt_cmd; struct client *client = llrcpt->rcpt.client; struct smtp_server_recipient *rcpt = llrcpt->rcpt.rcpt; + struct smtp_server_cmd_ctx *cmd = rcpt->cmd; struct smtp_address *address = rcpt->path; const struct mail_storage_service_input *input; unsigned int parallel_count = 0; @@ -359,7 +358,7 @@ int lmtp_local_rcpt(struct client *client, llrcpt = p_new(rcpt->pool, struct lmtp_local_recipient, 1); lmtp_recipient_init(&llrcpt->rcpt, client, - LMTP_RECIPIENT_TYPE_LOCAL, cmd, rcpt); + LMTP_RECIPIENT_TYPE_LOCAL, rcpt); llrcpt->detail = p_strdup(rcpt->pool, detail); llrcpt->service_user = service_user; diff --git a/src/lmtp/lmtp-proxy.c b/src/lmtp/lmtp-proxy.c index a8b8e3ae1c..aefee98ce9 100644 --- a/src/lmtp/lmtp-proxy.c +++ b/src/lmtp/lmtp-proxy.c @@ -434,8 +434,6 @@ lmtp_proxy_rcpt_approved(struct smtp_server_recipient *rcpt ATTR_UNUSED, { struct client *client = lprcpt->rcpt.client; - lmtp_recipient_finish(&lprcpt->rcpt); - /* add to proxy recipients */ array_append(&client->proxy->rcpt_to, &lprcpt, 1); } @@ -444,7 +442,8 @@ static void lmtp_proxy_rcpt_cb(const struct smtp_reply *proxy_reply, struct lmtp_proxy_recipient *lprcpt) { - struct smtp_server_cmd_ctx *cmd = lprcpt->rcpt.rcpt_cmd; + struct smtp_server_recipient *rcpt = lprcpt->rcpt.rcpt; + struct smtp_server_cmd_ctx *cmd = rcpt->cmd; struct smtp_reply reply; if (!lmtp_proxy_handle_reply(cmd, proxy_reply, &reply)) @@ -570,7 +569,7 @@ int lmtp_proxy_rcpt(struct client *client, lprcpt = p_new(rcpt->pool, struct lmtp_proxy_recipient, 1); lmtp_recipient_init(&lprcpt->rcpt, client, - LMTP_RECIPIENT_TYPE_PROXY, cmd, rcpt); + LMTP_RECIPIENT_TYPE_PROXY, rcpt); lprcpt->address = smtp_address_clone(rcpt->pool, address); lprcpt->conn = conn;