diff options
author | Daniel Gollub <dgollub@att.com> | 2019-11-11 15:07:38 +0100 |
---|---|---|
committer | Vyatta Package Maintainers <DL-vyatta-help@att.com> | 2019-11-13 17:08:02 +0000 |
commit | 822c8f60b72cca97fb2c86db37835a60917d1c7e (patch) | |
tree | d5593a4ed1cbb8e9709411679974355a41f0289e /tacplus-daemon/main.c | |
download | tacplusd-822c8f60b72cca97fb2c86db37835a60917d1c7e.tar.gz tacplusd-822c8f60b72cca97fb2c86db37835a60917d1c7e.zip |
DANOS ImportHEADdebian/1.19danos/1908master
Diffstat (limited to 'tacplus-daemon/main.c')
-rw-r--r-- | tacplus-daemon/main.c | 192 |
1 files changed, 192 insertions, 0 deletions
diff --git a/tacplus-daemon/main.c b/tacplus-daemon/main.c new file mode 100644 index 0000000..46de2ba --- /dev/null +++ b/tacplus-daemon/main.c @@ -0,0 +1,192 @@ +/* + TACACS+ D-Bus Daemon code + + Copyright (c) 2018-2019, AT&T Intellectual Property. + Copyright (c) 2015 Brocade Communications Systems, Inc. + + SPDX-License-Identifier: GPL-2.0-only +*/ + +#include <pthread.h> + +#include "global.h" +#include "main.h" +#include "statistics.h" +#include "tacplus_srv_conn.h" + +/* + * TODO + * add license to all source files + */ + +static int run = 1; /* Initially to enter while loop */ +static int reload = 0; + +static ConnectionControl _connControl = { .state = { .offline = false } }; +ConnectionControl *connControl = &_connControl; + +static void signal_wait(sigset_t *set) +{ + int s, sig; + + for (;;) { + s = sigwait(set, &sig); + if (s != 0) { + syslog(LOG_ERR, "Signal handler sigwait() call returned error"); + } + syslog(LOG_DEBUG, "Signal handler received: %d\n", sig); + switch(sig) { + case SIGTERM: + syslog(LOG_DEBUG, "Signal handler caught SIGTERM"); + run = 0; + return; + + case SIGHUP: + syslog(LOG_DEBUG, "Signal handler caught SIGHUP"); + reload = 1; + return; + + default: + syslog(LOG_DEBUG, "Ignoring signal %d", sig); + break; + } + } +} + +static int setup_service(const char *tacplus_cfg) +{ + int ret = 0; + + /* enable read timeout handling */ + tac_enable_readtimeout(1); + +#ifndef HAVE_LIBTAC_EVENT + /* libtac by default uses PAP auth method. tac_login is a global/extern variable of libtac */ + strncpy(tac_login, "login", 5); +#endif + + connControl->opts = tacplus_parse_reload_options(tacplus_cfg, + &connControl->opts); + if(connControl->opts == NULL) { + syslog(LOG_NOTICE, "No valid configuration"); + ret = -1; + goto done; + } + + /* Set global DSCP marking in libtac library */ + tac_set_dscp(connControl->opts->dscp); + + syslog(LOG_INFO, "Configuration loaded successfully"); + + ret = create_statistics(connControl->opts->n_servers); + if(ret != 0) { + syslog(LOG_ERR, "Failed to allocate statistics"); + goto done; + } + syslog(LOG_DEBUG, "Statistics allocated successfully"); + +done: + return ret; +} + +static int reload_service(const char *tacplus_cfg) +{ + int ret; + + reload = 0; + syslog(LOG_NOTICE, "Reloading"); + dbus_service_pause(); + + free_statistics(); + ret = setup_service(tacplus_cfg); + + ret |= dbus_service_resume(); + return ret; +} + +int main(int argc, char *argv[]) +{ + int ret = 0; + sigset_t set; + char *tacplus_cfg; + char *tacplus_pid; + + if (argc == 3) { + tacplus_cfg = argv[1]; + tacplus_pid = argv[2]; + } + else { + fprintf(stderr, "Insufficient arguments to the daemon\n"); + return -1; + } + + if (getenv("DEBUG")) + tac_debug_enable = 1; + + if (!getenv("NODAEMON")) { + openlog("tacplusd", LOG_ODELAY, LOG_AUTH); + daemonize(tacplus_pid); + } + else + openlog("tacplusd", LOG_PERROR, LOG_AUTH); + + /* from this point onwards, we're the child */ + syslog(LOG_NOTICE, "Tacplusd daemonized successfully"); + syslog(LOG_DEBUG, "Tacplusd started with %s\n", tacplus_cfg); + + sigemptyset(&set); + sigaddset(&set, SIGQUIT); + sigaddset(&set, SIGKILL); + sigaddset(&set, SIGUSR1); + sigaddset(&set, SIGUSR2); + sigaddset(&set, SIGTERM); + sigaddset(&set, SIGHUP); + + ret = pthread_sigmask(SIG_BLOCK, &set, NULL); + + if (ret != 0) { + syslog(LOG_ERR, "Blocking signals failed"); + goto done; + } + + pthread_mutex_init(&connControl->state.lock, NULL); + + dbus_service_init(); + + if (setup_service(tacplus_cfg) != 0) { + ret = -1; + goto done; + } + + if (dbus_service_start() < 0) { + syslog(LOG_ERR, "Failed to start DBus service"); + ret = -1; + goto done; + } + syslog(LOG_DEBUG, "DBus service setup successful"); + + /* Send an offline state change signal to indicate we have started up */ + signal_offline_state_change(); + + while (run) { + if (reload && (ret = reload_service(tacplus_cfg)) != 0) + goto done; + + signal_wait(&set); + + ret = dbus_service_failed() ? 1 : 0; + } + +done: + syslog(LOG_NOTICE, "Stopping"); + + dbus_service_stop(); + dbus_service_wait(); + dbus_service_deinit(); + + free_statistics(); + cleanup_tacplus_options(&connControl->opts); + + syslog(LOG_NOTICE, "Shutting down"); + return ret; +} |