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