1 /* Copyright (c) 2005-2018 Dovecot authors, see the included COPYING file */
2 
3 #include "lib.h"
4 #include "ioloop.h"
5 #include "array.h"
6 #include "str.h"
7 #include "str-sanitize.h"
8 #include "time-util.h"
9 #include "unichar.h"
10 #include "var-expand.h"
11 #include "message-address.h"
12 #include "smtp-address.h"
13 #include "lda-settings.h"
14 #include "mail-storage.h"
15 #include "mail-namespace.h"
16 #include "mail-storage-private.h"
17 #include "mail-duplicate.h"
18 #include "mail-deliver.h"
19 
20 #define DUPLICATE_DB_NAME "lda-dupes"
21 
22 #define MAIL_DELIVER_USER_CONTEXT(obj) \
23 	MODULE_CONTEXT_REQUIRE(obj, mail_deliver_user_module)
24 #define MAIL_DELIVER_STORAGE_CONTEXT(obj) \
25 	MODULE_CONTEXT_REQUIRE(obj, mail_deliver_storage_module)
26 
27 struct event_category event_category_mail_delivery = {
28 	.name = "local-delivery",
29 };
30 
31 struct mail_deliver_user {
32 	union mail_user_module_context module_ctx;
33 	struct mail_deliver_context *deliver_ctx;
34 	bool want_storage_id;
35 };
36 
37 deliver_mail_func_t *deliver_mail = NULL;
38 
39 struct mail_deliver_mailbox {
40 	union mailbox_module_context module_ctx;
41 };
42 
43 struct mail_deliver_transaction {
44 	union mailbox_transaction_module_context module_ctx;
45 
46 	struct mail_deliver_fields deliver_fields;
47 };
48 
49 static const char *lda_log_wanted_headers[] = {
50 	"From", "Message-ID", "Subject",
51 	NULL
52 };
53 static enum mail_fetch_field lda_log_wanted_fetch_fields =
54 	MAIL_FETCH_PHYSICAL_SIZE | MAIL_FETCH_VIRTUAL_SIZE;
55 static MODULE_CONTEXT_DEFINE_INIT(mail_deliver_user_module,
56 				  &mail_user_module_register);
57 static MODULE_CONTEXT_DEFINE_INIT(mail_deliver_storage_module,
58 				  &mail_storage_module_register);
59 
60 static struct message_address *
mail_deliver_get_message_address(struct mail * mail,const char * header)61 mail_deliver_get_message_address(struct mail *mail, const char *header)
62 {
63 	struct message_address *addr;
64 	const char *str;
65 
66 	if (mail_get_first_header(mail, header, &str) <= 0)
67 		return NULL;
68 	addr = message_address_parse(pool_datastack_create(),
69 				     (const unsigned char *)str,
70 				     strlen(str), 1, 0);
71 	if (addr == NULL || addr->mailbox == NULL || addr->domain == NULL ||
72 	    *addr->mailbox == '\0' || *addr->domain == '\0')
73 		return NULL;
74 	return addr;
75 }
76 
77 const struct smtp_address *
mail_deliver_get_address(struct mail * mail,const char * header)78 mail_deliver_get_address(struct mail *mail, const char *header)
79 {
80 	struct message_address *addr;
81 	struct smtp_address *smtp_addr;
82 
83 	addr = mail_deliver_get_message_address(mail, header);
84 	if (addr == NULL ||
85 	    smtp_address_create_from_msg_temp(addr, &smtp_addr) < 0)
86 		return NULL;
87 	return smtp_addr;
88 }
89 
90 static void
mail_deliver_update_event(struct mail_deliver_context * ctx)91 mail_deliver_update_event(struct mail_deliver_context *ctx)
92 {
93 	event_add_str(ctx->event, "message_id", ctx->fields.message_id);
94 	event_add_str(ctx->event, "message_subject", ctx->fields.subject);
95 	event_add_str(ctx->event, "message_from", ctx->fields.from);
96 	if (ctx->fields.psize != UOFF_T_MAX)
97 		event_add_int(ctx->event, "message_size", ctx->fields.psize);
98 	if (ctx->fields.vsize != UOFF_T_MAX)
99 		event_add_int(ctx->event, "message_vsize", ctx->fields.vsize);
100 }
101 
102 static void
update_str_field(pool_t pool,const char ** old_str,const char * new_str)103 update_str_field(pool_t pool, const char **old_str, const char *new_str)
104 {
105 	if (new_str == NULL || new_str[0] == '\0')
106 		*old_str = NULL;
107 	else if (*old_str == NULL || strcmp(*old_str, new_str) != 0)
108 		*old_str = p_strdup(pool, new_str);
109 }
110 
111 static void
mail_deliver_fields_update(struct mail_deliver_fields * fields,pool_t pool,struct mail * mail)112 mail_deliver_fields_update(struct mail_deliver_fields *fields, pool_t pool,
113 			   struct mail *mail)
114 {
115 	const char *message_id = NULL, *subject = NULL, *from_envelope = NULL;
116 	static struct message_address *from_addr;
117 	const char *from;
118 
119 	if (fields->filled)
120 		return;
121 	fields->filled = TRUE;
122 
123 	if (mail_get_message_id(mail, &message_id) > 0)
124 		message_id = str_sanitize(message_id, 200);
125 	update_str_field(pool, &fields->message_id, message_id);
126 
127 	if (mail_get_first_header_utf8(mail, "Subject", &subject) > 0)
128 		subject = str_sanitize(subject, 80);
129 	update_str_field(pool, &fields->subject, subject);
130 
131 	from_addr = mail_deliver_get_message_address(mail, "From");
132 	from = (from_addr == NULL ? NULL :
133 		t_strconcat(from_addr->mailbox, "@", from_addr->domain, NULL));
134 	update_str_field(pool, &fields->from, from);
135 
136 	if (mail_get_special(mail, MAIL_FETCH_FROM_ENVELOPE, &from_envelope) > 0)
137 		from_envelope = str_sanitize(from_envelope, 80);
138 	update_str_field(pool, &fields->from_envelope, from_envelope);
139 
140 	if (mail_get_physical_size(mail, &fields->psize) < 0)
141 		fields->psize = 0;
142 	if (mail_get_virtual_size(mail, &fields->vsize) < 0)
143 		fields->vsize = 0;
144 }
145 
146 const struct var_expand_table *
mail_deliver_ctx_get_log_var_expand_table(struct mail_deliver_context * ctx,const char * message)147 mail_deliver_ctx_get_log_var_expand_table(struct mail_deliver_context *ctx,
148 					  const char *message)
149 {
150 	unsigned int delivery_time_msecs;
151 
152 	/* If a mail was saved/copied, the fields are already filled and the
153 	   following call is ignored. Otherwise, only the source mail exists. */
154 	mail_deliver_fields_update(&ctx->fields, ctx->pool, ctx->src_mail);
155 	/* This call finishes a mail delivery. With Sieve there may be multiple
156 	   mail deliveries. */
157 	ctx->fields.filled = FALSE;
158 
159 	mail_deliver_update_event(ctx);
160 
161 	io_loop_time_refresh();
162 	delivery_time_msecs = timeval_diff_msecs(&ioloop_timeval,
163 						 &ctx->delivery_time_started);
164 
165 	const struct var_expand_table stack_tab[] = {
166 		{ '$', message, NULL },
167 		{ 'm', ctx->fields.message_id != NULL ?
168 		       ctx->fields.message_id : "unspecified", "msgid" },
169 		{ 's', ctx->fields.subject, "subject" },
170 		{ 'f', ctx->fields.from, "from" },
171 		{ 'e', ctx->fields.from_envelope, "from_envelope" },
172 		{ 'p', dec2str(ctx->fields.psize), "size" },
173 		{ 'w', dec2str(ctx->fields.vsize), "vsize" },
174 		{ '\0', dec2str(delivery_time_msecs), "delivery_time" },
175 		{ '\0', dec2str(ctx->session_time_msecs), "session_time" },
176 		{ '\0', smtp_address_encode(ctx->rcpt_params.orcpt.addr), "to_envelope" },
177 		{ '\0', ctx->fields.storage_id, "storage_id" },
178 		{ '\0', NULL, NULL }
179 	};
180 	return p_memdup(unsafe_data_stack_pool, stack_tab, sizeof(stack_tab));
181 }
182 
mail_deliver_log(struct mail_deliver_context * ctx,const char * fmt,...)183 void mail_deliver_log(struct mail_deliver_context *ctx, const char *fmt, ...)
184 {
185 	va_list args;
186 	string_t *str;
187 	const struct var_expand_table *tab;
188 	const char *msg, *error;
189 
190 	if (*ctx->set->deliver_log_format == '\0')
191 		return;
192 
193 	va_start(args, fmt);
194 	msg = t_strdup_vprintf(fmt, args);
195 
196 	str = t_str_new(256);
197 	tab = mail_deliver_ctx_get_log_var_expand_table(ctx, msg);
198 	if (var_expand(str, ctx->set->deliver_log_format, tab, &error) <= 0) {
199 		e_error(ctx->event,
200 			"Failed to expand deliver_log_format=%s: %s",
201 			ctx->set->deliver_log_format, error);
202 	}
203 
204 	e_info(ctx->event, "%s", str_c(str));
205 	va_end(args);
206 }
207 
mail_deliver_session_init(void)208 struct mail_deliver_session *mail_deliver_session_init(void)
209 {
210 	struct mail_deliver_session *session;
211 	pool_t pool;
212 
213 	pool = pool_alloconly_create("mail deliver session", 1024);
214 	session = p_new(pool, struct mail_deliver_session, 1);
215 	session->pool = pool;
216 	return session;
217 }
218 
mail_deliver_session_deinit(struct mail_deliver_session ** _session)219 void mail_deliver_session_deinit(struct mail_deliver_session **_session)
220 {
221 	struct mail_deliver_session *session = *_session;
222 
223 	*_session = NULL;
224 	pool_unref(&session->pool);
225 }
226 
mail_deliver_save_open(struct mail_deliver_save_open_context * ctx,const char * name,struct mailbox ** box_r,enum mail_error * error_r,const char ** error_str_r)227 int mail_deliver_save_open(struct mail_deliver_save_open_context *ctx,
228 			   const char *name, struct mailbox **box_r,
229 			   enum mail_error *error_r, const char **error_str_r)
230 {
231 	struct mailbox *box;
232 	enum mailbox_flags flags = MAILBOX_FLAG_POST_SESSION;
233 
234 	*box_r = NULL;
235 	*error_r = MAIL_ERROR_NONE;
236 	*error_str_r = NULL;
237 
238 	if (!uni_utf8_str_is_valid(name)) {
239 		*error_str_r = "Mailbox name not valid UTF-8";
240 		*error_r = MAIL_ERROR_PARAMS;
241 		return -1;
242 	}
243 
244 	if (ctx->lda_mailbox_autocreate)
245 		flags |= MAILBOX_FLAG_AUTO_CREATE;
246 	if (ctx->lda_mailbox_autosubscribe)
247 		flags |= MAILBOX_FLAG_AUTO_SUBSCRIBE;
248 	*box_r = box = mailbox_alloc_for_user(ctx->user, name, flags);
249 
250 	if (mailbox_open(box) == 0)
251 		return 0;
252 	*error_str_r = mailbox_get_last_internal_error(box, error_r);
253 	return -1;
254 }
255 
mail_deliver_check_duplicate(struct mail_deliver_session * session,struct mailbox * box)256 static bool mail_deliver_check_duplicate(struct mail_deliver_session *session,
257 					 struct mailbox *box)
258 {
259 	struct mailbox_metadata metadata;
260 	const guid_128_t *guid;
261 
262 	if (mailbox_get_metadata(box, MAILBOX_METADATA_GUID, &metadata) < 0) {
263 		/* just play it safe and assume a duplicate */
264 		return TRUE;
265 	}
266 
267 	/* there shouldn't be all that many recipients,
268 	   so just do a linear search */
269 	if (!array_is_created(&session->inbox_guids))
270 		p_array_init(&session->inbox_guids, session->pool, 8);
271 	array_foreach(&session->inbox_guids, guid) {
272 		if (memcmp(metadata.guid, *guid, sizeof(metadata.guid)) == 0)
273 			return TRUE;
274 	}
275 	array_push_back(&session->inbox_guids, &metadata.guid);
276 	return FALSE;
277 }
278 
mail_deliver_deduplicate_guid_if_needed(struct mail_deliver_session * session,struct mail_save_context * save_ctx)279 void mail_deliver_deduplicate_guid_if_needed(struct mail_deliver_session *session,
280 					     struct mail_save_context *save_ctx)
281 {
282 	struct mailbox_transaction_context *trans =
283 		mailbox_save_get_transaction(save_ctx);
284 	struct mailbox *box = mailbox_transaction_get_mailbox(trans);
285 	guid_128_t guid;
286 
287 	if (strcmp(mailbox_get_name(box), "INBOX") != 0)
288 		return;
289 
290 	/* avoid storing duplicate GUIDs to delivered mails to INBOX. this
291 	   happens if mail is delivered to same user multiple times within a
292 	   session. the problem with this is that if GUIDs are used as POP3
293 	   UIDLs, some clients can't handle the duplicates well. */
294 	if (mail_deliver_check_duplicate(session, box)) {
295 		guid_128_generate(guid);
296 		mailbox_save_set_guid(save_ctx, guid_128_to_string(guid));
297 	}
298 }
299 
mail_deliver_init(struct mail_deliver_context * ctx,struct mail_deliver_input * input)300 void mail_deliver_init(struct mail_deliver_context *ctx,
301 		       struct mail_deliver_input *input)
302 {
303 	i_zero(ctx);
304 	ctx->set = input->set;
305 	ctx->smtp_set = input->smtp_set;
306 
307 	ctx->session = input->session;
308 	ctx->pool = input->session->pool;
309 	pool_ref(ctx->pool);
310 
311 	ctx->session_time_msecs = input->session_time_msecs;
312 	ctx->delivery_time_started = input->delivery_time_started;
313 	ctx->session_id = p_strdup(ctx->pool, input->session_id);
314 	ctx->src_mail = input->src_mail;
315 	ctx->save_dest_mail = input->save_dest_mail;
316 
317 	ctx->mail_from = smtp_address_clone(ctx->pool, input->mail_from);
318 	smtp_params_mail_copy(ctx->pool, &ctx->mail_params,
319 			      &input->mail_params);
320 	ctx->rcpt_to = smtp_address_clone(ctx->pool, input->rcpt_to);
321 	smtp_params_rcpt_copy(ctx->pool, &ctx->rcpt_params,
322 			      &input->rcpt_params);
323 	ctx->rcpt_user = input->rcpt_user;
324 	ctx->rcpt_default_mailbox = p_strdup(ctx->pool,
325 					     input->rcpt_default_mailbox);
326 
327 	ctx->event = event_create(input->event_parent);
328 	event_add_category(ctx->event, &event_category_mail_delivery);
329 
330 	mail_deliver_fields_update(&ctx->fields, ctx->pool, ctx->src_mail);
331 	mail_deliver_update_event(ctx);
332 
333 	if (ctx->rcpt_to != NULL) {
334 		event_add_str(ctx->event, "rcpt_to",
335 			      smtp_address_encode(ctx->rcpt_to));
336 	}
337 	smtp_params_rcpt_add_to_event(&ctx->rcpt_params, ctx->event);
338 }
339 
mail_deliver_deinit(struct mail_deliver_context * ctx)340 void mail_deliver_deinit(struct mail_deliver_context *ctx)
341 {
342 	event_unref(&ctx->event);
343 	pool_unref(&ctx->pool);
344 }
345 
346 static struct mail *
mail_deliver_open_mail(struct mailbox * box,uint32_t uid,enum mail_fetch_field wanted_fields,struct mailbox_transaction_context ** trans_r)347 mail_deliver_open_mail(struct mailbox *box, uint32_t uid,
348 		       enum mail_fetch_field wanted_fields,
349 		       struct mailbox_transaction_context **trans_r)
350 {
351 	struct mailbox_transaction_context *t;
352 	struct mail *mail;
353 
354 	*trans_r = NULL;
355 
356 	if (mailbox_sync(box, MAILBOX_SYNC_FLAG_FAST) < 0)
357 		return NULL;
358 
359 	t = mailbox_transaction_begin(box, 0, __func__);
360 	mail = mail_alloc(t, wanted_fields, NULL);
361 
362 	if (!mail_set_uid(mail, uid)) {
363 		mail_free(&mail);
364 		mailbox_transaction_rollback(&t);
365 	}
366 	*trans_r = t;
367 	return mail;
368 }
369 
mail_deliver_save(struct mail_deliver_context * ctx,const char * mailbox,enum mail_flags flags,const char * const * keywords,struct mail_storage ** storage_r)370 int mail_deliver_save(struct mail_deliver_context *ctx, const char *mailbox,
371 		      enum mail_flags flags, const char *const *keywords,
372 		      struct mail_storage **storage_r)
373 {
374 	struct mail_deliver_save_open_context open_ctx;
375 	struct mailbox *box;
376 	enum mailbox_transaction_flags trans_flags;
377 	struct mailbox_transaction_context *t;
378 	struct mail_save_context *save_ctx;
379 	struct mailbox_header_lookup_ctx *headers_ctx;
380 	struct mail_keywords *kw;
381 	struct mail *dest_mail;
382 	enum mail_error error;
383 	const char *mailbox_name, *errstr, *guid;
384 	struct mail_transaction_commit_changes changes;
385 	bool default_save;
386 	int ret = 0;
387 
388 	i_assert(ctx->dest_mail == NULL);
389 
390 	default_save = strcmp(mailbox, ctx->rcpt_default_mailbox) == 0;
391 	if (default_save)
392 		ctx->tried_default_save = TRUE;
393 
394 	i_zero(&open_ctx);
395 	open_ctx.user = ctx->rcpt_user;
396 	open_ctx.lda_mailbox_autocreate = ctx->set->lda_mailbox_autocreate;
397 	open_ctx.lda_mailbox_autosubscribe = ctx->set->lda_mailbox_autosubscribe;
398 
399 	mailbox_name = str_sanitize(mailbox, 80);
400 	if (mail_deliver_save_open(&open_ctx, mailbox, &box,
401 				   &error, &errstr) < 0) {
402 		if (box != NULL) {
403 			*storage_r = mailbox_get_storage(box);
404 			mailbox_free(&box);
405 		}
406 		mail_deliver_log(ctx, "save failed to open mailbox %s: %s",
407 				 mailbox_name, errstr);
408 		return -1;
409 	}
410 	*storage_r = mailbox_get_storage(box);
411 
412 	trans_flags = MAILBOX_TRANSACTION_FLAG_EXTERNAL;
413 	if (ctx->save_dest_mail)
414 		trans_flags |= MAILBOX_TRANSACTION_FLAG_ASSIGN_UIDS;
415 	t = mailbox_transaction_begin(box, trans_flags, __func__);
416 
417 	kw = str_array_length(keywords) == 0 ? NULL :
418 		mailbox_keywords_create_valid(box, keywords);
419 	save_ctx = mailbox_save_alloc(t);
420 	if (ctx->mail_from != NULL) {
421 		mailbox_save_set_from_envelope(save_ctx,
422 			smtp_address_encode(ctx->mail_from));
423 	}
424 	mailbox_save_set_flags(save_ctx, flags, kw);
425 
426 	headers_ctx = mailbox_header_lookup_init(box, lda_log_wanted_headers);
427 	dest_mail = mailbox_save_get_dest_mail(save_ctx);
428 	mail_add_temp_wanted_fields(dest_mail, lda_log_wanted_fetch_fields, NULL);
429 	mailbox_header_lookup_unref(&headers_ctx);
430 	mail_deliver_deduplicate_guid_if_needed(ctx->session, save_ctx);
431 
432 	if (mailbox_save_using_mail(&save_ctx, ctx->src_mail) < 0)
433 		ret = -1;
434 	if (kw != NULL)
435 		mailbox_keywords_unref(&kw);
436 
437 	if (ret < 0)
438 		mailbox_transaction_rollback(&t);
439 	else
440 		ret = mailbox_transaction_commit_get_changes(&t, &changes);
441 
442 	if (ret == 0) {
443 		ctx->saved_mail = TRUE;
444 		if (ctx->save_dest_mail) {
445 			/* copying needs the message body. with maildir we also
446 			   need to get the GUID in case the message gets
447 			   expunged. get these early so the copying won't fail
448 			   later on. */
449 			i_assert(array_count(&changes.saved_uids) == 1);
450 			const struct seq_range *range =
451 				array_front(&changes.saved_uids);
452 			i_assert(range->seq1 == range->seq2);
453 			ctx->dest_mail = mail_deliver_open_mail(box, range->seq1,
454 				MAIL_FETCH_STREAM_BODY | MAIL_FETCH_GUID, &t);
455 			if (ctx->dest_mail == NULL) {
456 				i_assert(t == NULL);
457 			} else if (mail_get_special(ctx->dest_mail, MAIL_FETCH_GUID, &guid) < 0) {
458 				mail_free(&ctx->dest_mail);
459 				mailbox_transaction_rollback(&t);
460 			}
461 		}
462 		mail_deliver_log(ctx, "saved mail to %s", mailbox_name);
463 		pool_unref(&changes.pool);
464 	} else {
465 		mail_deliver_log(ctx, "save failed to %s: %s", mailbox_name,
466 			mail_storage_get_last_internal_error(*storage_r, &error));
467 	}
468 
469 	if (ctx->dest_mail == NULL)
470 		mailbox_free(&box);
471 	return ret;
472 }
473 
474 const struct smtp_address *
mail_deliver_get_return_address(struct mail_deliver_context * ctx)475 mail_deliver_get_return_address(struct mail_deliver_context *ctx)
476 {
477 	struct message_address *addr;
478 	struct smtp_address *smtp_addr;
479 	const char *path;
480 	int ret;
481 
482 	if (!smtp_address_isnull(ctx->mail_from))
483 		return ctx->mail_from;
484 
485 	if ((ret=mail_get_first_header(ctx->src_mail,
486 				       "Return-Path", &path)) <= 0) {
487 		if (ret < 0) {
488 			struct mailbox *box = ctx->src_mail->box;
489 			e_warning(ctx->event,
490 				  "Failed read return-path header: %s",
491 				  mailbox_get_last_internal_error(box, NULL));
492 		}
493 		return NULL;
494 	}
495 	if (message_address_parse_path(pool_datastack_create(),
496 				       (const unsigned char *)path,
497 				       strlen(path), &addr) < 0 ||
498 	    smtp_address_create_from_msg(ctx->pool, addr, &smtp_addr) < 0) {
499 		e_warning(ctx->event, "Failed to parse return-path header");
500 		return NULL;
501 	}
502 	return smtp_addr;
503 }
504 
mail_deliver_get_new_message_id(struct mail_deliver_context * ctx)505 const char *mail_deliver_get_new_message_id(struct mail_deliver_context *ctx)
506 {
507 	static int count = 0;
508 	struct mail_user *user = ctx->rcpt_user;
509 	const struct mail_storage_settings *mail_set =
510 		mail_user_set_get_storage_set(user);
511 
512 	return t_strdup_printf("<dovecot-%s-%s-%d@%s>",
513 			       dec2str(ioloop_timeval.tv_sec),
514 			       dec2str(ioloop_timeval.tv_usec),
515 			       count++, mail_set->hostname);
516 }
517 
mail_deliver_is_tempfailed(struct mail_deliver_context * ctx,struct mail_storage * storage)518 static bool mail_deliver_is_tempfailed(struct mail_deliver_context *ctx,
519 				       struct mail_storage *storage)
520 {
521 	enum mail_error error;
522 
523 	if (ctx->tempfail_error != NULL)
524 		return TRUE;
525 	if (storage != NULL) {
526 		(void)mail_storage_get_last_error(storage, &error);
527 		return error == MAIL_ERROR_TEMP;
528 	}
529 	return FALSE;
530 }
531 
532 static int
mail_do_deliver(struct mail_deliver_context * ctx,struct mail_storage ** storage_r)533 mail_do_deliver(struct mail_deliver_context *ctx,
534 		struct mail_storage **storage_r)
535 {
536 	int ret;
537 
538 	*storage_r = NULL;
539 	if (deliver_mail == NULL)
540 		ret = -1;
541 	else {
542 		ctx->dup_db = mail_duplicate_db_init(ctx->rcpt_user,
543 						     DUPLICATE_DB_NAME);
544 		if (deliver_mail(ctx, storage_r) <= 0) {
545 			/* if message was saved, don't bounce it even though
546 			   the script failed later. */
547 			ret = ctx->saved_mail ? 0 : -1;
548 		} else {
549 			/* success. message may or may not have been saved. */
550 			ret = 0;
551 		}
552 		mail_duplicate_db_deinit(&ctx->dup_db);
553 		if (ret < 0 && mail_deliver_is_tempfailed(ctx, *storage_r))
554 			return -1;
555 	}
556 
557 	if (ret < 0 && !ctx->tried_default_save) {
558 		/* plugins didn't handle this. save into the default mailbox. */
559 		ret = mail_deliver_save(ctx, ctx->rcpt_default_mailbox, 0, NULL,
560 					storage_r);
561 		if (ret < 0 && mail_deliver_is_tempfailed(ctx, *storage_r))
562 			return -1;
563 	}
564 	if (ret < 0 && strcasecmp(ctx->rcpt_default_mailbox, "INBOX") != 0) {
565 		/* still didn't work. try once more to save it
566 		   to INBOX. */
567 		ret = mail_deliver_save(ctx, "INBOX", 0, NULL, storage_r);
568 	}
569 	return ret;
570 }
571 
mail_deliver(struct mail_deliver_context * ctx,enum mail_deliver_error * error_code_r,const char ** error_r)572 int mail_deliver(struct mail_deliver_context *ctx,
573 		 enum mail_deliver_error *error_code_r,
574 		 const char **error_r)
575 {
576 	struct mail_deliver_user *muser =
577 		MAIL_DELIVER_USER_CONTEXT(ctx->rcpt_user);
578 	struct event_passthrough *e;
579 	struct mail_storage *storage = NULL;
580 	enum mail_deliver_error error_code = MAIL_DELIVER_ERROR_NONE;
581 	const char *error = NULL;
582 	int ret;
583 
584 	i_assert(muser->deliver_ctx == NULL);
585 
586 	mail_deliver_fields_update(&ctx->fields, ctx->pool, ctx->src_mail);
587 	mail_deliver_update_event(ctx);
588 
589 	muser->want_storage_id =
590 		var_has_key(ctx->set->deliver_log_format, '\0', "storage_id");
591 
592 	muser->deliver_ctx = ctx;
593 
594 	e = event_create_passthrough(ctx->event)->
595 		set_name("mail_delivery_started");
596 	e_debug(e->event(), "Local delivery started");
597 
598 	ret = mail_do_deliver(ctx, &storage);
599 
600 	if (ret >= 0)
601 		i_assert(ret == 0); /* ret > 0 has no defined meaning */
602 	else if (ctx->tempfail_error != NULL) {
603 		error = ctx->tempfail_error;
604 		error_code = MAIL_DELIVER_ERROR_TEMPORARY;
605 	} else if (storage != NULL) {
606 		enum mail_error mail_error;
607 
608 		error = mail_storage_get_last_error(storage, &mail_error);
609 		if (mail_error == MAIL_ERROR_NOQUOTA) {
610 			error_code = MAIL_DELIVER_ERROR_NOQUOTA;
611 		} else {
612 			error_code = MAIL_DELIVER_ERROR_TEMPORARY;
613 		}
614 	} else {
615 		/* This shouldn't happen */
616 		e_error(ctx->event, "BUG: Saving failed to unknown storage");
617 		error = "Temporary internal error";
618 		error_code = MAIL_DELIVER_ERROR_INTERNAL;
619 	}
620 
621 	e = event_create_passthrough(ctx->event)->
622 		set_name("mail_delivery_finished");
623 	if (ret == 0) {
624 		e_debug(e->event(), "Local delivery finished successfully");
625 	} else {
626 		e->add_str("error", error);
627 		e_debug(e->event(), "Local delivery failed: %s", error);
628 	}
629 
630 	muser->deliver_ctx = NULL;
631 
632 	*error_code_r = error_code;
633 	*error_r = error;
634 	return ret;
635 }
636 
mail_deliver_hook_set(deliver_mail_func_t * new_hook)637 deliver_mail_func_t *mail_deliver_hook_set(deliver_mail_func_t *new_hook)
638 {
639 	deliver_mail_func_t *old_hook = deliver_mail;
640 
641 	deliver_mail = new_hook;
642 	return old_hook;
643 }
644 
mail_deliver_save_finish(struct mail_save_context * ctx)645 static int mail_deliver_save_finish(struct mail_save_context *ctx)
646 {
647 	struct mailbox *box = ctx->transaction->box;
648 	struct mail_deliver_mailbox *mbox = MAIL_DELIVER_STORAGE_CONTEXT(box);
649 	struct mail_deliver_user *muser =
650 		MAIL_DELIVER_USER_CONTEXT(box->storage->user);
651 	struct mail_deliver_transaction *dt =
652 		MAIL_DELIVER_STORAGE_CONTEXT(ctx->transaction);
653 
654 	if (mbox->module_ctx.super.save_finish(ctx) < 0)
655 		return -1;
656 
657 	/* initialize most of the fields from dest_mail */
658 	mail_deliver_fields_update(&dt->deliver_fields,
659 				   muser->deliver_ctx->pool,
660 				   ctx->dest_mail);
661 	return 0;
662 }
663 
mail_deliver_copy(struct mail_save_context * ctx,struct mail * mail)664 static int mail_deliver_copy(struct mail_save_context *ctx, struct mail *mail)
665 {
666 	struct mailbox *box = ctx->transaction->box;
667 	struct mail_deliver_mailbox *mbox = MAIL_DELIVER_STORAGE_CONTEXT(box);
668 	struct mail_deliver_user *muser =
669 		MAIL_DELIVER_USER_CONTEXT(box->storage->user);
670 	struct mail_deliver_transaction *dt =
671 		MAIL_DELIVER_STORAGE_CONTEXT(ctx->transaction);
672 
673 	if (mbox->module_ctx.super.copy(ctx, mail) < 0)
674 		return -1;
675 
676 	/* initialize most of the fields from dest_mail */
677 	mail_deliver_fields_update(&dt->deliver_fields,
678 				   muser->deliver_ctx->pool,
679 				   ctx->dest_mail);
680 	return 0;
681 }
682 
683 static void
mail_deliver_fields_update_post_commit(struct mailbox * orig_box,uint32_t uid)684 mail_deliver_fields_update_post_commit(struct mailbox *orig_box, uint32_t uid)
685 {
686 	struct mail_deliver_user *muser =
687 		MAIL_DELIVER_USER_CONTEXT(orig_box->storage->user);
688 	struct mailbox *box;
689 	struct mailbox_transaction_context *t;
690 	struct mail *mail;
691 	const char *storage_id;
692 
693 	if (!muser->want_storage_id)
694 		return;
695 
696 	/* getting storage_id requires a whole new mailbox view that is
697 	   synced, so it'll contain the newly written mail. this is racy, so
698 	   it's possible another process has already deleted the mail. */
699 	box = mailbox_alloc(orig_box->list, orig_box->vname, 0);
700 	mailbox_set_reason(box, "lib-lda storage-id");
701 
702 	mail = mail_deliver_open_mail(box, uid, MAIL_FETCH_STORAGE_ID, &t);
703 	if (mail != NULL) {
704 		if (mail_get_special(mail, MAIL_FETCH_STORAGE_ID, &storage_id) < 0 ||
705 		    storage_id[0] == '\0')
706 			storage_id = NULL;
707 		muser->deliver_ctx->fields.storage_id =
708 			p_strdup(muser->deliver_ctx->pool, storage_id);
709 		mail_free(&mail);
710 		(void)mailbox_transaction_commit(&t);
711 	} else {
712 		muser->deliver_ctx->fields.storage_id = NULL;
713 	}
714 	mailbox_free(&box);
715 }
716 
717 static struct mailbox_transaction_context *
mail_deliver_transaction_begin(struct mailbox * box,enum mailbox_transaction_flags flags,const char * reason)718 mail_deliver_transaction_begin(struct mailbox *box,
719 			       enum mailbox_transaction_flags flags,
720 			       const char *reason)
721 {
722 	struct mail_deliver_mailbox *mbox = MAIL_DELIVER_STORAGE_CONTEXT(box);
723 	struct mail_deliver_user *muser =
724 		MAIL_DELIVER_USER_CONTEXT(box->storage->user);
725 	struct mailbox_transaction_context *t;
726 	struct mail_deliver_transaction *dt;
727 
728 	i_assert(muser->deliver_ctx != NULL);
729 
730 	t = mbox->module_ctx.super.transaction_begin(box, flags, reason);
731 	dt = p_new(muser->deliver_ctx->pool, struct mail_deliver_transaction, 1);
732 
733 	MODULE_CONTEXT_SET(t, mail_deliver_storage_module, dt);
734 	return t;
735 }
736 
737 static int
mail_deliver_transaction_commit(struct mailbox_transaction_context * ctx,struct mail_transaction_commit_changes * changes_r)738 mail_deliver_transaction_commit(struct mailbox_transaction_context *ctx,
739 				struct mail_transaction_commit_changes *changes_r)
740 {
741 	struct mailbox *box = ctx->box;
742 	struct mail_deliver_mailbox *mbox = MAIL_DELIVER_STORAGE_CONTEXT(box);
743 	struct mail_deliver_transaction *dt = MAIL_DELIVER_STORAGE_CONTEXT(ctx);
744 	struct mail_deliver_user *muser =
745 		MAIL_DELIVER_USER_CONTEXT(box->storage->user);
746 
747 	i_assert(muser->deliver_ctx != NULL);
748 
749 	/* sieve creates multiple transactions, saves the mails and
750 	   then commits all of them at the end. we'll need to keep
751 	   switching the deliver_ctx->fields for each commit.
752 
753 	   we also want to do this only for commits generated by sieve.
754 	   other plugins or storage backends may be creating transactions as
755 	   well, which we need to ignore. */
756 	if ((box->flags & MAILBOX_FLAG_POST_SESSION) != 0) {
757 		muser->deliver_ctx->fields = dt->deliver_fields;
758 		mail_deliver_update_event(muser->deliver_ctx);
759 	}
760 
761 	if (mbox->module_ctx.super.transaction_commit(ctx, changes_r) < 0)
762 		return -1;
763 
764 	if (array_count(&changes_r->saved_uids) > 0) {
765 		const struct seq_range *range =
766 			array_front(&changes_r->saved_uids);
767 
768 		mail_deliver_fields_update_post_commit(box, range->seq1);
769 	}
770 	return 0;
771 }
772 
mail_deliver_mail_user_created(struct mail_user * user)773 static void mail_deliver_mail_user_created(struct mail_user *user)
774 {
775 	struct mail_deliver_user *muser;
776 
777 	muser = p_new(user->pool, struct mail_deliver_user, 1);
778 	MODULE_CONTEXT_SET(user, mail_deliver_user_module, muser);
779 }
780 
mail_deliver_mailbox_allocated(struct mailbox * box)781 static void mail_deliver_mailbox_allocated(struct mailbox *box)
782 {
783 	struct mailbox_vfuncs *v = box->vlast;
784 	struct mail_deliver_mailbox *mbox;
785 	struct mail_deliver_user *muser =
786 		MAIL_DELIVER_USER_CONTEXT(box->storage->user);
787 
788 	/* we are doing something other than lda/lmtp delivery
789 	   and should not be involved */
790 	if (muser->deliver_ctx == NULL)
791 		return;
792 
793 	if ((box->flags & MAILBOX_FLAG_POST_SESSION) != 0)
794 		mailbox_set_reason(box, "lib-lda delivery");
795 
796 	mbox = p_new(box->pool, struct mail_deliver_mailbox, 1);
797 	mbox->module_ctx.super = *v;
798 	box->vlast = &mbox->module_ctx.super;
799 	v->save_finish = mail_deliver_save_finish;
800 	v->copy = mail_deliver_copy;
801 	v->transaction_begin = mail_deliver_transaction_begin;
802 	v->transaction_commit = mail_deliver_transaction_commit;
803 
804 	MODULE_CONTEXT_SET(box, mail_deliver_storage_module, mbox);
805  }
806 
807 static struct mail_storage_hooks mail_deliver_hooks = {
808 	.mail_user_created = mail_deliver_mail_user_created,
809 	.mailbox_allocated = mail_deliver_mailbox_allocated
810 };
811 
mail_deliver_hooks_init(void)812 void mail_deliver_hooks_init(void)
813 {
814 	mail_storage_hooks_add_internal(&mail_deliver_hooks);
815 }
816