From fb4f46f93da4ac50654fdcc2f26b2f37c73a9230 Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Sat, 22 Feb 2025 22:39:10 +0100 Subject: Migrate check_users to new ouput infrastructure --- plugins/check_users.d/config.h | 19 +++++ plugins/check_users.d/users.c | 166 +++++++++++++++++++++++++++++++++++++++++ plugins/check_users.d/users.h | 18 +++++ 3 files changed, 203 insertions(+) create mode 100644 plugins/check_users.d/config.h create mode 100644 plugins/check_users.d/users.c create mode 100644 plugins/check_users.d/users.h (limited to 'plugins/check_users.d') diff --git a/plugins/check_users.d/config.h b/plugins/check_users.d/config.h new file mode 100644 index 00000000..35b7b7f8 --- /dev/null +++ b/plugins/check_users.d/config.h @@ -0,0 +1,19 @@ +#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 new file mode 100644 index 00000000..7969ae79 --- /dev/null +++ b/plugins/check_users.d/users.c @@ -0,0 +1,166 @@ +#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 new file mode 100644 index 00000000..aacba775 --- /dev/null +++ b/plugins/check_users.d/users.h @@ -0,0 +1,18 @@ +#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