summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Miller <djm@cvs.openbsd.org>2005-10-31 11:48:30 +0000
committerDamien Miller <djm@cvs.openbsd.org>2005-10-31 11:48:30 +0000
commitdd89cbaa2f8a8eee27deccb1436d57f538e2429d (patch)
tree01e59ffeca01067633a70a30b7922fc0b2ec664b
parent9b2929588a4fd93855c17da3bf1ec6e8eac28ecc (diff)
make sure we clean up wtmp, etc. file when we receive a SIGTERM,
SIGINT or SIGQUIT when running without privilege separation (the normal privsep case is already OK). Patch mainly by dtucker@ and senthilkumar_sen AT hotpop.com; ok dtucker@
-rw-r--r--usr.bin/ssh/serverloop.c36
1 files changed, 35 insertions, 1 deletions
diff --git a/usr.bin/ssh/serverloop.c b/usr.bin/ssh/serverloop.c
index 9f98f9cd2ae..f31baaadc79 100644
--- a/usr.bin/ssh/serverloop.c
+++ b/usr.bin/ssh/serverloop.c
@@ -35,7 +35,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: serverloop.c,v 1.120 2005/10/30 08:52:17 djm Exp $");
+RCSID("$OpenBSD: serverloop.c,v 1.121 2005/10/31 11:48:29 djm Exp $");
#include "xmalloc.h"
#include "packet.h"
@@ -61,6 +61,7 @@ extern ServerOptions options;
/* XXX */
extern Kex *xxx_kex;
extern Authctxt *the_authctxt;
+extern int use_privsep;
static Buffer stdin_buffer; /* Buffer for stdin data. */
static Buffer stdout_buffer; /* Buffer for stdout data. */
@@ -90,6 +91,9 @@ static int client_alive_timeouts = 0;
static volatile sig_atomic_t child_terminated = 0; /* The child has terminated. */
+/* Cleanup on signals (!use_privsep case only) */
+static volatile sig_atomic_t received_sigterm = 0;
+
/* prototypes */
static void server_init_dispatch(void);
@@ -149,6 +153,12 @@ sigchld_handler(int sig)
errno = save_errno;
}
+static void
+sigterm_handler(int sig)
+{
+ received_sigterm = sig;
+}
+
/*
* Make packets from buffered stderr data, and buffer it for sending
* to the client.
@@ -500,6 +510,12 @@ server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg)
child_terminated = 0;
signal(SIGCHLD, sigchld_handler);
+ if (!use_privsep) {
+ signal(SIGTERM, sigterm_handler);
+ signal(SIGINT, sigterm_handler);
+ signal(SIGQUIT, sigterm_handler);
+ }
+
/* Initialize our global variables. */
fdin = fdin_arg;
fdout = fdout_arg;
@@ -627,6 +643,12 @@ server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg)
wait_until_can_do_something(&readset, &writeset, &max_fd,
&nalloc, max_time_milliseconds);
+ if (received_sigterm) {
+ logit("Exiting on signal %d", received_sigterm);
+ /* Clean up sessions, utmp, etc. */
+ cleanup_exit(255);
+ }
+
/* Process any channel events. */
channel_after_select(readset, writeset);
@@ -747,6 +769,12 @@ server_loop2(Authctxt *authctxt)
connection_in = packet_get_connection_in();
connection_out = packet_get_connection_out();
+ if (!use_privsep) {
+ signal(SIGTERM, sigterm_handler);
+ signal(SIGINT, sigterm_handler);
+ signal(SIGQUIT, sigterm_handler);
+ }
+
notify_setup();
max_fd = MAX(connection_in, connection_out);
@@ -764,6 +792,12 @@ server_loop2(Authctxt *authctxt)
wait_until_can_do_something(&readset, &writeset, &max_fd,
&nalloc, 0);
+ if (received_sigterm) {
+ logit("Exiting on signal %d", received_sigterm);
+ /* Clean up sessions, utmp, etc. */
+ cleanup_exit(255);
+ }
+
collect_children();
if (!rekeying) {
channel_after_select(readset, writeset);