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
usage(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
stat_increment(const char * k,size_t v)92 void stat_increment(const char *k, size_t v)
93 {
94 }
95
stat_decrement(const char * k,size_t v)96 void stat_decrement(const char *k, size_t v)
97 {
98 }
99
100 int
srv_connect(void)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
srv_connected(void)129 srv_connected(void)
130 {
131 return ibuf != NULL ? 1 : 0;
132 }
133
134 FILE *
offline_file(void)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
srv_flush(void)161 srv_flush(void)
162 {
163 if (imsgbuf_flush(ibuf) == -1)
164 err(1, "write error");
165 }
166
167 static void
srv_send(int msg,const void * data,size_t len)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
srv_recv(int type)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
srv_read(void * dst,size_t sz)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
srv_get_int(int * i)218 srv_get_int(int *i)
219 {
220 srv_read(i, sizeof(*i));
221 }
222
223 static void
srv_get_time(time_t * t)224 srv_get_time(time_t *t)
225 {
226 srv_read(t, sizeof(*t));
227 }
228
229 static void
srv_get_evpid(uint64_t * evpid)230 srv_get_evpid(uint64_t *evpid)
231 {
232 srv_read(evpid, sizeof(*evpid));
233 }
234
235 static void
srv_get_string(const char ** s)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
srv_get_envelope(struct envelope * evp)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
srv_end(void)278 srv_end(void)
279 {
280 if (rlen)
281 errx(1, "bogus data");
282 imsg_free(&imsg);
283 }
284
285 static int
srv_check_result(int verbose_)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
srv_iter_messages(uint32_t * res)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
srv_iter_envelopes(uint32_t msgid,struct envelope * evp)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
srv_iter_evpids(uint32_t msgid,uint64_t * evpid,int * offset)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
srv_foreach_envelope(struct parameter * argv,int ctl,size_t * total,size_t * ok)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
srv_show_cmd(int cmd,const void * data,size_t len)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
droppriv(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
do_permission_denied(int argc,struct parameter * argv)503 do_permission_denied(int argc, struct parameter *argv)
504 {
505 errx(1, "need root privileges");
506 }
507
508 static int
do_log_brief(int argc,struct parameter * argv)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
do_log_verbose(int argc,struct parameter * argv)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
do_monitor(int argc,struct parameter * argv)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
do_pause_envelope(int argc,struct parameter * argv)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
do_pause_mda(int argc,struct parameter * argv)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
do_pause_mta(int argc,struct parameter * argv)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
do_pause_smtp(int argc,struct parameter * argv)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
do_profile(int argc,struct parameter * argv)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
do_remove(int argc,struct parameter * argv)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
do_resume_envelope(int argc,struct parameter * argv)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
do_resume_mda(int argc,struct parameter * argv)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
do_resume_mta(int argc,struct parameter * argv)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
do_resume_route(int argc,struct parameter * argv)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
do_resume_smtp(int argc,struct parameter * argv)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
do_schedule(int argc,struct parameter * argv)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
do_show_envelope(int argc,struct parameter * argv)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
do_show_hoststats(int argc,struct parameter * argv)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
do_show_message(int argc,struct parameter * argv)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
do_show_queue(int argc,struct parameter * argv)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
do_show_hosts(int argc,struct parameter * argv)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
do_show_relays(int argc,struct parameter * argv)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
do_show_routes(int argc,struct parameter * argv)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
do_show_stats(int argc,struct parameter * argv)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
do_show_status(int argc,struct parameter * argv)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
do_trace(int argc,struct parameter * argv)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
do_unprofile(int argc,struct parameter * argv)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
do_untrace(int argc,struct parameter * argv)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
do_update_table(int argc,struct parameter * argv)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
do_encrypt(int argc,struct parameter * argv)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
do_block_mta(int argc,struct parameter * argv)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
do_unblock_mta(int argc,struct parameter * argv)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
do_show_mta_block(int argc,struct parameter * argv)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
do_discover(int argc,struct parameter * argv)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
do_spf_walk(int argc,struct parameter * argv)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
main(int argc,char ** argv)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
sendmail_compat(int argc,char ** argv)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
show_queue_envelope(struct envelope * e,int online)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
getflag(uint * bitmap,int bit,char * bitstr,char * buf,size_t len)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
show_offline_envelope(uint64_t evpid)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
display(const char * s)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
str_to_trace(const char * str)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
str_to_profile(const char * str)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
is_gzip_buffer(const char * buffer)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
is_gzip_fp(FILE * fp)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
is_encrypted_buffer(const char * buffer)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
is_encrypted_fp(FILE * fp)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