summaryrefslogtreecommitdiffstats
path: root/plugins/check_users.d/users.c
diff options
context:
space:
mode:
authorLorenz Kästle <12514511+RincewindsHat@users.noreply.github.com>2025-02-22 22:39:10 +0100
committerLorenz Kästle <12514511+RincewindsHat@users.noreply.github.com>2025-03-07 23:38:50 +0100
commitfb4f46f93da4ac50654fdcc2f26b2f37c73a9230 (patch)
tree2d09b35c6b033d85ff7117968ea6475ab8dec3dc /plugins/check_users.d/users.c
parent665e2f91306fa9b38044a382e4b7571a0c8c0c5f (diff)
downloadmonitoring-plugins-fb4f46f93da4ac50654fdcc2f26b2f37c73a9230.tar.gz
Migrate check_users to new ouput infrastructure
Diffstat (limited to 'plugins/check_users.d/users.c')
-rw-r--r--plugins/check_users.d/users.c166
1 files changed, 166 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..7969ae79
--- /dev/null
+++ b/plugins/check_users.d/users.c
@@ -0,0 +1,166 @@
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
54# ifdef HAVE_LIBSYSTEMD
55# include <systemd/sd-daemon.h>
56# include <systemd/sd-login.h>
57
58get_num_of_users_wrapper get_num_of_users_systemd() {
59 get_num_of_users_wrapper result = {};
60
61 // Test whether we booted with systemd
62 if (sd_booted() > 0) {
63 int users = sd_get_sessions(NULL);
64 if (users >= 0) {
65 // Success
66 result.users = users;
67 return result;
68 }
69
70 // Failure! return the error code
71 result.errorcode = users;
72 return result;
73 }
74
75 // Looks like we are not running systemd,
76 // return with error here
77 result.errorcode = NO_SYSTEMD_ERROR;
78 return result;
79}
80# endif
81
82# ifdef HAVE_UTMPX_H
83# include <utmpx.h>
84
85get_num_of_users_wrapper get_num_of_users_utmp() {
86 int users = 0;
87
88 /* get currently logged users from utmpx */
89 setutxent();
90
91 struct utmpx *putmpx;
92 while ((putmpx = getutxent()) != NULL) {
93 if (putmpx->ut_type == USER_PROCESS) {
94 users++;
95 }
96 }
97
98 endutxent();
99
100 get_num_of_users_wrapper result = {
101 .errorcode = 0,
102 .users = users,
103 };
104
105 return result;
106}
107# endif
108
109# ifndef HAVE_WTSAPI32_H
110# ifndef HAVE_LIBSYSTEMD
111# ifndef HAVE_UTMPX_H
112// Fall back option here for the others (probably still not on windows)
113
114# include "../popen.h"
115# include "../common.h"
116# include "../utils.h"
117
118get_num_of_users_wrapper get_num_of_users_who_command() {
119 /* run the command */
120 child_process = spopen(WHO_COMMAND);
121 if (child_process == NULL) {
122 // printf(_("Could not open pipe: %s\n"), WHO_COMMAND);
123 get_num_of_users_wrapper result = {
124 .errorcode = COULD_NOT_OPEN_PIPE,
125 };
126 return result;
127 }
128
129 child_stderr = fdopen(child_stderr_array[fileno(child_process)], "r");
130 if (child_stderr == NULL) {
131 // printf(_("Could not open stderr for %s\n"), WHO_COMMAND);
132 // TODO this error should probably be reported
133 }
134
135 get_num_of_users_wrapper result = {};
136 char input_buffer[MAX_INPUT_BUFFER];
137 while (fgets(input_buffer, MAX_INPUT_BUFFER - 1, child_process)) {
138 /* increment 'users' on all lines except total user count */
139 if (input_buffer[0] != '#') {
140 result.users++;
141 continue;
142 }
143
144 /* get total logged in users */
145 if (sscanf(input_buffer, _("# users=%d"), &result.users) == 1) {
146 break;
147 }
148 }
149
150 /* check STDERR */
151 if (fgets(input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) {
152 // if this fails, something broke and the result can not be relied upon or so is the theorie here
153 result.errorcode = STDERR_COULD_NOT_BE_READ;
154 }
155 (void)fclose(child_stderr);
156
157 /* close the pipe */
158 spclose(child_process);
159
160 return result;
161}
162
163# endif
164# endif
165# endif
166#endif