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