summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--misc.c20
-rw-r--r--misc.h3
-rw-r--r--sshd.c15
3 files changed, 29 insertions, 9 deletions
diff --git a/misc.c b/misc.c
index 07d4179e..65c9222a 100644
--- a/misc.c
+++ b/misc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: misc.c,v 1.106 2016/10/23 22:04:05 dtucker Exp $ */
+/* $OpenBSD: misc.c,v 1.107 2016/11/30 00:28:31 dtucker Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
* Copyright (c) 2005,2006 Damien Miller. All rights reserved.
@@ -1251,3 +1251,21 @@ bind_permitted(int port, uid_t uid)
return 0;
return 1;
}
+
+/* returns 1 if process is already daemonized, 0 otherwise */
+int
+daemonized(void)
+{
+ int fd;
+
+ if ((fd = open(_PATH_TTY, O_RDONLY | O_NOCTTY)) >= 0) {
+ close(fd);
+ return 0; /* have controlling terminal */
+ }
+ if (getppid() != 1)
+ return 0; /* parent is not init */
+ if (getsid(0) != getpid())
+ return 0; /* not session leader */
+ debug3("already daemonized");
+ return 1;
+}
diff --git a/misc.h b/misc.h
index 3578e8ef..c242f901 100644
--- a/misc.h
+++ b/misc.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: misc.h,v 1.60 2016/10/23 22:04:05 dtucker Exp $ */
+/* $OpenBSD: misc.h,v 1.61 2016/11/30 00:28:31 dtucker Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -31,6 +31,7 @@ struct Forward {
int forward_equals(const struct Forward *, const struct Forward *);
int bind_permitted(int, uid_t);
+int daemonized(void);
/* Common server and client forwarding options. */
struct ForwardOptions {
diff --git a/sshd.c b/sshd.c
index ce4a493e..fafcd340 100644
--- a/sshd.c
+++ b/sshd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshd.c,v 1.477 2016/11/29 03:54:50 dtucker Exp $ */
+/* $OpenBSD: sshd.c,v 1.478 2016/11/30 00:28:31 dtucker Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -1343,7 +1343,7 @@ main(int ac, char **av)
struct ssh *ssh = NULL;
extern char *optarg;
extern int optind;
- int r, opt, i, j, on = 1;
+ int r, opt, i, j, on = 1, already_daemon;
int sock_in = -1, sock_out = -1, newsock = -1;
const char *remote_ip;
int remote_port;
@@ -1802,11 +1802,12 @@ main(int ac, char **av)
log_init(__progname, options.log_level, options.log_facility, log_stderr);
/*
- * If not in debugging mode, and not started from inetd, disconnect
- * from the controlling terminal, and fork. The original process
- * exits.
+ * If not in debugging mode, not started from inetd and not already
+ * daemonized (eg re-exec via SIGHUP), disconnect from the controlling
+ * terminal, and fork. The original process exits.
*/
- if (!(debug_flag || inetd_flag || no_daemon_flag)) {
+ already_daemon = daemonized();
+ if (!(debug_flag || inetd_flag || no_daemon_flag || already_daemon)) {
if (daemon(0, 0) < 0)
fatal("daemon() failed: %.200s", strerror(errno));
@@ -1840,7 +1841,7 @@ main(int ac, char **av)
* Write out the pid file after the sigterm handler
* is setup and the listen sockets are bound
*/
- if (options.pid_file != NULL && !debug_flag) {
+ if (options.pid_file != NULL && !debug_flag && !already_daemon) {
FILE *f = fopen(options.pid_file, "w");
if (f == NULL) {