Imported Upstream version 3.2.1

This commit is contained in:
Mario Fetka
2017-11-02 09:55:48 +01:00
parent 02b430a86c
commit 52cbd1b45f
36 changed files with 2095 additions and 1811 deletions

View File

@@ -1,7 +1,7 @@
###############################
# Makefile for NRPE
#
# Last Modified: 08-13-2007
# NRPE Makefile
#
###############################
srcdir=@srcdir@

View File

@@ -1,17 +1,20 @@
/*-
/****************************************************************************
*
* acl.c - a small library for nrpe.c. It adds IPv4 subnets support to ACL in nrpe.
*
* License: GPLv2
* Copyright (c) 2011 Kaspersky Lab ZAO
* Last Modified: 08-10-2011 by Konstantin Malov with Oleg Koreshkov's help
*
* Description:
* acl.c creates two linked lists. One is for IPv4 hosts and networks, another is for domain names.
* All connecting hosts (if allowed_hosts is defined) are checked in these two lists.
*
* Some notes:
* 1) IPv6 isn't supported in ACL.
* 2) Only ANCII names are supported in ACL.
* acl.c creates two linked lists. One is for IPv4 hosts and networks, another
* is for domain names. All connecting hosts (if allowed_hosts is defined)
* are checked in these two lists.
*
* License: GPL
* Note:
* Only ANCII names are supported in ACL.
*
* License Notice:
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -26,10 +29,12 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
*
****************************************************************************/
#include "../include/config.h"
#include "../include/common.h"
#include "../include/utils.h"
#include <sys/types.h>
#include <sys/socket.h>
@@ -131,6 +136,7 @@ char * acl_substring(char *string, int s, int e) {
*/
int add_ipv4_to_acl(char *ipv4) {
int state = 0;
int octet = 0;
int index = 0; /* position in data array */
@@ -602,6 +608,7 @@ void parse_allowed_hosts(char *allowed_hosts) {
char *tok;
const char *delim = ",";
char *trimmed_tok;
int add_to_acl = 0;
if (debug == TRUE)
logit(LOG_INFO,
@@ -617,15 +624,32 @@ void parse_allowed_hosts(char *allowed_hosts) {
tok = strtok(hosts, delim);
#endif
while( tok) {
trimmed_tok = malloc( sizeof( char) * ( strlen( tok) + 1));
trim( tok, trimmed_tok);
if(debug == TRUE)
trimmed_tok = malloc(sizeof(char) * (strlen(tok) + 1));
trim(tok, trimmed_tok);
if (debug == TRUE)
logit(LOG_DEBUG, "parse_allowed_hosts: ADDING this record (%s) to ACL list!\n", trimmed_tok);
if( strlen( trimmed_tok) > 0) {
if (!add_ipv4_to_acl(trimmed_tok) && !add_ipv6_to_acl(trimmed_tok)
&& !add_domain_to_acl(trimmed_tok)) {
if (strlen(trimmed_tok) > 0) {
/* lets check the type of the address before we try and add it to the acl */
if (strchr(trimmed_tok, ':') != NULL) {
/* its an ipv6 address */
add_to_acl = add_ipv6_to_acl(trimmed_tok);
} else {
/* its either a fqdn or an ipv4 address
unfortunately, i don't want to re-invent the wheel here
the logic exists inside of add_ipv4_to_acl() to detect
whether or not it is a ip or not */
add_to_acl = add_ipv4_to_acl(trimmed_tok);
}
/* but we only try to add it to a domain if the other tests have failed */
if (!add_to_acl && !add_domain_to_acl(trimmed_tok)) {
logit(LOG_ERR,"Can't add to ACL this record (%s). Check allowed_hosts option!\n",trimmed_tok);
} else if (debug == TRUE)
} else if (debug == TRUE)
logit(LOG_DEBUG,"parse_allowed_hosts: Record added to ACL list!\n");
}
free( trimmed_tok);

View File

@@ -1,21 +1,40 @@
/********************************************************************************************
/****************************************************************************
*
* CHECK_NRPE.C - NRPE Plugin For Nagios
* Copyright (c) 1999-2008 Ethan Galstad (nagios@nagios.org)
* License: GPL
* check_nrpe.c - NRPE Plugin For Nagios
*
* Last Modified: 2017-05-24
* License: GPLv2
* Copyright (c) 2009-2017 Nagios Enterprises
* 1999-2008 Ethan Galstad (nagios@nagios.org)
*
* Command line: CHECK_NRPE -H <host_address> [-p port] [-c command] [-to to_sec]
* Command line:
*
* check_nrpe -H <host_address> [-p port] [-c command] [-to to_sec]
*
* Description:
*
* This plugin will attempt to connect to the NRPE daemon on the specified server and port.
* The daemon will attempt to run the command defined as [command]. Program output and
* return code are sent back from the daemon and displayed as this plugin's own output and
* return code.
* This plugin will attempt to connect to the NRPE daemon on the specified
* server and port. The daemon will attempt to run the command
* defined as [command]. Program output and return code are sent back
* from the daemon and displayed as this plugin's own
* output and return code.
*
********************************************************************************************/
* License Notice:
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
****************************************************************************/
#include "config.h"
#include "common.h"
@@ -37,6 +56,7 @@ char *command_name = NULL;
int socket_timeout = DEFAULT_SOCKET_TIMEOUT;
char timeout_txt[10];
int timeout_return_code = -1;
int stderr_to_stdout = 0;
int sd;
char rem_host[MAX_HOST_ADDRESS_LENGTH];
@@ -128,7 +148,11 @@ int main(int argc, char **argv)
if (timeout_return_code == -1)
timeout_return_code = STATE_CRITICAL;
if (sslprm.cipher_list[0] == '\0')
#if OPENSSL_VERSION_NUMBER >= 0x10100000
strncpy(sslprm.cipher_list, "ALL:!MD5:@STRENGTH:@SECLEVEL=0", MAX_FILENAME_LENGTH - 1);
#else
strncpy(sslprm.cipher_list, "ALL:!MD5:@STRENGTH", MAX_FILENAME_LENGTH - 1);
#endif
if (sslprm.ssl_proto_ver == SSL_Ver_Invalid)
sslprm.ssl_proto_ver = TLSv1_plus;
if (sslprm.allowDH == -1)
@@ -215,6 +239,8 @@ int process_arguments(int argc, char **argv, int from_config_file)
{"log-file", required_argument, 0, 'g'},
{"help", no_argument, 0, 'h'},
{"license", no_argument, 0, 'l'},
{"version", no_argument, 0, 'V'},
{"stderr-to-stdout", no_argument, 0, 'E'},
{0, 0, 0, 0}
};
#endif
@@ -224,7 +250,7 @@ int process_arguments(int argc, char **argv, int from_config_file)
return ERROR;
optind = 0;
snprintf(optchars, MAX_INPUT_BUFFER, "H:f:b:c:a:t:p:S:L:C:K:A:d:s:P:g:246hlnuV");
snprintf(optchars, MAX_INPUT_BUFFER, "H:f:b:c:a:t:p:S:L:C:K:A:d:s:P:g:246hlnuVE");
while (1) {
if (argindex > 0)
@@ -267,8 +293,7 @@ int process_arguments(int argc, char **argv, int from_config_file)
case 't':
if (from_config_file && socket_timeout != -1) {
logit(LOG_WARNING, "WARNING: Command-line socket timeout overrides "
"the config file option.");
logit(LOG_WARNING, "WARNING: Command-line socket timeout overrides the config file option.");
break;
}
socket_timeout=parse_timeout_string(optarg);
@@ -278,8 +303,7 @@ int process_arguments(int argc, char **argv, int from_config_file)
case 'p':
if (from_config_file && server_port != 0) {
logit(LOG_WARNING, "WARNING: Command-line server port overrides "
"the config file option.");
logit(LOG_WARNING, "WARNING: Command-line server port overrides the config file option.");
break;
}
server_port = atoi(optarg);
@@ -289,8 +313,7 @@ int process_arguments(int argc, char **argv, int from_config_file)
case 'P':
if (from_config_file && payload_size > 0) {
logit(LOG_WARNING, "WARNING: Command-line payload-size (-P) overrides "
"the config file option.");
logit(LOG_WARNING, "WARNING: Command-line payload-size (-P) overrides the config file option.");
break;
}
payload_size = atoi(optarg);
@@ -300,13 +323,20 @@ int process_arguments(int argc, char **argv, int from_config_file)
case 'H':
if (from_config_file && server_name != NULL) {
logit(LOG_WARNING, "WARNING: Command-line server name overrides "
"the config file option.");
logit(LOG_WARNING, "WARNING: Command-line server name overrides the config file option.");
break;
}
server_name = strdup(optarg);
break;
case 'E':
if (from_config_file && stderr_to_stdout != 0) {
logit(LOG_WARNING, "WARNING: Command-line stderr redirection overrides the config file option.");
break;
}
stderr_to_stdout = 1;
break;
case 'c':
if (from_config_file) {
printf("Error: The config file should not have a command (-c) option.\n");
@@ -329,8 +359,7 @@ int process_arguments(int argc, char **argv, int from_config_file)
case 'u':
if (from_config_file && timeout_return_code != -1) {
logit(LOG_WARNING, "WARNING: Command-line unknown-timeout (-u) "
"overrides the config file option.");
logit(LOG_WARNING, "WARNING: Command-line unknown-timeout (-u) overrides the config file option.");
break;
}
timeout_return_code = STATE_UNKNOWN;
@@ -338,8 +367,7 @@ int process_arguments(int argc, char **argv, int from_config_file)
case '2':
if (from_config_file && packet_ver != NRPE_PACKET_VERSION_3) {
logit(LOG_WARNING, "WARNING: Command-line v2-packets-only (-2) "
"overrides the config file option.");
logit(LOG_WARNING, "WARNING: Command-line v2-packets-only (-2) overrides the config file option.");
break;
}
packet_ver = NRPE_PACKET_VERSION_2;
@@ -348,8 +376,7 @@ int process_arguments(int argc, char **argv, int from_config_file)
case '4':
if (from_config_file && address_family != AF_UNSPEC) {
logit(LOG_WARNING, "WARNING: Command-line ipv4 (-4) "
"or ipv6 (-6) overrides the config file option.");
logit(LOG_WARNING, "WARNING: Command-line ipv4 (-4) or ipv6 (-6) overrides the config file option.");
break;
}
address_family = AF_INET;
@@ -357,8 +384,7 @@ int process_arguments(int argc, char **argv, int from_config_file)
case '6':
if (from_config_file && address_family != AF_UNSPEC) {
logit(LOG_WARNING, "WARNING: Command-line ipv4 (-4) "
"or ipv6 (-6) overrides the config file option.");
logit(LOG_WARNING, "WARNING: Command-line ipv4 (-4) or ipv6 (-6) overrides the config file option.");
break;
}
address_family = AF_INET6;
@@ -366,8 +392,7 @@ int process_arguments(int argc, char **argv, int from_config_file)
case 'd':
if (from_config_file && sslprm.allowDH != -1) {
logit(LOG_WARNING, "WARNING: Command-line use-adh (-d) "
"overrides the config file option.");
logit(LOG_WARNING, "WARNING: Command-line use-adh (-d) overrides the config file option.");
break;
}
if (!optarg || optarg[0] < '0' || optarg[0] > '2')
@@ -377,8 +402,7 @@ int process_arguments(int argc, char **argv, int from_config_file)
case 'A':
if (from_config_file && sslprm.cacert_file != NULL) {
logit(LOG_WARNING, "WARNING: Command-line ca-cert-file (-A) "
"overrides the config file option.");
logit(LOG_WARNING, "WARNING: Command-line ca-cert-file (-A) overrides the config file option.");
break;
}
sslprm.cacert_file = strdup(optarg);
@@ -386,8 +410,7 @@ int process_arguments(int argc, char **argv, int from_config_file)
case 'C':
if (from_config_file && sslprm.cert_file != NULL) {
logit(LOG_WARNING, "WARNING: Command-line client-cert (-C) "
"overrides the config file option.");
logit(LOG_WARNING, "WARNING: Command-line client-cert (-C) overrides the config file option.");
break;
}
sslprm.cert_file = strdup(optarg);
@@ -396,8 +419,7 @@ int process_arguments(int argc, char **argv, int from_config_file)
case 'K':
if (from_config_file && sslprm.privatekey_file != NULL) {
logit(LOG_WARNING, "WARNING: Command-line key-file (-K) "
"overrides the config file option.");
logit(LOG_WARNING, "WARNING: Command-line key-file (-K) overrides the config file option.");
break;
}
sslprm.privatekey_file = strdup(optarg);
@@ -406,8 +428,7 @@ int process_arguments(int argc, char **argv, int from_config_file)
case 'S':
if (from_config_file && sslprm.ssl_proto_ver != SSL_Ver_Invalid) {
logit(LOG_WARNING, "WARNING: Command-line ssl-version (-S) "
"overrides the config file option.");
logit(LOG_WARNING, "WARNING: Command-line ssl-version (-S) overrides the config file option.");
break;
}
@@ -439,8 +460,7 @@ int process_arguments(int argc, char **argv, int from_config_file)
case 'L':
if (from_config_file && sslprm.cipher_list[0] != '\0') {
logit(LOG_WARNING, "WARNING: Command-line cipher-list (-L) "
"overrides the config file option.");
logit(LOG_WARNING, "WARNING: Command-line cipher-list (-L) overrides the config file option.");
break;
}
strncpy(sslprm.cipher_list, optarg, sizeof(sslprm.cipher_list) - 1);
@@ -449,8 +469,7 @@ int process_arguments(int argc, char **argv, int from_config_file)
case 's':
if (from_config_file && have_log_opts == TRUE) {
logit(LOG_WARNING, "WARNING: Command-line ssl-logging (-s) "
"overrides the config file option.");
logit(LOG_WARNING, "WARNING: Command-line ssl-logging (-s) overrides the config file option.");
break;
}
sslprm.log_opts = strtoul(optarg, NULL, 0);
@@ -459,8 +478,7 @@ int process_arguments(int argc, char **argv, int from_config_file)
case 'g':
if (from_config_file && log_file != NULL) {
logit(LOG_WARNING, "WARNING: Command-line log-file (-g) "
"overrides the config file option.");
logit(LOG_WARNING, "WARNING: Command-line log-file (-g) overrides the config file option.");
break;
}
log_file = strdup(optarg);
@@ -499,14 +517,12 @@ int process_arguments(int argc, char **argv, int from_config_file)
}
if ((has_cert && !has_priv_key) || (!has_cert && has_priv_key)) {
printf("Error: the client certificate and the private key "
"must both be given or neither\n");
printf("Error: the client certificate and the private key must both be given or neither\n");
return ERROR;
}
if (payload_size > 0 && packet_ver != NRPE_PACKET_VERSION_2) {
printf("Error: if a fixed payload size is specified, "
"'-2' must also be specified\n");
printf("Error: if a fixed payload size is specified, '-2' must also be specified\n");
return ERROR;
}
@@ -564,6 +580,8 @@ int read_config_file(char *fname)
argv[argc] = my_strsep(&bufp, delims);
if (!argv[argc++])
break;
if (!bufp)
break;
}
fclose(f);
@@ -608,9 +626,8 @@ int translate_state (char *state_text) {
}
void set_timeout_state (char *state) {
if ((timeout_return_code = translate_state(state)) == ERROR)
printf("Timeout state must be a valid state name (OK, "
"WARNING, CRITICAL, UNKNOWN) or integer (0-3).\n");
if ((timeout_return_code = translate_state(state)) == ERROR)
printf("Timeout state must be a valid state name (OK, WARNING, CRITICAL, UNKNOWN) or integer (0-3).\n");
}
int parse_timeout_string (char *timeout_str)
@@ -649,87 +666,95 @@ int parse_timeout_string (char *timeout_str)
void usage(int result)
{
if (result != OK)
if (result != OK) {
printf("\n");
printf("Incorrect command line arguments supplied\n");
printf("\n");
printf("\n");
}
printf("NRPE Plugin for Nagios\n");
printf("Copyright (c) 1999-2008 Ethan Galstad (nagios@nagios.org)\n");
printf("Version: %s\n", PROGRAM_VERSION);
printf("Last Modified: %s\n", MODIFICATION_DATE);
printf("License: GPL v2 with exemptions (-l for more info)\n");
#ifdef HAVE_SSL
printf("SSL/TLS Available: OpenSSL 0.9.6 or higher required\n");
#endif
printf("\n");
if (result != OK || show_help == TRUE) {
printf("Usage: check_nrpe -H <host> [-2] [-4] [-6] [-n] [-u] [-V] [-l] [-d <dhopt>]\n"
" [-P <size>] [-S <ssl version>] [-L <cipherlist>] [-C <clientcert>]\n"
" [-K <key>] [-A <ca-certificate>] [-s <logopts>] [-b <bindaddr>]\n"
" [-f <cfg-file>] [-p <port>] [-t <interval>:<state>] [-g <log-file>]\n"
" [-c <command>] [-a <arglist...>]\n");
printf("Copyright (c) 2009-2017 Nagios Enterprises\n");
printf(" 1999-2008 Ethan Galstad (nagios@nagios.org)\n");
printf("\n");
printf("Last Modified: %s\n", MODIFICATION_DATE);
printf("\n");
printf("License: GPL v2 with exemptions (-l for more info)\n");
printf("\n");
#ifdef HAVE_SSL
printf("SSL/TLS Available: OpenSSL 0.9.6 or higher required\n");
printf("\n");
#endif
printf("Usage: check_nrpe -H <host> [-2] [-4] [-6] [-n] [-u] [-V] [-l] [-d <dhopt>]\n");
printf(" [-P <size>] [-S <ssl version>] [-L <cipherlist>] [-C <clientcert>]\n");
printf(" [-K <key>] [-A <ca-certificate>] [-s <logopts>] [-b <bindaddr>]\n");
printf(" [-f <cfg-file>] [-p <port>] [-t <interval>:<state>] [-g <log-file>]\n");
printf(" [-c <command>] [-E] [-a <arglist...>]\n");
printf("\n");
printf("Options:\n");
printf(" <host> = The address of the host running the NRPE daemon\n");
printf(" -2 = Only use Version 2 packets, not Version 3\n");
printf(" -4 = bind to ipv4 only\n");
printf(" -6 = bind to ipv6 only\n");
printf(" -n = Do no use SSL\n");
printf
(" -u = Make connection problems return UNKNOWN instead of CRITICAL\n");
printf(" -V = Show version\n");
printf(" -l = Show license\n");
printf(" <dhopt> = Anonymous Diffie Hellman use:\n");
printf(" 0 = Don't use Anonymous Diffie Hellman\n");
printf(" (This will be the default in a future release.)\n");
printf(" 1 = Allow Anonymous Diffie Hellman (default)\n");
printf(" 2 = Force Anonymous Diffie Hellman\n");
printf(" <size> = Specify non-default payload size for NSClient++\n");
printf
(" <ssl ver> = The SSL/TLS version to use. Can be any one of:\n");
printf(" -H, --host=HOST The address of the host running the NRPE daemon\n");
printf(" -2, --v2-packets-only Only use version 2 packets, not version 3\n");
printf(" -4, --ipv4 Bind to ipv4 only\n");
printf(" -6, --ipv6 Bind to ipv6 only\n");
printf(" -n, --no-ssl Do no use SSL\n");
printf(" -u, --unknown-timeout Make connection problems return UNKNOWN instead of CRITICAL\n");
printf(" -V, --version Print version info and quit\n");
printf(" -l, --license Show license\n");
printf(" -E, --stderr-to-stdout Redirect stderr to stdout\n");
printf(" -d, --use-dh=DHOPT Anonymous Diffie Hellman use:\n");
printf(" 0 Don't use Anonymous Diffie Hellman\n");
printf(" (This will be the default in a future release.)\n");
printf(" 1 Allow Anonymous Diffie Hellman (default)\n");
printf(" 2 Force Anonymous Diffie Hellman\n");
printf(" -P, --payload-size=SIZE Specify non-default payload size for NSClient++\n");
printf(" -S, --ssl-version=VERSION The SSL/TLS version to use. Can be any one of:\n");
#if OPENSSL_VERSION_NUMBER < 0x10100000
printf(" SSLv2 (only), SSLv2+ (or above),\n");
#endif /* OPENSSL_VERSION_NUMBER < 0x10100000 */
printf(" SSLv3 (only), SSLv3+ (or above),\n");
printf(" TLSv1 (only), TLSv1+ (or above DEFAULT),\n");
printf(" TLSv1.1 (only), TLSv1.1+ (or above),\n");
printf(" TLSv1.2 (only), TLSv1.2+ (or above)\n");
printf(" <cipherlist> = The list of SSL ciphers to use (currently defaults\n");
printf
(" to \"ALL:!MD5:@STRENGTH\". WILL change in a future release.)\n");
printf(" <clientcert> = The client certificate to use for PKI\n");
printf(" <key> = The private key to use with the client certificate\n");
printf(" <ca-cert> = The CA certificate to use for PKI\n");
printf(" <logopts> = SSL Logging Options\n");
printf(" <bindaddr> = bind to local address\n");
printf(" <cfg-file> = configuration file to use\n");
printf(" <log-file> = full path to the log file to write to\n");
printf(" [port] = The port on which the daemon is running (default=%d)\n",
DEFAULT_SERVER_PORT);
printf(" [command] = The name of the command that the remote daemon should run\n");
printf(" [arglist] = Optional arguments that should be passed to the command,\n");
printf(" separated by a space. If provided, this must be the last\n");
printf(" option supplied on the command line.\n");
printf(" SSLv2 SSL v2 only\n");
printf(" SSLv2+ SSL v2 or above\n");
#endif
printf(" SSLv3 SSL v3 only\n");
printf(" SSLv3+ SSL v3 or above \n");
printf(" TLSv1 TLS v1 only\n");
printf(" TLSv1+ TLS v1 or above (DEFAULT)\n");
printf(" TLSv1.1 TLS v1.1 only\n");
printf(" TLSv1.1+ TLS v1.1 or above\n");
printf(" TLSv1.2 TLS v1.2 only\n");
printf(" TLSv1.2+ TLS v1.2 or above\n");
printf(" -L, --cipher-list=LIST The list of SSL ciphers to use (currently defaults\n");
#if OPENSSL_VERSION_NUMBER >= 0x10100000
printf(" to \"ALL:!MD5:@STRENGTH:@SECLEVEL=0\". THIS WILL change in a future release.)\n");
#else
printf(" to \"ALL:!MD5:@STRENGTH\". THIS WILL change in a future release.)\n");
#endif
printf(" -C, --client-cert=FILE The client certificate to use for PKI\n");
printf(" -K, --key-file=FILE The private key to use with the client certificate\n");
printf(" -A, --ca-cert-file=FILE The CA certificate to use for PKI\n");
printf(" -s, --ssl-logging=OPTIONS SSL Logging Options\n");
printf(" -b, --bind=IPADDR Local address to bind to\n");
printf(" -f, --config-file=FILE Configuration file to use\n");
printf(" -g, --log-file=FILE Log file to write to\n");
printf(" -p, --port=PORT The port on which the daemon is running (default=%d)\n", DEFAULT_SERVER_PORT);
printf(" -c, --command=COMMAND The name of the command that the remote daemon should run\n");
printf(" -a, --args=LIST Optional arguments that should be passed to the command,\n");
printf(" separated by a space. If provided, this must be the last\n");
printf(" option supplied on the command line.\n");
printf("\n");
printf(" NEW TIMEOUT SYNTAX\n");
printf(" -t <interval>:<state>\n");
printf(" <interval> = Number of seconds before connection times out (default=%d)\n",DEFAULT_SOCKET_TIMEOUT);
printf(" <state> = Check state to exit with in the event of a timeout (default=CRITICAL)\n");
printf(" Timeout state must be a valid state name (case-insensitive) or integer:\n");
printf(" (OK, WARNING, CRITICAL, UNKNOWN) or integer (0-3)\n");
printf(" -t, --timeout=INTERVAL:STATE\n");
printf(" INTERVAL Number of seconds before connection times out (default=%d)\n", DEFAULT_SOCKET_TIMEOUT);
printf(" STATE Check state to exit with in the event of a timeout (default=CRITICAL)\n");
printf(" Timeout STATE must be a valid state name (case-insensitive) or integer:\n");
printf(" (OK, WARNING, CRITICAL, UNKNOWN) or integer (0-3)\n");
printf("\n");
printf("Note:\n");
printf
("This plugin requires that you have the NRPE daemon running on the remote host.\n");
printf
("You must also have configured the daemon to associate a specific plugin command\n");
printf("with the [command] option you are specifying here. Upon receipt of the\n");
printf
("[command] argument, the NRPE daemon will run the appropriate plugin command and\n");
printf
("send the plugin output and return code back to *this* plugin. This allows you\n");
printf
("to execute plugins on remote hosts and 'fake' the results to make Nagios think\n");
printf("This plugin requires that you have the NRPE daemon running on the remote host.\n");
printf("You must also have configured the daemon to associate a specific plugin command\n");
printf("with the [command] option you are specifying here. Upon receipt of the\n");
printf("[command] argument, the NRPE daemon will run the appropriate plugin command and\n");
printf("send the plugin output and return code back to *this* plugin. This allows you\n");
printf("to execute plugins on remote hosts and 'fake' the results to make Nagios think\n");
printf("the plugin is being run locally.\n");
printf("\n");
}
@@ -748,18 +773,11 @@ void setup_ssl()
if (sslprm.log_opts & SSL_LogStartup) {
char *val;
logit(LOG_INFO, "SSL Certificate File: %s",
sslprm.cert_file ? sslprm.cert_file : "None");
logit(LOG_INFO, "SSL Private Key File: %s",
sslprm.privatekey_file ? sslprm.privatekey_file : "None");
logit(LOG_INFO, "SSL CA Certificate File: %s",
sslprm.cacert_file ? sslprm.cacert_file : "None");
if (sslprm.allowDH < 2)
logit(LOG_INFO, "SSL Cipher List: %s", sslprm.cipher_list);
else
logit(LOG_INFO, "SSL Cipher List: ADH");
logit(LOG_INFO, "SSL Allow ADH: %s",
sslprm.allowDH == 0 ? "No" : (sslprm.allowDH == 1 ? "Allow" : "Require"));
logit(LOG_INFO, "SSL Certificate File: %s", sslprm.cert_file ? sslprm.cert_file : "None");
logit(LOG_INFO, "SSL Private Key File: %s", sslprm.privatekey_file ? sslprm.privatekey_file : "None");
logit(LOG_INFO, "SSL CA Certificate File: %s", sslprm.cacert_file ? sslprm.cacert_file : "None");
logit(LOG_INFO, "SSL Cipher List: %s", sslprm.cipher_list);
logit(LOG_INFO, "SSL Allow ADH: %d", sslprm.allowDH);
logit(LOG_INFO, "SSL Log Options: 0x%02x", sslprm.log_opts);
switch (sslprm.ssl_proto_ver) {
@@ -804,6 +822,9 @@ void setup_ssl()
if (use_ssl == TRUE) {
SSL_load_error_strings();
SSL_library_init();
ENGINE_load_builtin_engines();
RAND_set_rand_engine(NULL);
ENGINE_register_all_complete();
#if OPENSSL_VERSION_NUMBER >= 0x10100000
@@ -901,19 +922,16 @@ void setup_ssl()
if (!SSL_CTX_use_certificate_file(ctx, sslprm.cert_file, SSL_FILETYPE_PEM)) {
printf("Error: could not use certificate file '%s'.\n", sslprm.cert_file);
while ((x = ERR_get_error_line_data(NULL, NULL, NULL, NULL)) != 0) {
printf("Error: could not use certificate file '%s': %s\n",
sslprm.cert_file, ERR_reason_error_string(x));
printf("Error: could not use certificate file '%s': %s\n", sslprm.cert_file, ERR_reason_error_string(x));
}
SSL_CTX_free(ctx);
exit(STATE_CRITICAL);
}
if (!SSL_CTX_use_PrivateKey_file(ctx, sslprm.privatekey_file, SSL_FILETYPE_PEM)) {
SSL_CTX_free(ctx);
printf("Error: could not use private key file '%s'.\n",
sslprm.privatekey_file);
printf("Error: could not use private key file '%s'.\n", sslprm.privatekey_file);
while ((x = ERR_get_error_line_data(NULL, NULL, NULL, NULL)) != 0) {
printf("Error: could not use private key file '%s': %s\n",
sslprm.privatekey_file, ERR_reason_error_string(x));
printf("Error: could not use private key file '%s': %s\n", sslprm.privatekey_file, ERR_reason_error_string(x));
}
SSL_CTX_free(ctx);
exit(STATE_CRITICAL);
@@ -926,8 +944,7 @@ void setup_ssl()
if (!SSL_CTX_load_verify_locations(ctx, sslprm.cacert_file, NULL)) {
printf("Error: could not use CA certificate '%s'.\n", sslprm.cacert_file);
while ((x = ERR_get_error_line_data(NULL, NULL, NULL, NULL)) != 0) {
printf("Error: could not use CA certificate '%s': %s\n",
sslprm.privatekey_file, ERR_reason_error_string(x));
printf("Error: could not use CA certificate '%s': %s\n", sslprm.privatekey_file, ERR_reason_error_string(x));
}
SSL_CTX_free(ctx);
exit(STATE_CRITICAL);
@@ -942,15 +959,19 @@ void setup_ssl()
}
} else {
/* use anonymous DH ciphers */
if (sslprm.allowDH == 2)
strcpy(sslprm.cipher_list, "ADH");
if (sslprm.allowDH == 2) {
#if OPENSSL_VERSION_NUMBER >= 0x10100000
strncpy(sslprm.cipher_list, "ADH@SECLEVEL=0", MAX_FILENAME_LENGTH - 1);
#else
strncpy(sslprm.cipher_list, "ADH", MAX_FILENAME_LENGTH - 1);
#endif
}
}
if (SSL_CTX_set_cipher_list(ctx, sslprm.cipher_list) == 0) {
printf("Error: Could not set SSL/TLS cipher list: %s\n", sslprm.cipher_list);
while ((x = ERR_get_error_line_data(NULL, NULL, NULL, NULL)) != 0) {
printf("Could not set SSL/TLS cipher list '%s': %s\n",
sslprm.cipher_list, ERR_reason_error_string(x));
printf("Could not set SSL/TLS cipher list '%s': %s\n", sslprm.cipher_list, ERR_reason_error_string(x));
}
SSL_CTX_free(ctx);
exit(STATE_CRITICAL);
@@ -987,8 +1008,7 @@ int connect_to_remote()
int result, rc, ssl_err, ern, x, nerrs = 0;
/* try to connect to the host at the given port number */
if ((sd =
my_connect(server_name, &hostaddr, server_port, address_family, bind_address)) < 0)
if ((sd = my_connect(server_name, &hostaddr, server_port, address_family, bind_address, stderr_to_stdout)) < 0)
exit(timeout_return_code);
result = STATE_OK;
@@ -1025,36 +1045,31 @@ int connect_to_remote()
if (sslprm.log_opts & (SSL_LogCertDetails | SSL_LogIfClientCert)) {
rc = 0;
while ((x = ERR_get_error_line_data(NULL, NULL, NULL, NULL)) != 0) {
logit(LOG_ERR, "Error: Could not complete SSL handshake with %s: %s",
rem_host, ERR_reason_error_string(x));
logit(LOG_ERR, "Error: (ERR_get_error_line_data = %d), Could not complete SSL handshake with %s: %s", x, rem_host, ERR_reason_error_string(x));
++nerrs;
}
if (nerrs == 0)
logit(LOG_ERR, "Error: Could not complete SSL handshake with %s: rc=%d SSL-error=%d",
rem_host, rc, ssl_err);
if (nerrs == 0) {
logit(LOG_ERR, "Error: (nerrs = 0) Could not complete SSL handshake with %s: rc=%d SSL-error=%d", rem_host, rc, ssl_err);
}
} else {
while ((x = ERR_get_error_line_data(NULL, NULL, NULL, NULL)) != 0) {
logit(LOG_ERR, "Error: Could not complete SSL handshake with %s: %s",
rem_host, ERR_reason_error_string(x));
logit(LOG_ERR, "Error: (!log_opts) Could not complete SSL handshake with %s: %s", rem_host, ERR_reason_error_string(x));
++nerrs;
}
if (nerrs == 0)
logit(LOG_ERR, "Error: Could not complete SSL handshake with %s: "
"rc=%d SSL-error=%d", rem_host, rc, ssl_err);
if (nerrs == 0) {
logit(LOG_ERR, "Error: (nerrs = 0)(!log_opts) Could not complete SSL handshake with %s: rc=%d SSL-error=%d", rem_host, rc, ssl_err);
}
}
if (ssl_err == 5) {
/* Often, errno will be zero, so print a generic message here */
if (ern == 0)
printf("CHECK_NRPE: Error - Could not connect to %s. Check system logs on %s\n",
rem_host, rem_host);
printf("CHECK_NRPE: Error - Could not connect to %s. Check system logs on %s\n", rem_host, rem_host);
else
printf("CHECK_NRPE: Error - Could not connect to %s: %s\n",
rem_host, strerror(ern));
} else
printf("CHECK_NRPE: Error - Could not complete SSL handshake with %s: %d\n",
rem_host, ssl_err);
printf("CHECK_NRPE: Error - Could not connect to %s: %s\n", rem_host, strerror(ern));
} else {
printf("CHECK_NRPE: (ssl_err != 5) Error - Could not complete SSL handshake with %s: %d\n", rem_host, ssl_err);
}
# ifdef DEBUG
printf("SSL_connect=%d\n", rc);
@@ -1089,8 +1104,8 @@ int connect_to_remote()
if (peer) {
if (sslprm.log_opts & SSL_LogIfClientCert)
logit(LOG_NOTICE, "SSL %s has %s certificate",
rem_host, SSL_get_verify_result(ssl) ? "a valid" : "an invalid");
logit(LOG_NOTICE, "SSL %s has %s certificate", rem_host, SSL_get_verify_result(ssl) == X509_V_OK ? "a valid" : "an invalid");
if (sslprm.log_opts & SSL_LogCertDetails) {
X509_NAME_oneline(X509_get_subject_name(peer), buffer, sizeof(buffer));
logit(LOG_NOTICE, "SSL %s Cert Name: %s", rem_host, buffer);
@@ -1240,13 +1255,14 @@ int read_response()
} else if (rc == 0) {
/* server disconnected */
printf("CHECK_NRPE: Received 0 bytes from daemon. Check "
"the remote server logs for error messages.\n");
printf("CHECK_NRPE: Received 0 bytes from daemon. Check the remote server logs for error messages.\n");
if (packet_ver == NRPE_PACKET_VERSION_3) {
if (v3_receive_packet)
if (v3_receive_packet) {
free(v3_receive_packet);
} else if (v2_receive_packet)
}
} else if (v2_receive_packet) {
free(v2_receive_packet);
}
return STATE_UNKNOWN;
}
@@ -1259,8 +1275,9 @@ int read_response()
calculated_crc32 = calculate_crc32((char *)v3_receive_packet, pkt_size);
} else {
pkt_size = sizeof(v2_packet);
if (payload_size > 0)
if (payload_size > 0) {
pkt_size = sizeof(v2_packet) - MAX_PACKETBUFFER_LENGTH + payload_size;
}
packet_crc32 = ntohl(v2_receive_packet->crc32_value);
v2_receive_packet->crc32_value = 0L;
calculated_crc32 = calculate_crc32((char *)v2_receive_packet, pkt_size);
@@ -1270,10 +1287,12 @@ int read_response()
printf("CHECK_NRPE: Response packet had invalid CRC32.\n");
close(sd);
if (packet_ver == NRPE_PACKET_VERSION_3) {
if (v3_receive_packet)
if (v3_receive_packet) {
free(v3_receive_packet);
} else if (v2_receive_packet)
}
} else if (v2_receive_packet) {
free(v2_receive_packet);
}
return STATE_UNKNOWN;
}
@@ -1281,30 +1300,35 @@ int read_response()
/* and print the output returned by the daemon */
if (packet_ver == NRPE_PACKET_VERSION_3) {
result = ntohs(v3_receive_packet->result_code);
if (v3_receive_packet->buffer_length == 0)
if (v3_receive_packet->buffer_length == 0) {
printf("CHECK_NRPE: No output returned from daemon.\n");
else
} else {
printf("%s\n", v3_receive_packet->buffer);
}
} else {
result = ntohs(v2_receive_packet->result_code);
if (payload_size > 0)
if (payload_size > 0) {
v2_receive_packet->buffer[payload_size - 1] = '\x0';
else
} else {
v2_receive_packet->buffer[MAX_PACKETBUFFER_LENGTH - 1] = '\x0';
if (!strcmp(v2_receive_packet->buffer, ""))
}
if (!strcmp(v2_receive_packet->buffer, "")) {
printf("CHECK_NRPE: No output returned from daemon.\n");
else if (strstr(v2_receive_packet->buffer, "Invalid packet version.3") != NULL)
} else if (strstr(v2_receive_packet->buffer, "Invalid packet version.3") != NULL) {
/* NSClient++ doesn't recognize it */
return -1;
else
} else {
printf("%s\n", v2_receive_packet->buffer);
}
}
if (packet_ver == NRPE_PACKET_VERSION_3) {
if (v3_receive_packet)
if (v3_receive_packet) {
free(v3_receive_packet);
} else if (v2_receive_packet)
}
} else if (v2_receive_packet) {
free(v2_receive_packet);
}
return result;
}
@@ -1325,9 +1349,7 @@ int read_packet(int sock, void *ssl_ptr, v2_packet ** v2_pkt, v3_packet ** v3_pk
if (rc <= 0 || rc != bytes_to_recv) {
if (rc < bytes_to_recv) {
if (packet_ver != NRPE_PACKET_VERSION_3)
printf("CHECK_NRPE: Receive header underflow - "
"only %d bytes received (%ld expected).\n",
rc, sizeof(bytes_to_recv));
printf("CHECK_NRPE: Receive header underflow - only %d bytes received (%ld expected).\n", rc, sizeof(bytes_to_recv));
}
return -1;
}
@@ -1348,8 +1370,9 @@ int read_packet(int sock, void *ssl_ptr, v2_packet ** v2_pkt, v3_packet ** v3_pk
if (payload_size > 0) {
pkt_size = common_size + payload_size;
buffer_size = payload_size;
} else
} else {
buffer_size = pkt_size - common_size;
}
if ((*v2_pkt = calloc(1, pkt_size)) == NULL) {
logit(LOG_ERR, "Error: Could not allocate memory for packet");
return -1;
@@ -1398,8 +1421,7 @@ int read_packet(int sock, void *ssl_ptr, v2_packet ** v2_pkt, v3_packet ** v3_pk
*v2_pkt = NULL;
}
if (rc < buffer_size)
printf("CHECK_NRPE: Receive underflow - only %d bytes received "
"(%ld expected).\n", rc, sizeof(buffer_size));
printf("CHECK_NRPE: Receive underflow - only %d bytes received (%ld expected).\n", rc, sizeof(buffer_size));
return -1;
} else
tot_bytes += rc;
@@ -1415,8 +1437,7 @@ int read_packet(int sock, void *ssl_ptr, v2_packet ** v2_pkt, v3_packet ** v3_pk
if (rc <= 0 || rc != bytes_to_recv) {
if (rc < bytes_to_recv) {
if (packet_ver != NRPE_PACKET_VERSION_3)
printf("CHECK_NRPE: Receive header underflow - only %d bytes "
"received (%ld expected).\n", rc, sizeof(bytes_to_recv));
printf("CHECK_NRPE: Receive header underflow - only %d bytes received (%ld expected).\n", rc, sizeof(bytes_to_recv));
}
return -1;
}
@@ -1504,12 +1525,11 @@ int read_packet(int sock, void *ssl_ptr, v2_packet ** v2_pkt, v3_packet ** v3_pk
*v2_pkt = NULL;
}
if (bytes_read != buffer_size) {
if (packet_ver == NRPE_PACKET_VERSION_3)
printf("CHECK_NRPE: Receive buffer size - %ld bytes received "
"(%ld expected).\n", (long)bytes_read, sizeof(buffer_size));
else
printf("CHECK_NRPE: Receive underflow - only %ld bytes received "
"(%ld expected).\n", (long)bytes_read, sizeof(buffer_size));
if (packet_ver == NRPE_PACKET_VERSION_3) {
printf("CHECK_NRPE: Receive buffer size - %ld bytes received (%ld expected).\n", (long)bytes_read, sizeof(buffer_size));
} else {
printf("CHECK_NRPE: Receive underflow - only %ld bytes received (%ld expected).\n", (long)bytes_read, sizeof(buffer_size));
}
}
return -1;
} else
@@ -1542,8 +1562,8 @@ int verify_callback(int preverify_ok, X509_STORE_CTX * ctx)
if (!preverify_ok && sslprm.client_certs >= Ask_For_Cert
&& (sslprm.log_opts & SSL_LogCertDetails)) {
logit(LOG_ERR, "SSL Client has an invalid certificate: %s (issuer=%s) err=%d:%s",
name, issuer, err, X509_verify_cert_error_string(err));
logit(LOG_ERR, "SSL Client has an invalid certificate: %s (issuer=%s) err=%d:%s", name, issuer, err, X509_verify_cert_error_string(err));
}
return preverify_ok;
@@ -1565,11 +1585,15 @@ void alarm_handler(int sig)
if (timeout_txt[lth2] == 0)
break;
write(STDOUT_FILENO, msg1, sizeof(msg1) - 1);
write(STDOUT_FILENO, text, lth1);
write(STDOUT_FILENO, msg2, sizeof(msg2) - 1);
write(STDOUT_FILENO, timeout_txt, lth2);
write(STDOUT_FILENO, msg3, sizeof(msg3) - 1);
if ((write(STDOUT_FILENO, msg1, sizeof(msg1) - 1) == -1)
|| (write(STDOUT_FILENO, text, lth1) == -1)
|| (write(STDOUT_FILENO, msg2, sizeof(msg2) - 1) == -1)
|| (write(STDOUT_FILENO, timeout_txt, lth2) == -1)
|| (write(STDOUT_FILENO, msg3, sizeof(msg3) - 1) == -1)) {
logit(LOG_ERR, "ERROR: alarm_handler() write(): %s", strerror(errno));
}
exit(timeout_return_code);
}

View File

@@ -1,10 +1,10 @@
/*******************************************************************************
/****************************************************************************
*
* NRPE.C - Nagios Remote Plugin Executor
* nrpe.c - Nagios Remote Plugin Executor
*
* Copyright (c) 2009 Nagios Core Development Team and Community Contributors
* Copyright (c) 1999-2008 Ethan Galstad (nagios@nagios.org)
* License: GPL
* License: GPLv2
* Copyright (c) 2009-2017 Nagios Enterprises
* 1999-2008 Ethan Galstad (nagios@nagios.org)
*
* Command line: nrpe -c <config_file> [--inetd | --daemon]
*
@@ -16,13 +16,23 @@
* such as check_users, check_load, check_disk, etc. without
* having to use rsh or ssh.
*
******************************************************************************/
/*
* 08-10-2011 IPv4 subnetworks support added.
* Main change in nrpe.c is that is_an_allowed_host() moved to acl.c.
* now allowed_hosts is parsed by parse_allowed_hosts() from acl.c.
*/
* License Notice:
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
****************************************************************************/
#include "config.h"
#include "common.h"
@@ -102,6 +112,8 @@ int show_help = FALSE;
int show_license = FALSE;
int show_version = FALSE;
int use_inetd = TRUE;
int commands_running = 0;
int max_commands = 0;
int debug = FALSE;
int use_src = FALSE; /* Define parameter for SRC option */
int no_forking = FALSE;
@@ -135,7 +147,11 @@ struct _SSL_PARMS {
ClntCerts client_certs;
SslLogging log_opts;
} sslprm = {
#if OPENSSL_VERSION_NUMBER >= 0x10100000
NULL, NULL, NULL, "ALL:!MD5:@STRENGTH:@SECLEVEL=0", TLSv1_plus, TRUE, 0, SSL_NoLogging};
#else
NULL, NULL, NULL, "ALL:!MD5:@STRENGTH", TLSv1_plus, TRUE, 0, SSL_NoLogging};
#endif
#ifdef HAVE_SSL
@@ -167,7 +183,10 @@ int main(int argc, char **argv)
/* get absolute path of current working directory */
strcpy(config_file, "");
getcwd(config_file, sizeof(config_file));
if (getcwd(config_file, sizeof(config_file)) == NULL) {
printf("ERROR: getcwd(): %s, bailing out...\n", strerror(errno));
exit(STATE_CRITICAL);
}
/* append a forward slash */
strncat(config_file, "/", sizeof(config_file) - 2);
@@ -263,6 +282,9 @@ void init_ssl(void)
/* initialize SSL */
SSL_load_error_strings();
SSL_library_init();
ENGINE_load_builtin_engines();
RAND_set_rand_engine(NULL);
ENGINE_register_all_complete();
meth = SSLv23_server_method();
@@ -408,7 +430,7 @@ void init_ssl(void)
SSL_CTX_set_verify(ctx, vrfy, verify_callback);
if (!SSL_CTX_load_verify_locations(ctx, sslprm.cacert_file, NULL)) {
while ((x = ERR_get_error_line_data(NULL, NULL, NULL, NULL)) != 0) {
logit(LOG_ERR, "Error: could not use certificate file '%s': %s\n",
logit(LOG_ERR, "Error: could not use CA certificate file '%s': %s\n",
sslprm.cacert_file, ERR_reason_error_string(x));
}
SSL_CTX_free(ctx);
@@ -422,8 +444,14 @@ void init_ssl(void)
strcat(sslprm.cipher_list, ":!ADH");
} else {
/* use anonymous DH ciphers */
if (sslprm.allowDH == 2)
strcpy(sslprm.cipher_list, "ADH");
if (sslprm.allowDH == 2) {
#if OPENSSL_VERSION_NUMBER >= 0x10100000
strncpy(sslprm.cipher_list, "ADH@SECLEVEL=0", MAX_FILENAME_LENGTH - 1);
#else
strncpy(sslprm.cipher_list, "ADH", MAX_FILENAME_LENGTH - 1);
#endif
}
#ifdef USE_SSL_DH
dh = get_dh2048();
SSL_CTX_set_tmp_dh(ctx, dh);
@@ -452,12 +480,8 @@ void log_ssl_startup(void)
sslprm.privatekey_file ? sslprm.privatekey_file : "None");
logit(LOG_INFO, "SSL CA Certificate File: %s",
sslprm.cacert_file ? sslprm.cacert_file : "None");
if (sslprm.allowDH < 2)
logit(LOG_INFO, "SSL Cipher List: %s", sslprm.cipher_list);
else
logit(LOG_INFO, "SSL Cipher List: ADH");
logit(LOG_INFO, "SSL Allow ADH: %s",
sslprm.allowDH == 0 ? "No" : (sslprm.allowDH == 1 ? "Allow" : "Require"));
logit(LOG_INFO, "SSL Cipher List: %s", sslprm.cipher_list);
logit(LOG_INFO, "SSL Allow ADH: %d", sslprm.allowDH == 0);
logit(LOG_INFO, "SSL Client Certs: %s",
sslprm.client_certs == 0 ? "Don't Ask" : (sslprm.client_certs ==
1 ? "Accept" : "Require"));
@@ -503,50 +527,57 @@ void log_ssl_startup(void)
void usage(int result)
{
printf("\n");
if (result != OK) {
printf("\n");
printf("Incorrect command line arguments supplied\n");
printf("\n");
}
printf("NRPE - Nagios Remote Plugin Executor\n");
printf("Copyright (c) 1999-2008 Ethan Galstad (nagios@nagios.org)\n");
printf("Version: %s\n", PROGRAM_VERSION);
printf("Last Modified: %s\n", MODIFICATION_DATE);
printf("License: GPL v2 with exemptions (-l for more info)\n");
printf("\n");
if (result != OK || show_help == TRUE) {
printf("Copyright (c) 2009-2017 Nagios Enterprises\n");
printf(" 1999-2008 Ethan Galstad (nagios@nagios.org)\n");
printf("\n");
printf("Last Modified: %s\n", MODIFICATION_DATE);
printf("\n");
printf("License: GPL v2 with exemptions (-l for more info)\n");
printf("\n");
#ifdef HAVE_SSL
printf("SSL/TLS Available, OpenSSL 0.9.6 or higher required\n");
printf("SSL/TLS Available, OpenSSL 0.9.6 or higher required\n");
printf("\n");
#endif
#ifdef HAVE_LIBWRAP
printf("TCP Wrappers Available\n");
printf("TCP Wrappers Available\n");
printf("\n");
#endif
printf("\n");
#ifdef ENABLE_COMMAND_ARGUMENTS
printf("***************************************************************\n");
printf("** POSSIBLE SECURITY RISK - COMMAND ARGUMENTS ARE SUPPORTED! **\n");
printf("** Read the NRPE SECURITY file for more information **\n");
printf("***************************************************************\n");
printf("\n");
printf("***************************************************************\n");
printf("** POSSIBLE SECURITY RISK - COMMAND ARGUMENTS ARE SUPPORTED! **\n");
printf("** Read the NRPE SECURITY file for more information **\n");
printf("***************************************************************\n");
printf("\n");
#endif
#ifndef HAVE_LIBWRAP
printf("***************************************************************\n");
printf("** POSSIBLE SECURITY RISK - TCP WRAPPERS ARE NOT AVAILABLE! **\n");
printf("** Read the NRPE SECURITY file for more information **\n");
printf("***************************************************************\n");
printf("\n");
printf("***************************************************************\n");
printf("** POSSIBLE SECURITY RISK - TCP WRAPPERS ARE NOT AVAILABLE! **\n");
printf("** Read the NRPE SECURITY file for more information **\n");
printf("***************************************************************\n");
printf("\n");
#endif
if (show_license == TRUE)
display_license();
if (result != OK || show_help == TRUE) {
printf("Usage: nrpe [-n] -c <config_file> [-4|-6] <mode>\n");
printf("Usage: nrpe [-V] [-n] -c <config_file> [-4|-6] <mode>\n");
printf("\n");
printf("Options:\n");
printf(" -n = Do not use SSL\n");
printf(" -c <config_file> = Name of config file to use\n");
printf(" -4 = use ipv4 only\n");
printf(" -6 = use ipv6 only\n");
printf(" <mode> = One of the following operating modes:\n");
printf(" -i = Run as a service under inetd or xinetd\n");
printf(" -d = Run as a standalone daemon\n");
printf(" -d -s = Run as a subsystem under AIX\n");
printf(" -f = Don't fork() for systemd, launchd, etc.\n");
printf(" -V, --version Print version info and quit\n");
printf(" -n, --no-ssl Do not use SSL\n");
printf(" -c, --config=FILE Name of config file to use\n");
printf(" -4, --ipv4 Use ipv4 only\n");
printf(" -6, --ipv6 Use ipv6 only\n");
printf(" <mode> (One of the following operating modes)\n");
printf(" -i, --inetd Run as a service under inetd or xinetd\n");
printf(" -d, --daemon Run as a standalone daemon\n");
printf(" -s, --src Run as a subsystem under AIX\n");
printf(" -f, --no-forking Don't fork() (for systemd, launchd, etc.)\n");
printf("\n");
printf("Notes:\n");
printf("This program is designed to process requests from the check_nrpe\n");
@@ -559,6 +590,9 @@ void usage(int result)
printf("\n");
}
if (show_license == TRUE)
display_license();
exit(STATE_UNKNOWN);
}
@@ -621,6 +655,11 @@ void set_stdio_sigs(void)
struct sigaction sig_action;
#endif
if (chdir("/") == -1) {
printf("ERROR: chdir(): %s, bailing out...\n", strerror(errno));
exit(STATE_CRITICAL);
}
close(0); /* close standard file descriptors */
close(1);
close(2);
@@ -628,8 +667,6 @@ void set_stdio_sigs(void)
open("/dev/null", O_WRONLY);
open("/dev/null", O_WRONLY);
chdir("/");
/* handle signals */
#ifdef HAVE_SIGACTION
sig_action.sa_sigaction = NULL;
@@ -650,8 +687,10 @@ void set_stdio_sigs(void)
exit(STATE_CRITICAL);
clean_environ(keep_env_vars, nrpe_user);
drop_privileges(nrpe_user, nrpe_group, 0); /* drop privileges */
check_privileges(); /* make sure we're not root */
/* drop and then check privileges */
drop_privileges(nrpe_user, nrpe_group, 0);
check_privileges();
}
void cleanup(void)
@@ -786,6 +825,14 @@ int read_config_file(char *filename)
if (read_config_file(varvalue) == ERROR)
logit(LOG_ERR, "Continuing with errors...");
} else if (!strcmp(varname, "max_commands")) {
max_commands = atoi(varvalue);
if (max_commands < 0) {
logit(LOG_WARNING, "max_commands set too low, setting to 0\n");
max_commands = 0;
}
} else if (!strcmp(varname, "server_port")) {
server_port = atoi(varvalue);
if (server_port < 1024) {
@@ -1407,7 +1454,7 @@ int wait_conn_fork(int sock)
pid = fork();
if (pid < 0) {
logit(LOG_ERR, "fork() failed with error %d, bailing out...", errno);
logit(LOG_ERR, "Second fork() failed with error %d, bailing out...", errno);
exit(STATE_CRITICAL);
}
@@ -1500,10 +1547,10 @@ void conn_check_peer(int sock)
}
if (debug == TRUE)
logit(LOG_INFO, "CONN_CHECK_PEER: is this a blessed machine: %s port %d\n",
logit(LOG_INFO, "CONN_CHECK_PEER: checking if host is allowed: %s port %d\n",
remote_host, nptr->sin_port);
/* is this is a blessed machine? */
/* is this host allowed? */
if (allowed_hosts) {
#ifdef HAVE_STRUCT_SOCKADDR_STORAGE
switch (addr.ss_family) {
@@ -1707,7 +1754,7 @@ void handle_connection(int sock)
send_buff = calloc(1, sizeof(buffer));
strcpy(send_buff, buffer);
}
result = STATE_CRITICAL;
result = STATE_UNKNOWN;
} else {
@@ -1873,31 +1920,29 @@ int handle_conn_ssl(int sock, void *ssl_ptr)
/* keep attempting the request if needed */
while (((rc = SSL_accept(ssl)) != 1)
&& (SSL_get_error(ssl, rc) == SSL_ERROR_WANT_READ)) ;
&& (SSL_get_error(ssl, rc) == SSL_ERROR_WANT_READ));
if (rc != 1) {
/* oops, got an unrecoverable error -- get out */
if (sslprm.log_opts & (SSL_LogCertDetails | SSL_LogIfClientCert)) {
int nerrs = 0;
int nerrs = 0;
rc = 0;
while ((x = ERR_get_error_line_data(NULL, NULL, NULL, NULL)) != 0) {
errmsg = ERR_reason_error_string(x);
logit(LOG_ERR, "Error: Could not complete SSL handshake with %s: %s",
remote_host, errmsg);
if (errmsg && !strcmp(errmsg, "no shared cipher")) {
if (sslprm.cert_file == NULL || sslprm.cacert_file == NULL)
logit(LOG_ERR, "Error: This could be because you have not "
"specified certificate or ca-certificate files");
}
logit(LOG_ERR, "Error: (ERR_get_error_line_data = %d), Could not complete SSL handshake with %s: %s", x, remote_host, errmsg);
if (errmsg && !strcmp(errmsg, "no shared cipher") && (sslprm.cert_file == NULL || sslprm.cacert_file == NULL))
logit(LOG_ERR, "Error: This could be because you have not specified certificate or ca-certificate files");
++nerrs;
}
if (nerrs == 0)
logit(LOG_ERR, "Error: Could not complete SSL handshake with %s: %d",
remote_host, SSL_get_error(ssl, rc));
} else
logit(LOG_ERR, "Error: Could not complete SSL handshake with %s: %d",
remote_host, SSL_get_error(ssl, rc));
if (nerrs == 0) {
logit(LOG_ERR, "Error: (nerrs = 0) Could not complete SSL handshake with %s: %d", remote_host, SSL_get_error(ssl, rc));
}
} else {
logit(LOG_ERR, "Error: (!log_opts) Could not complete SSL handshake with %s: %d", remote_host, SSL_get_error(ssl, rc));
}
# ifdef DEBUG
errfp = fopen("/tmp/err.log", "a");
ERR_print_errors_fp(errfp);
@@ -1908,27 +1953,30 @@ int handle_conn_ssl(int sock, void *ssl_ptr)
/* successful handshake */
if (sslprm.log_opts & SSL_LogVersion)
logit(LOG_NOTICE, "Remote %s - SSL Version: %s",
remote_host, SSL_get_version(ssl));
logit(LOG_NOTICE, "Remote %s - SSL Version: %s", remote_host, SSL_get_version(ssl));
if (sslprm.log_opts & SSL_LogCipher) {
c = SSL_get_current_cipher(ssl);
logit(LOG_NOTICE, "Remote %s - %s, Cipher is %s", remote_host,
SSL_CIPHER_get_version(c), SSL_CIPHER_get_name(c));
logit(LOG_NOTICE, "Remote %s - %s, Cipher is %s", remote_host, SSL_CIPHER_get_version(c), SSL_CIPHER_get_name(c));
}
if ((sslprm.log_opts & SSL_LogIfClientCert)
|| (sslprm.log_opts & SSL_LogCertDetails))
{
|| (sslprm.log_opts & SSL_LogCertDetails)) {
peer = SSL_get_peer_certificate(ssl);
if (peer) {
if (sslprm.log_opts & SSL_LogIfClientCert)
logit(LOG_NOTICE, "SSL Client %s has %svalid certificate",
remote_host, SSL_get_verify_result(ssl) ? "a " : "an in");
logit(LOG_NOTICE, "SSL Client %s has %s certificate",
remote_host, SSL_get_verify_result(ssl) == X509_V_OK ? "a valid" : "an invalid");
if (sslprm.log_opts & SSL_LogCertDetails) {
X509_NAME_oneline(X509_get_subject_name(peer), buffer, sizeof(buffer));
logit(LOG_NOTICE, "SSL Client %s Cert Name: %s",
remote_host, buffer);
X509_NAME_oneline(X509_get_issuer_name(peer), buffer, sizeof(buffer));
logit(LOG_NOTICE, "SSL Client %s Cert Issuer: %s",
remote_host, buffer);
@@ -1963,7 +2011,7 @@ int read_packet(int sock, void *ssl_ptr, v2_packet * v2_pkt, v3_packet ** v3_pkt
packet_ver = ntohs(v2_pkt->packet_version);
if (packet_ver != NRPE_PACKET_VERSION_2 && packet_ver != NRPE_PACKET_VERSION_3) {
logit(LOG_ERR, "Error: Request packet version was invalid!");
logit(LOG_ERR, "Error: (use_ssl == false): Request packet version was invalid!");
return -1;
}
@@ -1991,7 +2039,7 @@ int read_packet(int sock, void *ssl_ptr, v2_packet * v2_pkt, v3_packet ** v3_pkt
buffer_size = ntohl(buffer_size);
pkt_size += buffer_size;
if ((*v3_pkt = calloc(1, pkt_size)) == NULL) {
logit(LOG_ERR, "Error: Could not allocate memory for packet");
logit(LOG_ERR, "Error: (use_ssl == false): Could not allocate memory for packet");
return -1;
}
@@ -2025,7 +2073,7 @@ int read_packet(int sock, void *ssl_ptr, v2_packet * v2_pkt, v3_packet ** v3_pkt
packet_ver = ntohs(v2_pkt->packet_version);
if (packet_ver != NRPE_PACKET_VERSION_2 && packet_ver != NRPE_PACKET_VERSION_3) {
logit(LOG_ERR, "Error: Request packet version was invalid!");
logit(LOG_ERR, "Error: (use_ssl == true): Request packet version was invalid!");
return -1;
}
@@ -2058,7 +2106,7 @@ int read_packet(int sock, void *ssl_ptr, v2_packet * v2_pkt, v3_packet ** v3_pkt
buffer_size = ntohl(buffer_size);
pkt_size += buffer_size;
if ((*v3_pkt = calloc(1, pkt_size)) == NULL) {
logit(LOG_ERR, "Error: Could not allocate memory for packet");
logit(LOG_ERR, "Error: (use_ssl == true): Could not allocate memory for packet");
return -1;
}
@@ -2129,7 +2177,19 @@ int my_system(char *command, int timeout, int *early_timeout, char **output)
if (command == NULL) /* if no command was passed, return with no error */
return STATE_OK;
pipe(fd); /* create a pipe */
/* make sure that we are within max_commands boundaries before attempting */
if (max_commands != 0) {
while (commands_running >= max_commands) {
logit(LOG_WARNING, "Commands choked. Sleeping 1s - commands_running: %d, max_commands: %d", commands_running, max_commands);
sleep(1);
}
}
/* create a pipe */
if (pipe(fd) == -1) {
logit(LOG_ERR, "ERROR: pipe(): %s, bailing out...", strerror(errno));
exit(STATE_CRITICAL);
}
/* make the pipe non-blocking */
fcntl(fd[0], F_SETFL, O_NONBLOCK);
@@ -2161,7 +2221,11 @@ int my_system(char *command, int timeout, int *early_timeout, char **output)
/* execute the command in the child process */
if (pid == 0) {
SETEUID(0); /* get root back so the next call works correctly */
/* get root back so the next call works correctly */
if (SETEUID(0) == -1 && debug)
logit(LOG_WARNING, "WARNING: my_system() seteuid(0): %s", strerror(errno));
drop_privileges(nrpe_user, nrpe_group, 1); /* drop privileges */
close(fd[0]); /* close pipe for reading */
setpgid(0, 0); /* become process group leader */
@@ -2184,8 +2248,11 @@ int my_system(char *command, int timeout, int *early_timeout, char **output)
if (fp == NULL) {
strncpy(buffer, "NRPE: Call to popen() failed\n", sizeof(buffer) - 1);
buffer[sizeof(buffer) - 1] = '\x0';
/* write the error back to the parent process */
write(fd[1], buffer, strlen(buffer) + 1);
if (write(fd[1], buffer, strlen(buffer) + 1) == -1)
logit(LOG_ERR, "ERROR: my_system() write(fd, buffer)-1 failed...");
result = STATE_CRITICAL;
} else {
@@ -2193,10 +2260,13 @@ int my_system(char *command, int timeout, int *early_timeout, char **output)
/* read all lines of output - supports Nagios 3.x multiline output */
while ((bytes_read = fread(buffer, 1, sizeof(buffer) - 1, fp)) > 0) {
/* write the output back to the parent process */
write(fd[1], buffer, bytes_read);
if (write(fd[1], buffer, bytes_read) == -1)
logit(LOG_ERR, "ERROR: my_system() write(fd, buffer)-2 failed...");
}
write(fd[1], "\0", 1);
if (write(fd[1], "\0", 1) == -1)
logit(LOG_ERR, "ERROR: my_system() write(fd, NULL) failed...");
status = pclose(fp); /* close the command and get termination status */
/* report an error if we couldn't close the command */
@@ -2216,6 +2286,8 @@ int my_system(char *command, int timeout, int *early_timeout, char **output)
} else {
/* parent waits for child to finish executing command */
commands_running++;
close(fd[1]); /* close pipe for writing */
waitpid(pid, &status, 0); /* wait for child to exit */
time(&end_time); /* get the end time for running the command */
@@ -2266,6 +2338,8 @@ int my_system(char *command, int timeout, int *early_timeout, char **output)
}
close(fd[0]); /* close the pipe for reading */
commands_running--;
}
#ifdef DEBUG
@@ -2296,6 +2370,9 @@ int drop_privileges(char *user, char *group, int full_drop)
struct group *grp;
struct passwd *pw;
if (use_inetd == TRUE)
return OK;
/* set effective group ID */
if (group != NULL) {
@@ -2342,11 +2419,9 @@ int drop_privileges(char *user, char *group, int full_drop)
/* initialize supplementary groups */
if (initgroups(user, gid) == -1) {
if (errno == EPERM)
logit(LOG_ERR,
"Warning: Unable to change supplementary groups using initgroups()");
logit(LOG_ERR, "Warning: Unable to change supplementary groups using initgroups()");
else {
logit(LOG_ERR,
"Warning: Possibly root user failed dropping privileges with initgroups()");
logit(LOG_ERR, "Warning: Possibly root user failed dropping privileges with initgroups()");
return ERROR;
}
}
@@ -2391,9 +2466,7 @@ int write_pid_file(void)
else {
/* previous process is still running */
logit(LOG_ERR,
"There's already an NRPE server running (PID %lu). Bailing out...",
(unsigned long)pid);
logit(LOG_ERR, "There's already an NRPE server running (PID %lu). Bailing out...", (unsigned long)pid);
return ERROR;
}
}
@@ -2402,7 +2475,10 @@ int write_pid_file(void)
/* write new pid file */
if ((fd = open(pid_file, O_WRONLY | O_CREAT, 0644)) >= 0) {
sprintf(pbuf, "%d\n", (int)getpid());
write(fd, pbuf, strlen(pbuf));
if (write(fd, pbuf, strlen(pbuf)) == -1)
logit(LOG_ERR, "ERROR: write_pid_file() write(fd, pbuf) failed...");
close(fd);
wrote_pid_file = TRUE;
} else {
@@ -2421,7 +2497,10 @@ int remove_pid_file(void)
if (wrote_pid_file == FALSE)
return OK; /* pid file was not written */
SETEUID(0); /* get root back so we can delete the pid file */
/* get root back so we can delete the pid file */
if (SETEUID(0) == -1 && debug)
logit(LOG_WARNING, "WARNING: remove_pid_file() seteuid(0): %s", strerror(errno));
if (unlink(pid_file) == -1) {
logit(LOG_ERR, "Cannot remove pidfile '%s' - check your privileges.", pid_file);
return ERROR;
@@ -2587,8 +2666,7 @@ int validate_request(v2_packet * v2pkt, v3_packet * v3pkt)
if (strchr(v2pkt->buffer, '!')) {
#ifdef ENABLE_COMMAND_ARGUMENTS
if (allow_arguments == FALSE) {
logit(LOG_ERR,
"Error: Request contained command arguments, but argument option is not enabled!");
logit(LOG_ERR, "Error: Request contained command arguments, but argument option is not enabled!");
return ERROR;
}
#else
@@ -2631,8 +2709,7 @@ int validate_request(v2_packet * v2pkt, v3_packet * v3pkt)
return ERROR;
# else
if (FALSE == allow_bash_cmd_subst) {
logit(LOG_ERR,
"Error: Request contained a bash command substitution, but they are disallowed!");
logit(LOG_ERR, "Error: Request contained a bash command substitution, but they are disallowed!");
return ERROR;
}
# endif
@@ -2737,11 +2814,12 @@ int process_arguments(int argc, char **argv)
{"src", no_argument, 0, 's'},
{"no-forking", no_argument, 0, 'f'},
{"4", no_argument, 0, '4'},
{"6", no_argument, 0, '4'},
{"ipv6", no_argument, 0, '6'},
{"daemon", no_argument, 0, 'd'},
{"no-ssl", no_argument, 0, 'n'},
{"help", no_argument, 0, 'h'},
{"license", no_argument, 0, 'l'},
{"version", no_argument, 0, 'V'},
{0, 0, 0, 0}
};
#endif
@@ -2771,6 +2849,7 @@ int process_arguments(int argc, char **argv)
case 'V':
show_version = TRUE;
have_mode = TRUE;
break;
case 'l':

View File

@@ -1,17 +1,16 @@
/****************************************************************************
*
* UTILS.C - NRPE Utility Functions
* utils.c - NRPE Utility Functions
*
* License: GPL
* Copyright (c) 1999-2006 Ethan Galstad (nagios@nagios.org)
*
* Last Modified: 12-11-2006
* License: GPLv2
* Copyright (c) 2009-2017 Nagios Enterprises
* 1999-2008 Ethan Galstad (nagios@nagios.org)
*
* Description:
*
* This file contains common network functions used in nrpe and check_nrpe.
*
* License Information:
* License Notice:
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -58,7 +57,7 @@ static unsigned long crc32_table[256];
char *log_file = NULL;
FILE *log_fp = NULL;
static int my_create_socket(struct addrinfo *ai, const char *bind_address);
static int my_create_socket(struct addrinfo *ai, const char *bind_address, int redirect_stderr);
/* build the crc table - must be called before calculating the crc value */
@@ -134,10 +133,10 @@ void randomize_buffer(char *buffer, int buffer_size)
/* opens a connection to a remote host */
#ifdef HAVE_STRUCT_SOCKADDR_STORAGE
int my_connect(const char *host, struct sockaddr_storage *hostaddr, u_short port,
int address_family, const char *bind_address)
int address_family, const char *bind_address, int redirect_stderr)
#else
int my_connect(const char *host, struct sockaddr *hostaddr, u_short port,
int address_family, const char *bind_address)
int address_family, const char *bind_address, int redirect_stderr)
#endif
{
struct addrinfo hints, *ai, *aitop;
@@ -145,12 +144,16 @@ int my_connect(const char *host, struct sockaddr *hostaddr, u_short port,
int gaierr;
int sock = -1;
FILE *output = stderr;
if (redirect_stderr)
output = stdout;
memset(&hints, 0, sizeof(hints));
hints.ai_family = address_family;
hints.ai_socktype = SOCK_STREAM;
snprintf(strport, sizeof strport, "%u", port);
if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0) {
fprintf(stderr, "Could not resolve hostname %.100s: %s\n", host, gai_strerror(gaierr));
fprintf(output, "Could not resolve hostname %.100s: %s\n", host, gai_strerror(gaierr));
exit(1);
}
@@ -163,12 +166,12 @@ int my_connect(const char *host, struct sockaddr *hostaddr, u_short port,
continue;
if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, sizeof(ntop),
strport, sizeof(strport), NI_NUMERICHOST | NI_NUMERICSERV) != 0) {
fprintf(stderr, "my_connect: getnameinfo failed\n");
fprintf(output, "my_connect: getnameinfo failed\n");
continue;
}
/* Create a socket for connecting. */
sock = my_create_socket(ai, bind_address);
sock = my_create_socket(ai, bind_address, redirect_stderr);
if (sock < 0)
continue; /* Any error is already output */
@@ -177,7 +180,7 @@ int my_connect(const char *host, struct sockaddr *hostaddr, u_short port,
memcpy(hostaddr, ai->ai_addr, ai->ai_addrlen);
break;
} else {
fprintf(stderr, "connect to address %s port %s: %s\n", ntop, strport,
fprintf(output, "connect to address %s port %s: %s\n", ntop, strport,
strerror(errno));
close(sock);
sock = -1;
@@ -188,21 +191,25 @@ int my_connect(const char *host, struct sockaddr *hostaddr, u_short port,
/* Return failure if we didn't get a successful connection. */
if (sock == -1) {
fprintf(stderr, "connect to host %s port %s: %s\n", host, strport, strerror(errno));
fprintf(output, "connect to host %s port %s: %s\n", host, strport, strerror(errno));
return -1;
}
return sock;
}
/* Creates a socket for the connection. */
int my_create_socket(struct addrinfo *ai, const char *bind_address)
int my_create_socket(struct addrinfo *ai, const char *bind_address, int redirect_stderr)
{
int sock, gaierr;
struct addrinfo hints, *res;
FILE *output = stderr;
if (redirect_stderr)
output = stdout;
sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
if (sock < 0)
fprintf(stderr, "socket: %.100s\n", strerror(errno));
fprintf(output, "socket: %.100s\n", strerror(errno));
/* Bind the socket to an alternative local IP address */
if (bind_address == NULL)
@@ -215,12 +222,12 @@ int my_create_socket(struct addrinfo *ai, const char *bind_address)
hints.ai_flags = AI_PASSIVE;
gaierr = getaddrinfo(bind_address, NULL, &hints, &res);
if (gaierr) {
fprintf(stderr, "getaddrinfo: %s: %s\n", bind_address, gai_strerror(gaierr));
fprintf(output, "getaddrinfo: %s: %s\n", bind_address, gai_strerror(gaierr));
close(sock);
return -1;
}
if (bind(sock, res->ai_addr, res->ai_addrlen) < 0) {
fprintf(stderr, "bind: %s: %s\n", bind_address, strerror(errno));
fprintf(output, "bind: %s: %s\n", bind_address, strerror(errno));
close(sock);
freeaddrinfo(res);
return -1;
@@ -319,24 +326,35 @@ int clean_environ(const char *keep_env_vars, const char *nrpe_user)
free(keep);
free(kept);
setenv("PATH", path, 1);
setenv("IFS", " \t\n", 1);
setenv("LOGNAME", nrpe_user, 0);
setenv("USER", nrpe_user, 0);
pw = (struct passwd *)getpwnam(nrpe_user);
if (pw == NULL) {
char *end = NULL;
uid_t uid = strtol(nrpe_user, &end, 10);
if (uid > 0)
pw = (struct passwd *)getpwuid(uid);
if (pw == NULL || *end != '\0')
return OK;
char * user = NULL;
if (nrpe_user != NULL) {
user = strdup(nrpe_user);
pw = (struct passwd *)getpwnam(nrpe_user);
}
if (nrpe_user == NULL || pw == NULL) {
pw = (struct passwd *)getpwuid(getuid());
if (pw != NULL) {
user = strdup(pw->pw_name);
}
}
if (pw == NULL) {
free(user);
return OK;
}
setenv("PATH", path, 1);
setenv("IFS", " \t\n", 1);
setenv("LOGNAME", user, 0);
setenv("USER", user, 0);
setenv("HOME", pw->pw_dir, 0);
setenv("SHELL", pw->pw_shell, 0);
free(user);
return OK;
}