summaryrefslogtreecommitdiff
path: root/usr.sbin/smtpd
diff options
context:
space:
mode:
authorGilles Chehade <gilles@cvs.openbsd.org>2014-04-01 09:00:47 +0000
committerGilles Chehade <gilles@cvs.openbsd.org>2014-04-01 09:00:47 +0000
commitf5c55fbf4e53f27f17ebeb0719e7af94f08cc3d2 (patch)
treeffbe295fb08a0eee27a5678a18343cdafa347c27 /usr.sbin/smtpd
parentd263b6b4230cd61756b4c086ba62f5ee94d333c1 (diff)
cleanup forkmda() and get rid of a useless seteuid()-based dance
prompted by deraadt@, ok eric@
Diffstat (limited to 'usr.sbin/smtpd')
-rw-r--r--usr.sbin/smtpd/delivery.c5
-rw-r--r--usr.sbin/smtpd/smtpd.c46
2 files changed, 19 insertions, 32 deletions
diff --git a/usr.sbin/smtpd/delivery.c b/usr.sbin/smtpd/delivery.c
index 7e0519b953f..bc693e86035 100644
--- a/usr.sbin/smtpd/delivery.c
+++ b/usr.sbin/smtpd/delivery.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: delivery.c,v 1.4 2013/05/24 17:03:14 eric Exp $ */
+/* $OpenBSD: delivery.c,v 1.5 2014/04/01 09:00:46 gilles Exp $ */
/*
* Copyright (c) 2011 Gilles Chehade <gilles@poolp.org>
@@ -54,8 +54,7 @@ delivery_backend_lookup(enum action_type type)
case A_LMTP:
return &delivery_backend_lmtp;
default:
- fatal("unsupported delivery_backend type");
+ break;
}
-
return NULL;
}
diff --git a/usr.sbin/smtpd/smtpd.c b/usr.sbin/smtpd/smtpd.c
index 77b25701558..0eec8b54a91 100644
--- a/usr.sbin/smtpd/smtpd.c
+++ b/usr.sbin/smtpd/smtpd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: smtpd.c,v 1.215 2014/03/24 14:55:12 gilles Exp $ */
+/* $OpenBSD: smtpd.c,v 1.216 2014/04/01 09:00:46 gilles Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@poolp.org>
@@ -833,8 +833,14 @@ forkmda(struct mproc *p, uint64_t id, struct deliver *deliver)
": \"%s\" as %s", id, deliver->to, deliver->user);
db = delivery_backend_lookup(deliver->mode);
- if (db == NULL)
+ if (db == NULL) {
+ snprintf(ebuf, sizeof ebuf, "could not find delivery backend");
+ m_create(p_mda, IMSG_MDA_DONE, 0, 0, -1);
+ m_add_id(p_mda, id);
+ m_add_string(p_mda, ebuf);
+ m_close(p_mda);
return;
+ }
if (deliver->userinfo.uid == 0 && ! db->allow_root) {
snprintf(ebuf, sizeof ebuf, "not allowed to deliver to: %s",
@@ -846,14 +852,8 @@ forkmda(struct mproc *p, uint64_t id, struct deliver *deliver)
return;
}
- /* lower privs early to allow fork fail due to ulimit */
- if (seteuid(deliver->userinfo.uid) < 0)
- fatal("smtpd: forkmda: cannot lower privileges");
-
if (pipe(pipefd) < 0) {
snprintf(ebuf, sizeof ebuf, "pipe: %s", strerror(errno));
- if (seteuid(0) < 0)
- fatal("smtpd: forkmda: cannot restore privileges");
m_create(p_mda, IMSG_MDA_DONE, 0, 0, -1);
m_add_id(p_mda, id);
m_add_string(p_mda, ebuf);
@@ -868,8 +868,6 @@ forkmda(struct mproc *p, uint64_t id, struct deliver *deliver)
umask(omode);
if (allout < 0) {
snprintf(ebuf, sizeof ebuf, "mkstemp: %s", strerror(errno));
- if (seteuid(0) < 0)
- fatal("smtpd: forkmda: cannot restore privileges");
m_create(p_mda, IMSG_MDA_DONE, 0, 0, -1);
m_add_id(p_mda, id);
m_add_string(p_mda, ebuf);
@@ -883,8 +881,6 @@ forkmda(struct mproc *p, uint64_t id, struct deliver *deliver)
pid = fork();
if (pid < 0) {
snprintf(ebuf, sizeof ebuf, "fork: %s", strerror(errno));
- if (seteuid(0) < 0)
- fatal("smtpd: forkmda: cannot restore privileges");
m_create(p_mda, IMSG_MDA_DONE, 0, 0, -1);
m_add_id(p_mda, id);
m_add_string(p_mda, ebuf);
@@ -897,8 +893,6 @@ forkmda(struct mproc *p, uint64_t id, struct deliver *deliver)
/* parent passes the child fd over to mda */
if (pid > 0) {
- if (seteuid(0) < 0)
- fatal("smtpd: forkmda: cannot restore privileges");
child = child_add(pid, CHILD_MDA, NULL);
child->mda_out = allout;
child->mda_id = id;
@@ -909,38 +903,32 @@ forkmda(struct mproc *p, uint64_t id, struct deliver *deliver)
return;
}
-#define error(m) { perror(m); _exit(1); }
- if (seteuid(0) < 0)
- error("forkmda: cannot restore privileges");
if (chdir(deliver->userinfo.directory) < 0 && chdir("/") < 0)
- error("chdir");
+ err(1, "chdir");
+ if (setgroups(1, &deliver->userinfo.gid) ||
+ setresgid(deliver->userinfo.gid, deliver->userinfo.gid, deliver->userinfo.gid) ||
+ setresuid(deliver->userinfo.uid, deliver->userinfo.uid, deliver->userinfo.uid))
+ err(1, "forkmda: cannot drop privileges");
if (dup2(pipefd[0], STDIN_FILENO) < 0 ||
dup2(allout, STDOUT_FILENO) < 0 ||
dup2(allout, STDERR_FILENO) < 0)
- error("forkmda: dup2");
+ err(1, "forkmda: dup2");
if (closefrom(STDERR_FILENO + 1) < 0)
- error("closefrom");
- if (setgroups(1, &deliver->userinfo.gid) ||
- setresgid(deliver->userinfo.gid, deliver->userinfo.gid, deliver->userinfo.gid) ||
- setresuid(deliver->userinfo.uid, deliver->userinfo.uid, deliver->userinfo.uid))
- error("forkmda: cannot drop privileges");
+ err(1, "closefrom");
if (setsid() < 0)
- error("setsid");
+ err(1, "setsid");
if (signal(SIGPIPE, SIG_DFL) == SIG_ERR ||
signal(SIGINT, SIG_DFL) == SIG_ERR ||
signal(SIGTERM, SIG_DFL) == SIG_ERR ||
signal(SIGCHLD, SIG_DFL) == SIG_ERR ||
signal(SIGHUP, SIG_DFL) == SIG_ERR)
- error("signal");
+ err(1, "signal");
/* avoid hangs by setting 5m timeout */
alarm(300);
db->open(deliver);
-
- error("forkmda: unknown mode");
}
-#undef error
static void
offline_scan(int fd, short ev, void *arg)