1 /* $OpenBSD: smtpctl.c,v 1.167 2020/02/24 16:16:07 millert Exp $ */ 2 3 /* 4 * Copyright (c) 2013 Eric Faurot <eric@openbsd.org> 5 * Copyright (c) 2006 Gilles Chehade <gilles@poolp.org> 6 * Copyright (c) 2006 Pierre-Yves Ritschard <pyr@openbsd.org> 7 * Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org> 8 * Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org> 9 * Copyright (c) 2003 Henning Brauer <henning@openbsd.org> 10 * 11 * Permission to use, copy, modify, and distribute this software for any 12 * purpose with or without fee is hereby granted, provided that the above 13 * copyright notice and this permission notice appear in all copies. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 16 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 17 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 18 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 19 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 20 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 21 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 22 */ 23 24 #include <sys/types.h> 25 #include <sys/socket.h> 26 #include <sys/queue.h> 27 #include <sys/tree.h> 28 #include <sys/un.h> 29 #include <sys/wait.h> 30 #include <sys/stat.h> 31 32 #include <err.h> 33 #include <errno.h> 34 #include <event.h> 35 #include <fts.h> 36 #include <grp.h> 37 #include <imsg.h> 38 #include <inttypes.h> 39 #include <pwd.h> 40 #include <stdio.h> 41 #include <stdlib.h> 42 #include <string.h> 43 #include <syslog.h> 44 #include <time.h> 45 #include <unistd.h> 46 #include <vis.h> 47 #include <limits.h> 48 49 #include "smtpd.h" 50 #include "parser.h" 51 #include "log.h" 52 53 #define PATH_GZCAT "/usr/bin/gzcat" 54 #define PATH_CAT "/bin/cat" 55 #define PATH_QUEUE "/queue" 56 #define PATH_ENCRYPT "/usr/bin/encrypt" 57 58 int srv_connect(void); 59 int srv_connected(void); 60 61 void usage(void); 62 static void show_queue_envelope(struct envelope *, int); 63 static void getflag(uint *, int, char *, char *, size_t); 64 static void display(const char *); 65 static int str_to_trace(const char *); 66 static int str_to_profile(const char *); 67 static void show_offline_envelope(uint64_t); 68 static int is_gzip_fp(FILE *); 69 static int is_encrypted_fp(FILE *); 70 static int is_encrypted_buffer(const char *); 71 static int is_gzip_buffer(const char *); 72 static FILE *offline_file(void); 73 static void sendmail_compat(int, char **); 74 75 extern int spfwalk(int, struct parameter *); 76 77 extern char *__progname; 78 int sendmail; 79 struct smtpd *env; 80 struct imsgbuf *ibuf; 81 struct imsg imsg; 82 char *rdata; 83 size_t rlen; 84 time_t now; 85 86 struct queue_backend queue_backend_null; 87 struct queue_backend queue_backend_proc; 88 struct queue_backend queue_backend_ram; 89 90 __dead void 91 usage(void) 92 { 93 if (sendmail) 94 fprintf(stderr, "usage: %s [-tv] [-f from] [-F name] to ...\n", 95 __progname); 96 else 97 fprintf(stderr, "usage: %s command [argument ...]\n", 98 __progname); 99 exit(1); 100 } 101 102 void stat_increment(const char *k, size_t v) 103 { 104 } 105 106 void stat_decrement(const char *k, size_t v) 107 { 108 } 109 110 int 111 srv_connect(void) 112 { 113 struct sockaddr_un s_un; 114 int ctl_sock, saved_errno; 115 116 /* connect to smtpd control socket */ 117 if ((ctl_sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) 118 err(1, "socket"); 119 120 memset(&s_un, 0, sizeof(s_un)); 121 s_un.sun_family = AF_UNIX; 122 (void)strlcpy(s_un.sun_path, SMTPD_SOCKET, sizeof(s_un.sun_path)); 123 if (connect(ctl_sock, (struct sockaddr *)&s_un, sizeof(s_un)) == -1) { 124 saved_errno = errno; 125 close(ctl_sock); 126 errno = saved_errno; 127 return (0); 128 } 129 130 ibuf = xcalloc(1, sizeof(struct imsgbuf)); 131 imsg_init(ibuf, ctl_sock); 132 133 return (1); 134 } 135 136 int 137 srv_connected(void) 138 { 139 return ibuf != NULL ? 1 : 0; 140 } 141 142 FILE * 143 offline_file(void) 144 { 145 char path[PATH_MAX]; 146 int fd; 147 FILE *fp; 148 149 if (!bsnprintf(path, sizeof(path), "%s%s/%lld.XXXXXXXXXX", PATH_SPOOL, 150 PATH_OFFLINE, (long long int) time(NULL))) 151 err(EX_UNAVAILABLE, "snprintf"); 152 153 if ((fd = mkstemp(path)) == -1 || (fp = fdopen(fd, "w+")) == NULL) { 154 if (fd != -1) 155 unlink(path); 156 err(EX_UNAVAILABLE, "cannot create temporary file %s", path); 157 } 158 159 if (fchmod(fd, 0600) == -1) { 160 unlink(path); 161 err(EX_SOFTWARE, "fchmod"); 162 } 163 164 return fp; 165 } 166 167 168 static void 169 srv_flush(void) 170 { 171 if (imsg_flush(ibuf) == -1) 172 err(1, "write error"); 173 } 174 175 static void 176 srv_send(int msg, const void *data, size_t len) 177 { 178 if (ibuf == NULL && !srv_connect()) 179 errx(1, "smtpd doesn't seem to be running"); 180 imsg_compose(ibuf, msg, IMSG_VERSION, 0, -1, data, len); 181 } 182 183 static void 184 srv_recv(int type) 185 { 186 ssize_t n; 187 188 srv_flush(); 189 190 while (1) { 191 if ((n = imsg_get(ibuf, &imsg)) == -1) 192 errx(1, "imsg_get error"); 193 if (n) { 194 if (imsg.hdr.type == IMSG_CTL_FAIL && 195 imsg.hdr.peerid != 0 && 196 imsg.hdr.peerid != IMSG_VERSION) 197 errx(1, "incompatible smtpctl and smtpd"); 198 if (type != -1 && type != (int)imsg.hdr.type) 199 errx(1, "bad message type"); 200 rdata = imsg.data; 201 rlen = imsg.hdr.len - sizeof(imsg.hdr); 202 break; 203 } 204 205 if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN) 206 errx(1, "imsg_read error"); 207 if (n == 0) 208 errx(1, "pipe closed"); 209 } 210 } 211 212 static void 213 srv_read(void *dst, size_t sz) 214 { 215 if (sz == 0) 216 return; 217 if (rlen < sz) 218 errx(1, "message too short"); 219 if (dst) 220 memmove(dst, rdata, sz); 221 rlen -= sz; 222 rdata += sz; 223 } 224 225 static void 226 srv_get_int(int *i) 227 { 228 srv_read(i, sizeof(*i)); 229 } 230 231 static void 232 srv_get_time(time_t *t) 233 { 234 srv_read(t, sizeof(*t)); 235 } 236 237 static void 238 srv_get_evpid(uint64_t *evpid) 239 { 240 srv_read(evpid, sizeof(*evpid)); 241 } 242 243 static void 244 srv_get_string(const char **s) 245 { 246 const char *end; 247 size_t len; 248 249 if (rlen == 0) 250 errx(1, "message too short"); 251 252 rlen -= 1; 253 if (*rdata++ == '\0') { 254 *s = NULL; 255 return; 256 } 257 258 if (rlen == 0) 259 errx(1, "bogus string"); 260 261 end = memchr(rdata, 0, rlen); 262 if (end == NULL) 263 errx(1, "unterminated string"); 264 265 len = end + 1 - rdata; 266 267 *s = rdata; 268 rlen -= len; 269 rdata += len; 270 } 271 272 static void 273 srv_get_envelope(struct envelope *evp) 274 { 275 uint64_t evpid; 276 const char *str; 277 278 srv_get_evpid(&evpid); 279 srv_get_string(&str); 280 281 envelope_load_buffer(evp, str, strlen(str)); 282 evp->id = evpid; 283 } 284 285 static void 286 srv_end(void) 287 { 288 if (rlen) 289 errx(1, "bogus data"); 290 imsg_free(&imsg); 291 } 292 293 static int 294 srv_check_result(int verbose_) 295 { 296 srv_recv(-1); 297 srv_end(); 298 299 switch (imsg.hdr.type) { 300 case IMSG_CTL_OK: 301 if (verbose_) 302 printf("command succeeded\n"); 303 return (0); 304 case IMSG_CTL_FAIL: 305 if (verbose_) { 306 if (rlen) 307 printf("command failed: %s\n", rdata); 308 else 309 printf("command failed\n"); 310 } 311 return (1); 312 default: 313 errx(1, "wrong message in response: %u", imsg.hdr.type); 314 } 315 return (0); 316 } 317 318 static int 319 srv_iter_messages(uint32_t *res) 320 { 321 static uint32_t *msgids = NULL, from = 0; 322 static size_t n, curr; 323 static int done = 0; 324 325 if (done) 326 return (0); 327 328 if (msgids == NULL) { 329 srv_send(IMSG_CTL_LIST_MESSAGES, &from, sizeof(from)); 330 srv_recv(IMSG_CTL_LIST_MESSAGES); 331 if (rlen == 0) { 332 srv_end(); 333 done = 1; 334 return (0); 335 } 336 msgids = malloc(rlen); 337 n = rlen / sizeof(*msgids); 338 srv_read(msgids, rlen); 339 srv_end(); 340 341 curr = 0; 342 from = msgids[n - 1] + 1; 343 if (from == 0) 344 done = 1; 345 } 346 347 *res = msgids[curr++]; 348 if (curr == n) { 349 free(msgids); 350 msgids = NULL; 351 } 352 353 return (1); 354 } 355 356 static int 357 srv_iter_envelopes(uint32_t msgid, struct envelope *evp) 358 { 359 static uint32_t currmsgid = 0; 360 static uint64_t from = 0; 361 static int done = 0, need_send = 1, found; 362 int flags; 363 time_t nexttry; 364 365 if (currmsgid != msgid) { 366 if (currmsgid != 0 && !done) 367 errx(1, "must finish current iteration first"); 368 currmsgid = msgid; 369 from = msgid_to_evpid(msgid); 370 done = 0; 371 found = 0; 372 need_send = 1; 373 } 374 375 if (done) 376 return (0); 377 378 again: 379 if (need_send) { 380 found = 0; 381 srv_send(IMSG_CTL_LIST_ENVELOPES, &from, sizeof(from)); 382 } 383 need_send = 0; 384 385 srv_recv(IMSG_CTL_LIST_ENVELOPES); 386 if (rlen == 0) { 387 srv_end(); 388 if (!found || evpid_to_msgid(from) != msgid) { 389 done = 1; 390 return (0); 391 } 392 need_send = 1; 393 goto again; 394 } 395 396 srv_get_int(&flags); 397 srv_get_time(&nexttry); 398 srv_get_envelope(evp); 399 srv_end(); 400 401 evp->flags |= flags; 402 evp->nexttry = nexttry; 403 404 from = evp->id + 1; 405 found++; 406 return (1); 407 } 408 409 static int 410 srv_iter_evpids(uint32_t msgid, uint64_t *evpid, int *offset) 411 { 412 static uint64_t *evpids = NULL, *tmp; 413 static int n, tmpalloc, alloc = 0; 414 struct envelope evp; 415 416 if (*offset == 0) { 417 n = 0; 418 while (srv_iter_envelopes(msgid, &evp)) { 419 if (n == alloc) { 420 tmpalloc = alloc ? (alloc * 2) : 128; 421 tmp = recallocarray(evpids, alloc, tmpalloc, 422 sizeof(*evpids)); 423 if (tmp == NULL) 424 err(1, "recallocarray"); 425 evpids = tmp; 426 alloc = tmpalloc; 427 } 428 evpids[n++] = evp.id; 429 } 430 } 431 432 if (*offset >= n) 433 return (0); 434 *evpid = evpids[*offset]; 435 *offset += 1; 436 return (1); 437 } 438 439 static void 440 srv_foreach_envelope(struct parameter *argv, int ctl, size_t *total, size_t *ok) 441 { 442 uint32_t msgid; 443 uint64_t evpid; 444 int i; 445 446 *total = 0; 447 *ok = 0; 448 449 if (argv == NULL) { 450 while (srv_iter_messages(&msgid)) { 451 i = 0; 452 while (srv_iter_evpids(msgid, &evpid, &i)) { 453 *total += 1; 454 srv_send(ctl, &evpid, sizeof(evpid)); 455 if (srv_check_result(0) == 0) 456 *ok += 1; 457 } 458 } 459 } else if (argv->type == P_MSGID) { 460 i = 0; 461 while (srv_iter_evpids(argv->u.u_msgid, &evpid, &i)) { 462 srv_send(ctl, &evpid, sizeof(evpid)); 463 if (srv_check_result(0) == 0) 464 *ok += 1; 465 } 466 } else { 467 *total += 1; 468 srv_send(ctl, &argv->u.u_evpid, sizeof(evpid)); 469 if (srv_check_result(0) == 0) 470 *ok += 1; 471 } 472 } 473 474 static void 475 srv_show_cmd(int cmd, const void *data, size_t len) 476 { 477 int done = 0; 478 479 srv_send(cmd, data, len); 480 481 do { 482 srv_recv(cmd); 483 if (rlen) { 484 printf("%s\n", rdata); 485 srv_read(NULL, rlen); 486 } 487 else 488 done = 1; 489 srv_end(); 490 } while (!done); 491 } 492 493 static void 494 droppriv(void) 495 { 496 struct passwd *pw; 497 498 if (geteuid()) 499 return; 500 501 if ((pw = getpwnam(SMTPD_USER)) == NULL) 502 errx(1, "unknown user " SMTPD_USER); 503 504 if ((setgroups(1, &pw->pw_gid) || 505 setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) || 506 setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))) 507 err(1, "cannot drop privileges"); 508 } 509 510 static int 511 do_permission_denied(int argc, struct parameter *argv) 512 { 513 errx(1, "need root privileges"); 514 } 515 516 static int 517 do_log_brief(int argc, struct parameter *argv) 518 { 519 int v = 0; 520 521 srv_send(IMSG_CTL_VERBOSE, &v, sizeof(v)); 522 return srv_check_result(1); 523 } 524 525 static int 526 do_log_verbose(int argc, struct parameter *argv) 527 { 528 int v = TRACE_DEBUG; 529 530 srv_send(IMSG_CTL_VERBOSE, &v, sizeof(v)); 531 return srv_check_result(1); 532 } 533 534 static int 535 do_monitor(int argc, struct parameter *argv) 536 { 537 struct stat_digest last, digest; 538 size_t count; 539 540 memset(&last, 0, sizeof(last)); 541 count = 0; 542 543 while (1) { 544 srv_send(IMSG_CTL_GET_DIGEST, NULL, 0); 545 srv_recv(IMSG_CTL_GET_DIGEST); 546 srv_read(&digest, sizeof(digest)); 547 srv_end(); 548 549 if (count % 25 == 0) { 550 if (count != 0) 551 printf("\n"); 552 printf("--- client --- " 553 "-- envelope -- " 554 "---- relay/delivery --- " 555 "------- misc -------\n" 556 "curr conn disc " 557 "curr enq deq " 558 "ok tmpfail prmfail loop " 559 "expire remove bounce\n"); 560 } 561 printf("%4zu %4zu %4zu " 562 "%4zu %4zu %4zu " 563 "%4zu %4zu %4zu %4zu " 564 "%4zu %4zu %4zu\n", 565 digest.clt_connect - digest.clt_disconnect, 566 digest.clt_connect - last.clt_connect, 567 digest.clt_disconnect - last.clt_disconnect, 568 569 digest.evp_enqueued - digest.evp_dequeued, 570 digest.evp_enqueued - last.evp_enqueued, 571 digest.evp_dequeued - last.evp_dequeued, 572 573 digest.dlv_ok - last.dlv_ok, 574 digest.dlv_tempfail - last.dlv_tempfail, 575 digest.dlv_permfail - last.dlv_permfail, 576 digest.dlv_loop - last.dlv_loop, 577 578 digest.evp_expired - last.evp_expired, 579 digest.evp_removed - last.evp_removed, 580 digest.evp_bounce - last.evp_bounce); 581 582 last = digest; 583 count++; 584 sleep(1); 585 } 586 587 return (0); 588 } 589 590 static int 591 do_pause_envelope(int argc, struct parameter *argv) 592 { 593 size_t total, ok; 594 595 srv_foreach_envelope(argv, IMSG_CTL_PAUSE_EVP, &total, &ok); 596 printf("%zu envelope%s paused\n", ok, (ok > 1) ? "s" : ""); 597 598 return (0); 599 } 600 601 static int 602 do_pause_mda(int argc, struct parameter *argv) 603 { 604 srv_send(IMSG_CTL_PAUSE_MDA, NULL, 0); 605 return srv_check_result(1); 606 } 607 608 static int 609 do_pause_mta(int argc, struct parameter *argv) 610 { 611 srv_send(IMSG_CTL_PAUSE_MTA, NULL, 0); 612 return srv_check_result(1); 613 } 614 615 static int 616 do_pause_smtp(int argc, struct parameter *argv) 617 { 618 srv_send(IMSG_CTL_PAUSE_SMTP, NULL, 0); 619 return srv_check_result(1); 620 } 621 622 static int 623 do_profile(int argc, struct parameter *argv) 624 { 625 int v; 626 627 v = str_to_profile(argv[0].u.u_str); 628 629 srv_send(IMSG_CTL_PROFILE_ENABLE, &v, sizeof(v)); 630 return srv_check_result(1); 631 } 632 633 static int 634 do_remove(int argc, struct parameter *argv) 635 { 636 size_t total, ok; 637 638 srv_foreach_envelope(argv, IMSG_CTL_REMOVE, &total, &ok); 639 printf("%zu envelope%s removed\n", ok, (ok > 1) ? "s" : ""); 640 641 return (0); 642 } 643 644 static int 645 do_resume_envelope(int argc, struct parameter *argv) 646 { 647 size_t total, ok; 648 649 srv_foreach_envelope(argv, IMSG_CTL_RESUME_EVP, &total, &ok); 650 printf("%zu envelope%s resumed\n", ok, (ok > 1) ? "s" : ""); 651 652 return (0); 653 } 654 655 static int 656 do_resume_mda(int argc, struct parameter *argv) 657 { 658 srv_send(IMSG_CTL_RESUME_MDA, NULL, 0); 659 return srv_check_result(1); 660 } 661 662 static int 663 do_resume_mta(int argc, struct parameter *argv) 664 { 665 srv_send(IMSG_CTL_RESUME_MTA, NULL, 0); 666 return srv_check_result(1); 667 } 668 669 static int 670 do_resume_route(int argc, struct parameter *argv) 671 { 672 uint64_t v; 673 674 if (argc == 0) 675 v = 0; 676 else 677 v = argv[0].u.u_routeid; 678 679 srv_send(IMSG_CTL_RESUME_ROUTE, &v, sizeof(v)); 680 return srv_check_result(1); 681 } 682 683 static int 684 do_resume_smtp(int argc, struct parameter *argv) 685 { 686 srv_send(IMSG_CTL_RESUME_SMTP, NULL, 0); 687 return srv_check_result(1); 688 } 689 690 static int 691 do_schedule(int argc, struct parameter *argv) 692 { 693 size_t total, ok; 694 695 srv_foreach_envelope(argv, IMSG_CTL_SCHEDULE, &total, &ok); 696 printf("%zu envelope%s scheduled\n", ok, (ok > 1) ? "s" : ""); 697 698 return (0); 699 } 700 701 static int 702 do_show_envelope(int argc, struct parameter *argv) 703 { 704 char buf[PATH_MAX]; 705 706 if (!bsnprintf(buf, sizeof(buf), "%s%s/%02x/%08x/%016" PRIx64, 707 PATH_SPOOL, 708 PATH_QUEUE, 709 (evpid_to_msgid(argv[0].u.u_evpid) & 0xff000000) >> 24, 710 evpid_to_msgid(argv[0].u.u_evpid), 711 argv[0].u.u_evpid)) 712 errx(1, "unable to retrieve envelope"); 713 714 display(buf); 715 716 return (0); 717 } 718 719 static int 720 do_show_hoststats(int argc, struct parameter *argv) 721 { 722 srv_show_cmd(IMSG_CTL_MTA_SHOW_HOSTSTATS, NULL, 0); 723 724 return (0); 725 } 726 727 static int 728 do_show_message(int argc, struct parameter *argv) 729 { 730 char buf[PATH_MAX]; 731 uint32_t msgid; 732 733 if (argv[0].type == P_EVPID) 734 msgid = evpid_to_msgid(argv[0].u.u_evpid); 735 else 736 msgid = argv[0].u.u_msgid; 737 738 if (!bsnprintf(buf, sizeof(buf), "%s%s/%02x/%08x/message", 739 PATH_SPOOL, 740 PATH_QUEUE, 741 (msgid & 0xff000000) >> 24, 742 msgid)) 743 errx(1, "unable to retrieve message"); 744 745 display(buf); 746 747 return (0); 748 } 749 750 static int 751 do_show_queue(int argc, struct parameter *argv) 752 { 753 struct envelope evp; 754 uint32_t msgid; 755 FTS *fts; 756 FTSENT *ftse; 757 char *qpath[] = {"/queue", NULL}; 758 char *tmp; 759 uint64_t evpid; 760 761 now = time(NULL); 762 763 if (!srv_connect()) { 764 log_init(1, LOG_MAIL); 765 queue_init("fs", 0); 766 if (chroot(PATH_SPOOL) == -1 || chdir("/") == -1) 767 err(1, "%s", PATH_SPOOL); 768 fts = fts_open(qpath, FTS_PHYSICAL|FTS_NOCHDIR, NULL); 769 if (fts == NULL) 770 err(1, "%s/queue", PATH_SPOOL); 771 772 while ((ftse = fts_read(fts)) != NULL) { 773 switch (ftse->fts_info) { 774 case FTS_DP: 775 case FTS_DNR: 776 break; 777 case FTS_F: 778 tmp = NULL; 779 evpid = strtoull(ftse->fts_name, &tmp, 16); 780 if (tmp && *tmp != '\0') 781 break; 782 show_offline_envelope(evpid); 783 } 784 } 785 786 fts_close(fts); 787 return (0); 788 } 789 790 if (argc == 0) { 791 msgid = 0; 792 while (srv_iter_messages(&msgid)) 793 while (srv_iter_envelopes(msgid, &evp)) 794 show_queue_envelope(&evp, 1); 795 } else if (argv[0].type == P_MSGID) { 796 while (srv_iter_envelopes(argv[0].u.u_msgid, &evp)) 797 show_queue_envelope(&evp, 1); 798 } 799 800 return (0); 801 } 802 803 static int 804 do_show_hosts(int argc, struct parameter *argv) 805 { 806 srv_show_cmd(IMSG_CTL_MTA_SHOW_HOSTS, NULL, 0); 807 808 return (0); 809 } 810 811 static int 812 do_show_relays(int argc, struct parameter *argv) 813 { 814 srv_show_cmd(IMSG_CTL_MTA_SHOW_RELAYS, NULL, 0); 815 816 return (0); 817 } 818 819 static int 820 do_show_routes(int argc, struct parameter *argv) 821 { 822 srv_show_cmd(IMSG_CTL_MTA_SHOW_ROUTES, NULL, 0); 823 824 return (0); 825 } 826 827 static int 828 do_show_stats(int argc, struct parameter *argv) 829 { 830 struct stat_kv kv; 831 time_t duration; 832 833 memset(&kv, 0, sizeof kv); 834 835 while (1) { 836 srv_send(IMSG_CTL_GET_STATS, &kv, sizeof kv); 837 srv_recv(IMSG_CTL_GET_STATS); 838 srv_read(&kv, sizeof(kv)); 839 srv_end(); 840 841 if (kv.iter == NULL) 842 break; 843 844 if (strcmp(kv.key, "uptime") == 0) { 845 duration = time(NULL) - kv.val.u.counter; 846 printf("uptime=%lld\n", (long long)duration); 847 printf("uptime.human=%s\n", 848 duration_to_text(duration)); 849 } 850 else { 851 switch (kv.val.type) { 852 case STAT_COUNTER: 853 printf("%s=%zd\n", 854 kv.key, kv.val.u.counter); 855 break; 856 case STAT_TIMESTAMP: 857 printf("%s=%" PRId64 "\n", 858 kv.key, (int64_t)kv.val.u.timestamp); 859 break; 860 case STAT_TIMEVAL: 861 printf("%s=%lld.%lld\n", 862 kv.key, (long long)kv.val.u.tv.tv_sec, 863 (long long)kv.val.u.tv.tv_usec); 864 break; 865 case STAT_TIMESPEC: 866 printf("%s=%lld.%06ld\n", 867 kv.key, 868 (long long)kv.val.u.ts.tv_sec * 1000000 + 869 kv.val.u.ts.tv_nsec / 1000000, 870 kv.val.u.ts.tv_nsec % 1000000); 871 break; 872 } 873 } 874 } 875 876 return (0); 877 } 878 879 static int 880 do_show_status(int argc, struct parameter *argv) 881 { 882 uint32_t sc_flags; 883 884 srv_send(IMSG_CTL_SHOW_STATUS, NULL, 0); 885 srv_recv(IMSG_CTL_SHOW_STATUS); 886 srv_read(&sc_flags, sizeof(sc_flags)); 887 srv_end(); 888 printf("MDA %s\n", 889 (sc_flags & SMTPD_MDA_PAUSED) ? "paused" : "running"); 890 printf("MTA %s\n", 891 (sc_flags & SMTPD_MTA_PAUSED) ? "paused" : "running"); 892 printf("SMTP %s\n", 893 (sc_flags & SMTPD_SMTP_PAUSED) ? "paused" : "running"); 894 return (0); 895 } 896 897 static int 898 do_trace(int argc, struct parameter *argv) 899 { 900 int v; 901 902 v = str_to_trace(argv[0].u.u_str); 903 904 srv_send(IMSG_CTL_TRACE_ENABLE, &v, sizeof(v)); 905 return srv_check_result(1); 906 } 907 908 static int 909 do_unprofile(int argc, struct parameter *argv) 910 { 911 int v; 912 913 v = str_to_profile(argv[0].u.u_str); 914 915 srv_send(IMSG_CTL_PROFILE_DISABLE, &v, sizeof(v)); 916 return srv_check_result(1); 917 } 918 919 static int 920 do_untrace(int argc, struct parameter *argv) 921 { 922 int v; 923 924 v = str_to_trace(argv[0].u.u_str); 925 926 srv_send(IMSG_CTL_TRACE_DISABLE, &v, sizeof(v)); 927 return srv_check_result(1); 928 } 929 930 static int 931 do_update_table(int argc, struct parameter *argv) 932 { 933 const char *name = argv[0].u.u_str; 934 935 srv_send(IMSG_CTL_UPDATE_TABLE, name, strlen(name) + 1); 936 return srv_check_result(1); 937 } 938 939 static int 940 do_encrypt(int argc, struct parameter *argv) 941 { 942 const char *p = NULL; 943 944 droppriv(); 945 946 if (argv) 947 p = argv[0].u.u_str; 948 execl(PATH_ENCRYPT, "encrypt", "--", p, (char *)NULL); 949 errx(1, "execl"); 950 } 951 952 static int 953 do_block_mta(int argc, struct parameter *argv) 954 { 955 struct ibuf *m; 956 957 if (ibuf == NULL && !srv_connect()) 958 errx(1, "smtpd doesn't seem to be running"); 959 m = imsg_create(ibuf, IMSG_CTL_MTA_BLOCK, IMSG_VERSION, 0, 960 sizeof(argv[0].u.u_ss) + strlen(argv[1].u.u_str) + 1); 961 if (imsg_add(m, &argv[0].u.u_ss, sizeof(argv[0].u.u_ss)) == -1) 962 errx(1, "imsg_add"); 963 if (imsg_add(m, argv[1].u.u_str, strlen(argv[1].u.u_str) + 1) == -1) 964 errx(1, "imsg_add"); 965 imsg_close(ibuf, m); 966 967 return srv_check_result(1); 968 } 969 970 static int 971 do_unblock_mta(int argc, struct parameter *argv) 972 { 973 struct ibuf *m; 974 975 if (ibuf == NULL && !srv_connect()) 976 errx(1, "smtpd doesn't seem to be running"); 977 978 m = imsg_create(ibuf, IMSG_CTL_MTA_UNBLOCK, IMSG_VERSION, 0, 979 sizeof(argv[0].u.u_ss) + strlen(argv[1].u.u_str) + 1); 980 if (imsg_add(m, &argv[0].u.u_ss, sizeof(argv[0].u.u_ss)) == -1) 981 errx(1, "imsg_add"); 982 if (imsg_add(m, argv[1].u.u_str, strlen(argv[1].u.u_str) + 1) == -1) 983 errx(1, "imsg_add"); 984 imsg_close(ibuf, m); 985 986 return srv_check_result(1); 987 } 988 989 static int 990 do_show_mta_block(int argc, struct parameter *argv) 991 { 992 srv_show_cmd(IMSG_CTL_MTA_SHOW_BLOCK, NULL, 0); 993 994 return (0); 995 } 996 997 static int 998 do_discover(int argc, struct parameter *argv) 999 { 1000 uint64_t evpid; 1001 uint32_t msgid; 1002 size_t n_evp; 1003 1004 if (ibuf == NULL && !srv_connect()) 1005 errx(1, "smtpd doesn't seem to be running"); 1006 1007 if (argv[0].type == P_EVPID) { 1008 evpid = argv[0].u.u_evpid; 1009 srv_send(IMSG_CTL_DISCOVER_EVPID, &evpid, sizeof evpid); 1010 srv_recv(IMSG_CTL_DISCOVER_EVPID); 1011 } else { 1012 msgid = argv[0].u.u_msgid; 1013 srv_send(IMSG_CTL_DISCOVER_MSGID, &msgid, sizeof msgid); 1014 srv_recv(IMSG_CTL_DISCOVER_MSGID); 1015 } 1016 1017 if (rlen == 0) { 1018 srv_end(); 1019 return (0); 1020 } else { 1021 srv_read(&n_evp, sizeof n_evp); 1022 srv_end(); 1023 } 1024 1025 printf("%zu envelope%s discovered\n", n_evp, (n_evp != 1) ? "s" : ""); 1026 return (0); 1027 } 1028 1029 static int 1030 do_spf_walk(int argc, struct parameter *argv) 1031 { 1032 droppriv(); 1033 1034 return spfwalk(argc, argv); 1035 } 1036 1037 #define cmd_install_priv(s, f) \ 1038 cmd_install((s), privileged ? (f) : do_permission_denied) 1039 1040 int 1041 main(int argc, char **argv) 1042 { 1043 gid_t gid; 1044 int privileged; 1045 char *argv_mailq[] = { "show", "queue", NULL }; 1046 1047 sendmail_compat(argc, argv); 1048 privileged = geteuid() == 0; 1049 1050 gid = getgid(); 1051 if (setresgid(gid, gid, gid) == -1) 1052 err(1, "setresgid"); 1053 1054 /* Privileged commands */ 1055 cmd_install_priv("discover <evpid>", do_discover); 1056 cmd_install_priv("discover <msgid>", do_discover); 1057 cmd_install_priv("pause mta from <addr> for <str>", do_block_mta); 1058 cmd_install_priv("resume mta from <addr> for <str>", do_unblock_mta); 1059 cmd_install_priv("show mta paused", do_show_mta_block); 1060 cmd_install_priv("log brief", do_log_brief); 1061 cmd_install_priv("log verbose", do_log_verbose); 1062 cmd_install_priv("monitor", do_monitor); 1063 cmd_install_priv("pause envelope <evpid>", do_pause_envelope); 1064 cmd_install_priv("pause envelope <msgid>", do_pause_envelope); 1065 cmd_install_priv("pause envelope all", do_pause_envelope); 1066 cmd_install_priv("pause mda", do_pause_mda); 1067 cmd_install_priv("pause mta", do_pause_mta); 1068 cmd_install_priv("pause smtp", do_pause_smtp); 1069 cmd_install_priv("profile <str>", do_profile); 1070 cmd_install_priv("remove <evpid>", do_remove); 1071 cmd_install_priv("remove <msgid>", do_remove); 1072 cmd_install_priv("remove all", do_remove); 1073 cmd_install_priv("resume envelope <evpid>", do_resume_envelope); 1074 cmd_install_priv("resume envelope <msgid>", do_resume_envelope); 1075 cmd_install_priv("resume envelope all", do_resume_envelope); 1076 cmd_install_priv("resume mda", do_resume_mda); 1077 cmd_install_priv("resume mta", do_resume_mta); 1078 cmd_install_priv("resume route <routeid>", do_resume_route); 1079 cmd_install_priv("resume smtp", do_resume_smtp); 1080 cmd_install_priv("schedule <msgid>", do_schedule); 1081 cmd_install_priv("schedule <evpid>", do_schedule); 1082 cmd_install_priv("schedule all", do_schedule); 1083 cmd_install_priv("show envelope <evpid>", do_show_envelope); 1084 cmd_install_priv("show hoststats", do_show_hoststats); 1085 cmd_install_priv("show message <msgid>", do_show_message); 1086 cmd_install_priv("show message <evpid>", do_show_message); 1087 cmd_install_priv("show queue", do_show_queue); 1088 cmd_install_priv("show queue <msgid>", do_show_queue); 1089 cmd_install_priv("show hosts", do_show_hosts); 1090 cmd_install_priv("show relays", do_show_relays); 1091 cmd_install_priv("show routes", do_show_routes); 1092 cmd_install_priv("show stats", do_show_stats); 1093 cmd_install_priv("show status", do_show_status); 1094 cmd_install_priv("trace <str>", do_trace); 1095 cmd_install_priv("unprofile <str>", do_unprofile); 1096 cmd_install_priv("untrace <str>", do_untrace); 1097 cmd_install_priv("update table <str>", do_update_table); 1098 1099 /* Unprivileged commands */ 1100 cmd_install("encrypt", do_encrypt); 1101 cmd_install("encrypt <str>", do_encrypt); 1102 cmd_install("spf walk", do_spf_walk); 1103 1104 if (strcmp(__progname, "mailq") == 0) 1105 return cmd_run(2, argv_mailq); 1106 if (strcmp(__progname, "smtpctl") == 0) 1107 return cmd_run(argc - 1, argv + 1); 1108 1109 errx(1, "unsupported mode"); 1110 return (0); 1111 } 1112 1113 void 1114 sendmail_compat(int argc, char **argv) 1115 { 1116 FILE *offlinefp = NULL; 1117 gid_t gid; 1118 int i, r; 1119 1120 if (strcmp(__progname, "sendmail") == 0 || 1121 strcmp(__progname, "send-mail") == 0) { 1122 /* 1123 * determine whether we are called with flags 1124 * that should invoke makemap/newaliases. 1125 */ 1126 for (i = 1; i < argc; i++) 1127 if (strncmp(argv[i], "-bi", 3) == 0) 1128 exit(makemap(P_SENDMAIL, argc, argv)); 1129 1130 if (!srv_connect()) 1131 offlinefp = offline_file(); 1132 1133 gid = getgid(); 1134 if (setresgid(gid, gid, gid) == -1) 1135 err(1, "setresgid"); 1136 1137 /* we'll reduce further down the road */ 1138 if (pledge("stdio rpath wpath cpath tmppath flock " 1139 "dns getpw recvfd", NULL) == -1) 1140 err(1, "pledge"); 1141 1142 sendmail = 1; 1143 exit(enqueue(argc, argv, offlinefp)); 1144 } else if (strcmp(__progname, "makemap") == 0) 1145 exit(makemap(P_MAKEMAP, argc, argv)); 1146 else if (strcmp(__progname, "newaliases") == 0) { 1147 r = makemap(P_NEWALIASES, argc, argv); 1148 /* 1149 * if server is available, notify of table update. 1150 * only makes sense for static tables AND if server is up. 1151 */ 1152 if (srv_connect()) { 1153 srv_send(IMSG_CTL_UPDATE_TABLE, "aliases", strlen("aliases") + 1); 1154 srv_check_result(0); 1155 } 1156 exit(r); 1157 } 1158 } 1159 1160 static void 1161 show_queue_envelope(struct envelope *e, int online) 1162 { 1163 const char *src = "?", *agent = "?"; 1164 char status[128], runstate[128], errline[LINE_MAX]; 1165 1166 status[0] = '\0'; 1167 1168 getflag(&e->flags, EF_BOUNCE, "bounce", status, sizeof(status)); 1169 getflag(&e->flags, EF_AUTHENTICATED, "auth", status, sizeof(status)); 1170 getflag(&e->flags, EF_INTERNAL, "internal", status, sizeof(status)); 1171 getflag(&e->flags, EF_SUSPEND, "suspend", status, sizeof(status)); 1172 getflag(&e->flags, EF_HOLD, "hold", status, sizeof(status)); 1173 1174 if (online) { 1175 if (e->flags & EF_PENDING) 1176 (void)snprintf(runstate, sizeof runstate, "pending|%zd", 1177 (ssize_t)(e->nexttry - now)); 1178 else if (e->flags & EF_INFLIGHT) 1179 (void)snprintf(runstate, sizeof runstate, 1180 "inflight|%zd", (ssize_t)(now - e->lasttry)); 1181 else 1182 (void)snprintf(runstate, sizeof runstate, "invalid|"); 1183 e->flags &= ~(EF_PENDING|EF_INFLIGHT); 1184 } 1185 else 1186 (void)strlcpy(runstate, "offline|", sizeof runstate); 1187 1188 if (e->flags) 1189 errx(1, "%016" PRIx64 ": unexpected flags 0x%04x", e->id, 1190 e->flags); 1191 1192 if (status[0]) 1193 status[strlen(status) - 1] = '\0'; 1194 1195 if (e->type == D_MDA) 1196 agent = "mda"; 1197 else if (e->type == D_MTA) 1198 agent = "mta"; 1199 else if (e->type == D_BOUNCE) 1200 agent = "bounce"; 1201 1202 if (e->ss.ss_family == AF_LOCAL) 1203 src = "local"; 1204 else if (e->ss.ss_family == AF_INET) 1205 src = "inet4"; 1206 else if (e->ss.ss_family == AF_INET6) 1207 src = "inet6"; 1208 1209 strnvis(errline, e->errorline, sizeof(errline), 0); 1210 1211 printf("%016"PRIx64 1212 "|%s|%s|%s|%s@%s|%s@%s|%s@%s" 1213 "|%zu|%zu|%zu|%zu|%s|%s\n", 1214 1215 e->id, 1216 1217 src, 1218 agent, 1219 status, 1220 e->sender.user, e->sender.domain, 1221 e->rcpt.user, e->rcpt.domain, 1222 e->dest.user, e->dest.domain, 1223 1224 (size_t) e->creation, 1225 (size_t) (e->creation + e->ttl), 1226 (size_t) e->lasttry, 1227 (size_t) e->retry, 1228 runstate, 1229 errline); 1230 } 1231 1232 static void 1233 getflag(uint *bitmap, int bit, char *bitstr, char *buf, size_t len) 1234 { 1235 if (*bitmap & bit) { 1236 *bitmap &= ~bit; 1237 (void)strlcat(buf, bitstr, len); 1238 (void)strlcat(buf, ",", len); 1239 } 1240 } 1241 1242 static void 1243 show_offline_envelope(uint64_t evpid) 1244 { 1245 FILE *fp = NULL; 1246 char pathname[PATH_MAX]; 1247 size_t plen; 1248 char *p; 1249 size_t buflen; 1250 char buffer[sizeof(struct envelope)]; 1251 1252 struct envelope evp; 1253 1254 if (!bsnprintf(pathname, sizeof pathname, 1255 "/queue/%02x/%08x/%016"PRIx64, 1256 (evpid_to_msgid(evpid) & 0xff000000) >> 24, 1257 evpid_to_msgid(evpid), evpid)) 1258 goto end; 1259 fp = fopen(pathname, "r"); 1260 if (fp == NULL) 1261 goto end; 1262 1263 buflen = fread(buffer, 1, sizeof (buffer) - 1, fp); 1264 p = buffer; 1265 plen = buflen; 1266 buffer[buflen] = '\0'; 1267 1268 if (is_encrypted_buffer(p)) { 1269 warnx("offline encrypted queue is not supported yet"); 1270 goto end; 1271 } 1272 1273 if (is_gzip_buffer(p)) { 1274 warnx("offline compressed queue is not supported yet"); 1275 goto end; 1276 } 1277 1278 if (!envelope_load_buffer(&evp, p, plen)) 1279 goto end; 1280 evp.id = evpid; 1281 show_queue_envelope(&evp, 0); 1282 1283 end: 1284 if (fp) 1285 fclose(fp); 1286 } 1287 1288 static void 1289 display(const char *s) 1290 { 1291 FILE *fp; 1292 char *key; 1293 int gzipped; 1294 char *gzcat_argv0 = strrchr(PATH_GZCAT, '/') + 1; 1295 1296 if ((fp = fopen(s, "r")) == NULL) 1297 err(1, "fopen"); 1298 1299 if (is_encrypted_fp(fp)) { 1300 int i; 1301 FILE *ofp = NULL; 1302 1303 if ((ofp = tmpfile()) == NULL) 1304 err(1, "tmpfile"); 1305 1306 for (i = 0; i < 3; i++) { 1307 key = getpass("key> "); 1308 if (crypto_setup(key, strlen(key))) 1309 break; 1310 } 1311 if (i == 3) 1312 errx(1, "crypto-setup: invalid key"); 1313 1314 if (!crypto_decrypt_file(fp, ofp)) { 1315 printf("object is encrypted: %s\n", key); 1316 exit(1); 1317 } 1318 1319 fclose(fp); 1320 fp = ofp; 1321 fseek(fp, 0, SEEK_SET); 1322 } 1323 gzipped = is_gzip_fp(fp); 1324 1325 lseek(fileno(fp), 0, SEEK_SET); 1326 (void)dup2(fileno(fp), STDIN_FILENO); 1327 if (gzipped) 1328 execl(PATH_GZCAT, gzcat_argv0, (char *)NULL); 1329 else 1330 execl(PATH_CAT, "cat", (char *)NULL); 1331 err(1, "execl"); 1332 } 1333 1334 static int 1335 str_to_trace(const char *str) 1336 { 1337 if (!strcmp(str, "imsg")) 1338 return TRACE_IMSG; 1339 if (!strcmp(str, "io")) 1340 return TRACE_IO; 1341 if (!strcmp(str, "smtp")) 1342 return TRACE_SMTP; 1343 if (!strcmp(str, "filters")) 1344 return TRACE_FILTERS; 1345 if (!strcmp(str, "mta")) 1346 return TRACE_MTA; 1347 if (!strcmp(str, "bounce")) 1348 return TRACE_BOUNCE; 1349 if (!strcmp(str, "scheduler")) 1350 return TRACE_SCHEDULER; 1351 if (!strcmp(str, "lookup")) 1352 return TRACE_LOOKUP; 1353 if (!strcmp(str, "stat")) 1354 return TRACE_STAT; 1355 if (!strcmp(str, "rules")) 1356 return TRACE_RULES; 1357 if (!strcmp(str, "mproc")) 1358 return TRACE_MPROC; 1359 if (!strcmp(str, "expand")) 1360 return TRACE_EXPAND; 1361 if (!strcmp(str, "all")) 1362 return ~TRACE_DEBUG; 1363 errx(1, "invalid trace keyword: %s", str); 1364 return (0); 1365 } 1366 1367 static int 1368 str_to_profile(const char *str) 1369 { 1370 if (!strcmp(str, "imsg")) 1371 return PROFILE_IMSG; 1372 if (!strcmp(str, "queue")) 1373 return PROFILE_QUEUE; 1374 errx(1, "invalid profile keyword: %s", str); 1375 return (0); 1376 } 1377 1378 static int 1379 is_gzip_buffer(const char *buffer) 1380 { 1381 uint16_t magic; 1382 1383 memcpy(&magic, buffer, sizeof magic); 1384 #define GZIP_MAGIC 0x8b1f 1385 return (magic == GZIP_MAGIC); 1386 } 1387 1388 static int 1389 is_gzip_fp(FILE *fp) 1390 { 1391 uint8_t magic[2]; 1392 int ret = 0; 1393 1394 if (fread(&magic, 1, sizeof magic, fp) != sizeof magic) 1395 goto end; 1396 1397 ret = is_gzip_buffer((const char *)&magic); 1398 end: 1399 fseek(fp, 0, SEEK_SET); 1400 return ret; 1401 } 1402 1403 1404 /* XXX */ 1405 /* 1406 * queue supports transparent encryption. 1407 * encrypted chunks are prefixed with an API version byte 1408 * which we ensure is unambiguous with gzipped / plain 1409 * objects. 1410 */ 1411 1412 static int 1413 is_encrypted_buffer(const char *buffer) 1414 { 1415 uint8_t magic; 1416 1417 magic = *buffer; 1418 #define ENCRYPTION_MAGIC 0x1 1419 return (magic == ENCRYPTION_MAGIC); 1420 } 1421 1422 static int 1423 is_encrypted_fp(FILE *fp) 1424 { 1425 uint8_t magic; 1426 int ret = 0; 1427 1428 if (fread(&magic, 1, sizeof magic, fp) != sizeof magic) 1429 goto end; 1430 1431 ret = is_encrypted_buffer((const char *)&magic); 1432 end: 1433 fseek(fp, 0, SEEK_SET); 1434 return ret; 1435 } 1436