From: Stephan Bosch Date: Fri, 23 Feb 2018 19:43:50 +0000 (+0100) Subject: lib-smtp: client: transaction: Don't call the DATA callbacks upon failure until the... X-Git-Tag: 2.3.9~2233 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=85a18b9917057acd6f1f718541adc0c7d149f6ee;p=thirdparty%2Fdovecot%2Fcore.git lib-smtp: client: transaction: Don't call the DATA callbacks upon failure until the transaction is complete. The transaction is not complete until smtp_client_transaction_send() is called. --- diff --git a/src/lib-smtp/smtp-client-private.h b/src/lib-smtp/smtp-client-private.h index 3775f0f138..d10aa134bb 100644 --- a/src/lib-smtp/smtp-client-private.h +++ b/src/lib-smtp/smtp-client-private.h @@ -99,6 +99,7 @@ struct smtp_client_transaction { unsigned int finish_timeout_msecs; struct timeout *to_finish, *to_send; + bool data_provided:1; bool finished:1; bool submitted_data:1; }; diff --git a/src/lib-smtp/smtp-client-transaction.c b/src/lib-smtp/smtp-client-transaction.c index ca5933c174..dc78e6a15a 100644 --- a/src/lib-smtp/smtp-client-transaction.c +++ b/src/lib-smtp/smtp-client-transaction.c @@ -356,9 +356,16 @@ void smtp_client_transaction_fail_reply(struct smtp_client_transaction *trans, } } - if (trans->cmd_data != NULL) + if (!trans->data_provided) { + /* smtp_client_transaction_send() was not called yet + */ + } else if (trans->cmd_data != NULL) { + /* the DATA command is still pending; handle the failure by + failing the DATA command. */ smtp_client_command_fail_reply(&trans->cmd_data, reply); - else { + } else { + /* the DATA command was not sent yet; call all DATA callbacks + for the recipients that were previously accepted. */ rcpts = array_get_modifiable(&trans->rcpts, &count); for (i = trans->rcpt_next_data_idx; i < count; i++) { if (rcpts[i]->data_callback != NULL) { @@ -379,9 +386,9 @@ void smtp_client_transaction_fail_reply(struct smtp_client_transaction *trans, smtp_client_command_abort(&trans->cmd_plug); trans->cmd_plug = NULL; - if (trans->data_input != NULL) { - /* abort the transaction if it is complete - (if it is not aborted already) */ + if (trans->data_provided) { + /* abort the transaction only if smtp_client_transaction_send() + was called (and if it is not aborted already) */ smtp_client_transaction_abort(trans); } @@ -732,6 +739,8 @@ void smtp_client_transaction_send( smtp_client_transaction_debug(trans, "Send"); + trans->data_provided = TRUE; + i_assert(trans->data_input == NULL); trans->data_input = data_input; i_stream_ref(data_input);