]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-smtp: server: MAIL command: Reliably start the transaction when several MAIL...
authorStephan Bosch <stephan.bosch@dovecot.fi>
Thu, 27 Sep 2018 20:16:56 +0000 (22:16 +0200)
committerAki Tuomi <aki.tuomi@open-xchange.com>
Wed, 10 Oct 2018 09:49:07 +0000 (09:49 +0000)
src/lib-smtp/smtp-server-cmd-mail.c

index 13a71adc82104110c78e7eeeb1bf111a9df61c06..7b6cad0a554975f4deeaa7fe25764f34712e38f6 100644 (file)
@@ -19,15 +19,8 @@ static bool
 cmd_mail_check_state(struct smtp_server_cmd_ctx *cmd)
 {
        struct smtp_server_connection *conn = cmd->conn;
-       struct smtp_server_command *command = cmd->cmd;
 
        if (conn->state.trans != NULL) {
-               if (!smtp_server_command_is_replied(command)) {
-                       conn->state.pending_mail_cmds--;
-                       smtp_server_command_remove_hook(
-                               command, SMTP_SERVER_COMMAND_HOOK_REPLIED,
-                               cmd_mail_replied);
-               }
                smtp_server_reply(cmd, 503, "5.5.0", "MAIL already given");
                return FALSE;
        }
@@ -35,8 +28,8 @@ cmd_mail_check_state(struct smtp_server_cmd_ctx *cmd)
 }
 
 static void
-cmd_mail_replied(struct smtp_server_cmd_ctx *cmd,
-                struct smtp_server_cmd_mail *data)
+cmd_mail_completed(struct smtp_server_cmd_ctx *cmd,
+                  struct smtp_server_cmd_mail *data)
 {
        struct smtp_server_connection *conn = cmd->conn;
        struct smtp_server_command *command = cmd->cmd;
@@ -45,11 +38,8 @@ cmd_mail_replied(struct smtp_server_cmd_ctx *cmd,
        conn->state.pending_mail_cmds--;
 
        i_assert(smtp_server_command_is_replied(command));
-       if (!smtp_server_command_replied_success(command)) {
-               /* failure; substitute our own error if predictable */
-               (void)cmd_mail_check_state(cmd);
+       if (!smtp_server_command_replied_success(command))
                return;
-       }
 
        /* success */
        conn->state.trans = smtp_server_transaction_create(conn,
@@ -62,6 +52,20 @@ cmd_mail_replied(struct smtp_server_cmd_ctx *cmd,
        }
 }
 
+static void
+cmd_mail_replied(struct smtp_server_cmd_ctx *cmd,
+                struct smtp_server_cmd_mail *data ATTR_UNUSED)
+{
+       struct smtp_server_command *command = cmd->cmd;
+
+       i_assert(smtp_server_command_is_replied(command));
+       if (!smtp_server_command_replied_success(command)) {
+               /* failure; substitute our own error if predictable */
+               (void)cmd_mail_check_state(cmd);
+               return;
+       }
+}
+
 static void
 cmd_mail_recheck(struct smtp_server_cmd_ctx *cmd,
                 struct smtp_server_cmd_mail *data ATTR_UNUSED)
@@ -179,6 +183,8 @@ void smtp_server_cmd_mail(struct smtp_server_cmd_ctx *cmd,
                                     cmd_mail_recheck, mail_data);
        smtp_server_command_add_hook(command, SMTP_SERVER_COMMAND_HOOK_REPLIED,
                                     cmd_mail_replied, mail_data);
+       smtp_server_command_add_hook(command, SMTP_SERVER_COMMAND_HOOK_COMPLETED,
+                                    cmd_mail_completed, mail_data);
 
        smtp_server_connection_set_state(conn, SMTP_SERVER_STATE_MAIL_FROM);
        conn->state.pending_mail_cmds++;