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