renew the ticket. This is useful when continuing to run the command
without a valid ticket would be pointless.
+ After a SIGHUP or SIGTERM when not running a command, k5start and
+ krenew now clean up their PID files, if any, before exiting.
+
kstart 4.0 (2011-12-29)
Remove k4start from the distribution. I no longer have a Kerberos v4
the normal period; instead, shorten the wakeup period and keep retrying
until the error resolves itself.
- * Clean up the PID files and any temporary ticket cache on receipt of
- SIGHUP or SIGTERM rather than just exiting.
-
k5start:
* Attempt to renew the ticket before prompting the user for a new
*/
static volatile sig_atomic_t alarm_signaled = 0;
+/*
+ * Set when the program receives SIGHUP or SIGTERM to do cleanup and exit.
+ * These signal handlers are only used when we're not running a command, since
+ * running a command provides its own signal handlers.
+ */
+static volatile sig_atomic_t exit_signaled = 0;
+
/*
* Convert from a string to a number, checking errors, and return -1 on any
}
+/*
+ * Signal handler for SIGHUP and SIGTERM. Just sets the global sentinel
+ * variable.
+ */
+static void
+exit_handler(int s UNUSED)
+{
+ exit_signaled = 1;
+}
+
+
/*
* Get the principal name for the krbtgt ticket for the local realm. The
* caller is responsible for freeing the principal. Takes an existing
}
+/*
+ * Add a signal handler, exiting if there was a failure.
+ */
+static void
+add_handler(krb5_context ctx, struct config *config, void (*handler)(int),
+ int sig, const char *name)
+{
+ struct sigaction sa;
+
+ memset(&sa, 0, sizeof(sa));
+ sa.sa_handler = handler;
+ if (sigaction(sig, &sa, NULL) < 0) {
+ syswarn("cannot set %s handler", name);
+ exit_cleanup(ctx, config, 1);
+ }
+}
+
+
/*
* The primary entry point of the framework. Both k5start and krenew call
* this function after setting up the options and configuration to do the real
/* Loop if we're running as a daemon. */
if (config->keep_ticket > 0) {
struct timeval timeout;
- struct sigaction sa;
code = 0;
- memset(&sa, 0, sizeof(sa));
- sa.sa_handler = alarm_handler;
- if (sigaction(SIGALRM, &sa, NULL) < 0) {
- syswarn("cannot set SIGALRM handler");
- exit_cleanup(ctx, config, 1);
+ add_handler(ctx, config, alarm_handler, SIGALRM, "SIGALRM");
+ if (config->command == NULL) {
+ add_handler(ctx, config, exit_handler, SIGHUP, "SIGHUP");
+ add_handler(ctx, config, exit_handler, SIGTERM, "SIGTERM");
}
while (1) {
if (config->command != NULL) {
timeout.tv_sec = config->keep_ticket * 60;
timeout.tv_usec = 0;
select(0, NULL, NULL, NULL, &timeout);
+ if (exit_signaled)
+ exit_cleanup(ctx, config, 0);
code = ticket_expired(ctx, config);
if (alarm_signaled || code != 0) {
code = config->auth(ctx, config, code);
# Tests for k5start daemon functionality.
#
# Written by Russ Allbery <rra@stanford.edu>
-# Copyright 2008, 2009, 2011
+# Copyright 2008, 2009, 2011, 2012
# The Board of Trustees of the Leland Stanford Junior University
#
# See LICENSE for licensing terms.
# Decide whether we have the configuration to run the tests.
if (-f "$DATA/test.keytab" and -f "$DATA/test.principal") {
- plan tests => 72;
+ plan tests => 76;
} else {
plan skip_all => "no keytab configuration";
exit 0;
like ($service, qr%^krbtgt/%, ' and the right service');
kill (15, $pid) or warn "Can't kill $pid: $!\n";
is (waitpid ($pid, 0), $pid, ' and k5start dies after SIGTERM');
-unlink "$TMP/pid";
+ok (!-f "$TMP/pid", ' and the PID file was removed');
# Try again with the -b flag.
unlink "$TMP/krb5cc_test";
$pid = contents ("$TMP/pid");
ok (kill (0, $pid), ' and the PID file is correct');
kill (15, $pid) or warn "Can't kill $pid: $!\n";
-unlink "$TMP/pid";
+select (undef, undef, undef, 0.2);
+ok (!-f "$TMP/pid", ' and the PID file was removed');
# Check that k5start keeps running if the ticket cache directory is not
# writeable.
}
unlink "$TMP/k5start-errors";
kill (15, $pid) or warn "Can't kill $pid: $!\n";
-unlink "$TMP/pid";
+is (waitpid ($pid, 0), $pid, ' and k5start dies after SIGTERM');
+ok (!-f "$TMP/pid", ' and the PID file was removed');
# If we do that again with -x, k5start should exit.
($out, $err, $status)
plan skip_all => 'cannot get renewable tickets';
exit 0;
}
- plan tests => 90;
+ plan tests => 94;
}
# Start a krenew daemon and be sure it gets tickets and stays running.
kill (15, $pid) or warn "Can't kill $pid: $!\n";
select (undef, undef, undef, 0.5);
ok (!kill (0, $pid), ' and it dies after SIGTERM');
-unlink "$TMP/pid";
+ok (!-f "$TMP/pid", ' and the PID file was removed');
# Now try with -i. In this case, krenew should keep running even if the
# ticket cache disappears and be able to start refreshing it again when it
kill (15, $pid) or warn "Can't kill $pid: $!\n";
select (undef, undef, undef, 0.5);
ok (!kill (0, $pid), ' and it dies after SIGTERM');
-unlink "$TMP/pid";
+ok (!-f "$TMP/pid", ' and the PID file was removed');
# Check that krenew keeps running if the ticket cache directory is not
# writeable.
}
unlink "$TMP/krenew-errors";
kill (15, $pid) or warn "Can't kill $pid: $!\n";
-unlink "$TMP/pid";
+is (waitpid ($pid, 0), $pid, ' and it dies on SIGTERM');
+ok (!-f "$TMP/pid", ' and the PID file was removed');
# If we do that again with -x, krenew should exit.
($out, $err, $status) = command ($KRENEW, '-xbK', 30, '-p', "$TMP/pid");