| /******************************************************************************* |
| * Copyright (C) 2004-2006 Intel Corp. All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions are met: |
| * |
| * - Redistributions of source code must retain the above copyright notice, |
| * this list of conditions and the following disclaimer. |
| * |
| * - Redistributions in binary form must reproduce the above copyright notice, |
| * this list of conditions and the following disclaimer in the documentation |
| * and/or other materials provided with the distribution. |
| * |
| * - Neither the name of Intel Corp. nor the names of its |
| * contributors may be used to endorse or promote products derived from this |
| * software without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' |
| * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| * ARE DISCLAIMED. IN NO EVENT SHALL Intel Corp. OR THE CONTRIBUTORS |
| * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| * POSSIBILITY OF SUCH DAMAGE. |
| *******************************************************************************/ |
| |
| /** |
| * @author Anas Nashif |
| */ |
| |
| #ifdef HAVE_CONFIG_H |
| #include <wsman_config.h> |
| #endif |
| |
| #include <stdio.h> |
| #include <stdlib.h> |
| |
| #ifdef HAVE_UNISTD_H |
| #include <unistd.h> |
| #endif |
| |
| #include <string.h> |
| |
| #include <errno.h> |
| #include <assert.h> |
| |
| #include "u/libu.h" |
| #include "wsmand-daemon.h" |
| #include "wsman-server-api.h" |
| |
| #ifdef PACKAGE_SUBSCRIPTION_DIR |
| #define DEFAULT_SUBSCRIPTION_REPOSITORY PACKAGE_SUBSCRIPTION_DIR |
| #else |
| #define DEFAULT_SUBSCRIPTION_REPOSITORY "/var/lib/openwsman/subscriptions" |
| #endif |
| #ifdef __APPLE__ |
| #define DEFAULT_BASIC_AUTH "libwsman_file_auth.dylib" |
| #else |
| #define DEFAULT_BASIC_AUTH "libwsman_file_auth.so" |
| #endif |
| |
| //int facility = LOG_DAEMON; |
| |
| static const char **wsmand_argv = NULL; |
| |
| |
| static int server_port = -1; |
| static int server_ssl_port = -1; |
| static int use_ipv4 = 1; |
| #ifdef ENABLE_IPV6 |
| static int use_ipv6 = 0; |
| #endif |
| static int use_digest = 0; |
| static char *ssl_key_file = NULL; |
| static char *service_path = DEFAULT_SERVICE_PATH; |
| static char *ssl_cert_file = NULL; |
| static char *ssl_disabled_protocols = NULL; |
| static char *pid_file = DEFAULT_PID_PATH; |
| static char *uri_subscription_repository = DEFAULT_SUBSCRIPTION_REPOSITORY; |
| static int daemon_flag = 0; |
| static int no_plugin_flag = 0; |
| static int use_ssl = 0; |
| static int debug_level = -1; |
| static int foreground_debug = 0; |
| static int syslog_level = -1; |
| static char *log_location = NULL; |
| static char *digest_password_file = NULL; |
| static char *basic_password_file = NULL; |
| static char *custom_anon_identify_file = NULL; |
| static char *custom_identify_file = NULL; |
| static char *basic_authenticator_arg = NULL; |
| static char *basic_authenticator = DEFAULT_BASIC_AUTH; |
| static int max_threads = 1; |
| static unsigned long enumIdleTimeout = 100; |
| static char *thread_stack_size="0"; |
| static int max_connections_per_thread=20; |
| |
| static char *config_file = NULL; |
| |
| |
| |
| int wsmand_parse_options(int argc, char **argv) |
| { |
| char retval; |
| u_option_context_t *opt_ctx; |
| u_error_t *error = NULL; |
| char *version = NULL; |
| |
| u_option_entry_t options[] = { |
| #if 0 |
| {"no-plugins", 'n', U_OPTION_ARG_NONE, &no_plugin_flag, |
| "Do not load any plugins", NULL}, |
| #endif |
| {"ssl", 'S', U_OPTION_ARG_NONE, &use_ssl, |
| "Use SSL port", NULL}, |
| {"version", 'q', U_OPTION_ARG_NONE, &version, |
| "Display application version", NULL}, |
| {"debug", 'd', U_OPTION_ARG_NONE, &foreground_debug, |
| "Start daemon in foreground and turn on debugging", NULL}, |
| {"syslog", 's', U_OPTION_ARG_INT, &syslog_level, |
| "Set the verbosity of syslog output.", "0-6"}, |
| {"enum-idle-timeout", 'e', U_OPTION_ARG_INT, |
| &enumIdleTimeout, |
| "Enumeration Idle timeout in secs", "default 100"}, |
| {"config-file", 'c', U_OPTION_ARG_STRING, &config_file, |
| "Alternate configuration file", "<file>"}, |
| {"pid-file", 'p', U_OPTION_ARG_STRING, &pid_file, |
| "PID file", "<file>"}, |
| {"subscription-repository-location", 'r', U_OPTION_ARG_STRING, &uri_subscription_repository, |
| "Subscription Repository Location", "<uri>"}, |
| {NULL} |
| }; |
| |
| wsmand_argv = (const char **) argv; |
| opt_ctx = u_option_context_new("WS-Management Server"); |
| u_option_context_set_ignore_unknown_options(opt_ctx, FALSE); |
| u_option_context_add_main_entries(opt_ctx, options, "wsman"); |
| retval = u_option_context_parse(opt_ctx, &argc, &argv, &error); |
| if (error) { |
| if (error->message) |
| printf("%s\n", error->message); |
| retval = 0; |
| } |
| if (version) { |
| fprintf(stdout, PACKAGE_NAME " " PACKAGE_VERSION "\n\n"); |
| exit(0); |
| } |
| |
| u_error_free(error); |
| u_option_context_free(opt_ctx); |
| return retval; |
| } |
| |
| const char **wsmand_options_get_argv(void) |
| { |
| return wsmand_argv; |
| } |
| |
| int wsmand_read_config(dictionary * ini) |
| { |
| if (!iniparser_find_entry(ini, "server")) { |
| return 0; |
| } |
| |
| server_port = iniparser_getint(ini, "server:port", 5985); |
| server_ssl_port = iniparser_getint(ini, "server:ssl_port", 5986); |
| debug_level = iniparser_getint(ini, "server:debug_level", 0); |
| enumIdleTimeout = |
| (unsigned long) iniparser_getint(ini, |
| "server:enum_idle_timeout", |
| 100); |
| service_path = |
| iniparser_getstring(ini, "server:service_path", "/wsman"); |
| ssl_key_file = iniparser_getstr(ini, "server:ssl_key_file"); |
| ssl_cert_file = iniparser_getstr(ini, "server:ssl_cert_file"); |
| ssl_disabled_protocols = iniparser_getstr(ini, "server:ssl_disabled_protocols"); |
| use_ipv4 = iniparser_getboolean(ini, "server:ipv4", 1); |
| #ifdef ENABLE_IPV6 |
| use_ipv6 = iniparser_getboolean(ini, "server:ipv6", 1); |
| if (! (use_ipv4 || use_ipv6)) { |
| fprintf(stderr, "Neither ipv4 nor ipv6 is enabled in openwsman.conf !\n"); |
| exit(1); |
| } |
| #endif |
| use_digest = iniparser_getboolean(ini, "server:use_digest", 0); |
| digest_password_file = iniparser_getstr(ini, |
| "server:digest_password_file"); |
| basic_password_file = |
| iniparser_getstr(ini, "server:basic_password_file"); |
| custom_identify_file = |
| iniparser_getstr(ini, "server:identify_file"); |
| custom_anon_identify_file = |
| iniparser_getstr(ini, "server:anon_identify_file"); |
| basic_authenticator = |
| iniparser_getstr(ini, "server:basic_authenticator"); |
| basic_authenticator_arg = |
| iniparser_getstr(ini, "server:basic_authenticator_arg"); |
| log_location = iniparser_getstr(ini, "server:log_location"); |
| max_threads = iniparser_getint(ini, "server:max_threads", 0); |
| uri_subscription_repository = iniparser_getstring(ini, "server:subs_repository", DEFAULT_SUBSCRIPTION_REPOSITORY); |
| max_connections_per_thread = iniparser_getint(ini, "server:max_connections_per_thread", iniparser_getint(ini, "server:max_connextions_per_thread", 20)); |
| thread_stack_size = iniparser_getstring(ini, "server:thread_stack_size", "0"); |
| #ifdef ENABLE_EVENTING_SUPPORT |
| wsman_server_set_subscription_repos(uri_subscription_repository); |
| #endif |
| return 1; |
| } |
| |
| int wsmand_options_get_max_connections_per_thread(void) |
| { |
| return max_connections_per_thread; |
| } |
| |
| unsigned int wsmand_options_get_thread_stack_size(void) |
| { |
| errno=0; |
| unsigned int stack_size = strtoul(thread_stack_size,NULL,10); |
| if(errno){ |
| debug("failed to convert string to unsigned int : %s", strerror(errno)); |
| return 0; |
| } |
| return stack_size; |
| } |
| |
| const char *wsmand_options_get_config_file(void) |
| { |
| char *p; |
| if (config_file == NULL) { |
| config_file = DEFAULT_CONFIG_FILE; |
| } |
| if (config_file != NULL && !u_path_is_absolute(config_file)) { |
| char cwd[PATH_MAX]; |
| if ((p = getcwd(cwd, PATH_MAX)) != NULL) |
| config_file = |
| u_strdup_printf("%s/%s", cwd, config_file); |
| } |
| return config_file; |
| } |
| |
| char *wsmand_options_get_digest_password_file(void) |
| { |
| return digest_password_file; |
| } |
| |
| char *wsmand_options_get_basic_password_file(void) |
| { |
| return basic_password_file; |
| } |
| |
| char *wsmand_options_get_identify_file(void) |
| { |
| return custom_identify_file; |
| } |
| char *wsmand_options_get_anon_identify_file(void) |
| { |
| return custom_anon_identify_file; |
| } |
| |
| char *wsmand_options_get_service_path(void) |
| { |
| return service_path; |
| } |
| |
| int wsmand_options_get_daemon_flag(void) |
| { |
| return daemon_flag; |
| } |
| |
| int wsmand_options_get_no_plugins_flag(void) |
| { |
| return no_plugin_flag; |
| } |
| |
| int wsmand_options_get_use_ssl(void) |
| { |
| return use_ssl; |
| } |
| |
| int wsmand_options_get_use_ipv4(void) |
| { |
| return use_ipv4; |
| } |
| |
| #ifdef ENABLE_IPV6 |
| int wsmand_options_get_use_ipv6(void) |
| { |
| return use_ipv6; |
| } |
| |
| /* called when opening an ipv6 socket failed */ |
| void wsmand_options_disable_use_ipv6(void) |
| { |
| use_ipv6 = 0; |
| } |
| #endif |
| |
| int wsmand_options_get_foreground_debug(void) |
| { |
| if (foreground_debug) |
| return 6; |
| else |
| return -1; |
| } |
| |
| |
| |
| int wsmand_options_get_debug_level(void) |
| { |
| return debug_level; |
| } |
| |
| |
| int wsmand_options_get_syslog_level(void) |
| { |
| return syslog_level; |
| } |
| |
| |
| int wsmand_options_get_server_port(void) |
| { |
| return server_port; |
| } |
| |
| |
| int wsmand_options_get_server_ssl_port(void) |
| { |
| return server_ssl_port; |
| } |
| |
| |
| |
| char *wsmand_options_get_ssl_key_file(void) |
| { |
| return ssl_key_file; |
| } |
| |
| char *wsmand_options_get_ssl_cert_file(void) |
| { |
| return ssl_cert_file; |
| } |
| |
| char *wsmand_options_get_ssl_disabled_protocols(void) |
| { |
| return ssl_disabled_protocols; |
| } |
| |
| int wsmand_options_get_digest(void) |
| { |
| return use_digest; |
| } |
| |
| |
| char *wsmand_options_get_pid_file(void) |
| { |
| return pid_file; |
| } |
| |
| |
| int wsmand_options_get_max_threads(void) |
| { |
| //XXX: we might wish to return a constant 1 till the |
| //MT issues on unix are solved. See compat_unix.h for |
| //details on the issue. |
| return max_threads; |
| } |
| |
| |
| char *wsmand_default_basic_authenticator() |
| { |
| return DEFAULT_BASIC_AUTH; |
| } |
| |
| char *wsmand_option_get_basic_authenticator() |
| { |
| return basic_authenticator; |
| } |
| |
| char *wsmand_option_get_basic_authenticator_arg() |
| { |
| return basic_authenticator_arg; |
| } |
| |
| unsigned long wsmand_options_get_enumIdleTimeout() |
| { |
| return enumIdleTimeout; |
| } |
| |
| typedef struct _ShutdownHandler ShutdownHandler; |
| struct _ShutdownHandler { |
| WsmandShutdownFn fn; |
| void *user_data; |
| }; |
| |
| static list_t *shutdown_handlers = NULL; |
| static int shutdown_counter = 0; |
| static int shutdown_pending = 0; |
| static int shutting_down = 0; |
| |
| void wsmand_shutdown_add_handler(WsmandShutdownFn fn, void *user_data) |
| { |
| ShutdownHandler *handler; |
| lnode_t *n; |
| |
| if (fn == NULL) |
| return; |
| |
| handler = u_zalloc(sizeof(ShutdownHandler)); |
| handler->fn = fn; |
| handler->user_data = user_data; |
| |
| n = lnode_create(handler); |
| |
| if (!shutdown_handlers) |
| shutdown_handlers = list_create(LISTCOUNT_T_MAX); |
| |
| list_prepend(shutdown_handlers, n); |
| } |
| |
| void wsmand_shutdown_block(void) |
| { |
| if (shutdown_counter < 0) |
| return; |
| |
| if (shutting_down) { |
| debug |
| ("Attempting to block shut-down while shut-down is already in progress!"); |
| } |
| ++shutdown_counter; |
| } |
| |
| void wsmand_shutdown_allow(void) |
| { |
| if (shutdown_counter <= 0) |
| return; |
| --shutdown_counter; |
| |
| if (shutdown_counter == 0 && shutdown_pending) { |
| wsmand_shutdown(); |
| } |
| } |
| |
| static int shutdown_idle_cb(void *user_data) |
| { |
| // int restart = (int )user_data; |
| lnode_t *n; |
| if (shutdown_handlers == NULL) { |
| goto NULL_SHUTDOWN_HANDLERS; |
| } |
| |
| if (list_isempty(shutdown_handlers)) { |
| goto EMPTY_LIST; |
| } |
| |
| n = list_first(shutdown_handlers); |
| |
| debug("shutdown_idle_cb started"); |
| |
| while (n) { |
| ShutdownHandler *handler = n->list_data; |
| |
| if (handler && handler->fn) |
| handler->fn(handler->user_data); |
| |
| u_free(handler); |
| n = list_next(shutdown_handlers, n); |
| } |
| |
| // list_destroy_nodes (shutdown_handlers); |
| EMPTY_LIST: |
| // list_destroy (shutdown_handlers); |
| NULL_SHUTDOWN_HANDLERS: |
| |
| if (user_data == NULL) { |
| /* We should be quitting the main loop (which will cause us to |
| exit) in a handler. If not, we'll throw in an exit just to be |
| sure. */ |
| exit(0); |
| } else { |
| const char **argv = wsmand_options_get_argv(); |
| |
| errno = 0; |
| if ((execv(argv[0], (char **) argv)) < 0) { |
| debug("Can not restart wsmand: %s", |
| strerror(errno)); |
| exit(EXIT_FAILURE); |
| } |
| } |
| |
| /* We should never reach here... */ |
| assert(1 == 1); |
| return 0; |
| } |
| |
| static void do_shutdown(int restart) |
| { |
| if (shutdown_counter > 0) { |
| debug("Shutting down pended"); |
| shutdown_pending = TRUE; |
| return; |
| } |
| debug("Shutting down daemon..."); |
| |
| if (shutting_down) { |
| debug |
| ("Shut-down request received while shut-down is already in progress!"); |
| return; |
| } |
| |
| shutting_down = TRUE; |
| if (restart) { |
| shutdown_idle_cb((void *) 1); |
| } else { |
| shutdown_idle_cb(NULL); |
| } |
| |
| } |
| |
| void wsmand_shutdown(void) |
| { |
| do_shutdown(FALSE); |
| } |
| |
| void wsmand_restart(void) |
| { |
| do_shutdown(TRUE); |
| } |