]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-smtp: server: Record the associated server command in the recipient object.
authorStephan Bosch <stephan.bosch@dovecot.fi>
Sun, 7 Oct 2018 16:37:48 +0000 (18:37 +0200)
committerVille Savolainen <ville.savolainen@dovecot.fi>
Tue, 12 Feb 2019 13:41:02 +0000 (15:41 +0200)
This avoids the need to do that in application code.

src/lib-smtp/smtp-server-cmd-data.c
src/lib-smtp/smtp-server-cmd-rcpt.c
src/lib-smtp/smtp-server-private.h
src/lib-smtp/smtp-server-recipient.c
src/lib-smtp/smtp-server-transaction.c
src/lib-smtp/smtp-server.h
src/lmtp/lmtp-common.c
src/lmtp/lmtp-common.h
src/lmtp/lmtp-local.c
src/lmtp/lmtp-proxy.c

index 3087b34b2d98fa5ee5d1ace72848fb658c669266..4bf6bf4110ab3b87cacfa26666704c83a339df68 100644 (file)
@@ -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);
index 21afee42d51896cc4f7e61e4980c9f396834df35..df76a0d32d111f244f0c475d50a2b697a1f7be8c 100644 (file)
@@ -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;
index f537a9bbea9e9e381b2a78c44079c645d0b6d6f8..af8a447fa7a87990bef0ee1c26761947cd093469 100644 (file)
@@ -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
  */
index 8e384c4cec9a842fdd6ad01895ef836a64f3e558..6d99e603ecf7e36e7de2472f0d3eab1b53860bbe 100644 (file)
@@ -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,
index 3613626de591a83a2d85b225fe3c8d74eea635d1..08227c765945f23b560f27ab8adc8b75b6b23d17 100644 (file)
@@ -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,
index 32abb883d1bc06da630c954ea4fb16497f20a0ef..e632ab40f391001ba03951136126bb8e6ac36241 100644 (file)
@@ -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;
 };
 
index 1bd143bfb19a833d9bd22c8182dcc164877aa018..f3a21540495b772794a25aae678e861c18479fb1 100644 (file)
@@ -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)
index 5325f73d171f9112609f12f10ad347d404114afa..80922f327a34b9f4d2962f70819de86a4caae93a 100644 (file)
@@ -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);
index 4e8e68272b26a7bb648bbd224fb67a96d2684fab..6c81bee5885d413231263f6cad66c26e44065c61 100644 (file)
@@ -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;
index a8b8e3ae1c97e248d10b00dfa26d77d6371407c5..aefee98ce90981df5c404df54849cd1516dca03d 100644 (file)
@@ -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;