summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorJeremie Courreges-Anglas <jca@cvs.openbsd.org>2016-03-31 23:00:47 +0000
committerJeremie Courreges-Anglas <jca@cvs.openbsd.org>2016-03-31 23:00:47 +0000
commit3c1e2cbfefb7201e2c5ce086d0b4b4cc9527713d (patch)
tree8e5b86b00824269ea63fb68c894fc89ea09115c9 /usr.sbin
parentc72e9d7421d8ee6b6c87822906d495370391a755 (diff)
Go in the background much later, to reduce possible silent failures.
rev. 1.34 moved the call to daemon() before the chroot, thus hiding errors if the target directory or _tftpd user don't exist. To go in the background later we need to preopen /dev/null. The code is put in a daemon(3) like function that could be used in other daemons. Lack of error reporting spotted by ajacoutot@, initial diff from dlg@. rdaemon() "concept" discussed with semarie@. ok ajacoutot@ dlg@
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/tftpd/tftpd.c42
1 files changed, 37 insertions, 5 deletions
diff --git a/usr.sbin/tftpd/tftpd.c b/usr.sbin/tftpd/tftpd.c
index d3d4ecbade6..5c4ac7a4830 100644
--- a/usr.sbin/tftpd/tftpd.c
+++ b/usr.sbin/tftpd/tftpd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tftpd.c,v 1.34 2015/12/14 16:34:55 semarie Exp $ */
+/* $OpenBSD: tftpd.c,v 1.35 2016/03/31 23:00:46 jca Exp $ */
/*
* Copyright (c) 2012 David Gwynne <dlg@uq.edu.au>
@@ -74,6 +74,7 @@
#include <errno.h>
#include <event.h>
#include <fcntl.h>
+#include <paths.h>
#include <poll.h>
#include <pwd.h>
#include <stdio.h>
@@ -152,6 +153,7 @@ struct tftp_client {
__dead void usage(void);
const char *getip(void *);
+int rdaemon(int devnull);
void rewrite_connect(const char *);
void rewrite_events(void);
@@ -285,6 +287,7 @@ main(int argc, char *argv[])
char *addr = NULL;
char *port = "tftp";
int family = AF_UNSPEC;
+ int devnull = -1;
while ((c = getopt(argc, argv, "46cdl:p:r:v")) != -1) {
switch (c) {
@@ -337,6 +340,9 @@ main(int argc, char *argv[])
openlog(__progname, LOG_PID|LOG_NDELAY, LOG_DAEMON);
tzset();
logger = &syslogger;
+ devnull = open(_PATH_DEVNULL, O_RDWR, 0);
+ if (devnull == -1)
+ err(1, "open %s", _PATH_DEVNULL);
}
if (rewrite != NULL)
@@ -344,9 +350,6 @@ main(int argc, char *argv[])
tftpd_listen(addr, port, family);
- if (!debug && daemon(1, 0) == -1)
- err(1, "unable to daemonize");
-
if (chroot(dir))
err(1, "chroot %s", dir);
if (chdir("/"))
@@ -358,8 +361,11 @@ main(int argc, char *argv[])
setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))
errx(1, "can't drop privileges");
+ if (!debug && rdaemon(devnull) == -1)
+ err(1, "unable to daemonize");
+
if (pledge("stdio rpath wpath cpath fattr dns inet", NULL) == -1)
- err(1, "pledge");
+ lerr(1, "pledge");
event_init();
@@ -1556,6 +1562,32 @@ getip(void *s)
return(hbuf);
}
+/* daemon(3) clone, intended to be used in a "r"estricted environment */
+int
+rdaemon(int devnull)
+{
+
+ switch (fork()) {
+ case -1:
+ return (-1);
+ case 0:
+ break;
+ default:
+ _exit(0);
+ }
+
+ if (setsid() == -1)
+ return (-1);
+
+ (void)dup2(devnull, STDIN_FILENO);
+ (void)dup2(devnull, STDOUT_FILENO);
+ (void)dup2(devnull, STDERR_FILENO);
+ if (devnull > 2)
+ (void)close(devnull);
+
+ return (0);
+}
+
void
syslog_vstrerror(int e, int priority, const char *fmt, va_list ap)
{