bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2013-2018 Dovecot authors, see the included COPYING file */
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch/* RCPT command */
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschcmd_rcpt_check_state(struct smtp_server_cmd_ctx *cmd)
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch struct smtp_server_connection *conn = cmd->conn;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch struct smtp_server_command *command = cmd->cmd;
4dd460cf19f1df3b51090427fea87e9c4b73c6d4Stephan Bosch struct smtp_server_transaction *trans = conn->state.trans;
4dd460cf19f1df3b51090427fea87e9c4b73c6d4Stephan Bosch if (conn->state.pending_mail_cmds == 0 && trans == NULL) {
4dd460cf19f1df3b51090427fea87e9c4b73c6d4Stephan Bosch if (conn->set.max_recipients > 0 && trans != NULL &&
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschstatic void cmd_rcpt_completed(struct smtp_server_cmd_ctx *cmd)
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch struct smtp_server_connection *conn = cmd->conn;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch struct smtp_server_command *command = cmd->cmd;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch struct smtp_server_transaction *trans = conn->state.trans;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch i_assert(smtp_server_command_is_replied(command));
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch if (!smtp_server_command_replied_success(command))
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch /* success */
5d5ad796fc34170333bb52c05614425a0dd7e182Stephan Bosch rcpt = smtp_server_transaction_add_rcpt(trans, data->path,
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschstatic void cmd_rcpt_replied(struct smtp_server_cmd_ctx *cmd)
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch struct smtp_server_command *command = cmd->cmd;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch i_assert(smtp_server_command_is_replied(command));
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch if (!smtp_server_command_replied_success(command)) {
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch /* failure; substitute our own error if predictable */
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschstatic void cmd_rcpt_recheck(struct smtp_server_cmd_ctx *cmd)
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch struct smtp_server_connection *conn = cmd->conn;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch /* all preceeding commands have finished and now the transaction state
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch is clear. This provides the opportunity to re-check the transaction
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch state and abort the pending proxied mail command if it is bound to
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch /* Advance state */
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch smtp_server_connection_set_state(conn, SMTP_SERVER_STATE_RCPT_TO);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschvoid smtp_server_cmd_rcpt(struct smtp_server_cmd_ctx *cmd,
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch struct smtp_server_connection *conn = cmd->conn;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch const struct smtp_server_settings *set = &conn->set;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch enum smtp_capability caps = set->capabilities;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch const struct smtp_server_callbacks *callbacks = conn->callbacks;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch struct smtp_server_command *command = cmd->cmd;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch /* rcpt = "RCPT TO:" ( "<Postmaster@" Domain ">" /
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch "<Postmaster>" / Forward-path ) [SP Rcpt-parameters] CRLF
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch Forward-path = Path
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch /* check transaction state as far as possible */
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch /* ( "<Postmaster@" Domain ">" / "<Postmaster>" / Forward-path ) */
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch if (params == NULL || strncasecmp(params, "TO:", 3) != 0) {
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch if (smtp_address_parse_path_full(pool_datastack_create(), params + 3,
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch "Invalid TO: Invalid character in path");
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch if (path->domain == NULL && !conn->set.rcpt_domain_optional &&
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch strcasecmp(path->localpart, "postmaster") != 0) {
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch rcpt_data = p_new(cmd->pool, struct smtp_server_cmd_rcpt, 1);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch /* [SP Rcpt-parameters] */
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch if (smtp_params_rcpt_parse(cmd->pool, params, caps,
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch rcpt_data->path = smtp_address_clone(cmd->pool, path);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch i_assert(callbacks != NULL && callbacks->conn_cmd_rcpt != NULL);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch if ((ret=callbacks->conn_cmd_rcpt(conn->context,
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch i_assert(ret == 0 || smtp_server_command_is_replied(command));
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch /* command is waiting for external event or it failed */
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch if (!smtp_server_command_is_replied(command)) {
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch /* set generic RCPT success reply if none is provided */