xref: /openbsd-src/usr.sbin/smtpd/smtpd.c (revision 4c1e55dc91edd6e69ccc60ce855900fbc12cf34f)
1 /*	$OpenBSD: smtpd.c,v 1.155 2012/07/09 17:57:54 gilles Exp $	*/
2 
3 /*
4  * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.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/param.h>
25 #include <sys/socket.h>
26 #include <sys/wait.h>
27 #include <sys/stat.h>
28 #include <sys/uio.h>
29 #include <sys/mman.h>
30 
31 #include <dirent.h>
32 #include <err.h>
33 #include <errno.h>
34 #include <fcntl.h>
35 #include <event.h>
36 #include <imsg.h>
37 #include <paths.h>
38 #include <pwd.h>
39 #include <signal.h>
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <string.h>
43 #include <time.h>
44 #include <unistd.h>
45 
46 #include "smtpd.h"
47 #include "log.h"
48 
49 static void parent_imsg(struct imsgev *, struct imsg *);
50 static void usage(void);
51 static void parent_shutdown(void);
52 static void parent_send_config(int, short, void *);
53 static void parent_send_config_listeners(void);
54 static void parent_send_config_client_certs(void);
55 static void parent_send_config_ruleset(int);
56 static void parent_sig_handler(int, short, void *);
57 static void forkmda(struct imsgev *, u_int32_t, struct deliver *);
58 static int parent_forward_open(char *);
59 static void fork_peers(void);
60 static struct child *child_lookup(pid_t);
61 static struct child *child_add(pid_t, int, int);
62 static void child_del(pid_t);
63 
64 static void	offline_scan(int, short, void *);
65 static int	offline_add(char *);
66 static void	offline_done(void);
67 static int	offline_enqueue(char *);
68 
69 static void	purge_task(int, short, void *);
70 
71 
72 struct offline {
73 	TAILQ_ENTRY(offline)	 entry;
74 	char			*path;
75 };
76 
77 #define OFFLINE_READMAX		20
78 #define OFFLINE_QUEUEMAX	5
79 static size_t			offline_running = 0;
80 TAILQ_HEAD(, offline)		offline_q;
81 
82 static struct event		offline_ev;
83 static struct timeval		offline_timeout;
84 
85 static pid_t			purge_pid;
86 static struct timeval		purge_timeout;
87 static struct event		purge_ev;
88 
89 extern char	**environ;
90 void		(*imsg_callback)(struct imsgev *, struct imsg *);
91 
92 struct smtpd	*env = NULL;
93 
94 const char	*backend_queue = "fs";
95 const char	*backend_scheduler = "ramqueue";
96 
97 static void
98 parent_imsg(struct imsgev *iev, struct imsg *imsg)
99 {
100 	struct forward_req	*fwreq;
101 	struct auth		*auth;
102 	struct auth_backend	*auth_backend;
103 	int			 fd;
104 
105 	log_imsg(PROC_PARENT, iev->proc, imsg);
106 
107 	if (iev->proc == PROC_SMTP) {
108 		switch (imsg->hdr.type) {
109 		case IMSG_PARENT_SEND_CONFIG:
110 			parent_send_config_listeners();
111 			return;
112 
113 		case IMSG_PARENT_AUTHENTICATE:
114 			auth_backend = auth_backend_lookup(AUTH_BSD);
115 			auth = imsg->data;
116 			auth->success = auth_backend->authenticate(auth->user,
117 			    auth->pass);
118 			imsg_compose_event(iev, IMSG_PARENT_AUTHENTICATE, 0, 0,
119 			    -1, auth, sizeof *auth);
120 			return;
121 		}
122 	}
123 
124 	if (iev->proc == PROC_LKA) {
125 		switch (imsg->hdr.type) {
126 		case IMSG_PARENT_FORWARD_OPEN:
127 			fwreq = imsg->data;
128 			fd = parent_forward_open(fwreq->as_user);
129 			fwreq->status = 0;
130 			if (fd == -2) {
131 				/* no ~/.forward, however it's optional. */
132 				fwreq->status = 1;
133 				fd = -1;
134 			} else if (fd != -1)
135 				fwreq->status = 1;
136 			imsg_compose_event(iev, IMSG_PARENT_FORWARD_OPEN, 0, 0,
137 			    fd, fwreq, sizeof *fwreq);
138 			return;
139 		}
140 	}
141 
142 	if (iev->proc == PROC_MDA) {
143 		switch (imsg->hdr.type) {
144 		case IMSG_PARENT_FORK_MDA:
145 			forkmda(iev, imsg->hdr.peerid, imsg->data);
146 			return;
147 		}
148 	}
149 
150 	if (iev->proc == PROC_CONTROL) {
151 		switch (imsg->hdr.type) {
152 		case IMSG_CTL_VERBOSE:
153 			log_verbose(*(int *)imsg->data);
154 
155 			/* forward to other processes */
156 			imsg_compose_event(env->sc_ievs[PROC_LKA], IMSG_CTL_VERBOSE,
157 	    		    0, 0, -1, imsg->data, sizeof(int));
158 			imsg_compose_event(env->sc_ievs[PROC_MDA], IMSG_CTL_VERBOSE,
159 	    		    0, 0, -1, imsg->data, sizeof(int));
160 			imsg_compose_event(env->sc_ievs[PROC_MFA], IMSG_CTL_VERBOSE,
161 	    		    0, 0, -1, imsg->data, sizeof(int));
162 			imsg_compose_event(env->sc_ievs[PROC_MTA], IMSG_CTL_VERBOSE,
163 	    		    0, 0, -1, imsg->data, sizeof(int));
164 			imsg_compose_event(env->sc_ievs[PROC_QUEUE], IMSG_CTL_VERBOSE,
165 	    		    0, 0, -1, imsg->data, sizeof(int));
166 			imsg_compose_event(env->sc_ievs[PROC_SMTP], IMSG_CTL_VERBOSE,
167 	    		    0, 0, -1, imsg->data, sizeof(int));
168 			return;
169 		}
170 	}
171 
172 	errx(1, "parent_imsg: unexpected %s imsg", imsg_to_str(imsg->hdr.type));
173 }
174 
175 static void
176 usage(void)
177 {
178 	extern char	*__progname;
179 
180 	fprintf(stderr, "usage: %s [-dnv] [-D macro=value] "
181 	    "[-f file] [-T trace]\n", __progname);
182 	exit(1);
183 }
184 
185 static void
186 parent_shutdown(void)
187 {
188 	struct child	*child;
189 	pid_t		 pid;
190 
191 	SPLAY_FOREACH(child, childtree, &env->children)
192 		if (child->type == CHILD_DAEMON)
193 			kill(child->pid, SIGTERM);
194 
195 	do {
196 		pid = waitpid(WAIT_MYPGRP, NULL, 0);
197 	} while (pid != -1 || (pid == -1 && errno == EINTR));
198 
199 	log_warnx("parent terminating");
200 	exit(0);
201 }
202 
203 static void
204 parent_send_config(int fd, short event, void *p)
205 {
206 	parent_send_config_listeners();
207 	parent_send_config_client_certs();
208 	parent_send_config_ruleset(PROC_MFA);
209 	parent_send_config_ruleset(PROC_LKA);
210 }
211 
212 static void
213 parent_send_config_listeners(void)
214 {
215 	struct listener		*l;
216 	struct ssl		*s;
217 	struct iovec		 iov[5];
218 	int			 opt;
219 
220 	log_debug("parent_send_config: configuring smtp");
221 	imsg_compose_event(env->sc_ievs[PROC_SMTP], IMSG_CONF_START,
222 	    0, 0, -1, NULL, 0);
223 
224 	SPLAY_FOREACH(s, ssltree, env->sc_ssl) {
225 		if (!(s->flags & F_SCERT))
226 			continue;
227 
228 		iov[0].iov_base = s;
229 		iov[0].iov_len = sizeof(*s);
230 		iov[1].iov_base = s->ssl_cert;
231 		iov[1].iov_len = s->ssl_cert_len;
232 		iov[2].iov_base = s->ssl_key;
233 		iov[2].iov_len = s->ssl_key_len;
234 		iov[3].iov_base = s->ssl_dhparams;
235 		iov[3].iov_len = s->ssl_dhparams_len;
236 		iov[4].iov_base = s->ssl_ca;
237 		iov[4].iov_len = s->ssl_ca_len;
238 
239 		imsg_composev(&env->sc_ievs[PROC_SMTP]->ibuf,
240 		    IMSG_CONF_SSL, 0, 0, -1, iov, nitems(iov));
241 		imsg_event_add(env->sc_ievs[PROC_SMTP]);
242 	}
243 
244 	TAILQ_FOREACH(l, env->sc_listeners, entry) {
245 		if ((l->fd = socket(l->ss.ss_family, SOCK_STREAM, 0)) == -1)
246 			fatal("socket");
247 		opt = 1;
248 		if (setsockopt(l->fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0)
249 			fatal("setsockopt");
250 		if (bind(l->fd, (struct sockaddr *)&l->ss, l->ss.ss_len) == -1)
251 			fatal("bind");
252 		imsg_compose_event(env->sc_ievs[PROC_SMTP], IMSG_CONF_LISTENER,
253 		    0, 0, l->fd, l, sizeof(*l));
254 	}
255 
256 	imsg_compose_event(env->sc_ievs[PROC_SMTP], IMSG_CONF_END,
257 	    0, 0, -1, NULL, 0);
258 }
259 
260 static void
261 parent_send_config_client_certs(void)
262 {
263 	struct ssl		*s;
264 	struct iovec		 iov[3];
265 
266 	log_debug("parent_send_config_client_certs: configuring smtp");
267 	imsg_compose_event(env->sc_ievs[PROC_MTA], IMSG_CONF_START,
268 	    0, 0, -1, NULL, 0);
269 
270 	SPLAY_FOREACH(s, ssltree, env->sc_ssl) {
271 		if (!(s->flags & F_CCERT))
272 			continue;
273 
274 		iov[0].iov_base = s;
275 		iov[0].iov_len = sizeof(*s);
276 		iov[1].iov_base = s->ssl_cert;
277 		iov[1].iov_len = s->ssl_cert_len;
278 		iov[2].iov_base = s->ssl_key;
279 		iov[2].iov_len = s->ssl_key_len;
280 
281 		imsg_composev(&env->sc_ievs[PROC_MTA]->ibuf, IMSG_CONF_SSL,
282 		    0, 0, -1, iov, nitems(iov));
283 		imsg_event_add(env->sc_ievs[PROC_MTA]);
284 	}
285 
286 	imsg_compose_event(env->sc_ievs[PROC_MTA], IMSG_CONF_END,
287 	    0, 0, -1, NULL, 0);
288 }
289 
290 void
291 parent_send_config_ruleset(int proc)
292 {
293 	struct rule		*r;
294 	struct map		*m;
295 	struct mapel		*mapel;
296 	struct filter		*f;
297 
298 	log_debug("parent_send_config_ruleset: reloading rules and maps");
299 	imsg_compose_event(env->sc_ievs[proc], IMSG_CONF_START,
300 	    0, 0, -1, NULL, 0);
301 
302 	if (proc == PROC_MFA) {
303 		TAILQ_FOREACH(f, env->sc_filters, f_entry) {
304 			imsg_compose_event(env->sc_ievs[proc], IMSG_CONF_FILTER,
305 			    0, 0, -1, f, sizeof(*f));
306 		}
307 	}
308 	else {
309 		TAILQ_FOREACH(m, env->sc_maps, m_entry) {
310 			imsg_compose_event(env->sc_ievs[proc], IMSG_CONF_MAP,
311 			    0, 0, -1, m, sizeof(*m));
312 			TAILQ_FOREACH(mapel, &m->m_contents, me_entry) {
313 			imsg_compose_event(env->sc_ievs[proc], IMSG_CONF_MAP_CONTENT,
314 			    0, 0, -1, mapel, sizeof(*mapel));
315 			}
316 		}
317 
318 		TAILQ_FOREACH(r, env->sc_rules, r_entry) {
319 			imsg_compose_event(env->sc_ievs[proc], IMSG_CONF_RULE,
320 			    0, 0, -1, r, sizeof(*r));
321 			imsg_compose_event(env->sc_ievs[proc], IMSG_CONF_RULE_SOURCE,
322 			    0, 0, -1, &r->r_sources->m_name, sizeof(r->r_sources->m_name));
323 		}
324 	}
325 
326 	imsg_compose_event(env->sc_ievs[proc], IMSG_CONF_END,
327 	    0, 0, -1, NULL, 0);
328 }
329 
330 static void
331 parent_sig_handler(int sig, short event, void *p)
332 {
333 	struct child	*child;
334 	int		 die = 0, status, fail;
335 	pid_t		 pid;
336 	char		*cause;
337 
338 	switch (sig) {
339 	case SIGTERM:
340 	case SIGINT:
341 		die = 1;
342 		/* FALLTHROUGH */
343 	case SIGCHLD:
344 		do {
345 			pid = waitpid(-1, &status, WNOHANG);
346 			if (pid <= 0)
347 				continue;
348 
349 			fail = 0;
350 			if (WIFSIGNALED(status)) {
351 				fail = 1;
352 				asprintf(&cause, "terminated; signal %d",
353 				    WTERMSIG(status));
354 			} else if (WIFEXITED(status)) {
355 				if (WEXITSTATUS(status) != 0) {
356 					fail = 1;
357 					asprintf(&cause, "exited abnormally");
358 				} else
359 					asprintf(&cause, "exited okay");
360 			} else
361 				fatalx("unexpected cause of SIGCHLD");
362 
363 			if (pid == purge_pid)
364 				purge_pid = -1;
365 
366 			child = child_lookup(pid);
367 			if (child == NULL)
368 				goto skip;
369 
370 			switch (child->type) {
371 			case CHILD_DAEMON:
372 				die = 1;
373 				if (fail)
374 					log_warnx("lost child: %s %s",
375 					    env->sc_title[child->title], cause);
376 				break;
377 
378 			case CHILD_MDA:
379 				if (WIFSIGNALED(status) &&
380 				    WTERMSIG(status) == SIGALRM) {
381 					free(cause);
382 					asprintf(&cause, "terminated; timeout");
383 				}
384 				imsg_compose_event(env->sc_ievs[PROC_MDA],
385 				    IMSG_MDA_DONE, child->mda_id, 0,
386 				    child->mda_out, cause, strlen(cause) + 1);
387 				break;
388 
389 			case CHILD_ENQUEUE_OFFLINE:
390 				if (fail)
391 					log_warnx("smtpd: couldn't enqueue offline "
392 					    "message %s; smtpctl %s", child->path, cause);
393 				else
394 					unlink(child->path);
395 				free(child->path);
396 				offline_done();
397 				break;
398 
399 			default:
400 				fatalx("unexpected child type");
401 			}
402 
403 			child_del(child->pid);
404     skip:
405 			free(cause);
406 		} while (pid > 0 || (pid == -1 && errno == EINTR));
407 
408 		if (die)
409 			parent_shutdown();
410 		break;
411 	default:
412 		fatalx("unexpected signal");
413 	}
414 }
415 
416 int
417 main(int argc, char *argv[])
418 {
419 	int		 c;
420 	int		 debug, verbose;
421 	int		 opts, flags;
422 	const char	*conffile = CONF_FILE;
423 	struct smtpd	 smtpd;
424 	struct event	 ev_sigint;
425 	struct event	 ev_sigterm;
426 	struct event	 ev_sigchld;
427 	struct event	 ev_sighup;
428 	struct timeval	 tv;
429 	struct peer	 peers[] = {
430 		{ PROC_CONTROL,	imsg_dispatch },
431 		{ PROC_LKA,	imsg_dispatch },
432 		{ PROC_MDA,	imsg_dispatch },
433 		{ PROC_MFA,	imsg_dispatch },
434 		{ PROC_MTA,	imsg_dispatch },
435 		{ PROC_SMTP,	imsg_dispatch },
436 		{ PROC_QUEUE,	imsg_dispatch }
437 	};
438 
439 	env = &smtpd;
440 
441 	flags = 0;
442 	opts = 0;
443 	debug = 0;
444 	verbose = 0;
445 
446 	log_init(1);
447 
448 	TAILQ_INIT(&offline_q);
449 
450 	while ((c = getopt(argc, argv, "B:dD:nP:f:T:v")) != -1) {
451 		switch (c) {
452 		case 'B':
453 			if (strstr(optarg, "queue=") == optarg)
454 				backend_queue = strchr(optarg, '=') + 1;
455 			else if (strstr(optarg, "scheduler=") == optarg)
456 				backend_scheduler = strchr(optarg, '=') + 1;
457 			else
458 				log_warnx("invalid backend specifier %s", optarg);
459 			break;
460 		case 'd':
461 			debug = 2;
462 			verbose |= TRACE_VERBOSE;
463 			break;
464 		case 'D':
465 			if (cmdline_symset(optarg) < 0)
466 				log_warnx("could not parse macro definition %s",
467 				    optarg);
468 			break;
469 		case 'n':
470 			debug = 2;
471 			opts |= SMTPD_OPT_NOACTION;
472 			break;
473 		case 'f':
474 			conffile = optarg;
475 			break;
476 		case 'T':
477 			if (!strcmp(optarg, "imsg"))
478 				verbose |= TRACE_IMSG;
479 			else if (!strcmp(optarg, "io"))
480 				verbose |= TRACE_IO;
481 			else if (!strcmp(optarg, "smtp"))
482 				verbose |= TRACE_SMTP;
483 			else if (!strcmp(optarg, "mta"))
484 				verbose |= TRACE_MTA;
485 			else if (!strcmp(optarg, "bounce"))
486 				verbose |= TRACE_BOUNCE;
487 			else if (!strcmp(optarg, "scheduler"))
488 				verbose |= TRACE_SCHEDULER;
489 			else if (!strcmp(optarg, "all"))
490 				verbose |= ~TRACE_VERBOSE;
491 			else
492 				log_warnx("unknown trace flag \"%s\"", optarg);
493 			break;
494 		case 'P':
495 			if (!strcmp(optarg, "smtp"))
496 				flags |= SMTPD_SMTP_PAUSED;
497 			else if (!strcmp(optarg, "mta"))
498 				flags |= SMTPD_MTA_PAUSED;
499 			else if (!strcmp(optarg, "mda"))
500 				flags |= SMTPD_MDA_PAUSED;
501 			break;
502 		case 'v':
503 			verbose |=  TRACE_VERBOSE;
504 			break;
505 		default:
506 			usage();
507 		}
508 	}
509 
510 	if (!(verbose & TRACE_VERBOSE))
511 		verbose = 0;
512 
513 	argv += optind;
514 	argc -= optind;
515 
516 	if (parse_config(&smtpd, conffile, opts))
517 		exit(1);
518 
519 	if (strlcpy(env->sc_conffile, conffile, MAXPATHLEN) >= MAXPATHLEN)
520 		errx(1, "config file exceeds MAXPATHLEN");
521 
522 
523 	if (env->sc_opts & SMTPD_OPT_NOACTION) {
524 		fprintf(stderr, "configuration OK\n");
525 		exit(0);
526 	}
527 
528 	env->sc_flags |= flags;
529 
530 	/* check for root privileges */
531 	if (geteuid())
532 		errx(1, "need root privileges");
533 
534 	if ((env->sc_pw =  getpwnam(SMTPD_USER)) == NULL)
535 		errx(1, "unknown user %s", SMTPD_USER);
536 
537 	if (ckdir(PATH_SPOOL, 0711, 0, 0, 1) == 0)
538 		errx(1, "error in spool directory setup");
539 	if (ckdir(PATH_SPOOL PATH_OFFLINE, 01777, 0, 0, 1) == 0)
540 		errx(1, "error in offline directory setup");
541 	if (ckdir(PATH_SPOOL PATH_PURGE, 0700, env->sc_pw->pw_uid, 0, 1) == 0)
542 		errx(1, "error in purge directory setup");
543 
544 	mvpurge(PATH_SPOOL PATH_INCOMING, PATH_SPOOL PATH_PURGE);
545 
546 	if (ckdir(PATH_SPOOL PATH_INCOMING, 0700, env->sc_pw->pw_uid, 0, 1) == 0)
547 		errx(1, "error in incoming directory setup");
548 
549 	log_debug("using \"%s\" queue backend", backend_queue);
550 	log_debug("using \"%s\" scheduler backend", backend_scheduler);
551 
552 	env->sc_queue = queue_backend_lookup(backend_queue);
553 	if (env->sc_queue == NULL)
554 		errx(1, "could not find queue backend \"%s\"", backend_queue);
555 
556 	if (!env->sc_queue->init(1))
557 		errx(1, "could not initialize queue backend");
558 
559 	log_init(debug);
560 	log_verbose(verbose);
561 
562 	if (!debug)
563 		if (daemon(0, 0) == -1)
564 			err(1, "failed to daemonize");
565 
566 	log_info("startup%s", (debug > 1)?" [debug mode]":"");
567 
568 	if (env->sc_hostname[0] == '\0')
569 		errx(1, "machine does not have a hostname set");
570 
571 	env->stats = mmap(NULL, sizeof(struct stats), PROT_WRITE|PROT_READ,
572 	    MAP_ANON|MAP_SHARED, -1, (off_t)0);
573 	if (env->stats == MAP_FAILED)
574 		fatal("mmap");
575 	bzero(env->stats, sizeof(struct stats));
576 	stat_init(env->stats->counters, STATS_MAX);
577 
578 	env->stats->parent.start = time(NULL);
579 
580 	fork_peers();
581 
582 	imsg_callback = parent_imsg;
583 	event_init();
584 
585 	signal_set(&ev_sigint, SIGINT, parent_sig_handler, NULL);
586 	signal_set(&ev_sigterm, SIGTERM, parent_sig_handler, NULL);
587 	signal_set(&ev_sigchld, SIGCHLD, parent_sig_handler, NULL);
588 	signal_set(&ev_sighup, SIGHUP, parent_sig_handler, NULL);
589 	signal_add(&ev_sigint, NULL);
590 	signal_add(&ev_sigterm, NULL);
591 	signal_add(&ev_sigchld, NULL);
592 	signal_add(&ev_sighup, NULL);
593 	signal(SIGPIPE, SIG_IGN);
594 
595 	config_pipes(peers, nitems(peers));
596 	config_peers(peers, nitems(peers));
597 
598 	evtimer_set(&env->sc_ev, parent_send_config, NULL);
599 	bzero(&tv, sizeof(tv));
600 	evtimer_add(&env->sc_ev, &tv);
601 
602 	/* defer offline scanning for a second */
603 	evtimer_set(&offline_ev, offline_scan, NULL);
604 	offline_timeout.tv_sec = 1;
605 	offline_timeout.tv_usec = 0;
606 	evtimer_add(&offline_ev, &offline_timeout);
607 
608 	purge_pid = -1;
609 	evtimer_set(&purge_ev, purge_task, NULL);
610 	purge_timeout.tv_sec = 10;
611 	purge_timeout.tv_usec = 0;
612 	evtimer_add(&purge_ev, &purge_timeout);
613 
614 	if (event_dispatch() < 0)
615 		fatal("event_dispatch");
616 
617 	return (0);
618 }
619 
620 static void
621 fork_peers(void)
622 {
623 	SPLAY_INIT(&env->children);
624 
625 	/*
626 	 * Pick descriptor limit that will guarantee impossibility of fd
627 	 * starvation condition.  The logic:
628 	 *
629 	 * Treat hardlimit as 100%.
630 	 * Limit smtp to 50% (inbound connections)
631 	 * Limit mta to 50% (outbound connections)
632 	 * Limit mda to 50% (local deliveries)
633 	 * In all three above, compute max session limit by halving the fd
634 	 * limit (50% -> 25%), because each session costs two fds.
635 	 * Limit queue to 100% to cover the extreme case when tons of fds are
636 	 * opened for all four possible purposes (smtp, mta, mda, bounce)
637 	 */
638 	fdlimit(0.5);
639 
640 	env->sc_instances[PROC_CONTROL] = 1;
641 	env->sc_instances[PROC_LKA] = 1;
642 	env->sc_instances[PROC_MDA] = 1;
643 	env->sc_instances[PROC_MFA] = 1;
644 	env->sc_instances[PROC_MTA] = 1;
645 	env->sc_instances[PROC_PARENT] = 1;
646 	env->sc_instances[PROC_QUEUE] = 1;
647 	env->sc_instances[PROC_SCHEDULER] = 1;
648 	env->sc_instances[PROC_SMTP] = 1;
649 
650 	init_pipes();
651 
652 	env->sc_title[PROC_CONTROL] = "control";
653 	env->sc_title[PROC_LKA] = "lookup agent";
654 	env->sc_title[PROC_MDA] = "mail delivery agent";
655 	env->sc_title[PROC_MFA] = "mail filter agent";
656 	env->sc_title[PROC_MTA] = "mail transfer agent";
657 	env->sc_title[PROC_QUEUE] = "queue";
658 	env->sc_title[PROC_SCHEDULER] = "scheduler";
659 	env->sc_title[PROC_SMTP] = "smtp server";
660 
661 	child_add(control(), CHILD_DAEMON, PROC_CONTROL);
662 	child_add(lka(), CHILD_DAEMON, PROC_LKA);
663 	child_add(mda(), CHILD_DAEMON, PROC_MDA);
664 	child_add(mfa(), CHILD_DAEMON, PROC_MFA);
665 	child_add(mta(), CHILD_DAEMON, PROC_MTA);
666 	child_add(queue(), CHILD_DAEMON, PROC_QUEUE);
667 	child_add(scheduler(), CHILD_DAEMON, PROC_SCHEDULER);
668 	child_add(smtp(), CHILD_DAEMON, PROC_SMTP);
669 
670 	setproctitle("[priv]");
671 }
672 
673 struct child *
674 child_add(pid_t pid, int type, int title)
675 {
676 	struct child	*child;
677 
678 	if ((child = calloc(1, sizeof(*child))) == NULL)
679 		fatal(NULL);
680 
681 	child->pid = pid;
682 	child->type = type;
683 	child->title = title;
684 
685 	if (SPLAY_INSERT(childtree, &env->children, child) != NULL)
686 		fatalx("child_add: double insert");
687 
688 	return (child);
689 }
690 
691 static void
692 child_del(pid_t pid)
693 {
694 	struct child	*p;
695 
696 	p = child_lookup(pid);
697 	if (p == NULL)
698 		fatalx("child_del: unknown child");
699 
700 	if (SPLAY_REMOVE(childtree, &env->children, p) == NULL)
701 		fatalx("child_del: tree remove failed");
702 	free(p);
703 }
704 
705 static struct child *
706 child_lookup(pid_t pid)
707 {
708 	struct child	 key;
709 
710 	key.pid = pid;
711 	return SPLAY_FIND(childtree, &env->children, &key);
712 }
713 
714 void
715 imsg_event_add(struct imsgev *iev)
716 {
717 	if (iev->handler == NULL) {
718 		imsg_flush(&iev->ibuf);
719 		return;
720 	}
721 
722 	iev->events = EV_READ;
723 	if (iev->ibuf.w.queued)
724 		iev->events |= EV_WRITE;
725 
726 	event_del(&iev->ev);
727 	event_set(&iev->ev, iev->ibuf.fd, iev->events, iev->handler, iev->data);
728 	event_add(&iev->ev, NULL);
729 }
730 
731 void
732 imsg_compose_event(struct imsgev *iev, u_int16_t type, u_int32_t peerid,
733     pid_t pid, int fd, void *data, u_int16_t datalen)
734 {
735 	if (imsg_compose(&iev->ibuf, type, peerid, pid, fd, data, datalen) == -1)
736 		fatal("imsg_compose_event");
737 	imsg_event_add(iev);
738 }
739 
740 
741 static void
742 purge_task(int fd, short ev, void *arg)
743 {
744 	DIR		*d;
745 	struct dirent	*de;
746 	int		 n;
747 	uid_t		 uid;
748 	gid_t		 gid;
749 
750 	if (purge_pid == -1) {
751 
752 		n = 0;
753 		if ((d = opendir(PATH_SPOOL PATH_PURGE))) {
754 			while ((de = readdir(d)) != NULL)
755 				n++;
756 			closedir(d);
757 		} else
758 			log_warn("purge_task: opendir");
759 
760 		if (n > 2) {
761 			switch(purge_pid = fork()) {
762 			case -1:
763 				log_warn("purge_task: fork");
764 				break;
765 			case 0:
766 				if (chroot(PATH_SPOOL PATH_PURGE) == -1)
767 					fatal("smtpd: chroot");
768 				if (chdir("/") == -1)
769 					fatal("smtpd: chdir");
770 				uid = env->sc_pw->pw_uid;
771 				gid = env->sc_pw->pw_gid;
772 				if (setgroups(1, &gid) ||
773 				    setresgid(gid, gid, gid) ||
774 				    setresuid(uid, uid, uid))
775 					fatal("smtpd: cannot drop privileges");
776 				rmtree("/", 1);
777 				_exit(0);
778 				break;
779 			default:
780 				break;
781 			}
782 		}
783 	}
784 
785 	evtimer_add(&purge_ev, &purge_timeout);
786 }
787 
788 static void
789 forkmda(struct imsgev *iev, u_int32_t id,
790     struct deliver *deliver)
791 {
792 	char		 ebuf[128], sfn[32];
793 	struct user_backend	*ub;
794 	struct delivery_backend	*db;
795 	struct mta_user u;
796 	struct child	*child;
797 	pid_t		 pid;
798 	int		 n, allout, pipefd[2];
799 
800 	log_debug("forkmda: to %s as %s", deliver->to, deliver->user);
801 
802 	bzero(&u, sizeof (u));
803 	ub = user_backend_lookup(USER_PWD);
804 	errno = 0;
805 	if (! ub->getbyname(&u, deliver->user)) {
806 		n = snprintf(ebuf, sizeof ebuf, "getpwnam: %s",
807 		    errno ? strerror(errno) : "no such user");
808 		imsg_compose_event(iev, IMSG_MDA_DONE, id, 0, -1, ebuf, n + 1);
809 		return;
810 	}
811 
812 	db = delivery_backend_lookup(deliver->mode);
813 	if (db == NULL)
814 		return;
815 
816 	/* lower privs early to allow fork fail due to ulimit */
817 	if (seteuid(u.uid) < 0)
818 		fatal("cannot lower privileges");
819 
820 	if (pipe(pipefd) < 0) {
821 		n = snprintf(ebuf, sizeof ebuf, "pipe: %s", strerror(errno));
822 		if (seteuid(0) < 0)
823 			fatal("forkmda: cannot restore privileges");
824 		imsg_compose_event(iev, IMSG_MDA_DONE, id, 0, -1, ebuf, n + 1);
825 		return;
826 	}
827 
828 	/* prepare file which captures stdout and stderr */
829 	strlcpy(sfn, "/tmp/smtpd.out.XXXXXXXXXXX", sizeof(sfn));
830 	allout = mkstemp(sfn);
831 	if (allout < 0) {
832 		n = snprintf(ebuf, sizeof ebuf, "mkstemp: %s", strerror(errno));
833 		if (seteuid(0) < 0)
834 			fatal("forkmda: cannot restore privileges");
835 		imsg_compose_event(iev, IMSG_MDA_DONE, id, 0, -1, ebuf, n + 1);
836 		close(pipefd[0]);
837 		close(pipefd[1]);
838 		return;
839 	}
840 	unlink(sfn);
841 
842 	pid = fork();
843 	if (pid < 0) {
844 		n = snprintf(ebuf, sizeof ebuf, "fork: %s", strerror(errno));
845 		if (seteuid(0) < 0)
846 			fatal("forkmda: cannot restore privileges");
847 		imsg_compose_event(iev, IMSG_MDA_DONE, id, 0, -1, ebuf, n + 1);
848 		close(pipefd[0]);
849 		close(pipefd[1]);
850 		close(allout);
851 		return;
852 	}
853 
854 	/* parent passes the child fd over to mda */
855 	if (pid > 0) {
856 		if (seteuid(0) < 0)
857 			fatal("forkmda: cannot restore privileges");
858 		child = child_add(pid, CHILD_MDA, -1);
859 		child->mda_out = allout;
860 		child->mda_id = id;
861 		close(pipefd[0]);
862 		imsg_compose_event(iev, IMSG_PARENT_FORK_MDA, id, 0, pipefd[1],
863 		    NULL, 0);
864 		return;
865 	}
866 
867 #define error(m) { perror(m); _exit(1); }
868 	if (seteuid(0) < 0)
869 		error("forkmda: cannot restore privileges");
870 	if (chdir(u.directory) < 0 && chdir("/") < 0)
871 		error("chdir");
872 	if (dup2(pipefd[0], STDIN_FILENO) < 0 ||
873 	    dup2(allout, STDOUT_FILENO) < 0 ||
874 	    dup2(allout, STDERR_FILENO) < 0)
875 		error("forkmda: dup2");
876 	if (closefrom(STDERR_FILENO + 1) < 0)
877 		error("closefrom");
878 	if (setgroups(1, &u.gid) ||
879 	    setresgid(u.gid, u.gid, u.gid) ||
880 	    setresuid(u.uid, u.uid, u.uid))
881 		error("forkmda: cannot drop privileges");
882 	if (setsid() < 0)
883 		error("setsid");
884 	if (signal(SIGPIPE, SIG_DFL) == SIG_ERR ||
885 	    signal(SIGINT, SIG_DFL) == SIG_ERR ||
886 	    signal(SIGTERM, SIG_DFL) == SIG_ERR ||
887 	    signal(SIGCHLD, SIG_DFL) == SIG_ERR ||
888 	    signal(SIGHUP, SIG_DFL) == SIG_ERR)
889 		error("signal");
890 
891 	/* avoid hangs by setting 5m timeout */
892 	alarm(300);
893 
894 	db->open(deliver);
895 
896 	error("forkmda: unknown mode");
897 }
898 #undef error
899 
900 static void
901 offline_scan(int fd, short ev, void *arg)
902 {
903 	DIR		*dir = arg;
904 	struct dirent	*d;
905 	int		 n = 0;
906 
907 	if (dir == NULL) {
908 		log_debug("smtpd: scanning offline queue...");
909 		if ((dir = opendir(PATH_SPOOL PATH_OFFLINE)) == NULL)
910 			errx(1, "smtpd: opendir");
911 	}
912 
913 	while((d = readdir(dir)) != NULL) {
914 		if (d->d_type != DT_REG)
915 			continue;
916 
917 		if (offline_add(d->d_name)) {
918 			log_warnx("smtpd: could not add offline message %s", d->d_name);
919 			continue;
920 		}
921 
922 		if ((n++) == OFFLINE_READMAX) {
923 			evtimer_set(&offline_ev, offline_scan, dir);
924 			offline_timeout.tv_sec = 0;
925 			offline_timeout.tv_usec = 100000;
926 			evtimer_add(&offline_ev, &offline_timeout);
927 			return;
928 		}
929 	}
930 
931 	log_debug("smtpd: offline scanning done");
932 	closedir(dir);
933 }
934 
935 static int
936 offline_enqueue(char *name)
937 {
938 	char		 t[MAXPATHLEN], *path;
939 	struct user_backend *ub;
940 	struct mta_user	 u;
941 	struct stat	 sb;
942 	pid_t		 pid;
943 	struct child	*child;
944 
945 	if (!bsnprintf(t, sizeof t, "%s/%s", PATH_SPOOL PATH_OFFLINE, name)) {
946 		log_warnx("smtpd: path name too long");
947 		return (-1);
948 	}
949 
950 	if ((path = strdup(t)) == NULL) {
951 		log_warn("smtpd: strdup");
952 		return (-1);
953 	}
954 
955 	log_debug("smtpd: enqueueing offline message %s", path);
956 
957 	if ((pid = fork()) == -1) {
958 		log_warn("smtpd: fork");
959 		free(path);
960 		return (-1);
961 	}
962 
963 	if (pid == 0) {
964 		char	*envp[2], *p, *tmp;
965 		FILE	*fp;
966 		size_t	 len;
967 		arglist	 args;
968 
969 		bzero(&args, sizeof(args));
970 
971 		if (lstat(path, &sb) == -1) {
972 			log_warn("smtpd: lstat: %s", path);
973 			_exit(1);
974 		}
975 
976 		if (chflags(path, 0) == -1) {
977 			log_warn("smtpd: chflags: %s", path);
978 			_exit(1);
979 		}
980 
981 		ub = user_backend_lookup(USER_PWD);
982 		bzero(&u, sizeof (u));
983 		errno = 0;
984 		if (! ub->getbyuid(&u, sb.st_uid)) {
985 			log_warnx("smtpd: getpwuid for uid %d failed",
986 			    sb.st_uid);
987 			_exit(1);
988 		}
989 
990 		if (! S_ISREG(sb.st_mode)) {
991 			log_warnx("smtpd: file %s (uid %d) not regular",
992 			    path, sb.st_uid);
993 			_exit(1);
994 		}
995 
996 		if (setgroups(1, &u.gid) ||
997 		    setresgid(u.gid, u.gid, u.gid) ||
998 		    setresuid(u.uid, u.uid, u.uid) ||
999 		    closefrom(STDERR_FILENO + 1) == -1)
1000 			_exit(1);
1001 
1002 		if ((fp = fopen(path, "r")) == NULL)
1003 			_exit(1);
1004 
1005 		if (chdir(u.directory) == -1 && chdir("/") == -1)
1006 			_exit(1);
1007 
1008 		if (setsid() == -1 ||
1009 		    signal(SIGPIPE, SIG_DFL) == SIG_ERR ||
1010 		    dup2(fileno(fp), STDIN_FILENO) == -1)
1011 			_exit(1);
1012 
1013 		if ((p = fgetln(fp, &len)) == NULL)
1014 			_exit(1);
1015 
1016 		if (p[len - 1] != '\n')
1017 			_exit(1);
1018 		p[len - 1] = '\0';
1019 
1020 		addargs(&args, "%s", "sendmail");
1021 
1022 		while ((tmp = strsep(&p, "|")) != NULL)
1023 			addargs(&args, "%s", tmp);
1024 
1025 		if (lseek(fileno(fp), len, SEEK_SET) == -1)
1026 			_exit(1);
1027 
1028 		envp[0] = "PATH=" _PATH_DEFPATH;
1029 		envp[1] = (char *)NULL;
1030 		environ = envp;
1031 
1032 		execvp(PATH_SMTPCTL, args.list);
1033 		_exit(1);
1034 	}
1035 
1036 	offline_running++;
1037 	child = child_add(pid, CHILD_ENQUEUE_OFFLINE, -1);
1038 	child->path = path;
1039 
1040 	return (0);
1041 }
1042 
1043 static int
1044 offline_add(char *path)
1045 {
1046 	struct offline	*q;
1047 
1048 	if (offline_running < OFFLINE_QUEUEMAX)
1049 		/* skip queue */
1050 		return offline_enqueue(path);
1051 
1052 	q = malloc(sizeof(*q) + strlen(path) + 1);
1053 	if (q == NULL)
1054 		return (-1);
1055 	q->path = (char *)q + sizeof(*q);
1056 	memmove(q->path, path, strlen(path) + 1);
1057 	TAILQ_INSERT_TAIL(&offline_q, q, entry);
1058 
1059 	return (0);
1060 }
1061 
1062 static void
1063 offline_done(void)
1064 {
1065 	struct offline	*q;
1066 
1067 	offline_running--;
1068 
1069 	while(offline_running < OFFLINE_QUEUEMAX) {
1070 		if ((q = TAILQ_FIRST(&offline_q)) == NULL)
1071 			break; /* all done */
1072 		TAILQ_REMOVE(&offline_q, q, entry);
1073 		offline_enqueue(q->path);
1074 		free(q);
1075 	}
1076 }
1077 
1078 static int
1079 parent_forward_open(char *username)
1080 {
1081 	struct user_backend *ub;
1082 	struct mta_user u;
1083 	char pathname[MAXPATHLEN];
1084 	int fd;
1085 
1086 	bzero(&u, sizeof (u));
1087 	ub = user_backend_lookup(USER_PWD);
1088 	if (! ub->getbyname(&u, username))
1089 		return -1;
1090 
1091 	if (! bsnprintf(pathname, sizeof (pathname), "%s/.forward", u.directory))
1092 		fatal("snprintf");
1093 
1094 	fd = open(pathname, O_RDONLY);
1095 	if (fd == -1) {
1096 		if (errno == ENOENT)
1097 			return -2;
1098 		log_warn("parent_forward_open: %s", pathname);
1099 		return -1;
1100 	}
1101 
1102 	if (! secure_file(fd, pathname, u.directory, u.uid, 1)) {
1103 		log_warnx("%s: unsecure file", pathname);
1104 		close(fd);
1105 		return -1;
1106 	}
1107 
1108 	return fd;
1109 }
1110 
1111 int
1112 child_cmp(struct child *c1, struct child *c2)
1113 {
1114 	if (c1->pid < c2->pid)
1115 		return (-1);
1116 
1117 	if (c1->pid > c2->pid)
1118 		return (1);
1119 
1120 	return (0);
1121 }
1122 
1123 void
1124 imsg_dispatch(int fd, short event, void *p)
1125 {
1126 	struct imsgev		*iev = p;
1127 	struct imsg		 imsg;
1128 	ssize_t			 n;
1129 
1130 	if (event & EV_READ) {
1131 		if ((n = imsg_read(&iev->ibuf)) == -1)
1132 			fatal("imsg_read");
1133 		if (n == 0) {
1134 			/* this pipe is dead, so remove the event handler */
1135 			event_del(&iev->ev);
1136 			event_loopexit(NULL);
1137 			return;
1138 		}
1139 	}
1140 
1141 	if (event & EV_WRITE) {
1142 		if (msgbuf_write(&iev->ibuf.w) == -1)
1143 			fatal("msgbuf_write");
1144 	}
1145 
1146 	for (;;) {
1147 		if ((n = imsg_get(&iev->ibuf, &imsg)) == -1)
1148 			fatal("imsg_get");
1149 		if (n == 0)
1150 			break;
1151 		imsg_callback(iev, &imsg);
1152 		imsg_free(&imsg);
1153 	}
1154 	imsg_event_add(iev);
1155 }
1156 
1157 SPLAY_GENERATE(childtree, child, entry, child_cmp);
1158 
1159 void
1160 log_imsg(int to, int from, struct imsg *imsg)
1161 {
1162 	log_trace(TRACE_IMSG, "imsg: %s <- %s: %s (len=%zu)",
1163 	    proc_to_str(to),
1164 	    proc_to_str(from),
1165 	    imsg_to_str(imsg->hdr.type),
1166 	    imsg->hdr.len - IMSG_HEADER_SIZE);
1167 }
1168 
1169 #define CASE(x) case x : return #x
1170 
1171 const char *
1172 proc_to_str(int proc)
1173 {
1174 	switch (proc) {
1175 	CASE(PROC_PARENT);
1176 	CASE(PROC_SMTP);
1177 	CASE(PROC_MFA);
1178 	CASE(PROC_LKA);
1179 	CASE(PROC_QUEUE);
1180 	CASE(PROC_MDA);
1181 	CASE(PROC_MTA);
1182 	CASE(PROC_CONTROL);
1183 	CASE(PROC_SCHEDULER);
1184 	default:
1185 		return "PROC_???";
1186 	}
1187 }
1188 
1189 const char *
1190 imsg_to_str(int type)
1191 {
1192 	static char	 buf[32];
1193 
1194 	switch(type) {
1195 	CASE(IMSG_NONE);
1196 	CASE(IMSG_CTL_OK);
1197 	CASE(IMSG_CTL_FAIL);
1198 	CASE(IMSG_CTL_SHUTDOWN);
1199 	CASE(IMSG_CTL_VERBOSE);
1200 	CASE(IMSG_CONF_START);
1201 	CASE(IMSG_CONF_SSL);
1202 	CASE(IMSG_CONF_LISTENER);
1203 	CASE(IMSG_CONF_MAP);
1204 	CASE(IMSG_CONF_MAP_CONTENT);
1205 	CASE(IMSG_CONF_RULE);
1206 	CASE(IMSG_CONF_RULE_SOURCE);
1207 	CASE(IMSG_CONF_FILTER);
1208 	CASE(IMSG_CONF_END);
1209 
1210 	CASE(IMSG_LKA_MAIL);
1211 	CASE(IMSG_LKA_RCPT);
1212 	CASE(IMSG_LKA_SECRET);
1213 	CASE(IMSG_LKA_RULEMATCH);
1214 	CASE(IMSG_MDA_SESS_NEW);
1215 	CASE(IMSG_MDA_DONE);
1216 
1217 	CASE(IMSG_MFA_CONNECT);
1218 	CASE(IMSG_MFA_HELO);
1219 	CASE(IMSG_MFA_MAIL);
1220 	CASE(IMSG_MFA_RCPT);
1221 	CASE(IMSG_MFA_DATALINE);
1222 	CASE(IMSG_MFA_QUIT);
1223 	CASE(IMSG_MFA_CLOSE);
1224 	CASE(IMSG_MFA_RSET);
1225 
1226 	CASE(IMSG_QUEUE_CREATE_MESSAGE);
1227 	CASE(IMSG_QUEUE_SUBMIT_ENVELOPE);
1228 	CASE(IMSG_QUEUE_COMMIT_ENVELOPES);
1229 	CASE(IMSG_QUEUE_REMOVE_MESSAGE);
1230 	CASE(IMSG_QUEUE_COMMIT_MESSAGE);
1231 	CASE(IMSG_QUEUE_TEMPFAIL);
1232 	CASE(IMSG_QUEUE_PAUSE_MDA);
1233 	CASE(IMSG_QUEUE_PAUSE_MTA);
1234 	CASE(IMSG_QUEUE_RESUME_MDA);
1235 	CASE(IMSG_QUEUE_RESUME_MTA);
1236 
1237 	CASE(IMSG_QUEUE_DELIVERY_OK);
1238 	CASE(IMSG_QUEUE_DELIVERY_TEMPFAIL);
1239 	CASE(IMSG_QUEUE_DELIVERY_PERMFAIL);
1240 
1241 	CASE(IMSG_QUEUE_MESSAGE_FD);
1242 	CASE(IMSG_QUEUE_MESSAGE_FILE);
1243 	CASE(IMSG_QUEUE_SCHEDULE);
1244 	CASE(IMSG_QUEUE_REMOVE);
1245 
1246 	CASE(IMSG_SCHEDULER_REMOVE);
1247 	CASE(IMSG_SCHEDULER_SCHEDULE);
1248 
1249 	CASE(IMSG_BATCH_CREATE);
1250 	CASE(IMSG_BATCH_APPEND);
1251 	CASE(IMSG_BATCH_CLOSE);
1252 	CASE(IMSG_BATCH_DONE);
1253 
1254 	CASE(IMSG_PARENT_FORWARD_OPEN);
1255 	CASE(IMSG_PARENT_FORK_MDA);
1256 
1257 	CASE(IMSG_PARENT_AUTHENTICATE);
1258 	CASE(IMSG_PARENT_SEND_CONFIG);
1259 
1260 	CASE(IMSG_STATS);
1261 	CASE(IMSG_SMTP_ENQUEUE);
1262 	CASE(IMSG_SMTP_PAUSE);
1263 	CASE(IMSG_SMTP_RESUME);
1264 
1265 	CASE(IMSG_DNS_HOST);
1266 	CASE(IMSG_DNS_HOST_END);
1267 	CASE(IMSG_DNS_MX);
1268 	CASE(IMSG_DNS_PTR);
1269 	default:
1270 		snprintf(buf, sizeof(buf), "IMSG_??? (%d)", type);
1271 
1272 		return buf;
1273 	}
1274 }
1275