1 /****************************************************************************
2  *
3  * nrpe.c - Nagios Remote Plugin Executor
4  *
5  * License: GPLv2
6  * Copyright (c) 2009-2017 Nagios Enterprises
7  *               1999-2008 Ethan Galstad (nagios@nagios.org)
8  *
9  * Command line: nrpe -c <config_file> [--inetd | --daemon]
10  *
11  * Description:
12  *
13  * This program is designed to run as a background process and
14  * handle incoming requests (from the host running Nagios) for
15  * plugin execution.  It is useful for running "local" plugins
16  * such as check_users, check_load, check_disk, etc. without
17  * having to use rsh or ssh.
18  *
19  * License Notice:
20  *
21  * This program is free software; you can redistribute it and/or modify
22  * it under the terms of the GNU General Public License as published by
23  * the Free Software Foundation; either version 2 of the License, or
24  * (at your option) any later version.
25  *
26  * This program is distributed in the hope that it will be useful,
27  * but WITHOUT ANY WARRANTY; without even the implied warranty of
28  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
29  * GNU General Public License for more details.
30  *
31  * You should have received a copy of the GNU General Public License
32  * along with this program; if not, write to the Free Software
33  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
34  *
35  ****************************************************************************/
36 
37 #include "config.h"
38 #include "common.h"
39 #include "nrpe.h"
40 #include "utils.h"
41 #include "acl.h"
42 
43 #ifdef HAVE_SSL
44 # ifdef USE_SSL_DH
45 #  include "../include/dh.h"
46 # endif
47 #endif
48 #ifndef HAVE_ASPRINTF
49 extern int asprintf(char **ptr, const char *format, ...);
50 #endif
51 
52 #ifdef HAVE_LIBWRAP
53 int       allow_severity = LOG_INFO;
54 int       deny_severity = LOG_WARNING;
55 # ifndef HAVE_RFC931_TIMEOUT
56 int       rfc931_timeout=15;
57 # endif
58 #endif
59 
60 #ifdef HAVE_SSL
61 # if (defined(__sun) && defined(SOLARIS_10)) || defined(_AIX) || defined(__hpux)
62 SSL_METHOD *meth;
63 # else
64 const SSL_METHOD *meth;
65 # endif
66 SSL_CTX  *ctx;
67 int       use_ssl = TRUE;
68 #else
69 int       use_ssl = FALSE;
70 #endif
71 
72 #define DEFAULT_COMMAND_TIMEOUT			60	/* default timeout for execution of plugins */
73 #define MAXFD							64
74 #define NASTY_METACHARS					"|`&><'\\[]{};\r\n"
75 #define MAX_LISTEN_SOCKS				16
76 #define DEFAULT_LISTEN_QUEUE_SIZE		5
77 #define DEFAULT_SSL_SHUTDOWN_TIMEOUT	15
78 
79 #define how_many(x,y) (((x)+((y)-1))/(y))
80 
81 extern int errno;
82 struct addrinfo *listen_addrs = NULL;
83 int       listen_socks[MAX_LISTEN_SOCKS];
84 char      remote_host[MAX_HOST_ADDRESS_LENGTH];
85 char     *macro_argv[MAX_COMMAND_ARGUMENTS];
86 char      config_file[MAX_INPUT_BUFFER] = "nrpe.cfg";
87 char      server_address[NI_MAXHOST] = "";
88 char     *command_name = NULL;
89 int       log_facility = LOG_DAEMON;
90 int       server_port = DEFAULT_SERVER_PORT;
91 int       num_listen_socks = 0;
92 int       address_family = AF_UNSPEC;
93 int       socket_timeout = DEFAULT_SOCKET_TIMEOUT;
94 int       command_timeout = DEFAULT_COMMAND_TIMEOUT;
95 int       connection_timeout = DEFAULT_CONNECTION_TIMEOUT;
96 int       ssl_shutdown_timeout = DEFAULT_SSL_SHUTDOWN_TIMEOUT;
97 char     *command_prefix = NULL;
98 int       packet_ver = 0;
99 command  *command_list = NULL;
100 char     *nrpe_user = NULL;
101 char     *nrpe_group = NULL;
102 char     *allowed_hosts = NULL;
103 char     *keep_env_vars = NULL;
104 char     *pid_file = NULL;
105 int       wrote_pid_file = FALSE;
106 int       allow_arguments = FALSE;
107 int       allow_bash_cmd_subst = FALSE;
108 int       allow_weak_random_seed = FALSE;
109 int       sigrestart = FALSE;
110 int       sigshutdown = FALSE;
111 int       show_help = FALSE;
112 int       show_license = FALSE;
113 int       show_version = FALSE;
114 int       use_inetd = TRUE;
115 int 	  commands_running = 0;
116 int       max_commands = 0;
117 int       debug = FALSE;
118 int       use_src = FALSE;		/* Define parameter for SRC option */
119 int       no_forking = FALSE;
120 int       listen_queue_size = DEFAULT_LISTEN_QUEUE_SIZE;
121 char     *nasty_metachars = NULL;
122 extern char *log_file;
123 
124 /* SSL/TLS parameters */
125 typedef enum _SSL_VER {
126 	SSLv2 = 1, SSLv2_plus, SSLv3, SSLv3_plus, TLSv1,
127 	TLSv1_plus, TLSv1_1, TLSv1_1_plus, TLSv1_2, TLSv1_2_plus
128 } SslVer;
129 
130 typedef enum _CLNT_CERTS {
131 	ClntCerts_Unknown = 0, Ask_For_Cert = 1, Require_Cert = 2
132 } ClntCerts;
133 
134 typedef enum _SSL_LOGGING {
135 	SSL_NoLogging = 0, SSL_LogStartup = 1, SSL_LogIpAddr = 2,
136 	SSL_LogVersion = 4, SSL_LogCipher = 8, SSL_LogIfClientCert = 16,
137 	SSL_LogCertDetails = 32
138 } SslLogging;
139 
140 struct _SSL_PARMS {
141 	char     *cert_file;
142 	char     *cacert_file;
143 	char     *privatekey_file;
144 	char      cipher_list[MAX_FILENAME_LENGTH];
145 	SslVer    ssl_proto_ver;
146 	int       allowDH;
147 	ClntCerts client_certs;
148 	SslLogging log_opts;
149 } sslprm = {
150 #if OPENSSL_VERSION_NUMBER >= 0x10100000
151 NULL, NULL, NULL, "ALL:!MD5:@STRENGTH:@SECLEVEL=0", TLSv1_plus, TRUE, 0, SSL_NoLogging};
152 #else
153 NULL, NULL, NULL, "ALL:!MD5:@STRENGTH", TLSv1_plus, TRUE, 0, SSL_NoLogging};
154 #endif
155 
156 
157 #ifdef HAVE_SSL
158 static int verify_callback(int ok, X509_STORE_CTX * ctx);
159 static void my_disconnect_sighandler(int sig);
160 static void complete_SSL_shutdown(SSL *);
161 #endif
162 
main(int argc,char ** argv)163 int main(int argc, char **argv)
164 {
165 	int       result = OK;
166 	int       x;
167 	uint32_t  y;
168 	char      buffer[MAX_INPUT_BUFFER];
169 
170 	init();
171 
172 	/* process command-line args */
173 	result = process_arguments(argc, argv);
174 	if (result != OK || show_help == TRUE || show_license == TRUE || show_version == TRUE)
175 		usage(result);
176 
177 	/* make sure the config file uses an absolute path */
178 	if (config_file[0] != '/') {
179 
180 		/* save the name of the config file */
181 		strncpy(buffer, config_file, sizeof(buffer));
182 		buffer[sizeof(buffer) - 1] = '\x0';
183 
184 		/* get absolute path of current working directory */
185 		strcpy(config_file, "");
186 		if (getcwd(config_file, sizeof(config_file)) == NULL) {
187 			printf("ERROR: getcwd(): %s, bailing out...\n", strerror(errno));
188 			exit(STATE_CRITICAL);
189 		}
190 
191 		/* append a forward slash */
192 		strncat(config_file, "/", sizeof(config_file) - 2);
193 		config_file[sizeof(config_file) - 1] = '\x0';
194 
195 		/* append the config file to the path */
196 		strncat(config_file, buffer, sizeof(config_file) - strlen(config_file) - 1);
197 		config_file[sizeof(config_file) - 1] = '\x0';
198 	}
199 
200 	/* read the config file */
201 	result = read_config_file(config_file);
202 	/* exit if there are errors... */
203 	if (result == ERROR) {
204 		logit(LOG_ERR, "Config file '%s' contained errors, aborting...", config_file);
205 		return STATE_CRITICAL;
206 	}
207 
208 	if (!nasty_metachars)
209 		nasty_metachars = strdup(NASTY_METACHARS);
210 
211 	/* initialize macros */
212 	for (x = 0; x < MAX_COMMAND_ARGUMENTS; x++)
213 		macro_argv[x] = NULL;
214 
215 	init_ssl();
216 
217 	/* if we're running under inetd... */
218 	if (use_inetd == TRUE)
219 		run_inetd();
220 
221 	else if (use_src == TRUE || no_forking == TRUE)
222 		run_src();
223 
224 	else
225 		run_daemon();
226 
227 #ifdef HAVE_SSL
228 	if (use_ssl == TRUE)
229 		SSL_CTX_free(ctx);
230 #endif
231 
232 	/* We are now running in daemon mode, or the connection handed over by inetd has
233 	   been completed, so the parent process exits */
234 	return STATE_OK;
235 }
236 
init(void)237 int init(void)
238 {
239 	char     *env_string = NULL;
240 	int       result = OK;
241 
242 	/* set some environment variables */
243 	asprintf(&env_string, "NRPE_MULTILINESUPPORT=1");
244 	putenv(env_string);
245 	asprintf(&env_string, "NRPE_PROGRAMVERSION=%s", PROGRAM_VERSION);
246 	putenv(env_string);
247 
248 	/* open a connection to the syslog facility */
249 	/* facility name may be overridden later */
250 	get_log_facility(NRPE_LOG_FACILITY);
251 	openlog("nrpe", LOG_PID, log_facility);
252 
253 	/* generate the CRC 32 table */
254 	generate_crc32_table();
255 
256 	return result;
257 }
258 
init_ssl(void)259 void init_ssl(void)
260 {
261 #ifdef HAVE_SSL
262 	DH            *dh;
263 	char          seedfile[FILENAME_MAX];
264 	char          errstr[120] = { "" };
265 	int           i, c, x, vrfy;
266 	unsigned long ssl_opts = SSL_OP_ALL | SSL_OP_SINGLE_DH_USE;
267 
268 	if (use_ssl == FALSE) {
269 		if (debug == TRUE)
270 			logit(LOG_INFO, "INFO: SSL/TLS NOT initialized. Network encryption DISABLED.");
271 		return;
272 	}
273 
274 #ifndef USE_SSL_DH
275 	ssl_opts = SSL_OP_ALL;
276 	sslprm.allowDH = 0;
277 #endif
278 
279 	if (sslprm.log_opts & SSL_LogStartup)
280 		log_ssl_startup();
281 
282 	/* initialize SSL */
283 	SSL_load_error_strings();
284 	SSL_library_init();
285 	ENGINE_load_builtin_engines();
286 	RAND_set_rand_engine(NULL);
287  	ENGINE_register_all_complete();
288 
289 	meth = SSLv23_server_method();
290 
291 	/* use week random seed if necessary */
292 	if (allow_weak_random_seed && (RAND_status() == 0)) {
293 		if (RAND_file_name(seedfile, sizeof(seedfile) - 1))
294 			if (RAND_load_file(seedfile, -1))
295 				RAND_write_file(seedfile);
296 
297 		if (RAND_status() == 0) {
298 			logit(LOG_ERR,
299 				   "Warning: SSL/TLS uses a weak random seed which is highly discouraged");
300 			srand(time(NULL));
301 			for (i = 0; i < 500 && RAND_status() == 0; i++) {
302 				for (c = 0; c < sizeof(seedfile); c += sizeof(int)) {
303 					*((int *)(seedfile + c)) = rand();
304 				}
305 				RAND_seed(seedfile, sizeof(seedfile));
306 			}
307 		}
308 	}
309 
310 #if OPENSSL_VERSION_NUMBER >= 0x10100000
311 
312 	meth = TLS_method();
313 
314 #else		/* OPENSSL_VERSION_NUMBER >= 0x10100000 */
315 
316 # ifndef OPENSSL_NO_SSL2
317 	if (sslprm.ssl_proto_ver == SSLv2)
318 		meth = SSLv2_server_method();
319 # endif
320 # ifndef OPENSSL_NO_SSL3
321 	if (sslprm.ssl_proto_ver == SSLv3)
322 		meth = SSLv3_server_method();
323 # endif
324 	if (sslprm.ssl_proto_ver == TLSv1)
325 		meth = TLSv1_server_method();
326 # ifdef SSL_TXT_TLSV1_1
327 	if (sslprm.ssl_proto_ver == TLSv1_1)
328 		meth = TLSv1_1_server_method();
329 #  ifdef SSL_TXT_TLSV1_2
330 	if (sslprm.ssl_proto_ver == TLSv1_2)
331 		meth = TLSv1_2_server_method();
332 #  endif	/* ifdef SSL_TXT_TLSV1_2 */
333 # endif		/* SSL_TXT_TLSV1_1 */
334 
335 #endif		/* OPENSSL_VERSION_NUMBER >= 0x10100000 */
336 
337 	ctx = SSL_CTX_new(meth);
338 	if (ctx == NULL) {
339 		while ((x = ERR_get_error()) != 0) {
340 			ERR_error_string(x, errstr);
341 			logit(LOG_ERR, "Error: could not create SSL context : %s", errstr);
342 		}
343 		SSL_CTX_free(ctx);
344 		exit(STATE_CRITICAL);
345 	}
346 
347 #if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER)
348 
349 	SSL_CTX_set_max_proto_version(ctx, 0);
350 
351 	switch(sslprm.ssl_proto_ver) {
352 
353 		case TLSv1_2:
354 			SSL_CTX_set_max_proto_version(ctx, TLS1_2_VERSION);
355 		case TLSv1_2_plus:
356 			SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION);
357 			break;
358 
359 		case TLSv1_1:
360 			SSL_CTX_set_max_proto_version(ctx, TLS1_1_VERSION);
361 		case TLSv1_1_plus:
362 			SSL_CTX_set_min_proto_version(ctx, TLS1_1_VERSION);
363 			break;
364 
365 		case TLSv1:
366 			SSL_CTX_set_max_proto_version(ctx, TLS1_VERSION);
367 		case TLSv1_plus:
368 			SSL_CTX_set_min_proto_version(ctx, TLS1_VERSION);
369 			break;
370 
371 		case SSLv3:
372 			SSL_CTX_set_max_proto_version(ctx, SSL3_VERSION);
373 		case SSLv3_plus:
374 			SSL_CTX_set_min_proto_version(ctx, SSL3_VERSION);
375 			break;
376 	}
377 
378 #else		/* OPENSSL_VERSION_NUMBER >= 0x10100000 */
379 
380 	switch(sslprm.ssl_proto_ver) {
381 		case SSLv2:
382 		case SSLv2_plus:
383 			break;
384 		case TLSv1_2:
385 		case TLSv1_2_plus:
386 #ifdef SSL_OP_NO_TLSv1_1
387 			ssl_opts |= SSL_OP_NO_TLSv1_1;
388 #endif
389 		case TLSv1_1:
390 		case TLSv1_1_plus:
391 			ssl_opts |= SSL_OP_NO_TLSv1;
392 		case TLSv1:
393 		case TLSv1_plus:
394 			ssl_opts |= SSL_OP_NO_SSLv3;
395 		case SSLv3:
396 		case SSLv3_plus:
397 			ssl_opts |= SSL_OP_NO_SSLv2;
398 			break;
399 	}
400 
401 #endif		/* OPENSSL_VERSION_NUMBER >= 0x10100000 */
402 
403 	SSL_CTX_set_options(ctx, ssl_opts);
404 
405 	if (sslprm.cert_file != NULL) {
406 		if (!SSL_CTX_use_certificate_file(ctx, sslprm.cert_file, SSL_FILETYPE_PEM)) {
407 			SSL_CTX_free(ctx);
408 			while ((x = ERR_get_error()) != 0) {
409 				ERR_error_string(x, errstr);
410 				logit(LOG_ERR, "Error: could not use certificate file %s : %s",
411 					   sslprm.cert_file, errstr);
412 			}
413 			exit(STATE_CRITICAL);
414 		}
415 		if (!SSL_CTX_use_PrivateKey_file(ctx, sslprm.privatekey_file, SSL_FILETYPE_PEM)) {
416 			while ((x = ERR_get_error()) != 0) {
417 				ERR_error_string(x, errstr);
418 				logit(LOG_ERR, "Error: could not use private key file '%s' : %s",
419 					 sslprm.privatekey_file, errstr);
420 			}
421 			SSL_CTX_free(ctx);
422 			exit(STATE_CRITICAL);
423 		}
424 	}
425 
426 	if (sslprm.client_certs != 0) {
427 		vrfy = SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE;
428 		if ((sslprm.client_certs & Require_Cert) != 0)
429 			vrfy |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
430 		SSL_CTX_set_verify(ctx, vrfy, verify_callback);
431 		if (!SSL_CTX_load_verify_locations(ctx, sslprm.cacert_file, NULL)) {
432 			while ((x = ERR_get_error_line_data(NULL, NULL, NULL, NULL)) != 0) {
433 				logit(LOG_ERR, "Error: could not use CA certificate file '%s': %s\n",
434 					   sslprm.cacert_file, ERR_reason_error_string(x));
435 			}
436 			SSL_CTX_free(ctx);
437 			logit(LOG_ERR, "Error: could not use CA certificate '%s'", sslprm.cacert_file);
438 			exit(STATE_CRITICAL);
439 		}
440 	}
441 
442 	if (!sslprm.allowDH) {
443 		if (strlen(sslprm.cipher_list) < sizeof(sslprm.cipher_list) - 6)
444 			strcat(sslprm.cipher_list, ":!ADH");
445 	} else {
446 		/* use anonymous DH ciphers */
447 		if (sslprm.allowDH == 2) {
448 #if OPENSSL_VERSION_NUMBER >= 0x10100000
449 			strncpy(sslprm.cipher_list, "ADH@SECLEVEL=0", MAX_FILENAME_LENGTH - 1);
450 #else
451 			strncpy(sslprm.cipher_list, "ADH", MAX_FILENAME_LENGTH - 1);
452 #endif
453 		}
454 
455 #ifdef USE_SSL_DH
456 		dh = get_dh2048();
457 		SSL_CTX_set_tmp_dh(ctx, dh);
458 		DH_free(dh);
459 #endif
460 	}
461 
462 	if (SSL_CTX_set_cipher_list(ctx, sslprm.cipher_list) == 0) {
463 		SSL_CTX_free(ctx);
464 		logit(LOG_ERR, "Error: Could not set SSL/TLS cipher list");
465 		exit(STATE_CRITICAL);
466 	}
467 
468 	if (debug == TRUE)
469 		logit(LOG_INFO, "INFO: SSL/TLS initialized. All network traffic will be encrypted.");
470 #endif
471 }
472 
log_ssl_startup(void)473 void log_ssl_startup(void)
474 {
475 #ifdef HAVE_SSL
476 	char     *vers;
477 
478 	logit(LOG_INFO, "SSL Certificate File: %s", sslprm.cert_file ? sslprm.cert_file : "None");
479 	logit(LOG_INFO, "SSL Private Key File: %s",
480 		   sslprm.privatekey_file ? sslprm.privatekey_file : "None");
481 	logit(LOG_INFO, "SSL CA Certificate File: %s",
482 		   sslprm.cacert_file ? sslprm.cacert_file : "None");
483 	logit(LOG_INFO, "SSL Cipher List: %s", sslprm.cipher_list);
484 	logit(LOG_INFO, "SSL Allow ADH: %d", sslprm.allowDH == 0);
485 	logit(LOG_INFO, "SSL Client Certs: %s",
486 		   sslprm.client_certs == 0 ? "Don't Ask" : (sslprm.client_certs ==
487 													 1 ? "Accept" : "Require"));
488 	logit(LOG_INFO, "SSL Log Options: 0x%02x", sslprm.log_opts);
489 	switch (sslprm.ssl_proto_ver) {
490 	case SSLv2:
491 		vers = "SSLv2";
492 		break;
493 	case SSLv2_plus:
494 		vers = "SSLv2 And Above";
495 		break;
496 	case SSLv3:
497 		vers = "SSLv3";
498 		break;
499 	case SSLv3_plus:
500 		vers = "SSLv3 And Above";
501 		break;
502 	case TLSv1:
503 		vers = "TLSv1";
504 		break;
505 	case TLSv1_plus:
506 		vers = "TLSv1 And Above";
507 		break;
508 	case TLSv1_1:
509 		vers = "TLSv1_1";
510 		break;
511 	case TLSv1_1_plus:
512 		vers = "TLSv1_1 And Above";
513 		break;
514 	case TLSv1_2:
515 		vers = "TLSv1_2";
516 		break;
517 	case TLSv1_2_plus:
518 		vers = "TLSv1_2 And Above";
519 		break;
520 	default:
521 		vers = "INVALID VALUE!";
522 		break;
523 	}
524 	logit(LOG_INFO, "SSL Version: %s", vers);
525 #endif
526 }
527 
usage(int result)528 void usage(int result)
529 {
530 	if (result != OK) {
531 		printf("\n");
532 		printf("Incorrect command line arguments supplied\n");
533 		printf("\n");
534 	}
535 	printf("NRPE - Nagios Remote Plugin Executor\n");
536 	printf("Version: %s\n", PROGRAM_VERSION);
537 	printf("\n");
538 	if (result != OK || show_help == TRUE) {
539 		printf("Copyright (c) 2009-2017 Nagios Enterprises\n");
540 		printf("              1999-2008 Ethan Galstad (nagios@nagios.org)\n");
541 		printf("\n");
542 		printf("Last Modified: %s\n", MODIFICATION_DATE);
543 		printf("\n");
544 		printf("License: GPL v2 with exemptions (-l for more info)\n");
545 		printf("\n");
546 #ifdef HAVE_SSL
547 		printf("SSL/TLS Available, OpenSSL 0.9.6 or higher required\n");
548 		printf("\n");
549 #endif
550 #ifdef HAVE_LIBWRAP
551 		printf("TCP Wrappers Available\n");
552 		printf("\n");
553 #endif
554 #ifdef ENABLE_COMMAND_ARGUMENTS
555 		printf("***************************************************************\n");
556 		printf("** POSSIBLE SECURITY RISK - COMMAND ARGUMENTS ARE SUPPORTED! **\n");
557 		printf("**      Read the NRPE SECURITY file for more information     **\n");
558 		printf("***************************************************************\n");
559 		printf("\n");
560 #endif
561 #ifndef HAVE_LIBWRAP
562 		printf("***************************************************************\n");
563 		printf("** POSSIBLE SECURITY RISK - TCP WRAPPERS ARE NOT AVAILABLE!  **\n");
564 		printf("**      Read the NRPE SECURITY file for more information     **\n");
565 		printf("***************************************************************\n");
566 		printf("\n");
567 #endif
568 		printf("Usage: nrpe [-V] [-n] -c <config_file> [-4|-6] <mode>\n");
569 		printf("\n");
570 		printf("Options:\n");
571 		printf(" -V, --version         Print version info and quit\n");
572 		printf(" -n, --no-ssl          Do not use SSL\n");
573 		printf(" -c, --config=FILE     Name of config file to use\n");
574 		printf(" -4, --ipv4            Use ipv4 only\n");
575 		printf(" -6, --ipv6            Use ipv6 only\n");
576 		printf(" <mode> (One of the following operating modes)\n");
577 		printf("   -i, --inetd         Run as a service under inetd or xinetd\n");
578 		printf("   -d, --daemon        Run as a standalone daemon\n");
579 		printf("   -s, --src           Run as a subsystem under AIX\n");
580 		printf("   -f, --no-forking    Don't fork() (for systemd, launchd, etc.)\n");
581 		printf("\n");
582 		printf("Notes:\n");
583 		printf("This program is designed to process requests from the check_nrpe\n");
584 		printf("plugin on the host(s) running Nagios.  It can run as a service\n");
585 		printf("under inetd or xinetd (read the docs for info on this), or as a\n");
586 		printf("standalone daemon. Once a request is received from an authorized\n");
587 		printf("host, NRPE will execute the command/plugin (as defined in the\n");
588 		printf("config file) and return the plugin output and return code to the\n");
589 		printf("check_nrpe plugin.\n");
590 		printf("\n");
591 	}
592 
593 	if (show_license == TRUE)
594 		display_license();
595 
596 	exit(STATE_UNKNOWN);
597 }
598 
run_inetd(void)599 void run_inetd(void)
600 {
601 	check_privileges();			/* make sure we're not root */
602 	close(2);					/* redirect STDERR to /dev/null */
603 	open("/dev/null", O_WRONLY);
604 	handle_connection(0);		/* handle the connection */
605 }
606 
run_src(void)607 void run_src(void)
608 {
609 	/* if we're running under SRC we don't fork but does drop-privileges */
610 
611 	set_stdio_sigs();
612 
613 	do {
614 		/* reset flags */
615 		sigrestart = FALSE;
616 		sigshutdown = FALSE;
617 
618 		wait_for_connections();	/* wait for connections */
619 		cleanup();
620 	} while (sigrestart == TRUE && sigshutdown == FALSE);
621 }
622 
623 /* daemonize and start listening for requests... */
run_daemon(void)624 void run_daemon(void)
625 {
626 	pid_t     pid;
627 
628 	pid = fork();
629 
630 	if (pid != 0) {
631 		if (pid == -1) {
632 			logit(LOG_ERR, "fork() failed with error %d, bailing out...", errno);
633 			exit(STATE_CRITICAL);
634 		}
635 
636 		return;
637 	}
638 
639 	setsid();					/* we're a daemon - set up a new process group */
640 	set_stdio_sigs();
641 
642 	do {
643 		/* reset flags */
644 		sigrestart = FALSE;
645 		sigshutdown = FALSE;
646 
647 		wait_for_connections();	/* wait for connections */
648 		cleanup();
649 	} while (sigrestart == TRUE && sigshutdown == FALSE);
650 }
651 
set_stdio_sigs(void)652 void set_stdio_sigs(void)
653 {
654 #ifdef HAVE_SIGACTION
655 	struct sigaction sig_action;
656 #endif
657 
658 	if (chdir("/") == -1) {
659 		printf("ERROR: chdir(): %s, bailing out...\n", strerror(errno));
660 		exit(STATE_CRITICAL);
661 	}
662 
663 	close(0);					/* close standard file descriptors */
664 	close(1);
665 	close(2);
666 	open("/dev/null", O_RDONLY);	/* redirect standard descriptors to /dev/null */
667 	open("/dev/null", O_WRONLY);
668 	open("/dev/null", O_WRONLY);
669 
670 	/* handle signals */
671 #ifdef HAVE_SIGACTION
672 	sig_action.sa_sigaction = NULL;
673 	sig_action.sa_handler = sighandler;
674 	sigfillset(&sig_action.sa_mask);
675 	sig_action.sa_flags = SA_NODEFER | SA_RESTART;
676 	sigaction(SIGQUIT, &sig_action, NULL);
677 	sigaction(SIGTERM, &sig_action, NULL);
678 	sigaction(SIGHUP, &sig_action, NULL);
679 #else	 /* HAVE_SIGACTION */
680 	signal(SIGQUIT, sighandler);
681 	signal(SIGTERM, sighandler);
682 	signal(SIGHUP, sighandler);
683 #endif	 /* HAVE_SIGACTION */
684 
685 	logit(LOG_NOTICE, "Starting up daemon");	/* log info */
686 	if (write_pid_file() == ERROR)	/* write pid file */
687 		exit(STATE_CRITICAL);
688 
689 	clean_environ(keep_env_vars, nrpe_user);
690 
691 	/* drop and then check privileges */
692 	drop_privileges(nrpe_user, nrpe_group, 0);
693 	check_privileges();
694 }
695 
cleanup(void)696 void cleanup(void)
697 {
698 	int       result;
699 
700 	free_memory();				/* free all memory we allocated */
701 
702 	if (sigrestart == TRUE && sigshutdown == FALSE) {
703 		close_log_file();
704 		result = read_config_file(config_file);	/* read the config file */
705 
706 		if (result == ERROR) {	/* exit if there are errors... */
707 			logit(LOG_ERR, "Config file '%s' contained errors, bailing out...", config_file);
708 			exit(STATE_CRITICAL);
709 		}
710 		return;
711 	}
712 
713 	remove_pid_file();			/* remove pid file */
714 	logit(LOG_NOTICE, "Daemon shutdown\n");
715 
716 	close_log_file();			/* close the log file */
717 }
718 
719 #ifdef HAVE_SSL
verify_callback(int preverify_ok,X509_STORE_CTX * ctx)720 int verify_callback(int preverify_ok, X509_STORE_CTX * ctx)
721 {
722 	char      name[256], issuer[256];
723 	X509     *err_cert;
724 	int       err;
725 	SSL      *ssl;
726 
727 	if (preverify_ok || ((sslprm.log_opts & SSL_LogCertDetails) == 0))
728 		return preverify_ok;
729 
730 	err_cert = X509_STORE_CTX_get_current_cert(ctx);
731 	err = X509_STORE_CTX_get_error(ctx);
732 
733 	/* Get the pointer to the SSL of the current connection */
734 	ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
735 
736 	X509_NAME_oneline(X509_get_subject_name(err_cert), name, 256);
737 	X509_NAME_oneline(X509_get_issuer_name(err_cert), issuer, 256);
738 
739 	if (!preverify_ok && (sslprm.log_opts & SSL_LogCertDetails)) {
740 		logit(LOG_ERR, "SSL Client has an invalid certificate: %s (issuer=%s) err=%d:%s",
741 			   name, issuer, err, X509_verify_cert_error_string(err));
742 	}
743 
744 	return preverify_ok;
745 }
746 #endif
747 
748 /* read in the configuration file */
read_config_file(char * filename)749 int read_config_file(char *filename)
750 {
751 	struct stat st;
752 	FILE     *fp;
753 	char      config_file[MAX_FILENAME_LENGTH];
754 	char      input_buffer[MAX_INPUT_BUFFER];
755 	char     *input_line;
756 	char     *temp_buffer;
757 	char     *varname;
758 	char     *varvalue;
759 	int       line = 0;
760 	int       len = 0;
761 	int       x = 0;
762 
763 	fp = fopen(filename, "r");	/* open the config file for reading */
764 
765 	/* exit if we couldn't open the config file */
766 	if (fp == NULL) {
767 		logit(LOG_ERR, "Unable to open config file '%s' for reading\n", filename);
768 		return ERROR;
769 	}
770 
771 	while (fgets(input_buffer, MAX_INPUT_BUFFER - 1, fp)) {
772 		line++;
773 		input_line = input_buffer;
774 
775 		/* skip leading whitespace */
776 		while (isspace(*input_line))
777 			++input_line;
778 
779 		/* trim trailing whitespace */
780 		len = strlen(input_line);
781 		for (x = len - 1; x >= 0; x--) {
782 			if (isspace(input_line[x]))
783 				input_line[x] = '\x0';
784 			else
785 				break;
786 		}
787 
788 		/* skip comments and blank lines */
789 		if (input_line[0] == '#' || input_line[0] == '\x0' || input_line[0] == '\n')
790 			continue;
791 
792 		/* get the variable name */
793 		varname = strtok(input_line, "=");
794 		if (varname == NULL) {
795 			logit(LOG_ERR, "No variable name specified in config file '%s' - Line %d\n",
796 				   filename, line);
797 			return ERROR;
798 		}
799 
800 		/* get the variable value */
801 		varvalue = strtok(NULL, "\n");
802 		if (varvalue == NULL) {
803 			logit(LOG_ERR, "No variable value specified in config file '%s' - Line %d\n",
804 				   filename, line);
805 			return ERROR;
806 
807 		} else if (!strcmp(varname, "include_dir")) {
808 			/* allow users to specify directories to recurse into for config files */
809 
810 			strncpy(config_file, varvalue, sizeof(config_file) - 1);
811 			config_file[sizeof(config_file) - 1] = '\x0';
812 
813 			/* strip trailing / if necessary */
814 			if (config_file[strlen(config_file) - 1] == '/')
815 				config_file[strlen(config_file) - 1] = '\x0';
816 
817 			/* process the config directory... */
818 			if (read_config_dir(config_file) == ERROR)
819 				logit(LOG_ERR, "Continuing with errors...");
820 
821 		} else if (!strcmp(varname, "include") || !strcmp(varname, "include_file")) {
822 			/* allow users to specify individual config files to include */
823 
824 			/* process the config file... */
825 			if (read_config_file(varvalue) == ERROR)
826 				logit(LOG_ERR, "Continuing with errors...");
827 
828 		} else if (!strcmp(varname, "max_commands")) {
829 
830 			max_commands = atoi(varvalue);
831 			if (max_commands < 0) {
832 				logit(LOG_WARNING, "max_commands set too low, setting to 0\n");
833 				max_commands = 0;
834 			}
835 
836 		} else if (!strcmp(varname, "server_port")) {
837 			server_port = atoi(varvalue);
838 			if (server_port < 1024) {
839 				logit(LOG_ERR,
840 					   "Invalid port number specified in config file '%s' - Line %d\n",
841 					   filename, line);
842 				return ERROR;
843 			}
844 
845 		} else if (!strcmp(varname, "command_prefix"))
846 			command_prefix = strdup(varvalue);
847 
848 		else if (!strcmp(varname, "server_address")) {
849 			strncpy(server_address, varvalue, sizeof(server_address) - 1);
850 			server_address[sizeof(server_address) - 1] = '\0';
851 
852 		} else if (!strcmp(varname, "allowed_hosts")) {
853 			allowed_hosts = strdup(varvalue);
854 			parse_allowed_hosts(allowed_hosts);
855 			if (debug == TRUE)
856 				show_acl_lists();
857 
858 		} else if (strstr(input_line, "command[")) {
859 			temp_buffer = strtok(varname, "[");
860 			temp_buffer = strtok(NULL, "]");
861 			if (temp_buffer == NULL) {
862 				logit(LOG_ERR, "Invalid command specified in config file '%s' - Line %d\n",
863 					   filename, line);
864 				return ERROR;
865 			}
866 			add_command(temp_buffer, varvalue);
867 
868 		} else if (strstr(input_buffer, "debug")) {
869 			debug = atoi(varvalue);
870 			if (debug > 0)
871 				debug = TRUE;
872 			else
873 				debug = FALSE;
874 
875 		} else if (!strcmp(varname, "nrpe_user"))
876 			nrpe_user = strdup(varvalue);
877 
878 		else if (!strcmp(varname, "nrpe_group"))
879 			nrpe_group = strdup(varvalue);
880 
881 		else if (!strcmp(varname, "dont_blame_nrpe"))
882 			allow_arguments = (atoi(varvalue) == 1) ? TRUE : FALSE;
883 
884 		else if (!strcmp(varname, "allow_bash_command_substitution"))
885 			allow_bash_cmd_subst = (atoi(varvalue) == 1) ? TRUE : FALSE;
886 
887 		else if (!strcmp(varname, "command_timeout")) {
888 			command_timeout = atoi(varvalue);
889 			if (command_timeout < 1) {
890 				logit(LOG_ERR,
891 					   "Invalid command_timeout specified in config file '%s' - Line %d\n",
892 					   filename, line);
893 				return ERROR;
894 			}
895 		} else if (!strcmp(varname, "connection_timeout")) {
896 			connection_timeout = atoi(varvalue);
897 			if (connection_timeout < 1) {
898 				logit(LOG_ERR,
899 					   "Invalid connection_timeout specified in config file '%s' - Line %d\n",
900 					   filename, line);
901 				return ERROR;
902 			}
903 
904 		} else if (!strcmp(varname, "ssl_shutdown_timeout")) {
905 			ssl_shutdown_timeout = atoi(varvalue);
906 			if (ssl_shutdown_timeout < 1) {
907 				logit(LOG_ERR,
908 					   "Invalid ssl_shutdown_timeout specified in config file '%s' - Line %d\n",
909 					   filename, line);
910 				return ERROR;
911 			}
912 
913 		} else if (!strcmp(varname, "allow_weak_random_seed"))
914 			allow_weak_random_seed = (atoi(varvalue) == 1) ? TRUE : FALSE;
915 
916 		else if (!strcmp(varname, "pid_file"))
917 			pid_file = strdup(varvalue);
918 
919 		else if (!strcmp(varname, "listen_queue_size")) {
920 			listen_queue_size = atoi(varvalue);
921 			if (listen_queue_size == 0) {
922 				logit(LOG_ERR,
923 					   "Invalid listen queue size specified in config file '%s' - Line %d\n",
924 					   filename, line);
925 				return ERROR;
926 			}
927 
928 		} else if (!strcmp(varname, "ssl_version")) {
929 			if (!strcmp(varvalue, "TLSv1.2"))
930 				sslprm.ssl_proto_ver = TLSv1_2;
931 			else if (!strcmp(varvalue, "TLSv1.2+"))
932 				sslprm.ssl_proto_ver = TLSv1_2_plus;
933 			else if (!strcmp(varvalue, "TLSv1.1"))
934 				sslprm.ssl_proto_ver = TLSv1_1;
935 			else if (!strcmp(varvalue, "TLSv1.1+"))
936 				sslprm.ssl_proto_ver = TLSv1_1_plus;
937 			else if (!strcmp(varvalue, "TLSv1"))
938 				sslprm.ssl_proto_ver = TLSv1;
939 			else if (!strcmp(varvalue, "TLSv1+"))
940 				sslprm.ssl_proto_ver = TLSv1_plus;
941 			else if (!strcmp(varvalue, "SSLv3"))
942 				sslprm.ssl_proto_ver = SSLv3;
943 			else if (!strcmp(varvalue, "SSLv3+"))
944 				sslprm.ssl_proto_ver = SSLv3_plus;
945 #if OPENSSL_VERSION_NUMBER < 0x10100000
946 			else if (!strcmp(varvalue, "SSLv2"))
947 				sslprm.ssl_proto_ver = SSLv2;
948 			else if (!strcmp(varvalue, "SSLv2+"))
949 				sslprm.ssl_proto_ver = SSLv2_plus;
950 #endif /* OPENSSL_VERSION_NUMBER < 0x10100000 */
951 			else {
952 				logit(LOG_ERR, "Invalid ssl version specified in config file '%s' - Line %d",
953 					   filename, line);
954 				return ERROR;
955 			}
956 
957 		} else if (!strcmp(varname, "ssl_use_adh")) {
958 			sslprm.allowDH = atoi(varvalue);
959 			if (sslprm.allowDH < 0 || sslprm.allowDH > 2) {
960 				logit(LOG_ERR,
961 					   "Invalid use adh value specified in config file '%s' - Line %d",
962 					   filename, line);
963 				return ERROR;
964 			}
965 
966 		} else if (!strcmp(varname, "ssl_logging"))
967 			sslprm.log_opts = strtoul(varvalue, NULL, 0);
968 
969 		else if (!strcmp(varname, "ssl_cipher_list")) {
970 			strncpy(sslprm.cipher_list, varvalue, sizeof(sslprm.cipher_list) - 1);
971 			sslprm.cipher_list[sizeof(sslprm.cipher_list) - 1] = '\0';
972 
973 		} else if (!strcmp(varname, "ssl_cert_file"))
974 			sslprm.cert_file = strdup(varvalue);
975 
976 		else if (!strcmp(varname, "ssl_cacert_file"))
977 			sslprm.cacert_file = strdup(varvalue);
978 
979 		else if (!strcmp(varname, "ssl_privatekey_file"))
980 			sslprm.privatekey_file = strdup(varvalue);
981 
982 		else if (!strcmp(varname, "ssl_client_certs")) {
983 			sslprm.client_certs = atoi(varvalue);
984 			if ((int)sslprm.client_certs < 0 || sslprm.client_certs > Require_Cert) {
985 				logit(LOG_ERR,
986 					   "Invalid client certs value specified in config file '%s' - Line %d",
987 					   filename, line);
988 				return ERROR;
989 			}
990 			/* if requiring or logging client certs, make sure "Ask" is turned on */
991 			if (sslprm.client_certs & Require_Cert)
992 				sslprm.client_certs |= Ask_For_Cert;
993 
994 		} else if (!strcmp(varname, "log_facility")) {
995 			if ((get_log_facility(varvalue)) == OK) {
996 				/* re-open log using new facility */
997 				closelog();
998 				openlog("nrpe", LOG_PID, log_facility);
999 			} else
1000 				logit(LOG_WARNING,
1001 					   "Invalid log_facility specified in config file '%s' - Line %d\n",
1002 					   filename, line);
1003 
1004 		} else if (!strcmp(varname, "keep_env_vars"))
1005 			keep_env_vars = strdup(varvalue);
1006 
1007 		else if (!strcmp(varname, "nasty_metachars"))
1008 			nasty_metachars = strdup(varvalue);
1009 
1010 		else if (!strcmp(varname, "log_file")) {
1011 			log_file = strdup(varvalue);
1012 			open_log_file();
1013 
1014 		} else {
1015 			logit(LOG_WARNING, "Unknown option specified in config file '%s' - Line %d\n",
1016 				   filename, line);
1017 			continue;
1018 		}
1019 	}
1020 
1021 	fclose(fp);					/* close the config file */
1022 	return OK;
1023 }
1024 
1025 /* process all config files in a specific config directory (with directory recursion) */
read_config_dir(char * dirname)1026 int read_config_dir(char *dirname)
1027 {
1028 	struct dirent *dirfile;
1029 #ifdef HAVE_SCANDIR
1030 	struct dirent **dirfiles;
1031 	int       x, i, n;
1032 #else
1033 	DIR      *dirp;
1034 	int       x;
1035 #endif
1036 	struct stat buf;
1037 	char      config_file[MAX_FILENAME_LENGTH];
1038 	int       result = OK;
1039 
1040 #ifdef HAVE_SCANDIR
1041 	/* read and sort the directory contents */
1042 	n = scandir(dirname, &dirfiles, 0, alphasort);
1043 	if (n < 0) {
1044 		logit(LOG_ERR, "Could not open config directory '%s' for reading.\n", dirname);
1045 		return ERROR;
1046 	}
1047 
1048 	for (i = 0; i < n; i++) {
1049 		dirfile = dirfiles[i];
1050 #else
1051 	/* open the directory for reading */
1052 	dirp = opendir(dirname);
1053 	if (dirp == NULL) {
1054 		logit(LOG_ERR, "Could not open config directory '%s' for reading.\n", dirname);
1055 		return ERROR;
1056 	}
1057 
1058 	while ((dirfile = readdir(dirp)) != NULL) {
1059 #endif
1060 
1061 		/* process all files in the directory... */
1062 
1063 		/* create the full path to the config file or subdirectory */
1064 		snprintf(config_file, sizeof(config_file) - 1, "%s/%s", dirname, dirfile->d_name);
1065 		config_file[sizeof(config_file) - 1] = '\x0';
1066 		stat(config_file, &buf);
1067 
1068 		/* process this if it's a config file... */
1069 		x = strlen(dirfile->d_name);
1070 		if (x > 4 && !strcmp(dirfile->d_name + (x - 4), ".cfg")) {
1071 
1072 			/* only process normal files */
1073 			if (!S_ISREG(buf.st_mode))
1074 				continue;
1075 
1076 			/* process the config file */
1077 			result = read_config_file(config_file);
1078 
1079 			/* break out if we encountered an error */
1080 			if (result == ERROR)
1081 				break;
1082 		}
1083 
1084 		/* recurse into subdirectories... */
1085 		if (S_ISDIR(buf.st_mode)) {
1086 
1087 			/* ignore current, parent and hidden directory entries */
1088 			if (dirfile->d_name[0] == '.')
1089 				continue;
1090 
1091 			/* process the config directory */
1092 			result = read_config_dir(config_file);
1093 
1094 			/* break out if we encountered an error */
1095 			if (result == ERROR)
1096 				break;
1097 
1098 		}
1099 	}
1100 
1101 #ifdef HAVE_SCANDIR
1102 	for (i = 0; i < n; i++)
1103 		free(dirfiles[i]);
1104 	free(dirfiles);
1105 #else
1106 	closedir(dirp);
1107 #endif
1108 
1109 	return result;
1110 }
1111 
1112 /* determines facility to use with syslog */
1113 int get_log_facility(char *varvalue)
1114 {
1115 	if (!strcmp(varvalue, "kern"))
1116 		log_facility = LOG_KERN;
1117 	else if (!strcmp(varvalue, "user"))
1118 		log_facility = LOG_USER;
1119 	else if (!strcmp(varvalue, "mail"))
1120 		log_facility = LOG_MAIL;
1121 	else if (!strcmp(varvalue, "daemon"))
1122 		log_facility = LOG_DAEMON;
1123 	else if (!strcmp(varvalue, "auth"))
1124 		log_facility = LOG_AUTH;
1125 	else if (!strcmp(varvalue, "syslog"))
1126 		log_facility = LOG_SYSLOG;
1127 	else if (!strcmp(varvalue, "lrp"))
1128 		log_facility = LOG_LPR;
1129 	else if (!strcmp(varvalue, "news"))
1130 		log_facility = LOG_NEWS;
1131 	else if (!strcmp(varvalue, "uucp"))
1132 		log_facility = LOG_UUCP;
1133 	else if (!strcmp(varvalue, "cron"))
1134 		log_facility = LOG_CRON;
1135 	else if (!strcmp(varvalue, "authpriv"))
1136 		log_facility = LOG_AUTHPRIV;
1137 	else if (!strcmp(varvalue, "ftp"))
1138 		log_facility = LOG_FTP;
1139 	else if (!strcmp(varvalue, "local0"))
1140 		log_facility = LOG_LOCAL0;
1141 	else if (!strcmp(varvalue, "local1"))
1142 		log_facility = LOG_LOCAL1;
1143 	else if (!strcmp(varvalue, "local2"))
1144 		log_facility = LOG_LOCAL2;
1145 	else if (!strcmp(varvalue, "local3"))
1146 		log_facility = LOG_LOCAL3;
1147 	else if (!strcmp(varvalue, "local4"))
1148 		log_facility = LOG_LOCAL4;
1149 	else if (!strcmp(varvalue, "local5"))
1150 		log_facility = LOG_LOCAL5;
1151 	else if (!strcmp(varvalue, "local6"))
1152 		log_facility = LOG_LOCAL6;
1153 	else if (!strcmp(varvalue, "local7"))
1154 		log_facility = LOG_LOCAL7;
1155 	else {
1156 		log_facility = LOG_DAEMON;
1157 		return ERROR;
1158 	}
1159 
1160 	return OK;
1161 }
1162 
1163 /* adds a new command definition from the config file to the list in memory */
1164 int add_command(char *command_name, char *command_line)
1165 {
1166 	command  *new_command;
1167 
1168 	if (command_name == NULL || command_line == NULL)
1169 		return ERROR;
1170 
1171 	/* allocate memory for the new command */
1172 	new_command = (command *) malloc(sizeof(command));
1173 	if (new_command == NULL)
1174 		return ERROR;
1175 
1176 	new_command->command_name = strdup(command_name);
1177 	if (new_command->command_name == NULL) {
1178 		free(new_command);
1179 		return ERROR;
1180 	}
1181 	new_command->command_line = strdup(command_line);
1182 	if (new_command->command_line == NULL) {
1183 		free(new_command->command_name);
1184 		free(new_command);
1185 		return ERROR;
1186 	}
1187 
1188 	/* add new command to head of list in memory */
1189 	new_command->next = command_list;
1190 	command_list = new_command;
1191 
1192 	if (debug == TRUE)
1193 		logit(LOG_DEBUG, "Added command[%s]=%s\n", command_name, command_line);
1194 
1195 	return OK;
1196 }
1197 
1198 /* given a command name, find the structure in memory */
1199 command  *find_command(char *command_name)
1200 {
1201 	command  *temp_command;
1202 
1203 	for (temp_command = command_list; temp_command != NULL; temp_command = temp_command->next)
1204 		if (!strcmp(command_name, temp_command->command_name))
1205 			return temp_command;
1206 
1207 	return NULL;
1208 }
1209 
1210 /* Start listen on a particular port */
1211 void create_listener(struct addrinfo *ai)
1212 {
1213 	int       ret;
1214 	char      ntop[NI_MAXHOST], strport[NI_MAXSERV];
1215 	int       listen_sock;
1216 	int       flag = 1;
1217 
1218 	if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
1219 		return;
1220 
1221 	if (num_listen_socks >= MAX_LISTEN_SOCKS) {
1222 		logit(LOG_ERR, "Too many listen sockets. Enlarge MAX_LISTEN_SOCKS");
1223 		exit(1);
1224 	}
1225 
1226 	if ((ret = getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, sizeof(ntop),
1227 						   strport, sizeof(strport), NI_NUMERICHOST | NI_NUMERICSERV)) != 0) {
1228 		logit(LOG_ERR, "getnameinfo failed: %.100s", gai_strerror(ret));
1229 		return;
1230 	}
1231 
1232 	/* Create socket for listening. */
1233 	listen_sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
1234 	if (listen_sock < 0) {
1235 		/* kernel may not support ipv6 */
1236 		logit(LOG_ERR, "socket: %.100s", strerror(errno));
1237 		return;
1238 	}
1239 
1240 	/* socket should be non-blocking */
1241 	fcntl(listen_sock, F_SETFL, O_NONBLOCK);
1242 
1243 	/* set the reuse address flag so we don't get errors when restarting */
1244 	if (setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag)) < 0) {
1245 		logit(LOG_ERR, "setsockopt SO_REUSEADDR: %s", strerror(errno));
1246 		return;
1247 	}
1248 #ifdef IPV6_V6ONLY
1249 	/* Only communicate in IPv6 over AF_INET6 sockets. */
1250 	if (ai->ai_family == AF_INET6) {
1251 		if (setsockopt(listen_sock, IPPROTO_IPV6, IPV6_V6ONLY, &flag, sizeof(flag)) == -1) {
1252 			fprintf(stderr, "setsockopt IPV6_V6ONLY: %s", strerror(errno));
1253 		}
1254 	}
1255 #endif
1256 
1257 	/* Bind the socket to the desired port. */
1258 	if (bind(listen_sock, ai->ai_addr, ai->ai_addrlen) < 0) {
1259 		logit(LOG_ERR, "Bind to port %s on %s failed: %.200s.",
1260 			   strport, ntop, strerror(errno));
1261 		close(listen_sock);
1262 		return;
1263 	}
1264 	listen_socks[num_listen_socks] = listen_sock;
1265 	num_listen_socks++;
1266 
1267 	/* Start listening on the port. */
1268 	if (listen(listen_sock, listen_queue_size) < 0) {
1269 		logit(LOG_ERR, "listen on [%s]:%s: %.100s", ntop, strport, strerror(errno));
1270 		exit(1);
1271 	}
1272 
1273 	logit(LOG_INFO, "Server listening on %s port %s.", ntop, strport);
1274 }
1275 
1276 /* Close all listening sockets */
1277 static void close_listen_socks(void)
1278 {
1279 	int       i;
1280 
1281 	for (i = 0; i <= num_listen_socks; i++) {
1282 		close(listen_socks[i]);
1283 		num_listen_socks--;
1284 	}
1285 }
1286 
1287 /* wait for incoming connection requests */
1288 void wait_for_connections(void)
1289 {
1290 #ifdef HAVE_STRUCT_SOCKADDR_STORAGE
1291 	struct sockaddr_storage from;
1292 #else
1293 	struct sockaddr from;
1294 #endif
1295 	socklen_t fromlen;
1296 	fd_set   *fdset = NULL;
1297 	int       maxfd = 0, new_sd = 0, i, rc, retval;
1298 
1299 	setup_wait_conn();
1300 
1301 	/* listen for connection requests - fork() if we get one */
1302 	while (1) {
1303 		/* bail out if necessary */
1304 		if (sigrestart == TRUE || sigshutdown == TRUE)
1305 			break;
1306 
1307 		for (i = 0; i < num_listen_socks; i++) {
1308 			if (listen_socks[i] > maxfd)
1309 				maxfd = listen_socks[i];
1310 		}
1311 
1312 		if (fdset != NULL)
1313 			free(fdset);
1314 		fdset = (fd_set *) calloc(how_many(maxfd + 1, NFDBITS), sizeof(fd_mask));
1315 
1316 		for (i = 0; i < num_listen_socks; i++)
1317 			FD_SET(listen_socks[i], fdset);
1318 
1319 		/* Wait in select until there is a connection. */
1320 		retval = select(maxfd + 1, fdset, NULL, NULL, NULL);
1321 
1322 		/* bail out if necessary */
1323 		if (sigrestart == TRUE || sigshutdown == TRUE)
1324 			break;
1325 
1326 		/* error */
1327 		if (retval < 0)
1328 			continue;
1329 
1330 		for (i = 0; i < num_listen_socks; i++) {
1331 			if (!FD_ISSET(listen_socks[i], fdset))
1332 				continue;
1333 			fromlen = (socklen_t)sizeof(from);
1334 
1335 			/* accept a new connection request */
1336 			new_sd = accept(listen_socks[i], (struct sockaddr *)&from, &fromlen);
1337 
1338 			/* some kind of error occurred... */
1339 			if (new_sd < 0) {
1340 				/* bail out if necessary */
1341 				if (sigrestart == TRUE || sigshutdown == TRUE)
1342 					break;
1343 				if (errno == EWOULDBLOCK || errno == EINTR)	/* retry */
1344 					continue;
1345 				/* socket is nonblocking and we don't have a connection yet */
1346 				if (errno == EAGAIN)
1347 					continue;
1348 				if (errno == ENOBUFS)	/* fix for HP-UX 11.0 - just retry */
1349 					continue;
1350 
1351 				break;			/* else handle the error later */
1352 			}
1353 
1354 
1355 			rc = wait_conn_fork(new_sd);
1356 			if (rc == TRUE)
1357 				continue;		/* Continue if this is the parent returning */
1358 
1359 			/* grandchild running here */
1360 			conn_check_peer(new_sd);
1361 
1362 			/* handle the client connection */
1363 			handle_connection(new_sd);
1364 
1365 			/* log info */
1366 			if (debug == TRUE)
1367 				logit(LOG_DEBUG, "Connection from %s closed.", remote_host);
1368 
1369 			/* close socket prior to exiting */
1370 			close(new_sd);
1371 
1372 			exit(STATE_OK);
1373 
1374 		}
1375 	}
1376 
1377 	/* close the sockets we're listening on */
1378 	close_listen_socks();
1379 	freeaddrinfo(listen_addrs);
1380 	listen_addrs = NULL;
1381 
1382 	return;
1383 }
1384 
1385 void setup_wait_conn(void)
1386 {
1387 	struct addrinfo *ai;
1388 	char	addrstr[100];
1389 	void	*ptr;
1390 
1391 	add_listen_addr(&listen_addrs, address_family,
1392 					(strcmp(server_address, "") == 0) ? NULL : server_address, server_port);
1393 
1394 	for (ai = listen_addrs; ai; ai = ai->ai_next) {
1395 		if (debug == TRUE) {
1396 			inet_ntop (ai->ai_family, ai->ai_addr->sa_data, addrstr, 100);
1397 			ptr = &((struct sockaddr_in *) ai->ai_addr)->sin_addr;
1398 			inet_ntop (ai->ai_family, ptr, addrstr, 100);
1399 			logit(LOG_INFO, "SETUP_WAIT_CONN FOR: IPv4 address: %s (%s)\n", addrstr, ai->ai_canonname);
1400 		}
1401 		create_listener(ai);
1402 	}
1403 
1404 	if (!num_listen_socks) {
1405 		logit(LOG_ERR, "Cannot bind to any address.");
1406 		exit(1);
1407 	}
1408 
1409 	/* log warning about command arguments */
1410 #ifdef ENABLE_COMMAND_ARGUMENTS
1411 	if (allow_arguments == TRUE)
1412 		logit(LOG_NOTICE,
1413 			   "Warning: Daemon is configured to accept command arguments from clients!");
1414 # ifdef ENABLE_BASH_COMMAND_SUBSTITUTION
1415 	if (TRUE == allow_bash_cmd_subst) {
1416 		if (TRUE == allow_arguments)
1417 			logit(LOG_NOTICE,
1418 				   "Warning: Daemon is configured to accept command arguments with bash command substitutions!");
1419 		else
1420 			logit(LOG_NOTICE,
1421 				   "Warning: Daemon is configured to accept command arguments with bash command substitutions, but is not configured to accept command arguments from clients. Enable command arguments if you wish to allow command arguments with bash command substitutions.");
1422 	}
1423 # endif
1424 #endif
1425 
1426 	logit(LOG_INFO, "Listening for connections on port %d", server_port);
1427 
1428 	if (allowed_hosts)
1429 		logit(LOG_INFO, "Allowing connections from: %s\n", allowed_hosts);
1430 }
1431 
1432 int wait_conn_fork(int sock)
1433 {
1434 #ifdef HAVE_SIGACTION
1435 	struct sigaction sig_action;
1436 #endif
1437 	pid_t     pid;
1438 
1439 	/* child process should handle the connection */
1440 	pid = fork();
1441 
1442 	if (pid > 0) {
1443 		close(sock);			/* parent doesn't need the new connection */
1444 		waitpid(pid, NULL, 0);	/* parent waits for first child to exit */
1445 		return TRUE;			/* tell caller this is the parent process */
1446 	}
1447 
1448 	if (pid < 0) {
1449 		logit(LOG_ERR, "fork() failed with error %d, bailing out...", errno);
1450 		exit(STATE_CRITICAL);
1451 	}
1452 
1453 	/* fork again so we don't create zombies */
1454 	pid = fork();
1455 
1456 	if (pid < 0) {
1457 		logit(LOG_ERR, "Second fork() failed with error %d, bailing out...", errno);
1458 		exit(STATE_CRITICAL);
1459 	}
1460 
1461 	if (pid > 0) {
1462 		/* first child returns immediately, grandchild is inherited by
1463 		   INIT process -> no zombies... */
1464 		exit(STATE_OK);
1465 	}
1466 
1467 	/* hey, there was an error... */
1468 	if (sock < 0) {
1469 		/* log error */
1470 		logit(LOG_ERR, "Network server accept failure (%d: %s)",
1471 			   errno, strerror(errno));
1472 		exit(STATE_OK);
1473 	}
1474 
1475 	/* all good - handle signals */
1476 #ifdef HAVE_SIGACTION
1477 	sig_action.sa_sigaction = NULL;
1478 	sig_action.sa_handler = child_sighandler;
1479 	sigfillset(&sig_action.sa_mask);
1480 	sig_action.sa_flags = SA_NODEFER | SA_RESTART;
1481 	sigaction(SIGQUIT, &sig_action, NULL);
1482 	sigaction(SIGTERM, &sig_action, NULL);
1483 	sigaction(SIGHUP, &sig_action, NULL);
1484 #else	 /* HAVE_SIGACTION */
1485 	signal(SIGQUIT, child_sighandler);
1486 	signal(SIGTERM, child_sighandler);
1487 	signal(SIGHUP, child_sighandler);
1488 #endif	 /* HAVE_SIGACTION */
1489 
1490 	close_listen_socks();		/* grandchild does not need to listen */
1491 
1492 	return FALSE;				/* tell caller this isn't the parent process */
1493 }
1494 
1495 void conn_check_peer(int sock)
1496 {
1497 #ifdef HAVE_LIBWRAP
1498 	struct request_info     req;
1499 #endif
1500 #ifdef HAVE_STRUCT_SOCKADDR_STORAGE
1501 	struct sockaddr_storage addr;
1502 #else
1503 	struct sockaddr			addr;
1504 #endif
1505 	struct sockaddr_in      *nptr;
1506 	struct sockaddr_in6     *nptr6;
1507 
1508 	char      ipstr[INET6_ADDRSTRLEN];
1509 	socklen_t addrlen;
1510 	int       rc;
1511 
1512 	/* find out who just connected... */
1513 	addrlen = sizeof(addr);
1514 	rc = getpeername(sock, (struct sockaddr *)&addr, &addrlen);
1515 
1516 	if (rc < 0) {
1517 		/* log error */
1518 		logit(LOG_ERR, "Error: Network server getpeername() failure (%d: %s)",
1519 			   errno, strerror(errno));
1520 
1521 		/* close socket prior to exiting */
1522 		close(sock);
1523 		return;
1524 	}
1525 
1526 #ifdef HAVE_STRUCT_SOCKADDR_STORAGE
1527 	switch (addr.ss_family) {
1528 #else
1529 	switch (addr.sa_family) {
1530 #endif
1531 
1532 	case AF_INET:
1533 		nptr = (struct sockaddr_in *)&addr;
1534 		strncpy(remote_host, inet_ntoa(nptr->sin_addr), sizeof(remote_host) - 1);
1535 		remote_host[MAX_HOST_ADDRESS_LENGTH - 1] = '\0';
1536 		break;
1537 
1538 	case AF_INET6:
1539 		nptr6 = (struct sockaddr_in6 *)&addr;
1540 		if (inet_ntop(AF_INET6, (const void *)&(nptr6->sin6_addr),
1541 					  ipstr, sizeof(ipstr)) == NULL) {
1542 			strncpy(ipstr, "Unknown", sizeof(ipstr));
1543 		}
1544 		strncpy(remote_host, ipstr, sizeof(remote_host) - 1);
1545 		remote_host[MAX_HOST_ADDRESS_LENGTH - 1] = '\0';
1546 		break;
1547 	}
1548 
1549 	if (debug == TRUE)
1550 		logit(LOG_INFO, "CONN_CHECK_PEER: checking if host is allowed: %s port %d\n",
1551 			 remote_host, nptr->sin_port);
1552 
1553 	/* is this host allowed? */
1554 	if (allowed_hosts) {
1555 #ifdef HAVE_STRUCT_SOCKADDR_STORAGE
1556 		switch (addr.ss_family) {
1557 #else
1558 		switch (addr.sa_family) {
1559 #endif
1560 
1561 		case AF_INET:
1562 			/* log info */
1563 			if (debug == TRUE || (sslprm.log_opts & SSL_LogIpAddr))
1564 				logit(LOG_DEBUG, "Connection from %s port %d", remote_host, nptr->sin_port);
1565 
1566 			if (!is_an_allowed_host(AF_INET, (void *)&(nptr->sin_addr))) {
1567 				/* log error */
1568 				logit(LOG_ERR, "Host %s is not allowed to talk to us!", remote_host);
1569 
1570 				/* log info */
1571 				if (debug == TRUE)
1572 					logit(LOG_DEBUG, "Connection from %s closed.", remote_host);
1573 
1574 				/* close socket prior to exiting */
1575 				close(sock);
1576 				exit(STATE_OK);
1577 
1578 			} else {
1579 
1580 				/* log info */
1581 				if (debug == TRUE) {
1582 					logit(LOG_DEBUG, "Host address is in allowed_hosts");
1583 				}
1584 
1585 			}
1586 			break;
1587 
1588 		case AF_INET6:
1589 			/* log info */
1590 			strcpy(remote_host, ipstr);
1591 			if (debug == TRUE || (sslprm.log_opts & SSL_LogIpAddr)) {
1592 				logit(LOG_DEBUG, "Connection from %s port %d", ipstr, nptr6->sin6_port);
1593 			}
1594 
1595 			if (!is_an_allowed_host(AF_INET6, (void *)&(nptr6->sin6_addr))) {
1596 				/* log error */
1597 				logit(LOG_ERR, "Host %s is not allowed to talk to us!", ipstr);
1598 
1599 				/* log info */
1600 				if (debug == TRUE)
1601 					logit(LOG_DEBUG, "Connection from %s closed.", ipstr);
1602 
1603 				/* close socket prior to exiting */
1604 				close(sock);
1605 				exit(STATE_OK);
1606 
1607 			} else {
1608 				/* log info */
1609 				if (debug == TRUE)
1610 					logit(LOG_DEBUG, "Host address is in allowed_hosts");
1611 			}
1612 			break;
1613 		}
1614 	}
1615 
1616 #ifdef HAVE_LIBWRAP
1617 	/* Check whether or not connections are allowed from this host */
1618 	request_init(&req, RQ_DAEMON, "nrpe", RQ_FILE, sock, 0);
1619 	fromhost(&req);
1620 
1621 	if (!hosts_access(&req)) {
1622 		logit(LOG_DEBUG, "Connection refused by TCP wrapper");
1623 		refuse(&req);			/* refuse the connection */
1624 		/* should not be reached */
1625 		logit(LOG_ERR, "libwrap refuse() returns!");
1626 		close(sock);
1627 		exit(STATE_CRITICAL);
1628 	}
1629 #endif
1630 }
1631 
1632 /* handles a client connection */
1633 void handle_connection(int sock)
1634 {
1635 	u_int32_t calculated_crc32;
1636 	command  *temp_command;
1637 	v2_packet receive_packet, send_packet;
1638 	v3_packet *v3_receive_packet = NULL, *v3_send_packet = NULL;
1639 	int       bytes_to_send;
1640 	char      buffer[MAX_INPUT_BUFFER], *send_buff = NULL, *send_pkt;
1641 	char      raw_command[MAX_INPUT_BUFFER];
1642 	char      processed_command[MAX_INPUT_BUFFER];
1643 	int       result = STATE_OK;
1644 	int       early_timeout = FALSE;
1645 	int       rc;
1646 	int       x;
1647 	int32_t   pkt_size;
1648 #ifdef DEBUG
1649 	FILE     *errfp;
1650 #endif
1651 #ifdef HAVE_SSL
1652 	SSL      *ssl = NULL;
1653 #endif
1654 
1655 	/* do SSL handshake */
1656 #ifdef HAVE_SSL
1657 	if (use_ssl == TRUE) {
1658     	if ((ssl = SSL_new(ctx)) == NULL) {
1659         	logit(LOG_ERR, "Error: Could not create SSL connection structure.");
1660 # ifdef DEBUG
1661             errfp = fopen("/tmp/err.log", "a");
1662     		ERR_print_errors_fp(errfp);
1663         	fclose(errfp);
1664 # endif
1665     		return;
1666         }
1667 
1668 		if (handle_conn_ssl(sock, ssl) != OK)
1669 			return;
1670 	}
1671 #endif
1672 
1673 #ifdef HAVE_SSL
1674 	rc = read_packet(sock, ssl, &receive_packet, &v3_receive_packet);
1675 #else
1676 	rc = read_packet(sock, NULL, &receive_packet, &v3_receive_packet);
1677 #endif
1678 
1679 	/* disable connection alarm - a new alarm will be setup during my_system */
1680 	alarm(0);
1681 
1682 	/* recv() error or client disconnect */
1683 	if (rc <= 0) {
1684 		/* log error */
1685 		logit(LOG_ERR, "Could not read request from client %s, bailing out...", remote_host);
1686 		if (v3_receive_packet)
1687 			free(v3_receive_packet);
1688 #ifdef HAVE_SSL
1689 		if (ssl) {
1690 			complete_SSL_shutdown(ssl);
1691 			SSL_free(ssl);
1692 			logit(LOG_INFO, "INFO: SSL Socket Shutdown.\n");
1693 		}
1694 #endif
1695 		return;
1696 	}
1697 
1698 	/* make sure the request is valid */
1699 	if (validate_request(&receive_packet, v3_receive_packet) == ERROR) {
1700 		/* log an error */
1701 		logit(LOG_ERR, "Client request from %s was invalid, bailing out...", remote_host);
1702 
1703 		/* free memory */
1704 		free(command_name);
1705 		command_name = NULL;
1706 		for (x = 0; x < MAX_COMMAND_ARGUMENTS; x++) {
1707 			free(macro_argv[x]);
1708 			macro_argv[x] = NULL;
1709 		}
1710 		if (v3_receive_packet)
1711 			free(v3_receive_packet);
1712 
1713 #ifdef HAVE_SSL
1714 		if (ssl) {
1715 			complete_SSL_shutdown(ssl);
1716 			SSL_free(ssl);
1717 		}
1718 #endif
1719 
1720 		return;
1721 	}
1722 
1723 	/* log info */
1724 	if (debug == TRUE)
1725 		logit(LOG_DEBUG, "Host %s is asking for command '%s' to be run...",
1726 			   remote_host, command_name);
1727 
1728 	/* if this is the version check command, just spew it out */
1729 	if (!strcmp(command_name, NRPE_HELLO_COMMAND)) {
1730 		snprintf(buffer, sizeof(buffer), "NRPE v%s", PROGRAM_VERSION);
1731 		buffer[sizeof(buffer) - 1] = '\x0';
1732 		if (debug == TRUE)		/* log info */
1733 			logit(LOG_DEBUG, "Response to %s: %s", remote_host, buffer);
1734 		if (v3_receive_packet)
1735 			send_buff = strdup(buffer);
1736 		else {
1737 			send_buff = calloc(1, sizeof(buffer));
1738 			strcpy(send_buff, buffer);
1739 		}
1740 		result = STATE_OK;
1741 
1742 	} else {
1743 
1744 		/* find the command we're supposed to run */
1745 		temp_command = find_command(command_name);
1746 		if (temp_command == NULL) {
1747 			snprintf(buffer, sizeof(buffer), "NRPE: Command '%s' not defined", command_name);
1748 			buffer[sizeof(buffer) - 1] = '\x0';
1749 			if (debug == TRUE)	/* log error */
1750 				logit(LOG_DEBUG, "%s", buffer);
1751 			if (v3_receive_packet)
1752 				send_buff = strdup(buffer);
1753 			else {
1754 				send_buff = calloc(1, sizeof(buffer));
1755 				strcpy(send_buff, buffer);
1756 			}
1757 			result = STATE_UNKNOWN;
1758 
1759 		} else {
1760 
1761 			/* process command line */
1762 			if (command_prefix == NULL)
1763 				strncpy(raw_command, temp_command->command_line, sizeof(raw_command) - 1);
1764 			else
1765 				snprintf(raw_command, sizeof(raw_command) - 1, "%s %s", command_prefix,
1766 						 temp_command->command_line);
1767 			raw_command[sizeof(raw_command) - 1] = '\x0';
1768 			process_macros(raw_command, processed_command, sizeof(processed_command));
1769 
1770 			if (debug == TRUE)	/* log info */
1771 				logit(LOG_DEBUG, "Running command: %s", processed_command);
1772 
1773 			/* run the command */
1774 			strcpy(buffer, "");
1775 			result = my_system(processed_command, command_timeout, &early_timeout, &send_buff);
1776 
1777 			if (debug == TRUE)	/* log debug info */
1778 				logit(LOG_DEBUG, "Command completed with return code %d and output: %s",
1779 					   result, send_buff);
1780 
1781 			/* see if the command timed out */
1782 			if (early_timeout == TRUE) {
1783 				sprintf(send_buff, "NRPE: Command timed out after %d seconds\n",
1784 						command_timeout);
1785 				result = STATE_UNKNOWN;
1786 			} else if (!strcmp(send_buff, "")) {
1787 				sprintf(send_buff, "NRPE: Unable to read output\n");
1788 				result = STATE_UNKNOWN;
1789 			}
1790 
1791 			/* check return code bounds */
1792 			if ((result < 0) || (result > 3)) {
1793 				/* log error */
1794 				logit(LOG_ERR, "Bad return code for [%s]: %d", send_buff, result);
1795 				result = STATE_UNKNOWN;
1796 			}
1797 		}
1798 	}
1799 
1800 	/* free memory */
1801 	free(command_name);
1802 	command_name = NULL;
1803 	for (x = 0; x < MAX_COMMAND_ARGUMENTS; x++) {
1804 		free(macro_argv[x]);
1805 		macro_argv[x] = NULL;
1806 	}
1807 	if (v3_receive_packet)
1808 		free(v3_receive_packet);
1809 	pkt_size = strlen(send_buff);
1810 	/* strip newline character from end of output buffer */
1811 	if (send_buff[strlen(send_buff) - 1] == '\n')
1812 		send_buff[strlen(send_buff) - 1] = '\x0';
1813 
1814 	if (packet_ver == NRPE_PACKET_VERSION_2) {
1815 		pkt_size = sizeof(v2_packet);
1816 		send_pkt = (char *)&send_packet;
1817 
1818 		/* clear the response packet buffer */
1819 		memset(&send_packet, 0, sizeof(send_packet));
1820 		/* fill the packet with semi-random data */
1821 		randomize_buffer((char *)&send_packet, sizeof(send_packet));
1822 
1823 		/* initialize response packet data */
1824 		send_packet.packet_version = htons(packet_ver);
1825 		send_packet.packet_type = htons(RESPONSE_PACKET);
1826 		send_packet.result_code = htons(result);
1827 		strncpy(&send_packet.buffer[0], send_buff, MAX_PACKETBUFFER_LENGTH);
1828 		send_packet.buffer[MAX_PACKETBUFFER_LENGTH - 1] = '\x0';
1829 
1830 		/* calculate the crc 32 value of the packet */
1831 		send_packet.crc32_value = 0;
1832 		calculated_crc32 = calculate_crc32((char *)&send_packet, sizeof(send_packet));
1833 		send_packet.crc32_value = htonl(calculated_crc32);
1834 
1835 	} else {
1836 
1837 		pkt_size = (sizeof(v3_packet) - 1) + strlen(send_buff);
1838 		v3_send_packet = calloc(1, pkt_size);
1839 		send_pkt = (char *)v3_send_packet;
1840 		/* initialize response packet data */
1841 		v3_send_packet->packet_version = htons(packet_ver);
1842 		v3_send_packet->packet_type = htons(RESPONSE_PACKET);
1843 		v3_send_packet->result_code = htons(result);
1844 		v3_send_packet->alignment = 0;
1845 		v3_send_packet->buffer_length = htonl(strlen(send_buff));
1846 		strcpy(&v3_send_packet->buffer[0], send_buff);
1847 
1848 		/* calculate the crc 32 value of the packet */
1849 		v3_send_packet->crc32_value = 0;
1850 		calculated_crc32 = calculate_crc32((char *)v3_send_packet, pkt_size);
1851 		v3_send_packet->crc32_value = htonl(calculated_crc32);
1852 	}
1853 
1854 	/* send the response back to the client */
1855 	bytes_to_send = pkt_size;
1856 	if (use_ssl == FALSE)
1857 		sendall(sock, send_pkt, &bytes_to_send);
1858 #ifdef HAVE_SSL
1859 	else
1860 		SSL_write(ssl, send_pkt, bytes_to_send);
1861 #endif
1862 
1863 #ifdef HAVE_SSL
1864 	if (ssl) {
1865 		complete_SSL_shutdown(ssl);
1866 		SSL_free(ssl);
1867 	}
1868 #endif
1869 
1870 	if (v3_send_packet)
1871 		free(v3_send_packet);
1872 
1873 	/* log info */
1874 	if (debug == TRUE)
1875 		logit(LOG_DEBUG, "Return Code: %d, Output: %s", result, send_buff);
1876 
1877 	free(send_buff);
1878 
1879 	return;
1880 }
1881 
1882 void init_handle_conn(void)
1883 {
1884 #ifdef HAVE_SIGACTION
1885 	struct sigaction sig_action;
1886 #endif
1887 
1888 	/* log info */
1889 	if (debug == TRUE)
1890 		logit(LOG_DEBUG, "Handling the connection...");
1891 
1892 	/* set connection handler */
1893 #ifdef HAVE_SIGACTION
1894 	sig_action.sa_sigaction = NULL;
1895 	sig_action.sa_handler = my_connection_sighandler;
1896 	sigfillset(&sig_action.sa_mask);
1897 	sig_action.sa_flags = SA_NODEFER | SA_RESTART;
1898 	sigaction(SIGALRM, &sig_action, NULL);
1899 #else
1900 	signal(SIGALRM, my_connection_sighandler);
1901 #endif	 /* HAVE_SIGACTION */
1902 	alarm(connection_timeout);
1903 }
1904 
1905 int handle_conn_ssl(int sock, void *ssl_ptr)
1906 {
1907 #ifdef HAVE_SSL
1908 # if (defined(__sun) && defined(SOLARIS_10)) || defined(_AIX) || defined(__hpux)
1909 	SSL_CIPHER *c;
1910 #else
1911 	const SSL_CIPHER *c;
1912 #endif
1913 	const char *errmsg = NULL;
1914 	char      buffer[MAX_INPUT_BUFFER];
1915 	SSL      *ssl = (SSL*)ssl_ptr;
1916 	X509     *peer;
1917 	int       rc, x;
1918 
1919 	SSL_set_fd(ssl, sock);
1920 
1921 	/* keep attempting the request if needed */
1922 	while (((rc = SSL_accept(ssl)) != 1)
1923 			&& (SSL_get_error(ssl, rc) == SSL_ERROR_WANT_READ));
1924 
1925 	if (rc != 1) {
1926 		/* oops, got an unrecoverable error -- get out */
1927 		if (sslprm.log_opts & (SSL_LogCertDetails | SSL_LogIfClientCert)) {
1928 			int nerrs = 0;
1929 			rc = 0;
1930 			while ((x = ERR_get_error_line_data(NULL, NULL, NULL, NULL)) != 0) {
1931 				errmsg = ERR_reason_error_string(x);
1932 				logit(LOG_ERR, "Error: (ERR_get_error_line_data = %d), Could not complete SSL handshake with %s: %s", x, remote_host, errmsg);
1933 
1934 				if (errmsg && !strcmp(errmsg, "no shared cipher") && (sslprm.cert_file == NULL || sslprm.cacert_file == NULL))
1935 					logit(LOG_ERR, "Error: This could be because you have not specified certificate or ca-certificate files");
1936 
1937 				++nerrs;
1938 			}
1939 
1940 			if (nerrs == 0) {
1941 				logit(LOG_ERR, "Error: (nerrs = 0) Could not complete SSL handshake with %s: %d", remote_host, SSL_get_error(ssl, rc));
1942 			}
1943 		} else {
1944 			logit(LOG_ERR, "Error: (!log_opts) Could not complete SSL handshake with %s: %d", remote_host, SSL_get_error(ssl, rc));
1945 		}
1946 # ifdef DEBUG
1947 		errfp = fopen("/tmp/err.log", "a");
1948 		ERR_print_errors_fp(errfp);
1949 		fclose(errfp);
1950 # endif
1951 		return ERROR;
1952 	}
1953 
1954 	/* successful handshake */
1955 	if (sslprm.log_opts & SSL_LogVersion)
1956 		logit(LOG_NOTICE, "Remote %s - SSL Version: %s", remote_host, SSL_get_version(ssl));
1957 
1958 	if (sslprm.log_opts & SSL_LogCipher) {
1959 		c = SSL_get_current_cipher(ssl);
1960 		logit(LOG_NOTICE, "Remote %s - %s, Cipher is %s", remote_host, SSL_CIPHER_get_version(c), SSL_CIPHER_get_name(c));
1961 	}
1962 
1963 	if ((sslprm.log_opts & SSL_LogIfClientCert)
1964 		|| (sslprm.log_opts & SSL_LogCertDetails)) {
1965 
1966 
1967 		peer = SSL_get_peer_certificate(ssl);
1968 
1969 		if (peer) {
1970 			if (sslprm.log_opts & SSL_LogIfClientCert)
1971 				logit(LOG_NOTICE, "SSL Client %s has %s certificate",
1972 					   remote_host, SSL_get_verify_result(ssl) == X509_V_OK ? "a valid" : "an invalid");
1973 
1974 			if (sslprm.log_opts & SSL_LogCertDetails) {
1975 
1976 				X509_NAME_oneline(X509_get_subject_name(peer), buffer, sizeof(buffer));
1977 				logit(LOG_NOTICE, "SSL Client %s Cert Name: %s",
1978 					   remote_host, buffer);
1979 
1980 				X509_NAME_oneline(X509_get_issuer_name(peer), buffer, sizeof(buffer));
1981 				logit(LOG_NOTICE, "SSL Client %s Cert Issuer: %s",
1982 					   remote_host, buffer);
1983 			}
1984 
1985 		} else if (sslprm.client_certs == 0)
1986 			logit(LOG_NOTICE, "SSL Not asking for client certification");
1987 
1988 		else
1989 			logit(LOG_NOTICE, "SSL Client %s did not present a certificate",
1990 				   remote_host);
1991 	}
1992 #endif
1993 
1994 	return OK;
1995 }
1996 
1997 int read_packet(int sock, void *ssl_ptr, v2_packet * v2_pkt, v3_packet ** v3_pkt)
1998 {
1999 	int32_t   common_size, tot_bytes, bytes_to_recv, buffer_size;
2000 	int       rc;
2001 	char     *buff_ptr;
2002 
2003 	/* Read only the part that's common between versions 2 & 3 */
2004 	common_size = tot_bytes = bytes_to_recv = (char *)&v2_pkt->buffer - (char *)v2_pkt;
2005 
2006 	if (use_ssl == FALSE) {
2007 		rc = recvall(sock, (char *)v2_pkt, &tot_bytes, socket_timeout);
2008 
2009 		if (rc <= 0 || rc != bytes_to_recv)
2010 			return -1;
2011 
2012 		packet_ver = ntohs(v2_pkt->packet_version);
2013 		if (packet_ver != NRPE_PACKET_VERSION_2 && packet_ver != NRPE_PACKET_VERSION_3) {
2014 			logit(LOG_ERR, "Error: (use_ssl == false): Request packet version was invalid!");
2015 			return -1;
2016 		}
2017 
2018 		if (packet_ver == NRPE_PACKET_VERSION_2) {
2019 			buffer_size = sizeof(v2_packet) - common_size;
2020 			buff_ptr = (char *)v2_pkt + common_size;
2021 
2022 		} else {
2023 			int32_t   pkt_size = sizeof(v3_packet) - 1;
2024 
2025 			/* Read the alignment filler */
2026 			bytes_to_recv = sizeof(int16_t);
2027 			rc = recvall(sock, (char *)&buffer_size, &bytes_to_recv, socket_timeout);
2028 			if (rc <= 0 || bytes_to_recv != sizeof(int16_t))
2029 				return -1;
2030 			tot_bytes += rc;
2031 
2032 			/* Read the buffer size */
2033 			bytes_to_recv = sizeof(buffer_size);
2034 			rc = recvall(sock, (char *)&buffer_size, &bytes_to_recv, socket_timeout);
2035 			if (rc <= 0 || bytes_to_recv != sizeof(buffer_size))
2036 				return -1;
2037 			tot_bytes += rc;
2038 
2039 			buffer_size = ntohl(buffer_size);
2040 			pkt_size += buffer_size;
2041 			if ((*v3_pkt = calloc(1, pkt_size)) == NULL) {
2042 				logit(LOG_ERR, "Error: (use_ssl == false): Could not allocate memory for packet");
2043 				return -1;
2044 			}
2045 
2046 			memcpy(*v3_pkt, v2_pkt, common_size);
2047 			(*v3_pkt)->buffer_length = htonl(buffer_size);
2048 			buff_ptr = (*v3_pkt)->buffer;
2049 		}
2050 
2051 		bytes_to_recv = buffer_size;
2052 		rc = recvall(sock, buff_ptr, &bytes_to_recv, socket_timeout);
2053 
2054 		if (rc <= 0 || rc != buffer_size) {
2055 			if (packet_ver == NRPE_PACKET_VERSION_3) {
2056 				free(*v3_pkt);
2057 				*v3_pkt = NULL;
2058 			}
2059 			return -1;
2060 		} else
2061 			tot_bytes += rc;
2062 	}
2063 #ifdef HAVE_SSL
2064 	else {
2065 		SSL      *ssl = (SSL *) ssl_ptr;
2066 
2067 		while (((rc = SSL_read(ssl, v2_pkt, bytes_to_recv)) <= 0)
2068 			   && (SSL_get_error(ssl, rc) == SSL_ERROR_WANT_READ)) {
2069 		}
2070 
2071 		if (rc <= 0 || rc != bytes_to_recv)
2072 			return -1;
2073 
2074 		packet_ver = ntohs(v2_pkt->packet_version);
2075 		if (packet_ver != NRPE_PACKET_VERSION_2 && packet_ver != NRPE_PACKET_VERSION_3) {
2076 			logit(LOG_ERR, "Error: (use_ssl == true): Request packet version was invalid!");
2077 			return -1;
2078 		}
2079 
2080 		if (packet_ver == NRPE_PACKET_VERSION_2) {
2081 			buffer_size = sizeof(v2_packet) - common_size;
2082 			buff_ptr = (char *)v2_pkt + common_size;
2083 		} else {
2084 			int32_t   pkt_size = sizeof(v3_packet) - 1;
2085 
2086 			/* Read the alignment filler */
2087 			bytes_to_recv = sizeof(int16_t);
2088 			while (((rc = SSL_read(ssl, &buffer_size, bytes_to_recv)) <= 0)
2089 				   && (SSL_get_error(ssl, rc) == SSL_ERROR_WANT_READ)) {
2090 			}
2091 
2092 			if (rc <= 0 || bytes_to_recv != sizeof(int16_t))
2093 				return -1;
2094 			tot_bytes += rc;
2095 
2096 			/* Read the buffer size */
2097 			bytes_to_recv = sizeof(buffer_size);
2098 			while (((rc = SSL_read(ssl, &buffer_size, bytes_to_recv)) <= 0)
2099 				   && (SSL_get_error(ssl, rc) == SSL_ERROR_WANT_READ)) {
2100 			}
2101 
2102 			if (rc <= 0 || bytes_to_recv != sizeof(buffer_size))
2103 				return -1;
2104 			tot_bytes += rc;
2105 
2106 			buffer_size = ntohl(buffer_size);
2107 			pkt_size += buffer_size;
2108 			if ((*v3_pkt = calloc(1, pkt_size)) == NULL) {
2109 				logit(LOG_ERR, "Error: (use_ssl == true): Could not allocate memory for packet");
2110 				return -1;
2111 			}
2112 
2113 			memcpy(*v3_pkt, v2_pkt, common_size);
2114 			(*v3_pkt)->buffer_length = htonl(buffer_size);
2115 			buff_ptr = (*v3_pkt)->buffer;
2116 		}
2117 
2118 		bytes_to_recv = buffer_size;
2119 		while (((rc = SSL_read(ssl, buff_ptr, bytes_to_recv)) <= 0)
2120 			   && (SSL_get_error(ssl, rc) == SSL_ERROR_WANT_READ)) {
2121 		}
2122 
2123 		if (rc <= 0 || rc != buffer_size) {
2124 			if (packet_ver == NRPE_PACKET_VERSION_3) {
2125 				free(*v3_pkt);
2126 				*v3_pkt = NULL;
2127 			}
2128 			return -1;
2129 		} else
2130 			tot_bytes += rc;
2131 	}
2132 #endif
2133 
2134 	return tot_bytes;
2135 }
2136 
2137 /* free all allocated memory */
2138 void free_memory(void)
2139 {
2140 	command  *this_command;
2141 	command  *next_command;
2142 
2143 	/* free memory for the command list */
2144 	this_command = command_list;
2145 	while (this_command != NULL) {
2146 		next_command = this_command->next;
2147 		if (this_command->command_name)
2148 			free(this_command->command_name);
2149 		if (this_command->command_line)
2150 			free(this_command->command_line);
2151 		free(this_command);
2152 		this_command = next_command;
2153 	}
2154 
2155 	command_list = NULL;
2156 	return;
2157 }
2158 
2159 /* executes a system command via popen(), but protects against timeouts */
2160 int my_system(char *command, int timeout, int *early_timeout, char **output)
2161 {
2162 	FILE     *fp;
2163 	pid_t     pid;
2164 	time_t    start_time, end_time;
2165 	int       status;
2166 	int       result;
2167 	char      buffer[MAX_INPUT_BUFFER];
2168 	int       fd[2];
2169 	int       bytes_read = 0, tot_bytes = 0;
2170 	int       output_size;
2171 #ifdef HAVE_SIGACTION
2172 	struct sigaction sig_action;
2173 #endif
2174 
2175 	*early_timeout = FALSE;		/* initialize return variables */
2176 
2177 	if (command == NULL)		/* if no command was passed, return with no error */
2178 		return STATE_OK;
2179 
2180 	/* make sure that we are within max_commands boundaries before attempting */
2181 	if (max_commands != 0) {
2182 		while (commands_running >= max_commands) {
2183 			logit(LOG_WARNING, "Commands choked. Sleeping 1s - commands_running: %d, max_commands: %d", commands_running, max_commands);
2184 			sleep(1);
2185 		}
2186 	}
2187 
2188 	/* create a pipe */
2189 	if (pipe(fd) == -1) {
2190 		logit(LOG_ERR, "ERROR: pipe(): %s, bailing out...", strerror(errno));
2191 		exit(STATE_CRITICAL);
2192 	}
2193 
2194 	/* make the pipe non-blocking */
2195 	fcntl(fd[0], F_SETFL, O_NONBLOCK);
2196 	fcntl(fd[1], F_SETFL, O_NONBLOCK);
2197 
2198 	time(&start_time);			/* get the command start time */
2199 
2200 	pid = fork();				/* fork */
2201 
2202 	/* return an error if we couldn't fork */
2203 	if (pid == -1) {
2204 		snprintf(buffer, sizeof(buffer) - 1, "NRPE: Call to fork() failed\n");
2205 		buffer[sizeof(buffer) - 1] = '\x0';
2206 
2207 		if (packet_ver == NRPE_PACKET_VERSION_2) {
2208 			int       output_size = sizeof(v2_packet);
2209 			*output = calloc(1, output_size);
2210 			strncpy(*output, buffer, output_size - 1);
2211 			*output[output_size - 1] = '\0';
2212 		} else
2213 			*output = strdup(buffer);
2214 
2215 		/* close both ends of the pipe */
2216 		close(fd[0]);
2217 		close(fd[1]);
2218 
2219 		return STATE_UNKNOWN;
2220 	}
2221 
2222 	/* execute the command in the child process */
2223 	if (pid == 0) {
2224 
2225 		/* get root back so the next call works correctly */
2226 		if (SETEUID(0) == -1 && debug)
2227 			logit(LOG_WARNING, "WARNING: my_system() seteuid(0): %s", strerror(errno));
2228 
2229 		drop_privileges(nrpe_user, nrpe_group, 1);	/* drop privileges */
2230 		close(fd[0]);			/* close pipe for reading */
2231 		setpgid(0, 0);			/* become process group leader */
2232 
2233 		/* trap commands that timeout */
2234 #ifdef HAVE_SIGACTION
2235 		sig_action.sa_sigaction = NULL;
2236 		sig_action.sa_handler = my_system_sighandler;
2237 		sigfillset(&sig_action.sa_mask);
2238 		sig_action.sa_flags = SA_NODEFER | SA_RESTART;
2239 		sigaction(SIGALRM, &sig_action, NULL);
2240 #else
2241 		signal(SIGALRM, my_system_sighandler);
2242 #endif	 /* HAVE_SIGACTION */
2243 		alarm(timeout);
2244 
2245 		fp = popen(command, "r");	/* run the command */
2246 
2247 		/* report an error if we couldn't run the command */
2248 		if (fp == NULL) {
2249 			strncpy(buffer, "NRPE: Call to popen() failed\n", sizeof(buffer) - 1);
2250 			buffer[sizeof(buffer) - 1] = '\x0';
2251 
2252 			/* write the error back to the parent process */
2253 			if (write(fd[1], buffer, strlen(buffer) + 1) == -1)
2254 				logit(LOG_ERR, "ERROR: my_system() write(fd, buffer)-1 failed...");
2255 
2256 			result = STATE_CRITICAL;
2257 
2258 		} else {
2259 
2260 			/* read all lines of output - supports Nagios 3.x multiline output */
2261 			while ((bytes_read = fread(buffer, 1, sizeof(buffer) - 1, fp)) > 0) {
2262 				/* write the output back to the parent process */
2263 				if (write(fd[1], buffer, bytes_read) == -1)
2264 					logit(LOG_ERR, "ERROR: my_system() write(fd, buffer)-2 failed...");
2265 			}
2266 
2267 			if (write(fd[1], "\0", 1) == -1)
2268 				logit(LOG_ERR, "ERROR: my_system() write(fd, NULL) failed...");
2269 
2270 			status = pclose(fp);	/* close the command and get termination status */
2271 
2272 			/* report an error if we couldn't close the command */
2273 			if (status == -1)
2274 				result = STATE_CRITICAL;
2275 			else if (!WIFEXITED(status))
2276 				/* report an error if child died due to signal (Klas Lindfors) */
2277 				result = STATE_CRITICAL;
2278 			else
2279 				result = WEXITSTATUS(status);
2280 		}
2281 
2282 		close(fd[1]);			/* close pipe for writing */
2283 		alarm(0);				/* reset the alarm */
2284 		exit(result);			/* return plugin exit code to parent process */
2285 
2286 	} else {
2287 		/* parent waits for child to finish executing command */
2288 
2289 		commands_running++;
2290 
2291 		close(fd[1]);			/* close pipe for writing */
2292 		waitpid(pid, &status, 0);	/* wait for child to exit */
2293 		time(&end_time);		/* get the end time for running the command */
2294 		result = WEXITSTATUS(status);	/* get the exit code returned from the program */
2295 
2296 		/* because of my idiotic idea of having UNKNOWN states be equivalent to -1, I must hack things a bit... */
2297 		if (result == 255)
2298 			result = STATE_UNKNOWN;
2299 
2300 		/* check bounds on the return value */
2301 		if (result < 0 || result > 3)
2302 			result = STATE_UNKNOWN;
2303 
2304 		if (packet_ver == NRPE_PACKET_VERSION_2) {
2305 			output_size = sizeof(v2_packet);
2306 			*output = calloc(1, output_size);
2307 		} else {
2308 			output_size = 1024 * 64;	/* Maximum buffer is 64K */
2309 			*output = calloc(1, output_size);
2310 		}
2311 
2312 		/* try and read the results from the command output (retry if we encountered a signal) */
2313 		for (;;) {
2314 			bytes_read = read(fd[0], buffer, sizeof(buffer) - 1);
2315 			if (bytes_read == 0)
2316 				break;
2317 			if (bytes_read == -1) {
2318 				if (errno == EINTR)
2319 					continue;
2320 				else
2321 					break;
2322 			}
2323 			if (tot_bytes < output_size)	/* If buffer is full, discard the rest */
2324 				strncat(*output, buffer, output_size - tot_bytes - 1);
2325 			tot_bytes += bytes_read;
2326 		}
2327 
2328 		(*output)[output_size - 1] = '\0';
2329 
2330 		/* if there was a critical return code and no output AND the
2331 		 * command time exceeded the timeout thresholds, assume a timeout */
2332 		if (result == STATE_CRITICAL && bytes_read == -1 && (end_time - start_time) >= timeout) {
2333 			*early_timeout = TRUE;
2334 
2335 			/* send termination signal to child process group */
2336 			kill((pid_t) (-pid), SIGTERM);
2337 			kill((pid_t) (-pid), SIGKILL);
2338 		}
2339 
2340 		close(fd[0]);			/* close the pipe for reading */
2341 
2342 		commands_running--;
2343 	}
2344 
2345 #ifdef DEBUG
2346 	printf("my_system() end\n");
2347 #endif
2348 
2349 	return result;
2350 }
2351 
2352 /* handle timeouts when executing commands via my_system() */
2353 void my_system_sighandler(int sig)
2354 {
2355 	exit(STATE_CRITICAL);		/* force the child process to exit... */
2356 }
2357 
2358 /* handle errors where connection takes too long */
2359 void my_connection_sighandler(int sig)
2360 {
2361 	logit(LOG_ERR, "Connection has taken too long to establish. Exiting...");
2362 	exit(STATE_CRITICAL);
2363 }
2364 
2365 /* drops privileges */
2366 int drop_privileges(char *user, char *group, int full_drop)
2367 {
2368 	uid_t     uid = (uid_t)-1;
2369 	gid_t     gid = (gid_t)-1;
2370 	struct group *grp;
2371 	struct passwd *pw;
2372 
2373 	if (use_inetd == TRUE)
2374 		return OK;
2375 
2376 	/* set effective group ID */
2377 	if (group != NULL) {
2378 
2379 		/* see if this is a group name */
2380 		if (strspn(group, "0123456789") < strlen(group)) {
2381 			grp = (struct group *)getgrnam(group);
2382 			if (grp != NULL)
2383 				gid = (gid_t) (grp->gr_gid);
2384 			else
2385 				logit(LOG_ERR, "Warning: Could not get group entry for '%s'", group);
2386 			endgrent();
2387 
2388 		} else
2389 			/* else we were passed the GID */
2390 			gid = (gid_t) atoi(group);
2391 
2392 		/* set effective group ID if other than current EGID */
2393 		if (gid != getegid()) {
2394 			if (setgid(gid) == -1)
2395 				logit(LOG_ERR, "Warning: Could not set effective GID=%d", (int)gid);
2396 		}
2397 	}
2398 
2399 
2400 	/* set effective user ID */
2401 	if (user != NULL) {
2402 
2403 		/* see if this is a user name */
2404 		if (strspn(user, "0123456789") < strlen(user)) {
2405 			pw = (struct passwd *)getpwnam(user);
2406 			if (pw != NULL)
2407 				uid = (uid_t) (pw->pw_uid);
2408 			else
2409 				logit(LOG_ERR, "Warning: Could not get passwd entry for '%s'", user);
2410 			endpwent();
2411 
2412 		} else
2413 			/* else we were passed the UID */
2414 			uid = (uid_t) atoi(user);
2415 
2416 		if (uid != geteuid()) {
2417 		/* set effective user ID if other than current EUID */
2418 #ifdef HAVE_INITGROUPS
2419 			/* initialize supplementary groups */
2420 			if (initgroups(user, gid) == -1) {
2421 				if (errno == EPERM)
2422 					logit(LOG_ERR, "Warning: Unable to change supplementary groups using initgroups()");
2423 				else {
2424 					logit(LOG_ERR, "Warning: Possibly root user failed dropping privileges with initgroups()");
2425 					return ERROR;
2426 				}
2427 			}
2428 #endif
2429 
2430 			if (full_drop) {
2431 				if (setuid(uid) == -1)
2432 					logit(LOG_ERR, "Warning: Could not set UID=%d", (int)uid);
2433 			} else if (SETEUID(uid) == -1)
2434 				logit(LOG_ERR, "Warning: Could not set effective UID=%d", (int)uid);
2435 		}
2436 	}
2437 
2438 	return OK;
2439 }
2440 
2441 /* write an optional pid file */
2442 int write_pid_file(void)
2443 {
2444 	int       fd;
2445 	int       result = 0;
2446 	pid_t     pid = 0;
2447 	char      pbuf[16];
2448 
2449 	/* no pid file was specified */
2450 	if (pid_file == NULL)
2451 		return OK;
2452 
2453 	/* read existing pid file */
2454 	if ((fd = open(pid_file, O_RDONLY)) >= 0) {
2455 
2456 		result = read(fd, pbuf, (sizeof pbuf) - 1);
2457 		close(fd);
2458 
2459 		if (result > 0) {
2460 			pbuf[result] = '\x0';
2461 			pid = (pid_t) atoi(pbuf);
2462 
2463 			/* if previous process is no longer running running, remove the old pid file */
2464 			if (pid && (pid == getpid() || kill(pid, 0) < 0))
2465 				unlink(pid_file);
2466 
2467 			else {
2468 				/* previous process is still running */
2469 				logit(LOG_ERR, "There's already an NRPE server running (PID %lu).  Bailing out...", (unsigned long)pid);
2470 				return ERROR;
2471 			}
2472 		}
2473 	}
2474 
2475 	/* write new pid file */
2476 	if ((fd = open(pid_file, O_WRONLY | O_CREAT, 0644)) >= 0) {
2477 		sprintf(pbuf, "%d\n", (int)getpid());
2478 
2479 		if (write(fd, pbuf, strlen(pbuf)) == -1)
2480 			logit(LOG_ERR, "ERROR: write_pid_file() write(fd, pbuf) failed...");
2481 
2482 		close(fd);
2483 		wrote_pid_file = TRUE;
2484 	} else {
2485 		logit(LOG_ERR, "Cannot write to pidfile '%s' - check your privileges.", pid_file);
2486 		return ERROR;
2487 	}
2488 
2489 	return OK;
2490 }
2491 
2492 /* remove pid file */
2493 int remove_pid_file(void)
2494 {
2495 	if (pid_file == NULL)
2496 		return OK;				/* no pid file was specified */
2497 	if (wrote_pid_file == FALSE)
2498 		return OK;				/* pid file was not written */
2499 
2500 	/* get root back so we can delete the pid file */
2501 	if (SETEUID(0) == -1 && debug)
2502 		logit(LOG_WARNING, "WARNING: remove_pid_file() seteuid(0): %s", strerror(errno));
2503 
2504 	if (unlink(pid_file) == -1) {
2505 		logit(LOG_ERR, "Cannot remove pidfile '%s' - check your privileges.", pid_file);
2506 		return ERROR;
2507 	}
2508 
2509 	return OK;
2510 }
2511 
2512 #ifdef HAVE_SSL
2513 
2514 void my_disconnect_sighandler(int sig)
2515 {
2516 	logit(LOG_ERR, "SSL_shutdown() has taken too long to complete. Exiting now..");
2517 	exit(STATE_CRITICAL);
2518 }
2519 
2520 void complete_SSL_shutdown(SSL * ssl)
2521 {
2522 	/* Thanks to Jari Takkala (jtakkala@gmail.com) for the following information.
2523 
2524 	   We need to call SSL_shutdown() at least twice, otherwise we'll
2525 	   be left with data in the socket receive buffer, and the
2526 	   subsequent process termination will cause TCP RST's to be sent
2527 	   to the client.
2528 
2529 	   See http://bugs.ruby-lang.org/projects/ruby-trunk/repository/revisions/32219/diff
2530 	   for more information.
2531 	 */
2532 
2533 	int       x;
2534 
2535 	/* set disconnection handler */
2536 	signal(SIGALRM, my_disconnect_sighandler);
2537 	alarm(ssl_shutdown_timeout);
2538 
2539 	for (x = 0; x < 4; x++) {
2540 		if (SSL_shutdown(ssl))
2541 			break;
2542 	}
2543 
2544 	alarm(0);
2545 }
2546 #endif	 /*HAVE_SSL */
2547 
2548 /* bail if daemon is running as root */
2549 int check_privileges(void)
2550 {
2551 	uid_t     uid = geteuid();
2552 	gid_t     gid = getegid();
2553 
2554 	if (uid == 0 || gid == 0) {
2555 		logit(LOG_ERR, "Error: NRPE daemon cannot be run as user/group root!");
2556 		exit(STATE_CRITICAL);
2557 	}
2558 
2559 	return OK;
2560 }
2561 
2562 /* handle signals (parent process) */
2563 void sighandler(int sig)
2564 {
2565 	static char *sigs[] = {
2566 		"EXIT", "HUP", "INT", "QUIT", "ILL", "TRAP", "ABRT", "BUS", "FPE",
2567 		"KILL", "USR1", "SEGV", "USR2", "PIPE", "ALRM", "TERM", "STKFLT",
2568 		"CHLD", "CONT", "STOP", "TSTP", "TTIN", "TTOU", "URG", "XCPU",
2569 		"XFSZ", "VTALRM", "PROF", "WINCH", "IO", "PWR", "UNUSED", "ZERR",
2570 		"DEBUG", (char *)NULL
2571 	};
2572 	int       i;
2573 
2574 	if (sig < 0)
2575 		sig = -sig;
2576 
2577 	for (i = 0; sigs[i] != (char *)NULL; i++) ;
2578 	sig %= i;
2579 
2580 	/* we received a SIGHUP, so restart... */
2581 	if (sig == SIGHUP) {
2582 		sigrestart = TRUE;
2583 		logit(LOG_NOTICE, "Caught SIGHUP - restarting...\n");
2584 	}
2585 
2586 	/* else begin shutting down... */
2587 	if (sig == SIGTERM) {
2588 		/* if shutdown is already true, we're in a signal trap loop! */
2589 		if (sigshutdown == TRUE)
2590 			exit(STATE_CRITICAL);
2591 		sigshutdown = TRUE;
2592 		logit(LOG_NOTICE, "Caught SIG%s - shutting down...\n", sigs[sig]);
2593 	}
2594 
2595 	return;
2596 }
2597 
2598 /* handle signals (child processes) */
2599 void child_sighandler(int sig)
2600 {
2601 	exit(0);					/* terminate */
2602 }
2603 
2604 /* tests whether or not a client request is valid */
2605 int validate_request(v2_packet * v2pkt, v3_packet * v3pkt)
2606 {
2607 	u_int32_t	packet_crc32;
2608 	u_int32_t	calculated_crc32;
2609 	char		*buff, *ptr;
2610 	int			rc;
2611 #ifdef ENABLE_COMMAND_ARGUMENTS
2612 	int			x;
2613 #endif
2614 
2615 	/* check the crc 32 value */
2616 	if (packet_ver == NRPE_PACKET_VERSION_3) {
2617 		int32_t   pkt_size = (sizeof(v3_packet) - 1) + ntohl(v3pkt->buffer_length);
2618 		packet_crc32 = ntohl(v3pkt->crc32_value);
2619 		v3pkt->crc32_value = 0L;
2620 		v3pkt->alignment = 0;
2621 		calculated_crc32 = calculate_crc32((char *)v3pkt, pkt_size);
2622 	} else {
2623 		packet_crc32 = ntohl(v2pkt->crc32_value);
2624 		v2pkt->crc32_value = 0L;
2625 		calculated_crc32 = calculate_crc32((char *)v2pkt, sizeof(v2_packet));
2626 	}
2627 
2628 	if (packet_crc32 != calculated_crc32) {
2629 		logit(LOG_ERR, "Error: Request packet had invalid CRC32.");
2630 		return ERROR;
2631 	}
2632 
2633 	/* make sure this is the right type of packet */
2634 	if (ntohs(v2pkt->packet_type) != QUERY_PACKET) {
2635 		logit(LOG_ERR, "Error: Request packet type was invalid!");
2636 		return ERROR;
2637 	}
2638 
2639 	/* make sure buffer is terminated */
2640 	if (packet_ver == NRPE_PACKET_VERSION_3) {
2641 		int32_t   l = ntohs(v3pkt->buffer_length);
2642 		v3pkt->buffer[l - 1] = '\x0';
2643 		buff = v3pkt->buffer;
2644 	} else {
2645 		v2pkt->buffer[MAX_PACKETBUFFER_LENGTH - 1] = '\x0';
2646 		buff = v2pkt->buffer;
2647 	}
2648 
2649 	/* client must send some kind of request */
2650 	if (buff[0] == '\0') {
2651 		logit(LOG_ERR, "Error: Request contained no query!");
2652 		return ERROR;
2653 	}
2654 
2655 	/* make sure request doesn't contain nasties */
2656 	if (packet_ver == NRPE_PACKET_VERSION_3)
2657 		rc = contains_nasty_metachars(v3pkt->buffer);
2658 	else
2659 		rc = contains_nasty_metachars(v2pkt->buffer);
2660 	if (rc == TRUE) {
2661 		logit(LOG_ERR, "Error: Request contained illegal metachars!");
2662 		return ERROR;
2663 	}
2664 
2665 	/* make sure the request doesn't contain arguments */
2666 	if (strchr(v2pkt->buffer, '!')) {
2667 #ifdef ENABLE_COMMAND_ARGUMENTS
2668 		if (allow_arguments == FALSE) {
2669 			logit(LOG_ERR, "Error: Request contained command arguments, but argument option is not enabled!");
2670 			return ERROR;
2671 		}
2672 #else
2673 		logit(LOG_ERR, "Error: Request contained command arguments!");
2674 		return ERROR;
2675 #endif
2676 	}
2677 
2678 	/* get command name */
2679 #ifdef ENABLE_COMMAND_ARGUMENTS
2680 	ptr = strtok(buff, "!");
2681 #else
2682 	ptr = buff;
2683 #endif
2684 	command_name = strdup(ptr);
2685 	if (command_name == NULL) {
2686 		logit(LOG_ERR, "Error: Memory allocation failed");
2687 		return ERROR;
2688 	}
2689 #ifdef ENABLE_COMMAND_ARGUMENTS
2690 	/* get command arguments */
2691 	if (allow_arguments == TRUE) {
2692 
2693 		for (x = 0; x < MAX_COMMAND_ARGUMENTS; x++) {
2694 			ptr = strtok(NULL, "!");
2695 			if (ptr == NULL)
2696 				break;
2697 			macro_argv[x] = strdup(ptr);
2698 			if (macro_argv[x] == NULL) {
2699 				logit(LOG_ERR, "Error: Memory allocation failed");
2700 				return ERROR;
2701 			}
2702 			if (!strcmp(macro_argv[x], "")) {
2703 				logit(LOG_ERR, "Error: Request contained an empty command argument");
2704 				return ERROR;
2705 			}
2706 			if (strstr(macro_argv[x], "$(")) {
2707 # ifndef ENABLE_BASH_COMMAND_SUBSTITUTION
2708 				logit(LOG_ERR, "Error: Request contained a bash command substitution!");
2709 				return ERROR;
2710 # else
2711 				if (FALSE == allow_bash_cmd_subst) {
2712 					logit(LOG_ERR, "Error: Request contained a bash command substitution, but they are disallowed!");
2713 					return ERROR;
2714 				}
2715 # endif
2716 			}
2717 		}
2718 	}
2719 #endif
2720 	return OK;
2721 }
2722 
2723 /* tests whether a buffer contains illegal metachars */
2724 int contains_nasty_metachars(char *str)
2725 {
2726 	int       result;
2727 
2728 	if (str == NULL)
2729 		return FALSE;
2730 
2731 	result = strcspn(str, nasty_metachars);
2732 	if (result != strlen(str))
2733 		return TRUE;
2734 
2735 	return FALSE;
2736 }
2737 
2738 /* replace macros in buffer */
2739 int process_macros(char *input_buffer, char *output_buffer, int buffer_length)
2740 {
2741 	char     *temp_buffer;
2742 	int       in_macro;
2743 	int       arg_index = 0;
2744 	char     *selected_macro = NULL;
2745 
2746 	strcpy(output_buffer, "");
2747 
2748 	in_macro = FALSE;
2749 
2750 	for (temp_buffer = my_strsep(&input_buffer, "$"); temp_buffer != NULL;
2751 		 temp_buffer = my_strsep(&input_buffer, "$")) {
2752 
2753 		selected_macro = NULL;
2754 
2755 		if (in_macro == FALSE) {
2756 			if (strlen(output_buffer) + strlen(temp_buffer) < buffer_length - 1) {
2757 				strncat(output_buffer, temp_buffer, buffer_length - strlen(output_buffer) - 1);
2758 				output_buffer[buffer_length - 1] = '\x0';
2759 			}
2760 			in_macro = TRUE;
2761 
2762 		} else {
2763 
2764 			if (strlen(output_buffer) + strlen(temp_buffer) < buffer_length - 1) {
2765 
2766 				/* argument macro */
2767 				if (strstr(temp_buffer, "ARG") == temp_buffer) {
2768 					arg_index = atoi(temp_buffer + 3);
2769 					if (arg_index >= 1 && arg_index <= MAX_COMMAND_ARGUMENTS)
2770 						selected_macro = macro_argv[arg_index - 1];
2771 
2772 				} else if (!strcmp(temp_buffer, "")) {
2773 					/* an escaped $ is done by specifying two $$ next to each other */
2774 					strncat(output_buffer, "$", buffer_length - strlen(output_buffer) - 1);
2775 
2776 				} else {
2777 					/* a non-macro, just some user-defined string between two $s */
2778 					strncat(output_buffer, "$", buffer_length - strlen(output_buffer) - 1);
2779 					output_buffer[buffer_length - 1] = '\x0';
2780 					strncat(output_buffer, temp_buffer,
2781 							buffer_length - strlen(output_buffer) - 1);
2782 					output_buffer[buffer_length - 1] = '\x0';
2783 					strncat(output_buffer, "$", buffer_length - strlen(output_buffer) - 1);
2784 				}
2785 
2786 
2787 				/* insert macro */
2788 				if (selected_macro != NULL)
2789 					strncat(output_buffer, (selected_macro == NULL) ? "" : selected_macro,
2790 							buffer_length - strlen(output_buffer) - 1);
2791 
2792 				output_buffer[buffer_length - 1] = '\x0';
2793 			}
2794 
2795 			in_macro = FALSE;
2796 		}
2797 	}
2798 
2799 	return OK;
2800 }
2801 
2802 /* process command line arguments */
2803 int process_arguments(int argc, char **argv)
2804 {
2805 	char      optchars[MAX_INPUT_BUFFER];
2806 	int       c = 1;
2807 	int       have_mode = FALSE;
2808 #ifdef HAVE_GETOPT_LONG
2809 	int       option_index = 0;
2810 	static struct option long_options[] = {
2811 		{"config", required_argument, 0, 'c'},
2812 		{"inetd", no_argument, 0, 'i'},
2813 		/* To compatibility between short and long options but not used on AIX */
2814 		{"src", no_argument, 0, 's'},
2815 		{"no-forking", no_argument, 0, 'f'},
2816 		{"4", no_argument, 0, '4'},
2817 		{"ipv6", no_argument, 0, '6'},
2818 		{"daemon", no_argument, 0, 'd'},
2819 		{"no-ssl", no_argument, 0, 'n'},
2820 		{"help", no_argument, 0, 'h'},
2821 		{"license", no_argument, 0, 'l'},
2822 		{"version", no_argument, 0, 'V'},
2823 		{0, 0, 0, 0}
2824 	};
2825 #endif
2826 
2827 	/* no options were supplied */
2828 	if (argc < 2)
2829 		return ERROR;
2830 
2831 	snprintf(optchars, MAX_INPUT_BUFFER, "c:hVldi46nsf");
2832 
2833 	while (1) {
2834 #ifdef HAVE_GETOPT_LONG
2835 		c = getopt_long(argc, argv, optchars, long_options, &option_index);
2836 #else
2837 		c = getopt(argc, argv, optchars);
2838 #endif
2839 		if (c == -1 || c == EOF)
2840 			break;
2841 
2842 		/* process all arguments */
2843 		switch (c) {
2844 
2845 		case '?':
2846 		case 'h':
2847 			show_help = TRUE;
2848 			break;
2849 
2850 		case 'V':
2851 			show_version = TRUE;
2852 			have_mode = TRUE;
2853 			break;
2854 
2855 		case 'l':
2856 			show_license = TRUE;
2857 			break;
2858 
2859 		case 'c':
2860 			strncpy(config_file, optarg, sizeof(config_file));
2861 			config_file[sizeof(config_file) - 1] = '\x0';
2862 			break;
2863 
2864 		case 'd':
2865 			use_inetd = FALSE;
2866 			have_mode = TRUE;
2867 			break;
2868 
2869 		case 'i':
2870 			use_inetd = TRUE;
2871 			have_mode = TRUE;
2872 			break;
2873 
2874 		case '4':
2875 			address_family = AF_INET;
2876 			break;
2877 
2878 		case '6':
2879 			address_family = AF_INET6;
2880 			break;
2881 
2882 		case 'n':
2883 			use_ssl = FALSE;
2884 			break;
2885 
2886 		case 's':				/* Argument s to indicate SRC option */
2887 			use_src = TRUE;
2888 			have_mode = TRUE;
2889 			break;
2890 
2891 		case 'f':
2892 			use_inetd = FALSE;
2893 			no_forking = TRUE;
2894 			have_mode = TRUE;
2895 			break;
2896 
2897 		default:
2898 			return ERROR;
2899 		}
2900 	}
2901 
2902 	/* bail if we didn't get required args */
2903 	if (have_mode == FALSE)
2904 		return ERROR;
2905 
2906 	return OK;
2907 }
2908