| Index: src/tcsd/svrside.c
|
| diff --git a/src/tcsd/svrside.c b/src/tcsd/svrside.c
|
| index d6a23123b19c48fe9317699e8680e8e6b12b59a3..27c18bf3fc8e4e817e3cff8e37457d9b679b6c45 100644
|
| --- a/src/tcsd/svrside.c
|
| +++ b/src/tcsd/svrside.c
|
| @@ -20,6 +20,7 @@
|
| #include <sys/stat.h>
|
| #include <sys/socket.h>
|
| #include <netdb.h>
|
| +#include <pwd.h>
|
| #if (defined (__OpenBSD__) || defined (__FreeBSD__))
|
| #include <netinet/in.h>
|
| #endif
|
| @@ -40,9 +41,11 @@
|
|
|
| struct tcsd_config tcsd_options;
|
| struct tpm_properties tpm_metrics;
|
| +static volatile int hup = 0, term = 0;
|
| +extern char *optarg;
|
|
|
| -void
|
| -tcsd_shutdown()
|
| +static void
|
| +tcsd_shutdown(void)
|
| {
|
| /* order is important here:
|
| * allow all threads to complete their current request */
|
| @@ -54,44 +57,27 @@ tcsd_shutdown()
|
| EVENT_LOG_final();
|
| }
|
|
|
| -void
|
| -tcsd_signal_int(int signal)
|
| +static void
|
| +tcsd_signal_term(int signal)
|
| {
|
| - switch (signal) {
|
| - case SIGINT:
|
| - LogInfo("Caught SIGINT. Cleaning up and exiting.");
|
| - break;
|
| - case SIGHUP:
|
| - LogInfo("Caught SIGHUP. Cleaning up and exiting.");
|
| - break;
|
| - default:
|
| - LogError("Caught signal %d (which I didn't register for!)."
|
| - " Ignoring.", signal);
|
| - break;
|
| - }
|
| - tcsd_shutdown();
|
| - exit(signal);
|
| + term = 1;
|
| }
|
|
|
| void
|
| -tcsd_signal_chld(int signal)
|
| +tcsd_signal_hup(int signal)
|
| {
|
| - /* kill zombies */
|
| - wait3(NULL, WNOHANG, NULL);
|
| + hup = 1;
|
| }
|
|
|
| -TSS_RESULT
|
| -signals_init()
|
| +static TSS_RESULT
|
| +signals_init(void)
|
| {
|
| int rc;
|
| sigset_t sigmask;
|
| + struct sigaction sa;
|
|
|
| sigemptyset(&sigmask);
|
| - if ((rc = sigaddset(&sigmask, SIGCHLD))) {
|
| - LogError("sigaddset: %s", strerror(errno));
|
| - return TCSERR(TSS_E_INTERNAL_ERROR);
|
| - }
|
| - if ((rc = sigaddset(&sigmask, SIGINT))) {
|
| + if ((rc = sigaddset(&sigmask, SIGTERM))) {
|
| LogError("sigaddset: %s", strerror(errno));
|
| return TCSERR(TSS_E_INTERNAL_ERROR);
|
| }
|
| @@ -105,30 +91,25 @@ signals_init()
|
| return TCSERR(TSS_E_INTERNAL_ERROR);
|
| }
|
|
|
| - tcsd_sa_int.sa_handler = tcsd_signal_int;
|
| - tcsd_sa_chld.sa_handler = tcsd_signal_chld;
|
| - tcsd_sa_chld.sa_flags = SA_RESTART;
|
| -
|
| - if ((rc = sigaction(SIGINT, &tcsd_sa_int, NULL))) {
|
| - LogError("signal SIGINT not registered: %s", strerror(errno));
|
| + sa.sa_flags = 0;
|
| + sigemptyset(&sa.sa_mask);
|
| + sa.sa_handler = tcsd_signal_term;
|
| + if ((rc = sigaction(SIGTERM, &sa, NULL))) {
|
| + LogError("signal SIGTERM not registered: %s", strerror(errno));
|
| return TCSERR(TSS_E_INTERNAL_ERROR);
|
| }
|
|
|
| - if ((rc = sigaction(SIGHUP, &tcsd_sa_int, NULL))) {
|
| + sa.sa_handler = tcsd_signal_hup;
|
| + if ((rc = sigaction(SIGHUP, &sa, NULL))) {
|
| LogError("signal SIGHUP not registered: %s", strerror(errno));
|
| return TCSERR(TSS_E_INTERNAL_ERROR);
|
| }
|
|
|
| - if ((rc = sigaction(SIGCHLD, &tcsd_sa_chld, NULL))) {
|
| - LogError("signal SIGCHLD not registered: %s", strerror(errno));
|
| - return TCSERR(TSS_E_INTERNAL_ERROR);
|
| - }
|
| -
|
| return TSS_SUCCESS;
|
| }
|
|
|
| -TSS_RESULT
|
| -tcsd_startup()
|
| +static TSS_RESULT
|
| +tcsd_startup(void)
|
| {
|
| TSS_RESULT result;
|
|
|
| @@ -202,16 +183,31 @@ tcsd_startup()
|
| return TSS_SUCCESS;
|
| }
|
|
|
| +
|
| void
|
| usage(void)
|
| {
|
| fprintf(stderr, "\tusage: tcsd [-f] [-h]\n\n");
|
| fprintf(stderr, "\t-f|--foreground\trun in the foreground. Logging goes to stderr "
|
| "instead of syslog.\n");
|
| + fprintf(stderr, "\t-e| attempts to connect to software TPMs over TCP");
|
| fprintf(stderr, "\t-h|--help\tdisplay this help message\n");
|
| fprintf(stderr, "\n");
|
| }
|
|
|
| +static TSS_RESULT
|
| +reload_config(void)
|
| +{
|
| + TSS_RESULT result;
|
| + hup = 0;
|
| +
|
| + // FIXME: reload the config - work in progress
|
| + result = TSS_SUCCESS;
|
| +
|
| + return result;
|
| +}
|
| +
|
| +
|
| int
|
| main(int argc, char **argv)
|
| {
|
| @@ -220,6 +216,7 @@ main(int argc, char **argv)
|
| int sd, newsd, c, option_index = 0;
|
| unsigned client_len;
|
| char *hostname = NULL;
|
| + struct passwd *pwd;
|
| struct hostent *client_hostent = NULL;
|
| struct option long_options[] = {
|
| {"help", 0, NULL, 'h'},
|
| @@ -227,13 +224,17 @@ main(int argc, char **argv)
|
| {0, 0, 0, 0}
|
| };
|
|
|
| - while ((c = getopt_long(argc, argv, "fh", long_options, &option_index)) != -1) {
|
| + unsetenv("TCSD_USE_TCP_DEVICE");
|
| + while ((c = getopt_long(argc, argv, "fhe", long_options, &option_index)) != -1) {
|
| switch (c) {
|
| case 'f':
|
| setenv("TCSD_FOREGROUND", "1", 1);
|
| break;
|
| case 'h':
|
| /* fall through */
|
| + case 'e':
|
| + setenv("TCSD_USE_TCP_DEVICE", "1", 1);
|
| + break;
|
| default:
|
| usage();
|
| return -1;
|
| @@ -244,14 +245,6 @@ main(int argc, char **argv)
|
| if ((result = tcsd_startup()))
|
| return (int)result;
|
|
|
| - if (getenv("TCSD_FOREGROUND") == NULL) {
|
| - if (daemon(0, 0) == -1) {
|
| - perror("daemon");
|
| - tcsd_shutdown();
|
| - return -1;
|
| - }
|
| - }
|
| -
|
| sd = socket(AF_INET, SOCK_STREAM, 0);
|
| if (sd < 0) {
|
| LogError("Failed socket: %s", strerror(errno));
|
| @@ -275,19 +268,51 @@ main(int argc, char **argv)
|
| LogError("Failed bind: %s", strerror(errno));
|
| return -1;
|
| }
|
| +#ifndef SOLARIS
|
| + pwd = getpwnam(TSS_USER_NAME);
|
| + if (pwd == NULL) {
|
| + if (errno == 0) {
|
| + LogError("User \"%s\" not found, please add this user"
|
| + " manually.", TSS_USER_NAME);
|
| + } else {
|
| + LogError("getpwnam(%s): %s", TSS_USER_NAME, strerror(errno));
|
| + }
|
| + return TCSERR(TSS_E_INTERNAL_ERROR);
|
| + }
|
| + setuid(pwd->pw_uid);
|
| +#endif
|
| if (listen(sd, TCSD_MAX_SOCKETS_QUEUED) < 0) {
|
| LogError("Failed listen: %s", strerror(errno));
|
| return -1;
|
| }
|
| client_len = (unsigned)sizeof(client_addr);
|
| +
|
| + if (getenv("TCSD_FOREGROUND") == NULL) {
|
| + if (daemon(0, 0) == -1) {
|
| + perror("daemon");
|
| + tcsd_shutdown();
|
| + return -1;
|
| + }
|
| + }
|
| +
|
| LogInfo("%s: TCSD up and running.", PACKAGE_STRING);
|
| do {
|
| newsd = accept(sd, (struct sockaddr *) &client_addr, &client_len);
|
| - LogDebug("accepted socket %i", newsd);
|
| if (newsd < 0) {
|
| - LogError("Failed accept: %s", strerror(errno));
|
| - break;
|
| + if (errno == EINTR) {
|
| + if (term)
|
| + break;
|
| + else if (hup) {
|
| + if (reload_config() != TSS_SUCCESS)
|
| + LogError("Failed reloading config");
|
| + }
|
| + continue;
|
| + } else {
|
| + LogError("Failed accept: %s", strerror(errno));
|
| + continue;
|
| + }
|
| }
|
| + LogDebug("accepted socket %i", newsd);
|
|
|
| if ((client_hostent = gethostbyaddr((char *) &client_addr.sin_addr,
|
| sizeof(client_addr.sin_addr),
|
| @@ -307,8 +332,12 @@ main(int argc, char **argv)
|
|
|
| tcsd_thread_create(newsd, hostname);
|
| hostname = NULL;
|
| - } while (1);
|
| + if (hup) {
|
| + if (reload_config() != TSS_SUCCESS)
|
| + LogError("Failed reloading config");
|
| + }
|
| + } while (term ==0);
|
|
|
| - /* To close correctly, we must recieve a SIGHUP */
|
| - return -1;
|
| + /* To close correctly, we must receive a SIGTERM */
|
| + return 0;
|
| }
|
|
|