From d35c43e95f9efed3ef89bee288b8ec8f65ad2014 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Tue, 25 Feb 2025 15:02:55 +0100 Subject: Revert "Migrate check_users to new ouput infrastructure" This reverts commit 10086edbf03fd807794bcfb3fff626da69a9fdb2. --- plugins/Makefile.am | 1 - plugins/check_users.c | 249 +++++++++++++++++++++-------------------- plugins/check_users.d/config.h | 19 ---- plugins/check_users.d/users.c | 166 --------------------------- plugins/check_users.d/users.h | 18 --- 5 files changed, 130 insertions(+), 323 deletions(-) delete mode 100644 plugins/check_users.d/config.h delete mode 100644 plugins/check_users.d/users.c delete mode 100644 plugins/check_users.d/users.h (limited to 'plugins') diff --git a/plugins/Makefile.am b/plugins/Makefile.am index e0069653..d43c1971 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -125,7 +125,6 @@ check_time_LDADD = $(NETLIBS) check_ntp_time_LDADD = $(NETLIBS) $(MATHLIBS) check_ups_LDADD = $(NETLIBS) check_users_LDADD = $(BASEOBJS) $(WTSAPI32LIBS) $(SYSTEMDLIBS) -check_users_SOURCES = check_users.c check_users.d/users.c check_by_ssh_LDADD = $(NETLIBS) check_ide_smart_LDADD = $(BASEOBJS) negate_LDADD = $(BASEOBJS) diff --git a/plugins/check_users.c b/plugins/check_users.c index 6ec87d21..f1e1c39d 100644 --- a/plugins/check_users.c +++ b/plugins/check_users.c @@ -3,7 +3,7 @@ * Monitoring check_users plugin * * License: GPL - * Copyright (c) 2000-2025 Monitoring Plugins Development Team + * Copyright (c) 2000-2024 Monitoring Plugins Development Team * * Description: * @@ -30,19 +30,12 @@ * *****************************************************************************/ -#include "check_users.d/config.h" -#include "thresholds.h" const char *progname = "check_users"; -const char *copyright = "2000-2025"; +const char *copyright = "2000-2024"; const char *email = "devel@monitoring-plugins.org"; -#include "check_users.d/users.h" -#include "output.h" -#include "perfdata.h" -#include "states.h" -#include "utils_base.h" -#include "./common.h" -#include "./utils.h" +#include "common.h" +#include "utils.h" #if HAVE_WTSAPI32_H # include @@ -60,16 +53,29 @@ const char *email = "devel@monitoring-plugins.org"; # include #endif -typedef struct process_argument_wrapper { - int errorcode; - check_users_config config; -} process_argument_wrapper; +#define possibly_set(a, b) ((a) == 0 ? (b) : 0) -process_argument_wrapper process_arguments(int /*argc*/, char ** /*argv*/); -void print_help(void); +static int process_arguments(int, char **); +static void print_help(void); void print_usage(void); +static char *warning_range = NULL; +static char *critical_range = NULL; +static thresholds *thlds = NULL; + int main(int argc, char **argv) { + int users = -1; + int result = STATE_UNKNOWN; +#if HAVE_WTSAPI32_H + WTS_SESSION_INFO *wtsinfo; + DWORD wtscount; + DWORD index; +#elif HAVE_UTMPX_H + struct utmpx *putmpx; +#else + char input_buffer[MAX_INPUT_BUFFER]; +#endif + setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); @@ -77,106 +83,121 @@ int main(int argc, char **argv) { /* Parse extra opts if any */ argv = np_extra_opts(&argc, argv, progname); - process_argument_wrapper tmp = process_arguments(argc, argv); - - if (tmp.errorcode == ERROR) { + if (process_arguments(argc, argv) == ERROR) usage4(_("Could not parse arguments")); - } - check_users_config config = tmp.config; + users = 0; + +#ifdef HAVE_LIBSYSTEMD + if (sd_booted() > 0) + users = sd_get_sessions(NULL); + else { +#endif +#if HAVE_WTSAPI32_H + if (!WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &wtsinfo, &wtscount)) { + printf(_("Could not enumerate RD sessions: %d\n"), GetLastError()); + return STATE_UNKNOWN; + } + + for (index = 0; index < wtscount; index++) { + LPTSTR username; + DWORD size; + int len; -#ifdef _WIN32 -# if HAVE_WTSAPI32_H - get_num_of_users_wrapper user_wrapper = get_num_of_users_windows(); -# else -# error Did not find WTSAPI32 -# endif // HAVE_WTSAPI32_H + if (!WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, wtsinfo[index].SessionId, WTSUserName, &username, &size)) + continue; + + len = lstrlen(username); + + WTSFreeMemory(username); + + if (len == 0) + continue; + + if (wtsinfo[index].State == WTSActive || wtsinfo[index].State == WTSDisconnected) + users++; + } + + WTSFreeMemory(wtsinfo); +#elif HAVE_UTMPX_H + /* get currently logged users from utmpx */ + setutxent(); + + while ((putmpx = getutxent()) != NULL) + if (putmpx->ut_type == USER_PROCESS) + users++; + + endutxent(); #else -# ifdef HAVE_LIBSYSTEMD - get_num_of_users_wrapper user_wrapper = get_num_of_users_systemd(); -# elif HAVE_UTMPX_H - get_num_of_users_wrapper user_wrapper = get_num_of_users_utmp(); -# else // !HAVE_LIBSYSTEMD && !HAVE_UTMPX_H - get_num_of_users_wrapper user_wrapper = get_num_of_users_who_command(); -# endif // HAVE_LIBSYSTEMD -#endif // _WIN32 - - mp_check overall = mp_check_init(); - mp_subcheck sc_users = mp_subcheck_init(); - - if (user_wrapper.errorcode != 0) { - sc_users = mp_set_subcheck_state(sc_users, STATE_UNKNOWN); - sc_users.output = "Failed to retrieve number of users"; - mp_add_subcheck_to_check(&overall, sc_users); - mp_exit(overall); + /* run the command */ + child_process = spopen(WHO_COMMAND); + if (child_process == NULL) { + printf(_("Could not open pipe: %s\n"), WHO_COMMAND); + return STATE_UNKNOWN; } + + child_stderr = fdopen(child_stderr_array[fileno(child_process)], "r"); + if (child_stderr == NULL) + printf(_("Could not open stderr for %s\n"), WHO_COMMAND); + + while (fgets(input_buffer, MAX_INPUT_BUFFER - 1, child_process)) { + /* increment 'users' on all lines except total user count */ + if (input_buffer[0] != '#') { + users++; + continue; + } + + /* get total logged in users */ + if (sscanf(input_buffer, _("# users=%d"), &users) == 1) + break; + } + + /* check STDERR */ + if (fgets(input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) + result = possibly_set(result, STATE_UNKNOWN); + (void)fclose(child_stderr); + + /* close the pipe */ + if (spclose(child_process)) + result = possibly_set(result, STATE_UNKNOWN); +#endif +#ifdef HAVE_LIBSYSTEMD + } +#endif + /* check the user count against warning and critical thresholds */ + result = get_status((double)users, thlds); - mp_perfdata users_pd = { - .label = "users", - .value = mp_create_pd_value(user_wrapper.users), - }; - - users_pd = mp_pd_set_thresholds(users_pd, config.thresholds); - mp_add_perfdata_to_subcheck(&sc_users, users_pd); - - int tmp_status = mp_get_pd_status(users_pd); - sc_users = mp_set_subcheck_state(sc_users, tmp_status); - - switch (tmp_status) { - case STATE_WARNING: - xasprintf(&sc_users.output, "%d users currently logged in. This violates the warning threshold", user_wrapper.users); - break; - case STATE_CRITICAL: - xasprintf(&sc_users.output, "%d users currently logged in. This violates the critical threshold", user_wrapper.users); - break; - default: - xasprintf(&sc_users.output, "%d users currently logged in", user_wrapper.users); + if (result == STATE_UNKNOWN) + printf("%s\n", _("Unable to read output")); + else { + printf(_("USERS %s - %d users currently logged in |%s\n"), state_text(result), users, + sperfdata_int("users", users, "", warning_range, critical_range, true, 0, false, 0)); } - mp_add_subcheck_to_check(&overall, sc_users); - mp_exit(overall); + return result; } -#define output_format_index CHAR_MAX + 1 - /* process command-line arguments */ -process_argument_wrapper process_arguments(int argc, char **argv) { +int process_arguments(int argc, char **argv) { static struct option longopts[] = {{"critical", required_argument, 0, 'c'}, {"warning", required_argument, 0, 'w'}, {"version", no_argument, 0, 'V'}, {"help", no_argument, 0, 'h'}, - {"output-format", required_argument, 0, output_format_index}, {0, 0, 0, 0}}; - if (argc < 2) { + if (argc < 2) usage("\n"); - } - - char *warning_range = NULL; - char *critical_range = NULL; - check_users_config config = check_users_config_init(); + int option_char; while (true) { - int counter = getopt_long(argc, argv, "+hVvc:w:", longopts, NULL); + int option = 0; + option_char = getopt_long(argc, argv, "+hVvc:w:", longopts, &option); - if (counter == -1 || counter == EOF || counter == 1) { + if (option_char == -1 || option_char == EOF || option_char == 1) break; - } - switch (counter) { - case output_format_index: { - parsed_output_format parser = mp_parse_output_format(optarg); - if (!parser.parsing_success) { - // TODO List all available formats here, maybe add anothoer usage function - printf("Invalid output format: %s\n", optarg); - exit(STATE_UNKNOWN); - } - - config.output_format_is_set = true; - config.output_format = parser.output_format; - break; - } + switch (option_char) { case '?': /* print short usage statement if args not parsable */ usage5(); case 'h': /* help */ @@ -194,35 +215,26 @@ process_argument_wrapper process_arguments(int argc, char **argv) { } } - // TODO add proper verification for ranges here! - if (warning_range) { - mp_range_parsed tmp = mp_parse_range_string(warning_range); - if (tmp.error == MP_PARSING_SUCCES) { - config.thresholds.warning = tmp.range; - config.thresholds.warning_is_set = true; - } else { - printf("Failed to parse warning range: %s", warning_range); - exit(STATE_UNKNOWN); - } - } + option_char = optind; - if (critical_range) { - mp_range_parsed tmp = mp_parse_range_string(critical_range); - if (tmp.error == MP_PARSING_SUCCES) { - config.thresholds.critical = tmp.range; - config.thresholds.critical_is_set = true; - } else { - printf("Failed to parse critical range: %s", critical_range); - exit(STATE_UNKNOWN); - } + if (warning_range == NULL && argc > option_char) + warning_range = argv[option_char++]; + + if (critical_range == NULL && argc > option_char) + critical_range = argv[option_char++]; + + /* this will abort in case of invalid ranges */ + set_thresholds(&thlds, warning_range, critical_range); + + if (!thlds->warning) { + usage4(_("Warning threshold must be a valid range expression")); } - process_argument_wrapper result = { - .errorcode = OK, - .config = config, - }; + if (!thlds->critical) { + usage4(_("Critical threshold must be a valid range expression")); + } - return result; + return OK; } void print_help(void) { @@ -245,7 +257,6 @@ void print_help(void) { printf(" %s\n", _("Set WARNING status if number of logged in users violates RANGE_EXPRESSION")); printf(" %s\n", "-c, --critical=RANGE_EXPRESSION"); printf(" %s\n", _("Set CRITICAL status if number of logged in users violates RANGE_EXPRESSION")); - printf(UT_OUTPUT_FORMAT); printf(UT_SUPPORT); } diff --git a/plugins/check_users.d/config.h b/plugins/check_users.d/config.h deleted file mode 100644 index 35b7b7f8..00000000 --- a/plugins/check_users.d/config.h +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -#include "output.h" -#include "thresholds.h" -typedef struct check_users_config { - mp_thresholds thresholds; - - bool output_format_is_set; - mp_output_format output_format; -} check_users_config; - -check_users_config check_users_config_init() { - check_users_config tmp = { - .thresholds = mp_thresholds_init(), - - .output_format_is_set = false, - }; - return tmp; -} diff --git a/plugins/check_users.d/users.c b/plugins/check_users.d/users.c deleted file mode 100644 index 7969ae79..00000000 --- a/plugins/check_users.d/users.c +++ /dev/null @@ -1,166 +0,0 @@ -#include "./users.h" - -#ifdef _WIN32 -# ifdef HAVE_WTSAPI32_H -# include -# include -# undef ERROR -# define ERROR -1 - -get_num_of_users_wrapper get_num_of_users_windows() { - WTS_SESSION_INFO *wtsinfo; - DWORD wtscount; - - get_num_of_users_wrapper result = {}; - - if (!WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &wtsinfo, &wtscount)) { - // printf(_("Could not enumerate RD sessions: %d\n"), GetLastError()); - result.error = WINDOWS_COULD_NOT_ENUMERATE_SESSIONS; - return result; - } - - for (DWORD index = 0; index < wtscount; index++) { - LPTSTR username; - DWORD size; - - if (!WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, wtsinfo[index].SessionId, WTSUserName, &username, &size)) { - continue; - } - - int len = lstrlen(username); - - WTSFreeMemory(username); - - if (len == 0) { - continue; - } - - if (wtsinfo[index].State == WTSActive || wtsinfo[index].State == WTSDisconnected) { - result.users++; - } - } - - WTSFreeMemory(wtsinfo); - return result; -} -# else // HAVE_WTSAPI32_H -# error On windows but without the WTSAPI32 lib -# endif // HAVE_WTSAPI32_H - -#else // _WIN32 - -# include "../../config.h" - -# ifdef HAVE_LIBSYSTEMD -# include -# include - -get_num_of_users_wrapper get_num_of_users_systemd() { - get_num_of_users_wrapper result = {}; - - // Test whether we booted with systemd - if (sd_booted() > 0) { - int users = sd_get_sessions(NULL); - if (users >= 0) { - // Success - result.users = users; - return result; - } - - // Failure! return the error code - result.errorcode = users; - return result; - } - - // Looks like we are not running systemd, - // return with error here - result.errorcode = NO_SYSTEMD_ERROR; - return result; -} -# endif - -# ifdef HAVE_UTMPX_H -# include - -get_num_of_users_wrapper get_num_of_users_utmp() { - int users = 0; - - /* get currently logged users from utmpx */ - setutxent(); - - struct utmpx *putmpx; - while ((putmpx = getutxent()) != NULL) { - if (putmpx->ut_type == USER_PROCESS) { - users++; - } - } - - endutxent(); - - get_num_of_users_wrapper result = { - .errorcode = 0, - .users = users, - }; - - return result; -} -# endif - -# ifndef HAVE_WTSAPI32_H -# ifndef HAVE_LIBSYSTEMD -# ifndef HAVE_UTMPX_H -// Fall back option here for the others (probably still not on windows) - -# include "../popen.h" -# include "../common.h" -# include "../utils.h" - -get_num_of_users_wrapper get_num_of_users_who_command() { - /* run the command */ - child_process = spopen(WHO_COMMAND); - if (child_process == NULL) { - // printf(_("Could not open pipe: %s\n"), WHO_COMMAND); - get_num_of_users_wrapper result = { - .errorcode = COULD_NOT_OPEN_PIPE, - }; - return result; - } - - child_stderr = fdopen(child_stderr_array[fileno(child_process)], "r"); - if (child_stderr == NULL) { - // printf(_("Could not open stderr for %s\n"), WHO_COMMAND); - // TODO this error should probably be reported - } - - get_num_of_users_wrapper result = {}; - char input_buffer[MAX_INPUT_BUFFER]; - while (fgets(input_buffer, MAX_INPUT_BUFFER - 1, child_process)) { - /* increment 'users' on all lines except total user count */ - if (input_buffer[0] != '#') { - result.users++; - continue; - } - - /* get total logged in users */ - if (sscanf(input_buffer, _("# users=%d"), &result.users) == 1) { - break; - } - } - - /* check STDERR */ - if (fgets(input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) { - // if this fails, something broke and the result can not be relied upon or so is the theorie here - result.errorcode = STDERR_COULD_NOT_BE_READ; - } - (void)fclose(child_stderr); - - /* close the pipe */ - spclose(child_process); - - return result; -} - -# endif -# endif -# endif -#endif diff --git a/plugins/check_users.d/users.h b/plugins/check_users.d/users.h deleted file mode 100644 index aacba775..00000000 --- a/plugins/check_users.d/users.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -typedef struct get_num_of_users_wrapper { - int errorcode; - int users; -} get_num_of_users_wrapper; - -enum { - NO_SYSTEMD_ERROR = 64, - WINDOWS_COULD_NOT_ENUMERATE_SESSIONS, - COULD_NOT_OPEN_PIPE, - STDERR_COULD_NOT_BE_READ, -}; - -get_num_of_users_wrapper get_num_of_users_systemd(); -get_num_of_users_wrapper get_num_of_users_utmp(); -get_num_of_users_wrapper get_num_of_users_windows(); -get_num_of_users_wrapper get_num_of_users_who_command(); -- cgit v1.2.3-74-g34f1