summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremie Courreges-Anglas <jca@cvs.openbsd.org>2016-09-15 16:16:04 +0000
committerJeremie Courreges-Anglas <jca@cvs.openbsd.org>2016-09-15 16:16:04 +0000
commit59d8babc9d895cabb7c63196d27624ab1eec2987 (patch)
treef060a14d1edb14e41ef61f29b0bd8f5591042129
parentebe5ab80415dd7b9e17988cbf90476799118d89a (diff)
Go in the background later, using rdaemon().
rdaemon() works like daemon(3) but requires its caller to pre-open /dev/null. This makes it possible to go in the background after a chroot(2), allowing for more error checking. The pattern is basically - open /dev/null - chroot - privdrop - rdaemon "design" initialy discussed with semarie@ a while ago, ok dlg@
-rw-r--r--usr.sbin/dhcrelay/dhcrelay.c46
-rw-r--r--usr.sbin/ftp-proxy/ftp-proxy.c47
-rw-r--r--usr.sbin/rtadvd/rtadvd.c51
3 files changed, 123 insertions, 21 deletions
diff --git a/usr.sbin/dhcrelay/dhcrelay.c b/usr.sbin/dhcrelay/dhcrelay.c
index 88b1afda29d..54ee05a6fc3 100644
--- a/usr.sbin/dhcrelay/dhcrelay.c
+++ b/usr.sbin/dhcrelay/dhcrelay.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dhcrelay.c,v 1.41 2016/09/04 10:43:52 jca Exp $ */
+/* $OpenBSD: dhcrelay.c,v 1.42 2016/09/15 16:16:03 jca Exp $ */
/*
* Copyright (c) 2004 Henning Brauer <henning@cvs.openbsd.org>
@@ -48,6 +48,7 @@
#include <net/if.h>
#include <errno.h>
+#include <fcntl.h>
#include <netdb.h>
#include <paths.h>
#include <pwd.h>
@@ -62,6 +63,7 @@
#include "dhcpd.h"
void usage(void);
+int rdaemon(int);
void relay(struct interface_info *, struct dhcp_packet *, int,
unsigned int, struct iaddr, struct hardware *);
char *print_hw_addr(int, int, unsigned char *);
@@ -91,7 +93,7 @@ struct server_list {
int
main(int argc, char *argv[])
{
- int ch, daemonize, opt, rdomain;
+ int ch, devnull = -1, daemonize, opt, rdomain;
extern char *__progname;
struct server_list *sp = NULL;
struct passwd *pw;
@@ -158,8 +160,11 @@ main(int argc, char *argv[])
argv++;
}
- if (daemonize)
- log_perror = 0;
+ if (daemonize) {
+ devnull = open(_PATH_DEVNULL, O_RDWR, 0);
+ if (devnull == -1)
+ error("open(%s): %m", _PATH_DEVNULL);
+ }
if (interfaces == NULL)
error("no interface given");
@@ -230,8 +235,6 @@ main(int argc, char *argv[])
time(&cur_time);
bootp_packet_handler = relay;
- if (daemonize)
- daemon(0, 0);
if ((pw = getpwnam("_dhcp")) == NULL)
error("user \"_dhcp\" not found");
@@ -244,6 +247,12 @@ main(int argc, char *argv[])
setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))
error("can't drop privileges: %m");
+ if (daemonize) {
+ if (rdaemon(devnull) == -1)
+ error("rdaemon: %m");
+ log_perror = 0;
+ }
+
dispatch();
/* not reached */
@@ -356,6 +365,31 @@ usage(void)
exit(1);
}
+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);
+}
+
char *
print_hw_addr(int htype, int hlen, unsigned char *data)
{
diff --git a/usr.sbin/ftp-proxy/ftp-proxy.c b/usr.sbin/ftp-proxy/ftp-proxy.c
index 366a6fabcac..74216d0791f 100644
--- a/usr.sbin/ftp-proxy/ftp-proxy.c
+++ b/usr.sbin/ftp-proxy/ftp-proxy.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ftp-proxy.c,v 1.34 2016/02/12 08:12:48 ajacoutot Exp $ */
+/* $OpenBSD: ftp-proxy.c,v 1.35 2016/09/15 16:16:03 jca Exp $ */
/*
* Copyright (c) 2004, 2005 Camiel Dobbelaar, <cd@sentia.nl>
@@ -32,6 +32,7 @@
#include <event.h>
#include <fcntl.h>
#include <netdb.h>
+#include <paths.h>
#include <pwd.h>
#include <signal.h>
#include <stdarg.h>
@@ -101,6 +102,7 @@ void logmsg(int, const char *, ...);
u_int16_t parse_port(int);
u_int16_t pick_proxy_port(void);
void proxy_reply(int, struct sockaddr *, u_int16_t);
+int rdaemon(int);
void server_error(struct bufferevent *, short, void *);
int server_parse(struct session *s);
int allow_data_connection(struct session *s);
@@ -610,7 +612,7 @@ main(int argc, char *argv[])
struct rlimit rlp;
struct addrinfo hints, *res;
struct event ev_sighup, ev_sigint, ev_sigterm;
- int ch, error, listenfd, on;
+ int ch, devnull, error, listenfd, on;
const char *errstr;
/* Defaults. */
@@ -770,18 +772,22 @@ main(int argc, char *argv[])
init_filter(qname, tagname, verbose);
if (daemonize) {
- if (daemon(0, 0) == -1)
+ devnull = open(_PATH_DEVNULL, O_RDWR, 0);
+ if (devnull == -1)
+ err(1, "open(%s)", _PATH_DEVNULL);
+ }
+
+ if (!drop_privs())
+ err(1, "cannot drop privileges");
+
+ if (daemonize) {
+ if (rdaemon(devnull) == -1)
err(1, "cannot daemonize");
openlog(__progname, LOG_PID | LOG_NDELAY, LOG_DAEMON);
}
/* Use logmsg for output from here on. */
- if (!drop_privs()) {
- logmsg(LOG_ERR, "cannot drop privileges: %s", strerror(errno));
- exit(1);
- }
-
event_init();
/* Setup signal handler. */
@@ -1132,3 +1138,28 @@ usage(void)
" [-t timeout]\n", __progname);
exit(1);
}
+
+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);
+}
diff --git a/usr.sbin/rtadvd/rtadvd.c b/usr.sbin/rtadvd/rtadvd.c
index 8b8436cc6f0..b21ceeed070 100644
--- a/usr.sbin/rtadvd/rtadvd.c
+++ b/usr.sbin/rtadvd/rtadvd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rtadvd.c,v 1.78 2016/09/03 16:57:29 jca Exp $ */
+/* $OpenBSD: rtadvd.c,v 1.79 2016/09/15 16:16:03 jca Exp $ */
/* $KAME: rtadvd.c,v 1.66 2002/05/29 14:18:36 itojun Exp $ */
/*
@@ -55,6 +55,8 @@
#include <string.h>
#include <pwd.h>
#include <signal.h>
+#include <fcntl.h>
+#include <paths.h>
#include "rtadvd.h"
#include "advcap.h"
@@ -139,6 +141,7 @@ static int nd6_options(struct nd_opt_hdr *, int,
static void free_ndopts(union nd_opts *);
static void ra_output(struct rainfo *);
static struct rainfo *if_indextorainfo(int);
+static int rdaemon(int);
static void dump_cb(int, short, void *);
static void die_cb(int, short, void *);
@@ -151,6 +154,7 @@ main(int argc, char *argv[])
{
struct passwd *pw;
int ch;
+ int devnull = -1;
struct event ev_sock;
struct event ev_rtsock;
struct event ev_sigterm;
@@ -182,6 +186,12 @@ main(int argc, char *argv[])
if (argc == 0)
usage();
+ if (!dflag) {
+ devnull = open(_PATH_DEVNULL, O_RDWR, 0);
+ if (devnull == -1)
+ fatal("open(\"" _PATH_DEVNULL "\")");
+ }
+
SLIST_INIT(&ralist);
/* get iflist block from kernel */
@@ -196,12 +206,6 @@ main(int argc, char *argv[])
if (inet_pton(AF_INET6, ALLNODES, &sin6_allnodes.sin6_addr) != 1)
fatal("inet_pton failed");
- if (conffile != NULL)
- log_init(dflag);
-
- if (!dflag)
- daemon(1, 0);
-
sock_open();
if (sflag == 0)
@@ -218,6 +222,14 @@ main(int argc, char *argv[])
setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))
fatal("cannot drop privileges");
+ if (!dflag) {
+ if (rdaemon(devnull) == -1)
+ fatal("rdaemon");
+ }
+
+ if (conffile != NULL)
+ log_init(dflag);
+
if (pledge("stdio inet route", NULL) == -1)
err(1, "pledge");
@@ -1297,3 +1309,28 @@ ra_timer_update(struct rainfo *rai)
log_debug("RA timer on %s set to %lld.%lds", rai->ifname,
(long long)tm->tv_sec, tm->tv_usec);
}
+
+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);
+}