summaryrefslogtreecommitdiffstats
path: root/plugins
diff options
context:
space:
mode:
authorLorenz Kästle <12514511+RincewindsHat@users.noreply.github.com>2026-01-09 15:13:36 +0100
committerGitHub <noreply@github.com>2026-01-09 15:13:36 +0100
commit46563cea2b56b28b913cdb1c0493e6ee978fa134 (patch)
treec37c65783dc12266282088564819928f7e8b0e4e /plugins
parent6d1edb3df2feb7fca636226b520e76b0366a7ddd (diff)
parentfccadd7ced0230af858a4ae3f8f0de19582c5a12 (diff)
downloadmonitoring-plugins-master.tar.gz
Merge pull request #2200 from RincewindsHat/modern_output/check_radiusHEADmaster
check_radius: Implement modern output
Diffstat (limited to 'plugins')
-rw-r--r--plugins/check_radius.c130
-rw-r--r--plugins/check_radius.d/config.h6
2 files changed, 107 insertions, 29 deletions
diff --git a/plugins/check_radius.c b/plugins/check_radius.c
index d26f7cf3..93352bcc 100644
--- a/plugins/check_radius.c
+++ b/plugins/check_radius.c
@@ -28,6 +28,7 @@
28 * 28 *
29 *****************************************************************************/ 29 *****************************************************************************/
30 30
31#include "output.h"
31const char *progname = "check_radius"; 32const char *progname = "check_radius";
32const char *copyright = "2000-2024"; 33const char *copyright = "2000-2024";
33const char *email = "devel@monitoring-plugins.org"; 34const char *email = "devel@monitoring-plugins.org";
@@ -158,49 +159,80 @@ int main(int argc, char **argv) {
158 159
159 check_radius_config config = tmp_config.config; 160 check_radius_config config = tmp_config.config;
160 161
162 if (config.output_format_is_set) {
163 mp_set_format(config.output_format);
164 }
165
161#if defined(HAVE_LIBFREERADIUS_CLIENT) || defined(HAVE_LIBRADIUSCLIENT_NG) || \ 166#if defined(HAVE_LIBFREERADIUS_CLIENT) || defined(HAVE_LIBRADIUSCLIENT_NG) || \
162 defined(HAVE_LIBRADCLI) 167 defined(HAVE_LIBRADCLI)
163 rc_handle *rch = NULL; 168 rc_handle *rch = NULL;
164#endif 169#endif
165 170
171 mp_check overall = mp_check_init();
172 mp_subcheck sc_read_config = mp_subcheck_init();
173
166 char *str = strdup("dictionary"); 174 char *str = strdup("dictionary");
167 if ((config.config_file && my_rc_read_config(config.config_file, &rch)) || 175 if ((config.config_file && my_rc_read_config(config.config_file, &rch)) ||
168 my_rc_read_dictionary(my_rc_conf_str(str))) { 176 my_rc_read_dictionary(my_rc_conf_str(str))) {
169 die(STATE_UNKNOWN, _("Config file error\n")); 177 sc_read_config = mp_set_subcheck_state(sc_read_config, STATE_UNKNOWN);
178 xasprintf(&sc_read_config.output, "failed to read config file");
179 mp_add_subcheck_to_check(&overall, sc_read_config);
180 mp_exit(overall);
170 } 181 }
171 182
183 sc_read_config = mp_set_subcheck_state(sc_read_config, STATE_OK);
184 xasprintf(&sc_read_config.output, "read config file successfully");
185 mp_add_subcheck_to_check(&overall, sc_read_config);
186
172 uint32_t service = PW_AUTHENTICATE_ONLY; 187 uint32_t service = PW_AUTHENTICATE_ONLY;
173 188
189 mp_subcheck sc_configuring = mp_subcheck_init();
174 SEND_DATA data; 190 SEND_DATA data;
175 memset(&data, 0, sizeof(data)); 191 memset(&data, 0, sizeof(data));
176 if (!(my_rc_avpair_add(&data.send_pairs, PW_SERVICE_TYPE, &service, 0) && 192 if (!(my_rc_avpair_add(&data.send_pairs, PW_SERVICE_TYPE, &service, 0) &&
177 my_rc_avpair_add(&data.send_pairs, PW_USER_NAME, config.username, 0) && 193 my_rc_avpair_add(&data.send_pairs, PW_USER_NAME, config.username, 0) &&
178 my_rc_avpair_add(&data.send_pairs, PW_USER_PASSWORD, config.password, 0))) { 194 my_rc_avpair_add(&data.send_pairs, PW_USER_PASSWORD, config.password, 0))) {
179 die(STATE_UNKNOWN, _("Out of Memory?\n")); 195 xasprintf(&sc_configuring.output, "Failed to the radius options: Out of Memory?");
196 sc_configuring = mp_set_subcheck_state(sc_configuring, STATE_UNKNOWN);
197 mp_add_subcheck_to_check(&overall, sc_configuring);
198 mp_exit(overall);
180 } 199 }
181 200
182 if (config.nas_id != NULL) { 201 if (config.nas_id != NULL) {
183 if (!(my_rc_avpair_add(&data.send_pairs, PW_NAS_IDENTIFIER, config.nas_id, 0))) { 202 if (!(my_rc_avpair_add(&data.send_pairs, PW_NAS_IDENTIFIER, config.nas_id, 0))) {
184 die(STATE_UNKNOWN, _("Invalid NAS-Identifier\n")); 203 xasprintf(&sc_configuring.output,
204 "Failed to the radius options: invalid NAS identifier?");
205 sc_configuring = mp_set_subcheck_state(sc_configuring, STATE_UNKNOWN);
206 mp_add_subcheck_to_check(&overall, sc_configuring);
207 mp_exit(overall);
185 } 208 }
186 } 209 }
187 210
188 char name[HOST_NAME_MAX]; 211 char name[HOST_NAME_MAX];
189 if (config.nas_ip_address == NULL) { 212 if (config.nas_ip_address == NULL) {
190 if (gethostname(name, sizeof(name)) != 0) { 213 if (gethostname(name, sizeof(name)) != 0) {
191 die(STATE_UNKNOWN, _("gethostname() failed!\n")); 214 xasprintf(&sc_configuring.output, "gethostname() failed");
215 sc_configuring = mp_set_subcheck_state(sc_configuring, STATE_UNKNOWN);
216 mp_add_subcheck_to_check(&overall, sc_configuring);
217 mp_exit(overall);
192 } 218 }
193 config.nas_ip_address = name; 219 config.nas_ip_address = name;
194 } 220 }
195 221
196 struct sockaddr_storage radius_server_socket; 222 struct sockaddr_storage radius_server_socket;
197 if (!dns_lookup(config.nas_ip_address, &radius_server_socket, AF_UNSPEC)) { 223 if (!dns_lookup(config.nas_ip_address, &radius_server_socket, AF_UNSPEC)) {
198 die(STATE_UNKNOWN, _("Invalid NAS-IP-Address\n")); 224 xasprintf(&sc_configuring.output, "invalid NAS IP address. Lookup failed");
225 sc_configuring = mp_set_subcheck_state(sc_configuring, STATE_UNKNOWN);
226 mp_add_subcheck_to_check(&overall, sc_configuring);
227 mp_exit(overall);
199 } 228 }
200 229
201 uint32_t client_id = ntohl(((struct sockaddr_in *)&radius_server_socket)->sin_addr.s_addr); 230 uint32_t client_id = ntohl(((struct sockaddr_in *)&radius_server_socket)->sin_addr.s_addr);
202 if (my_rc_avpair_add(&(data.send_pairs), PW_NAS_IP_ADDRESS, &client_id, 0) == NULL) { 231 if (my_rc_avpair_add(&(data.send_pairs), PW_NAS_IP_ADDRESS, &client_id, 0) == NULL) {
203 die(STATE_UNKNOWN, _("Invalid NAS-IP-Address\n")); 232 xasprintf(&sc_configuring.output, "invalid NAS IP address. Setting option failed");
233 sc_configuring = mp_set_subcheck_state(sc_configuring, STATE_UNKNOWN);
234 mp_add_subcheck_to_check(&overall, sc_configuring);
235 mp_exit(overall);
204 } 236 }
205 237
206 my_rc_buildreq(&data, PW_ACCESS_REQUEST, config.server, config.port, (int)timeout_interval, 238 my_rc_buildreq(&data, PW_ACCESS_REQUEST, config.server, config.port, (int)timeout_interval,
@@ -218,51 +250,78 @@ int main(int argc, char **argv) {
218 rc_avpair_free(data.receive_pairs); 250 rc_avpair_free(data.receive_pairs);
219 } 251 }
220 252
253 mp_subcheck sc_eval = mp_subcheck_init();
254
221 if (result == TIMEOUT_RC) { 255 if (result == TIMEOUT_RC) {
222 printf("Timeout\n"); 256 xasprintf(&sc_eval.output, "timeout");
223 exit(STATE_CRITICAL); 257 sc_eval = mp_set_subcheck_state(sc_eval, STATE_CRITICAL);
258 mp_add_subcheck_to_check(&overall, sc_eval);
259 mp_exit(overall);
224 } 260 }
225 261
226 if (result == ERROR_RC) { 262 if (result == ERROR_RC) {
227 printf(_("Auth Error\n")); 263 xasprintf(&sc_eval.output, "auth error");
228 exit(STATE_CRITICAL); 264 sc_eval = mp_set_subcheck_state(sc_eval, STATE_CRITICAL);
265 mp_add_subcheck_to_check(&overall, sc_eval);
266 mp_exit(overall);
229 } 267 }
230 268
231 if (result == REJECT_RC) { 269 if (result == REJECT_RC) {
232 printf(_("Auth Failed\n")); 270 xasprintf(&sc_eval.output, "auth failed");
233 exit(STATE_WARNING); 271 sc_eval = mp_set_subcheck_state(sc_eval, STATE_WARNING);
272 mp_add_subcheck_to_check(&overall, sc_eval);
273 mp_exit(overall);
234 } 274 }
235 275
236 if (result == BADRESP_RC) { 276 if (result == BADRESP_RC) {
237 printf(_("Bad Response\n")); 277 xasprintf(&sc_eval.output, "bad response");
238 exit(STATE_WARNING); 278 sc_eval = mp_set_subcheck_state(sc_eval, STATE_WARNING);
279 mp_add_subcheck_to_check(&overall, sc_eval);
280 mp_exit(overall);
239 } 281 }
240 282
241 if (config.expect && !strstr(msg, config.expect)) { 283 if (config.expect && !strstr(msg, config.expect)) {
242 printf("%s\n", msg); 284 xasprintf(&sc_eval.output, "%s", msg);
243 exit(STATE_WARNING); 285 sc_eval = mp_set_subcheck_state(sc_eval, STATE_WARNING);
286 mp_add_subcheck_to_check(&overall, sc_eval);
287 mp_exit(overall);
244 } 288 }
245 289
246 if (result == OK_RC) { 290 if (result == OK_RC) {
247 printf(_("Auth OK\n")); 291 xasprintf(&sc_eval.output, "auth OK");
248 exit(STATE_OK); 292 sc_eval = mp_set_subcheck_state(sc_eval, STATE_OK);
293 mp_add_subcheck_to_check(&overall, sc_eval);
294 mp_exit(overall);
249 } 295 }
250 296
251 (void)snprintf(msg, sizeof(msg), _("Unexpected result code %d"), result); 297 xasprintf(&sc_eval.output, "unexpected result code: %d", result);
252 printf("%s\n", msg); 298 sc_eval = mp_set_subcheck_state(sc_eval, STATE_UNKNOWN);
253 exit(STATE_UNKNOWN); 299 mp_add_subcheck_to_check(&overall, sc_eval);
300
301 mp_exit(overall);
254} 302}
255 303
256/* process command-line arguments */ 304/* process command-line arguments */
257check_radius_config_wrapper process_arguments(int argc, char **argv) { 305check_radius_config_wrapper process_arguments(int argc, char **argv) {
258 static struct option longopts[] = { 306 enum {
259 {"hostname", required_argument, 0, 'H'}, {"port", required_argument, 0, 'P'}, 307 output_format_index
260 {"username", required_argument, 0, 'u'}, {"password", required_argument, 0, 'p'}, 308 };
261 {"nas-id", required_argument, 0, 'n'}, {"nas-ip-address", required_argument, 0, 'N'}, 309
262 {"filename", required_argument, 0, 'F'}, {"expect", required_argument, 0, 'e'}, 310 static struct option longopts[] = {{"hostname", required_argument, 0, 'H'},
263 {"retries", required_argument, 0, 'r'}, {"timeout", required_argument, 0, 't'}, 311 {"port", required_argument, 0, 'P'},
264 {"verbose", no_argument, 0, 'v'}, {"version", no_argument, 0, 'V'}, 312 {"username", required_argument, 0, 'u'},
265 {"help", no_argument, 0, 'h'}, {0, 0, 0, 0}}; 313 {"password", required_argument, 0, 'p'},
314 {"nas-id", required_argument, 0, 'n'},
315 {"nas-ip-address", required_argument, 0, 'N'},
316 {"filename", required_argument, 0, 'F'},
317 {"expect", required_argument, 0, 'e'},
318 {"retries", required_argument, 0, 'r'},
319 {"timeout", required_argument, 0, 't'},
320 {"verbose", no_argument, 0, 'v'},
321 {"version", no_argument, 0, 'V'},
322 {"help", no_argument, 0, 'h'},
323 {"output-format", required_argument, 0, output_format_index},
324 {0, 0, 0, 0}};
266 325
267 check_radius_config_wrapper result = { 326 check_radius_config_wrapper result = {
268 .errorcode = OK, 327 .errorcode = OK,
@@ -340,6 +399,18 @@ check_radius_config_wrapper process_arguments(int argc, char **argv) {
340 usage2(_("Timeout interval must be a positive integer"), optarg); 399 usage2(_("Timeout interval must be a positive integer"), optarg);
341 } 400 }
342 break; 401 break;
402 case output_format_index: {
403 parsed_output_format parser = mp_parse_output_format(optarg);
404 if (!parser.parsing_success) {
405 // TODO List all available formats here, maybe add anothoer usage function
406 printf("Invalid output format: %s\n", optarg);
407 exit(STATE_UNKNOWN);
408 }
409
410 result.config.output_format_is_set = true;
411 result.config.output_format = parser.output_format;
412 break;
413 }
343 } 414 }
344 } 415 }
345 416
@@ -393,6 +464,7 @@ void print_help(void) {
393 printf(" %s\n", _("Response string to expect from the server")); 464 printf(" %s\n", _("Response string to expect from the server"));
394 printf(" %s\n", "-r, --retries=INTEGER"); 465 printf(" %s\n", "-r, --retries=INTEGER");
395 printf(" %s\n", _("Number of times to retry a failed connection")); 466 printf(" %s\n", _("Number of times to retry a failed connection"));
467 printf(UT_OUTPUT_FORMAT);
396 468
397 printf(UT_CONN_TIMEOUT, timeout_interval); 469 printf(UT_CONN_TIMEOUT, timeout_interval);
398 470
diff --git a/plugins/check_radius.d/config.h b/plugins/check_radius.d/config.h
index b27d31e7..656bf98e 100644
--- a/plugins/check_radius.d/config.h
+++ b/plugins/check_radius.d/config.h
@@ -1,6 +1,7 @@
1#pragma once 1#pragma once
2 2
3#include "../../config.h" 3#include "../../config.h"
4#include "output.h"
4#include <stddef.h> 5#include <stddef.h>
5#if defined(HAVE_LIBRADCLI) 6#if defined(HAVE_LIBRADCLI)
6# include <radcli/radcli.h> 7# include <radcli/radcli.h>
@@ -23,6 +24,9 @@ typedef struct {
23 unsigned short port; 24 unsigned short port;
24 25
25 char *expect; 26 char *expect;
27
28 bool output_format_is_set;
29 mp_output_format output_format;
26} check_radius_config; 30} check_radius_config;
27 31
28check_radius_config check_radius_config_init() { 32check_radius_config check_radius_config_init() {
@@ -37,6 +41,8 @@ check_radius_config check_radius_config_init() {
37 .port = PW_AUTH_UDP_PORT, 41 .port = PW_AUTH_UDP_PORT,
38 42
39 .expect = NULL, 43 .expect = NULL,
44
45 .output_format_is_set = false,
40 }; 46 };
41 return tmp; 47 return tmp;
42} 48}