]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-smtp: server: Create the definitive recipient object right at the reception of...
authorStephan Bosch <stephan.bosch@dovecot.fi>
Sun, 7 Oct 2018 19:37:00 +0000 (21:37 +0200)
committerStephan Bosch <stephan.bosch@dovecot.fi>
Thu, 11 Oct 2018 12:57:36 +0000 (14:57 +0200)
Before, it first allocated stuff on the command pool, which gets freed when the RCPT
command finishes. Allocating the recipient data on its own pool from the start
considerably simplifies the code and prevents very nasty bugs.

18 files changed:
src/lib-smtp/smtp-server-cmd-rcpt.c
src/lib-smtp/smtp-server.h
src/lib-smtp/test-smtp-payload.c
src/lib-smtp/test-smtp-server-errors.c
src/lmtp/commands.c
src/lmtp/commands.h
src/lmtp/lmtp-common.c
src/lmtp/lmtp-common.h
src/lmtp/lmtp-local.c
src/lmtp/lmtp-local.h
src/lmtp/lmtp-proxy.c
src/lmtp/lmtp-proxy.h
src/submission/submission-backend-relay.c
src/submission/submission-backend.c
src/submission/submission-backend.h
src/submission/submission-client.h
src/submission/submission-commands.c
src/submission/submission-commands.h

index c383bd08b0326cc6150041b352063b573bc1b9cf..21afee42d51896cc4f7e61e4980c9f396834df35 100644 (file)
 
 /* RCPT command */
 
+struct smtp_server_cmd_rcpt {
+       struct smtp_server_recipient *rcpt;
+};
+
+static void
+cmd_rcpt_destroy(struct smtp_server_cmd_ctx *cmd ATTR_UNUSED,
+                struct smtp_server_cmd_rcpt *data)
+{
+       smtp_server_recipient_destroy(&data->rcpt);
+}
+
 static bool
 cmd_rcpt_check_state(struct smtp_server_cmd_ctx *cmd)
 {
@@ -40,8 +51,7 @@ cmd_rcpt_completed(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;
-       struct smtp_server_recipient *rcpt;
+       struct smtp_server_recipient *rcpt = data->rcpt;
 
        i_assert(conn->state.pending_rcpt_cmds > 0);
        conn->state.pending_rcpt_cmds--;
@@ -55,17 +65,8 @@ cmd_rcpt_completed(struct smtp_server_cmd_ctx *cmd,
        }
 
        /* success */
-       rcpt = smtp_server_recipient_create(conn, data->path);
-       smtp_params_rcpt_copy(rcpt->pool, &rcpt->params, &data->params);
-       rcpt->context = data->trans_context;
-
+       data->rcpt = NULL; /* clear to prevent destruction */
        smtp_server_recipient_approved(rcpt);
-
-       if (data->hook_finished != NULL) {
-               data->hook_finished(cmd, trans, rcpt,
-                                   array_count(&trans->rcpt_to) - 1);
-               data->hook_finished = NULL;
-       }
 }
 
 static void
@@ -96,6 +97,7 @@ void smtp_server_cmd_rcpt(struct smtp_server_cmd_ctx *cmd,
        const struct smtp_server_callbacks *callbacks = conn->callbacks;
        struct smtp_server_command *command = cmd->cmd;
        struct smtp_server_cmd_rcpt *rcpt_data;
+       struct smtp_server_recipient *rcpt;
        enum smtp_address_parse_flags path_parse_flags;
        const char *const *param_extensions = NULL;
        struct smtp_address *path;
@@ -155,13 +157,16 @@ void smtp_server_cmd_rcpt(struct smtp_server_cmd_ctx *cmd,
                return;
        }
 
+       rcpt = smtp_server_recipient_create(conn, path);
+
        rcpt_data = p_new(cmd->pool, struct smtp_server_cmd_rcpt, 1);
+       rcpt_data->rcpt = rcpt;
 
        /* [SP Rcpt-parameters] */
        if (array_is_created(&conn->rcpt_param_extensions))
                param_extensions = array_idx(&conn->rcpt_param_extensions, 0);
-       if (smtp_params_rcpt_parse(cmd->pool, params, caps, param_extensions,
-                                  &rcpt_data->params, &pperror, &error) < 0) {
+       if (smtp_params_rcpt_parse(rcpt->pool, params, caps, param_extensions,
+                                  &rcpt->params, &pperror, &error) < 0) {
                switch (pperror) {
                case SMTP_PARAM_PARSE_ERROR_BAD_SYNTAX:
                        smtp_server_reply(cmd,
@@ -177,19 +182,18 @@ void smtp_server_cmd_rcpt(struct smtp_server_cmd_ctx *cmd,
                return;
        }
 
-       rcpt_data->path = smtp_address_clone(cmd->pool, path);
-
        smtp_server_command_add_hook(command, SMTP_SERVER_COMMAND_HOOK_NEXT,
                                     cmd_rcpt_recheck, rcpt_data);
        smtp_server_command_add_hook(command, SMTP_SERVER_COMMAND_HOOK_COMPLETED,
                                     cmd_rcpt_completed, rcpt_data);
-
+       smtp_server_command_add_hook(command, SMTP_SERVER_COMMAND_HOOK_DESTROY,
+                                    cmd_rcpt_destroy, rcpt_data);
+       
        conn->state.pending_rcpt_cmds++;
 
        smtp_server_command_ref(command);
        i_assert(callbacks != NULL && callbacks->conn_cmd_rcpt != NULL);
-       if ((ret=callbacks->conn_cmd_rcpt(conn->context,
-               cmd, rcpt_data)) <= 0) {
+       if ((ret=callbacks->conn_cmd_rcpt(conn->context, cmd, rcpt)) <= 0) {
                i_assert(ret == 0 || smtp_server_command_is_replied(command));
                /* command is waiting for external event or it failed */
                smtp_server_command_unref(&command);
index ac8c60d8c282da60fca67e1b26539835a29044c7..32abb883d1bc06da630c954ea4fb16497f20a0ef 100644 (file)
@@ -145,19 +145,6 @@ struct smtp_server_cmd_mail {
        struct timeval timestamp;
 };
 
-struct smtp_server_cmd_rcpt {
-       struct smtp_address *path;
-       struct smtp_params_rcpt params;
-
-       /* called once the recipient is definitively added to the transaction */
-       void (*hook_finished)(struct smtp_server_cmd_ctx *cmd,
-                             struct smtp_server_transaction *trans,
-                             struct smtp_server_recipient *rcpt,
-                             unsigned int index);
-
-       void *trans_context;
-};
-
 struct smtp_server_cmd_auth {
        const char *sasl_mech;
        const char *initial_response;
@@ -208,7 +195,7 @@ struct smtp_server_callbacks {
        /* RCPT */
        int (*conn_cmd_rcpt)(void *conn_ctx,
                struct smtp_server_cmd_ctx *cmd,
-               struct smtp_server_cmd_rcpt *data);
+               struct smtp_server_recipient *rcpt);
        /* RSET */
        int (*conn_cmd_rset)(void *conn_ctx,
                struct smtp_server_cmd_ctx *cmd);
index 1579b79e3ef1af457c650935f81a184337608918..a3fe0137ca71cf498f30aa3338f4367ed494709d 100644 (file)
@@ -327,11 +327,11 @@ test_server_conn_trans_free(void *context ATTR_UNUSED,
 static int
 test_server_conn_cmd_rcpt(void *conn_ctx ATTR_UNUSED,
        struct smtp_server_cmd_ctx *cmd ATTR_UNUSED,
-       struct smtp_server_cmd_rcpt *data)
+       struct smtp_server_recipient *rcpt)
 {
        if (debug) {
                i_debug("test server: RCPT TO:%s",
-                       smtp_address_encode(data->path));
+                       smtp_address_encode(rcpt->path));
        }
 
        return 1;
index 309022e9720f03a37acebad90bda5b3e12fc2254..afd900244ee16018cb03d22ddae2e9b77067840b 100644 (file)
@@ -382,11 +382,11 @@ test_server_hanging_command_payload_trans_free(void *conn_ctx  ATTR_UNUSED,
 static int
 test_server_hanging_command_payload_rcpt(void *conn_ctx ATTR_UNUSED,
        struct smtp_server_cmd_ctx *cmd ATTR_UNUSED,
-       struct smtp_server_cmd_rcpt *data)
+       struct smtp_server_recipient *rcpt)
 {
        if (debug) {
                i_debug("RCPT TO:%s",
-                       smtp_address_encode(data->path));
+                       smtp_address_encode(rcpt->path));
        }
 
        return 1;
@@ -526,7 +526,7 @@ test_server_bad_command_helo(void *conn_ctx ATTR_UNUSED,
 static int
 test_server_bad_command_rcpt(void *conn_ctx ATTR_UNUSED,
        struct smtp_server_cmd_ctx *cmd ATTR_UNUSED,
-       struct smtp_server_cmd_rcpt *data ATTR_UNUSED)
+       struct smtp_server_recipient *rcpt ATTR_UNUSED)
 {
        return 1;
 }
@@ -620,7 +620,7 @@ test_server_long_command_helo(void *conn_ctx ATTR_UNUSED,
 static int
 test_server_long_command_rcpt(void *conn_ctx ATTR_UNUSED,
        struct smtp_server_cmd_ctx *cmd ATTR_UNUSED,
-       struct smtp_server_cmd_rcpt *data ATTR_UNUSED)
+       struct smtp_server_recipient *rcpt ATTR_UNUSED)
 {
        return 1;
 }
@@ -718,11 +718,11 @@ test_server_big_data_trans_free(void *conn_ctx  ATTR_UNUSED,
 static int
 test_server_big_data_rcpt(void *conn_ctx ATTR_UNUSED,
        struct smtp_server_cmd_ctx *cmd ATTR_UNUSED,
-       struct smtp_server_cmd_rcpt *data)
+       struct smtp_server_recipient *rcpt)
 {
        if (debug) {
                i_debug("RCPT TO:%s",
-                       smtp_address_encode(data->path));
+                       smtp_address_encode(rcpt->path));
        }
        return 1;
 }
@@ -869,7 +869,7 @@ test_server_bad_ehlo_helo(void *conn_ctx ATTR_UNUSED,
 static int
 test_server_bad_ehlo_rcpt(void *conn_ctx ATTR_UNUSED,
        struct smtp_server_cmd_ctx *cmd ATTR_UNUSED,
-       struct smtp_server_cmd_rcpt *data ATTR_UNUSED)
+       struct smtp_server_recipient *rcpt ATTR_UNUSED)
 {
        return 1;
 }
@@ -1048,7 +1048,7 @@ test_server_bad_mail_disconnect(void *context ATTR_UNUSED, const char *reason)
 static int
 test_server_bad_mail_rcpt(void *conn_ctx ATTR_UNUSED,
        struct smtp_server_cmd_ctx *cmd ATTR_UNUSED,
-       struct smtp_server_cmd_rcpt *data ATTR_UNUSED)
+       struct smtp_server_recipient *rcpt ATTR_UNUSED)
 {
        test_assert(FALSE);
        return 1;
@@ -1228,7 +1228,7 @@ test_server_bad_rcpt_disconnect(void *context ATTR_UNUSED, const char *reason)
 static int
 test_server_bad_rcpt_rcpt(void *conn_ctx ATTR_UNUSED,
        struct smtp_server_cmd_ctx *cmd ATTR_UNUSED,
-       struct smtp_server_cmd_rcpt *data ATTR_UNUSED)
+       struct smtp_server_recipient *rcpt ATTR_UNUSED)
 {
        return 1;
 }
@@ -1415,7 +1415,7 @@ test_server_mail_workarounds_disconnect(void *context ATTR_UNUSED,
 static int
 test_server_mail_workarounds_rcpt(void *conn_ctx ATTR_UNUSED,
        struct smtp_server_cmd_ctx *cmd ATTR_UNUSED,
-       struct smtp_server_cmd_rcpt *data ATTR_UNUSED)
+       struct smtp_server_recipient *rcpt ATTR_UNUSED)
 {
        test_assert(FALSE);
        return 1;
@@ -1609,7 +1609,7 @@ test_server_rcpt_workarounds_disconnect(void *context ATTR_UNUSED,
 static int
 test_server_rcpt_workarounds_rcpt(void *conn_ctx ATTR_UNUSED,
        struct smtp_server_cmd_ctx *cmd ATTR_UNUSED,
-       struct smtp_server_cmd_rcpt *data ATTR_UNUSED)
+       struct smtp_server_recipient *rcpt ATTR_UNUSED)
 {
        return 1;
 }
@@ -1708,11 +1708,11 @@ test_server_too_many_recipients_trans_free(void *conn_ctx  ATTR_UNUSED,
 static int
 test_server_too_many_recipients_rcpt(void *conn_ctx ATTR_UNUSED,
        struct smtp_server_cmd_ctx *cmd ATTR_UNUSED,
-       struct smtp_server_cmd_rcpt *data)
+       struct smtp_server_recipient *rcpt)
 {
        if (debug) {
                i_debug("RCPT TO:%s",
-                       smtp_address_encode(data->path));
+                       smtp_address_encode(rcpt->path));
        }
        return 1;
 }
@@ -1785,7 +1785,7 @@ static void test_client_data_no_mail(unsigned int index)
 static int
 test_server_data_no_mail_rcpt(void *conn_ctx ATTR_UNUSED,
        struct smtp_server_cmd_ctx *cmd ATTR_UNUSED,
-       struct smtp_server_cmd_rcpt *data ATTR_UNUSED)
+       struct smtp_server_recipient *rcpt ATTR_UNUSED)
 {
        /* not supposed to get here */
        i_assert(FALSE);
@@ -1877,7 +1877,7 @@ test_server_data_no_rcpt_trans_free(void *conn_ctx  ATTR_UNUSED,
 static int
 test_server_data_no_rcpt_rcpt(void *conn_ctx ATTR_UNUSED,
        struct smtp_server_cmd_ctx *cmd ATTR_UNUSED,
-       struct smtp_server_cmd_rcpt *data ATTR_UNUSED)
+       struct smtp_server_recipient *rcpt ATTR_UNUSED)
 {
        /* not supposed to get here */
        i_assert(FALSE);
@@ -1962,11 +1962,11 @@ test_server_data_binarymime_trans_free(void *conn_ctx  ATTR_UNUSED,
 static int
 test_server_data_binarymime_rcpt(void *conn_ctx ATTR_UNUSED,
        struct smtp_server_cmd_ctx *cmd ATTR_UNUSED,
-       struct smtp_server_cmd_rcpt *data)
+       struct smtp_server_recipient *rcpt)
 {
        if (debug) {
                i_debug("RCPT TO:%s",
-                       smtp_address_encode(data->path));
+                       smtp_address_encode(rcpt->path));
        }
        return 1;
 }
index 51625a6d9c587044692e611a01dfe3ef88d90eb3..95c4145067a6e9be893e3a2e0bb80093bb0906c6 100644 (file)
@@ -44,7 +44,7 @@ int cmd_mail(void *conn_ctx,
  */
 
 int cmd_rcpt(void *conn_ctx, struct smtp_server_cmd_ctx *cmd,
-            struct smtp_server_cmd_rcpt *data)
+            struct smtp_server_recipient *rcpt)
 {
        struct client *client = (struct client *)conn_ctx;
        const char *username, *detail;
@@ -53,17 +53,17 @@ int cmd_rcpt(void *conn_ctx, struct smtp_server_cmd_ctx *cmd,
 
        smtp_address_detail_parse_temp(
                client->unexpanded_lda_set->recipient_delimiter,
-               data->path, &username, &delim, &detail);
+               rcpt->path, &username, &delim, &detail);
        if (client->lmtp_set->lmtp_proxy) {
                /* proxied? */
-               if ((ret=lmtp_proxy_rcpt(client, cmd, data,
+               if ((ret=lmtp_proxy_rcpt(client, cmd, rcpt,
                                         username, detail, delim)) != 0)
                        return (ret < 0 ? -1 : 0);
                /* no */
        }
 
        /* local delivery */
-       return lmtp_local_rcpt(client, cmd, data, username, detail);
+       return lmtp_local_rcpt(client, cmd, rcpt, username, detail);
 }
 
 /*
index f7a2aa8ad41d8aa5be40deeaf51e4b93a5fa2355..4aaa51c81133bbf7a41f7ac4df65790fd5a70fe4 100644 (file)
@@ -8,7 +8,7 @@ struct smtp_server_cmd_helo;
 int cmd_mail(void *conn_ctx, struct smtp_server_cmd_ctx *cmd,
             struct smtp_server_cmd_mail *data);
 int cmd_rcpt(void *conn_ctx, struct smtp_server_cmd_ctx *cmd,
-            struct smtp_server_cmd_rcpt *data);
+            struct smtp_server_recipient *rcpt);
 int cmd_data_continue(void *conn_ctx, struct smtp_server_cmd_ctx *cmd,
                      struct smtp_server_transaction *trans);
 int cmd_data_begin(void *conn_ctx, struct smtp_server_cmd_ctx *cmd ATTR_UNUSED,
index f740600a24961d49c8e7ae07b88892771971327c..58678e56c64f2bc20be89a281c3d271209b632a4 100644 (file)
@@ -8,23 +8,18 @@ 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_cmd_rcpt *data)
+                        struct smtp_server_recipient *rcpt)
 {
        lrcpt->client = client;
        lrcpt->type = type;
        lrcpt->rcpt_cmd = cmd;
-       lrcpt->path = data->path;
+       lrcpt->rcpt = rcpt;
+       lrcpt->path = rcpt->path;
 }
 
-void lmtp_recipient_finish(struct lmtp_recipient *lrcpt,
-                          struct smtp_server_recipient *rcpt,
-                          unsigned int index)
+void lmtp_recipient_finish(struct lmtp_recipient *lrcpt)
 {
-       rcpt->context = lrcpt;
-
-       lrcpt->path = rcpt->path;
-       lrcpt->rcpt = rcpt;
-       lrcpt->index = index;
+       lrcpt->index = lrcpt->rcpt->index;
        lrcpt->rcpt_cmd = NULL;
 }
 
index a2dc1f86289fcb582da288f95aeee3d286908ac0..d81f3dc12114cb1748a81b44b65b7e4d8461bf26 100644 (file)
@@ -26,11 +26,9 @@ 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_cmd_rcpt *data);
+                        struct smtp_server_recipient *rcpt);
 
-void lmtp_recipient_finish(struct lmtp_recipient *lrcpt,
-                          struct smtp_server_recipient *rcpt,
-                          unsigned int index);
+void lmtp_recipient_finish(struct lmtp_recipient *lrcpt);
 
 struct lmtp_recipient *
 lmtp_recipient_find_duplicate(struct lmtp_recipient *lrcpt,
index 87bcd43f1bc986d5b3b485a089eb1c0f320fab8e..27168ffc7d1d2da32964637187c0f8d534573512 100644 (file)
@@ -252,13 +252,10 @@ lmtp_local_rcpt_check_quota(struct lmtp_local_recipient *llrcpt)
        return ret;
 }
 
-static void lmtp_local_rcpt_finished(
-       struct smtp_server_cmd_ctx *cmd,
-       struct smtp_server_transaction *trans,
-       struct smtp_server_recipient *rcpt,
-       unsigned int index)
+static void
+lmtp_local_rcpt_approved(struct smtp_server_recipient *rcpt,
+                        struct lmtp_local_recipient *llrcpt)
 {
-       struct lmtp_local_recipient *llrcpt = rcpt->context;
        struct client *client = llrcpt->rcpt.client;
 
        smtp_server_command_remove_hook(
@@ -266,17 +263,11 @@ static void lmtp_local_rcpt_finished(
                SMTP_SERVER_COMMAND_HOOK_DESTROY,
                lmtp_local_rcpt_cmd_destroy);
 
-       if (!smtp_server_command_replied_success(cmd->cmd)) {
-               /* failed in RCPT command; clean up early */
-               lmtp_local_rcpt_deinit(llrcpt);
-               return;
-       }
-
-       lmtp_recipient_finish(&llrcpt->rcpt, rcpt, index);
+       lmtp_recipient_finish(&llrcpt->rcpt);
 
        /* resolve duplicate recipient */
        llrcpt->duplicate = (struct lmtp_local_recipient *)
-               lmtp_recipient_find_duplicate(&llrcpt->rcpt, trans);
+               lmtp_recipient_find_duplicate(&llrcpt->rcpt, rcpt->trans);
        i_assert(llrcpt->duplicate == NULL ||
                 llrcpt->duplicate->duplicate == NULL);
 
@@ -332,11 +323,11 @@ lmtp_local_rcpt_anvil_cb(const char *reply, void *context)
 
 int lmtp_local_rcpt(struct client *client,
        struct smtp_server_cmd_ctx *cmd,
-       struct smtp_server_cmd_rcpt *data,
+       struct smtp_server_recipient *rcpt,
        const char *username, const char *detail)
 {
        struct smtp_server_connection *conn = cmd->conn;
-       const struct smtp_address *address = data->path;
+       const struct smtp_address *address = rcpt->path;
        struct smtp_server_transaction *trans;
        struct lmtp_local_recipient *llrcpt;
        struct mail_storage_service_input input;
@@ -391,7 +382,7 @@ int lmtp_local_rcpt(struct client *client,
 
        llrcpt = i_new(struct lmtp_local_recipient, 1);
        lmtp_recipient_init(&llrcpt->rcpt, client,
-                           LMTP_RECIPIENT_TYPE_LOCAL, cmd, data);
+                           LMTP_RECIPIENT_TYPE_LOCAL, cmd, rcpt);
 
        llrcpt->detail = i_strdup(detail);
        llrcpt->service_user = service_user;
@@ -400,8 +391,10 @@ int lmtp_local_rcpt(struct client *client,
        smtp_server_command_add_hook(cmd->cmd, SMTP_SERVER_COMMAND_HOOK_DESTROY,
                                     lmtp_local_rcpt_cmd_destroy, llrcpt);
 
-       data->trans_context = llrcpt;
-       data->hook_finished = lmtp_local_rcpt_finished;
+       smtp_server_recipient_add_hook(
+               rcpt, SMTP_SERVER_RECIPIENT_HOOK_APPROVED,
+               lmtp_local_rcpt_approved, llrcpt);
+       rcpt->context = llrcpt;
 
        if (client->lmtp_set->lmtp_user_concurrency_limit == 0) {
                (void)lmtp_local_rcpt_anvil_finish(llrcpt);
index edd6156f7f9c3977e3faa6d425566d266ac9137a..11331f9511fd54825f2558d3a7c1e090f4197f28 100644 (file)
@@ -13,7 +13,7 @@ void lmtp_local_deinit(struct lmtp_local **_local);
 
 int lmtp_local_rcpt(struct client *client,
                    struct smtp_server_cmd_ctx *cmd,
-                   struct smtp_server_cmd_rcpt *data,
+                   struct smtp_server_recipient *rcpt,
                    const char *username, const char *detail);
 
 void lmtp_local_add_headers(struct lmtp_local *local,
index fe9e1a019ef99f40188cb17f61c8938640127b24..6550db1e481c0cb1f3d5398bec8c16e86d497406 100644 (file)
@@ -444,12 +444,9 @@ lmtp_proxy_rcpt_cmd_destroy(struct smtp_server_cmd_ctx *cmd ATTR_UNUSED,
 }
 
 static void
-lmtp_proxy_rcpt_finished(struct smtp_server_cmd_ctx *cmd,
-                        struct smtp_server_transaction *trans ATTR_UNUSED,
-                        struct smtp_server_recipient *rcpt,
-                        unsigned int index)
+lmtp_proxy_rcpt_approved(struct smtp_server_recipient *rcpt ATTR_UNUSED,
+                        struct lmtp_proxy_recipient *lprcpt)
 {
-       struct lmtp_proxy_recipient *lprcpt = rcpt->context;
        struct client *client = lprcpt->rcpt.client;
 
        if (lprcpt->rcpt.rcpt_cmd != NULL) {
@@ -459,13 +456,7 @@ lmtp_proxy_rcpt_finished(struct smtp_server_cmd_ctx *cmd,
                        lmtp_proxy_rcpt_cmd_destroy);
        }
 
-       if (!smtp_server_command_replied_success(cmd->cmd)) {
-               /* failed in RCPT command; clean up early */
-               lmtp_proxy_recipient_deinit(lprcpt);
-               return;
-       }
-
-       lmtp_recipient_finish(&lprcpt->rcpt, rcpt, index);
+       lmtp_recipient_finish(&lprcpt->rcpt);
 
        /* add to local recipients */
        array_append(&client->proxy->rcpt_to, &lprcpt, 1);
@@ -495,7 +486,7 @@ lmtp_proxy_rcpt_cb(const struct smtp_reply *proxy_reply,
 
 int lmtp_proxy_rcpt(struct client *client,
                    struct smtp_server_cmd_ctx *cmd,
-                   struct smtp_server_cmd_rcpt *data,
+                   struct smtp_server_recipient *rcpt,
                    const char *username, const char *detail,
                    char delim)
 {
@@ -504,7 +495,7 @@ int lmtp_proxy_rcpt(struct client *client,
        struct lmtp_proxy_connection *conn;
        struct lmtp_proxy_recipient *lprcpt;
        struct smtp_server_transaction *trans;
-       struct smtp_address *address = data->path;
+       struct smtp_address *address = rcpt->path;
        struct auth_user_info info;
        struct mail_storage_service_input input;
        const char *const *fields, *errstr, *orig_username = username;
@@ -596,25 +587,25 @@ int lmtp_proxy_rcpt(struct client *client,
        if (client->proxy == NULL)
                client->proxy = lmtp_proxy_init(client, trans);
 
-       data->path = smtp_address_clone(cmd->pool, address);
-
        conn = lmtp_proxy_get_connection(client->proxy, &set);
        pool_unref(&auth_pool);
 
        lprcpt = i_new(struct lmtp_proxy_recipient, 1);
        lmtp_recipient_init(&lprcpt->rcpt, client,
-                           LMTP_RECIPIENT_TYPE_PROXY, cmd, data);
-
+                           LMTP_RECIPIENT_TYPE_PROXY, cmd, rcpt);
+       lprcpt->rcpt.path = smtp_address_clone(rcpt->pool, address);
        lprcpt->conn = conn;
 
        smtp_server_command_add_hook(cmd->cmd, SMTP_SERVER_COMMAND_HOOK_DESTROY,
                                     lmtp_proxy_rcpt_cmd_destroy, lprcpt);
 
-       data->trans_context = lprcpt;
-       data->hook_finished = lmtp_proxy_rcpt_finished;
+       smtp_server_recipient_add_hook(
+               rcpt, SMTP_SERVER_RECIPIENT_HOOK_APPROVED,
+               lmtp_proxy_rcpt_approved, lprcpt);
+       rcpt->context = lprcpt;
 
        smtp_client_transaction_add_rcpt(conn->lmtp_trans,
-               address, &data->params,
+               address, &rcpt->params,
                lmtp_proxy_rcpt_cb, lmtp_proxy_data_cb, lprcpt);
        return 1;
 }
@@ -631,7 +622,7 @@ lmtp_proxy_data_cb(const struct smtp_reply *proxy_reply,
        struct lmtp_proxy *proxy = conn->proxy;
        struct smtp_server_cmd_ctx *cmd = proxy->pending_data_cmd;
        struct smtp_server_transaction *trans = proxy->trans;
-       struct smtp_address *address = lprcpt->rcpt.rcpt->path;
+       struct smtp_address *address = lprcpt->rcpt.path;
        const struct smtp_client_transaction_times *times =
                smtp_client_transaction_get_times(conn->lmtp_trans);
        unsigned int rcpt_index = lprcpt->rcpt.index;
index ee6fc2e4a50037c2c7d0faa1bd77b058e861735a..bd475eac937ee1bcb963b79ca725007928313e1d 100644 (file)
@@ -18,7 +18,7 @@ void lmtp_proxy_deinit(struct lmtp_proxy **proxy);
 
 int lmtp_proxy_rcpt(struct client *client,
                    struct smtp_server_cmd_ctx *cmd,
-                   struct smtp_server_cmd_rcpt *data,
+                   struct smtp_server_recipient *rcpt,
                    const char *username, const char *detail, char delim);
 
 void lmtp_proxy_data(struct client *client,
index 734df10e29dceca6743aab52c4dec72a242bb806..48a6d60e719469ece920100e076a62911da9bd49 100644 (file)
@@ -427,7 +427,7 @@ struct relay_cmd_rcpt_context {
        struct submission_backend_relay *backend;
 
        struct smtp_server_cmd_ctx *cmd;
-       struct smtp_server_cmd_rcpt *data;
+       struct smtp_server_recipient *rcpt;
 
        struct smtp_client_transaction_rcpt *relay_rcpt;
 };
@@ -476,7 +476,7 @@ relay_cmd_rcpt_callback(const struct smtp_reply *relay_reply,
 static int
 backend_relay_cmd_rcpt(struct submission_backend *_backend,
                       struct smtp_server_cmd_ctx *cmd,
-                      struct smtp_server_cmd_rcpt *data)
+                      struct smtp_server_recipient *rcpt)
 {
        struct submission_backend_relay *backend =
                (struct submission_backend_relay *)_backend;
@@ -486,7 +486,7 @@ backend_relay_cmd_rcpt(struct submission_backend *_backend,
        rcpt_cmd = p_new(cmd->pool, struct relay_cmd_rcpt_context, 1);
        rcpt_cmd->backend = backend;
        rcpt_cmd->cmd = cmd;
-       rcpt_cmd->data = data;
+       rcpt_cmd->rcpt = rcpt;
 
        smtp_server_command_add_hook(cmd->cmd, SMTP_SERVER_COMMAND_HOOK_REPLIED,
                                     relay_cmd_rcpt_replied, rcpt_cmd);
@@ -496,7 +496,7 @@ backend_relay_cmd_rcpt(struct submission_backend *_backend,
                        backend->conn, backend_relay_trans_finished, backend);
        }
        rcpt_cmd->relay_rcpt = smtp_client_transaction_add_rcpt(
-               backend->trans, data->path,  &data->params,
+               backend->trans, rcpt->path,  &rcpt->params,
                relay_cmd_rcpt_callback, relay_cmd_rcpt_data_callback,
                rcpt_cmd);
        return 0;
index 66dfc81ca074e231ceb166b170366144bee5041b..0878428b51ef759bd420a4b807a938c8340e99bf 100644 (file)
@@ -177,14 +177,14 @@ int submission_backend_cmd_mail(struct submission_backend *backend,
 
 int submission_backend_cmd_rcpt(struct submission_backend *backend,
                                struct smtp_server_cmd_ctx *cmd,
-                               struct smtp_server_cmd_rcpt *data)
+                               struct smtp_server_recipient *rcpt)
 {
        if (backend->v.cmd_rcpt == NULL) {
                /* backend is not interested, respond right away */
                return 1;
        }
 
-       return backend->v.cmd_rcpt(backend, cmd, data);
+       return backend->v.cmd_rcpt(backend, cmd, rcpt);
 }
 
 int submission_backend_cmd_rset(struct submission_backend *backend,
index 92f58fa87c14bf0853738012ef1d3702220d0d7e..8e2bc315eb093c061cc767a36115d1b3f2dff976 100644 (file)
@@ -27,7 +27,7 @@ struct submission_backend_vfuncs {
                        struct smtp_server_cmd_mail *data);
        int (*cmd_rcpt)(struct submission_backend *backend,
                        struct smtp_server_cmd_ctx *cmd,
-                       struct smtp_server_cmd_rcpt *data);
+                       struct smtp_server_recipient *rcpt);
        int (*cmd_rset)(struct submission_backend *backend,
                        struct smtp_server_cmd_ctx *cmd);
        int (*cmd_data)(struct submission_backend *backend,
@@ -92,7 +92,7 @@ int submission_backend_cmd_mail(struct submission_backend *backend,
                                struct smtp_server_cmd_mail *data);
 int submission_backend_cmd_rcpt(struct submission_backend *backend,
                                struct smtp_server_cmd_ctx *cmd,
-                               struct smtp_server_cmd_rcpt *data);
+                               struct smtp_server_recipient *rcpt);
 int submission_backend_cmd_rset(struct submission_backend *backend,
                                struct smtp_server_cmd_ctx *cmd);
 int submission_backends_cmd_data(struct client *client,
index 4c7a81b2c1064c382bc6160a78cffb2de869899d..2968043549cd8c2c329f254f5e80c544d51a87ff 100644 (file)
@@ -39,7 +39,7 @@ struct submission_client_vfuncs {
        int (*cmd_rcpt)(struct client *client,
                        struct submission_recipient *srcpt,
                        struct smtp_server_cmd_ctx *cmd,
-                       struct smtp_server_cmd_rcpt *data);
+                       struct smtp_server_recipient *rcpt);
        int (*cmd_rset)(struct client *client, struct smtp_server_cmd_ctx *cmd);
        int (*cmd_data)(struct client *client,
                        struct smtp_server_cmd_ctx *cmd,
index 11291cc89ef8bcadf49f96d9f1b06286bca4b62d..f44a99223c73dd5fd94428371005aebe2bb420ad 100644 (file)
@@ -152,41 +152,35 @@ cmd_rcpt_destroy(struct smtp_server_cmd_ctx *cmd ATTR_UNUSED,
 }
 
 static void
-submission_rcpt_finished(struct smtp_server_cmd_ctx *cmd,
-                        struct smtp_server_transaction *trans ATTR_UNUSED,
-                        struct smtp_server_recipient *rcpt,
-                        unsigned int index)
+cmd_rcpt_approved(struct smtp_server_recipient *rcpt,
+                 struct submission_recipient *srcpt)
 {
-       struct submission_recipient *srcpt = rcpt->context;
-
-       smtp_server_command_remove_hook(cmd->cmd,
-                                       SMTP_SERVER_COMMAND_HOOK_DESTROY,
-                                       cmd_rcpt_destroy);
-
-       submission_recipient_finished(srcpt, rcpt, index);
+       submission_recipient_finished(srcpt, rcpt, rcpt->index);
 }
 
 int cmd_rcpt(void *conn_ctx, struct smtp_server_cmd_ctx *cmd,
-            struct smtp_server_cmd_rcpt *data)
+            struct smtp_server_recipient *rcpt)
 {
        struct client *client = conn_ctx;
        struct submission_recipient *srcpt;
 
-       srcpt = submission_recipient_create(client, data->path);
+       srcpt = submission_recipient_create(client, rcpt->path);
 
        smtp_server_command_add_hook(cmd->cmd, SMTP_SERVER_COMMAND_HOOK_DESTROY,
                                     cmd_rcpt_destroy, srcpt);
 
-       data->trans_context = srcpt;
-       data->hook_finished = submission_rcpt_finished;
+       smtp_server_recipient_add_hook(
+               rcpt, SMTP_SERVER_RECIPIENT_HOOK_APPROVED,
+               cmd_rcpt_approved, srcpt);
+       rcpt->context = srcpt;
 
-       return client->v.cmd_rcpt(client, srcpt, cmd, data);
+       return client->v.cmd_rcpt(client, srcpt, cmd, rcpt);
 }
 
 int client_default_cmd_rcpt(struct client *client ATTR_UNUSED,
                            struct submission_recipient *srcpt,
                            struct smtp_server_cmd_ctx *cmd,
-                           struct smtp_server_cmd_rcpt *data)
+                           struct smtp_server_recipient *rcpt)
 {
        struct smtp_server_transaction *trans;
 
@@ -194,7 +188,7 @@ int client_default_cmd_rcpt(struct client *client ATTR_UNUSED,
        if (trans != NULL)
                submission_backend_trans_start(srcpt->backend, trans);
 
-       return submission_backend_cmd_rcpt(srcpt->backend, cmd, data);
+       return submission_backend_cmd_rcpt(srcpt->backend, cmd, rcpt);
 }
 
 /*
index c89f5728702e7d679b2f3dd46b4be4c9caa2c64f..875ca3e2a925d6f9d393ed180be58bc6c5f28461 100644 (file)
@@ -31,12 +31,12 @@ int client_default_cmd_mail(struct client *client,
  */
 
 int cmd_rcpt(void *conn_ctx, struct smtp_server_cmd_ctx *cmd,
-            struct smtp_server_cmd_rcpt *data);
+            struct smtp_server_recipient *rcpt);
 
 int client_default_cmd_rcpt(struct client *client ATTR_UNUSED,
                            struct submission_recipient *srcpt,
                            struct smtp_server_cmd_ctx *cmd,
-                           struct smtp_server_cmd_rcpt *data);
+                           struct smtp_server_recipient *rcpt);
 
 /*
  * RSET command