summaryrefslogtreecommitdiffstats
path: root/plugins/check_users.d
diff options
context:
space:
mode:
authorLorenz Kästle <12514511+RincewindsHat@users.noreply.github.com>2025-09-09 02:07:32 +0200
committerLorenz Kästle <12514511+RincewindsHat@users.noreply.github.com>2025-09-09 02:07:32 +0200
commitfbd60d6a9d9ba5b45879280dcfda92379dec65da (patch)
treea7c0e428be10bb27b6344c6531b804451c4d40cc /plugins/check_users.d
parentb54869391faab7ef91586c81de21f18a61bac5aa (diff)
parent615fec347cd575c0ee4343aa17ee99962f375f64 (diff)
downloadmonitoring-plugins-fbd60d6a9d9ba5b45879280dcfda92379dec65da.tar.gz
Merge branch 'master' into refactor/check_curl
Diffstat (limited to 'plugins/check_users.d')
-rw-r--r--plugins/check_users.d/config.h20
-rw-r--r--plugins/check_users.d/users.c167
-rw-r--r--plugins/check_users.d/users.h18
3 files changed, 205 insertions, 0 deletions
diff --git a/plugins/check_users.d/config.h b/plugins/check_users.d/config.h
new file mode 100644
index 00000000..26d3ee70
--- /dev/null
+++ b/plugins/check_users.d/config.h
@@ -0,0 +1,20 @@
1#pragma once
2
3#include "output.h"
4#include "thresholds.h"
5
6typedef struct check_users_config {
7 mp_thresholds thresholds;
8
9 bool output_format_is_set;
10 mp_output_format output_format;
11} check_users_config;
12
13check_users_config check_users_config_init() {
14 check_users_config tmp = {
15 .thresholds = mp_thresholds_init(),
16
17 .output_format_is_set = false,
18 };
19 return tmp;
20}
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
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 @@
1#pragma once
2
3typedef struct get_num_of_users_wrapper {
4 int errorcode;
5 int users;
6} get_num_of_users_wrapper;
7
8enum {
9 NO_SYSTEMD_ERROR = 64,
10 WINDOWS_COULD_NOT_ENUMERATE_SESSIONS,
11 COULD_NOT_OPEN_PIPE,
12 STDERR_COULD_NOT_BE_READ,
13};
14
15get_num_of_users_wrapper get_num_of_users_systemd();
16get_num_of_users_wrapper get_num_of_users_utmp();
17get_num_of_users_wrapper get_num_of_users_windows();
18get_num_of_users_wrapper get_num_of_users_who_command();