summaryrefslogtreecommitdiffstats
path: root/plugins/check_radius.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/check_radius.c')
-rw-r--r--plugins/check_radius.c132
1 files changed, 103 insertions, 29 deletions
diff --git a/plugins/check_radius.c b/plugins/check_radius.c
index d26f7cf3..f20af660 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";
@@ -61,6 +62,8 @@ void print_usage(void);
61# define my_rc_conf_str(a) rc_conf_str(rch, a) 62# define my_rc_conf_str(a) rc_conf_str(rch, a)
62# if defined(HAVE_LIBRADCLI) 63# if defined(HAVE_LIBRADCLI)
63# define my_rc_send_server(a, b) rc_send_server(rch, a, b, AUTH) 64# define my_rc_send_server(a, b) rc_send_server(rch, a, b, AUTH)
65# elif defined(HAVE_LIBFREERADIUS_CLIENT)
66# define my_rc_send_server(a, b) rc_send_server(rch, a, b, 0)
64# else 67# else
65# define my_rc_send_server(a, b) rc_send_server(rch, a, b) 68# define my_rc_send_server(a, b) rc_send_server(rch, a, b)
66# endif 69# endif
@@ -158,49 +161,80 @@ int main(int argc, char **argv) {
158 161
159 check_radius_config config = tmp_config.config; 162 check_radius_config config = tmp_config.config;
160 163
164 if (config.output_format_is_set) {
165 mp_set_format(config.output_format);
166 }
167
161#if defined(HAVE_LIBFREERADIUS_CLIENT) || defined(HAVE_LIBRADIUSCLIENT_NG) || \ 168#if defined(HAVE_LIBFREERADIUS_CLIENT) || defined(HAVE_LIBRADIUSCLIENT_NG) || \
162 defined(HAVE_LIBRADCLI) 169 defined(HAVE_LIBRADCLI)
163 rc_handle *rch = NULL; 170 rc_handle *rch = NULL;
164#endif 171#endif
165 172
173 mp_check overall = mp_check_init();
174 mp_subcheck sc_read_config = mp_subcheck_init();
175
166 char *str = strdup("dictionary"); 176 char *str = strdup("dictionary");
167 if ((config.config_file && my_rc_read_config(config.config_file, &rch)) || 177 if ((config.config_file && my_rc_read_config(config.config_file, &rch)) ||
168 my_rc_read_dictionary(my_rc_conf_str(str))) { 178 my_rc_read_dictionary(my_rc_conf_str(str))) {
169 die(STATE_UNKNOWN, _("Config file error\n")); 179 sc_read_config = mp_set_subcheck_state(sc_read_config, STATE_UNKNOWN);
180 xasprintf(&sc_read_config.output, "failed to read config file");
181 mp_add_subcheck_to_check(&overall, sc_read_config);
182 mp_exit(overall);
170 } 183 }
171 184
185 sc_read_config = mp_set_subcheck_state(sc_read_config, STATE_OK);
186 xasprintf(&sc_read_config.output, "read config file successfully");
187 mp_add_subcheck_to_check(&overall, sc_read_config);
188
172 uint32_t service = PW_AUTHENTICATE_ONLY; 189 uint32_t service = PW_AUTHENTICATE_ONLY;
173 190
191 mp_subcheck sc_configuring = mp_subcheck_init();
174 SEND_DATA data; 192 SEND_DATA data;
175 memset(&data, 0, sizeof(data)); 193 memset(&data, 0, sizeof(data));
176 if (!(my_rc_avpair_add(&data.send_pairs, PW_SERVICE_TYPE, &service, 0) && 194 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) && 195 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))) { 196 my_rc_avpair_add(&data.send_pairs, PW_USER_PASSWORD, config.password, 0))) {
179 die(STATE_UNKNOWN, _("Out of Memory?\n")); 197 xasprintf(&sc_configuring.output, "Failed to the radius options: Out of Memory?");
198 sc_configuring = mp_set_subcheck_state(sc_configuring, STATE_UNKNOWN);
199 mp_add_subcheck_to_check(&overall, sc_configuring);
200 mp_exit(overall);
180 } 201 }
181 202
182 if (config.nas_id != NULL) { 203 if (config.nas_id != NULL) {
183 if (!(my_rc_avpair_add(&data.send_pairs, PW_NAS_IDENTIFIER, config.nas_id, 0))) { 204 if (!(my_rc_avpair_add(&data.send_pairs, PW_NAS_IDENTIFIER, config.nas_id, 0))) {
184 die(STATE_UNKNOWN, _("Invalid NAS-Identifier\n")); 205 xasprintf(&sc_configuring.output,
206 "Failed to the radius options: invalid NAS identifier?");
207 sc_configuring = mp_set_subcheck_state(sc_configuring, STATE_UNKNOWN);
208 mp_add_subcheck_to_check(&overall, sc_configuring);
209 mp_exit(overall);
185 } 210 }
186 } 211 }
187 212
188 char name[HOST_NAME_MAX]; 213 char name[HOST_NAME_MAX];
189 if (config.nas_ip_address == NULL) { 214 if (config.nas_ip_address == NULL) {
190 if (gethostname(name, sizeof(name)) != 0) { 215 if (gethostname(name, sizeof(name)) != 0) {
191 die(STATE_UNKNOWN, _("gethostname() failed!\n")); 216 xasprintf(&sc_configuring.output, "gethostname() failed");
217 sc_configuring = mp_set_subcheck_state(sc_configuring, STATE_UNKNOWN);
218 mp_add_subcheck_to_check(&overall, sc_configuring);
219 mp_exit(overall);
192 } 220 }
193 config.nas_ip_address = name; 221 config.nas_ip_address = name;
194 } 222 }
195 223
196 struct sockaddr_storage radius_server_socket; 224 struct sockaddr_storage radius_server_socket;
197 if (!dns_lookup(config.nas_ip_address, &radius_server_socket, AF_UNSPEC)) { 225 if (!dns_lookup(config.nas_ip_address, &radius_server_socket, AF_UNSPEC)) {
198 die(STATE_UNKNOWN, _("Invalid NAS-IP-Address\n")); 226 xasprintf(&sc_configuring.output, "invalid NAS IP address. Lookup failed");
227 sc_configuring = mp_set_subcheck_state(sc_configuring, STATE_UNKNOWN);
228 mp_add_subcheck_to_check(&overall, sc_configuring);
229 mp_exit(overall);
199 } 230 }
200 231
201 uint32_t client_id = ntohl(((struct sockaddr_in *)&radius_server_socket)->sin_addr.s_addr); 232 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) { 233 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")); 234 xasprintf(&sc_configuring.output, "invalid NAS IP address. Setting option failed");
235 sc_configuring = mp_set_subcheck_state(sc_configuring, STATE_UNKNOWN);
236 mp_add_subcheck_to_check(&overall, sc_configuring);
237 mp_exit(overall);
204 } 238 }
205 239
206 my_rc_buildreq(&data, PW_ACCESS_REQUEST, config.server, config.port, (int)timeout_interval, 240 my_rc_buildreq(&data, PW_ACCESS_REQUEST, config.server, config.port, (int)timeout_interval,
@@ -218,51 +252,78 @@ int main(int argc, char **argv) {
218 rc_avpair_free(data.receive_pairs); 252 rc_avpair_free(data.receive_pairs);
219 } 253 }
220 254
255 mp_subcheck sc_eval = mp_subcheck_init();
256
221 if (result == TIMEOUT_RC) { 257 if (result == TIMEOUT_RC) {
222 printf("Timeout\n"); 258 xasprintf(&sc_eval.output, "timeout");
223 exit(STATE_CRITICAL); 259 sc_eval = mp_set_subcheck_state(sc_eval, STATE_CRITICAL);
260 mp_add_subcheck_to_check(&overall, sc_eval);
261 mp_exit(overall);
224 } 262 }
225 263
226 if (result == ERROR_RC) { 264 if (result == ERROR_RC) {
227 printf(_("Auth Error\n")); 265 xasprintf(&sc_eval.output, "auth error");
228 exit(STATE_CRITICAL); 266 sc_eval = mp_set_subcheck_state(sc_eval, STATE_CRITICAL);
267 mp_add_subcheck_to_check(&overall, sc_eval);
268 mp_exit(overall);
229 } 269 }
230 270
231 if (result == REJECT_RC) { 271 if (result == REJECT_RC) {
232 printf(_("Auth Failed\n")); 272 xasprintf(&sc_eval.output, "auth failed");
233 exit(STATE_WARNING); 273 sc_eval = mp_set_subcheck_state(sc_eval, STATE_WARNING);
274 mp_add_subcheck_to_check(&overall, sc_eval);
275 mp_exit(overall);
234 } 276 }
235 277
236 if (result == BADRESP_RC) { 278 if (result == BADRESP_RC) {
237 printf(_("Bad Response\n")); 279 xasprintf(&sc_eval.output, "bad response");
238 exit(STATE_WARNING); 280 sc_eval = mp_set_subcheck_state(sc_eval, STATE_WARNING);
281 mp_add_subcheck_to_check(&overall, sc_eval);
282 mp_exit(overall);
239 } 283 }
240 284
241 if (config.expect && !strstr(msg, config.expect)) { 285 if (config.expect && !strstr(msg, config.expect)) {
242 printf("%s\n", msg); 286 xasprintf(&sc_eval.output, "%s", msg);
243 exit(STATE_WARNING); 287 sc_eval = mp_set_subcheck_state(sc_eval, STATE_WARNING);
288 mp_add_subcheck_to_check(&overall, sc_eval);
289 mp_exit(overall);
244 } 290 }
245 291
246 if (result == OK_RC) { 292 if (result == OK_RC) {
247 printf(_("Auth OK\n")); 293 xasprintf(&sc_eval.output, "auth OK");
248 exit(STATE_OK); 294 sc_eval = mp_set_subcheck_state(sc_eval, STATE_OK);
295 mp_add_subcheck_to_check(&overall, sc_eval);
296 mp_exit(overall);
249 } 297 }
250 298
251 (void)snprintf(msg, sizeof(msg), _("Unexpected result code %d"), result); 299 xasprintf(&sc_eval.output, "unexpected result code: %d", result);
252 printf("%s\n", msg); 300 sc_eval = mp_set_subcheck_state(sc_eval, STATE_UNKNOWN);
253 exit(STATE_UNKNOWN); 301 mp_add_subcheck_to_check(&overall, sc_eval);
302
303 mp_exit(overall);
254} 304}
255 305
256/* process command-line arguments */ 306/* process command-line arguments */
257check_radius_config_wrapper process_arguments(int argc, char **argv) { 307check_radius_config_wrapper process_arguments(int argc, char **argv) {
258 static struct option longopts[] = { 308 enum {
259 {"hostname", required_argument, 0, 'H'}, {"port", required_argument, 0, 'P'}, 309 output_format_index
260 {"username", required_argument, 0, 'u'}, {"password", required_argument, 0, 'p'}, 310 };
261 {"nas-id", required_argument, 0, 'n'}, {"nas-ip-address", required_argument, 0, 'N'}, 311
262 {"filename", required_argument, 0, 'F'}, {"expect", required_argument, 0, 'e'}, 312 static struct option longopts[] = {{"hostname", required_argument, 0, 'H'},
263 {"retries", required_argument, 0, 'r'}, {"timeout", required_argument, 0, 't'}, 313 {"port", required_argument, 0, 'P'},
264 {"verbose", no_argument, 0, 'v'}, {"version", no_argument, 0, 'V'}, 314 {"username", required_argument, 0, 'u'},
265 {"help", no_argument, 0, 'h'}, {0, 0, 0, 0}}; 315 {"password", required_argument, 0, 'p'},
316 {"nas-id", required_argument, 0, 'n'},
317 {"nas-ip-address", required_argument, 0, 'N'},
318 {"filename", required_argument, 0, 'F'},
319 {"expect", required_argument, 0, 'e'},
320 {"retries", required_argument, 0, 'r'},
321 {"timeout", required_argument, 0, 't'},
322 {"verbose", no_argument, 0, 'v'},
323 {"version", no_argument, 0, 'V'},
324 {"help", no_argument, 0, 'h'},
325 {"output-format", required_argument, 0, output_format_index},
326 {0, 0, 0, 0}};
266 327
267 check_radius_config_wrapper result = { 328 check_radius_config_wrapper result = {
268 .errorcode = OK, 329 .errorcode = OK,
@@ -340,6 +401,18 @@ check_radius_config_wrapper process_arguments(int argc, char **argv) {
340 usage2(_("Timeout interval must be a positive integer"), optarg); 401 usage2(_("Timeout interval must be a positive integer"), optarg);
341 } 402 }
342 break; 403 break;
404 case output_format_index: {
405 parsed_output_format parser = mp_parse_output_format(optarg);
406 if (!parser.parsing_success) {
407 // TODO List all available formats here, maybe add anothoer usage function
408 printf("Invalid output format: %s\n", optarg);
409 exit(STATE_UNKNOWN);
410 }
411
412 result.config.output_format_is_set = true;
413 result.config.output_format = parser.output_format;
414 break;
415 }
343 } 416 }
344 } 417 }
345 418
@@ -393,6 +466,7 @@ void print_help(void) {
393 printf(" %s\n", _("Response string to expect from the server")); 466 printf(" %s\n", _("Response string to expect from the server"));
394 printf(" %s\n", "-r, --retries=INTEGER"); 467 printf(" %s\n", "-r, --retries=INTEGER");
395 printf(" %s\n", _("Number of times to retry a failed connection")); 468 printf(" %s\n", _("Number of times to retry a failed connection"));
469 printf(UT_OUTPUT_FORMAT);
396 470
397 printf(UT_CONN_TIMEOUT, timeout_interval); 471 printf(UT_CONN_TIMEOUT, timeout_interval);
398 472