]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lda/lmtp: If mail delivery fails with tempfail, don't fallback to saving to INBOX.
authorTimo Sirainen <tss@iki.fi>
Sat, 1 Jun 2013 14:17:47 +0000 (17:17 +0300)
committerTimo Sirainen <tss@iki.fi>
Sat, 1 Jun 2013 14:17:47 +0000 (17:17 +0300)
src/lda/main.c
src/lib-lda/mail-deliver.c
src/lib-lda/mail-deliver.h
src/lmtp/commands.c

index 447168fac82905d278a77715691963b3757ecfc7..4ed8a315e82dea502b9acbba4910d7120bbd1234 100644 (file)
@@ -436,14 +436,17 @@ int main(int argc, char *argv[])
        lda_set_dest_addr(&ctx, user, destaddr_source);
 
        if (mail_deliver(&ctx, &storage) < 0) {
-               if (storage == NULL) {
+               if (storage != NULL) {
+                       errstr = mail_storage_get_last_error(storage, &error);
+               } else if (ctx.tempfail_error != NULL) {
+                       errstr = ctx.tempfail_error;
+                       error = MAIL_ERROR_TEMP;
+               } else {
                        /* This shouldn't happen */
                        i_error("BUG: Saving failed to unknown storage");
                        return EX_TEMPFAIL;
                }
 
-               errstr = mail_storage_get_last_error(storage, &error);
-
                if (stderr_rejection) {
                        /* write to stderr also for tempfails so that MTA
                           can log the reason if it wants to. */
index 069f878b72fb668d479bcf86c6fe722305df85ec..458dcd2b405e09d8f946989c6bb8fac2278cef61 100644 (file)
@@ -371,6 +371,20 @@ const char *mail_deliver_get_new_message_id(struct mail_deliver_context *ctx)
                               count++, ctx->set->hostname);
 }
 
+static bool mail_deliver_is_tempfailed(struct mail_deliver_context *ctx,
+                                      struct mail_storage *storage)
+{
+       enum mail_error error;
+
+       if (ctx->tempfail_error != NULL)
+               return TRUE;
+       if (storage != NULL) {
+               (void)mail_storage_get_last_error(storage, &error);
+               return error == MAIL_ERROR_TEMP;
+       }
+       return FALSE;
+}
+
 int mail_deliver(struct mail_deliver_context *ctx,
                 struct mail_storage **storage_r)
 {
@@ -390,12 +404,16 @@ int mail_deliver(struct mail_deliver_context *ctx,
                        ret = 0;
                }
                duplicate_deinit(&ctx->dup_ctx);
+               if (ret < 0 && mail_deliver_is_tempfailed(ctx, *storage_r))
+                       return -1;
        }
 
        if (ret < 0 && !ctx->tried_default_save) {
                /* plugins didn't handle this. save into the default mailbox. */
                ret = mail_deliver_save(ctx, ctx->dest_mailbox_name, 0, NULL,
                                        storage_r);
+               if (ret < 0 && mail_deliver_is_tempfailed(ctx, *storage_r))
+                       return -1;
        }
        if (ret < 0 && strcasecmp(ctx->dest_mailbox_name, "INBOX") != 0) {
                /* still didn't work. try once more to save it
index fbc2941820964c4d725e1c0e64fabc04af8301e7..f0646a22724eccd4d9f7a1518463e3a3e4f7f928 100644 (file)
@@ -48,6 +48,10 @@ struct mail_deliver_context {
        /* mail_deliver_log() caches the var expand table here */
        struct var_expand_table *var_expand_table;
 
+       /* Error message for a temporary failure. This is necessary only when
+          there is no storage where to get the error message from. */
+       const char *tempfail_error;
+
        bool tried_default_save;
        bool saved_mail;
        bool save_dest_mail;
index 4de117f464135760aee0def33de54c936aacbcf0..8d8baa0b359fb68334f3a27fd4d4bbc8e807d2ab 100644 (file)
@@ -694,13 +694,7 @@ client_deliver(struct client *client, const struct mail_recipient *rcpt,
                client_send_line(client, "250 2.0.0 <%s> %s Saved",
                                 rcpt->address, client->state.session_id);
                ret = 0;
-       } else if (storage == NULL) {
-               /* This shouldn't happen */
-               i_error("BUG: Saving failed to unknown storage");
-               client_send_line(client, ERRSTR_TEMP_MAILBOX_FAIL,
-                                rcpt->address);
-               ret = -1;
-       } else {
+       } else if (storage != NULL) {
                error = mail_storage_get_last_error(storage, &mail_error);
                if (mail_error == MAIL_ERROR_NOSPACE) {
                        client_send_line(client, "%s <%s> %s",
@@ -712,6 +706,16 @@ client_deliver(struct client *client, const struct mail_recipient *rcpt,
                                         rcpt->address, error);
                }
                ret = -1;
+       } else if (dctx.tempfail_error != NULL) {
+               client_send_line(client, "451 4.2.0 <%s> %s",
+                                rcpt->address, dctx.tempfail_error);
+               ret = -1;
+       } else {
+               /* This shouldn't happen */
+               i_error("BUG: Saving failed to unknown storage");
+               client_send_line(client, ERRSTR_TEMP_MAILBOX_FAIL,
+                                rcpt->address);
+               ret = -1;
        }
        return ret;
 }