monitoring-plugins/plugins/check_users.d/users.c
2025-09-26 12:51:42 +01:00

169 lines
3.6 KiB
C

#include "./users.h"
#ifdef _WIN32
# ifdef HAVE_WTSAPI32_H
# include <windows.h>
# include <wtsapi32.h>
# 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"
# include <stddef.h>
# ifdef HAVE_LIBSYSTEMD
# include <systemd/sd-daemon.h>
# include <systemd/sd-login.h>
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_uids(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 <utmpx.h>
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 "../common.h"
# include "../popen.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