xref: /openbsd-src/usr.sbin/smtpd/mda.c (revision f2da64fbbbf1b03f09f390ab01267c93dfd77c4c)
1 /*	$OpenBSD: mda.c,v 1.120 2016/09/01 15:12:45 eric Exp $	*/
2 
3 /*
4  * Copyright (c) 2008 Gilles Chehade <gilles@poolp.org>
5  * Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org>
6  * Copyright (c) 2009 Jacek Masiulaniec <jacekm@dobremiasto.net>
7  * Copyright (c) 2012 Eric Faurot <eric@openbsd.org>
8  *
9  * Permission to use, copy, modify, and distribute this software for any
10  * purpose with or without fee is hereby granted, provided that the above
11  * copyright notice and this permission notice appear in all copies.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
16  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
19  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20  */
21 
22 #include <sys/types.h>
23 #include <sys/queue.h>
24 #include <sys/tree.h>
25 #include <sys/socket.h>
26 
27 #include <ctype.h>
28 #include <err.h>
29 #include <errno.h>
30 #include <event.h>
31 #include <imsg.h>
32 #include <inttypes.h>
33 #include <pwd.h>
34 #include <signal.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include <time.h>
39 #include <unistd.h>
40 #include <limits.h>
41 #include <vis.h>
42 
43 #include "smtpd.h"
44 #include "log.h"
45 
46 #define MDA_HIWAT		65536
47 
48 struct mda_envelope {
49 	TAILQ_ENTRY(mda_envelope)	 entry;
50 	uint64_t			 id;
51 	time_t				 creation;
52 	char				*sender;
53 	char				*dest;
54 	char				*rcpt;
55 	enum action_type		 method;
56 	char				*user;
57 	char				*buffer;
58 };
59 
60 #define USER_WAITINFO	0x01
61 #define USER_RUNNABLE	0x02
62 #define USER_ONHOLD	0x04
63 #define USER_HOLDQ	0x08
64 
65 struct mda_user {
66 	uint64_t			id;
67 	TAILQ_ENTRY(mda_user)		entry;
68 	TAILQ_ENTRY(mda_user)		entry_runnable;
69 	char				name[LOGIN_NAME_MAX];
70 	char				usertable[PATH_MAX];
71 	size_t				evpcount;
72 	TAILQ_HEAD(, mda_envelope)	envelopes;
73 	int				flags;
74 	size_t				running;
75 	struct userinfo			userinfo;
76 };
77 
78 struct mda_session {
79 	uint64_t		 id;
80 	struct mda_user		*user;
81 	struct mda_envelope	*evp;
82 	struct io		 io;
83 	struct iobuf		 iobuf;
84 	FILE			*datafp;
85 };
86 
87 static void mda_io(struct io *, int);
88 static int mda_check_loop(FILE *, struct mda_envelope *);
89 static int mda_getlastline(int, char *, size_t);
90 static void mda_done(struct mda_session *);
91 static void mda_fail(struct mda_user *, int, const char *,
92     enum enhanced_status_code);
93 static void mda_drain(void);
94 static void mda_log(const struct mda_envelope *, const char *, const char *);
95 static void mda_queue_ok(uint64_t);
96 static void mda_queue_tempfail(uint64_t, const char *,
97     enum enhanced_status_code);
98 static void mda_queue_permfail(uint64_t, const char *, enum enhanced_status_code);
99 static void mda_queue_loop(uint64_t);
100 static struct mda_user *mda_user(const struct envelope *);
101 static void mda_user_free(struct mda_user *);
102 static const char *mda_user_to_text(const struct mda_user *);
103 static struct mda_envelope *mda_envelope(const struct envelope *);
104 static void mda_envelope_free(struct mda_envelope *);
105 static struct mda_session * mda_session(struct mda_user *);
106 
107 static struct tree	sessions;
108 static struct tree	users;
109 
110 static TAILQ_HEAD(, mda_user)	runnable;
111 
112 void
113 mda_imsg(struct mproc *p, struct imsg *imsg)
114 {
115 	struct mda_session	*s;
116 	struct mda_user		*u;
117 	struct mda_envelope	*e;
118 	struct envelope		 evp;
119 	struct userinfo		*userinfo;
120 	struct deliver		 deliver;
121 	struct msg		 m;
122 	const void		*data;
123 	const char		*error, *parent_error;
124 	uint64_t		 reqid;
125 	time_t			 now;
126 	size_t			 sz;
127 	char			 out[256], buf[LINE_MAX];
128 	int			 n;
129 	enum lka_resp_status	status;
130 
131 	if (p->proc == PROC_LKA) {
132 		switch (imsg->hdr.type) {
133 		case IMSG_MDA_LOOKUP_USERINFO:
134 			m_msg(&m, imsg);
135 			m_get_id(&m, &reqid);
136 			m_get_int(&m, (int *)&status);
137 			if (status == LKA_OK)
138 				m_get_data(&m, &data, &sz);
139 			m_end(&m);
140 
141 			u = tree_xget(&users, reqid);
142 
143 			if (status == LKA_TEMPFAIL)
144 				mda_fail(u, 0,
145 				    "Temporary failure in user lookup",
146 				    ESC_OTHER_ADDRESS_STATUS);
147 			else if (status == LKA_PERMFAIL)
148 				mda_fail(u, 1,
149 				    "Permanent failure in user lookup",
150 				    ESC_DESTINATION_MAILBOX_HAS_MOVED);
151 			else {
152 				if (sz != sizeof(u->userinfo))
153 					fatalx("mda: userinfo size mismatch");
154 				memmove(&u->userinfo, data, sz);
155 				u->flags &= ~USER_WAITINFO;
156 				u->flags |= USER_RUNNABLE;
157 				TAILQ_INSERT_TAIL(&runnable, u, entry_runnable);
158 				mda_drain();
159 			}
160 			return;
161 		}
162 	}
163 
164 	if (p->proc == PROC_QUEUE) {
165 		switch (imsg->hdr.type) {
166 
167 		case IMSG_QUEUE_DELIVER:
168 			m_msg(&m, imsg);
169 			m_get_envelope(&m, &evp);
170 			m_end(&m);
171 
172 			u = mda_user(&evp);
173 
174 			if (u->evpcount >= env->sc_mda_task_hiwat) {
175 				if (!(u->flags & USER_ONHOLD)) {
176 					log_debug("debug: mda: hiwat reached for "
177 					    "user \"%s\": holding envelopes",
178 					    mda_user_to_text(u));
179 					u->flags |= USER_ONHOLD;
180 				}
181 			}
182 
183 			if (u->flags & USER_ONHOLD) {
184 				u->flags |= USER_HOLDQ;
185 				m_create(p_queue, IMSG_MDA_DELIVERY_HOLD,
186 				    0, 0, -1);
187 				m_add_evpid(p_queue, evp.id);
188 				m_add_id(p_queue, u->id);
189 				m_close(p_queue);
190 				return;
191 			}
192 
193 			e = mda_envelope(&evp);
194 			TAILQ_INSERT_TAIL(&u->envelopes, e, entry);
195 			u->evpcount += 1;
196 			stat_increment("mda.pending", 1);
197 
198 			if (!(u->flags & USER_RUNNABLE) &&
199 			    !(u->flags & USER_WAITINFO)) {
200 				u->flags |= USER_RUNNABLE;
201 				TAILQ_INSERT_TAIL(&runnable, u, entry_runnable);
202 			}
203 
204 			mda_drain();
205 			return;
206 
207 		case IMSG_MDA_OPEN_MESSAGE:
208 			m_msg(&m, imsg);
209 			m_get_id(&m, &reqid);
210 			m_end(&m);
211 
212 			s = tree_xget(&sessions, reqid);
213 			e = s->evp;
214 
215 			if (imsg->fd == -1) {
216 				log_debug("debug: mda: cannot get message fd");
217 				mda_queue_tempfail(e->id,
218 				    "Cannot get message fd",
219 				    ESC_OTHER_MAIL_SYSTEM_STATUS);
220 				mda_log(e, "TempFail", "Cannot get message fd");
221 				mda_done(s);
222 				return;
223 			}
224 
225 			log_debug("debug: mda: got message fd %d "
226 			    "for session %016"PRIx64 " evpid %016"PRIx64,
227 			    imsg->fd, s->id, e->id);
228 
229 			if ((s->datafp = fdopen(imsg->fd, "r")) == NULL) {
230 				log_warn("warn: mda: fdopen");
231 				close(imsg->fd);
232 				mda_queue_tempfail(e->id, "fdopen failed",
233 				    ESC_OTHER_MAIL_SYSTEM_STATUS);
234 				mda_log(e, "TempFail", "fdopen failed");
235 				mda_done(s);
236 				return;
237 			}
238 
239 			/* check delivery loop */
240 			if (mda_check_loop(s->datafp, e)) {
241 				log_debug("debug: mda: loop detected");
242 				mda_queue_loop(e->id);
243 				mda_log(e, "PermFail", "Loop detected");
244 				mda_done(s);
245 				return;
246 			}
247 
248 			n = 0;
249 			/*
250 			 * prepend "From " separator ... for
251 			 * A_MDA and A_FILENAME backends only
252 			 */
253 			if (e->method == A_MDA || e->method == A_FILENAME) {
254 				time(&now);
255 				if (e->sender[0])
256 					n = iobuf_fqueue(&s->iobuf,
257 					    "From %s %s", e->sender,
258 					    ctime(&now));
259 				else
260 					n = iobuf_fqueue(&s->iobuf,
261 					    "From MAILER-DAEMON@%s %s",
262 					    env->sc_hostname, ctime(&now));
263 			}
264 			if (n != -1) {
265 				/* start queueing delivery headers */
266 				if (e->sender[0])
267 					/*
268 					 * XXX: remove existing Return-Path,
269 					 * if any
270 					 */
271 					n = iobuf_fqueue(&s->iobuf,
272 					    "Return-Path: %s\n"
273 					    "Delivered-To: %s\n",
274 					    e->sender,
275 					    e->rcpt ? e->rcpt : e->dest);
276 				else
277 					n = iobuf_fqueue(&s->iobuf,
278 					    "Delivered-To: %s\n",
279 					    e->rcpt ? e->rcpt : e->dest);
280 			}
281 			if (n == -1) {
282 				log_warn("warn: mda: "
283 				    "fail to write delivery info");
284 				mda_queue_tempfail(e->id, "Out of memory",
285 				    ESC_OTHER_MAIL_SYSTEM_STATUS);
286 				mda_log(e, "TempFail", "Out of memory");
287 				mda_done(s);
288 				return;
289 			}
290 
291 			/* request parent to fork a helper process */
292 			userinfo = &s->user->userinfo;
293 			memset(&deliver, 0, sizeof deliver);
294 			switch (e->method) {
295 			case A_MDA:
296 				deliver.mode = A_MDA;
297 				deliver.userinfo = *userinfo;
298 				(void)strlcpy(deliver.user, userinfo->username,
299 				    sizeof(deliver.user));
300 				if (strlcpy(deliver.to, e->buffer,
301 					sizeof(deliver.to))
302 				    >= sizeof(deliver.to)) {
303 					mda_queue_tempfail(e->id,
304 					    "mda command too long",
305 					    ESC_OTHER_MAIL_SYSTEM_STATUS);
306 					mda_log(e, "TempFail",
307 					    "mda command too long");
308 					mda_done(s);
309 					return;
310 				}
311 				break;
312 
313 			case A_MBOX:
314 				/*
315 				 * MBOX is a special case as we MUST
316 				 * deliver as root, just override the uid.
317 				 */
318 				deliver.mode = A_MBOX;
319 				deliver.userinfo = *userinfo;
320 				deliver.userinfo.uid = 0;
321 				(void)strlcpy(deliver.user, "root",
322 				    sizeof(deliver.user));
323 				(void)strlcpy(deliver.from, e->sender,
324 				    sizeof(deliver.from));
325 				(void)strlcpy(deliver.to, userinfo->username,
326 				    sizeof(deliver.to));
327 				break;
328 
329 			case A_MAILDIR:
330 				deliver.mode = A_MAILDIR;
331 				deliver.userinfo = *userinfo;
332 				(void)strlcpy(deliver.user, userinfo->username,
333 				    sizeof(deliver.user));
334 				(void)strlcpy(deliver.dest, e->dest,
335 				    sizeof(deliver.dest));
336 				if (strlcpy(deliver.to, e->buffer,
337 					sizeof(deliver.to))
338 				    >= sizeof(deliver.to)) {
339 					log_warn("warn: mda: "
340 					    "deliver buffer too large");
341 					mda_queue_tempfail(e->id,
342 					    "Maildir path too long",
343 					    ESC_OTHER_MAIL_SYSTEM_STATUS);
344 					mda_log(e, "TempFail",
345 					    "Maildir path too long");
346 					mda_done(s);
347 					return;
348 				}
349 				break;
350 
351 			case A_FILENAME:
352 				deliver.mode = A_FILENAME;
353 				deliver.userinfo = *userinfo;
354 				(void)strlcpy(deliver.user, userinfo->username,
355 				    sizeof deliver.user);
356 				if (strlcpy(deliver.to, e->buffer,
357 					sizeof(deliver.to))
358 				    >= sizeof(deliver.to)) {
359 					log_warn("warn: mda: "
360 					    "deliver buffer too large");
361 					mda_queue_tempfail(e->id,
362 					    "filename path too long",
363 					    ESC_OTHER_MAIL_SYSTEM_STATUS);
364 					mda_log(e, "TempFail",
365 					    "filename path too long");
366 					mda_done(s);
367 					return;
368 				}
369 				break;
370 
371 			case A_LMTP:
372 				deliver.mode = A_LMTP;
373 				deliver.userinfo = *userinfo;
374 				(void)strlcpy(deliver.user, e->user,
375 				    sizeof(deliver.user));
376 				(void)strlcpy(deliver.from, e->sender,
377 				    sizeof(deliver.from));
378 				(void)strlcpy(deliver.dest, e->dest,
379 				    sizeof(deliver.dest));
380 				if (strlcpy(deliver.to, e->buffer,
381 					sizeof(deliver.to))
382 				    >= sizeof(deliver.to)) {
383 					log_warn("warn: mda: "
384 					    "deliver buffer too large");
385 					mda_queue_tempfail(e->id,
386 					    "socket path too long",
387 					    ESC_OTHER_MAIL_SYSTEM_STATUS);
388 					mda_log(e, "TempFail",
389 					    "socket path too long");
390 					mda_done(s);
391 					return;
392 				}
393 				break;
394 
395 			default:
396 				errx(1, "mda: unknown delivery method: %d",
397 				    e->method);
398 			}
399 
400 			log_debug("debug: mda: querying mda fd "
401 			    "for session %016"PRIx64 " evpid %016"PRIx64,
402 			    s->id, s->evp->id);
403 
404 			m_create(p_parent, IMSG_MDA_FORK, 0, 0, -1);
405 			m_add_id(p_parent, reqid);
406 			m_add_data(p_parent, &deliver, sizeof(deliver));
407 			m_close(p_parent);
408 			return;
409 		}
410 	}
411 
412 	if (p->proc == PROC_PARENT) {
413 		switch (imsg->hdr.type) {
414 		case IMSG_MDA_FORK:
415 			m_msg(&m, imsg);
416 			m_get_id(&m, &reqid);
417 			m_end(&m);
418 
419 			s = tree_xget(&sessions, reqid);
420 			e = s->evp;
421 			if (imsg->fd == -1) {
422 				log_warn("warn: mda: fail to retrieve mda fd");
423 				mda_queue_tempfail(e->id, "Cannot get mda fd",
424 				    ESC_OTHER_MAIL_SYSTEM_STATUS);
425 				mda_log(e, "TempFail", "Cannot get mda fd");
426 				mda_done(s);
427 				return;
428 			}
429 
430 			log_debug("debug: mda: got mda fd %d "
431 			    "for session %016"PRIx64 " evpid %016"PRIx64,
432 			    imsg->fd, s->id, s->evp->id);
433 
434 			io_set_nonblocking(imsg->fd);
435 			io_init(&s->io, imsg->fd, s, mda_io, &s->iobuf);
436 			io_set_write(&s->io);
437 			return;
438 
439 		case IMSG_MDA_DONE:
440 			m_msg(&m, imsg);
441 			m_get_id(&m, &reqid);
442 			m_get_string(&m, &parent_error);
443 			m_end(&m);
444 
445 			s = tree_xget(&sessions, reqid);
446 			e = s->evp;
447 			/*
448 			 * Grab last line of mda stdout/stderr if available.
449 			 */
450 			out[0] = '\0';
451 			if (imsg->fd != -1)
452 				mda_getlastline(imsg->fd, out, sizeof(out));
453 			/*
454 			 * Choose between parent's description of error and
455 			 * child's output, the latter having preference over
456 			 * the former.
457 			 */
458 			error = NULL;
459 			if (strcmp(parent_error, "exited okay") == 0) {
460 				if (s->datafp || iobuf_queued(&s->iobuf))
461 					error = "mda exited prematurely";
462 			} else
463 				error = out[0] ? out : parent_error;
464 
465 			/* update queue entry */
466 			if (error) {
467 				mda_queue_tempfail(e->id, error,
468 				    ESC_OTHER_MAIL_SYSTEM_STATUS);
469 				(void)snprintf(buf, sizeof buf,
470 				    "Error (%s)", error);
471 				mda_log(e, "TempFail", buf);
472 			}
473 			else {
474 				mda_queue_ok(e->id);
475 				mda_log(e, "Ok", "Delivered");
476 			}
477 			mda_done(s);
478 			return;
479 		}
480 	}
481 
482 	errx(1, "mda_imsg: unexpected %s imsg", imsg_to_str(imsg->hdr.type));
483 }
484 
485 void
486 mda_postfork()
487 {
488 }
489 
490 void
491 mda_postprivdrop()
492 {
493 	tree_init(&sessions);
494 	tree_init(&users);
495 	TAILQ_INIT(&runnable);
496 }
497 
498 static void
499 mda_io(struct io *io, int evt)
500 {
501 	struct mda_session	*s = io->arg;
502 	char			*ln = NULL;
503 	size_t			 sz = 0;
504 	ssize_t			 len;
505 
506 	log_trace(TRACE_IO, "mda: %p: %s %s", s, io_strevent(evt),
507 	    io_strio(io));
508 
509 	switch (evt) {
510 	case IO_LOWAT:
511 
512 	/* done */
513 	done:
514 		if (s->datafp == NULL) {
515 			log_debug("debug: mda: all data sent for session"
516 			    " %016"PRIx64 " evpid %016"PRIx64,
517 			    s->id, s->evp->id);
518 			io_clear(io);
519 			return;
520 		}
521 
522 		while (iobuf_queued(&s->iobuf) < MDA_HIWAT) {
523 			if ((len = getline(&ln, &sz, s->datafp)) == -1)
524 				break;
525 			if (iobuf_queue(&s->iobuf, ln, len) == -1) {
526 				m_create(p_parent, IMSG_MDA_KILL,
527 				    0, 0, -1);
528 				m_add_id(p_parent, s->id);
529 				m_add_string(p_parent, "Out of memory");
530 				m_close(p_parent);
531 				io_pause(io, IO_PAUSE_OUT);
532 				free(ln);
533 				return;
534 			}
535 		}
536 
537 		free(ln);
538 		ln = NULL;
539 		if (ferror(s->datafp)) {
540 			log_debug("debug: mda: ferror on session %016"PRIx64,
541 			    s->id);
542 			m_create(p_parent, IMSG_MDA_KILL, 0, 0, -1);
543 			m_add_id(p_parent, s->id);
544 			m_add_string(p_parent, "Error reading body");
545 			m_close(p_parent);
546 			io_pause(io, IO_PAUSE_OUT);
547 			return;
548 		}
549 
550 		if (feof(s->datafp)) {
551 			log_debug("debug: mda: end-of-file for session"
552 			    " %016"PRIx64 " evpid %016"PRIx64,
553 			    s->id, s->evp->id);
554 			fclose(s->datafp);
555 			s->datafp = NULL;
556 			if (iobuf_queued(&s->iobuf) == 0)
557 				goto done;
558 		}
559 		return;
560 
561 	case IO_TIMEOUT:
562 		log_debug("debug: mda: timeout on session %016"PRIx64, s->id);
563 		io_pause(io, IO_PAUSE_OUT);
564 		return;
565 
566 	case IO_ERROR:
567 		log_debug("debug: mda: io error on session %016"PRIx64": %s",
568 		    s->id, io->error);
569 		io_pause(io, IO_PAUSE_OUT);
570 		return;
571 
572 	case IO_DISCONNECTED:
573 		log_debug("debug: mda: io disconnected on session %016"PRIx64,
574 		    s->id);
575 		io_pause(io, IO_PAUSE_OUT);
576 		return;
577 
578 	default:
579 		log_debug("debug: mda: unexpected event on session %016"PRIx64,
580 		    s->id);
581 		io_pause(io, IO_PAUSE_OUT);
582 		return;
583 	}
584 }
585 
586 static int
587 mda_check_loop(FILE *fp, struct mda_envelope *e)
588 {
589 	char		*buf = NULL;
590 	size_t		 sz = 0;
591 	ssize_t		 len;
592 	int		 ret = 0;
593 
594 	while ((len = getline(&buf, &sz, fp)) != -1) {
595 		if (buf[len - 1] == '\n')
596 			buf[len - 1] = '\0';
597 
598 		if (strchr(buf, ':') == NULL && !isspace((unsigned char)*buf))
599 			break;
600 
601 		if (strncasecmp("Delivered-To: ", buf, 14) == 0) {
602 			if (strcasecmp(buf + 14, e->dest) == 0) {
603 				ret = 1;
604 				break;
605 			}
606 		}
607 	}
608 
609 	free(buf);
610 	fseek(fp, SEEK_SET, 0);
611 	return (ret);
612 }
613 
614 static int
615 mda_getlastline(int fd, char *dst, size_t dstsz)
616 {
617 	FILE	*fp;
618 	char	*ln = NULL;
619 	size_t	 sz = 0;
620 	ssize_t	 len;
621 
622 	if (lseek(fd, 0, SEEK_SET) < 0) {
623 		log_warn("warn: mda: lseek");
624 		close(fd);
625 		return (-1);
626 	}
627 	fp = fdopen(fd, "r");
628 	if (fp == NULL) {
629 		log_warn("warn: mda: fdopen");
630 		close(fd);
631 		return (-1);
632 	}
633 	while ((len = getline(&ln, &sz, fp)) != -1) {
634 		if (ln[len - 1] == '\n')
635 			ln[len - 1] = '\0';
636 	}
637 	fclose(fp);
638 
639 	if (sz != 0) {
640 		(void)strlcpy(dst, "\"", dstsz);
641 		(void)strnvis(dst + 1, ln, dstsz - 2, VIS_SAFE | VIS_CSTYLE);
642 		(void)strlcat(dst, "\"", dstsz);
643 	}
644 
645 	free(ln);
646 	return (0);
647 }
648 
649 static void
650 mda_fail(struct mda_user *user, int permfail, const char *error,
651     enum enhanced_status_code code)
652 {
653 	struct mda_envelope	*e;
654 
655 	while ((e = TAILQ_FIRST(&user->envelopes))) {
656 		TAILQ_REMOVE(&user->envelopes, e, entry);
657 		if (permfail) {
658 			mda_log(e, "PermFail", error);
659 			mda_queue_permfail(e->id, error, code);
660 		}
661 		else {
662 			mda_log(e, "TempFail", error);
663 			mda_queue_tempfail(e->id, error, code);
664 		}
665 		mda_envelope_free(e);
666 	}
667 
668 	mda_user_free(user);
669 }
670 
671 static void
672 mda_drain(void)
673 {
674 	struct mda_user		*u;
675 
676 	while ((u = (TAILQ_FIRST(&runnable)))) {
677 
678 		TAILQ_REMOVE(&runnable, u, entry_runnable);
679 
680 		if (u->evpcount == 0 && u->running == 0) {
681 			log_debug("debug: mda: all done for user \"%s\"",
682 			    mda_user_to_text(u));
683 			mda_user_free(u);
684 			continue;
685 		}
686 
687 		if (u->evpcount == 0) {
688 			log_debug("debug: mda: no more envelope for \"%s\"",
689 			    mda_user_to_text(u));
690 			u->flags &= ~USER_RUNNABLE;
691 			continue;
692 		}
693 
694 		if (u->running >= env->sc_mda_max_user_session) {
695 			log_debug("debug: mda: "
696 			    "maximum number of session reached for user \"%s\"",
697 			    mda_user_to_text(u));
698 			u->flags &= ~USER_RUNNABLE;
699 			continue;
700 		}
701 
702 		if (tree_count(&sessions) >= env->sc_mda_max_session) {
703 			log_debug("debug: mda: "
704 			    "maximum number of session reached");
705 			TAILQ_INSERT_HEAD(&runnable, u, entry_runnable);
706 			return;
707 		}
708 
709 		mda_session(u);
710 
711 		if (u->evpcount == env->sc_mda_task_lowat) {
712 			if (u->flags & USER_ONHOLD) {
713 				log_debug("debug: mda: down to lowat for user "
714 				    "\"%s\": releasing",
715 				    mda_user_to_text(u));
716 				u->flags &= ~USER_ONHOLD;
717 			}
718 			if (u->flags & USER_HOLDQ) {
719 				m_create(p_queue, IMSG_MDA_HOLDQ_RELEASE,
720 				    0, 0, -1);
721 				m_add_id(p_queue, u->id);
722 				m_add_int(p_queue, env->sc_mda_task_release);
723 				m_close(p_queue);
724 			}
725 		}
726 
727 		/* re-add the user at the tail of the queue */
728 		TAILQ_INSERT_TAIL(&runnable, u, entry_runnable);
729 	}
730 }
731 
732 static void
733 mda_done(struct mda_session *s)
734 {
735 	log_debug("debug: mda: session %016" PRIx64 " done", s->id);
736 
737 	tree_xpop(&sessions, s->id);
738 
739 	mda_envelope_free(s->evp);
740 
741 	s->user->running--;
742 	if (!(s->user->flags & USER_RUNNABLE)) {
743 		log_debug("debug: mda: user \"%s\" becomes runnable",
744 		    s->user->name);
745 		TAILQ_INSERT_TAIL(&runnable, s->user, entry_runnable);
746 		s->user->flags |= USER_RUNNABLE;
747 	}
748 
749 	if (s->datafp)
750 		fclose(s->datafp);
751 	io_clear(&s->io);
752 	iobuf_clear(&s->iobuf);
753 
754 	free(s);
755 
756 	stat_decrement("mda.running", 1);
757 
758 	mda_drain();
759 }
760 
761 static void
762 mda_log(const struct mda_envelope *evp, const char *prefix, const char *status)
763 {
764 	char rcpt[LINE_MAX];
765 	const char *method;
766 
767 	rcpt[0] = '\0';
768 	if (evp->rcpt)
769 		(void)snprintf(rcpt, sizeof rcpt, "rcpt=<%s>, ", evp->rcpt);
770 
771 	if (evp->method == A_MAILDIR)
772 		method = "maildir";
773 	else if (evp->method == A_MBOX)
774 		method = "mbox";
775 	else if (evp->method == A_FILENAME)
776 		method = "file";
777 	else if (evp->method == A_MDA)
778 		method = "mda";
779 	else if (evp->method == A_LMTP)
780 		method = "lmtp";
781 	else
782 		method = "???";
783 
784 	log_info("%016"PRIx64" mda event=delivery evpid=%016" PRIx64 " from=<%s> to=<%s> "
785 	    "%suser=%s method=%s delay=%s result=%s stat=%s",
786 	    (uint64_t)0,
787 	    evp->id,
788 	    evp->sender ? evp->sender : "",
789 	    evp->dest,
790 	    rcpt,
791 	    evp->user,
792 	    method,
793 	    duration_to_text(time(NULL) - evp->creation),
794 	    prefix,
795 	    status);
796 }
797 
798 static void
799 mda_queue_ok(uint64_t evpid)
800 {
801 	m_create(p_queue, IMSG_MDA_DELIVERY_OK, 0, 0, -1);
802 	m_add_evpid(p_queue, evpid);
803 	m_close(p_queue);
804 }
805 
806 static void
807 mda_queue_tempfail(uint64_t evpid, const char *reason,
808     enum enhanced_status_code code)
809 {
810 	m_create(p_queue, IMSG_MDA_DELIVERY_TEMPFAIL, 0, 0, -1);
811 	m_add_evpid(p_queue, evpid);
812 	m_add_string(p_queue, reason);
813 	m_add_int(p_queue, (int)code);
814 	m_close(p_queue);
815 }
816 
817 static void
818 mda_queue_permfail(uint64_t evpid, const char *reason,
819     enum enhanced_status_code code)
820 {
821 	m_create(p_queue, IMSG_MDA_DELIVERY_PERMFAIL, 0, 0, -1);
822 	m_add_evpid(p_queue, evpid);
823 	m_add_string(p_queue, reason);
824 	m_add_int(p_queue, (int)code);
825 	m_close(p_queue);
826 }
827 
828 static void
829 mda_queue_loop(uint64_t evpid)
830 {
831 	m_create(p_queue, IMSG_MDA_DELIVERY_LOOP, 0, 0, -1);
832 	m_add_evpid(p_queue, evpid);
833 	m_close(p_queue);
834 }
835 
836 static struct mda_user *
837 mda_user(const struct envelope *evp)
838 {
839 	struct mda_user	*u;
840 	void		*i;
841 
842 	i = NULL;
843 	while (tree_iter(&users, &i, NULL, (void**)(&u))) {
844 		if (!strcmp(evp->agent.mda.username, u->name) &&
845 		    !strcmp(evp->agent.mda.usertable, u->usertable))
846 			return (u);
847 	}
848 
849 	u = xcalloc(1, sizeof *u, "mda_user");
850 	u->id = generate_uid();
851 	TAILQ_INIT(&u->envelopes);
852 	(void)strlcpy(u->name, evp->agent.mda.username, sizeof(u->name));
853 	(void)strlcpy(u->usertable, evp->agent.mda.usertable,
854 	    sizeof(u->usertable));
855 
856 	tree_xset(&users, u->id, u);
857 
858 	m_create(p_lka, IMSG_MDA_LOOKUP_USERINFO, 0, 0, -1);
859 	m_add_id(p_lka, u->id);
860 	m_add_string(p_lka, evp->agent.mda.usertable);
861 	if (evp->agent.mda.delivery_user[0])
862 		m_add_string(p_lka, evp->agent.mda.delivery_user);
863 	else
864 		m_add_string(p_lka, evp->agent.mda.username);
865 	m_close(p_lka);
866 	u->flags |= USER_WAITINFO;
867 
868 	stat_increment("mda.user", 1);
869 
870 	if (evp->agent.mda.delivery_user[0])
871 		log_debug("mda: new user %016" PRIx64
872 		    " for \"%s\" delivering as \"%s\"",
873 		    u->id, mda_user_to_text(u), evp->agent.mda.delivery_user);
874 	else
875 		log_debug("mda: new user %016" PRIx64
876 		    " for \"%s\"", u->id, mda_user_to_text(u));
877 
878 	return (u);
879 }
880 
881 static void
882 mda_user_free(struct mda_user *u)
883 {
884 	tree_xpop(&users, u->id);
885 
886 	if (u->flags & USER_HOLDQ) {
887 		m_create(p_queue, IMSG_MDA_HOLDQ_RELEASE, 0, 0, -1);
888 		m_add_id(p_queue, u->id);
889 		m_add_int(p_queue, 0);
890 		m_close(p_queue);
891 	}
892 
893 	free(u);
894 	stat_decrement("mda.user", 1);
895 }
896 
897 static const char *
898 mda_user_to_text(const struct mda_user *u)
899 {
900 	static char buf[1024];
901 
902 	(void)snprintf(buf, sizeof(buf), "%s:%s", u->usertable, u->name);
903 
904 	return (buf);
905 }
906 
907 static struct mda_envelope *
908 mda_envelope(const struct envelope *evp)
909 {
910 	struct mda_envelope	*e;
911 	char			 buf[LINE_MAX];
912 
913 	e = xcalloc(1, sizeof *e, "mda_envelope");
914 	e->id = evp->id;
915 	e->creation = evp->creation;
916 	buf[0] = '\0';
917 	if (evp->sender.user[0] && evp->sender.domain[0])
918 		(void)snprintf(buf, sizeof buf, "%s@%s",
919 		    evp->sender.user, evp->sender.domain);
920 	e->sender = xstrdup(buf, "mda_envelope:sender");
921 	(void)snprintf(buf, sizeof buf, "%s@%s", evp->dest.user,
922 	    evp->dest.domain);
923 	e->dest = xstrdup(buf, "mda_envelope:dest");
924 	(void)snprintf(buf, sizeof buf, "%s@%s", evp->rcpt.user,
925 	    evp->rcpt.domain);
926 	if (strcmp(buf, e->dest))
927 		e->rcpt = xstrdup(buf, "mda_envelope:rcpt");
928 	e->method = evp->agent.mda.method;
929 	e->buffer = xstrdup(evp->agent.mda.buffer, "mda_envelope:buffer");
930 	e->user = xstrdup(evp->agent.mda.username, "mda_envelope:user");
931 
932 	stat_increment("mda.envelope", 1);
933 
934 	return (e);
935 }
936 
937 static void
938 mda_envelope_free(struct mda_envelope *e)
939 {
940 	free(e->sender);
941 	free(e->dest);
942 	free(e->rcpt);
943 	free(e->user);
944 	free(e->buffer);
945 	free(e);
946 
947 	stat_decrement("mda.envelope", 1);
948 }
949 
950 static struct mda_session *
951 mda_session(struct mda_user * u)
952 {
953 	struct mda_session *s;
954 
955 	s = xcalloc(1, sizeof *s, "mda_session");
956 	s->id = generate_uid();
957 	s->user = u;
958 	s->io.sock = -1;
959 	if (iobuf_init(&s->iobuf, 0, 0) == -1)
960 		fatal("mda_session");
961 
962 	tree_xset(&sessions, s->id, s);
963 
964 	s->evp = TAILQ_FIRST(&u->envelopes);
965 	TAILQ_REMOVE(&u->envelopes, s->evp, entry);
966 	u->evpcount--;
967 	u->running++;
968 
969 	stat_decrement("mda.pending", 1);
970 	stat_increment("mda.running", 1);
971 
972 	log_debug("debug: mda: new session %016" PRIx64
973 	    " for user \"%s\" evpid %016" PRIx64, s->id,
974 	    mda_user_to_text(u), s->evp->id);
975 
976 	m_create(p_queue, IMSG_MDA_OPEN_MESSAGE, 0, 0, -1);
977 	m_add_id(p_queue, s->id);
978 	m_add_msgid(p_queue, evpid_to_msgid(s->evp->id));
979 	m_close(p_queue);
980 
981 	return (s);
982 }
983