summaryrefslogtreecommitdiffstats
path: root/lib/utils_base.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/utils_base.c')
-rw-r--r--lib/utils_base.c134
1 files changed, 81 insertions, 53 deletions
diff --git a/lib/utils_base.c b/lib/utils_base.c
index 54463e92..04c4b4f9 100644
--- a/lib/utils_base.c
+++ b/lib/utils_base.c
@@ -3,7 +3,7 @@
3* utils_base.c 3* utils_base.c
4* 4*
5* License: GPL 5* License: GPL
6* Copyright (c) 2006 Nagios Plugins Development Team 6* Copyright (c) 2006 Monitoring Plugins Development Team
7* 7*
8* Library of useful functions for plugins 8* Library of useful functions for plugins
9* 9*
@@ -30,56 +30,58 @@
30#include <ctype.h> 30#include <ctype.h>
31#include <fcntl.h> 31#include <fcntl.h>
32#include <sys/stat.h> 32#include <sys/stat.h>
33#include <unistd.h>
34#include <sys/types.h>
33 35
34#define np_free(ptr) { if(ptr) { free(ptr); ptr = NULL; } } 36#define np_free(ptr) { if(ptr) { free(ptr); ptr = NULL; } }
35 37
36nagios_plugin *this_nagios_plugin=NULL; 38monitoring_plugin *this_monitoring_plugin=NULL;
37 39
38int _np_state_read_file(FILE *); 40int _np_state_read_file(FILE *);
39 41
40void np_init( char *plugin_name, int argc, char **argv ) { 42void np_init( char *plugin_name, int argc, char **argv ) {
41 if (this_nagios_plugin==NULL) { 43 if (this_monitoring_plugin==NULL) {
42 this_nagios_plugin = calloc(1, sizeof(nagios_plugin)); 44 this_monitoring_plugin = calloc(1, sizeof(monitoring_plugin));
43 if (this_nagios_plugin==NULL) { 45 if (this_monitoring_plugin==NULL) {
44 die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), 46 die(STATE_UNKNOWN, _("Cannot allocate memory: %s"),
45 strerror(errno)); 47 strerror(errno));
46 } 48 }
47 this_nagios_plugin->plugin_name = strdup(plugin_name); 49 this_monitoring_plugin->plugin_name = strdup(plugin_name);
48 if (this_nagios_plugin->plugin_name==NULL) 50 if (this_monitoring_plugin->plugin_name==NULL)
49 die(STATE_UNKNOWN, _("Cannot execute strdup: %s"), strerror(errno)); 51 die(STATE_UNKNOWN, _("Cannot execute strdup: %s"), strerror(errno));
50 this_nagios_plugin->argc = argc; 52 this_monitoring_plugin->argc = argc;
51 this_nagios_plugin->argv = argv; 53 this_monitoring_plugin->argv = argv;
52 } 54 }
53} 55}
54 56
55void np_set_args( int argc, char **argv ) { 57void np_set_args( int argc, char **argv ) {
56 if (this_nagios_plugin==NULL) 58 if (this_monitoring_plugin==NULL)
57 die(STATE_UNKNOWN, _("This requires np_init to be called")); 59 die(STATE_UNKNOWN, _("This requires np_init to be called"));
58 60
59 this_nagios_plugin->argc = argc; 61 this_monitoring_plugin->argc = argc;
60 this_nagios_plugin->argv = argv; 62 this_monitoring_plugin->argv = argv;
61} 63}
62 64
63 65
64void np_cleanup() { 66void np_cleanup() {
65 if (this_nagios_plugin!=NULL) { 67 if (this_monitoring_plugin!=NULL) {
66 if(this_nagios_plugin->state!=NULL) { 68 if(this_monitoring_plugin->state!=NULL) {
67 if(this_nagios_plugin->state->state_data) { 69 if(this_monitoring_plugin->state->state_data) {
68 np_free(this_nagios_plugin->state->state_data->data); 70 np_free(this_monitoring_plugin->state->state_data->data);
69 np_free(this_nagios_plugin->state->state_data); 71 np_free(this_monitoring_plugin->state->state_data);
70 } 72 }
71 np_free(this_nagios_plugin->state->name); 73 np_free(this_monitoring_plugin->state->name);
72 np_free(this_nagios_plugin->state); 74 np_free(this_monitoring_plugin->state);
73 } 75 }
74 np_free(this_nagios_plugin->plugin_name); 76 np_free(this_monitoring_plugin->plugin_name);
75 np_free(this_nagios_plugin); 77 np_free(this_monitoring_plugin);
76 } 78 }
77 this_nagios_plugin=NULL; 79 this_monitoring_plugin=NULL;
78} 80}
79 81
80/* Hidden function to get a pointer to this_nagios_plugin for testing */ 82/* Hidden function to get a pointer to this_monitoring_plugin for testing */
81void _get_nagios_plugin( nagios_plugin **pointer ){ 83void _get_monitoring_plugin( monitoring_plugin **pointer ){
82 *pointer = this_nagios_plugin; 84 *pointer = this_monitoring_plugin;
83} 85}
84 86
85void 87void
@@ -89,7 +91,7 @@ die (int result, const char *fmt, ...)
89 va_start (ap, fmt); 91 va_start (ap, fmt);
90 vprintf (fmt, ap); 92 vprintf (fmt, ap);
91 va_end (ap); 93 va_end (ap);
92 if(this_nagios_plugin!=NULL) { 94 if(this_monitoring_plugin!=NULL) {
93 np_cleanup(); 95 np_cleanup();
94 } 96 }
95 exit (result); 97 exit (result);
@@ -367,6 +369,23 @@ char *np_extract_value(const char *varlist, const char *name, char sep) {
367 return value; 369 return value;
368} 370}
369 371
372
373/*
374 * Read a string representing a state (ok, warning... or numeric: 0, 1) and
375 * return the corresponding STATE_ value or ERROR)
376 */
377int mp_translate_state (char *state_text) {
378 if (!strcasecmp(state_text,"OK") || !strcmp(state_text,"0"))
379 return STATE_OK;
380 if (!strcasecmp(state_text,"WARNING") || !strcmp(state_text,"1"))
381 return STATE_WARNING;
382 if (!strcasecmp(state_text,"CRITICAL") || !strcmp(state_text,"2"))
383 return STATE_CRITICAL;
384 if (!strcasecmp(state_text,"UNKNOWN") || !strcmp(state_text,"3"))
385 return STATE_UNKNOWN;
386 return ERROR;
387}
388
370/* 389/*
371 * Returns a string to use as a keyname, based on an md5 hash of argv, thus 390 * Returns a string to use as a keyname, based on an md5 hash of argv, thus
372 * hopefully a unique key per service/plugin invocation. Use the extra-opts 391 * hopefully a unique key per service/plugin invocation. Use the extra-opts
@@ -375,14 +394,14 @@ char *np_extract_value(const char *varlist, const char *name, char sep) {
375char *_np_state_generate_key() { 394char *_np_state_generate_key() {
376 struct sha1_ctx ctx; 395 struct sha1_ctx ctx;
377 int i; 396 int i;
378 char **argv = this_nagios_plugin->argv; 397 char **argv = this_monitoring_plugin->argv;
379 unsigned char result[20]; 398 unsigned char result[20];
380 char keyname[41]; 399 char keyname[41];
381 char *p=NULL; 400 char *p=NULL;
382 401
383 sha1_init_ctx(&ctx); 402 sha1_init_ctx(&ctx);
384 403
385 for(i=0; i<this_nagios_plugin->argc; i++) { 404 for(i=0; i<this_monitoring_plugin->argc; i++) {
386 sha1_process_bytes(argv[i], strlen(argv[i]), &ctx); 405 sha1_process_bytes(argv[i], strlen(argv[i]), &ctx);
387 } 406 }
388 407
@@ -401,9 +420,9 @@ char *_np_state_generate_key() {
401} 420}
402 421
403void _cleanup_state_data() { 422void _cleanup_state_data() {
404 if (this_nagios_plugin->state->state_data!=NULL) { 423 if (this_monitoring_plugin->state->state_data!=NULL) {
405 np_free(this_nagios_plugin->state->state_data->data); 424 np_free(this_monitoring_plugin->state->state_data->data);
406 np_free(this_nagios_plugin->state->state_data); 425 np_free(this_monitoring_plugin->state->state_data);
407 } 426 }
408} 427}
409 428
@@ -415,9 +434,18 @@ void _cleanup_state_data() {
415char* _np_state_calculate_location_prefix(){ 434char* _np_state_calculate_location_prefix(){
416 char *env_dir; 435 char *env_dir;
417 436
418 env_dir = getenv("NAGIOS_PLUGIN_STATE_DIRECTORY"); 437 /* Do not allow passing MP_STATE_PATH in setuid plugins
419 if(env_dir && env_dir[0] != '\0') 438 * for security reasons */
420 return env_dir; 439 if (mp_suid() == FALSE) {
440 env_dir = getenv("MP_STATE_PATH");
441 if(env_dir && env_dir[0] != '\0')
442 return env_dir;
443 /* This is the former ENV, for backward-compatibility */
444 env_dir = getenv("NAGIOS_PLUGIN_STATE_DIRECTORY");
445 if(env_dir && env_dir[0] != '\0')
446 return env_dir;
447 }
448
421 return NP_STATE_DIR_PREFIX; 449 return NP_STATE_DIR_PREFIX;
422} 450}
423 451
@@ -432,7 +460,7 @@ void np_enable_state(char *keyname, int expected_data_version) {
432 char *temp_keyname = NULL; 460 char *temp_keyname = NULL;
433 char *p=NULL; 461 char *p=NULL;
434 462
435 if(this_nagios_plugin==NULL) 463 if(this_monitoring_plugin==NULL)
436 die(STATE_UNKNOWN, _("This requires np_init to be called")); 464 die(STATE_UNKNOWN, _("This requires np_init to be called"));
437 465
438 this_state = (state_key *) calloc(1, sizeof(state_key)); 466 this_state = (state_key *) calloc(1, sizeof(state_key));
@@ -456,15 +484,15 @@ void np_enable_state(char *keyname, int expected_data_version) {
456 p++; 484 p++;
457 } 485 }
458 this_state->name=temp_keyname; 486 this_state->name=temp_keyname;
459 this_state->plugin_name=this_nagios_plugin->plugin_name; 487 this_state->plugin_name=this_monitoring_plugin->plugin_name;
460 this_state->data_version=expected_data_version; 488 this_state->data_version=expected_data_version;
461 this_state->state_data=NULL; 489 this_state->state_data=NULL;
462 490
463 /* Calculate filename */ 491 /* Calculate filename */
464 asprintf(&temp_filename, "%s/%s/%s", _np_state_calculate_location_prefix(), this_nagios_plugin->plugin_name, this_state->name); 492 asprintf(&temp_filename, "%s/%s/%s", _np_state_calculate_location_prefix(), this_monitoring_plugin->plugin_name, this_state->name);
465 this_state->_filename=temp_filename; 493 this_state->_filename=temp_filename;
466 494
467 this_nagios_plugin->state = this_state; 495 this_monitoring_plugin->state = this_state;
468} 496}
469 497
470/* 498/*
@@ -479,11 +507,11 @@ state_data *np_state_read() {
479 FILE *statefile; 507 FILE *statefile;
480 int rc = FALSE; 508 int rc = FALSE;
481 509
482 if(this_nagios_plugin==NULL) 510 if(this_monitoring_plugin==NULL)
483 die(STATE_UNKNOWN, _("This requires np_init to be called")); 511 die(STATE_UNKNOWN, _("This requires np_init to be called"));
484 512
485 /* Open file. If this fails, no previous state found */ 513 /* Open file. If this fails, no previous state found */
486 statefile = fopen( this_nagios_plugin->state->_filename, "r" ); 514 statefile = fopen( this_monitoring_plugin->state->_filename, "r" );
487 if(statefile!=NULL) { 515 if(statefile!=NULL) {
488 516
489 this_state_data = (state_data *) calloc(1, sizeof(state_data)); 517 this_state_data = (state_data *) calloc(1, sizeof(state_data));
@@ -492,7 +520,7 @@ state_data *np_state_read() {
492 strerror(errno)); 520 strerror(errno));
493 521
494 this_state_data->data=NULL; 522 this_state_data->data=NULL;
495 this_nagios_plugin->state->state_data = this_state_data; 523 this_monitoring_plugin->state->state_data = this_state_data;
496 524
497 rc = _np_state_read_file(statefile); 525 rc = _np_state_read_file(statefile);
498 526
@@ -503,10 +531,10 @@ state_data *np_state_read() {
503 _cleanup_state_data(); 531 _cleanup_state_data();
504 } 532 }
505 533
506 return this_nagios_plugin->state->state_data; 534 return this_monitoring_plugin->state->state_data;
507} 535}
508 536
509/* 537/*
510 * Read the state file 538 * Read the state file
511 */ 539 */
512int _np_state_read_file(FILE *f) { 540int _np_state_read_file(FILE *f) {
@@ -544,7 +572,7 @@ int _np_state_read_file(FILE *f) {
544 break; 572 break;
545 case STATE_DATA_VERSION: 573 case STATE_DATA_VERSION:
546 i=atoi(line); 574 i=atoi(line);
547 if(i != this_nagios_plugin->state->data_version) 575 if(i != this_monitoring_plugin->state->data_version)
548 failure++; 576 failure++;
549 else 577 else
550 expected=STATE_DATA_TIME; 578 expected=STATE_DATA_TIME;
@@ -555,13 +583,13 @@ int _np_state_read_file(FILE *f) {
555 if(data_time > current_time) 583 if(data_time > current_time)
556 failure++; 584 failure++;
557 else { 585 else {
558 this_nagios_plugin->state->state_data->time = data_time; 586 this_monitoring_plugin->state->state_data->time = data_time;
559 expected=STATE_DATA_TEXT; 587 expected=STATE_DATA_TEXT;
560 } 588 }
561 break; 589 break;
562 case STATE_DATA_TEXT: 590 case STATE_DATA_TEXT:
563 this_nagios_plugin->state->state_data->data = strdup(line); 591 this_monitoring_plugin->state->state_data->data = strdup(line);
564 if(this_nagios_plugin->state->state_data->data==NULL) 592 if(this_monitoring_plugin->state->state_data->data==NULL)
565 die(STATE_UNKNOWN, _("Cannot execute strdup: %s"), strerror(errno)); 593 die(STATE_UNKNOWN, _("Cannot execute strdup: %s"), strerror(errno));
566 expected=STATE_DATA_END; 594 expected=STATE_DATA_END;
567 status=TRUE; 595 status=TRUE;
@@ -596,8 +624,8 @@ void np_state_write_string(time_t data_time, char *data_string) {
596 current_time=data_time; 624 current_time=data_time;
597 625
598 /* If file doesn't currently exist, create directories */ 626 /* If file doesn't currently exist, create directories */
599 if(access(this_nagios_plugin->state->_filename,F_OK)!=0) { 627 if(access(this_monitoring_plugin->state->_filename,F_OK)!=0) {
600 asprintf(&directories, "%s", this_nagios_plugin->state->_filename); 628 asprintf(&directories, "%s", this_monitoring_plugin->state->_filename);
601 if(directories==NULL) 629 if(directories==NULL)
602 die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), 630 die(STATE_UNKNOWN, _("Cannot allocate memory: %s"),
603 strerror(errno)); 631 strerror(errno));
@@ -607,7 +635,7 @@ void np_state_write_string(time_t data_time, char *data_string) {
607 *p='\0'; 635 *p='\0';
608 if((access(directories,F_OK)!=0) && (mkdir(directories, S_IRWXU)!=0)) { 636 if((access(directories,F_OK)!=0) && (mkdir(directories, S_IRWXU)!=0)) {
609 /* Can't free this! Otherwise error message is wrong! */ 637 /* Can't free this! Otherwise error message is wrong! */
610 /* np_free(directories); */ 638 /* np_free(directories); */
611 die(STATE_UNKNOWN, _("Cannot create directory: %s"), directories); 639 die(STATE_UNKNOWN, _("Cannot create directory: %s"), directories);
612 } 640 }
613 *p='/'; 641 *p='/';
@@ -616,7 +644,7 @@ void np_state_write_string(time_t data_time, char *data_string) {
616 np_free(directories); 644 np_free(directories);
617 } 645 }
618 646
619 asprintf(&temp_file,"%s.XXXXXX",this_nagios_plugin->state->_filename); 647 asprintf(&temp_file,"%s.XXXXXX",this_monitoring_plugin->state->_filename);
620 if(temp_file==NULL) 648 if(temp_file==NULL)
621 die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), 649 die(STATE_UNKNOWN, _("Cannot allocate memory: %s"),
622 strerror(errno)); 650 strerror(errno));
@@ -636,7 +664,7 @@ void np_state_write_string(time_t data_time, char *data_string) {
636 664
637 fprintf(fp,"# NP State file\n"); 665 fprintf(fp,"# NP State file\n");
638 fprintf(fp,"%d\n",NP_STATE_FORMAT_VERSION); 666 fprintf(fp,"%d\n",NP_STATE_FORMAT_VERSION);
639 fprintf(fp,"%d\n",this_nagios_plugin->state->data_version); 667 fprintf(fp,"%d\n",this_monitoring_plugin->state->data_version);
640 fprintf(fp,"%lu\n",current_time); 668 fprintf(fp,"%lu\n",current_time);
641 fprintf(fp,"%s\n",data_string); 669 fprintf(fp,"%s\n",data_string);
642 670
@@ -654,7 +682,7 @@ void np_state_write_string(time_t data_time, char *data_string) {
654 die(STATE_UNKNOWN, _("Error writing temp file")); 682 die(STATE_UNKNOWN, _("Error writing temp file"));
655 } 683 }
656 684
657 if(rename(temp_file, this_nagios_plugin->state->_filename)!=0) { 685 if(rename(temp_file, this_monitoring_plugin->state->_filename)!=0) {
658 unlink(temp_file); 686 unlink(temp_file);
659 np_free(temp_file); 687 np_free(temp_file);
660 die(STATE_UNKNOWN, _("Cannot rename state temp file")); 688 die(STATE_UNKNOWN, _("Cannot rename state temp file"));