summaryrefslogtreecommitdiffstats
path: root/plugins/check_users.d/users.c
diff options
context:
space:
mode:
authorLorenz Kästle <12514511+RincewindsHat@users.noreply.github.com>2025-08-11 23:22:54 +0200
committerGitHub <noreply@github.com>2025-08-11 23:22:54 +0200
commit723e0d3466d85a6ed9811d0661db289e7d9406d9 (patch)
tree4b26f57d9f62c3cb084e063011910efa42fea0f4 /plugins/check_users.d/users.c
parent2046ae85574c32370facab3c01f2152e56e1e981 (diff)
parent7382fa90f84d38cd2ae08c880e9ed6a4ad644d35 (diff)
downloadmonitoring-plugins-723e0d3466d85a6ed9811d0661db289e7d9406d9.tar.gz
Merge pull request #2107 from RincewindsHat/refactor/check_users
Refactor/check users
Diffstat (limited to 'plugins/check_users.d/users.c')
-rw-r--r--plugins/check_users.d/users.c167
1 files changed, 167 insertions, 0 deletions
diff --git a/plugins/check_users.d/users.c b/plugins/check_users.d/users.c
new file mode 100644
index 00000000..a8b168a0
--- /dev/null
+++ b/plugins/check_users.d/users.c
@@ -0,0 +1,167 @@
1#include "./users.h"
2
3#ifdef _WIN32
4# ifdef HAVE_WTSAPI32_H
5# include <windows.h>
6# include <wtsapi32.h>
7# undef ERROR
8# define ERROR -1
9
10get_num_of_users_wrapper get_num_of_users_windows() {
11 WTS_SESSION_INFO *wtsinfo;
12 DWORD wtscount;
13
14 get_num_of_users_wrapper result = {};
15
16 if (!WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &wtsinfo, &wtscount)) {
17 // printf(_("Could not enumerate RD sessions: %d\n"), GetLastError());
18 result.error = WINDOWS_COULD_NOT_ENUMERATE_SESSIONS;
19 return result;
20 }
21
22 for (DWORD index = 0; index < wtscount; index++) {
23 LPTSTR username;
24 DWORD size;
25
26 if (!WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, wtsinfo[index].SessionId, WTSUserName, &username, &size)) {
27 continue;
28 }
29
30 int len = lstrlen(username);
31
32 WTSFreeMemory(username);
33
34 if (len == 0) {
35 continue;
36 }
37
38 if (wtsinfo[index].State == WTSActive || wtsinfo[index].State == WTSDisconnected) {
39 result.users++;
40 }
41 }
42
43 WTSFreeMemory(wtsinfo);
44 return result;
45}
46# else // HAVE_WTSAPI32_H
47# error On windows but without the WTSAPI32 lib
48# endif // HAVE_WTSAPI32_H
49
50#else // _WIN32
51
52# include "../../config.h"
53# include <stddef.h>
54
55# ifdef HAVE_LIBSYSTEMD
56# include <systemd/sd-daemon.h>
57# include <systemd/sd-login.h>
58
59get_num_of_users_wrapper get_num_of_users_systemd() {
60 get_num_of_users_wrapper result = {};
61
62 // Test whether we booted with systemd
63 if (sd_booted() > 0) {
64 int users = sd_get_uids(NULL);
65 if (users >= 0) {
66 // Success
67 result.users = users;
68 return result;
69 }
70
71 // Failure! return the error code
72 result.errorcode = users;
73 return result;
74 }
75
76 // Looks like we are not running systemd,
77 // return with error here
78 result.errorcode = NO_SYSTEMD_ERROR;
79 return result;
80}
81# endif
82
83# ifdef HAVE_UTMPX_H
84# include <utmpx.h>
85
86get_num_of_users_wrapper get_num_of_users_utmp() {
87 int users = 0;
88
89 /* get currently logged users from utmpx */
90 setutxent();
91
92 struct utmpx *putmpx;
93 while ((putmpx = getutxent()) != NULL) {
94 if (putmpx->ut_type == USER_PROCESS) {
95 users++;
96 }
97 }
98
99 endutxent();
100
101 get_num_of_users_wrapper result = {
102 .errorcode = 0,
103 .users = users,
104 };
105
106 return result;
107}
108# endif
109
110# ifndef HAVE_WTSAPI32_H
111# ifndef HAVE_LIBSYSTEMD
112# ifndef HAVE_UTMPX_H
113// Fall back option here for the others (probably still not on windows)
114
115# include "../popen.h"
116# include "../common.h"
117# include "../utils.h"
118
119get_num_of_users_wrapper get_num_of_users_who_command() {
120 /* run the command */
121 child_process = spopen(WHO_COMMAND);
122 if (child_process == NULL) {
123 // printf(_("Could not open pipe: %s\n"), WHO_COMMAND);
124 get_num_of_users_wrapper result = {
125 .errorcode = COULD_NOT_OPEN_PIPE,
126 };
127 return result;
128 }
129
130 child_stderr = fdopen(child_stderr_array[fileno(child_process)], "r");
131 if (child_stderr == NULL) {
132 // printf(_("Could not open stderr for %s\n"), WHO_COMMAND);
133 // TODO this error should probably be reported
134 }
135
136 get_num_of_users_wrapper result = {};
137 char input_buffer[MAX_INPUT_BUFFER];
138 while (fgets(input_buffer, MAX_INPUT_BUFFER - 1, child_process)) {
139 /* increment 'users' on all lines except total user count */
140 if (input_buffer[0] != '#') {
141 result.users++;
142 continue;
143 }
144
145 /* get total logged in users */
146 if (sscanf(input_buffer, _("# users=%d"), &result.users) == 1) {
147 break;
148 }
149 }
150
151 /* check STDERR */
152 if (fgets(input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) {
153 // if this fails, something broke and the result can not be relied upon or so is the theorie here
154 result.errorcode = STDERR_COULD_NOT_BE_READ;
155 }
156 (void)fclose(child_stderr);
157
158 /* close the pipe */
159 spclose(child_process);
160
161 return result;
162}
163
164# endif
165# endif
166# endif
167#endif