diff options
Diffstat (limited to 'lib/utils_base.c')
| -rw-r--r-- | lib/utils_base.c | 134 |
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 | ||
| 36 | nagios_plugin *this_nagios_plugin=NULL; | 38 | monitoring_plugin *this_monitoring_plugin=NULL; |
| 37 | 39 | ||
| 38 | int _np_state_read_file(FILE *); | 40 | int _np_state_read_file(FILE *); |
| 39 | 41 | ||
| 40 | void np_init( char *plugin_name, int argc, char **argv ) { | 42 | void 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 | ||
| 55 | void np_set_args( int argc, char **argv ) { | 57 | void 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 | ||
| 64 | void np_cleanup() { | 66 | void 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 */ |
| 81 | void _get_nagios_plugin( nagios_plugin **pointer ){ | 83 | void _get_monitoring_plugin( monitoring_plugin **pointer ){ |
| 82 | *pointer = this_nagios_plugin; | 84 | *pointer = this_monitoring_plugin; |
| 83 | } | 85 | } |
| 84 | 86 | ||
| 85 | void | 87 | void |
| @@ -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 | */ | ||
| 377 | int 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) { | |||
| 375 | char *_np_state_generate_key() { | 394 | char *_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 | ||
| 403 | void _cleanup_state_data() { | 422 | void _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() { | |||
| 415 | char* _np_state_calculate_location_prefix(){ | 434 | char* _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 | */ |
| 512 | int _np_state_read_file(FILE *f) { | 540 | int _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")); |
