1 /* $OpenBSD: smtpd.c,v 1.238 2015/01/20 17:37:54 deraadt Exp $ */ 2 3 /* 4 * Copyright (c) 2008 Gilles Chehade <gilles@poolp.org> 5 * Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org> 6 * Copyright (c) 2009 Jacek Masiulaniec <jacekm@dobremiasto.net> 7 * 8 * Permission to use, copy, modify, and distribute this software for any 9 * purpose with or without fee is hereby granted, provided that the above 10 * copyright notice and this permission notice appear in all copies. 11 * 12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 19 */ 20 21 #include <sys/types.h> 22 #include <sys/queue.h> 23 #include <sys/tree.h> 24 #include <sys/socket.h> 25 #include <sys/wait.h> 26 #include <sys/stat.h> 27 #include <sys/uio.h> 28 #include <sys/mman.h> 29 30 #include <bsd_auth.h> 31 #include <dirent.h> 32 #include <err.h> 33 #include <errno.h> 34 #include <event.h> 35 #include <fcntl.h> 36 #include <imsg.h> 37 #include <inttypes.h> 38 #include <login_cap.h> 39 #include <paths.h> 40 #include <pwd.h> 41 #include <signal.h> 42 #include <stdio.h> 43 #include <limits.h> 44 #include <stdlib.h> 45 #include <string.h> 46 #include <time.h> 47 #include <unistd.h> 48 #include <util.h> 49 50 #include <openssl/ssl.h> 51 #include <openssl/evp.h> 52 53 #include "smtpd.h" 54 #include "log.h" 55 #include "ssl.h" 56 57 static void parent_imsg(struct mproc *, struct imsg *); 58 static void usage(void); 59 static void parent_shutdown(int); 60 static void parent_send_config(int, short, void *); 61 static void parent_send_config_lka(void); 62 static void parent_send_config_pony(void); 63 static void parent_send_config_ca(void); 64 static void parent_sig_handler(int, short, void *); 65 static void forkmda(struct mproc *, uint64_t, struct deliver *); 66 static int parent_forward_open(char *, char *, uid_t, gid_t); 67 static void fork_peers(void); 68 static struct child *child_add(pid_t, int, const char *); 69 70 static void offline_scan(int, short, void *); 71 static int offline_add(char *); 72 static void offline_done(void); 73 static int offline_enqueue(char *); 74 75 static void purge_task(void); 76 static int parent_auth_user(const char *, const char *); 77 static void load_pki_tree(void); 78 static void load_pki_keys(void); 79 80 enum child_type { 81 CHILD_DAEMON, 82 CHILD_MDA, 83 CHILD_ENQUEUE_OFFLINE, 84 }; 85 86 struct child { 87 pid_t pid; 88 enum child_type type; 89 const char *title; 90 int mda_out; 91 uint64_t mda_id; 92 char *path; 93 char *cause; 94 }; 95 96 struct offline { 97 TAILQ_ENTRY(offline) entry; 98 char *path; 99 }; 100 101 #define OFFLINE_READMAX 20 102 #define OFFLINE_QUEUEMAX 5 103 static size_t offline_running = 0; 104 TAILQ_HEAD(, offline) offline_q; 105 106 static struct event config_ev; 107 static struct event offline_ev; 108 static struct timeval offline_timeout; 109 110 static pid_t purge_pid = -1; 111 112 extern char **environ; 113 void (*imsg_callback)(struct mproc *, struct imsg *); 114 115 enum smtp_proc_type smtpd_process; 116 117 struct smtpd *env = NULL; 118 119 struct mproc *p_control = NULL; 120 struct mproc *p_lka = NULL; 121 struct mproc *p_parent = NULL; 122 struct mproc *p_queue = NULL; 123 struct mproc *p_scheduler = NULL; 124 struct mproc *p_pony = NULL; 125 struct mproc *p_ca = NULL; 126 127 const char *backend_queue = "fs"; 128 const char *backend_scheduler = "ramqueue"; 129 const char *backend_stat = "ram"; 130 131 int profiling = 0; 132 int verbose = 0; 133 int debug = 0; 134 int foreground = 0; 135 int control_socket = -1; 136 137 struct tree children; 138 139 static void 140 parent_imsg(struct mproc *p, struct imsg *imsg) 141 { 142 struct forward_req *fwreq; 143 struct deliver deliver; 144 struct child *c; 145 struct msg m; 146 const void *data; 147 const char *username, *password, *cause; 148 uint64_t reqid; 149 size_t sz; 150 void *i; 151 int fd, n, v, ret; 152 153 if (p->proc == PROC_LKA) { 154 switch (imsg->hdr.type) { 155 case IMSG_LKA_OPEN_FORWARD: 156 fwreq = imsg->data; 157 fd = parent_forward_open(fwreq->user, fwreq->directory, 158 fwreq->uid, fwreq->gid); 159 fwreq->status = 0; 160 if (fd == -1 && errno != ENOENT) { 161 if (errno == EAGAIN) 162 fwreq->status = -1; 163 } 164 else 165 fwreq->status = 1; 166 m_compose(p, IMSG_LKA_OPEN_FORWARD, 0, 0, fd, 167 fwreq, sizeof *fwreq); 168 return; 169 170 case IMSG_LKA_AUTHENTICATE: 171 /* 172 * If we reached here, it means we want root to lookup 173 * system user. 174 */ 175 m_msg(&m, imsg); 176 m_get_id(&m, &reqid); 177 m_get_string(&m, &username); 178 m_get_string(&m, &password); 179 m_end(&m); 180 181 ret = parent_auth_user(username, password); 182 183 m_create(p, IMSG_LKA_AUTHENTICATE, 0, 0, -1); 184 m_add_id(p, reqid); 185 m_add_int(p, ret); 186 m_close(p); 187 return; 188 } 189 } 190 191 if (p->proc == PROC_PONY) { 192 switch (imsg->hdr.type) { 193 case IMSG_MDA_FORK: 194 m_msg(&m, imsg); 195 m_get_id(&m, &reqid); 196 m_get_data(&m, &data, &sz); 197 m_end(&m); 198 if (sz != sizeof(deliver)) 199 fatalx("expected deliver"); 200 memmove(&deliver, data, sz); 201 forkmda(p, reqid, &deliver); 202 return; 203 204 case IMSG_MDA_KILL: 205 m_msg(&m, imsg); 206 m_get_id(&m, &reqid); 207 m_get_string(&m, &cause); 208 m_end(&m); 209 210 i = NULL; 211 while ((n = tree_iter(&children, &i, NULL, (void**)&c))) 212 if (c->type == CHILD_MDA && 213 c->mda_id == reqid && 214 c->cause == NULL) 215 break; 216 if (!n) { 217 log_debug("debug: smtpd: " 218 "kill request: proc not found"); 219 return; 220 } 221 222 c->cause = xstrdup(cause, "parent_imsg"); 223 log_debug("debug: smtpd: kill requested for %u: %s", 224 c->pid, c->cause); 225 kill(c->pid, SIGTERM); 226 return; 227 } 228 } 229 230 if (p->proc == PROC_CONTROL) { 231 switch (imsg->hdr.type) { 232 case IMSG_CTL_VERBOSE: 233 m_msg(&m, imsg); 234 m_get_int(&m, &v); 235 m_end(&m); 236 log_verbose(v); 237 return; 238 239 case IMSG_CTL_PROFILE: 240 m_msg(&m, imsg); 241 m_get_int(&m, &v); 242 m_end(&m); 243 profiling = v; 244 return; 245 246 case IMSG_CTL_SHUTDOWN: 247 parent_shutdown(0); 248 return; 249 } 250 } 251 252 errx(1, "parent_imsg: unexpected %s imsg from %s", 253 imsg_to_str(imsg->hdr.type), proc_title(p->proc)); 254 } 255 256 static void 257 usage(void) 258 { 259 extern char *__progname; 260 261 fprintf(stderr, "usage: %s [-dhnv] [-D macro=value] " 262 "[-f file] [-P system] [-T trace]\n", __progname); 263 exit(1); 264 } 265 266 static void 267 parent_shutdown(int ret) 268 { 269 void *iter; 270 struct child *child; 271 pid_t pid; 272 273 iter = NULL; 274 while (tree_iter(&children, &iter, NULL, (void**)&child)) 275 if (child->type == CHILD_DAEMON) 276 kill(child->pid, SIGTERM); 277 278 do { 279 pid = waitpid(WAIT_MYPGRP, NULL, 0); 280 } while (pid != -1 || (pid == -1 && errno == EINTR)); 281 282 unlink(SMTPD_SOCKET); 283 284 log_warnx("warn: parent terminating"); 285 exit(ret); 286 } 287 288 static void 289 parent_send_config(int fd, short event, void *p) 290 { 291 parent_send_config_lka(); 292 parent_send_config_pony(); 293 parent_send_config_ca(); 294 purge_config(PURGE_PKI); 295 } 296 297 static void 298 parent_send_config_pony(void) 299 { 300 log_debug("debug: parent_send_config: configuring pony process"); 301 m_compose(p_pony, IMSG_CONF_START, 0, 0, -1, NULL, 0); 302 m_compose(p_pony, IMSG_CONF_END, 0, 0, -1, NULL, 0); 303 } 304 305 void 306 parent_send_config_lka() 307 { 308 log_debug("debug: parent_send_config_ruleset: reloading"); 309 m_compose(p_lka, IMSG_CONF_START, 0, 0, -1, NULL, 0); 310 m_compose(p_lka, IMSG_CONF_END, 0, 0, -1, NULL, 0); 311 } 312 313 static void 314 parent_send_config_ca(void) 315 { 316 log_debug("debug: parent_send_config: configuring ca process"); 317 m_compose(p_ca, IMSG_CONF_START, 0, 0, -1, NULL, 0); 318 m_compose(p_ca, IMSG_CONF_END, 0, 0, -1, NULL, 0); 319 } 320 321 static void 322 parent_sig_handler(int sig, short event, void *p) 323 { 324 struct child *child; 325 int die = 0, status, fail; 326 pid_t pid; 327 char *cause; 328 329 switch (sig) { 330 case SIGTERM: 331 case SIGINT: 332 die = 1; 333 /* FALLTHROUGH */ 334 case SIGCHLD: 335 do { 336 pid = waitpid(-1, &status, WNOHANG); 337 if (pid <= 0) 338 continue; 339 340 fail = 0; 341 if (WIFSIGNALED(status)) { 342 fail = 1; 343 asprintf(&cause, "terminated; signal %d", 344 WTERMSIG(status)); 345 } else if (WIFEXITED(status)) { 346 if (WEXITSTATUS(status) != 0) { 347 fail = 1; 348 asprintf(&cause, "exited abnormally"); 349 } else 350 asprintf(&cause, "exited okay"); 351 } else 352 fatalx("smtpd: unexpected cause of SIGCHLD"); 353 354 if (pid == purge_pid) 355 purge_pid = -1; 356 357 child = tree_pop(&children, pid); 358 if (child == NULL) 359 goto skip; 360 361 switch (child->type) { 362 case CHILD_DAEMON: 363 die = 1; 364 if (fail) 365 log_warnx("warn: lost child: %s %s", 366 child->title, cause); 367 break; 368 369 case CHILD_MDA: 370 if (WIFSIGNALED(status) && 371 WTERMSIG(status) == SIGALRM) { 372 free(cause); 373 asprintf(&cause, "terminated; timeout"); 374 } 375 else if (child->cause && 376 WIFSIGNALED(status) && 377 WTERMSIG(status) == SIGTERM) { 378 free(cause); 379 cause = child->cause; 380 child->cause = NULL; 381 } 382 if (child->cause) 383 free(child->cause); 384 log_debug("debug: smtpd: mda process done " 385 "for session %016"PRIx64 ": %s", 386 child->mda_id, cause); 387 m_create(p_pony, IMSG_MDA_DONE, 0, 0, 388 child->mda_out); 389 m_add_id(p_pony, child->mda_id); 390 m_add_string(p_pony, cause); 391 m_close(p_pony); 392 /* free(cause); */ 393 break; 394 395 case CHILD_ENQUEUE_OFFLINE: 396 if (fail) 397 log_warnx("warn: smtpd: " 398 "couldn't enqueue offline " 399 "message %s; smtpctl %s", 400 child->path, cause); 401 else 402 unlink(child->path); 403 free(child->path); 404 offline_done(); 405 break; 406 407 default: 408 fatalx("smtpd: unexpected child type"); 409 } 410 free(child); 411 skip: 412 free(cause); 413 } while (pid > 0 || (pid == -1 && errno == EINTR)); 414 415 if (die) 416 parent_shutdown(1); 417 break; 418 default: 419 fatalx("smtpd: unexpected signal"); 420 } 421 } 422 423 int 424 main(int argc, char *argv[]) 425 { 426 int c, i; 427 int opts, flags; 428 const char *conffile = CONF_FILE; 429 struct smtpd smtpd; 430 struct event ev_sigint; 431 struct event ev_sigterm; 432 struct event ev_sigchld; 433 struct event ev_sighup; 434 struct timeval tv; 435 436 env = &smtpd; 437 438 flags = 0; 439 opts = 0; 440 debug = 0; 441 verbose = 0; 442 443 log_init(1); 444 445 TAILQ_INIT(&offline_q); 446 447 while ((c = getopt(argc, argv, "B:dD:hnP:f:T:v")) != -1) { 448 switch (c) { 449 case 'B': 450 if (strstr(optarg, "queue=") == optarg) 451 backend_queue = strchr(optarg, '=') + 1; 452 else if (strstr(optarg, "scheduler=") == optarg) 453 backend_scheduler = strchr(optarg, '=') + 1; 454 else if (strstr(optarg, "stat=") == optarg) 455 backend_stat = strchr(optarg, '=') + 1; 456 else 457 log_warnx("warn: " 458 "invalid backend specifier %s", 459 optarg); 460 break; 461 case 'd': 462 foreground = 1; 463 break; 464 case 'D': 465 if (cmdline_symset(optarg) < 0) 466 log_warnx("warn: " 467 "could not parse macro definition %s", 468 optarg); 469 break; 470 case 'h': 471 log_info("version: OpenSMTPD " SMTPD_VERSION); 472 usage(); 473 break; 474 case 'n': 475 debug = 2; 476 opts |= SMTPD_OPT_NOACTION; 477 break; 478 case 'f': 479 conffile = optarg; 480 break; 481 case 'T': 482 if (!strcmp(optarg, "imsg")) 483 verbose |= TRACE_IMSG; 484 else if (!strcmp(optarg, "io")) 485 verbose |= TRACE_IO; 486 else if (!strcmp(optarg, "smtp")) 487 verbose |= TRACE_SMTP; 488 else if (!strcmp(optarg, "mfa") || 489 !strcmp(optarg, "filter") || 490 !strcmp(optarg, "filters")) 491 verbose |= TRACE_FILTERS; 492 else if (!strcmp(optarg, "mta") || 493 !strcmp(optarg, "transfer")) 494 verbose |= TRACE_MTA; 495 else if (!strcmp(optarg, "bounce") || 496 !strcmp(optarg, "bounces")) 497 verbose |= TRACE_BOUNCE; 498 else if (!strcmp(optarg, "scheduler")) 499 verbose |= TRACE_SCHEDULER; 500 else if (!strcmp(optarg, "lookup")) 501 verbose |= TRACE_LOOKUP; 502 else if (!strcmp(optarg, "stat") || 503 !strcmp(optarg, "stats")) 504 verbose |= TRACE_STAT; 505 else if (!strcmp(optarg, "rules")) 506 verbose |= TRACE_RULES; 507 else if (!strcmp(optarg, "mproc")) 508 verbose |= TRACE_MPROC; 509 else if (!strcmp(optarg, "expand")) 510 verbose |= TRACE_EXPAND; 511 else if (!strcmp(optarg, "table") || 512 !strcmp(optarg, "tables")) 513 verbose |= TRACE_TABLES; 514 else if (!strcmp(optarg, "queue")) 515 verbose |= TRACE_QUEUE; 516 else if (!strcmp(optarg, "all")) 517 verbose |= ~TRACE_DEBUG; 518 else if (!strcmp(optarg, "profstat")) 519 profiling |= PROFILE_TOSTAT; 520 else if (!strcmp(optarg, "profile-imsg")) 521 profiling |= PROFILE_IMSG; 522 else if (!strcmp(optarg, "profile-queue")) 523 profiling |= PROFILE_QUEUE; 524 else if (!strcmp(optarg, "profile-buffers")) 525 profiling |= PROFILE_BUFFERS; 526 else 527 log_warnx("warn: unknown trace flag \"%s\"", 528 optarg); 529 break; 530 case 'P': 531 if (!strcmp(optarg, "smtp")) 532 flags |= SMTPD_SMTP_PAUSED; 533 else if (!strcmp(optarg, "mta")) 534 flags |= SMTPD_MTA_PAUSED; 535 else if (!strcmp(optarg, "mda")) 536 flags |= SMTPD_MDA_PAUSED; 537 break; 538 case 'v': 539 verbose |= TRACE_DEBUG; 540 break; 541 default: 542 usage(); 543 } 544 } 545 546 argv += optind; 547 argc -= optind; 548 549 if (argc || *argv) 550 usage(); 551 552 ssl_init(); 553 554 if (parse_config(&smtpd, conffile, opts)) 555 exit(1); 556 557 if (strlcpy(env->sc_conffile, conffile, PATH_MAX) 558 >= PATH_MAX) 559 errx(1, "config file exceeds PATH_MAX"); 560 561 if (env->sc_opts & SMTPD_OPT_NOACTION) { 562 load_pki_tree(); 563 load_pki_keys(); 564 fprintf(stderr, "configuration OK\n"); 565 exit(0); 566 } 567 568 env->sc_flags |= flags; 569 570 /* check for root privileges */ 571 if (geteuid()) 572 errx(1, "need root privileges"); 573 574 /* the control socket ensures that only one smtpd instance is running */ 575 control_socket = control_create_socket(); 576 577 if (!queue_init(backend_queue, 1)) 578 errx(1, "could not initialize queue backend"); 579 580 env->sc_stat = stat_backend_lookup(backend_stat); 581 if (env->sc_stat == NULL) 582 errx(1, "could not find stat backend \"%s\"", backend_stat); 583 584 if (env->sc_queue_flags & QUEUE_ENCRYPTION) { 585 if (env->sc_queue_key == NULL) { 586 char *password; 587 588 password = getpass("queue key: "); 589 if (password == NULL) 590 err(1, "getpass"); 591 592 env->sc_queue_key = strdup(password); 593 explicit_bzero(password, strlen(password)); 594 if (env->sc_queue_key == NULL) 595 err(1, "strdup"); 596 } 597 else { 598 char *buf; 599 char *lbuf; 600 size_t len; 601 602 if (strcasecmp(env->sc_queue_key, "stdin") == 0) { 603 lbuf = NULL; 604 buf = fgetln(stdin, &len); 605 if (buf[len - 1] == '\n') { 606 lbuf = calloc(len, 1); 607 if (lbuf == NULL) 608 err(1, "calloc"); 609 memcpy(lbuf, buf, len-1); 610 } 611 else { 612 lbuf = calloc(len+1, 1); 613 if (lbuf == NULL) 614 err(1, "calloc"); 615 memcpy(lbuf, buf, len); 616 } 617 env->sc_queue_key = lbuf; 618 } 619 } 620 } 621 622 if (env->sc_queue_flags & QUEUE_COMPRESSION) 623 env->sc_comp = compress_backend_lookup("gzip"); 624 625 log_init(foreground); 626 log_verbose(verbose); 627 628 load_pki_tree(); 629 630 log_info("info: %s %s starting", SMTPD_NAME, SMTPD_VERSION); 631 632 if (! foreground) 633 if (daemon(0, 0) == -1) 634 err(1, "failed to daemonize"); 635 636 for (i = 0; i < MAX_BOUNCE_WARN; i++) { 637 if (env->sc_bounce_warn[i] == 0) 638 break; 639 log_debug("debug: bounce warning after %s", 640 duration_to_text(env->sc_bounce_warn[i])); 641 } 642 643 log_debug("debug: using \"%s\" queue backend", backend_queue); 644 log_debug("debug: using \"%s\" scheduler backend", backend_scheduler); 645 log_debug("debug: using \"%s\" stat backend", backend_stat); 646 log_info("info: startup%s", (verbose & TRACE_DEBUG)?" [debug mode]":""); 647 648 if (env->sc_hostname[0] == '\0') 649 errx(1, "machine does not have a hostname set"); 650 env->sc_uptime = time(NULL); 651 652 fork_peers(); 653 654 config_process(PROC_PARENT); 655 656 imsg_callback = parent_imsg; 657 event_init(); 658 659 signal_set(&ev_sigint, SIGINT, parent_sig_handler, NULL); 660 signal_set(&ev_sigterm, SIGTERM, parent_sig_handler, NULL); 661 signal_set(&ev_sigchld, SIGCHLD, parent_sig_handler, NULL); 662 signal_set(&ev_sighup, SIGHUP, parent_sig_handler, NULL); 663 signal_add(&ev_sigint, NULL); 664 signal_add(&ev_sigterm, NULL); 665 signal_add(&ev_sigchld, NULL); 666 signal_add(&ev_sighup, NULL); 667 signal(SIGPIPE, SIG_IGN); 668 669 config_peer(PROC_CONTROL); 670 config_peer(PROC_LKA); 671 config_peer(PROC_QUEUE); 672 config_peer(PROC_CA); 673 config_peer(PROC_PONY); 674 config_done(); 675 676 evtimer_set(&config_ev, parent_send_config, NULL); 677 memset(&tv, 0, sizeof(tv)); 678 evtimer_add(&config_ev, &tv); 679 680 /* defer offline scanning for a second */ 681 evtimer_set(&offline_ev, offline_scan, NULL); 682 offline_timeout.tv_sec = 1; 683 offline_timeout.tv_usec = 0; 684 evtimer_add(&offline_ev, &offline_timeout); 685 686 if (pidfile(NULL) < 0) 687 err(1, "pidfile"); 688 689 purge_task(); 690 691 if (event_dispatch() < 0) 692 fatal("smtpd: event_dispatch"); 693 694 return (0); 695 } 696 697 static void 698 load_pki_tree(void) 699 { 700 struct pki *pki; 701 const char *k; 702 void *iter_dict; 703 704 log_debug("debug: init ssl-tree"); 705 iter_dict = NULL; 706 while (dict_iter(env->sc_pki_dict, &iter_dict, &k, (void **)&pki)) { 707 log_debug("info: loading pki information for %s", k); 708 if (pki->pki_cert_file == NULL) 709 fatalx("load_pki_tree: missing certificate file"); 710 if (pki->pki_key_file == NULL) 711 fatalx("load_pki_tree: missing key file"); 712 713 if (! ssl_load_certificate(pki, pki->pki_cert_file)) 714 fatalx("load_pki_tree: failed to load certificate file"); 715 716 if (pki->pki_ca_file) 717 if (! ssl_load_cafile(pki, pki->pki_ca_file)) 718 fatalx("load_pki_tree: failed to load CA file"); 719 if (pki->pki_dhparams_file) 720 if (! ssl_load_dhparams(pki, pki->pki_dhparams_file)) 721 fatalx("load_pki_tree: failed to load dhparams file"); 722 } 723 } 724 725 void 726 load_pki_keys(void) 727 { 728 struct pki *pki; 729 const char *k; 730 void *iter_dict; 731 732 log_debug("debug: init ssl-tree"); 733 iter_dict = NULL; 734 while (dict_iter(env->sc_pki_dict, &iter_dict, &k, (void **)&pki)) { 735 log_debug("info: loading pki keys for %s", k); 736 737 if (! ssl_load_keyfile(pki, pki->pki_key_file, k)) 738 fatalx("load_pki_keys: failed to load key file"); 739 } 740 } 741 742 static void 743 fork_peers(void) 744 { 745 tree_init(&children); 746 747 init_pipes(); 748 749 child_add(queue(), CHILD_DAEMON, proc_title(PROC_QUEUE)); 750 child_add(control(), CHILD_DAEMON, proc_title(PROC_CONTROL)); 751 child_add(lka(), CHILD_DAEMON, proc_title(PROC_LKA)); 752 child_add(scheduler(), CHILD_DAEMON, proc_title(PROC_SCHEDULER)); 753 child_add(pony(), CHILD_DAEMON, proc_title(PROC_PONY)); 754 child_add(ca(), CHILD_DAEMON, proc_title(PROC_CA)); 755 post_fork(PROC_PARENT); 756 } 757 758 void 759 post_fork(int proc) 760 { 761 if (proc != PROC_QUEUE && env->sc_queue_key) 762 explicit_bzero(env->sc_queue_key, strlen(env->sc_queue_key)); 763 764 if (proc != PROC_CONTROL) { 765 close(control_socket); 766 control_socket = -1; 767 } 768 769 if (proc == PROC_CA) { 770 load_pki_keys(); 771 } 772 } 773 774 int 775 fork_proc_backend(const char *key, const char *conf, const char *procname) 776 { 777 pid_t pid; 778 int sp[2]; 779 char path[PATH_MAX]; 780 char name[PATH_MAX]; 781 char *arg; 782 783 if (strlcpy(name, conf, sizeof(name)) >= sizeof(name)) { 784 log_warnx("warn: %s-proc: conf too long", key); 785 return (0); 786 } 787 788 arg = strchr(name, ':'); 789 if (arg) 790 *arg++ = '\0'; 791 792 if (snprintf(path, sizeof(path), PATH_LIBEXEC "/%s-%s", key, name) >= 793 (ssize_t)sizeof(path)) { 794 log_warn("warn: %s-proc: exec path too long", key); 795 return (-1); 796 } 797 798 if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, sp) == -1) { 799 log_warn("warn: %s-proc: socketpair", key); 800 return (-1); 801 } 802 803 if ((pid = fork()) == -1) { 804 log_warn("warn: %s-proc: fork", key); 805 close(sp[0]); 806 close(sp[1]); 807 return (-1); 808 } 809 810 if (pid == 0) { 811 /* child process */ 812 dup2(sp[0], STDIN_FILENO); 813 if (closefrom(STDERR_FILENO + 1) < 0) 814 exit(1); 815 816 if (procname == NULL) 817 procname = name; 818 819 execl(path, procname, arg, NULL); 820 err(1, "execl: %s", path); 821 } 822 823 /* parent process */ 824 close(sp[0]); 825 826 return (sp[1]); 827 } 828 829 struct child * 830 child_add(pid_t pid, int type, const char *title) 831 { 832 struct child *child; 833 834 if ((child = calloc(1, sizeof(*child))) == NULL) 835 fatal("smtpd: child_add: calloc"); 836 837 child->pid = pid; 838 child->type = type; 839 child->title = title; 840 841 tree_xset(&children, pid, child); 842 843 return (child); 844 } 845 846 static void 847 purge_task(void) 848 { 849 struct passwd *pw; 850 DIR *d; 851 int n; 852 uid_t uid; 853 gid_t gid; 854 855 n = 0; 856 if ((d = opendir(PATH_SPOOL PATH_PURGE))) { 857 while (readdir(d) != NULL) 858 n++; 859 closedir(d); 860 } else 861 log_warn("warn: purge_task: opendir"); 862 863 if (n > 2) { 864 switch (purge_pid = fork()) { 865 case -1: 866 log_warn("warn: purge_task: fork"); 867 break; 868 case 0: 869 if ((pw = getpwnam(SMTPD_USER)) == NULL) 870 fatalx("unknown user " SMTPD_USER); 871 if (chroot(PATH_SPOOL PATH_PURGE) == -1) 872 fatal("smtpd: chroot"); 873 if (chdir("/") == -1) 874 fatal("smtpd: chdir"); 875 uid = pw->pw_uid; 876 gid = pw->pw_gid; 877 if (setgroups(1, &gid) || 878 setresgid(gid, gid, gid) || 879 setresuid(uid, uid, uid)) 880 fatal("smtpd: cannot drop privileges"); 881 rmtree("/", 1); 882 _exit(0); 883 break; 884 default: 885 break; 886 } 887 } 888 } 889 890 static void 891 forkmda(struct mproc *p, uint64_t id, struct deliver *deliver) 892 { 893 char ebuf[128], sfn[32]; 894 struct delivery_backend *db; 895 struct child *child; 896 pid_t pid; 897 int allout, pipefd[2]; 898 mode_t omode; 899 900 log_debug("debug: smtpd: forking mda for session %016"PRIx64 901 ": \"%s\" as %s", id, deliver->to, deliver->user); 902 903 db = delivery_backend_lookup(deliver->mode); 904 if (db == NULL) { 905 (void)snprintf(ebuf, sizeof ebuf, "could not find delivery backend"); 906 m_create(p_pony, IMSG_MDA_DONE, 0, 0, -1); 907 m_add_id(p_pony, id); 908 m_add_string(p_pony, ebuf); 909 m_close(p_pony); 910 return; 911 } 912 913 if (deliver->userinfo.uid == 0 && ! db->allow_root) { 914 (void)snprintf(ebuf, sizeof ebuf, "not allowed to deliver to: %s", 915 deliver->user); 916 m_create(p_pony, IMSG_MDA_DONE, 0, 0, -1); 917 m_add_id(p_pony, id); 918 m_add_string(p_pony, ebuf); 919 m_close(p_pony); 920 return; 921 } 922 923 if (pipe(pipefd) < 0) { 924 (void)snprintf(ebuf, sizeof ebuf, "pipe: %s", strerror(errno)); 925 m_create(p_pony, IMSG_MDA_DONE, 0, 0, -1); 926 m_add_id(p_pony, id); 927 m_add_string(p_pony, ebuf); 928 m_close(p_pony); 929 return; 930 } 931 932 /* prepare file which captures stdout and stderr */ 933 (void)strlcpy(sfn, "/tmp/smtpd.out.XXXXXXXXXXX", sizeof(sfn)); 934 omode = umask(7077); 935 allout = mkstemp(sfn); 936 umask(omode); 937 if (allout < 0) { 938 (void)snprintf(ebuf, sizeof ebuf, "mkstemp: %s", strerror(errno)); 939 m_create(p_pony, IMSG_MDA_DONE, 0, 0, -1); 940 m_add_id(p_pony, id); 941 m_add_string(p_pony, ebuf); 942 m_close(p_pony); 943 close(pipefd[0]); 944 close(pipefd[1]); 945 return; 946 } 947 unlink(sfn); 948 949 pid = fork(); 950 if (pid < 0) { 951 (void)snprintf(ebuf, sizeof ebuf, "fork: %s", strerror(errno)); 952 m_create(p_pony, IMSG_MDA_DONE, 0, 0, -1); 953 m_add_id(p_pony, id); 954 m_add_string(p_pony, ebuf); 955 m_close(p_pony); 956 close(pipefd[0]); 957 close(pipefd[1]); 958 close(allout); 959 return; 960 } 961 962 /* parent passes the child fd over to mda */ 963 if (pid > 0) { 964 child = child_add(pid, CHILD_MDA, NULL); 965 child->mda_out = allout; 966 child->mda_id = id; 967 close(pipefd[0]); 968 m_create(p, IMSG_MDA_FORK, 0, 0, pipefd[1]); 969 m_add_id(p, id); 970 m_close(p); 971 return; 972 } 973 974 if (chdir(deliver->userinfo.directory) < 0 && chdir("/") < 0) 975 err(1, "chdir"); 976 if (setgroups(1, &deliver->userinfo.gid) || 977 setresgid(deliver->userinfo.gid, deliver->userinfo.gid, deliver->userinfo.gid) || 978 setresuid(deliver->userinfo.uid, deliver->userinfo.uid, deliver->userinfo.uid)) 979 err(1, "forkmda: cannot drop privileges"); 980 if (dup2(pipefd[0], STDIN_FILENO) < 0 || 981 dup2(allout, STDOUT_FILENO) < 0 || 982 dup2(allout, STDERR_FILENO) < 0) 983 err(1, "forkmda: dup2"); 984 if (closefrom(STDERR_FILENO + 1) < 0) 985 err(1, "closefrom"); 986 if (setsid() < 0) 987 err(1, "setsid"); 988 if (signal(SIGPIPE, SIG_DFL) == SIG_ERR || 989 signal(SIGINT, SIG_DFL) == SIG_ERR || 990 signal(SIGTERM, SIG_DFL) == SIG_ERR || 991 signal(SIGCHLD, SIG_DFL) == SIG_ERR || 992 signal(SIGHUP, SIG_DFL) == SIG_ERR) 993 err(1, "signal"); 994 995 /* avoid hangs by setting 5m timeout */ 996 alarm(300); 997 998 db->open(deliver); 999 } 1000 1001 static void 1002 offline_scan(int fd, short ev, void *arg) 1003 { 1004 DIR *dir = arg; 1005 struct dirent *d; 1006 int n = 0; 1007 1008 if (dir == NULL) { 1009 log_debug("debug: smtpd: scanning offline queue..."); 1010 if ((dir = opendir(PATH_SPOOL PATH_OFFLINE)) == NULL) 1011 errx(1, "smtpd: opendir"); 1012 } 1013 1014 while ((d = readdir(dir)) != NULL) { 1015 if (d->d_type != DT_REG) 1016 continue; 1017 1018 if (offline_add(d->d_name)) { 1019 log_warnx("warn: smtpd: " 1020 "could not add offline message %s", d->d_name); 1021 continue; 1022 } 1023 1024 if ((n++) == OFFLINE_READMAX) { 1025 evtimer_set(&offline_ev, offline_scan, dir); 1026 offline_timeout.tv_sec = 0; 1027 offline_timeout.tv_usec = 100000; 1028 evtimer_add(&offline_ev, &offline_timeout); 1029 return; 1030 } 1031 } 1032 1033 log_debug("debug: smtpd: offline scanning done"); 1034 closedir(dir); 1035 } 1036 1037 static int 1038 offline_enqueue(char *name) 1039 { 1040 char t[PATH_MAX], *path; 1041 struct stat sb; 1042 pid_t pid; 1043 struct child *child; 1044 struct passwd *pw; 1045 1046 if (!bsnprintf(t, sizeof t, "%s/%s", PATH_SPOOL PATH_OFFLINE, name)) { 1047 log_warnx("warn: smtpd: path name too long"); 1048 return (-1); 1049 } 1050 1051 if ((path = strdup(t)) == NULL) { 1052 log_warn("warn: smtpd: strdup"); 1053 return (-1); 1054 } 1055 1056 log_debug("debug: smtpd: enqueueing offline message %s", path); 1057 1058 if ((pid = fork()) == -1) { 1059 log_warn("warn: smtpd: fork"); 1060 free(path); 1061 return (-1); 1062 } 1063 1064 if (pid == 0) { 1065 char *envp[2], *p, *tmp; 1066 FILE *fp; 1067 size_t len; 1068 arglist args; 1069 1070 memset(&args, 0, sizeof(args)); 1071 1072 if (lstat(path, &sb) == -1) { 1073 log_warn("warn: smtpd: lstat: %s", path); 1074 _exit(1); 1075 } 1076 1077 if (chflags(path, 0) == -1) { 1078 log_warn("warn: smtpd: chflags: %s", path); 1079 _exit(1); 1080 } 1081 1082 pw = getpwuid(sb.st_uid); 1083 if (pw == NULL) { 1084 log_warnx("warn: smtpd: getpwuid for uid %d failed", 1085 sb.st_uid); 1086 _exit(1); 1087 } 1088 1089 if (! S_ISREG(sb.st_mode)) { 1090 log_warnx("warn: smtpd: file %s (uid %d) not regular", 1091 path, sb.st_uid); 1092 _exit(1); 1093 } 1094 1095 if (setgroups(1, &pw->pw_gid) || 1096 setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) || 1097 setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) || 1098 closefrom(STDERR_FILENO + 1) == -1) 1099 _exit(1); 1100 1101 if ((fp = fopen(path, "r")) == NULL) 1102 _exit(1); 1103 1104 if (chdir(pw->pw_dir) == -1 && chdir("/") == -1) 1105 _exit(1); 1106 1107 if (setsid() == -1 || 1108 signal(SIGPIPE, SIG_DFL) == SIG_ERR || 1109 dup2(fileno(fp), STDIN_FILENO) == -1) 1110 _exit(1); 1111 1112 if ((p = fgetln(fp, &len)) == NULL) 1113 _exit(1); 1114 1115 if (p[len - 1] != '\n') 1116 _exit(1); 1117 p[len - 1] = '\0'; 1118 1119 addargs(&args, "%s", "sendmail"); 1120 addargs(&args, "%s", "-S"); 1121 1122 while ((tmp = strsep(&p, "|")) != NULL) 1123 addargs(&args, "%s", tmp); 1124 1125 if (lseek(fileno(fp), len, SEEK_SET) == -1) 1126 _exit(1); 1127 1128 envp[0] = "PATH=" _PATH_DEFPATH; 1129 envp[1] = (char *)NULL; 1130 environ = envp; 1131 1132 execvp(PATH_SMTPCTL, args.list); 1133 _exit(1); 1134 } 1135 1136 offline_running++; 1137 child = child_add(pid, CHILD_ENQUEUE_OFFLINE, NULL); 1138 child->path = path; 1139 1140 return (0); 1141 } 1142 1143 static int 1144 offline_add(char *path) 1145 { 1146 struct offline *q; 1147 1148 if (offline_running < OFFLINE_QUEUEMAX) 1149 /* skip queue */ 1150 return offline_enqueue(path); 1151 1152 q = malloc(sizeof(*q) + strlen(path) + 1); 1153 if (q == NULL) 1154 return (-1); 1155 q->path = (char *)q + sizeof(*q); 1156 memmove(q->path, path, strlen(path) + 1); 1157 TAILQ_INSERT_TAIL(&offline_q, q, entry); 1158 1159 return (0); 1160 } 1161 1162 static void 1163 offline_done(void) 1164 { 1165 struct offline *q; 1166 1167 offline_running--; 1168 1169 while (offline_running < OFFLINE_QUEUEMAX) { 1170 if ((q = TAILQ_FIRST(&offline_q)) == NULL) 1171 break; /* all done */ 1172 TAILQ_REMOVE(&offline_q, q, entry); 1173 offline_enqueue(q->path); 1174 free(q); 1175 } 1176 } 1177 1178 static int 1179 parent_forward_open(char *username, char *directory, uid_t uid, gid_t gid) 1180 { 1181 char pathname[PATH_MAX]; 1182 int fd; 1183 struct stat sb; 1184 1185 if (! bsnprintf(pathname, sizeof (pathname), "%s/.forward", 1186 directory)) 1187 fatal("smtpd: parent_forward_open: snprintf"); 1188 1189 if (stat(directory, &sb) < 0) { 1190 log_warn("warn: smtpd: parent_forward_open: %s", directory); 1191 return -1; 1192 } 1193 if (sb.st_mode & S_ISVTX) { 1194 log_warnx("warn: smtpd: parent_forward_open: %s is sticky", 1195 directory); 1196 errno = EAGAIN; 1197 return -1; 1198 } 1199 1200 do { 1201 fd = open(pathname, O_RDONLY); 1202 } while (fd == -1 && errno == EINTR); 1203 if (fd == -1) { 1204 if (errno == ENOENT) 1205 return -1; 1206 if (errno == EMFILE || errno == ENFILE || errno == EIO) { 1207 errno = EAGAIN; 1208 return -1; 1209 } 1210 log_warn("warn: smtpd: parent_forward_open: %s", pathname); 1211 return -1; 1212 } 1213 1214 if (! secure_file(fd, pathname, directory, uid, 1)) { 1215 log_warnx("warn: smtpd: %s: unsecure file", pathname); 1216 close(fd); 1217 return -1; 1218 } 1219 1220 return fd; 1221 } 1222 1223 void 1224 imsg_dispatch(struct mproc *p, struct imsg *imsg) 1225 { 1226 struct timespec t0, t1, dt; 1227 int msg; 1228 1229 if (imsg == NULL) { 1230 exit(1); 1231 return; 1232 } 1233 1234 log_imsg(smtpd_process, p->proc, imsg); 1235 1236 if (profiling & PROFILE_IMSG) 1237 clock_gettime(CLOCK_MONOTONIC, &t0); 1238 1239 msg = imsg->hdr.type; 1240 imsg_callback(p, imsg); 1241 1242 if (profiling & PROFILE_IMSG) { 1243 clock_gettime(CLOCK_MONOTONIC, &t1); 1244 timespecsub(&t1, &t0, &dt); 1245 1246 log_debug("profile-imsg: %s %s %s %d %lld.%09ld", 1247 proc_name(smtpd_process), 1248 proc_name(p->proc), 1249 imsg_to_str(msg), 1250 (int)imsg->hdr.len, 1251 (long long)dt.tv_sec, 1252 dt.tv_nsec); 1253 1254 if (profiling & PROFILE_TOSTAT) { 1255 char key[STAT_KEY_SIZE]; 1256 /* can't profstat control process yet */ 1257 if (smtpd_process == PROC_CONTROL) 1258 return; 1259 1260 if (! bsnprintf(key, sizeof key, 1261 "profiling.imsg.%s.%s.%s", 1262 proc_name(smtpd_process), 1263 proc_name(p->proc), 1264 imsg_to_str(msg))) 1265 return; 1266 stat_set(key, stat_timespec(&dt)); 1267 } 1268 } 1269 } 1270 1271 void 1272 log_imsg(int to, int from, struct imsg *imsg) 1273 { 1274 1275 if (to == PROC_CONTROL && imsg->hdr.type == IMSG_STAT_SET) 1276 return; 1277 1278 if (imsg->fd != -1) 1279 log_trace(TRACE_IMSG, "imsg: %s <- %s: %s (len=%zu, fd=%d)", 1280 proc_name(to), 1281 proc_name(from), 1282 imsg_to_str(imsg->hdr.type), 1283 imsg->hdr.len - IMSG_HEADER_SIZE, 1284 imsg->fd); 1285 else 1286 log_trace(TRACE_IMSG, "imsg: %s <- %s: %s (len=%zu)", 1287 proc_name(to), 1288 proc_name(from), 1289 imsg_to_str(imsg->hdr.type), 1290 imsg->hdr.len - IMSG_HEADER_SIZE); 1291 } 1292 1293 const char * 1294 proc_title(enum smtp_proc_type proc) 1295 { 1296 switch (proc) { 1297 case PROC_PARENT: 1298 return "[priv]"; 1299 case PROC_LKA: 1300 return "lookup"; 1301 case PROC_QUEUE: 1302 return "queue"; 1303 case PROC_CONTROL: 1304 return "control"; 1305 case PROC_SCHEDULER: 1306 return "scheduler"; 1307 case PROC_PONY: 1308 return "pony express"; 1309 case PROC_CA: 1310 return "klondike"; 1311 default: 1312 return "unknown"; 1313 } 1314 } 1315 1316 const char * 1317 proc_name(enum smtp_proc_type proc) 1318 { 1319 switch (proc) { 1320 case PROC_PARENT: 1321 return "parent"; 1322 case PROC_LKA: 1323 return "lka"; 1324 case PROC_QUEUE: 1325 return "queue"; 1326 case PROC_CONTROL: 1327 return "control"; 1328 case PROC_SCHEDULER: 1329 return "scheduler"; 1330 case PROC_PONY: 1331 return "pony"; 1332 case PROC_CA: 1333 return "ca"; 1334 case PROC_FILTER: 1335 return "filter-proc"; 1336 case PROC_CLIENT: 1337 return "client-proc"; 1338 default: 1339 return "unknown"; 1340 } 1341 } 1342 1343 #define CASE(x) case x : return #x 1344 1345 const char * 1346 imsg_to_str(int type) 1347 { 1348 static char buf[32]; 1349 1350 switch (type) { 1351 CASE(IMSG_NONE); 1352 1353 CASE(IMSG_CTL_OK); 1354 CASE(IMSG_CTL_FAIL); 1355 1356 CASE(IMSG_CTL_GET_DIGEST); 1357 CASE(IMSG_CTL_GET_STATS); 1358 CASE(IMSG_CTL_LIST_MESSAGES); 1359 CASE(IMSG_CTL_LIST_ENVELOPES); 1360 CASE(IMSG_CTL_MTA_SHOW_HOSTS); 1361 CASE(IMSG_CTL_MTA_SHOW_RELAYS); 1362 CASE(IMSG_CTL_MTA_SHOW_ROUTES); 1363 CASE(IMSG_CTL_MTA_SHOW_HOSTSTATS); 1364 CASE(IMSG_CTL_MTA_BLOCK); 1365 CASE(IMSG_CTL_MTA_UNBLOCK); 1366 CASE(IMSG_CTL_MTA_SHOW_BLOCK); 1367 CASE(IMSG_CTL_PAUSE_EVP); 1368 CASE(IMSG_CTL_PAUSE_MDA); 1369 CASE(IMSG_CTL_PAUSE_MTA); 1370 CASE(IMSG_CTL_PAUSE_SMTP); 1371 CASE(IMSG_CTL_PROFILE); 1372 CASE(IMSG_CTL_PROFILE_DISABLE); 1373 CASE(IMSG_CTL_PROFILE_ENABLE); 1374 CASE(IMSG_CTL_RESUME_EVP); 1375 CASE(IMSG_CTL_RESUME_MDA); 1376 CASE(IMSG_CTL_RESUME_MTA); 1377 CASE(IMSG_CTL_RESUME_SMTP); 1378 CASE(IMSG_CTL_RESUME_ROUTE); 1379 CASE(IMSG_CTL_REMOVE); 1380 CASE(IMSG_CTL_SCHEDULE); 1381 CASE(IMSG_CTL_SHOW_STATUS); 1382 CASE(IMSG_CTL_SHUTDOWN); 1383 CASE(IMSG_CTL_TRACE_DISABLE); 1384 CASE(IMSG_CTL_TRACE_ENABLE); 1385 CASE(IMSG_CTL_UPDATE_TABLE); 1386 CASE(IMSG_CTL_VERBOSE); 1387 1388 CASE(IMSG_CTL_SMTP_SESSION); 1389 1390 CASE(IMSG_CONF_START); 1391 CASE(IMSG_CONF_END); 1392 1393 CASE(IMSG_STAT_INCREMENT); 1394 CASE(IMSG_STAT_DECREMENT); 1395 CASE(IMSG_STAT_SET); 1396 1397 CASE(IMSG_LKA_AUTHENTICATE); 1398 CASE(IMSG_LKA_OPEN_FORWARD); 1399 CASE(IMSG_LKA_ENVELOPE_SUBMIT); 1400 CASE(IMSG_LKA_ENVELOPE_COMMIT); 1401 1402 CASE(IMSG_QUEUE_DELIVER); 1403 CASE(IMSG_QUEUE_DELIVERY_OK); 1404 CASE(IMSG_QUEUE_DELIVERY_TEMPFAIL); 1405 CASE(IMSG_QUEUE_DELIVERY_PERMFAIL); 1406 CASE(IMSG_QUEUE_DELIVERY_LOOP); 1407 CASE(IMSG_QUEUE_ENVELOPE_ACK); 1408 CASE(IMSG_QUEUE_ENVELOPE_COMMIT); 1409 CASE(IMSG_QUEUE_ENVELOPE_REMOVE); 1410 CASE(IMSG_QUEUE_ENVELOPE_SCHEDULE); 1411 CASE(IMSG_QUEUE_ENVELOPE_SUBMIT); 1412 CASE(IMSG_QUEUE_HOLDQ_HOLD); 1413 CASE(IMSG_QUEUE_HOLDQ_RELEASE); 1414 CASE(IMSG_QUEUE_MESSAGE_COMMIT); 1415 CASE(IMSG_QUEUE_MESSAGE_ROLLBACK); 1416 CASE(IMSG_QUEUE_SMTP_SESSION); 1417 CASE(IMSG_QUEUE_TRANSFER); 1418 1419 CASE(IMSG_MDA_DELIVERY_OK); 1420 CASE(IMSG_MDA_DELIVERY_TEMPFAIL); 1421 CASE(IMSG_MDA_DELIVERY_PERMFAIL); 1422 CASE(IMSG_MDA_DELIVERY_LOOP); 1423 CASE(IMSG_MDA_DELIVERY_HOLD); 1424 CASE(IMSG_MDA_DONE); 1425 CASE(IMSG_MDA_FORK); 1426 CASE(IMSG_MDA_HOLDQ_RELEASE); 1427 CASE(IMSG_MDA_LOOKUP_USERINFO); 1428 CASE(IMSG_MDA_KILL); 1429 CASE(IMSG_MDA_OPEN_MESSAGE); 1430 1431 CASE(IMSG_MTA_DELIVERY_OK); 1432 CASE(IMSG_MTA_DELIVERY_TEMPFAIL); 1433 CASE(IMSG_MTA_DELIVERY_PERMFAIL); 1434 CASE(IMSG_MTA_DELIVERY_LOOP); 1435 CASE(IMSG_MTA_DELIVERY_HOLD); 1436 CASE(IMSG_MTA_DNS_HOST); 1437 CASE(IMSG_MTA_DNS_HOST_END); 1438 CASE(IMSG_MTA_DNS_PTR); 1439 CASE(IMSG_MTA_DNS_MX); 1440 CASE(IMSG_MTA_DNS_MX_PREFERENCE); 1441 CASE(IMSG_MTA_HOLDQ_RELEASE); 1442 CASE(IMSG_MTA_LOOKUP_CREDENTIALS); 1443 CASE(IMSG_MTA_LOOKUP_SOURCE); 1444 CASE(IMSG_MTA_LOOKUP_HELO); 1445 CASE(IMSG_MTA_OPEN_MESSAGE); 1446 CASE(IMSG_MTA_SCHEDULE); 1447 CASE(IMSG_MTA_SSL_INIT); 1448 CASE(IMSG_MTA_SSL_VERIFY_CERT); 1449 CASE(IMSG_MTA_SSL_VERIFY_CHAIN); 1450 CASE(IMSG_MTA_SSL_VERIFY); 1451 1452 CASE(IMSG_SCHED_ENVELOPE_BOUNCE); 1453 CASE(IMSG_SCHED_ENVELOPE_DELIVER); 1454 CASE(IMSG_SCHED_ENVELOPE_EXPIRE); 1455 CASE(IMSG_SCHED_ENVELOPE_INJECT); 1456 CASE(IMSG_SCHED_ENVELOPE_REMOVE); 1457 CASE(IMSG_SCHED_ENVELOPE_TRANSFER); 1458 1459 CASE(IMSG_SMTP_AUTHENTICATE); 1460 CASE(IMSG_SMTP_DNS_PTR); 1461 CASE(IMSG_SMTP_MESSAGE_COMMIT); 1462 CASE(IMSG_SMTP_MESSAGE_CREATE); 1463 CASE(IMSG_SMTP_MESSAGE_ROLLBACK); 1464 CASE(IMSG_SMTP_MESSAGE_OPEN); 1465 CASE(IMSG_SMTP_EXPAND_RCPT); 1466 CASE(IMSG_SMTP_LOOKUP_HELO); 1467 CASE(IMSG_SMTP_SSL_INIT); 1468 CASE(IMSG_SMTP_SSL_VERIFY_CERT); 1469 CASE(IMSG_SMTP_SSL_VERIFY_CHAIN); 1470 CASE(IMSG_SMTP_SSL_VERIFY); 1471 1472 CASE(IMSG_SMTP_REQ_CONNECT); 1473 CASE(IMSG_SMTP_REQ_HELO); 1474 CASE(IMSG_SMTP_REQ_MAIL); 1475 CASE(IMSG_SMTP_REQ_RCPT); 1476 CASE(IMSG_SMTP_REQ_DATA); 1477 CASE(IMSG_SMTP_REQ_EOM); 1478 CASE(IMSG_SMTP_EVENT_RSET); 1479 CASE(IMSG_SMTP_EVENT_COMMIT); 1480 CASE(IMSG_SMTP_EVENT_ROLLBACK); 1481 CASE(IMSG_SMTP_EVENT_DISCONNECT); 1482 1483 CASE(IMSG_CA_PRIVENC); 1484 CASE(IMSG_CA_PRIVDEC); 1485 default: 1486 (void)snprintf(buf, sizeof(buf), "IMSG_??? (%d)", type); 1487 1488 return buf; 1489 } 1490 } 1491 1492 int 1493 parent_auth_user(const char *username, const char *password) 1494 { 1495 char user[LOGIN_NAME_MAX]; 1496 char pass[LINE_MAX]; 1497 int ret; 1498 1499 (void)strlcpy(user, username, sizeof(user)); 1500 (void)strlcpy(pass, password, sizeof(pass)); 1501 1502 ret = auth_userokay(user, NULL, "auth-smtp", pass); 1503 if (ret) 1504 return LKA_OK; 1505 return LKA_PERMFAIL; 1506 } 1507