xref: /openbsd-src/usr.sbin/smtpd/smtpd.c (revision 1a8dbaac879b9f3335ad7fb25429ce63ac1d6bac)
1 /*	$OpenBSD: smtpd.c,v 1.335 2020/09/23 19:11:50 martijn 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  *
8  * Permission to use, copy, modify, and distribute this software for any
9  * purpose with or without fee is hereby granted, provided that the above
10  * copyright notice and this permission notice appear in all copies.
11  *
12  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19  */
20 
21 #include <sys/types.h>
22 #include <sys/queue.h>
23 #include <sys/tree.h>
24 #include <sys/socket.h>
25 #include <sys/wait.h>
26 #include <sys/stat.h>
27 #include <sys/uio.h>
28 #include <sys/mman.h>
29 
30 #include <bsd_auth.h>
31 #include <dirent.h>
32 #include <err.h>
33 #include <errno.h>
34 #include <event.h>
35 #include <fcntl.h>
36 #include <fts.h>
37 #include <grp.h>
38 #include <imsg.h>
39 #include <inttypes.h>
40 #include <login_cap.h>
41 #include <paths.h>
42 #include <poll.h>
43 #include <pwd.h>
44 #include <signal.h>
45 #include <stdio.h>
46 #include <syslog.h>
47 #include <limits.h>
48 #include <stdlib.h>
49 #include <string.h>
50 #include <sysexits.h>
51 #include <time.h>
52 #include <unistd.h>
53 
54 #include <openssl/ssl.h>
55 #include <openssl/evp.h>
56 
57 #include "smtpd.h"
58 #include "log.h"
59 #include "ssl.h"
60 
61 #define SMTPD_MAXARG 32
62 
63 static void parent_imsg(struct mproc *, struct imsg *);
64 static void usage(void);
65 static int smtpd(void);
66 static void parent_shutdown(void);
67 static void parent_send_config(int, short, void *);
68 static void parent_send_config_lka(void);
69 static void parent_send_config_pony(void);
70 static void parent_send_config_ca(void);
71 static void parent_sig_handler(int, short, void *);
72 static void forkmda(struct mproc *, uint64_t, struct deliver *);
73 static int parent_forward_open(char *, char *, uid_t, gid_t);
74 static struct child *child_add(pid_t, int, const char *);
75 static struct mproc *start_child(int, char **, char *);
76 static struct mproc *setup_peer(enum smtp_proc_type, pid_t, int);
77 static void setup_peers(struct mproc *, struct mproc *);
78 static void setup_done(struct mproc *);
79 static void setup_proc(void);
80 static struct mproc *setup_peer(enum smtp_proc_type, pid_t, int);
81 static int imsg_wait(struct imsgbuf *, struct imsg *, int);
82 
83 static void	offline_scan(int, short, void *);
84 static int	offline_add(char *, uid_t, gid_t);
85 static void	offline_done(void);
86 static int	offline_enqueue(char *, uid_t, gid_t);
87 
88 static void	purge_task(void);
89 static int	parent_auth_user(const char *, const char *);
90 static void	load_pki_tree(void);
91 static void	load_pki_keys(void);
92 
93 static void	fork_filter_processes(void);
94 static void	fork_filter_process(const char *, const char *, const char *, const char *, const char *, uint32_t);
95 
96 enum child_type {
97 	CHILD_DAEMON,
98 	CHILD_MDA,
99 	CHILD_PROCESSOR,
100 	CHILD_ENQUEUE_OFFLINE,
101 };
102 
103 struct child {
104 	pid_t			 pid;
105 	enum child_type		 type;
106 	const char		*title;
107 	int			 mda_out;
108 	uint64_t		 mda_id;
109 	char			*path;
110 	char			*cause;
111 };
112 
113 struct offline {
114 	TAILQ_ENTRY(offline)	 entry;
115 	uid_t			 uid;
116 	gid_t			 gid;
117 	char			*path;
118 };
119 
120 #define OFFLINE_READMAX		20
121 #define OFFLINE_QUEUEMAX	5
122 static size_t			offline_running = 0;
123 TAILQ_HEAD(, offline)		offline_q;
124 
125 static struct event		config_ev;
126 static struct event		offline_ev;
127 static struct timeval		offline_timeout;
128 
129 static pid_t			purge_pid = -1;
130 
131 extern char	**environ;
132 void		(*imsg_callback)(struct mproc *, struct imsg *);
133 
134 enum smtp_proc_type	smtpd_process;
135 
136 struct smtpd	*env = NULL;
137 
138 struct mproc	*p_control = NULL;
139 struct mproc	*p_lka = NULL;
140 struct mproc	*p_parent = NULL;
141 struct mproc	*p_queue = NULL;
142 struct mproc	*p_scheduler = NULL;
143 struct mproc	*p_pony = NULL;
144 struct mproc	*p_ca = NULL;
145 
146 const char	*backend_queue = "fs";
147 const char	*backend_scheduler = "ramqueue";
148 const char	*backend_stat = "ram";
149 
150 int	profiling = 0;
151 int	debug = 0;
152 int	foreground = 0;
153 int	control_socket = -1;
154 
155 struct tree	 children;
156 
157 static void
158 parent_imsg(struct mproc *p, struct imsg *imsg)
159 {
160 	struct forward_req	*fwreq;
161 	struct filter_proc	*processor;
162 	struct deliver		 deliver;
163 	struct child		*c;
164 	struct msg		 m;
165 	const void		*data;
166 	const char		*username, *password, *cause, *procname;
167 	uint64_t		 reqid;
168 	size_t			 sz;
169 	void			*i;
170 	int			 fd, n, v, ret;
171 
172 	if (imsg == NULL)
173 		fatalx("process %s socket closed", p->name);
174 
175 	switch (imsg->hdr.type) {
176 	case IMSG_LKA_OPEN_FORWARD:
177 		CHECK_IMSG_DATA_SIZE(imsg, sizeof *fwreq);
178 		fwreq = imsg->data;
179 		fd = parent_forward_open(fwreq->user, fwreq->directory,
180 		    fwreq->uid, fwreq->gid);
181 		fwreq->status = 0;
182 		if (fd == -1 && errno != ENOENT) {
183 			if (errno == EAGAIN)
184 				fwreq->status = -1;
185 		}
186 		else
187 			fwreq->status = 1;
188 		m_compose(p, IMSG_LKA_OPEN_FORWARD, 0, 0, fd,
189 		    fwreq, sizeof *fwreq);
190 		return;
191 
192 	case IMSG_LKA_AUTHENTICATE:
193 		/*
194 		 * If we reached here, it means we want root to lookup
195 		 * system user.
196 		 */
197 		m_msg(&m, imsg);
198 		m_get_id(&m, &reqid);
199 		m_get_string(&m, &username);
200 		m_get_string(&m, &password);
201 		m_end(&m);
202 
203 		ret = parent_auth_user(username, password);
204 
205 		m_create(p, IMSG_LKA_AUTHENTICATE, 0, 0, -1);
206 		m_add_id(p, reqid);
207 		m_add_int(p, ret);
208 		m_close(p);
209 		return;
210 
211 	case IMSG_MDA_FORK:
212 		m_msg(&m, imsg);
213 		m_get_id(&m, &reqid);
214 		m_get_data(&m, &data, &sz);
215 		m_end(&m);
216 		if (sz != sizeof(deliver))
217 			fatalx("expected deliver");
218 		memmove(&deliver, data, sz);
219 		forkmda(p, reqid, &deliver);
220 		return;
221 
222 	case IMSG_MDA_KILL:
223 		m_msg(&m, imsg);
224 		m_get_id(&m, &reqid);
225 		m_get_string(&m, &cause);
226 		m_end(&m);
227 
228 		i = NULL;
229 		while ((n = tree_iter(&children, &i, NULL, (void**)&c)))
230 			if (c->type == CHILD_MDA &&
231 			    c->mda_id == reqid &&
232 			    c->cause == NULL)
233 				break;
234 		if (!n) {
235 			log_debug("debug: smtpd: "
236 			    "kill request: proc not found");
237 			return;
238 		}
239 
240 		c->cause = xstrdup(cause);
241 		log_debug("debug: smtpd: kill requested for %u: %s",
242 		    c->pid, c->cause);
243 		kill(c->pid, SIGTERM);
244 		return;
245 
246 	case IMSG_CTL_VERBOSE:
247 		m_msg(&m, imsg);
248 		m_get_int(&m, &v);
249 		m_end(&m);
250 		log_trace_verbose(v);
251 		return;
252 
253 	case IMSG_CTL_PROFILE:
254 		m_msg(&m, imsg);
255 		m_get_int(&m, &v);
256 		m_end(&m);
257 		profiling = v;
258 		return;
259 
260 	case IMSG_LKA_PROCESSOR_ERRFD:
261 		m_msg(&m, imsg);
262 		m_get_string(&m, &procname);
263 		m_end(&m);
264 
265 		processor = dict_xget(env->sc_filter_processes_dict, procname);
266 		m_create(p_lka, IMSG_LKA_PROCESSOR_ERRFD, 0, 0, processor->errfd);
267 		m_add_string(p_lka, procname);
268 		m_close(p_lka);
269 		return;
270 	}
271 
272 	errx(1, "parent_imsg: unexpected %s imsg from %s",
273 	    imsg_to_str(imsg->hdr.type), proc_title(p->proc));
274 }
275 
276 static void
277 usage(void)
278 {
279 	extern char	*__progname;
280 
281 	fprintf(stderr, "usage: %s [-dFhnv] [-D macro=value] "
282 	    "[-f file] [-P system] [-T trace]\n", __progname);
283 	exit(1);
284 }
285 
286 static void
287 parent_shutdown(void)
288 {
289 	pid_t pid;
290 
291 	mproc_clear(p_ca);
292 	mproc_clear(p_pony);
293 	mproc_clear(p_control);
294 	mproc_clear(p_lka);
295 	mproc_clear(p_scheduler);
296 	mproc_clear(p_queue);
297 
298 	do {
299 		pid = waitpid(WAIT_MYPGRP, NULL, 0);
300 	} while (pid != -1 || (pid == -1 && errno == EINTR));
301 
302 	unlink(SMTPD_SOCKET);
303 
304 	log_info("Exiting");
305 	exit(0);
306 }
307 
308 static void
309 parent_send_config(int fd, short event, void *p)
310 {
311 	parent_send_config_lka();
312 	parent_send_config_pony();
313 	parent_send_config_ca();
314 	purge_config(PURGE_PKI);
315 }
316 
317 static void
318 parent_send_config_pony(void)
319 {
320 	log_debug("debug: parent_send_config: configuring pony process");
321 	m_compose(p_pony, IMSG_CONF_START, 0, 0, -1, NULL, 0);
322 	m_compose(p_pony, IMSG_CONF_END, 0, 0, -1, NULL, 0);
323 }
324 
325 void
326 parent_send_config_lka()
327 {
328 	log_debug("debug: parent_send_config_ruleset: reloading");
329 	m_compose(p_lka, IMSG_CONF_START, 0, 0, -1, NULL, 0);
330 	m_compose(p_lka, IMSG_CONF_END, 0, 0, -1, NULL, 0);
331 }
332 
333 static void
334 parent_send_config_ca(void)
335 {
336 	log_debug("debug: parent_send_config: configuring ca process");
337 	m_compose(p_ca, IMSG_CONF_START, 0, 0, -1, NULL, 0);
338 	m_compose(p_ca, IMSG_CONF_END, 0, 0, -1, NULL, 0);
339 }
340 
341 static void
342 parent_sig_handler(int sig, short event, void *p)
343 {
344 	struct child	*child;
345 	int		 status, fail;
346 	pid_t		 pid;
347 	char		*cause;
348 
349 	switch (sig) {
350 	case SIGTERM:
351 	case SIGINT:
352 		log_debug("debug: got signal %d", sig);
353 		parent_shutdown();
354 		/* NOT REACHED */
355 
356 	case SIGCHLD:
357 		do {
358 			int len;
359 			enum mda_resp_status mda_status;
360 			int mda_sysexit;
361 
362 			pid = waitpid(-1, &status, WNOHANG);
363 			if (pid <= 0)
364 				continue;
365 
366 			fail = 0;
367 			if (WIFSIGNALED(status)) {
368 				fail = 1;
369 				len = asprintf(&cause, "terminated; signal %d",
370 				    WTERMSIG(status));
371 				mda_status = MDA_TEMPFAIL;
372 				mda_sysexit = 0;
373 			} else if (WIFEXITED(status)) {
374 				if (WEXITSTATUS(status) != 0) {
375 					fail = 1;
376 					len = asprintf(&cause,
377 					    "exited abnormally");
378 					mda_sysexit = WEXITSTATUS(status);
379 					if (mda_sysexit == EX_OSERR ||
380 					    mda_sysexit == EX_TEMPFAIL)
381 						mda_status = MDA_TEMPFAIL;
382 					else
383 						mda_status = MDA_PERMFAIL;
384 				} else {
385 					len = asprintf(&cause, "exited okay");
386 					mda_status = MDA_OK;
387 					mda_sysexit = 0;
388 				}
389 			} else
390 				/* WIFSTOPPED or WIFCONTINUED */
391 				continue;
392 
393 			if (len == -1)
394 				fatal("asprintf");
395 
396 			if (pid == purge_pid)
397 				purge_pid = -1;
398 
399 			child = tree_pop(&children, pid);
400 			if (child == NULL)
401 				goto skip;
402 
403 			switch (child->type) {
404 			case CHILD_PROCESSOR:
405 				if (fail) {
406 					log_warnx("warn: lost processor: %s %s",
407 					    child->title, cause);
408 					parent_shutdown();
409 				}
410 				break;
411 
412 			case CHILD_DAEMON:
413 				if (fail)
414 					log_warnx("warn: lost child: %s %s",
415 					    child->title, cause);
416 				break;
417 
418 			case CHILD_MDA:
419 				if (WIFSIGNALED(status) &&
420 				    WTERMSIG(status) == SIGALRM) {
421 					char *tmp;
422 					if (asprintf(&tmp,
423 					    "terminated; timeout") != -1) {
424 						free(cause);
425 						cause = tmp;
426 					}
427 				}
428 				else if (child->cause &&
429 				    WIFSIGNALED(status) &&
430 				    WTERMSIG(status) == SIGTERM) {
431 					free(cause);
432 					cause = child->cause;
433 					child->cause = NULL;
434 				}
435 				free(child->cause);
436 				log_debug("debug: smtpd: mda process done "
437 				    "for session %016"PRIx64 ": %s",
438 				    child->mda_id, cause);
439 
440 				m_create(p_pony, IMSG_MDA_DONE, 0, 0,
441 				    child->mda_out);
442 				m_add_id(p_pony, child->mda_id);
443 				m_add_int(p_pony, mda_status);
444 				m_add_int(p_pony, mda_sysexit);
445 				m_add_string(p_pony, cause);
446 				m_close(p_pony);
447 
448 				break;
449 
450 			case CHILD_ENQUEUE_OFFLINE:
451 				if (fail)
452 					log_warnx("warn: smtpd: "
453 					    "couldn't enqueue offline "
454 					    "message %s; smtpctl %s",
455 					    child->path, cause);
456 				else
457 					unlink(child->path);
458 				free(child->path);
459 				offline_done();
460 				break;
461 
462 			default:
463 				fatalx("smtpd: unexpected child type");
464 			}
465 			free(child);
466     skip:
467 			free(cause);
468 		} while (pid > 0 || (pid == -1 && errno == EINTR));
469 
470 		break;
471 	default:
472 		fatalx("smtpd: unexpected signal");
473 	}
474 }
475 
476 int
477 main(int argc, char *argv[])
478 {
479 	int		 c, i;
480 	int		 opts, flags;
481 	const char	*conffile = CONF_FILE;
482 	int		 save_argc = argc;
483 	char		**save_argv = argv;
484 	char		*rexec = NULL;
485 	struct smtpd	*conf;
486 
487 	if ((conf = config_default()) == NULL)
488 		err(1, NULL);
489 
490 	env = conf;
491 
492 	flags = 0;
493 	opts = 0;
494 	debug = 0;
495 	tracing = 0;
496 
497 	log_init(1, LOG_MAIL);
498 
499 	TAILQ_INIT(&offline_q);
500 
501 	while ((c = getopt(argc, argv, "B:dD:hnP:f:FT:vx:")) != -1) {
502 		switch (c) {
503 		case 'B':
504 			if (strstr(optarg, "queue=") == optarg)
505 				backend_queue = strchr(optarg, '=') + 1;
506 			else if (strstr(optarg, "scheduler=") == optarg)
507 				backend_scheduler = strchr(optarg, '=') + 1;
508 			else if (strstr(optarg, "stat=") == optarg)
509 				backend_stat = strchr(optarg, '=') + 1;
510 			else
511 				log_warnx("warn: "
512 				    "invalid backend specifier %s",
513 				    optarg);
514 			break;
515 		case 'd':
516 			foreground = 1;
517 			foreground_log = 1;
518 			break;
519 		case 'D':
520 			if (cmdline_symset(optarg) < 0)
521 				log_warnx("warn: "
522 				    "could not parse macro definition %s",
523 				    optarg);
524 			break;
525 		case 'h':
526 			log_info("version: " SMTPD_NAME " " SMTPD_VERSION);
527 			usage();
528 			break;
529 		case 'n':
530 			debug = 2;
531 			opts |= SMTPD_OPT_NOACTION;
532 			break;
533 		case 'f':
534 			conffile = optarg;
535 			break;
536 		case 'F':
537 			foreground = 1;
538 			break;
539 
540 		case 'T':
541 			if (!strcmp(optarg, "imsg"))
542 				tracing |= TRACE_IMSG;
543 			else if (!strcmp(optarg, "io"))
544 				tracing |= TRACE_IO;
545 			else if (!strcmp(optarg, "smtp"))
546 				tracing |= TRACE_SMTP;
547 			else if (!strcmp(optarg, "filters"))
548 				tracing |= TRACE_FILTERS;
549 			else if (!strcmp(optarg, "mta") ||
550 			    !strcmp(optarg, "transfer"))
551 				tracing |= TRACE_MTA;
552 			else if (!strcmp(optarg, "bounce") ||
553 			    !strcmp(optarg, "bounces"))
554 				tracing |= TRACE_BOUNCE;
555 			else if (!strcmp(optarg, "scheduler"))
556 				tracing |= TRACE_SCHEDULER;
557 			else if (!strcmp(optarg, "lookup"))
558 				tracing |= TRACE_LOOKUP;
559 			else if (!strcmp(optarg, "stat") ||
560 			    !strcmp(optarg, "stats"))
561 				tracing |= TRACE_STAT;
562 			else if (!strcmp(optarg, "rules"))
563 				tracing |= TRACE_RULES;
564 			else if (!strcmp(optarg, "mproc"))
565 				tracing |= TRACE_MPROC;
566 			else if (!strcmp(optarg, "expand"))
567 				tracing |= TRACE_EXPAND;
568 			else if (!strcmp(optarg, "table") ||
569 			    !strcmp(optarg, "tables"))
570 				tracing |= TRACE_TABLES;
571 			else if (!strcmp(optarg, "queue"))
572 				tracing |= TRACE_QUEUE;
573 			else if (!strcmp(optarg, "all"))
574 				tracing |= ~TRACE_DEBUG;
575 			else if (!strcmp(optarg, "profstat"))
576 				profiling |= PROFILE_TOSTAT;
577 			else if (!strcmp(optarg, "profile-imsg"))
578 				profiling |= PROFILE_IMSG;
579 			else if (!strcmp(optarg, "profile-queue"))
580 				profiling |= PROFILE_QUEUE;
581 			else
582 				log_warnx("warn: unknown trace flag \"%s\"",
583 				    optarg);
584 			break;
585 		case 'P':
586 			if (!strcmp(optarg, "smtp"))
587 				flags |= SMTPD_SMTP_PAUSED;
588 			else if (!strcmp(optarg, "mta"))
589 				flags |= SMTPD_MTA_PAUSED;
590 			else if (!strcmp(optarg, "mda"))
591 				flags |= SMTPD_MDA_PAUSED;
592 			break;
593 		case 'v':
594 			tracing |=  TRACE_DEBUG;
595 			break;
596 		case 'x':
597 			rexec = optarg;
598 			break;
599 		default:
600 			usage();
601 		}
602 	}
603 
604 	argv += optind;
605 	argc -= optind;
606 
607 	if (argc || *argv)
608 		usage();
609 
610 	env->sc_opts |= opts;
611 
612 	ssl_init();
613 
614 	if (parse_config(conf, conffile, opts))
615 		exit(1);
616 
617 	if (strlcpy(env->sc_conffile, conffile, PATH_MAX)
618 	    >= PATH_MAX)
619 		errx(1, "config file exceeds PATH_MAX");
620 
621 	if (env->sc_opts & SMTPD_OPT_NOACTION) {
622 		if (env->sc_queue_key &&
623 		    crypto_setup(env->sc_queue_key,
624 		    strlen(env->sc_queue_key)) == 0) {
625 			fatalx("crypto_setup:"
626 			    "invalid key for queue encryption");
627 		}
628 		load_pki_tree();
629 		load_pki_keys();
630 		fprintf(stderr, "configuration OK\n");
631 		exit(0);
632 	}
633 
634 	env->sc_flags |= flags;
635 
636 	/* check for root privileges */
637 	if (geteuid())
638 		errx(1, "need root privileges");
639 
640 	log_init(foreground_log, LOG_MAIL);
641 	log_trace_verbose(tracing);
642 	load_pki_tree();
643 	load_pki_keys();
644 
645 	log_debug("debug: using \"%s\" queue backend", backend_queue);
646 	log_debug("debug: using \"%s\" scheduler backend", backend_scheduler);
647 	log_debug("debug: using \"%s\" stat backend", backend_stat);
648 
649 	if (env->sc_hostname[0] == '\0')
650 		errx(1, "machine does not have a hostname set");
651 	env->sc_uptime = time(NULL);
652 
653 	if (rexec == NULL) {
654 		smtpd_process = PROC_PARENT;
655 
656 		if (env->sc_queue_flags & QUEUE_ENCRYPTION) {
657 			if (env->sc_queue_key == NULL) {
658 				char	*password;
659 
660 				password = getpass("queue key: ");
661 				if (password == NULL)
662 					err(1, "getpass");
663 
664 				env->sc_queue_key = strdup(password);
665 				explicit_bzero(password, strlen(password));
666 				if (env->sc_queue_key == NULL)
667 					err(1, "strdup");
668 			}
669 			else {
670 				char   *buf = NULL;
671 				size_t	sz = 0;
672 				ssize_t	len;
673 
674 				if (strcasecmp(env->sc_queue_key, "stdin") == 0) {
675 					if ((len = getline(&buf, &sz, stdin)) == -1)
676 						err(1, "getline");
677 					if (buf[len - 1] == '\n')
678 						buf[len - 1] = '\0';
679 					env->sc_queue_key = buf;
680 				}
681 			}
682 		}
683 
684 		log_info("info: %s %s starting", SMTPD_NAME, SMTPD_VERSION);
685 
686 		if (!foreground)
687 			if (daemon(0, 0) == -1)
688 				err(1, "failed to daemonize");
689 
690 		/* setup all processes */
691 
692 		p_ca = start_child(save_argc, save_argv, "ca");
693 		p_ca->proc = PROC_CA;
694 
695 		p_control = start_child(save_argc, save_argv, "control");
696 		p_control->proc = PROC_CONTROL;
697 
698 		p_lka = start_child(save_argc, save_argv, "lka");
699 		p_lka->proc = PROC_LKA;
700 
701 		p_pony = start_child(save_argc, save_argv, "pony");
702 		p_pony->proc = PROC_PONY;
703 
704 		p_queue = start_child(save_argc, save_argv, "queue");
705 		p_queue->proc = PROC_QUEUE;
706 
707 		p_scheduler = start_child(save_argc, save_argv, "scheduler");
708 		p_scheduler->proc = PROC_SCHEDULER;
709 
710 		setup_peers(p_control, p_ca);
711 		setup_peers(p_control, p_lka);
712 		setup_peers(p_control, p_pony);
713 		setup_peers(p_control, p_queue);
714 		setup_peers(p_control, p_scheduler);
715 		setup_peers(p_pony, p_ca);
716 		setup_peers(p_pony, p_lka);
717 		setup_peers(p_pony, p_queue);
718 		setup_peers(p_queue, p_lka);
719 		setup_peers(p_queue, p_scheduler);
720 
721 		if (env->sc_queue_key) {
722 			if (imsg_compose(&p_queue->imsgbuf, IMSG_SETUP_KEY, 0,
723 			    0, -1, env->sc_queue_key, strlen(env->sc_queue_key)
724 			    + 1) == -1)
725 				fatal("imsg_compose");
726 			if (imsg_flush(&p_queue->imsgbuf) == -1)
727 				fatal("imsg_flush");
728 		}
729 
730 		setup_done(p_ca);
731 		setup_done(p_control);
732 		setup_done(p_lka);
733 		setup_done(p_pony);
734 		setup_done(p_queue);
735 		setup_done(p_scheduler);
736 
737 		log_debug("smtpd: setup done");
738 
739 		return smtpd();
740 	}
741 
742 	if (!strcmp(rexec, "ca")) {
743 		smtpd_process = PROC_CA;
744 		setup_proc();
745 
746 		return ca();
747 	}
748 
749 	else if (!strcmp(rexec, "control")) {
750 		smtpd_process = PROC_CONTROL;
751 		setup_proc();
752 
753 		/* the control socket ensures that only one smtpd instance is running */
754 		control_socket = control_create_socket();
755 
756 		env->sc_stat = stat_backend_lookup(backend_stat);
757 		if (env->sc_stat == NULL)
758 			errx(1, "could not find stat backend \"%s\"", backend_stat);
759 
760 		return control();
761 	}
762 
763 	else if (!strcmp(rexec, "lka")) {
764 		smtpd_process = PROC_LKA;
765 		setup_proc();
766 
767 		return lka();
768 	}
769 
770 	else if (!strcmp(rexec, "pony")) {
771 		smtpd_process = PROC_PONY;
772 		setup_proc();
773 
774 		return pony();
775 	}
776 
777 	else if (!strcmp(rexec, "queue")) {
778 		smtpd_process = PROC_QUEUE;
779 		setup_proc();
780 
781 		if (env->sc_queue_flags & QUEUE_COMPRESSION)
782 			env->sc_comp = compress_backend_lookup("gzip");
783 
784 		if (!queue_init(backend_queue, 1))
785 			errx(1, "could not initialize queue backend");
786 
787 		return queue();
788 	}
789 
790 	else if (!strcmp(rexec, "scheduler")) {
791 		smtpd_process = PROC_SCHEDULER;
792 		setup_proc();
793 
794 		for (i = 0; i < MAX_BOUNCE_WARN; i++) {
795 			if (env->sc_bounce_warn[i] == 0)
796 				break;
797 			log_debug("debug: bounce warning after %s",
798 			    duration_to_text(env->sc_bounce_warn[i]));
799 		}
800 
801 		return scheduler();
802 	}
803 
804 	fatalx("bad rexec: %s", rexec);
805 
806 	return (1);
807 }
808 
809 static struct mproc *
810 start_child(int save_argc, char **save_argv, char *rexec)
811 {
812 	struct mproc *p;
813 	char *argv[SMTPD_MAXARG];
814 	int sp[2], argc = 0;
815 	pid_t pid;
816 
817 	if (save_argc >= SMTPD_MAXARG - 2)
818 		fatalx("too many arguments");
819 
820 	if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, sp) == -1)
821 		fatal("socketpair");
822 
823 	io_set_nonblocking(sp[0]);
824 	io_set_nonblocking(sp[1]);
825 
826 	switch (pid = fork()) {
827 	case -1:
828 		fatal("%s: fork", save_argv[0]);
829 	case 0:
830 		break;
831 	default:
832 		close(sp[0]);
833 		p = calloc(1, sizeof(*p));
834 		if (p == NULL)
835 			fatal("calloc");
836 		if((p->name = strdup(rexec)) == NULL)
837 			fatal("strdup");
838 		mproc_init(p, sp[1]);
839 		p->pid = pid;
840 		p->handler = parent_imsg;
841 		return p;
842 	}
843 
844 	if (sp[0] != 3) {
845 		if (dup2(sp[0], 3) == -1)
846 			fatal("%s: dup2", rexec);
847 	} else if (fcntl(sp[0], F_SETFD, 0) == -1)
848 		fatal("%s: fcntl", rexec);
849 
850 	if (closefrom(4) == -1)
851 		fatal("%s: closefrom", rexec);
852 
853 	for (argc = 0; argc < save_argc; argc++)
854 		argv[argc] = save_argv[argc];
855 	argv[argc++] = "-x";
856 	argv[argc++] = rexec;
857 	argv[argc++] = NULL;
858 
859 	execvp(argv[0], argv);
860 	fatal("%s: execvp", rexec);
861 }
862 
863 static void
864 setup_peers(struct mproc *a, struct mproc *b)
865 {
866 	int sp[2];
867 
868 	if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, sp) == -1)
869 		fatal("socketpair");
870 
871 	io_set_nonblocking(sp[0]);
872 	io_set_nonblocking(sp[1]);
873 
874 	if (imsg_compose(&a->imsgbuf, IMSG_SETUP_PEER, b->proc, b->pid, sp[0],
875 	    NULL, 0) == -1)
876 		fatal("imsg_compose");
877 	if (imsg_flush(&a->imsgbuf) == -1)
878 		fatal("imsg_flush");
879 
880 	if (imsg_compose(&b->imsgbuf, IMSG_SETUP_PEER, a->proc, a->pid, sp[1],
881 	    NULL, 0) == -1)
882 		fatal("imsg_compose");
883 	if (imsg_flush(&b->imsgbuf) == -1)
884 		fatal("imsg_flush");
885 }
886 
887 static void
888 setup_done(struct mproc *p)
889 {
890 	struct imsg imsg;
891 
892 	if (imsg_compose(&p->imsgbuf, IMSG_SETUP_DONE, 0, 0, -1, NULL, 0) == -1)
893 		fatal("imsg_compose");
894 	if (imsg_flush(&p->imsgbuf) == -1)
895 		fatal("imsg_flush");
896 
897 	if (imsg_wait(&p->imsgbuf, &imsg, 10000) == -1)
898 		fatal("imsg_wait");
899 
900 	if (imsg.hdr.type != IMSG_SETUP_DONE)
901 		fatalx("expect IMSG_SETUP_DONE");
902 
903 	log_debug("setup_done: %s[%d] done", p->name, p->pid);
904 
905 	imsg_free(&imsg);
906 }
907 
908 static void
909 setup_proc(void)
910 {
911 	struct imsgbuf *ibuf;
912 	struct imsg imsg;
913         int setup = 1;
914 
915 	log_procinit(proc_title(smtpd_process));
916 
917 	p_parent = calloc(1, sizeof(*p_parent));
918 	if (p_parent == NULL)
919 		fatal("calloc");
920 	if((p_parent->name = strdup("parent")) == NULL)
921 		fatal("strdup");
922 	p_parent->proc = PROC_PARENT;
923 	p_parent->handler = imsg_dispatch;
924 	mproc_init(p_parent, 3);
925 
926 	ibuf = &p_parent->imsgbuf;
927 
928 	while (setup) {
929 		if (imsg_wait(ibuf, &imsg, 10000) == -1)
930 			fatal("imsg_wait");
931 
932 		switch (imsg.hdr.type) {
933 		case IMSG_SETUP_KEY:
934 			env->sc_queue_key = strdup(imsg.data);
935 			break;
936 		case IMSG_SETUP_PEER:
937 			setup_peer(imsg.hdr.peerid, imsg.hdr.pid, imsg.fd);
938 			break;
939 		case IMSG_SETUP_DONE:
940 			setup = 0;
941 			break;
942 		default:
943 			fatal("bad imsg %d", imsg.hdr.type);
944 		}
945 		imsg_free(&imsg);
946 	}
947 
948 	if (imsg_compose(ibuf, IMSG_SETUP_DONE, 0, 0, -1, NULL, 0) == -1)
949 		fatal("imsg_compose");
950 
951 	if (imsg_flush(ibuf) == -1)
952 		fatal("imsg_flush");
953 
954 	log_debug("setup_proc: %s done", proc_title(smtpd_process));
955 }
956 
957 static struct mproc *
958 setup_peer(enum smtp_proc_type proc, pid_t pid, int sock)
959 {
960 	struct mproc *p, **pp;
961 
962 	log_debug("setup_peer: %s -> %s[%u] fd=%d", proc_title(smtpd_process),
963 	    proc_title(proc), pid, sock);
964 
965 	if (sock == -1)
966 		fatalx("peer socket not received");
967 
968 	switch (proc) {
969 	case PROC_LKA:
970 		pp = &p_lka;
971 		break;
972 	case PROC_QUEUE:
973 		pp = &p_queue;
974 		break;
975 	case PROC_CONTROL:
976 		pp = &p_control;
977 		break;
978 	case PROC_SCHEDULER:
979 		pp = &p_scheduler;
980 		break;
981 	case PROC_PONY:
982 		pp = &p_pony;
983 		break;
984 	case PROC_CA:
985 		pp = &p_ca;
986 		break;
987 	default:
988 		fatalx("unknown peer");
989 	}
990 
991 	if (*pp)
992 		fatalx("peer already set");
993 
994 	p = calloc(1, sizeof(*p));
995 	if (p == NULL)
996 		fatal("calloc");
997 	if((p->name = strdup(proc_title(proc))) == NULL)
998 		fatal("strdup");
999 	mproc_init(p, sock);
1000 	p->pid = pid;
1001 	p->proc = proc;
1002 	p->handler = imsg_dispatch;
1003 
1004 	*pp = p;
1005 
1006 	return p;
1007 }
1008 
1009 static int
1010 imsg_wait(struct imsgbuf *ibuf, struct imsg *imsg, int timeout)
1011 {
1012 	struct pollfd pfd[1];
1013 	ssize_t n;
1014 
1015 	pfd[0].fd = ibuf->fd;
1016 	pfd[0].events = POLLIN;
1017 
1018 	while (1) {
1019 		if ((n = imsg_get(ibuf, imsg)) == -1)
1020 			return -1;
1021 		if (n)
1022 			return 1;
1023 
1024 		n = poll(pfd, 1, timeout);
1025 		if (n == -1)
1026 			return -1;
1027 		if (n == 0) {
1028 			errno = ETIMEDOUT;
1029 			return -1;
1030 		}
1031 
1032 		if (((n = imsg_read(ibuf)) == -1 && errno != EAGAIN) || n == 0)
1033 			return -1;
1034 	}
1035 }
1036 
1037 int
1038 smtpd(void) {
1039 	struct event	 ev_sigint;
1040 	struct event	 ev_sigterm;
1041 	struct event	 ev_sigchld;
1042 	struct event	 ev_sighup;
1043 	struct timeval	 tv;
1044 
1045 	imsg_callback = parent_imsg;
1046 
1047 	tree_init(&children);
1048 
1049 	child_add(p_queue->pid, CHILD_DAEMON, proc_title(PROC_QUEUE));
1050 	child_add(p_control->pid, CHILD_DAEMON, proc_title(PROC_CONTROL));
1051 	child_add(p_lka->pid, CHILD_DAEMON, proc_title(PROC_LKA));
1052 	child_add(p_scheduler->pid, CHILD_DAEMON, proc_title(PROC_SCHEDULER));
1053 	child_add(p_pony->pid, CHILD_DAEMON, proc_title(PROC_PONY));
1054 	child_add(p_ca->pid, CHILD_DAEMON, proc_title(PROC_CA));
1055 
1056 	event_init();
1057 
1058 	signal_set(&ev_sigint, SIGINT, parent_sig_handler, NULL);
1059 	signal_set(&ev_sigterm, SIGTERM, parent_sig_handler, NULL);
1060 	signal_set(&ev_sigchld, SIGCHLD, parent_sig_handler, NULL);
1061 	signal_set(&ev_sighup, SIGHUP, parent_sig_handler, NULL);
1062 	signal_add(&ev_sigint, NULL);
1063 	signal_add(&ev_sigterm, NULL);
1064 	signal_add(&ev_sigchld, NULL);
1065 	signal_add(&ev_sighup, NULL);
1066 	signal(SIGPIPE, SIG_IGN);
1067 
1068 	config_peer(PROC_CONTROL);
1069 	config_peer(PROC_LKA);
1070 	config_peer(PROC_QUEUE);
1071 	config_peer(PROC_CA);
1072 	config_peer(PROC_PONY);
1073 
1074 	evtimer_set(&config_ev, parent_send_config, NULL);
1075 	memset(&tv, 0, sizeof(tv));
1076 	evtimer_add(&config_ev, &tv);
1077 
1078 	/* defer offline scanning for a second */
1079 	evtimer_set(&offline_ev, offline_scan, NULL);
1080 	offline_timeout.tv_sec = 1;
1081 	offline_timeout.tv_usec = 0;
1082 	evtimer_add(&offline_ev, &offline_timeout);
1083 
1084 	fork_filter_processes();
1085 
1086 	purge_task();
1087 
1088 	if (pledge("stdio rpath wpath cpath fattr tmppath "
1089 	    "getpw sendfd proc exec id inet chown unix", NULL) == -1)
1090 		err(1, "pledge");
1091 
1092 	event_dispatch();
1093 	fatalx("exited event loop");
1094 
1095 	return (0);
1096 }
1097 
1098 static void
1099 load_pki_tree(void)
1100 {
1101 	struct pki	*pki;
1102 	struct ca	*sca;
1103 	const char	*k;
1104 	void		*iter_dict;
1105 
1106 	log_debug("debug: init ssl-tree");
1107 	iter_dict = NULL;
1108 	while (dict_iter(env->sc_pki_dict, &iter_dict, &k, (void **)&pki)) {
1109 		log_debug("info: loading pki information for %s", k);
1110 		if (pki->pki_cert_file == NULL)
1111 			fatalx("load_pki_tree: missing certificate file");
1112 		if (pki->pki_key_file == NULL)
1113 			fatalx("load_pki_tree: missing key file");
1114 
1115 		if (!ssl_load_certificate(pki, pki->pki_cert_file))
1116 			fatalx("load_pki_tree: failed to load certificate file");
1117 	}
1118 
1119 	log_debug("debug: init ca-tree");
1120 	iter_dict = NULL;
1121 	while (dict_iter(env->sc_ca_dict, &iter_dict, &k, (void **)&sca)) {
1122 		log_debug("info: loading CA information for %s", k);
1123 		if (!ssl_load_cafile(sca, sca->ca_cert_file))
1124 			fatalx("load_pki_tree: failed to load CA file");
1125 	}
1126 }
1127 
1128 void
1129 load_pki_keys(void)
1130 {
1131 	struct pki	*pki;
1132 	const char	*k;
1133 	void		*iter_dict;
1134 
1135 	log_debug("debug: init ssl-tree");
1136 	iter_dict = NULL;
1137 	while (dict_iter(env->sc_pki_dict, &iter_dict, &k, (void **)&pki)) {
1138 		log_debug("info: loading pki keys for %s", k);
1139 
1140 		if (!ssl_load_keyfile(pki, pki->pki_key_file, k))
1141 			fatalx("load_pki_keys: failed to load key file");
1142 	}
1143 }
1144 
1145 int
1146 fork_proc_backend(const char *key, const char *conf, const char *procname)
1147 {
1148 	pid_t		pid;
1149 	int		sp[2];
1150 	char		path[PATH_MAX];
1151 	char		name[PATH_MAX];
1152 	char		*arg;
1153 
1154 	if (strlcpy(name, conf, sizeof(name)) >= sizeof(name)) {
1155 		log_warnx("warn: %s-proc: conf too long", key);
1156 		return (0);
1157 	}
1158 
1159 	arg = strchr(name, ':');
1160 	if (arg)
1161 		*arg++ = '\0';
1162 
1163 	if (snprintf(path, sizeof(path), PATH_LIBEXEC "/%s-%s", key, name) >=
1164 	    (ssize_t)sizeof(path)) {
1165 		log_warn("warn: %s-proc: exec path too long", key);
1166 		return (-1);
1167 	}
1168 
1169 	if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, sp) == -1) {
1170 		log_warn("warn: %s-proc: socketpair", key);
1171 		return (-1);
1172 	}
1173 
1174 	if ((pid = fork()) == -1) {
1175 		log_warn("warn: %s-proc: fork", key);
1176 		close(sp[0]);
1177 		close(sp[1]);
1178 		return (-1);
1179 	}
1180 
1181 	if (pid == 0) {
1182 		/* child process */
1183 		dup2(sp[0], STDIN_FILENO);
1184 		if (closefrom(STDERR_FILENO + 1) == -1)
1185 			exit(1);
1186 
1187 		if (procname == NULL)
1188 			procname = name;
1189 
1190 		execl(path, procname, arg, (char *)NULL);
1191 		err(1, "execl: %s", path);
1192 	}
1193 
1194 	/* parent process */
1195 	close(sp[0]);
1196 
1197 	return (sp[1]);
1198 }
1199 
1200 struct child *
1201 child_add(pid_t pid, int type, const char *title)
1202 {
1203 	struct child	*child;
1204 
1205 	if ((child = calloc(1, sizeof(*child))) == NULL)
1206 		fatal("smtpd: child_add: calloc");
1207 
1208 	child->pid = pid;
1209 	child->type = type;
1210 	child->title = title;
1211 
1212 	tree_xset(&children, pid, child);
1213 
1214 	return (child);
1215 }
1216 
1217 static void
1218 purge_task(void)
1219 {
1220 	struct passwd	*pw;
1221 	DIR		*d;
1222 	int		 n;
1223 	uid_t		 uid;
1224 	gid_t		 gid;
1225 
1226 	n = 0;
1227 	if ((d = opendir(PATH_SPOOL PATH_PURGE))) {
1228 		while (readdir(d) != NULL)
1229 			n++;
1230 		closedir(d);
1231 	} else
1232 		log_warn("warn: purge_task: opendir");
1233 
1234 	if (n > 2) {
1235 		switch (purge_pid = fork()) {
1236 		case -1:
1237 			log_warn("warn: purge_task: fork");
1238 			break;
1239 		case 0:
1240 			if ((pw = getpwnam(SMTPD_QUEUE_USER)) == NULL)
1241 				fatalx("unknown user " SMTPD_QUEUE_USER);
1242 			if (chroot(PATH_SPOOL PATH_PURGE) == -1)
1243 				fatal("smtpd: chroot");
1244 			if (chdir("/") == -1)
1245 				fatal("smtpd: chdir");
1246 			uid = pw->pw_uid;
1247 			gid = pw->pw_gid;
1248 			if (setgroups(1, &gid) ||
1249 			    setresgid(gid, gid, gid) ||
1250 			    setresuid(uid, uid, uid))
1251 				fatal("smtpd: cannot drop privileges");
1252 			rmtree("/", 1);
1253 			_exit(0);
1254 			break;
1255 		default:
1256 			break;
1257 		}
1258 	}
1259 }
1260 
1261 static void
1262 fork_filter_processes(void)
1263 {
1264 	const char	*name;
1265 	void		*iter;
1266 	const char	*fn;
1267 	struct filter_config *fc;
1268 	struct filter_config *fcs;
1269 	struct filter_proc *fp;
1270 	size_t		 i;
1271 
1272 	/* For each filter chain, assign the registered subsystem to subfilters */
1273 	iter = NULL;
1274 	while (dict_iter(env->sc_filters_dict, &iter, (const char **)&fn, (void **)&fc)) {
1275 		if (fc->chain) {
1276 			for (i = 0; i < fc->chain_size; ++i) {
1277 				fcs = dict_xget(env->sc_filters_dict, fc->chain[i]);
1278 				fcs->filter_subsystem |= fc->filter_subsystem;
1279 			}
1280 		}
1281 	}
1282 
1283 	/* For each filter, assign the registered subsystem to underlying proc */
1284 	iter = NULL;
1285 	while (dict_iter(env->sc_filters_dict, &iter, (const char **)&fn, (void **)&fc)) {
1286 		if (fc->proc) {
1287 			fp = dict_xget(env->sc_filter_processes_dict, fc->proc);
1288 			fp->filter_subsystem |= fc->filter_subsystem;
1289 		}
1290 	}
1291 
1292 	iter = NULL;
1293 	while (dict_iter(env->sc_filter_processes_dict, &iter, &name, (void **)&fp))
1294 		fork_filter_process(name, fp->command, fp->user, fp->group, fp->chroot, fp->filter_subsystem);
1295 }
1296 
1297 static void
1298 fork_filter_process(const char *name, const char *command, const char *user, const char *group, const char *chroot_path, uint32_t subsystems)
1299 {
1300 	pid_t		 pid;
1301 	struct filter_proc	*processor;
1302 	char		 buf;
1303 	int		 sp[2], errfd[2];
1304 	struct passwd	*pw;
1305 	struct group	*gr;
1306 	char		 exec[_POSIX_ARG_MAX];
1307 	int		 execr;
1308 
1309 	if (user == NULL)
1310 		user = SMTPD_USER;
1311 	if ((pw = getpwnam(user)) == NULL)
1312 		err(1, "getpwnam");
1313 
1314 	if (group) {
1315 		if ((gr = getgrnam(group)) == NULL)
1316 			err(1, "getgrnam");
1317 	}
1318 	else {
1319 		if ((gr = getgrgid(pw->pw_gid)) == NULL)
1320 			err(1, "getgrgid");
1321 	}
1322 
1323 	if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, sp) == -1)
1324 		err(1, "socketpair");
1325 	if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, errfd) == -1)
1326 		err(1, "socketpair");
1327 
1328 	if ((pid = fork()) == -1)
1329 		err(1, "fork");
1330 
1331 	/* parent passes the child fd over to lka */
1332 	if (pid > 0) {
1333 		processor = dict_xget(env->sc_filter_processes_dict, name);
1334 		processor->errfd = errfd[1];
1335 		child_add(pid, CHILD_PROCESSOR, name);
1336 		close(sp[0]);
1337 		close(errfd[0]);
1338 		m_create(p_lka, IMSG_LKA_PROCESSOR_FORK, 0, 0, sp[1]);
1339 		m_add_string(p_lka, name);
1340 		m_add_u32(p_lka, (uint32_t)subsystems);
1341 		m_close(p_lka);
1342 		return;
1343 	}
1344 
1345 	close(sp[1]);
1346 	close(errfd[1]);
1347 	dup2(sp[0], STDIN_FILENO);
1348 	dup2(sp[0], STDOUT_FILENO);
1349 	dup2(errfd[0], STDERR_FILENO);
1350 
1351 	if (chroot_path) {
1352 		if (chroot(chroot_path) != 0 || chdir("/") != 0)
1353 			err(1, "chroot: %s", chroot_path);
1354 	}
1355 
1356 	if (setgroups(1, &gr->gr_gid) ||
1357 	    setresgid(gr->gr_gid, gr->gr_gid, gr->gr_gid) ||
1358 	    setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))
1359 		err(1, "fork_filter_process: cannot drop privileges");
1360 
1361 	if (closefrom(STDERR_FILENO + 1) == -1)
1362 		err(1, "closefrom");
1363 	if (setsid() == -1)
1364 		err(1, "setsid");
1365 	if (signal(SIGPIPE, SIG_DFL) == SIG_ERR ||
1366 	    signal(SIGINT, SIG_DFL) == SIG_ERR ||
1367 	    signal(SIGTERM, SIG_DFL) == SIG_ERR ||
1368 	    signal(SIGCHLD, SIG_DFL) == SIG_ERR ||
1369 	    signal(SIGHUP, SIG_DFL) == SIG_ERR)
1370 		err(1, "signal");
1371 
1372 	if (command[0] == '/')
1373 		execr = snprintf(exec, sizeof(exec), "exec %s", command);
1374 	else
1375 		execr = snprintf(exec, sizeof(exec), "exec %s/%s",
1376 		    PATH_LIBEXEC, command);
1377 	if (execr >= (int) sizeof(exec))
1378 		errx(1, "%s: exec path too long", name);
1379 
1380 	/*
1381 	 * Wait for lka to acknowledge that it received the fd.
1382 	 * This prevents a race condition between the filter sending an error
1383 	 * message, and exiting and lka not being able to log it because of
1384 	 * SIGCHLD.
1385 	 * (Ab)use read to determine if the fd is installed; since stderr is
1386 	 * never going to be read from we can shutdown(2) the write-end in lka.
1387 	 */
1388 	if (read(STDERR_FILENO, &buf, 1) != 0)
1389 		errx(1, "lka didn't properly close write end of error socket");
1390 	if (system(exec) == -1)
1391 		err(1, NULL);
1392 
1393 	/* there's no successful exit from a processor */
1394 	_exit(1);
1395 }
1396 
1397 static void
1398 forkmda(struct mproc *p, uint64_t id, struct deliver *deliver)
1399 {
1400 	char		 ebuf[128], sfn[32];
1401 	struct dispatcher	*dsp;
1402 	struct child	*child;
1403 	pid_t		 pid;
1404 	int		 allout, pipefd[2];
1405 	struct passwd	*pw;
1406 	const char	*pw_name;
1407 	uid_t	pw_uid;
1408 	gid_t	pw_gid;
1409 	const char	*pw_dir;
1410 
1411 	dsp = dict_xget(env->sc_dispatchers, deliver->dispatcher);
1412 	if (dsp->type != DISPATCHER_LOCAL)
1413 		fatalx("non-local dispatcher called from forkmda()");
1414 
1415 	log_debug("debug: smtpd: forking mda for session %016"PRIx64
1416 	    ": %s as %s", id, deliver->userinfo.username,
1417 	    dsp->u.local.user ? dsp->u.local.user : deliver->userinfo.username);
1418 
1419 	if (dsp->u.local.user) {
1420 		if ((pw = getpwnam(dsp->u.local.user)) == NULL) {
1421 			(void)snprintf(ebuf, sizeof ebuf,
1422 			    "delivery user '%s' does not exist",
1423 			    dsp->u.local.user);
1424 			m_create(p_pony, IMSG_MDA_DONE, 0, 0, -1);
1425 			m_add_id(p_pony, id);
1426 			m_add_int(p_pony, MDA_PERMFAIL);
1427 			m_add_int(p_pony, EX_NOUSER);
1428 			m_add_string(p_pony, ebuf);
1429 			m_close(p_pony);
1430 			return;
1431 		}
1432 		pw_name = pw->pw_name;
1433 		pw_uid = pw->pw_uid;
1434 		pw_gid = pw->pw_gid;
1435 		pw_dir = pw->pw_dir;
1436 	}
1437 	else {
1438 		pw_name = deliver->userinfo.username;
1439 		pw_uid = deliver->userinfo.uid;
1440 		pw_gid = deliver->userinfo.gid;
1441 		pw_dir = deliver->userinfo.directory;
1442 	}
1443 
1444 	if (pw_uid == 0 && deliver->mda_exec[0]) {
1445 		pw_name = deliver->userinfo.username;
1446 		pw_uid = deliver->userinfo.uid;
1447 		pw_gid = deliver->userinfo.gid;
1448 		pw_dir = deliver->userinfo.directory;
1449 	}
1450 
1451 	if (pw_uid == 0 && !dsp->u.local.is_mbox) {
1452 		(void)snprintf(ebuf, sizeof ebuf, "not allowed to deliver to: %s",
1453 		    deliver->userinfo.username);
1454 		m_create(p_pony, IMSG_MDA_DONE, 0, 0, -1);
1455 		m_add_id(p_pony, id);
1456 		m_add_int(p_pony, MDA_PERMFAIL);
1457 		m_add_int(p_pony, EX_NOPERM);
1458 		m_add_string(p_pony, ebuf);
1459 		m_close(p_pony);
1460 		return;
1461 	}
1462 
1463 	if (pipe(pipefd) == -1) {
1464 		(void)snprintf(ebuf, sizeof ebuf, "pipe: %s", strerror(errno));
1465 		m_create(p_pony, IMSG_MDA_DONE, 0, 0, -1);
1466 		m_add_id(p_pony, id);
1467 		m_add_int(p_pony, MDA_TEMPFAIL);
1468 		m_add_int(p_pony, EX_OSERR);
1469 		m_add_string(p_pony, ebuf);
1470 		m_close(p_pony);
1471 		return;
1472 	}
1473 
1474 	/* prepare file which captures stdout and stderr */
1475 	(void)strlcpy(sfn, "/tmp/smtpd.out.XXXXXXXXXXX", sizeof(sfn));
1476 	allout = mkstemp(sfn);
1477 	if (allout == -1) {
1478 		(void)snprintf(ebuf, sizeof ebuf, "mkstemp: %s", strerror(errno));
1479 		m_create(p_pony, IMSG_MDA_DONE, 0, 0, -1);
1480 		m_add_id(p_pony, id);
1481 		m_add_int(p_pony, MDA_TEMPFAIL);
1482 		m_add_int(p_pony, EX_OSERR);
1483 		m_add_string(p_pony, ebuf);
1484 		m_close(p_pony);
1485 		close(pipefd[0]);
1486 		close(pipefd[1]);
1487 		return;
1488 	}
1489 	unlink(sfn);
1490 
1491 	pid = fork();
1492 	if (pid == -1) {
1493 		(void)snprintf(ebuf, sizeof ebuf, "fork: %s", strerror(errno));
1494 		m_create(p_pony, IMSG_MDA_DONE, 0, 0, -1);
1495 		m_add_id(p_pony, id);
1496 		m_add_int(p_pony, MDA_TEMPFAIL);
1497 		m_add_int(p_pony, EX_OSERR);
1498 		m_add_string(p_pony, ebuf);
1499 		m_close(p_pony);
1500 		close(pipefd[0]);
1501 		close(pipefd[1]);
1502 		close(allout);
1503 		return;
1504 	}
1505 
1506 	/* parent passes the child fd over to mda */
1507 	if (pid > 0) {
1508 		child = child_add(pid, CHILD_MDA, NULL);
1509 		child->mda_out = allout;
1510 		child->mda_id = id;
1511 		close(pipefd[0]);
1512 		m_create(p, IMSG_MDA_FORK, 0, 0, pipefd[1]);
1513 		m_add_id(p, id);
1514 		m_close(p);
1515 		return;
1516 	}
1517 
1518 	/* mbox helper, create mailbox before privdrop if it doesn't exist */
1519 	if (dsp->u.local.is_mbox)
1520 		mda_mbox_init(deliver);
1521 
1522 	if (chdir(pw_dir) == -1 && chdir("/") == -1)
1523 		err(1, "chdir");
1524 	if (setgroups(1, &pw_gid) ||
1525 	    setresgid(pw_gid, pw_gid, pw_gid) ||
1526 	    setresuid(pw_uid, pw_uid, pw_uid))
1527 		err(1, "forkmda: cannot drop privileges");
1528 	if (dup2(pipefd[0], STDIN_FILENO) == -1 ||
1529 	    dup2(allout, STDOUT_FILENO) == -1 ||
1530 	    dup2(allout, STDERR_FILENO) == -1)
1531 		err(1, "forkmda: dup2");
1532 	if (closefrom(STDERR_FILENO + 1) == -1)
1533 		err(1, "closefrom");
1534 	if (setsid() == -1)
1535 		err(1, "setsid");
1536 	if (signal(SIGPIPE, SIG_DFL) == SIG_ERR ||
1537 	    signal(SIGINT, SIG_DFL) == SIG_ERR ||
1538 	    signal(SIGTERM, SIG_DFL) == SIG_ERR ||
1539 	    signal(SIGCHLD, SIG_DFL) == SIG_ERR ||
1540 	    signal(SIGHUP, SIG_DFL) == SIG_ERR)
1541 		err(1, "signal");
1542 
1543 	/* avoid hangs by setting 5m timeout */
1544 	alarm(300);
1545 
1546 	if (dsp->u.local.is_mbox &&
1547 	    dsp->u.local.mda_wrapper == NULL &&
1548 	    deliver->mda_exec[0] == '\0')
1549 		mda_mbox(deliver);
1550 	else
1551 		mda_unpriv(dsp, deliver, pw_name, pw_dir);
1552 }
1553 
1554 static void
1555 offline_scan(int fd, short ev, void *arg)
1556 {
1557 	char		*path_argv[2];
1558 	FTS		*fts = arg;
1559 	FTSENT		*e;
1560 	int		 n = 0;
1561 
1562 	path_argv[0] = PATH_SPOOL PATH_OFFLINE;
1563 	path_argv[1] = NULL;
1564 
1565 	if (fts == NULL) {
1566 		log_debug("debug: smtpd: scanning offline queue...");
1567 		fts = fts_open(path_argv, FTS_PHYSICAL | FTS_NOCHDIR, NULL);
1568 		if (fts == NULL) {
1569 			log_warn("fts_open: %s", path_argv[0]);
1570 			return;
1571 		}
1572 	}
1573 
1574 	while ((e = fts_read(fts)) != NULL) {
1575 		if (e->fts_info != FTS_F)
1576 			continue;
1577 
1578 		/* offline files must be at depth 1 */
1579 		if (e->fts_level != 1)
1580 			continue;
1581 
1582 		/* offline file group must match parent directory group */
1583 		if (e->fts_statp->st_gid != e->fts_parent->fts_statp->st_gid)
1584 			continue;
1585 
1586 		if (e->fts_statp->st_size == 0) {
1587 			if (unlink(e->fts_accpath) == -1)
1588 				log_warnx("warn: smtpd: could not unlink %s", e->fts_accpath);
1589 			continue;
1590 		}
1591 
1592 		if (offline_add(e->fts_name, e->fts_statp->st_uid,
1593 		    e->fts_statp->st_gid)) {
1594 			log_warnx("warn: smtpd: "
1595 			    "could not add offline message %s", e->fts_name);
1596 			continue;
1597 		}
1598 
1599 		if ((n++) == OFFLINE_READMAX) {
1600 			evtimer_set(&offline_ev, offline_scan, fts);
1601 			offline_timeout.tv_sec = 0;
1602 			offline_timeout.tv_usec = 100000;
1603 			evtimer_add(&offline_ev, &offline_timeout);
1604 			return;
1605 		}
1606 	}
1607 
1608 	log_debug("debug: smtpd: offline scanning done");
1609 	fts_close(fts);
1610 }
1611 
1612 static int
1613 offline_enqueue(char *name, uid_t uid, gid_t gid)
1614 {
1615 	char		*path;
1616 	struct stat	 sb;
1617 	pid_t		 pid;
1618 	struct child	*child;
1619 	struct passwd	*pw;
1620 	int		 pathlen;
1621 
1622 	pathlen = asprintf(&path, "%s/%s", PATH_SPOOL PATH_OFFLINE, name);
1623 	if (pathlen == -1) {
1624 		log_warnx("warn: smtpd: asprintf");
1625 		return (-1);
1626 	}
1627 
1628 	if (pathlen >= PATH_MAX) {
1629 		log_warnx("warn: smtpd: pathname exceeds PATH_MAX");
1630 		free(path);
1631 		return (-1);
1632 	}
1633 
1634 	log_debug("debug: smtpd: enqueueing offline message %s", path);
1635 
1636 	if ((pid = fork()) == -1) {
1637 		log_warn("warn: smtpd: fork");
1638 		free(path);
1639 		return (-1);
1640 	}
1641 
1642 	if (pid == 0) {
1643 		char	*envp[2], *p = NULL, *tmp;
1644 		int	 fd;
1645 		FILE	*fp;
1646 		size_t	 sz = 0;
1647 		ssize_t	 len;
1648 		arglist	 args;
1649 
1650 		if (closefrom(STDERR_FILENO + 1) == -1)
1651 			_exit(1);
1652 
1653 		memset(&args, 0, sizeof(args));
1654 
1655 		if ((fd = open(path, O_RDONLY|O_NOFOLLOW|O_NONBLOCK)) == -1) {
1656 			log_warn("warn: smtpd: open: %s", path);
1657 			_exit(1);
1658 		}
1659 
1660 		if (fstat(fd, &sb) == -1) {
1661 			log_warn("warn: smtpd: fstat: %s", path);
1662 			_exit(1);
1663 		}
1664 
1665 		if (!S_ISREG(sb.st_mode)) {
1666 			log_warnx("warn: smtpd: file %s (uid %d) not regular",
1667 			    path, sb.st_uid);
1668 			_exit(1);
1669 		}
1670 
1671 		if (sb.st_nlink != 1) {
1672 			log_warnx("warn: smtpd: file %s is hard-link", path);
1673 			_exit(1);
1674 		}
1675 
1676 		if (sb.st_uid != uid) {
1677 			log_warnx("warn: smtpd: file %s has bad uid %d",
1678 			    path, sb.st_uid);
1679 			_exit(1);
1680 		}
1681 
1682 		if (sb.st_gid != gid) {
1683 			log_warnx("warn: smtpd: file %s has bad gid %d",
1684 			    path, sb.st_gid);
1685 			_exit(1);
1686 		}
1687 
1688 		pw = getpwuid(sb.st_uid);
1689 		if (pw == NULL) {
1690 			log_warnx("warn: smtpd: getpwuid for uid %d failed",
1691 			    sb.st_uid);
1692 			_exit(1);
1693 		}
1694 
1695 		if (setgroups(1, &pw->pw_gid) ||
1696 		    setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) ||
1697 		    setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))
1698 			_exit(1);
1699 
1700 		if ((fp = fdopen(fd, "r")) == NULL)
1701 			_exit(1);
1702 
1703 		if (chdir(pw->pw_dir) == -1 && chdir("/") == -1)
1704 			_exit(1);
1705 
1706 		if (setsid() == -1 ||
1707 		    signal(SIGPIPE, SIG_DFL) == SIG_ERR ||
1708 		    dup2(fileno(fp), STDIN_FILENO) == -1)
1709 			_exit(1);
1710 
1711 		if ((len = getline(&p, &sz, fp)) == -1)
1712 			_exit(1);
1713 
1714 		if (p[len - 1] != '\n')
1715 			_exit(1);
1716 		p[len - 1] = '\0';
1717 
1718 		addargs(&args, "%s", "sendmail");
1719 		addargs(&args, "%s", "-S");
1720 
1721 		while ((tmp = strsep(&p, "|")) != NULL)
1722 			addargs(&args, "%s", tmp);
1723 
1724 		free(p);
1725 		if (lseek(fileno(fp), len, SEEK_SET) == -1)
1726 			_exit(1);
1727 
1728 		envp[0] = "PATH=" _PATH_DEFPATH;
1729 		envp[1] = (char *)NULL;
1730 		environ = envp;
1731 
1732 		execvp(PATH_SMTPCTL, args.list);
1733 		_exit(1);
1734 	}
1735 
1736 	offline_running++;
1737 	child = child_add(pid, CHILD_ENQUEUE_OFFLINE, NULL);
1738 	child->path = path;
1739 
1740 	return (0);
1741 }
1742 
1743 static int
1744 offline_add(char *path, uid_t uid, gid_t gid)
1745 {
1746 	struct offline	*q;
1747 
1748 	if (offline_running < OFFLINE_QUEUEMAX)
1749 		/* skip queue */
1750 		return offline_enqueue(path, uid, gid);
1751 
1752 	q = malloc(sizeof(*q) + strlen(path) + 1);
1753 	if (q == NULL)
1754 		return (-1);
1755 	q->uid = uid;
1756 	q->gid = gid;
1757 	q->path = (char *)q + sizeof(*q);
1758 	memmove(q->path, path, strlen(path) + 1);
1759 	TAILQ_INSERT_TAIL(&offline_q, q, entry);
1760 
1761 	return (0);
1762 }
1763 
1764 static void
1765 offline_done(void)
1766 {
1767 	struct offline	*q;
1768 
1769 	offline_running--;
1770 
1771 	while (offline_running < OFFLINE_QUEUEMAX) {
1772 		if ((q = TAILQ_FIRST(&offline_q)) == NULL)
1773 			break; /* all done */
1774 		TAILQ_REMOVE(&offline_q, q, entry);
1775 		offline_enqueue(q->path, q->uid, q->gid);
1776 		free(q);
1777 	}
1778 }
1779 
1780 static int
1781 parent_forward_open(char *username, char *directory, uid_t uid, gid_t gid)
1782 {
1783 	char		pathname[PATH_MAX];
1784 	int		fd;
1785 	struct stat	sb;
1786 
1787 	if (!bsnprintf(pathname, sizeof (pathname), "%s/.forward",
1788 		directory)) {
1789 		log_warnx("warn: smtpd: %s: pathname too large", pathname);
1790 		return -1;
1791 	}
1792 
1793 	if (stat(directory, &sb) == -1) {
1794 		log_warn("warn: smtpd: parent_forward_open: %s", directory);
1795 		return -1;
1796 	}
1797 	if (sb.st_mode & S_ISVTX) {
1798 		log_warnx("warn: smtpd: parent_forward_open: %s is sticky",
1799 		    directory);
1800 		errno = EAGAIN;
1801 		return -1;
1802 	}
1803 
1804 	do {
1805 		fd = open(pathname, O_RDONLY|O_NOFOLLOW|O_NONBLOCK);
1806 	} while (fd == -1 && errno == EINTR);
1807 	if (fd == -1) {
1808 		if (errno == ENOENT)
1809 			return -1;
1810 		if (errno == EMFILE || errno == ENFILE || errno == EIO) {
1811 			errno = EAGAIN;
1812 			return -1;
1813 		}
1814 		if (errno == ELOOP)
1815 			log_warnx("warn: smtpd: parent_forward_open: %s: "
1816 			    "cannot follow symbolic links", pathname);
1817 		else
1818 			log_warn("warn: smtpd: parent_forward_open: %s", pathname);
1819 		return -1;
1820 	}
1821 
1822 	if (!secure_file(fd, pathname, directory, uid, 1)) {
1823 		log_warnx("warn: smtpd: %s: unsecure file", pathname);
1824 		close(fd);
1825 		return -1;
1826 	}
1827 
1828 	return fd;
1829 }
1830 
1831 void
1832 imsg_dispatch(struct mproc *p, struct imsg *imsg)
1833 {
1834 	struct timespec	t0, t1, dt;
1835 	int		msg;
1836 
1837 	if (imsg == NULL) {
1838 		imsg_callback(p, imsg);
1839 		return;
1840 	}
1841 
1842 	log_imsg(smtpd_process, p->proc, imsg);
1843 
1844 	if (profiling & PROFILE_IMSG)
1845 		clock_gettime(CLOCK_MONOTONIC, &t0);
1846 
1847 	msg = imsg->hdr.type;
1848 	imsg_callback(p, imsg);
1849 
1850 	if (profiling & PROFILE_IMSG) {
1851 		clock_gettime(CLOCK_MONOTONIC, &t1);
1852 		timespecsub(&t1, &t0, &dt);
1853 
1854 		log_debug("profile-imsg: %s %s %s %d %lld.%09ld",
1855 		    proc_name(smtpd_process),
1856 		    proc_name(p->proc),
1857 		    imsg_to_str(msg),
1858 		    (int)imsg->hdr.len,
1859 		    (long long)dt.tv_sec,
1860 		    dt.tv_nsec);
1861 
1862 		if (profiling & PROFILE_TOSTAT) {
1863 			char	key[STAT_KEY_SIZE];
1864 			/* can't profstat control process yet */
1865 			if (smtpd_process == PROC_CONTROL)
1866 				return;
1867 
1868 			if (!bsnprintf(key, sizeof key,
1869 				"profiling.imsg.%s.%s.%s",
1870 				proc_name(smtpd_process),
1871 				proc_name(p->proc),
1872 				imsg_to_str(msg)))
1873 				return;
1874 			stat_set(key, stat_timespec(&dt));
1875 		}
1876 	}
1877 }
1878 
1879 void
1880 log_imsg(int to, int from, struct imsg *imsg)
1881 {
1882 
1883 	if (to == PROC_CONTROL && imsg->hdr.type == IMSG_STAT_SET)
1884 		return;
1885 
1886 	if (imsg->fd != -1)
1887 		log_trace(TRACE_IMSG, "imsg: %s <- %s: %s (len=%zu, fd=%d)",
1888 		    proc_name(to),
1889 		    proc_name(from),
1890 		    imsg_to_str(imsg->hdr.type),
1891 		    imsg->hdr.len - IMSG_HEADER_SIZE,
1892 		    imsg->fd);
1893 	else
1894 		log_trace(TRACE_IMSG, "imsg: %s <- %s: %s (len=%zu)",
1895 		    proc_name(to),
1896 		    proc_name(from),
1897 		    imsg_to_str(imsg->hdr.type),
1898 		    imsg->hdr.len - IMSG_HEADER_SIZE);
1899 }
1900 
1901 const char *
1902 proc_title(enum smtp_proc_type proc)
1903 {
1904 	switch (proc) {
1905 	case PROC_PARENT:
1906 		return "[priv]";
1907 	case PROC_LKA:
1908 		return "lookup";
1909 	case PROC_QUEUE:
1910 		return "queue";
1911 	case PROC_CONTROL:
1912 		return "control";
1913 	case PROC_SCHEDULER:
1914 		return "scheduler";
1915 	case PROC_PONY:
1916 		return "pony express";
1917 	case PROC_CA:
1918 		return "klondike";
1919 	case PROC_CLIENT:
1920 		return "client";
1921 	case PROC_PROCESSOR:
1922 		return "processor";
1923 	}
1924 	return "unknown";
1925 }
1926 
1927 const char *
1928 proc_name(enum smtp_proc_type proc)
1929 {
1930 	switch (proc) {
1931 	case PROC_PARENT:
1932 		return "parent";
1933 	case PROC_LKA:
1934 		return "lka";
1935 	case PROC_QUEUE:
1936 		return "queue";
1937 	case PROC_CONTROL:
1938 		return "control";
1939 	case PROC_SCHEDULER:
1940 		return "scheduler";
1941 	case PROC_PONY:
1942 		return "pony";
1943 	case PROC_CA:
1944 		return "ca";
1945 	case PROC_CLIENT:
1946 		return "client-proc";
1947 	default:
1948 		return "unknown";
1949 	}
1950 }
1951 
1952 #define CASE(x) case x : return #x
1953 
1954 const char *
1955 imsg_to_str(int type)
1956 {
1957 	static char	 buf[32];
1958 
1959 	switch (type) {
1960 	CASE(IMSG_NONE);
1961 
1962 	CASE(IMSG_CTL_OK);
1963 	CASE(IMSG_CTL_FAIL);
1964 
1965 	CASE(IMSG_CTL_GET_DIGEST);
1966 	CASE(IMSG_CTL_GET_STATS);
1967 	CASE(IMSG_CTL_LIST_MESSAGES);
1968 	CASE(IMSG_CTL_LIST_ENVELOPES);
1969 	CASE(IMSG_CTL_MTA_SHOW_HOSTS);
1970 	CASE(IMSG_CTL_MTA_SHOW_RELAYS);
1971 	CASE(IMSG_CTL_MTA_SHOW_ROUTES);
1972 	CASE(IMSG_CTL_MTA_SHOW_HOSTSTATS);
1973 	CASE(IMSG_CTL_MTA_BLOCK);
1974 	CASE(IMSG_CTL_MTA_UNBLOCK);
1975 	CASE(IMSG_CTL_MTA_SHOW_BLOCK);
1976 	CASE(IMSG_CTL_PAUSE_EVP);
1977 	CASE(IMSG_CTL_PAUSE_MDA);
1978 	CASE(IMSG_CTL_PAUSE_MTA);
1979 	CASE(IMSG_CTL_PAUSE_SMTP);
1980 	CASE(IMSG_CTL_PROFILE);
1981 	CASE(IMSG_CTL_PROFILE_DISABLE);
1982 	CASE(IMSG_CTL_PROFILE_ENABLE);
1983 	CASE(IMSG_CTL_RESUME_EVP);
1984 	CASE(IMSG_CTL_RESUME_MDA);
1985 	CASE(IMSG_CTL_RESUME_MTA);
1986 	CASE(IMSG_CTL_RESUME_SMTP);
1987 	CASE(IMSG_CTL_RESUME_ROUTE);
1988 	CASE(IMSG_CTL_REMOVE);
1989 	CASE(IMSG_CTL_SCHEDULE);
1990 	CASE(IMSG_CTL_SHOW_STATUS);
1991 	CASE(IMSG_CTL_TRACE_DISABLE);
1992 	CASE(IMSG_CTL_TRACE_ENABLE);
1993 	CASE(IMSG_CTL_UPDATE_TABLE);
1994 	CASE(IMSG_CTL_VERBOSE);
1995 	CASE(IMSG_CTL_DISCOVER_EVPID);
1996 	CASE(IMSG_CTL_DISCOVER_MSGID);
1997 
1998 	CASE(IMSG_CTL_SMTP_SESSION);
1999 
2000 	CASE(IMSG_GETADDRINFO);
2001 	CASE(IMSG_GETADDRINFO_END);
2002 	CASE(IMSG_GETNAMEINFO);
2003 	CASE(IMSG_RES_QUERY);
2004 
2005 	CASE(IMSG_CERT_INIT);
2006 	CASE(IMSG_CERT_CERTIFICATE);
2007 	CASE(IMSG_CERT_VERIFY);
2008 
2009 	CASE(IMSG_SETUP_KEY);
2010 	CASE(IMSG_SETUP_PEER);
2011 	CASE(IMSG_SETUP_DONE);
2012 
2013 	CASE(IMSG_CONF_START);
2014 	CASE(IMSG_CONF_END);
2015 
2016 	CASE(IMSG_STAT_INCREMENT);
2017 	CASE(IMSG_STAT_DECREMENT);
2018 	CASE(IMSG_STAT_SET);
2019 
2020 	CASE(IMSG_LKA_AUTHENTICATE);
2021 	CASE(IMSG_LKA_OPEN_FORWARD);
2022 	CASE(IMSG_LKA_ENVELOPE_SUBMIT);
2023 	CASE(IMSG_LKA_ENVELOPE_COMMIT);
2024 
2025 	CASE(IMSG_QUEUE_DELIVER);
2026 	CASE(IMSG_QUEUE_DELIVERY_OK);
2027 	CASE(IMSG_QUEUE_DELIVERY_TEMPFAIL);
2028 	CASE(IMSG_QUEUE_DELIVERY_PERMFAIL);
2029 	CASE(IMSG_QUEUE_DELIVERY_LOOP);
2030 	CASE(IMSG_QUEUE_DISCOVER_EVPID);
2031 	CASE(IMSG_QUEUE_DISCOVER_MSGID);
2032 	CASE(IMSG_QUEUE_ENVELOPE_ACK);
2033 	CASE(IMSG_QUEUE_ENVELOPE_COMMIT);
2034 	CASE(IMSG_QUEUE_ENVELOPE_REMOVE);
2035 	CASE(IMSG_QUEUE_ENVELOPE_SCHEDULE);
2036 	CASE(IMSG_QUEUE_ENVELOPE_SUBMIT);
2037 	CASE(IMSG_QUEUE_HOLDQ_HOLD);
2038 	CASE(IMSG_QUEUE_HOLDQ_RELEASE);
2039 	CASE(IMSG_QUEUE_MESSAGE_COMMIT);
2040 	CASE(IMSG_QUEUE_MESSAGE_ROLLBACK);
2041 	CASE(IMSG_QUEUE_SMTP_SESSION);
2042 	CASE(IMSG_QUEUE_TRANSFER);
2043 
2044 	CASE(IMSG_MDA_DELIVERY_OK);
2045 	CASE(IMSG_MDA_DELIVERY_TEMPFAIL);
2046 	CASE(IMSG_MDA_DELIVERY_PERMFAIL);
2047 	CASE(IMSG_MDA_DELIVERY_LOOP);
2048 	CASE(IMSG_MDA_DELIVERY_HOLD);
2049 	CASE(IMSG_MDA_DONE);
2050 	CASE(IMSG_MDA_FORK);
2051 	CASE(IMSG_MDA_HOLDQ_RELEASE);
2052 	CASE(IMSG_MDA_LOOKUP_USERINFO);
2053 	CASE(IMSG_MDA_KILL);
2054 	CASE(IMSG_MDA_OPEN_MESSAGE);
2055 
2056 	CASE(IMSG_MTA_DELIVERY_OK);
2057 	CASE(IMSG_MTA_DELIVERY_TEMPFAIL);
2058 	CASE(IMSG_MTA_DELIVERY_PERMFAIL);
2059 	CASE(IMSG_MTA_DELIVERY_LOOP);
2060 	CASE(IMSG_MTA_DELIVERY_HOLD);
2061 	CASE(IMSG_MTA_DNS_HOST);
2062 	CASE(IMSG_MTA_DNS_HOST_END);
2063 	CASE(IMSG_MTA_DNS_MX);
2064 	CASE(IMSG_MTA_DNS_MX_PREFERENCE);
2065 	CASE(IMSG_MTA_HOLDQ_RELEASE);
2066 	CASE(IMSG_MTA_LOOKUP_CREDENTIALS);
2067 	CASE(IMSG_MTA_LOOKUP_SOURCE);
2068 	CASE(IMSG_MTA_LOOKUP_HELO);
2069 	CASE(IMSG_MTA_LOOKUP_SMARTHOST);
2070 	CASE(IMSG_MTA_OPEN_MESSAGE);
2071 	CASE(IMSG_MTA_SCHEDULE);
2072 
2073 	CASE(IMSG_SCHED_ENVELOPE_BOUNCE);
2074 	CASE(IMSG_SCHED_ENVELOPE_DELIVER);
2075 	CASE(IMSG_SCHED_ENVELOPE_EXPIRE);
2076 	CASE(IMSG_SCHED_ENVELOPE_INJECT);
2077 	CASE(IMSG_SCHED_ENVELOPE_REMOVE);
2078 	CASE(IMSG_SCHED_ENVELOPE_TRANSFER);
2079 
2080 	CASE(IMSG_SMTP_AUTHENTICATE);
2081 	CASE(IMSG_SMTP_MESSAGE_COMMIT);
2082 	CASE(IMSG_SMTP_MESSAGE_CREATE);
2083 	CASE(IMSG_SMTP_MESSAGE_ROLLBACK);
2084 	CASE(IMSG_SMTP_MESSAGE_OPEN);
2085 	CASE(IMSG_SMTP_CHECK_SENDER);
2086 	CASE(IMSG_SMTP_EXPAND_RCPT);
2087 	CASE(IMSG_SMTP_LOOKUP_HELO);
2088 
2089 	CASE(IMSG_SMTP_REQ_CONNECT);
2090 	CASE(IMSG_SMTP_REQ_HELO);
2091 	CASE(IMSG_SMTP_REQ_MAIL);
2092 	CASE(IMSG_SMTP_REQ_RCPT);
2093 	CASE(IMSG_SMTP_REQ_DATA);
2094 	CASE(IMSG_SMTP_REQ_EOM);
2095 	CASE(IMSG_SMTP_EVENT_RSET);
2096 	CASE(IMSG_SMTP_EVENT_COMMIT);
2097 	CASE(IMSG_SMTP_EVENT_ROLLBACK);
2098 	CASE(IMSG_SMTP_EVENT_DISCONNECT);
2099 
2100 	CASE(IMSG_LKA_PROCESSOR_FORK);
2101 	CASE(IMSG_LKA_PROCESSOR_ERRFD);
2102 
2103 	CASE(IMSG_REPORT_SMTP_LINK_CONNECT);
2104 	CASE(IMSG_REPORT_SMTP_LINK_DISCONNECT);
2105 	CASE(IMSG_REPORT_SMTP_LINK_TLS);
2106 	CASE(IMSG_REPORT_SMTP_LINK_GREETING);
2107 	CASE(IMSG_REPORT_SMTP_LINK_IDENTIFY);
2108 	CASE(IMSG_REPORT_SMTP_LINK_AUTH);
2109 
2110 	CASE(IMSG_REPORT_SMTP_TX_RESET);
2111 	CASE(IMSG_REPORT_SMTP_TX_BEGIN);
2112 	CASE(IMSG_REPORT_SMTP_TX_ENVELOPE);
2113 	CASE(IMSG_REPORT_SMTP_TX_COMMIT);
2114 	CASE(IMSG_REPORT_SMTP_TX_ROLLBACK);
2115 
2116 	CASE(IMSG_REPORT_SMTP_PROTOCOL_CLIENT);
2117 	CASE(IMSG_REPORT_SMTP_PROTOCOL_SERVER);
2118 
2119 	CASE(IMSG_FILTER_SMTP_BEGIN);
2120 	CASE(IMSG_FILTER_SMTP_END);
2121 	CASE(IMSG_FILTER_SMTP_PROTOCOL);
2122 	CASE(IMSG_FILTER_SMTP_DATA_BEGIN);
2123 	CASE(IMSG_FILTER_SMTP_DATA_END);
2124 
2125 	CASE(IMSG_CA_RSA_PRIVENC);
2126 	CASE(IMSG_CA_RSA_PRIVDEC);
2127 	CASE(IMSG_CA_ECDSA_SIGN);
2128 	default:
2129 		(void)snprintf(buf, sizeof(buf), "IMSG_??? (%d)", type);
2130 
2131 		return buf;
2132 	}
2133 }
2134 
2135 int
2136 parent_auth_user(const char *username, const char *password)
2137 {
2138 	char	user[LOGIN_NAME_MAX];
2139 	char	pass[LINE_MAX];
2140 	int	ret;
2141 
2142 	(void)strlcpy(user, username, sizeof(user));
2143 	(void)strlcpy(pass, password, sizeof(pass));
2144 
2145 	ret = auth_userokay(user, NULL, "auth-smtp", pass);
2146 	if (ret)
2147 		return LKA_OK;
2148 	return LKA_PERMFAIL;
2149 }
2150