1 /* $OpenBSD: smtpd.c,v 1.130 2011/09/01 19:56:49 eric 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 <err.h> 32 #include <errno.h> 33 #include <fcntl.h> 34 #include <event.h> 35 #include <imsg.h> 36 #include <paths.h> 37 #include <pwd.h> 38 #include <signal.h> 39 #include <stdio.h> 40 #include <stdlib.h> 41 #include <string.h> 42 #include <time.h> 43 #include <unistd.h> 44 45 #include "smtpd.h" 46 #include "log.h" 47 48 static void parent_imsg(struct imsgev *, struct imsg *); 49 static void usage(void); 50 static void parent_shutdown(void); 51 static void parent_send_config(int, short, void *); 52 static void parent_send_config_listeners(void); 53 static void parent_send_config_client_certs(void); 54 static void parent_send_config_ruleset(int); 55 static void parent_sig_handler(int, short, void *); 56 static void forkmda(struct imsgev *, u_int32_t, struct deliver *); 57 static int parent_enqueue_offline(char *); 58 static int parent_forward_open(char *); 59 static int path_starts_with(char *, char *); 60 static void fork_peers(void); 61 static struct child *child_lookup(pid_t); 62 static struct child *child_add(pid_t, int, int); 63 static void child_del(pid_t); 64 65 static int queueing_add(char *); 66 static void queueing_done(void); 67 68 struct queueing { 69 TAILQ_ENTRY(queueing) entry; 70 char *path; 71 }; 72 73 #define QUEUEING_MAX 5 74 static size_t queueing_running = 0; 75 TAILQ_HEAD(, queueing) queueing_q; 76 77 extern char **environ; 78 void (*imsg_callback)(struct imsgev *, struct imsg *); 79 80 struct smtpd *env = NULL; 81 82 int __b64_pton(char const *, unsigned char *, size_t); 83 84 static void 85 parent_imsg(struct imsgev *iev, struct imsg *imsg) 86 { 87 struct forward_req *fwreq; 88 struct auth *auth; 89 struct auth_backend *auth_backend; 90 int fd; 91 92 if (iev->proc == PROC_SMTP) { 93 switch (imsg->hdr.type) { 94 case IMSG_PARENT_SEND_CONFIG: 95 parent_send_config_listeners(); 96 return; 97 98 case IMSG_PARENT_AUTHENTICATE: 99 auth_backend = auth_backend_lookup(AUTH_BSD); 100 auth = imsg->data; 101 auth->success = auth_backend->authenticate(auth->user, 102 auth->pass); 103 imsg_compose_event(iev, IMSG_PARENT_AUTHENTICATE, 0, 0, 104 -1, auth, sizeof *auth); 105 return; 106 } 107 } 108 109 if (iev->proc == PROC_LKA) { 110 switch (imsg->hdr.type) { 111 case IMSG_PARENT_FORWARD_OPEN: 112 fwreq = imsg->data; 113 fd = parent_forward_open(fwreq->as_user); 114 fwreq->status = 0; 115 if (fd == -2) { 116 /* no ~/.forward, however it's optional. */ 117 fwreq->status = 1; 118 fd = -1; 119 } else if (fd != -1) 120 fwreq->status = 1; 121 imsg_compose_event(iev, IMSG_PARENT_FORWARD_OPEN, 0, 0, 122 fd, fwreq, sizeof *fwreq); 123 return; 124 } 125 } 126 127 if (iev->proc == PROC_QUEUE) { 128 switch (imsg->hdr.type) { 129 case IMSG_PARENT_ENQUEUE_OFFLINE: 130 if (! queueing_add(imsg->data)) 131 imsg_compose_event(iev, 132 IMSG_PARENT_ENQUEUE_OFFLINE, 0, 0, -1, 133 NULL, 0); 134 return; 135 } 136 } 137 138 if (iev->proc == PROC_MDA) { 139 switch (imsg->hdr.type) { 140 case IMSG_PARENT_FORK_MDA: 141 forkmda(iev, imsg->hdr.peerid, imsg->data); 142 return; 143 } 144 } 145 146 if (iev->proc == PROC_CONTROL) { 147 switch (imsg->hdr.type) { 148 case IMSG_CTL_VERBOSE: 149 log_verbose(*(int *)imsg->data); 150 151 /* forward to other processes */ 152 imsg_compose_event(env->sc_ievs[PROC_LKA], IMSG_CTL_VERBOSE, 153 0, 0, -1, imsg->data, sizeof(int)); 154 imsg_compose_event(env->sc_ievs[PROC_MDA], IMSG_CTL_VERBOSE, 155 0, 0, -1, imsg->data, sizeof(int)); 156 imsg_compose_event(env->sc_ievs[PROC_MFA], IMSG_CTL_VERBOSE, 157 0, 0, -1, imsg->data, sizeof(int)); 158 imsg_compose_event(env->sc_ievs[PROC_MTA], IMSG_CTL_VERBOSE, 159 0, 0, -1, imsg->data, sizeof(int)); 160 imsg_compose_event(env->sc_ievs[PROC_QUEUE], IMSG_CTL_VERBOSE, 161 0, 0, -1, imsg->data, sizeof(int)); 162 imsg_compose_event(env->sc_ievs[PROC_SMTP], IMSG_CTL_VERBOSE, 163 0, 0, -1, imsg->data, sizeof(int)); 164 return; 165 } 166 } 167 168 fatalx("parent_imsg: unexpected imsg"); 169 } 170 171 static void 172 usage(void) 173 { 174 extern char *__progname; 175 176 fprintf(stderr, "usage: %s [-dnv] [-D macro=value] " 177 "[-f file]\n", __progname); 178 exit(1); 179 } 180 181 static void 182 parent_shutdown(void) 183 { 184 struct child *child; 185 pid_t pid; 186 187 SPLAY_FOREACH(child, childtree, &env->children) 188 if (child->type == CHILD_DAEMON) 189 kill(child->pid, SIGTERM); 190 191 do { 192 pid = waitpid(WAIT_MYPGRP, NULL, 0); 193 } while (pid != -1 || (pid == -1 && errno == EINTR)); 194 195 log_warnx("parent terminating"); 196 exit(0); 197 } 198 199 static void 200 parent_send_config(int fd, short event, void *p) 201 { 202 parent_send_config_listeners(); 203 parent_send_config_client_certs(); 204 parent_send_config_ruleset(PROC_MFA); 205 parent_send_config_ruleset(PROC_LKA); 206 } 207 208 static void 209 parent_send_config_listeners(void) 210 { 211 struct listener *l; 212 struct ssl *s; 213 struct iovec iov[4]; 214 int opt; 215 216 log_debug("parent_send_config: configuring smtp"); 217 imsg_compose_event(env->sc_ievs[PROC_SMTP], IMSG_CONF_START, 218 0, 0, -1, NULL, 0); 219 220 SPLAY_FOREACH(s, ssltree, env->sc_ssl) { 221 if (!(s->flags & F_SCERT)) 222 continue; 223 224 iov[0].iov_base = s; 225 iov[0].iov_len = sizeof(*s); 226 iov[1].iov_base = s->ssl_cert; 227 iov[1].iov_len = s->ssl_cert_len; 228 iov[2].iov_base = s->ssl_key; 229 iov[2].iov_len = s->ssl_key_len; 230 iov[3].iov_base = s->ssl_dhparams; 231 iov[3].iov_len = s->ssl_dhparams_len; 232 233 imsg_composev(&env->sc_ievs[PROC_SMTP]->ibuf, 234 IMSG_CONF_SSL, 0, 0, -1, iov, nitems(iov)); 235 imsg_event_add(env->sc_ievs[PROC_SMTP]); 236 } 237 238 TAILQ_FOREACH(l, env->sc_listeners, entry) { 239 if ((l->fd = socket(l->ss.ss_family, SOCK_STREAM, 0)) == -1) 240 fatal("socket"); 241 opt = 1; 242 if (setsockopt(l->fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) 243 fatal("setsockopt"); 244 if (bind(l->fd, (struct sockaddr *)&l->ss, l->ss.ss_len) == -1) 245 fatal("bind"); 246 imsg_compose_event(env->sc_ievs[PROC_SMTP], IMSG_CONF_LISTENER, 247 0, 0, l->fd, l, sizeof(*l)); 248 } 249 250 imsg_compose_event(env->sc_ievs[PROC_SMTP], IMSG_CONF_END, 251 0, 0, -1, NULL, 0); 252 } 253 254 static void 255 parent_send_config_client_certs(void) 256 { 257 struct ssl *s; 258 struct iovec iov[4]; 259 260 log_debug("parent_send_config_client_certs: configuring smtp"); 261 imsg_compose_event(env->sc_ievs[PROC_MTA], IMSG_CONF_START, 262 0, 0, -1, NULL, 0); 263 264 SPLAY_FOREACH(s, ssltree, env->sc_ssl) { 265 if (!(s->flags & F_CCERT)) 266 continue; 267 268 iov[0].iov_base = s; 269 iov[0].iov_len = sizeof(*s); 270 iov[1].iov_base = s->ssl_cert; 271 iov[1].iov_len = s->ssl_cert_len; 272 iov[2].iov_base = s->ssl_key; 273 iov[2].iov_len = s->ssl_key_len; 274 iov[3].iov_base = s->ssl_dhparams; 275 iov[3].iov_len = s->ssl_dhparams_len; 276 277 imsg_composev(&env->sc_ievs[PROC_MTA]->ibuf, IMSG_CONF_SSL, 278 0, 0, -1, iov, nitems(iov)); 279 imsg_event_add(env->sc_ievs[PROC_MTA]); 280 } 281 282 imsg_compose_event(env->sc_ievs[PROC_MTA], IMSG_CONF_END, 283 0, 0, -1, NULL, 0); 284 } 285 286 void 287 parent_send_config_ruleset(int proc) 288 { 289 struct rule *r; 290 struct map *m; 291 struct mapel *mapel; 292 struct filter *f; 293 294 log_debug("parent_send_config_ruleset: reloading rules and maps"); 295 imsg_compose_event(env->sc_ievs[proc], IMSG_CONF_START, 296 0, 0, -1, NULL, 0); 297 298 if (proc == PROC_MFA) { 299 TAILQ_FOREACH(f, env->sc_filters, f_entry) { 300 imsg_compose_event(env->sc_ievs[proc], IMSG_CONF_FILTER, 301 0, 0, -1, f, sizeof(*f)); 302 } 303 } 304 else { 305 TAILQ_FOREACH(m, env->sc_maps, m_entry) { 306 imsg_compose_event(env->sc_ievs[proc], IMSG_CONF_MAP, 307 0, 0, -1, m, sizeof(*m)); 308 TAILQ_FOREACH(mapel, &m->m_contents, me_entry) { 309 imsg_compose_event(env->sc_ievs[proc], IMSG_CONF_MAP_CONTENT, 310 0, 0, -1, mapel, sizeof(*mapel)); 311 } 312 } 313 314 TAILQ_FOREACH(r, env->sc_rules, r_entry) { 315 imsg_compose_event(env->sc_ievs[proc], IMSG_CONF_RULE, 316 0, 0, -1, r, sizeof(*r)); 317 imsg_compose_event(env->sc_ievs[proc], IMSG_CONF_RULE_SOURCE, 318 0, 0, -1, &r->r_sources->m_name, sizeof(r->r_sources->m_name)); 319 } 320 } 321 322 imsg_compose_event(env->sc_ievs[proc], IMSG_CONF_END, 323 0, 0, -1, NULL, 0); 324 } 325 326 static void 327 parent_sig_handler(int sig, short event, void *p) 328 { 329 struct child *child; 330 int die = 0, status, fail; 331 pid_t pid; 332 char *cause; 333 334 switch (sig) { 335 case SIGTERM: 336 case SIGINT: 337 die = 1; 338 /* FALLTHROUGH */ 339 case SIGCHLD: 340 do { 341 pid = waitpid(-1, &status, WNOHANG); 342 if (pid <= 0) 343 continue; 344 345 child = child_lookup(pid); 346 if (child == NULL) 347 fatalx("unexpected SIGCHLD"); 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 switch (child->type) { 364 case CHILD_DAEMON: 365 die = 1; 366 if (fail) 367 log_warnx("lost child: %s %s", 368 env->sc_title[child->title], cause); 369 break; 370 371 case CHILD_MDA: 372 if (WIFSIGNALED(status) && 373 WTERMSIG(status) == SIGALRM) { 374 free(cause); 375 asprintf(&cause, "terminated; timeout"); 376 } 377 imsg_compose_event(env->sc_ievs[PROC_MDA], 378 IMSG_MDA_DONE, child->mda_id, 0, 379 child->mda_out, cause, strlen(cause) + 1); 380 break; 381 382 case CHILD_ENQUEUE_OFFLINE: 383 if (fail) 384 log_warnx("couldn't enqueue offline " 385 "message; smtpctl %s", cause); 386 else 387 log_debug("offline message enqueued"); 388 imsg_compose_event(env->sc_ievs[PROC_QUEUE], 389 IMSG_PARENT_ENQUEUE_OFFLINE, 0, 0, -1, 390 NULL, 0); 391 queueing_done(); 392 break; 393 394 default: 395 fatalx("unexpected child type"); 396 } 397 398 child_del(child->pid); 399 free(cause); 400 } while (pid > 0 || (pid == -1 && errno == EINTR)); 401 402 if (die) 403 parent_shutdown(); 404 break; 405 default: 406 fatalx("unexpected signal"); 407 } 408 } 409 410 int 411 main(int argc, char *argv[]) 412 { 413 int c; 414 int debug, verbose; 415 int opts; 416 const char *conffile = CONF_FILE; 417 struct smtpd smtpd; 418 struct event ev_sigint; 419 struct event ev_sigterm; 420 struct event ev_sigchld; 421 struct event ev_sighup; 422 struct timeval tv; 423 struct peer peers[] = { 424 { PROC_CONTROL, imsg_dispatch }, 425 { PROC_LKA, imsg_dispatch }, 426 { PROC_MDA, imsg_dispatch }, 427 { PROC_MFA, imsg_dispatch }, 428 { PROC_MTA, imsg_dispatch }, 429 { PROC_SMTP, imsg_dispatch }, 430 { PROC_QUEUE, imsg_dispatch } 431 }; 432 433 env = &smtpd; 434 435 opts = 0; 436 debug = 0; 437 verbose = 0; 438 439 log_init(1); 440 441 TAILQ_INIT(&queueing_q); 442 443 while ((c = getopt(argc, argv, "dD:nf:v")) != -1) { 444 switch (c) { 445 case 'd': 446 debug = 2; 447 verbose = 1; 448 break; 449 case 'D': 450 if (cmdline_symset(optarg) < 0) 451 log_warnx("could not parse macro definition %s", 452 optarg); 453 break; 454 case 'n': 455 debug = 2; 456 opts |= SMTPD_OPT_NOACTION; 457 break; 458 case 'f': 459 conffile = optarg; 460 break; 461 case 'v': 462 verbose = 1; 463 opts |= SMTPD_OPT_VERBOSE; 464 break; 465 default: 466 usage(); 467 } 468 } 469 470 argv += optind; 471 argc -= optind; 472 473 if (parse_config(&smtpd, conffile, opts)) 474 exit(1); 475 476 if (strlcpy(env->sc_conffile, conffile, MAXPATHLEN) >= MAXPATHLEN) 477 errx(1, "config file exceeds MAXPATHLEN"); 478 479 480 if (env->sc_opts & SMTPD_OPT_NOACTION) { 481 fprintf(stderr, "configuration OK\n"); 482 exit(0); 483 } 484 485 /* check for root privileges */ 486 if (geteuid()) 487 errx(1, "need root privileges"); 488 489 if ((env->sc_pw = getpwnam(SMTPD_USER)) == NULL) 490 errx(1, "unknown user %s", SMTPD_USER); 491 492 env->sc_queue = queue_backend_lookup(QT_FS); 493 if (env->sc_queue == NULL) 494 errx(1, "could not find queue backend"); 495 496 if (!env->sc_queue->init()) 497 errx(1, "invalid directory permissions"); 498 499 log_init(debug); 500 log_verbose(verbose); 501 502 if (!debug) 503 if (daemon(0, 0) == -1) 504 err(1, "failed to daemonize"); 505 506 log_info("startup%s", (debug > 1)?" [debug mode]":""); 507 508 if (env->sc_hostname[0] == '\0') 509 errx(1, "machine does not have a hostname set"); 510 511 env->stats = mmap(NULL, sizeof(struct stats), PROT_WRITE|PROT_READ, 512 MAP_ANON|MAP_SHARED, -1, (off_t)0); 513 if (env->stats == MAP_FAILED) 514 fatal("mmap"); 515 bzero(env->stats, sizeof(struct stats)); 516 stat_init(env->stats->counters, STATS_MAX); 517 518 env->stats->parent.start = time(NULL); 519 520 fork_peers(); 521 522 imsg_callback = parent_imsg; 523 event_init(); 524 525 signal_set(&ev_sigint, SIGINT, parent_sig_handler, NULL); 526 signal_set(&ev_sigterm, SIGTERM, parent_sig_handler, NULL); 527 signal_set(&ev_sigchld, SIGCHLD, parent_sig_handler, NULL); 528 signal_set(&ev_sighup, SIGHUP, parent_sig_handler, NULL); 529 signal_add(&ev_sigint, NULL); 530 signal_add(&ev_sigterm, NULL); 531 signal_add(&ev_sigchld, NULL); 532 signal_add(&ev_sighup, NULL); 533 signal(SIGPIPE, SIG_IGN); 534 535 config_pipes(peers, nitems(peers)); 536 config_peers(peers, nitems(peers)); 537 538 evtimer_set(&env->sc_ev, parent_send_config, NULL); 539 bzero(&tv, sizeof(tv)); 540 evtimer_add(&env->sc_ev, &tv); 541 542 if (event_dispatch() < 0) 543 fatal("event_dispatch"); 544 545 return (0); 546 } 547 548 static void 549 fork_peers(void) 550 { 551 SPLAY_INIT(&env->children); 552 553 /* 554 * Pick descriptor limit that will guarantee impossibility of fd 555 * starvation condition. The logic: 556 * 557 * Treat hardlimit as 100%. 558 * Limit smtp to 50% (inbound connections) 559 * Limit mta to 50% (outbound connections) 560 * Limit mda to 50% (local deliveries) 561 * In all three above, compute max session limit by halving the fd 562 * limit (50% -> 25%), because each session costs two fds. 563 * Limit queue to 100% to cover the extreme case when tons of fds are 564 * opened for all four possible purposes (smtp, mta, mda, bounce) 565 */ 566 fdlimit(0.5); 567 568 env->sc_instances[PROC_CONTROL] = 1; 569 env->sc_instances[PROC_LKA] = 1; 570 env->sc_instances[PROC_MDA] = 1; 571 env->sc_instances[PROC_MFA] = 1; 572 env->sc_instances[PROC_MTA] = 1; 573 env->sc_instances[PROC_PARENT] = 1; 574 env->sc_instances[PROC_QUEUE] = 1; 575 env->sc_instances[PROC_RUNNER] = 1; 576 env->sc_instances[PROC_SMTP] = 1; 577 578 init_pipes(); 579 580 env->sc_title[PROC_CONTROL] = "control"; 581 env->sc_title[PROC_LKA] = "lookup agent"; 582 env->sc_title[PROC_MDA] = "mail delivery agent"; 583 env->sc_title[PROC_MFA] = "mail filter agent"; 584 env->sc_title[PROC_MTA] = "mail transfer agent"; 585 env->sc_title[PROC_QUEUE] = "queue"; 586 env->sc_title[PROC_RUNNER] = "runner"; 587 env->sc_title[PROC_SMTP] = "smtp server"; 588 589 child_add(control(), CHILD_DAEMON, PROC_CONTROL); 590 child_add(lka(), CHILD_DAEMON, PROC_LKA); 591 child_add(mda(), CHILD_DAEMON, PROC_MDA); 592 child_add(mfa(), CHILD_DAEMON, PROC_MFA); 593 child_add(mta(), CHILD_DAEMON, PROC_MTA); 594 child_add(queue(), CHILD_DAEMON, PROC_QUEUE); 595 child_add(runner(), CHILD_DAEMON, PROC_RUNNER); 596 child_add(smtp(), CHILD_DAEMON, PROC_SMTP); 597 598 setproctitle("[priv]"); 599 } 600 601 struct child * 602 child_add(pid_t pid, int type, int title) 603 { 604 struct child *child; 605 606 if ((child = calloc(1, sizeof(*child))) == NULL) 607 fatal(NULL); 608 609 child->pid = pid; 610 child->type = type; 611 child->title = title; 612 613 if (SPLAY_INSERT(childtree, &env->children, child) != NULL) 614 fatalx("child_add: double insert"); 615 616 return (child); 617 } 618 619 static void 620 child_del(pid_t pid) 621 { 622 struct child *p; 623 624 p = child_lookup(pid); 625 if (p == NULL) 626 fatalx("child_del: unknown child"); 627 628 if (SPLAY_REMOVE(childtree, &env->children, p) == NULL) 629 fatalx("child_del: tree remove failed"); 630 free(p); 631 } 632 633 static struct child * 634 child_lookup(pid_t pid) 635 { 636 struct child key; 637 638 key.pid = pid; 639 return SPLAY_FIND(childtree, &env->children, &key); 640 } 641 642 void 643 imsg_event_add(struct imsgev *iev) 644 { 645 if (iev->handler == NULL) { 646 imsg_flush(&iev->ibuf); 647 return; 648 } 649 650 iev->events = EV_READ; 651 if (iev->ibuf.w.queued) 652 iev->events |= EV_WRITE; 653 654 event_del(&iev->ev); 655 event_set(&iev->ev, iev->ibuf.fd, iev->events, iev->handler, iev->data); 656 event_add(&iev->ev, NULL); 657 } 658 659 void 660 imsg_compose_event(struct imsgev *iev, u_int16_t type, u_int32_t peerid, 661 pid_t pid, int fd, void *data, u_int16_t datalen) 662 { 663 if (imsg_compose(&iev->ibuf, type, peerid, pid, fd, data, datalen) == -1) 664 fatal("imsg_compose_event"); 665 imsg_event_add(iev); 666 } 667 668 static void 669 forkmda(struct imsgev *iev, u_int32_t id, 670 struct deliver *deliver) 671 { 672 char ebuf[128], sfn[32]; 673 struct user_backend *ub; 674 struct user u; 675 struct child *child; 676 pid_t pid; 677 int n, allout, pipefd[2]; 678 679 log_debug("forkmda: to %s as %s", deliver->to, deliver->user); 680 681 bzero(&u, sizeof (u)); 682 ub = user_backend_lookup(USER_GETPWNAM); 683 errno = 0; 684 if (! ub->getbyname(&u, deliver->user)) { 685 n = snprintf(ebuf, sizeof ebuf, "getpwnam: %s", 686 errno ? strerror(errno) : "no such user"); 687 imsg_compose_event(iev, IMSG_MDA_DONE, id, 0, -1, ebuf, n + 1); 688 return; 689 } 690 691 /* lower privs early to allow fork fail due to ulimit */ 692 if (seteuid(u.uid) < 0) 693 fatal("cannot lower privileges"); 694 695 if (pipe(pipefd) < 0) { 696 n = snprintf(ebuf, sizeof ebuf, "pipe: %s", strerror(errno)); 697 if (seteuid(0) < 0) 698 fatal("forkmda: cannot restore privileges"); 699 imsg_compose_event(iev, IMSG_MDA_DONE, id, 0, -1, ebuf, n + 1); 700 return; 701 } 702 703 /* prepare file which captures stdout and stderr */ 704 strlcpy(sfn, "/tmp/smtpd.out.XXXXXXXXXXX", sizeof(sfn)); 705 allout = mkstemp(sfn); 706 if (allout < 0) { 707 n = snprintf(ebuf, sizeof ebuf, "mkstemp: %s", strerror(errno)); 708 if (seteuid(0) < 0) 709 fatal("forkmda: cannot restore privileges"); 710 imsg_compose_event(iev, IMSG_MDA_DONE, id, 0, -1, ebuf, n + 1); 711 close(pipefd[0]); 712 close(pipefd[1]); 713 return; 714 } 715 unlink(sfn); 716 717 pid = fork(); 718 if (pid < 0) { 719 n = snprintf(ebuf, sizeof ebuf, "fork: %s", strerror(errno)); 720 if (seteuid(0) < 0) 721 fatal("forkmda: cannot restore privileges"); 722 imsg_compose_event(iev, IMSG_MDA_DONE, id, 0, -1, ebuf, n + 1); 723 close(pipefd[0]); 724 close(pipefd[1]); 725 close(allout); 726 return; 727 } 728 729 /* parent passes the child fd over to mda */ 730 if (pid > 0) { 731 if (seteuid(0) < 0) 732 fatal("forkmda: cannot restore privileges"); 733 child = child_add(pid, CHILD_MDA, -1); 734 child->mda_out = allout; 735 child->mda_id = id; 736 close(pipefd[0]); 737 imsg_compose_event(iev, IMSG_PARENT_FORK_MDA, id, 0, pipefd[1], 738 NULL, 0); 739 return; 740 } 741 742 #define error(m) { perror(m); _exit(1); } 743 if (seteuid(0) < 0) 744 error("forkmda: cannot restore privileges"); 745 if (chdir(u.directory) < 0 && chdir("/") < 0) 746 error("chdir"); 747 if (dup2(pipefd[0], STDIN_FILENO) < 0 || 748 dup2(allout, STDOUT_FILENO) < 0 || 749 dup2(allout, STDERR_FILENO) < 0) 750 error("forkmda: dup2"); 751 if (closefrom(STDERR_FILENO + 1) < 0) 752 error("closefrom"); 753 if (setgroups(1, &u.gid) || 754 setresgid(u.gid, u.gid, u.gid) || 755 setresuid(u.uid, u.uid, u.uid)) 756 error("forkmda: cannot drop privileges"); 757 if (setsid() < 0) 758 error("setsid"); 759 if (signal(SIGPIPE, SIG_DFL) == SIG_ERR || 760 signal(SIGINT, SIG_DFL) == SIG_ERR || 761 signal(SIGTERM, SIG_DFL) == SIG_ERR || 762 signal(SIGCHLD, SIG_DFL) == SIG_ERR || 763 signal(SIGHUP, SIG_DFL) == SIG_ERR) 764 error("signal"); 765 766 /* avoid hangs by setting 5m timeout */ 767 alarm(300); 768 769 if (deliver->mode == A_EXT) { 770 char *environ_new[2]; 771 772 environ_new[0] = "PATH=" _PATH_DEFPATH; 773 environ_new[1] = (char *)NULL; 774 environ = environ_new; 775 execle("/bin/sh", "/bin/sh", "-c", deliver->to, (char *)NULL, 776 environ_new); 777 error("execle"); 778 } 779 780 if (deliver->mode == A_MAILDIR) { 781 char tmp[PATH_MAX], new[PATH_MAX]; 782 int ch, fd; 783 FILE *fp; 784 785 #define error2(m) { n = errno; unlink(tmp); errno = n; error(m); } 786 setproctitle("maildir delivery"); 787 if (mkdir(deliver->to, 0700) < 0 && errno != EEXIST) 788 error("cannot mkdir maildir"); 789 if (chdir(deliver->to) < 0) 790 error("cannot cd to maildir"); 791 if (mkdir("cur", 0700) < 0 && errno != EEXIST) 792 error("mkdir cur failed"); 793 if (mkdir("tmp", 0700) < 0 && errno != EEXIST) 794 error("mkdir tmp failed"); 795 if (mkdir("new", 0700) < 0 && errno != EEXIST) 796 error("mkdir new failed"); 797 snprintf(tmp, sizeof tmp, "tmp/%lld.%d.%s", 798 (long long int) time(NULL), 799 getpid(), env->sc_hostname); 800 fd = open(tmp, O_CREAT | O_EXCL | O_WRONLY, 0600); 801 if (fd < 0) 802 error("cannot open tmp file"); 803 fp = fdopen(fd, "w"); 804 if (fp == NULL) 805 error2("fdopen"); 806 while ((ch = getc(stdin)) != EOF) 807 if (putc(ch, fp) == EOF) 808 break; 809 if (ferror(stdin)) 810 error2("read error"); 811 if (fflush(fp) == EOF || ferror(fp)) 812 error2("write error"); 813 if (fsync(fd) < 0) 814 error2("fsync"); 815 if (fclose(fp) == EOF) 816 error2("fclose"); 817 snprintf(new, sizeof new, "new/%s", tmp + 4); 818 if (rename(tmp, new) < 0) 819 error2("cannot rename tmp->new"); 820 _exit(0); 821 } 822 #undef error2 823 824 if (deliver->mode == A_FILENAME) { 825 struct stat sb; 826 time_t now; 827 size_t len; 828 int fd; 829 FILE *fp; 830 char *ln; 831 832 #define error2(m) { n = errno; ftruncate(fd, sb.st_size); errno = n; error(m); } 833 setproctitle("file delivery"); 834 fd = open(deliver->to, O_CREAT | O_APPEND | O_WRONLY, 0600); 835 if (fd < 0) 836 error("open"); 837 if (fstat(fd, &sb) < 0) 838 error("fstat"); 839 if (S_ISREG(sb.st_mode) && flock(fd, LOCK_EX) < 0) 840 error("flock"); 841 fp = fdopen(fd, "a"); 842 if (fp == NULL) 843 error("fdopen"); 844 time(&now); 845 fprintf(fp, "From %s@%s %s", SMTPD_USER, env->sc_hostname, 846 ctime(&now)); 847 while ((ln = fgetln(stdin, &len)) != NULL) { 848 if (ln[len - 1] == '\n') 849 len--; 850 if (len >= 5 && memcmp(ln, "From ", 5) == 0) 851 putc('>', fp); 852 fprintf(fp, "%.*s\n", (int)len, ln); 853 if (ferror(fp)) 854 break; 855 } 856 if (ferror(stdin)) 857 error2("read error"); 858 putc('\n', fp); 859 if (fflush(fp) == EOF || ferror(fp)) 860 error2("write error"); 861 if (fsync(fd) < 0) 862 error2("fsync"); 863 if (fclose(fp) == EOF) 864 error2("fclose"); 865 _exit(0); 866 } 867 868 error("forkmda: unknown mode"); 869 } 870 #undef error 871 #undef error2 872 873 static int 874 parent_enqueue_offline(char *runner_path) 875 { 876 char path[MAXPATHLEN]; 877 struct user_backend *ub; 878 struct user u; 879 struct stat sb; 880 pid_t pid; 881 882 log_debug("parent_enqueue_offline: path %s", runner_path); 883 884 if (! bsnprintf(path, sizeof(path), "%s%s", PATH_SPOOL, runner_path)) 885 fatalx("parent_enqueue_offline: filename too long"); 886 887 if (! path_starts_with(path, PATH_SPOOL PATH_OFFLINE)) 888 fatalx("parent_enqueue_offline: path outside offline dir"); 889 890 if (lstat(path, &sb) == -1) { 891 if (errno == ENOENT) { 892 log_warn("parent_enqueue_offline: %s", path); 893 return (0); 894 } 895 fatal("parent_enqueue_offline: lstat"); 896 } 897 898 if (chflags(path, 0) == -1) { 899 if (errno == ENOENT) { 900 log_warn("parent_enqueue_offline: %s", path); 901 return (0); 902 } 903 fatal("parent_enqueue_offline: chflags"); 904 } 905 906 ub = user_backend_lookup(USER_GETPWNAM); 907 bzero(&u, sizeof (u)); 908 errno = 0; 909 if (! ub->getbyuid(&u, sb.st_uid)) { 910 log_warn("parent_enqueue_offline: getpwuid for uid %d failed", 911 sb.st_uid); 912 unlink(path); 913 return (0); 914 } 915 916 if (! S_ISREG(sb.st_mode)) { 917 log_warnx("file %s (uid %d) not regular, removing", path, sb.st_uid); 918 if (S_ISDIR(sb.st_mode)) 919 rmdir(path); 920 else 921 unlink(path); 922 return (0); 923 } 924 925 if ((pid = fork()) == -1) 926 fatal("parent_enqueue_offline: fork"); 927 928 if (pid == 0) { 929 char *envp[2], *p, *tmp; 930 FILE *fp; 931 size_t len; 932 arglist args; 933 934 bzero(&args, sizeof(args)); 935 936 if (setgroups(1, &u.gid) || 937 setresgid(u.gid, u.gid, u.gid) || 938 setresuid(u.uid, u.uid, u.uid) || 939 closefrom(STDERR_FILENO + 1) == -1) { 940 unlink(path); 941 _exit(1); 942 } 943 944 if ((fp = fopen(path, "r")) == NULL) { 945 unlink(path); 946 _exit(1); 947 } 948 unlink(path); 949 950 if (chdir(u.directory) == -1 && chdir("/") == -1) 951 _exit(1); 952 953 if (setsid() == -1 || 954 signal(SIGPIPE, SIG_DFL) == SIG_ERR || 955 dup2(fileno(fp), STDIN_FILENO) == -1) 956 _exit(1); 957 958 if ((p = fgetln(fp, &len)) == NULL) 959 _exit(1); 960 961 if (p[len - 1] != '\n') 962 _exit(1); 963 p[len - 1] = '\0'; 964 965 addargs(&args, "%s", "sendmail"); 966 967 while ((tmp = strsep(&p, "|")) != NULL) 968 addargs(&args, "%s", tmp); 969 970 if (lseek(fileno(fp), len, SEEK_SET) == -1) 971 _exit(1); 972 973 envp[0] = "PATH=" _PATH_DEFPATH; 974 envp[1] = (char *)NULL; 975 environ = envp; 976 977 execvp(PATH_SMTPCTL, args.list); 978 _exit(1); 979 } 980 981 queueing_running++; 982 child_add(pid, CHILD_ENQUEUE_OFFLINE, -1); 983 984 return (1); 985 } 986 987 static int 988 queueing_add(char *path) 989 { 990 struct queueing *q; 991 992 if (queueing_running < QUEUEING_MAX) 993 /* skip queue */ 994 return parent_enqueue_offline(path); 995 996 q = malloc(sizeof(*q) + strlen(path) + 1); 997 if (q == NULL) 998 return (-1); 999 q->path = (char *)q + sizeof(*q); 1000 memmove(q->path, path, strlen(path) + 1); 1001 TAILQ_INSERT_TAIL(&queueing_q, q, entry); 1002 1003 return (1); 1004 } 1005 1006 static void 1007 queueing_done(void) 1008 { 1009 struct queueing *q; 1010 1011 queueing_running--; 1012 1013 while(queueing_running < QUEUEING_MAX) { 1014 if ((q = TAILQ_FIRST(&queueing_q)) == NULL) 1015 break; /* all done */ 1016 TAILQ_REMOVE(&queueing_q, q, entry); 1017 parent_enqueue_offline(q->path); 1018 free(q); 1019 } 1020 } 1021 1022 static int 1023 parent_forward_open(char *username) 1024 { 1025 struct user_backend *ub; 1026 struct user u; 1027 char pathname[MAXPATHLEN]; 1028 int fd; 1029 1030 bzero(&u, sizeof (u)); 1031 ub = user_backend_lookup(USER_GETPWNAM); 1032 if (! ub->getbyname(&u, username)) 1033 return -1; 1034 1035 if (! bsnprintf(pathname, sizeof (pathname), "%s/.forward", u.directory)) 1036 fatal("snprintf"); 1037 1038 fd = open(pathname, O_RDONLY); 1039 if (fd == -1) { 1040 if (errno == ENOENT) 1041 return -2; 1042 log_warn("parent_forward_open: %s", pathname); 1043 return -1; 1044 } 1045 1046 if (! secure_file(fd, pathname, u.directory, u.uid, 1)) { 1047 log_warnx("%s: unsecure file", pathname); 1048 close(fd); 1049 return -1; 1050 } 1051 1052 return fd; 1053 } 1054 1055 int 1056 path_starts_with(char *file, char *prefix) 1057 { 1058 char rprefix[MAXPATHLEN]; 1059 char rfile[MAXPATHLEN]; 1060 1061 if (realpath(file, rfile) == NULL || realpath(prefix, rprefix) == NULL) 1062 return (-1); 1063 1064 return (strncmp(rfile, rprefix, strlen(rprefix)) == 0); 1065 } 1066 1067 int 1068 child_cmp(struct child *c1, struct child *c2) 1069 { 1070 if (c1->pid < c2->pid) 1071 return (-1); 1072 1073 if (c1->pid > c2->pid) 1074 return (1); 1075 1076 return (0); 1077 } 1078 1079 void 1080 imsg_dispatch(int fd, short event, void *p) 1081 { 1082 struct imsgev *iev = p; 1083 struct imsg imsg; 1084 ssize_t n; 1085 1086 if (event & EV_READ) { 1087 if ((n = imsg_read(&iev->ibuf)) == -1) 1088 fatal("imsg_read"); 1089 if (n == 0) { 1090 /* this pipe is dead, so remove the event handler */ 1091 event_del(&iev->ev); 1092 event_loopexit(NULL); 1093 return; 1094 } 1095 } 1096 1097 if (event & EV_WRITE) { 1098 if (msgbuf_write(&iev->ibuf.w) == -1) 1099 fatal("msgbuf_write"); 1100 } 1101 1102 for (;;) { 1103 if ((n = imsg_get(&iev->ibuf, &imsg)) == -1) 1104 fatal("imsg_get"); 1105 if (n == 0) 1106 break; 1107 imsg_callback(iev, &imsg); 1108 imsg_free(&imsg); 1109 } 1110 imsg_event_add(iev); 1111 } 1112 1113 SPLAY_GENERATE(childtree, child, entry, child_cmp); 1114