diff options
author | Eric Faurot <eric@cvs.openbsd.org> | 2018-01-26 08:00:55 +0000 |
---|---|---|
committer | Eric Faurot <eric@cvs.openbsd.org> | 2018-01-26 08:00:55 +0000 |
commit | e5aed0e9a38502ce8a5f3060cfa5b5d855c8ea1a (patch) | |
tree | 8717e68c91de98b0c239f58b4ba08d226e8021ac | |
parent | db77752d9acc5275491544bed0fb4569b422db8f (diff) |
allow unpriviledged user to run "encrypt" and "spf walk"
ok todd@, gilles@, sunil@
-rw-r--r-- | usr.sbin/smtpd/smtpctl.c | 137 | ||||
-rw-r--r-- | usr.sbin/smtpd/spfwalk.c | 14 |
2 files changed, 90 insertions, 61 deletions
diff --git a/usr.sbin/smtpd/smtpctl.c b/usr.sbin/smtpd/smtpctl.c index ec2320b0a31..5642d1b5da2 100644 --- a/usr.sbin/smtpd/smtpctl.c +++ b/usr.sbin/smtpd/smtpctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: smtpctl.c,v 1.155 2018/01/06 07:59:27 sunil Exp $ */ +/* $OpenBSD: smtpctl.c,v 1.156 2018/01/26 08:00:54 eric Exp $ */ /* * Copyright (c) 2013 Eric Faurot <eric@openbsd.org> @@ -69,7 +69,7 @@ static int is_gzip_buffer(const char *); static FILE *offline_file(void); static void sendmail_compat(int, char **); -extern int do_spfwalk(int, struct parameter *); +extern int spfwalk(int, struct parameter *); extern char *__progname; int sendmail; @@ -478,6 +478,29 @@ srv_show_cmd(int cmd, const void *data, size_t len) } while (!done); } +static void +droppriv(void) +{ + struct passwd *pw; + + if (geteuid()) + return; + + if ((pw = getpwnam(SMTPD_USER)) == NULL) + errx(1, "unknown user " SMTPD_USER); + + if ((setgroups(1, &pw->pw_gid) || + setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) || + setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))) + err(1, "cannot drop privileges"); +} + +static int +do_permission_denied(int argc, struct parameter *argv) +{ + errx(1, "need root privileges"); +} + static int do_log_brief(int argc, struct parameter *argv) { @@ -906,6 +929,8 @@ do_encrypt(int argc, struct parameter *argv) { const char *p = NULL; + droppriv(); + if (argv) p = argv[0].u.u_str; execl(PATH_ENCRYPT, "encrypt", p, (char *)NULL); @@ -1014,67 +1039,81 @@ do_uncorrupt(int argc, struct parameter *argv) return (0); } +static int +do_spf_walk(int argc, struct parameter *argv) +{ + droppriv(); + + return spfwalk(argc, argv); +} + +#define cmd_install_priv(s, f) \ + cmd_install((s), privileged ? (f) : do_permission_denied) + int main(int argc, char **argv) { gid_t gid; + int privileged; char *argv_mailq[] = { "show", "queue", NULL }; sendmail_compat(argc, argv); - if (geteuid()) - errx(1, "need root privileges"); + privileged = geteuid() == 0; gid = getgid(); if (setresgid(gid, gid, gid) == -1) err(1, "setresgid"); - cmd_install("discover <evpid>", do_discover); - cmd_install("discover <msgid>", do_discover); + /* Privileged commands */ + cmd_install_priv("discover <evpid>", do_discover); + cmd_install_priv("discover <msgid>", do_discover); + cmd_install_priv("pause mta from <addr> for <str>", do_block_mta); + cmd_install_priv("resume mta from <addr> for <str>", do_unblock_mta); + cmd_install_priv("show mta paused", do_show_mta_block); + cmd_install_priv("log brief", do_log_brief); + cmd_install_priv("log verbose", do_log_verbose); + cmd_install_priv("monitor", do_monitor); + cmd_install_priv("pause envelope <evpid>", do_pause_envelope); + cmd_install_priv("pause envelope <msgid>", do_pause_envelope); + cmd_install_priv("pause envelope all", do_pause_envelope); + cmd_install_priv("pause mda", do_pause_mda); + cmd_install_priv("pause mta", do_pause_mta); + cmd_install_priv("pause smtp", do_pause_smtp); + cmd_install_priv("profile <str>", do_profile); + cmd_install_priv("remove <evpid>", do_remove); + cmd_install_priv("remove <msgid>", do_remove); + cmd_install_priv("remove all", do_remove); + cmd_install_priv("resume envelope <evpid>", do_resume_envelope); + cmd_install_priv("resume envelope <msgid>", do_resume_envelope); + cmd_install_priv("resume envelope all", do_resume_envelope); + cmd_install_priv("resume mda", do_resume_mda); + cmd_install_priv("resume mta", do_resume_mta); + cmd_install_priv("resume route <routeid>", do_resume_route); + cmd_install_priv("resume smtp", do_resume_smtp); + cmd_install_priv("schedule <msgid>", do_schedule); + cmd_install_priv("schedule <evpid>", do_schedule); + cmd_install_priv("schedule all", do_schedule); + cmd_install_priv("show envelope <evpid>", do_show_envelope); + cmd_install_priv("show hoststats", do_show_hoststats); + cmd_install_priv("show message <msgid>", do_show_message); + cmd_install_priv("show message <evpid>", do_show_message); + cmd_install_priv("show queue", do_show_queue); + cmd_install_priv("show queue <msgid>", do_show_queue); + cmd_install_priv("show hosts", do_show_hosts); + cmd_install_priv("show relays", do_show_relays); + cmd_install_priv("show routes", do_show_routes); + cmd_install_priv("show stats", do_show_stats); + cmd_install_priv("show status", do_show_status); + cmd_install_priv("trace <str>", do_trace); + cmd_install_priv("uncorrupt <msgid>", do_uncorrupt); + cmd_install_priv("unprofile <str>", do_unprofile); + cmd_install_priv("untrace <str>", do_untrace); + cmd_install_priv("update table <str>", do_update_table); + + /* Unprivileged commands */ cmd_install("encrypt", do_encrypt); cmd_install("encrypt <str>", do_encrypt); - cmd_install("pause mta from <addr> for <str>", do_block_mta); - cmd_install("resume mta from <addr> for <str>", do_unblock_mta); - cmd_install("show mta paused", do_show_mta_block); - cmd_install("log brief", do_log_brief); - cmd_install("log verbose", do_log_verbose); - cmd_install("monitor", do_monitor); - cmd_install("pause envelope <evpid>", do_pause_envelope); - cmd_install("pause envelope <msgid>", do_pause_envelope); - cmd_install("pause envelope all", do_pause_envelope); - cmd_install("pause mda", do_pause_mda); - cmd_install("pause mta", do_pause_mta); - cmd_install("pause smtp", do_pause_smtp); - cmd_install("profile <str>", do_profile); - cmd_install("remove <evpid>", do_remove); - cmd_install("remove <msgid>", do_remove); - cmd_install("remove all", do_remove); - cmd_install("resume envelope <evpid>", do_resume_envelope); - cmd_install("resume envelope <msgid>", do_resume_envelope); - cmd_install("resume envelope all", do_resume_envelope); - cmd_install("resume mda", do_resume_mda); - cmd_install("resume mta", do_resume_mta); - cmd_install("resume route <routeid>", do_resume_route); - cmd_install("resume smtp", do_resume_smtp); - cmd_install("schedule <msgid>", do_schedule); - cmd_install("schedule <evpid>", do_schedule); - cmd_install("schedule all", do_schedule); - cmd_install("show envelope <evpid>", do_show_envelope); - cmd_install("show hoststats", do_show_hoststats); - cmd_install("show message <msgid>", do_show_message); - cmd_install("show message <evpid>", do_show_message); - cmd_install("show queue", do_show_queue); - cmd_install("show queue <msgid>", do_show_queue); - cmd_install("show hosts", do_show_hosts); - cmd_install("show relays", do_show_relays); - cmd_install("show routes", do_show_routes); - cmd_install("show stats", do_show_stats); - cmd_install("show status", do_show_status); - cmd_install("spf walk", do_spfwalk); - cmd_install("trace <str>", do_trace); - cmd_install("uncorrupt <msgid>", do_uncorrupt); - cmd_install("unprofile <str>", do_unprofile); - cmd_install("untrace <str>", do_untrace); - cmd_install("update table <str>", do_update_table); + cmd_install("spf walk", do_spf_walk); if (strcmp(__progname, "mailq") == 0) return cmd_run(2, argv_mailq); diff --git a/usr.sbin/smtpd/spfwalk.c b/usr.sbin/smtpd/spfwalk.c index 1e3ff8fbe67..46bff7086b9 100644 --- a/usr.sbin/smtpd/spfwalk.c +++ b/usr.sbin/smtpd/spfwalk.c @@ -25,7 +25,6 @@ #include <err.h> #include <errno.h> #include <event.h> -#include <pwd.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -36,7 +35,7 @@ #include "unpack_dns.h" #include "parser.h" -int do_spfwalk(int, struct parameter *); +int spfwalk(int, struct parameter *); static void dispatch_txt(struct dns_rr *); static void dispatch_mx(struct dns_rr *); @@ -51,9 +50,8 @@ int ip_v6 = 0; int ip_both = 1; int -do_spfwalk(int argc, struct parameter *argv) +spfwalk(int argc, struct parameter *argv) { - struct passwd *pw; const char *ip_family = NULL; char *line = NULL; size_t linesize = 0; @@ -76,14 +74,6 @@ do_spfwalk(int argc, struct parameter *argv) argv += optind; argc -= optind; - if ((pw = getpwnam(SMTPD_USER)) == NULL) - errx(1, "unknown user " SMTPD_USER); - - if (setgroups(1, &pw->pw_gid) || - setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) || - setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid)) - err(1, "do_spfwalk: cannot drop privileges"); - event_init(); while ((linelen = getline(&line, &linesize, stdin)) != -1) { |