]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-smtp: smtp-server-command - Always call the NEXT_TO_REPLY hook.
authorStephan Bosch <stephan.bosch@open-xchange.com>
Mon, 31 Aug 2020 12:58:44 +0000 (14:58 +0200)
committeraki.tuomi <aki.tuomi@open-xchange.com>
Thu, 10 Sep 2020 12:43:56 +0000 (12:43 +0000)
Before, it wasn't called when a reply was submitted before the command became
next to reply.

src/lib-smtp/smtp-server-cmd-mail.c
src/lib-smtp/smtp-server-cmd-rcpt.c
src/lib-smtp/smtp-server-command.c
src/lib-smtp/smtp-server-connection.c

index b46609c1a0ade5af69520d4b329800698e126344..7fcebb1fa6e73744c221eaa36c329f48c3c2446b 100644 (file)
 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 (smtp_server_command_is_replied(command) &&
+           !smtp_server_command_replied_success(command) &&
+           !smtp_server_command_reply_is_forwarded(command))
+               return FALSE;
 
        if (conn->state.trans != NULL) {
                smtp_server_reply(cmd, 503, "5.5.0", "MAIL already given");
@@ -33,10 +39,11 @@ cmd_mail_completed(struct smtp_server_cmd_ctx *cmd,
        conn->state.pending_mail_cmds--;
 
        i_assert(smtp_server_command_is_replied(command));
+       i_assert(conn->state.state == SMTP_SERVER_STATE_MAIL_FROM ||
+                !smtp_server_command_replied_success(command));
+
        if (!smtp_server_command_replied_success(command)) {
-               /* Failure; substitute our own error if predictable */
-               if (smtp_server_command_reply_is_forwarded(command))
-                       (void)cmd_mail_check_state(cmd);
+               /* Failure */
                return;
        }
 
index 2be4f6aee440a5dc88ea86a7228094ae9be3ed54..1a4a0014dd4c759c0564d9346bd4dda10007f42b 100644 (file)
@@ -26,8 +26,14 @@ cmd_rcpt_destroy(struct smtp_server_cmd_ctx *cmd ATTR_UNUSED,
 static bool cmd_rcpt_check_state(struct smtp_server_cmd_ctx *cmd)
 {
        struct smtp_server_connection *conn = cmd->conn;
+       struct smtp_server_command *command = cmd->cmd;
        struct smtp_server_transaction *trans = conn->state.trans;
 
+       if (smtp_server_command_is_replied(command) &&
+           !smtp_server_command_replied_success(command) &&
+           !smtp_server_command_reply_is_forwarded(command))
+               return FALSE;
+
        if (conn->state.pending_mail_cmds == 0 && trans == NULL) {
                smtp_server_reply(cmd,
                        503, "5.5.0", "MAIL needed first");
@@ -55,21 +61,13 @@ cmd_rcpt_completed(struct smtp_server_cmd_ctx *cmd,
        i_assert(conn->state.pending_rcpt_cmds > 0);
        conn->state.pending_rcpt_cmds--;
 
-       if (conn->state.state < SMTP_SERVER_STATE_RCPT_TO) {
-               i_assert(conn->state.state == SMTP_SERVER_STATE_MAIL_FROM);
-               smtp_server_connection_set_state(
-                       conn, SMTP_SERVER_STATE_RCPT_TO,
-                       smtp_address_encode(data->rcpt->path));
-       }
-
        i_assert(smtp_server_command_is_replied(command));
+       i_assert(conn->state.state == SMTP_SERVER_STATE_RCPT_TO ||
+                !smtp_server_command_replied_success(command));
+
        if (!smtp_server_command_replied_success(command)) {
+               /* Failure */
                conn->state.denied_rcpt_cmds++;
-
-               /* Failure; substitute our own error if predictable */
-               if (smtp_server_command_reply_is_forwarded(command))
-                       (void)cmd_rcpt_check_state(cmd);
-
                smtp_server_recipient_denied(
                        rcpt, smtp_server_command_get_reply(cmd->cmd, 0));
                return;
index 6edabf46c0127dc6d753c5e59f4c5680421fd887..8281d18b6df0cbbc0e4b7d690322d69079f2d827 100644 (file)
@@ -465,8 +465,12 @@ bool smtp_server_command_next_to_reply(struct smtp_server_command **_cmd)
 
        e_debug(cmd->context.event, "Next to reply");
 
-       return smtp_server_command_call_hooks(
-               _cmd, SMTP_SERVER_COMMAND_HOOK_NEXT, TRUE);
+       if (!smtp_server_command_call_hooks(
+               _cmd, SMTP_SERVER_COMMAND_HOOK_NEXT, TRUE))
+               return FALSE;
+
+       smtp_server_command_remove_hooks(cmd, SMTP_SERVER_COMMAND_HOOK_NEXT);
+       return TRUE;
 }
 
 void smtp_server_command_ready_to_reply(struct smtp_server_command *cmd)
@@ -568,8 +572,6 @@ void smtp_server_command_submit_reply(struct smtp_server_command *cmd)
 
        i_assert(submitted == cmd->replies_submitted);
 
-       smtp_server_command_remove_hooks(cmd, SMTP_SERVER_COMMAND_HOOK_NEXT);
-
        /* Limit number of consecutive bad commands */
        if (is_bad)
                conn->bad_counter++;
index ad70ad7f3d7e057fb9ea203c63c408134762a430..3cd79cf0a64b934a03b5d866b4a0b0919bcaed4e 100644 (file)
@@ -638,10 +638,10 @@ smtp_server_connection_next_reply(struct smtp_server_connection *conn)
                return FALSE;
        }
 
-       if (cmd->state < SMTP_SERVER_COMMAND_STATE_READY_TO_REPLY) {
-               (void)smtp_server_command_next_to_reply(&cmd);
+       if (!smtp_server_command_next_to_reply(&cmd))
+               return FALSE;
+       if (cmd->state < SMTP_SERVER_COMMAND_STATE_READY_TO_REPLY)
                return FALSE;
-       }
 
        i_assert(cmd->state == SMTP_SERVER_COMMAND_STATE_READY_TO_REPLY &&
                 array_is_created(&cmd->replies));