smtp_address_encode_path(rcpt_to), rcpt_to_source);
}
+static int
+lda_deliver(struct mail_deliver_context *ctx,
+ struct mail_storage_service_user *service_user,
+ const char *user, const char *path,
+ struct smtp_address *rcpt_to, const char *rcpt_to_source,
+ bool stderr_rejection)
+{
+ const struct var_expand_table *var_table;
+ struct lda_settings *lda_set;
+ struct smtp_submit_settings *smtp_set;
+ struct mail_storage *storage;
+ const char *errstr;
+ int ret;
+
+ var_table = mail_user_var_expand_table(ctx->rcpt_user);
+ smtp_set = mail_storage_service_user_get_set(service_user)[1];
+ lda_set = mail_storage_service_user_get_set(service_user)[2];
+ ret = settings_var_expand(
+ &lda_setting_parser_info,
+ lda_set, ctx->rcpt_user->pool, var_table,
+ &errstr);
+ if (ret > 0) {
+ ret = settings_var_expand(
+ &smtp_submit_setting_parser_info,
+ smtp_set, ctx->rcpt_user->pool, var_table,
+ &errstr);
+ }
+ if (ret <= 0)
+ i_fatal("Failed to expand settings: %s", errstr);
+ ctx->set = lda_set;
+ ctx->smtp_set = smtp_set;
+
+ ctx->src_mail = lda_raw_mail_open(ctx, path);
+ lda_set_rcpt_to(ctx, rcpt_to, user, rcpt_to_source);
+
+ if (mail_deliver(ctx, &storage) < 0) {
+ enum mail_error error;
+
+ if (ctx->tempfail_error != NULL) {
+ errstr = ctx->tempfail_error;
+ error = MAIL_ERROR_TEMP;
+ } else if (storage != NULL) {
+ errstr = mail_storage_get_last_error(storage, &error);
+ } else {
+ /* This shouldn't happen */
+ i_error("BUG: Saving failed to unknown storage");
+ return EX_TEMPFAIL;
+ }
+
+ if (stderr_rejection) {
+ /* write to stderr also for tempfails so that MTA
+ can log the reason if it wants to. */
+ fprintf(stderr, "%s\n", errstr);
+ }
+
+ if (error != MAIL_ERROR_NOQUOTA ||
+ ctx->set->quota_full_tempfail) {
+ /* Saving to INBOX should always work unless
+ we're over quota. If it didn't, it's probably a
+ configuration problem. */
+ return EX_TEMPFAIL;
+ }
+ ctx->mailbox_full = TRUE;
+ ctx->dsn = TRUE;
+
+ /* we'll have to reply with permanent failure */
+ mail_deliver_log(ctx, "rejected: %s",
+ str_sanitize(errstr, 512));
+
+ if (stderr_rejection)
+ return EX_NOPERM;
+ ret = mail_send_rejection(ctx, ctx->rcpt_to, errstr);
+ if (ret != 0)
+ return ret < 0 ? EX_TEMPFAIL : ret;
+ /* ok, rejection sent */
+ }
+ return EX_OK;
+}
+
static void failure_exit_callback(int *status)
{
/* we want all our exit codes to be sysexits.h compatible.
struct mail_deliver_context ctx;
enum mail_storage_service_flags service_flags = 0;
const char *user, *errstr, *path;
- struct lda_settings *lda_set;
- struct smtp_submit_settings *smtp_set;
struct smtp_address *rcpt_to, *final_rcpt_to, *mail_from;
struct mail_storage_service_ctx *storage_service;
struct mail_storage_service_user *service_user;
struct mail_storage_service_input service_input;
- const struct var_expand_table *var_table;
- struct mail_storage *storage;
const char *user_source = "", *rcpt_to_source = "";
uid_t process_euid;
bool stderr_rejection = FALSE;
int ret, c;
- enum mail_error error;
if (getuid() != geteuid() && geteuid() == 0) {
/* running setuid - don't allow this if the binary is
ctx.mail_from = mail_from;
ctx.rcpt_to = final_rcpt_to;
- var_table = mail_user_var_expand_table(ctx.rcpt_user);
- smtp_set = mail_storage_service_user_get_set(service_user)[1];
- lda_set = mail_storage_service_user_get_set(service_user)[2];
- ret = settings_var_expand(
- &lda_setting_parser_info,
- lda_set, ctx.rcpt_user->pool, var_table,
- &errstr);
- if (ret > 0) {
- ret = settings_var_expand(
- &smtp_submit_setting_parser_info,
- smtp_set, ctx.rcpt_user->pool, var_table,
- &errstr);
- }
- if (ret <= 0)
- i_fatal("Failed to expand settings: %s", errstr);
- ctx.set = lda_set;
- ctx.smtp_set = smtp_set;
-
- ctx.src_mail = lda_raw_mail_open(&ctx, path);
- lda_set_rcpt_to(&ctx, rcpt_to, user, rcpt_to_source);
-
- if (mail_deliver(&ctx, &storage) < 0) {
- if (ctx.tempfail_error != NULL) {
- errstr = ctx.tempfail_error;
- error = MAIL_ERROR_TEMP;
- } else if (storage != NULL) {
- errstr = mail_storage_get_last_error(storage, &error);
- } else {
- /* This shouldn't happen */
- i_error("BUG: Saving failed to unknown storage");
- return EX_TEMPFAIL;
- }
-
- if (stderr_rejection) {
- /* write to stderr also for tempfails so that MTA
- can log the reason if it wants to. */
- fprintf(stderr, "%s\n", errstr);
- }
-
- if (error != MAIL_ERROR_NOQUOTA ||
- ctx.set->quota_full_tempfail) {
- /* Saving to INBOX should always work unless
- we're over quota. If it didn't, it's probably a
- configuration problem. */
- return EX_TEMPFAIL;
- }
- ctx.mailbox_full = TRUE;
- ctx.dsn = TRUE;
-
- /* we'll have to reply with permanent failure */
- mail_deliver_log(&ctx, "rejected: %s",
- str_sanitize(errstr, 512));
-
- if (stderr_rejection)
- return EX_NOPERM;
- ret = mail_send_rejection(&ctx, ctx.rcpt_to, errstr);
- if (ret != 0)
- return ret < 0 ? EX_TEMPFAIL : ret;
- /* ok, rejection sent */
- }
+ ret = lda_deliver(&ctx, service_user, user, path,
+ rcpt_to, rcpt_to_source, stderr_rejection);
+ if (ret != EX_OK)
+ return ret;
{
struct mailbox_transaction_context *t =