Exemple #1
0
static void
process_command_line_args (int argc, char *const *argv)
{
  int ch = -1;

  while (-1 != (ch = getopt (argc, argv, "rf:vVh")))
    {
      switch (ch)
        {
        case 'r':
          /* FIXME: implement read-only option */
          break;
        case 'f':
          set_contacts_file ();
          break;
        case 'v':
          display_version ();
          exit (0);
          break;
        case 'V':
          display_license ();
          exit (0);
          break;
        case 'h':
        case '?':
        default:
          display_usage (argv[0]);
          exit (0);
        }
    }
}
Exemple #2
0
void
button_released_cb (GtkButton *button, gpointer user_data) {

    if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(about_radiobutton)) == TRUE) {

        display_about();
        about_counter = 0;

    } else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(help_radiobutton)) == TRUE) {

        display_help();
        about_counter = 1;

    } else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(license_radiobutton)) == TRUE) {

        display_license();
        about_counter = 2;

    }
}
Exemple #3
0
static void
button_released_cb (GtkButton *button, GUI *appGUI)
{
	if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (appGUI->about_radiobutton)) == TRUE) {

		display_about (appGUI);
		appGUI->about_counter = 0;

	} else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (appGUI->help_radiobutton)) == TRUE) {

		display_help (appGUI);
		appGUI->about_counter = 1;

	} else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (appGUI->license_radiobutton)) == TRUE) {

		display_license (appGUI);
		appGUI->about_counter = 2;

	}
}
Exemple #4
0
int
main(int argc, char **argv)
{
	const char *progname = getprogname();
#ifndef SMALL
	char *gzip;
	int len;
#endif
	int ch;

#ifndef SMALL
	if ((gzip = getenv("GZIP")) != NULL)
		prepend_gzip(gzip, &argc, &argv);
	signal(SIGINT, sigint_handler);
#endif

	/*
	 * XXX
	 * handle being called `gunzip', `zcat' and `gzcat'
	 */
	if (strcmp(progname, "gunzip") == 0)
		dflag = 1;
	else if (strcmp(progname, "zcat") == 0 ||
		 strcmp(progname, "gzcat") == 0)
		dflag = cflag = 1;

#ifdef SMALL
#define OPT_LIST "123456789cdhlV"
#else
#define OPT_LIST "123456789acdfhklLNnqrS:tVv"
#endif

	while ((ch = getopt_long(argc, argv, OPT_LIST, longopts, NULL)) != -1) {
		switch (ch) {
		case '1': case '2': case '3':
		case '4': case '5': case '6':
		case '7': case '8': case '9':
			numflag = ch - '0';
			break;
		case 'c':
			cflag = 1;
			break;
		case 'd':
			dflag = 1;
			break;
		case 'l':
			lflag = 1;
			dflag = 1;
			break;
		case 'V':
			display_version();
			/* NOTREACHED */
#ifndef SMALL
		case 'a':
			fprintf(stderr, "%s: option --ascii ignored on this system\n", progname);
			break;
		case 'f':
			fflag = 1;
			break;
		case 'k':
			kflag = 1;
			break;
		case 'L':
			display_license();
			/* NOT REACHED */
		case 'N':
			nflag = 0;
			Nflag = 1;
			break;
		case 'n':
			nflag = 1;
			Nflag = 0;
			break;
		case 'q':
			qflag = 1;
			break;
		case 'r':
			rflag = 1;
			break;
		case 'S':
			len = strlen(optarg);
			if (len != 0) {
				if (len > SUFFIX_MAXLEN)
					errx(1, "incorrect suffix: '%s': too long", optarg);
				suffixes[0].zipped = optarg;
				suffixes[0].ziplen = len;
			} else {
				suffixes[NUM_SUFFIXES - 1].zipped = "";
				suffixes[NUM_SUFFIXES - 1].ziplen = 0;
			}
			break;
		case 't':
			cflag = 1;
			tflag = 1;
			dflag = 1;
			break;
		case 'v':
			vflag = 1;
			break;
#endif
		default:
			usage();
			/* NOTREACHED */
		}
	}
	argv += optind;
	argc -= optind;

	if (argc == 0) {
		if (dflag)	/* stdin mode */
			handle_stdin();
		else		/* stdout mode */
			handle_stdout();
	} else {
		do {
			handle_pathname(argv[0]);
		} while (*++argv);
	}
#ifndef SMALL
	if (qflag == 0 && lflag && argc > 1)
		print_list(-1, 0, "(totals)", 0);
#endif
	exit(exit_value);
}
Exemple #5
0
int main(int argc, char **argv){
	int result=OK;
	int x;
	char buffer[MAX_INPUT_BUFFER];
	char *env_string=NULL;
#ifdef HAVE_SSL
	DH *dh;
	char seedfile[FILENAME_MAX];
	int i,c;
#endif

	/* set some environment variables */
	asprintf(&env_string,"NRPE_MULTILINESUPPORT=1");
	putenv(env_string);
	asprintf(&env_string,"NRPE_PROGRAMVERSION=%s",PROGRAM_VERSION);
	putenv(env_string);

	/* process command-line args */
	result=process_arguments(argc,argv);

        if(result!=OK || show_help==TRUE || show_license==TRUE || show_version==TRUE){

		printf("\n");
		printf("NRPE - Nagios Remote Plugin Executor\n");
		printf("Copyright (c) 1999-2008 Ethan Galstad ([email protected])\n");
		printf("Version: %s\n",PROGRAM_VERSION);
		printf("Last Modified: %s\n",MODIFICATION_DATE);
		printf("License: GPL v2 with exemptions (-l for more info)\n");
#ifdef HAVE_SSL
		printf("SSL/TLS Available: Anonymous DH Mode, OpenSSL 0.9.6 or higher required\n");
#endif
#ifdef HAVE_LIBWRAP
		printf("TCP Wrappers Available\n");
#endif
		printf("\n");
#ifdef ENABLE_COMMAND_ARGUMENTS
		printf("***************************************************************\n");
		printf("** POSSIBLE SECURITY RISK - COMMAND ARGUMENTS ARE SUPPORTED! **\n");
		printf("**      Read the NRPE SECURITY file for more information     **\n");
		printf("***************************************************************\n");
		printf("\n");
#endif
#ifndef HAVE_LIBWRAP
		printf("***************************************************************\n");
		printf("** POSSIBLE SECURITY RISK - TCP WRAPPERS ARE NOT AVAILABLE!  **\n");
		printf("**      Read the NRPE SECURITY file for more information     **\n");
		printf("***************************************************************\n");
		printf("\n");
#endif
	        }

	if(show_license==TRUE)
		display_license();

	else if(result!=OK || show_help==TRUE){

		printf("Usage: nrpe [-n] -c <config_file> <mode>\n");
		printf("\n");
		printf("Options:\n");
		printf(" -n            = Do not use SSL\n");
		printf(" <config_file> = Name of config file to use\n");
		printf(" <mode>        = One of the following two operating modes:\n");  
		printf("   -i          =    Run as a service under inetd or xinetd\n");
		printf("   -d          =    Run as a standalone daemon\n");
		printf("\n");
		printf("Notes:\n");
		printf("This program is designed to process requests from the check_nrpe\n");
		printf("plugin on the host(s) running Nagios.  It can run as a service\n");
		printf("under inetd or xinetd (read the docs for info on this), or as a\n");
		printf("standalone daemon. Once a request is received from an authorized\n");
		printf("host, NRPE will execute the command/plugin (as defined in the\n");
		printf("config file) and return the plugin output and return code to the\n");
		printf("check_nrpe plugin.\n");
		printf("\n");
		}

        if(result!=OK || show_help==TRUE || show_license==TRUE || show_version==TRUE)
		exit(STATE_UNKNOWN);


	/* open a connection to the syslog facility */
	/* facility name may be overridden later */
	get_log_facility(NRPE_LOG_FACILITY);
        openlog("nrpe",LOG_PID,log_facility); 

	/* make sure the config file uses an absolute path */
	if(config_file[0]!='/'){

		/* save the name of the config file */
		strncpy(buffer,config_file,sizeof(buffer));
		buffer[sizeof(buffer)-1]='\x0';

		/* get absolute path of current working directory */
		strcpy(config_file,"");
		getcwd(config_file,sizeof(config_file));

		/* append a forward slash */
		strncat(config_file,"/",sizeof(config_file)-2);
		config_file[sizeof(config_file)-1]='\x0';

		/* append the config file to the path */
		strncat(config_file,buffer,sizeof(config_file)-strlen(config_file)-1);
		config_file[sizeof(config_file)-1]='\x0';
	        }

	/* read the config file */
	result=read_config_file(config_file);	

	/* exit if there are errors... */
	if(result==ERROR){
		syslog(LOG_ERR,"Config file '%s' contained errors, aborting...",config_file);
		return STATE_CRITICAL;
		}

        /* generate the CRC 32 table */
        generate_crc32_table();

	/* initialize macros */
	for(x=0;x<MAX_COMMAND_ARGUMENTS;x++)
		macro_argv[x]=NULL;

#ifdef HAVE_SSL
	/* initialize SSL */
	if(use_ssl==TRUE){
		SSL_library_init();
		SSLeay_add_ssl_algorithms();
		meth=SSLv23_server_method();
		SSL_load_error_strings();

		/* use week random seed if necessary */
		if(allow_weak_random_seed && (RAND_status()==0)){

			if(RAND_file_name(seedfile,sizeof(seedfile)-1))
				if(RAND_load_file(seedfile,-1))
					RAND_write_file(seedfile);

			if(RAND_status()==0){
				syslog(LOG_ERR,"Warning: SSL/TLS uses a weak random seed which is highly discouraged");
				srand(time(NULL));
				for(i=0;i<500 && RAND_status()==0;i++){
					for(c=0;c<sizeof(seedfile);c+=sizeof(int)){
						*((int *)(seedfile+c))=rand();
					        }
					RAND_seed(seedfile,sizeof(seedfile));
					}
				}
			}

		if((ctx=SSL_CTX_new(meth))==NULL){
			syslog(LOG_ERR,"Error: could not create SSL context.\n");
			exit(STATE_CRITICAL);
		        }

		/* ADDED 01/19/2004 */
		/* use only TLSv1 protocol */
		SSL_CTX_set_options(ctx,SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);

		/* use anonymous DH ciphers */
		SSL_CTX_set_cipher_list(ctx,"ADH");
		dh=get_dh512();
		SSL_CTX_set_tmp_dh(ctx,dh);
		DH_free(dh);
		if(debug==TRUE)
			syslog(LOG_INFO,"INFO: SSL/TLS initialized. All network traffic will be encrypted.");
	        }
	else{
		if(debug==TRUE)
			syslog(LOG_INFO,"INFO: SSL/TLS NOT initialized. Network encryption DISABLED.");
	        }
#endif

	/* if we're running under inetd... */
	if(use_inetd==TRUE){

		/* make sure we're not root */
		check_privileges();

		/* redirect STDERR to /dev/null */
		close(2);
		open("/dev/null",O_WRONLY);

		/* handle the connection */
		handle_connection(0);
	        }

	/* else daemonize and start listening for requests... */
	else if(fork()==0){
		
		/* we're a daemon - set up a new process group */
		setsid();

		/* close standard file descriptors */
		close(0);
		close(1);
		close(2);

		/* redirect standard descriptors to /dev/null */
		open("/dev/null",O_RDONLY);
		open("/dev/null",O_WRONLY);
		open("/dev/null",O_WRONLY);

		chdir("/");
		/*umask(0);*/

		/* handle signals */
		signal(SIGQUIT,sighandler);
		signal(SIGTERM,sighandler);
		signal(SIGHUP,sighandler);

		/* log info to syslog facility */
		syslog(LOG_NOTICE,"Starting up daemon");

		/* write pid file */
		if(write_pid_file()==ERROR)
			return STATE_CRITICAL;
		
		/* drop privileges */
		drop_privileges(nrpe_user,nrpe_group);

		/* make sure we're not root */
		check_privileges();

		do{

			/* reset flags */
			sigrestart=FALSE;
			sigshutdown=FALSE;

			/* wait for connections */
			wait_for_connections();

			/* free all memory we allocated */
			free_memory();

			if(sigrestart==TRUE){

				/* read the config file */
				result=read_config_file(config_file);	

				/* exit if there are errors... */
				if(result==ERROR){
					syslog(LOG_ERR,"Config file '%s' contained errors, bailing out...",config_file);
					return STATE_CRITICAL;
				        }
			        }
	
		        }while(sigrestart==TRUE && sigshutdown==FALSE);

		/* remove pid file */
		remove_pid_file();

		syslog(LOG_NOTICE,"Daemon shutdown\n");
	        }

#ifdef HAVE_SSL
	if(use_ssl==TRUE)
		SSL_CTX_free(ctx);
#endif

	/* We are now running in daemon mode, or the connection handed over by inetd has
	   been completed, so the parent process exits */
        return STATE_OK;
	}
Exemple #6
0
int main(int argc, char **argv){
	int result=OK;
	int x;
	char buffer[MAX_INPUT_BUFFER];
#ifdef HAVE_SSL
	DH *dh;
#endif

	result=process_arguments(argc,argv);

        if(result!=OK || show_help==TRUE || show_license==TRUE || show_version==TRUE){

		printf("\n");
		printf("NRPE - Nagios Remote Plugin Executor\n");
		printf("Copyright (c) 1999-2003 Ethan Galstad ([email protected])\n");
		printf("Version: %s\n",PROGRAM_VERSION);
		printf("Last Modified: %s\n",MODIFICATION_DATE);
		printf("License: GPL with exemptions (-l for more info)\n");
#ifdef HAVE_SSL
		printf("SSL/TLS Available: Anonymous DH Mode, OpenSSL 0.9.6 or higher required\n");
#endif
		printf("\n");
#ifdef ENABLE_COMMAND_ARGUMENTS
		printf("***************************************************************\n");
		printf("** POSSIBLE SECURITY RISK - COMMAND ARGUMENTS ARE SUPPORTED! **\n");
		printf("**      Read the NRPE SECURITY file for more information     **\n");
		printf("***************************************************************\n");
		printf("\n");
#endif
	        }

	if(show_license==TRUE)
		display_license();

	else if(result!=OK || show_help==TRUE){

		printf("Usage: nrpe -c <config_file> <mode>\n");
		printf("\n");
		printf("Options:\n");
		printf(" <config_file> = Name of config file to use\n");
		printf(" <mode>        = One of the following two operating modes:\n");  
		printf("   -i          =    Run as a service under inetd or xinetd\n");
		printf("   -d          =    Run as a standalone daemon\n");
		printf("\n");
		printf("Notes:\n");
		printf("This program is designed to process requests from the check_nrpe\n");
		printf("plugin on the host(s) running Nagios.  It can run as a service\n");
		printf("under inetd or xinetd (read the docs for info on this), or as a\n");
		printf("standalone daemon. Once a request is received from an authorized\n");
		printf("host, NRPE will execute the command/plugin (as defined in the\n");
		printf("config file) and return the plugin output and return code to the\n");
		printf("check_nrpe plugin.\n");
		printf("\n");
		}

        if(result!=OK || show_help==TRUE || show_license==TRUE || show_version==TRUE)
		exit(STATE_UNKNOWN);


	/* open a connection to the syslog facility */
        openlog("nrpe",LOG_PID,LOG_DAEMON); 

	/* read the config file */
	result=read_config_file(config_file);	

	/* exit if there are errors... */
	if(result==ERROR){
		syslog(LOG_ERR,"Config file '%s' contained errors, bailing out...",config_file);
		return STATE_CRITICAL;
		}

	/* initialize macros */
	for(x=0;x<MAX_COMMAND_ARGUMENTS;x++)
		macro_argv[x]=NULL;

        /* generate the CRC 32 table */
        generate_crc32_table();

#ifdef HAVE_SSL
	/* initialize SSL */
	if(use_ssl==TRUE){
		SSL_library_init();
		SSLeay_add_ssl_algorithms();
		meth=SSLv23_server_method();
		SSL_load_error_strings();
		if((ctx=SSL_CTX_new(meth))==NULL){
			syslog(LOG_ERR,"Error: could not create SSL context.\n");
			exit(STATE_CRITICAL);
		        }
		/*SSL_CTX_set_cipher_list(ctx,"ALL");*/
		SSL_CTX_set_cipher_list(ctx,"ADH");
		dh=get_dh512();
		SSL_CTX_set_tmp_dh(ctx,dh);
		DH_free(dh);
		if(debug==TRUE)
			syslog(LOG_INFO,"INFO: SSL/TLS initialized. All network traffic will be encrypted.");
	        }
	else{
		if(debug==TRUE)
			syslog(LOG_INFO,"INFO: SSL/TLS NOT initialized. Network encryption DISABLED.");
	        }
#endif

	/* wait for connections */
	wait_for_connections();

#ifdef HAVE_SSL
	if(use_ssl==TRUE)
		SSL_CTX_free(ctx);
#endif

	/* We are now running in daemon mode, or the connection handed over by inetd has
	   been completed, so the parent process exits */
        return STATE_OK;
	}
int main(int argc, char **argv) {
	int sd;
	int rc;
	int result;
	data_packet send_packet;
	int bytes_to_send;
	char input[MAX_INPUT_BUFFER];
	char input_buffer[MAX_INPUT_BUFFER];
	char *temp_ptr;
	char host_name[MAX_HOSTNAME_LENGTH];
	char svc_description[MAX_DESCRIPTION_LENGTH];
	char plugin_output[MAX_PLUGINOUTPUT_LENGTH];
	int total_packets = 0;
	int16_t return_code;
	u_int32_t calculated_crc32;
	char *inputptr, *ptr1, *ptr2, *ptr3, *ptr4;


	/* process command-line arguments */
	result = process_arguments(argc, argv);

	if (result != OK || show_help == TRUE || show_license == TRUE || show_version == TRUE) {

		if (result != OK)
			printf("Incorrect command line arguments supplied\n");
		printf("\n");
		printf("NSCA Client %s\n", PROGRAM_VERSION);
		printf("Copyright (c) 2010-2012 Icinga Development Team and Community Contributors (http://www.icinga.org)\n");
		printf("Copyright (c) 2000-2007 Ethan Galstad (www.nagios.org)\n");
		printf("Last Modified: %s\n", MODIFICATION_DATE);
		printf("License: GPL v2\n");
		printf("Encryption Routines: ");
#ifdef HAVE_LIBMCRYPT
		printf("AVAILABLE");
#else
		printf("NOT AVAILABLE");
#endif
		printf("\n");
		printf("\n");
	}

	if (result != OK || show_help == TRUE) {
		printf("Usage: %s -H <host_address> [-p port] [-to to_sec] [-d delim] [-c config_file]\n", argv[0]);
		printf("\n");
		printf("Options:\n");
		printf(" <host_address> = The IP address of the host running the NSCA daemon\n");
		printf(" [port]         = The port on which the daemon is running - default is %s\n", DEFAULT_SERVER_PORT);
		printf(" [to_sec]       = Number of seconds before connection attempt times out.\n");
		printf("                  (default timeout is %d seconds)\n", DEFAULT_SOCKET_TIMEOUT);
		printf(" [delim]        = Delimiter to use when parsing input (defaults to a tab)\n");
		printf(" [config_file]  = Name of config file to use\n");
		printf("\n");
		printf("Note:\n");
		printf("This utility is used to send passive check results to the NSCA daemon.  Host and\n");
		printf("Service check data that is to be sent to the NSCA daemon is read from standard\n");
		printf("input. Input should be provided in the following format (tab-delimited unless\n");
		printf("overriden with -d command line argument, one entry per line):\n");
		printf("\n");
		printf("Service Checks:\n");
		printf("<host_name>[tab]<svc_description>[tab]<return_code>[tab]<plugin_output>[newline]\n\n");
		printf("Host Checks:\n");
		printf("<host_name>[tab]<return_code>[tab]<plugin_output>[newline]\n\n");
		printf("When submitting multiple simultaneous results, separate each set with the ETB\n");
		printf("character (^W or 0x17)\n");
		printf("\n");
	}

	if (show_license == TRUE)
		display_license();

	if (result != OK || show_help == TRUE || show_license == TRUE || show_version == TRUE)
		do_exit(STATE_UNKNOWN);



	/* read the config file */
	result = read_config_file(config_file);

	/* exit if there are errors... */
	if (result == ERROR) {
		printf("Error: Config file '%s' contained errors...\n", config_file);
		do_exit(STATE_CRITICAL);
	}

	/* generate the CRC 32 table */
	generate_crc32_table();

	/* initialize alarm signal handling */
	signal(SIGALRM, alarm_handler);

	/* set socket timeout */
	alarm(socket_timeout);

	time(&start_time);

	/* try to connect to the host at the given port number */
	result = my_tcp_connect(server_name, server_port, &sd);

	/* we couldn't connect */
	if (result != STATE_OK) {
		printf("Error: Could not connect to host %s on port %s\n", server_name, server_port);
		do_exit(STATE_CRITICAL);
	}

#ifdef DEBUG
	printf("Connected okay...\n");
#endif

	/* read the initialization packet containing the IV and timestamp */
	result = read_init_packet(sd);
	if (result != OK) {
		printf("Error: Could not read init packet from server\n");
		close(sd);
		do_exit(STATE_CRITICAL);
	}

#ifdef DEBUG
	printf("Got init packet from server\n");
#endif

	/* initialize encryption/decryption routines with the IV we received from the server */
	if (encrypt_init(password, encryption_method, received_iv, &CI) != OK) {
		printf("Error: Failed to initialize encryption libraries for method %d\n", encryption_method);
		close(sd);
		do_exit(STATE_CRITICAL);
	}

#ifdef DEBUG
	printf("Initialized encryption routines\n");
#endif


	/**** WE'RE CONNECTED AND READY TO SEND ****/

	/* read all data from STDIN until there isn't anymore */
	while (!feof(stdin)) {
		int c = getc(stdin);
		if (c == -1) {
			break;
		}
		int pos = 0;
		while (c != 23) {
			if (c == -1) { // in case we don't terminate properly, or are in single-input mode.
				break;
			}
			input_buffer[pos] = c;
			c = getc(stdin);
			pos++;
		}
		input_buffer[pos] = 0;

		strip(input_buffer);

		if (!strcmp(input_buffer, ""))
			continue;

		/* get the host name */
		ptr1 = strtok(input_buffer, delimiter);
		if (ptr1 == NULL)
			continue;

		/* get the service description or return code */
		ptr2 = strtok(NULL, delimiter);
		if (ptr2 == NULL)
			continue;

		/* get the return code or plugin output */
		ptr3 = strtok(NULL, delimiter);
		if (ptr3 == NULL)
			continue;

		/* get the plugin output - if NULL, this is a host check result */
		ptr4 = strtok(NULL, "\x0");

		strncpy(host_name, ptr1, sizeof(host_name) - 1);
		host_name[sizeof(host_name) - 1] = '\x0';
		if (ptr4 == NULL) {
			strcpy(svc_description, "");
			return_code = atoi(ptr2);
			ptr3 = escape_newlines(ptr3);
			strncpy(plugin_output, ptr3, sizeof(plugin_output) - 1);
		} else {
			strncpy(svc_description, ptr2, sizeof(svc_description) - 1);
			return_code = atoi(ptr3);
			ptr4 = escape_newlines(ptr4);
			strncpy(plugin_output, ptr4, sizeof(plugin_output) - 1);
		}
		svc_description[sizeof(svc_description) - 1] = '\x0';
		plugin_output[sizeof(plugin_output) - 1] = '\x0';

		/* increment count of packets we're sending */
		total_packets++;

		/* clear the packet buffer */
		bzero(&send_packet, sizeof(send_packet));

		/* fill the packet with semi-random data */
		randomize_buffer((char *)&send_packet, sizeof(send_packet));

		/* copy the data we want to send into the packet */
		send_packet.packet_version = (int16_t)htons(NSCA_PACKET_VERSION_3);
		send_packet.return_code = (int16_t)htons(return_code);
		strcpy(&send_packet.host_name[0], host_name);
		strcpy(&send_packet.svc_description[0], svc_description);
		strcpy(&send_packet.plugin_output[0], plugin_output);

		/* use timestamp provided by the server */
		send_packet.timestamp = (u_int32_t)htonl(packet_timestamp);

		/* calculate the crc 32 value of the packet */
		send_packet.crc32_value = (u_int32_t)0L;
		calculated_crc32 = calculate_crc32((char *)&send_packet, sizeof(send_packet));
		send_packet.crc32_value = (u_int32_t)htonl(calculated_crc32);

		/* encrypt the packet */
		encrypt_buffer((char *)&send_packet, sizeof(send_packet), password, encryption_method, CI);

		/* send the packet */
		bytes_to_send = sizeof(send_packet);
		rc = sendall(sd, (char *)&send_packet, &bytes_to_send);

		/* there was an error sending the packet */
		if (rc == -1) {
			printf("Error: Could not send data to host\n");
			close(sd);
			do_exit(STATE_UNKNOWN);
		}

		/* for some reason we didn't send all the bytes we were supposed to */
		else if (bytes_to_send < sizeof(send_packet)) {
			printf("Warning: Sent only %d of %d bytes to host\n", rc, sizeof(send_packet));
			close(sd);
			return STATE_UNKNOWN;
		}
	}

#ifdef DEBUG
	printf("Done sending data\n");
#endif

	/* close the connection */
	close(sd);

	printf("%d data packet(s) sent to host successfully.\n", total_packets);

	/* exit cleanly */
	do_exit(STATE_OK);

	/* no compiler complaints here... */
	return STATE_OK;
}
Exemple #8
0
int main(int argc, char **argv){
        u_int32_t packet_crc32;
        u_int32_t calculated_crc32;
	int16_t result;
	int rc;
	packet send_packet;
	packet receive_packet;
	int bytes_to_send;
	int bytes_to_recv;

	result=process_arguments(argc,argv);

        if(result!=OK || show_help==TRUE || show_license==TRUE || show_version==TRUE){

		if(result!=OK)
			printf("Incorrect command line arguments supplied\n");
                printf("\n");
		printf("NRPE Plugin for Nagios\n");
		printf("Copyright (c) 1999-2008 Ethan Galstad ([email protected])\n");
		printf("Version: %s\n",PROGRAM_VERSION);
		printf("Last Modified: %s\n",MODIFICATION_DATE);
		printf("License: GPL v2 with exemptions (-l for more info)\n");
#ifdef HAVE_SSL
		printf("SSL/TLS Available: Anonymous DH Mode, OpenSSL 0.9.6 or higher required\n");
#endif
		printf("\n");
	        }

	if(result!=OK || show_help==TRUE){

		printf("Usage: check_nrpe -H <host> [ -b <bindaddr> ] [-4] [-6] [-n] [-u] [-p <port>] [-t <timeout>] [-c <command>] [-a <arglist...>]\n");
		printf("\n");
		printf("Options:\n");
		printf(" -n         = Do no use SSL\n");
		printf(" -u         = Make socket timeouts return an UNKNOWN state instead of CRITICAL\n");
		printf(" <host>     = The address of the host running the NRPE daemon\n");
		printf(" <bindaddr> = bind to local address\n");
		printf(" -4         = user ipv4 only\n");
		printf(" -6         = user ipv6 only\n");
		printf(" [port]     = The port on which the daemon is running (default=%d)\n",DEFAULT_SERVER_PORT);
		printf(" [timeout]  = Number of seconds before connection times out (default=%d)\n",DEFAULT_SOCKET_TIMEOUT);
		printf(" [command]  = The name of the command that the remote daemon should run\n");
		printf(" [arglist]  = Optional arguments that should be passed to the command.  Multiple\n");
		printf("              arguments should be separated by a space.  If provided, this must be\n");
		printf("              the last option supplied on the command line.\n");
		printf("\n");
		printf("Note:\n");
		printf("This plugin requires that you have the NRPE daemon running on the remote host.\n");
		printf("You must also have configured the daemon to associate a specific plugin command\n");
		printf("with the [command] option you are specifying here.  Upon receipt of the\n");
		printf("[command] argument, the NRPE daemon will run the appropriate plugin command and\n");
		printf("send the plugin output and return code back to *this* plugin.  This allows you\n");
		printf("to execute plugins on remote hosts and 'fake' the results to make Nagios think\n");
		printf("the plugin is being run locally.\n");
		printf("\n");
	        }

	if(show_license==TRUE)
		display_license();

        if(result!=OK || show_help==TRUE || show_license==TRUE || show_version==TRUE)
		exit(STATE_UNKNOWN);


        /* generate the CRC 32 table */
        generate_crc32_table();

#ifdef HAVE_SSL
	/* initialize SSL */
	if(use_ssl==TRUE){
		SSL_library_init();
		SSLeay_add_ssl_algorithms();
		meth=SSLv23_client_method();
		SSL_load_error_strings();
		if((ctx=SSL_CTX_new(meth))==NULL){
			printf("CHECK_NRPE: Error - could not create SSL context.\n");
			exit(STATE_CRITICAL);
		        }

		/* ADDED 01/19/2004 */
		/* use only TLSv1 protocol */
		SSL_CTX_set_options(ctx,SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
                }
#endif

	/* initialize alarm signal handling */
	signal(SIGALRM,alarm_handler);

	/* set socket timeout */
	alarm(socket_timeout);

	/* try to connect to the host at the given port number */
	if((sd=my_connect(server_name, &hostaddr, server_port, address_family, 
			bind_address)) < 0 ) {
		exit (255);
		}
	else {
		result=STATE_OK;
	}

#ifdef HAVE_SSL
	/* do SSL handshake */
	if(result==STATE_OK && use_ssl==TRUE){
		if((ssl=SSL_new(ctx))!=NULL){
			SSL_CTX_set_cipher_list(ctx,"ADH");
			SSL_set_fd(ssl,sd);
			if((rc=SSL_connect(ssl))!=1){
				printf("CHECK_NRPE: Error - Could not complete SSL handshake.\n");
#ifdef DEBUG
				printf("SSL_connect=%d\n",rc);
				/*
				rc=SSL_get_error(ssl,rc);
				printf("SSL_get_error=%d\n",rc);
				printf("ERR_get_error=%lu\n",ERR_get_error());
				printf("%s\n",ERR_error_string(rc,NULL));
				*/
				ERR_print_errors_fp(stdout);
#endif
				result=STATE_CRITICAL;
			        }
		        }
		else{
			printf("CHECK_NRPE: Error - Could not create SSL connection structure.\n");
			result=STATE_CRITICAL;
		        }

		/* bail if we had errors */
		if(result!=STATE_OK){
			SSL_CTX_free(ctx);
			close(sd);
			exit(result);
		        }
	        }
#endif

	/* we're connected and ready to go */
	if(result==STATE_OK){

		/* clear the packet buffer */
		bzero(&send_packet,sizeof(send_packet));

		/* fill the packet with semi-random data */
		randomize_buffer((char *)&send_packet,sizeof(send_packet));

		/* initialize packet data */
		send_packet.packet_version=(int16_t)htons(NRPE_PACKET_VERSION_2);
		send_packet.packet_type=(int16_t)htons(QUERY_PACKET);
		strncpy(&send_packet.buffer[0],query,MAX_PACKETBUFFER_LENGTH);
		send_packet.buffer[MAX_PACKETBUFFER_LENGTH-1]='\x0';

		/* calculate the crc 32 value of the packet */
		send_packet.crc32_value=(u_int32_t)0L;
		calculated_crc32=calculate_crc32((char *)&send_packet,sizeof(send_packet));
		send_packet.crc32_value=(u_int32_t)htonl(calculated_crc32);


		/***** ENCRYPT REQUEST *****/


		/* send the packet */
		bytes_to_send=sizeof(send_packet);
		if(use_ssl==FALSE)
			rc=sendall(sd,(char *)&send_packet,&bytes_to_send);
#ifdef HAVE_SSL
		else{
			rc=SSL_write(ssl,&send_packet,bytes_to_send);
			if(rc<0)
				rc=-1;
		        }
#endif
		if(rc==-1){
			printf("CHECK_NRPE: Error sending query to host.\n");
			close(sd);
			return STATE_UNKNOWN;
		        }

		/* wait for the response packet */
		bytes_to_recv=sizeof(receive_packet);
		if(use_ssl==FALSE)
			rc=recvall(sd,(char *)&receive_packet,&bytes_to_recv,socket_timeout);
#ifdef HAVE_SSL
		else
			rc=SSL_read(ssl,&receive_packet,bytes_to_recv);
#endif

		/* reset timeout */
		alarm(0);

		/* close the connection */
#ifdef HAVE_SSL
		if(use_ssl==TRUE){
			SSL_shutdown(ssl);
			SSL_free(ssl);
			SSL_CTX_free(ctx);
	                }
#endif
		graceful_close(sd,1000);

		/* recv() error */
		if(rc<0){
			printf("CHECK_NRPE: Error receiving data from daemon.\n");
			return STATE_UNKNOWN;
		        }

		/* server disconnected */
		else if(rc==0){
			printf("CHECK_NRPE: Received 0 bytes from daemon.  Check the remote server logs for error messages.\n");
			return STATE_UNKNOWN;
		        }

		/* receive underflow */
		else if(bytes_to_recv<sizeof(receive_packet)){
			printf("CHECK_NRPE: Receive underflow - only %d bytes received (%d expected).\n",bytes_to_recv,sizeof(receive_packet));
			return STATE_UNKNOWN;
		        }

		
		/***** DECRYPT RESPONSE *****/


		/* check the crc 32 value */
		packet_crc32=ntohl(receive_packet.crc32_value);
		receive_packet.crc32_value=0L;
		calculated_crc32=calculate_crc32((char *)&receive_packet,sizeof(receive_packet));
		if(packet_crc32!=calculated_crc32){
			printf("CHECK_NRPE: Response packet had invalid CRC32.\n");
			close(sd);
			return STATE_UNKNOWN;
                        }
	
		/* check packet version */
		if(ntohs(receive_packet.packet_version)!=NRPE_PACKET_VERSION_2){
			printf("CHECK_NRPE: Invalid packet version received from server.\n");
			close(sd);
			return STATE_UNKNOWN;
			}

		/* check packet type */
		if(ntohs(receive_packet.packet_type)!=RESPONSE_PACKET){
			printf("CHECK_NRPE: Invalid packet type received from server.\n");
			close(sd);
			return STATE_UNKNOWN;
			}

		/* get the return code from the remote plugin */
		result=(int16_t)ntohs(receive_packet.result_code);

		/* print the output returned by the daemon */
		receive_packet.buffer[MAX_PACKETBUFFER_LENGTH-1]='\x0';
		if(!strcmp(receive_packet.buffer,""))
			printf("CHECK_NRPE: No output returned from daemon.\n");
		else
			printf("%s\n",receive_packet.buffer);
	        }

	/* reset the alarm */
	else
		alarm(0);

	return result;
        }
Exemple #9
0
void
parse_cmdline (conf_t conf, int argc, char **argv)
{
/*  Parses the command-line, altering the configuration [conf] as specified.
 */
    char          *prog;
    int            c;
    char          *p;
    int            i;
    long int       l;
    unsigned long  u;
    int            multiplier;
    munge_err_t    e;

    opterr = 0;                         /* suppress default getopt err msgs */

    prog = (prog = strrchr (argv[0], '/')) ? prog + 1 : argv[0];

    for (;;) {

        c = getopt_long (argc, argv, short_opts, long_opts, NULL);

        if (c == -1) {                  /* reached end of option list */
            break;
        }
        switch (c) {
            case 'h':
                display_help (prog);
                exit (EMUNGE_SUCCESS);
                break;
            case 'L':
                display_license ();
                exit (EMUNGE_SUCCESS);
                break;
            case 'V':
                display_version ();
                exit (EMUNGE_SUCCESS);
                break;
            case 'q':
                g_got_quiet = 1;
                break;
            case 'c':
                i = munge_enum_str_to_int (MUNGE_ENUM_CIPHER, optarg);
                if ((i < 0) || !munge_enum_is_valid (MUNGE_ENUM_CIPHER, i)) {
                    log_err (EMUNGE_SNAFU, LOG_ERR,
                        "Invalid cipher type \"%s\"", optarg);
                }
                e = munge_ctx_set (conf->ctx, MUNGE_OPT_CIPHER_TYPE, i);
                if (e != EMUNGE_SUCCESS) {
                    log_err (EMUNGE_SNAFU, LOG_ERR,
                        "Failed to set cipher type: %s",
                        munge_ctx_strerror (conf->ctx));
                }
                break;
            case 'C':
                display_strings ("Cipher types", MUNGE_ENUM_CIPHER);
                exit (EMUNGE_SUCCESS);
                break;
            case 'm':
                i = munge_enum_str_to_int (MUNGE_ENUM_MAC, optarg);
                if ((i < 0) || !munge_enum_is_valid (MUNGE_ENUM_MAC, i)) {
                    log_err (EMUNGE_SNAFU, LOG_ERR,
                        "Invalid MAC type \"%s\"", optarg);
                }
                e = munge_ctx_set (conf->ctx, MUNGE_OPT_MAC_TYPE, i);
                if (e != EMUNGE_SUCCESS) {
                    log_err (EMUNGE_SNAFU, LOG_ERR,
                        "Failed to set MAC type: %s",
                        munge_ctx_strerror (conf->ctx));
                }
                break;
            case 'M':
                display_strings ("MAC types", MUNGE_ENUM_MAC);
                exit (EMUNGE_SUCCESS);
                break;
            case 'z':
                i = munge_enum_str_to_int (MUNGE_ENUM_ZIP, optarg);
                if ((i < 0) || !munge_enum_is_valid (MUNGE_ENUM_ZIP, i)) {
                    log_err (EMUNGE_SNAFU, LOG_ERR,
                        "Invalid compression type \"%s\"", optarg);
                }
                e = munge_ctx_set (conf->ctx, MUNGE_OPT_ZIP_TYPE, i);
                if (e != EMUNGE_SUCCESS) {
                    log_err (EMUNGE_SNAFU, LOG_ERR,
                        "Failed to set compression type: %s",
                        munge_ctx_strerror (conf->ctx));
                }
                break;
            case 'Z':
                display_strings ("Compression types", MUNGE_ENUM_ZIP);
                exit (EMUNGE_SUCCESS);
                break;
            case 'e':
                conf->do_decode = 0;
                break;
            case 'd':
                conf->do_decode = 1;
                break;
            case 'l':
                errno = 0;
                l = strtol (optarg, &p, 10);
                if ((optarg == p) || ((*p != '\0') && (*(p+1) != '\0'))
                        || (l < 0)) {
                    log_err (EMUNGE_SNAFU, LOG_ERR,
                        "Invalid number of bytes '%s'", optarg);
                }
                if (((errno == ERANGE) && (l == LONG_MAX)) || (l > INT_MAX)) {
                    log_err (EMUNGE_SNAFU, LOG_ERR,
                        "Exceeded maximum number of %d bytes", INT_MAX);
                }
                if (!(multiplier = get_si_multiple (*p))) {
                    log_err (EMUNGE_SNAFU, LOG_ERR,
                        "Invalid number specifier '%c'", *p);
                }
                if (l > (INT_MAX / multiplier)) {
                    log_err (EMUNGE_SNAFU, LOG_ERR,
                        "Exceeded maximum number of %d bytes", INT_MAX);
                }
                conf->num_payload = (int) (l * multiplier);
                break;
            case 'u':
                if (query_uid (optarg, (uid_t *) &i) < 0) {
                    log_err (EMUNGE_SNAFU, LOG_ERR,
                        "Unrecognized user \"%s\"", optarg);
                }
                e = munge_ctx_set (conf->ctx, MUNGE_OPT_UID_RESTRICTION, i);
                if (e != EMUNGE_SUCCESS) {
                    log_err (EMUNGE_SNAFU, LOG_ERR,
                        "Failed to set UID restriction: %s",
                        munge_ctx_strerror (conf->ctx));
                }
                break;
            case 'g':
                if (query_gid (optarg, (gid_t *) &i) < 0) {
                    log_err (EMUNGE_SNAFU, LOG_ERR,
                        "Unrecognized group \"%s\"", optarg);
                }
                e = munge_ctx_set (conf->ctx, MUNGE_OPT_GID_RESTRICTION, i);
                if (e != EMUNGE_SUCCESS) {
                    log_err (EMUNGE_SNAFU, LOG_ERR,
                        "Failed to set GID restriction: %s",
                        munge_ctx_strerror (conf->ctx));
                }
                break;
            case 't':
                errno = 0;
                l = strtol (optarg, &p, 10);
                if ((optarg == p) || (*p != '\0') || (l < -1)) {
                    log_err (EMUNGE_SNAFU, LOG_ERR,
                        "Invalid time-to-live '%s'", optarg);
                }
                if ((errno == ERANGE) && (l == LONG_MAX)) {
                    log_err (EMUNGE_SNAFU, LOG_ERR,
                        "Overflowed maximum time-to-live of %ld seconds",
                        LONG_MAX);
                }
                if (l > UINT_MAX) {
                    log_err (EMUNGE_SNAFU, LOG_ERR,
                        "Exceeded maximum time-to-live of %u seconds",
                        UINT_MAX);
                }
                if (l == -1) {
                    l = MUNGE_TTL_MAXIMUM;
                }
                e = munge_ctx_set (conf->ctx, MUNGE_OPT_TTL, (int) l);
                if (e != EMUNGE_SUCCESS) {
                    log_err (EMUNGE_SNAFU, LOG_ERR,
                        "Failed to set time-to-live: %s",
                        munge_ctx_strerror (conf->ctx));
                }
                break;
            case 'S':
                e = munge_ctx_set (conf->ctx, MUNGE_OPT_SOCKET, optarg);
                if (e != EMUNGE_SUCCESS) {
                    log_err (EMUNGE_SNAFU, LOG_ERR,
                        "Failed to set munge socket name: %s",
                        munge_ctx_strerror (conf->ctx));
                }
                break;
            case 'D':
                errno = 0;
                l = strtol (optarg, &p, 10);
                if ((optarg == p) || ((*p != '\0') && (*(p+1) != '\0'))
                        || (l <= 0)) {
                    log_err (EMUNGE_SNAFU, LOG_ERR,
                        "Invalid duration '%s'", optarg);
                }
                if (((errno == ERANGE) && (l == LONG_MAX)) || (l > INT_MAX)) {
                    log_err (EMUNGE_SNAFU, LOG_ERR,
                        "Exceeded maximum duration of %d seconds", INT_MAX);
                }
                if (!(multiplier = get_time_multiple (*p))) {
                    log_err (EMUNGE_SNAFU, LOG_ERR,
                        "Invalid duration specifier '%c'", *p);
                }
                if (l > (INT_MAX / multiplier)) {
                    log_err (EMUNGE_SNAFU, LOG_ERR,
                        "Exceeded maximum duration of %d seconds", INT_MAX);
                }
                conf->num_seconds = (int) (l * multiplier);
                break;
            case 'N':
                errno = 0;
                u = strtoul (optarg, &p, 10);
                if ((optarg == p) || ((*p != '\0') && (*(p+1) != '\0'))
                        || (u == 0)) {
                    log_err (EMUNGE_SNAFU, LOG_ERR,
                        "Invalid number of credentials '%s'", optarg);
                }
                if ((errno == ERANGE) && (u == ULONG_MAX)) {
                    log_err (EMUNGE_SNAFU, LOG_ERR,
                        "Exceeded maximum number of %lu credentials",
                        ULONG_MAX);
                }
                if (!(multiplier = get_si_multiple (*p))) {
                    log_err (EMUNGE_SNAFU, LOG_ERR,
                        "Invalid number specifier '%c'", *p);
                }
                if (u > (ULONG_MAX / multiplier)) {
                    log_err (EMUNGE_SNAFU, LOG_ERR,
                        "Exceeded maximum number of %lu credentials",
                        ULONG_MAX);
                }
                conf->num_creds = u * multiplier;
                break;
            case 'T':
                errno = 0;
                l = strtol (optarg, &p, 10);
                if ((optarg == p) || (*p != '\0') || (l <= 0)) {
                    log_err (EMUNGE_SNAFU, LOG_ERR,
                        "Invalid number of threads '%s'", optarg);
                }
                if (((errno == ERANGE) && (l == LONG_MAX)) || (l > INT_MAX)
                        || (l > conf->max_threads)) {
                    log_err (EMUNGE_SNAFU, LOG_ERR,
                        "Exceeded maximum number of %d thread%s",
                        conf->max_threads,
                        (conf->max_threads == 1) ? "" : "s");
                }
                conf->num_threads = (int) l;
                break;
            case 'W':
                errno = 0;
                l = strtol (optarg, &p, 10);
                if ((optarg == p) || (*p != '\0') || (l <= 0)) {
                    log_err (EMUNGE_SNAFU, LOG_ERR,
                        "Invalid number of seconds '%s'", optarg);
                }
                if (((errno == ERANGE) && (l == LONG_MAX)) || (l > INT_MAX)) {
                    log_err (EMUNGE_SNAFU, LOG_ERR,
                        "Exceeded maximum number of %d seconds", INT_MAX);
                }
                conf->warn_time = (int) l;
                break;
            case '?':
                if (optopt > 0) {
                    log_err (EMUNGE_SNAFU, LOG_ERR,
                        "Invalid option \"-%c\"", optopt);
                }
                else if (optind > 1) {
                    log_err (EMUNGE_SNAFU, LOG_ERR,
                        "Invalid option \"%s\"", argv[optind - 1]);
                }
                else {
                    log_err (EMUNGE_SNAFU, LOG_ERR,
                        "Failed to process command-line");
                }
                break;
            case ':':
                if ((optind > 1)
                        && (strncmp (argv[optind - 1], "--", 2) == 0)) {
                    log_err (EMUNGE_SNAFU, LOG_ERR,
                        "Missing argument for option \"%s\"",
                        argv[optind - 1]);
                }
                else if (optopt > 0) {
                    log_err (EMUNGE_SNAFU, LOG_ERR,
                        "Missing argument for option \"-%c\"", optopt);
                }
                else {
                    log_err (EMUNGE_SNAFU, LOG_ERR,
                        "Failed to process command-line");
                }
                break;
            default:
                if ((optind > 1)
                        && (strncmp (argv[optind - 1], "--", 2) == 0)) {
                    log_err (EMUNGE_SNAFU, LOG_ERR,
                        "Unimplemented option \"%s\"", argv[optind - 1]);
                }
                else {
                    log_err (EMUNGE_SNAFU, LOG_ERR,
                        "Unimplemented option \"-%c\"", c);
                }
                break;
        }
    }
    if (argv[optind]) {
        log_err (EMUNGE_SNAFU, LOG_ERR,
            "Unrecognized parameter \"%s\"", argv[optind]);
    }
    /*  Create arbitrary payload of the specified length.
     */
    if (conf->num_payload > 0) {
        if (!(conf->payload = malloc (conf->num_payload + 1))) {
            log_err (EMUNGE_NO_MEMORY, LOG_ERR,
                "Failed to allocate credential payload of %d byte%s",
                conf->num_payload, (conf->num_payload == 1 ? "" : "s"));
        }
        for (i = 0, c = 'A'; i < conf->num_payload; i++) {
            if ((conf->payload[i] = c++) == 'Z') {
                c = 'A';
            }
        }
        conf->payload[conf->num_payload] = '\0';
    }
    return;
}
Exemple #10
0
int main(int argc, char **argv) {
	char buffer[MAX_INPUT_BUFFER];
	int result;
	uid_t uid = -1;
	gid_t gid = -1;


	/* process command-line arguments */
	result = process_arguments(argc, argv);

	if (result != OK || show_help == TRUE || show_license == TRUE || show_version == TRUE) {

		if (result != OK)
			printf("Incorrect command line arguments supplied\n");
		printf("\n");
		printf("NSCA - Nagios Service Check Acceptor for Icinga\n");
		printf("Copyright (c) 2010-2012 Icinga Development Team and Community Contributors (http://www.icinga.org)\n");
		printf("Copyright (c) 2009-2012 Nagios Core Development Team and Community Contributors\n");
		printf("Copyright (c) 2000-2009 Ethan Galstad\n");
		printf("Version: %s\n", PROGRAM_VERSION);
		printf("Last Modified: %s\n", MODIFICATION_DATE);
		printf("License: GPL v2\n");
		printf("Encryption Routines: ");
#ifdef HAVE_LIBMCRYPT
		printf("AVAILABLE");
#else
		printf("NOT AVAILABLE");
#endif
		printf("\n");
#ifdef HAVE_LIBWRAP
		printf("TCP Wrappers Available\n");
#endif
		printf("\n");
	}

	if (result != OK || show_help == TRUE) {
		printf("Usage: %s -c <config_file> [mode]\n", argv[0]);
		printf("\n");
		printf("Options:\n");
		printf(" <config_file> = Name of config file to use\n");
		printf(" [mode]        = Determines how NSCA should run. Valid modes:\n");
		printf("   --inetd     = Run as a service under inetd or xinetd\n");
		printf("   --daemon    = Run as a standalone multi-process daemon\n");
		printf("   --single    = Run as a standalone single-process daemon (default)\n");
		printf("\n");
		printf("Notes:\n");
		printf("This program is designed to accept passive check results from\n");
		printf("remote hosts that use the send_nsca utility.  Can run as a service\n");
		printf("under inetd or xinetd (read the docs for info on this), or as a\n");
		printf("standalone daemon.\n");
		printf("\n");
	}

	if (show_license == TRUE)
		display_license();

	if (result != OK || show_help == TRUE || show_license == TRUE || show_version == TRUE)
		do_exit(STATE_UNKNOWN);


	/* open a connection to the syslog facility */
	/* facility may be overridden later */
	get_log_facility(NSCA_LOG_FACILITY);
	openlog("nsca", LOG_PID | LOG_NDELAY, log_facility);

	/* make sure the config file uses an absolute path */
	if (config_file[0] != '/') {

		/* save the name of the config file */
		strncpy(buffer, config_file, sizeof(buffer));
		buffer[sizeof(buffer) - 1] = '\0';

		/* get absolute path of current working directory */
		strcpy(config_file, "");
		getcwd(config_file, sizeof(config_file));

		/* append a forward slash */
		strncat(config_file, "/", sizeof(config_file) - 2);
		config_file[sizeof(config_file) - 1] = '\0';

		/* append the config file to the path */
		strncat(config_file, buffer, sizeof(config_file) - strlen(config_file) - 1);
		config_file[sizeof(config_file) - 1] = '\0';
	}

	/* read the config file */
	result = read_config_file(config_file);

	/* exit if there are errors... */
	if (result == ERROR)
		do_exit(STATE_CRITICAL);

	/* generate the CRC 32 table */
	generate_crc32_table();


	/* how should we handle client connections? */
	switch (mode) {

	case INETD:
		/* chroot if configured */
		do_chroot();

		/* if we're running under inetd, handle one connection and get out */
		handle_connection(0, NULL);
		break;

	case MULTI_PROCESS_DAEMON:

		/* older style, mult-process daemon */
		/* execution cascades below... */
		install_child_handler();

		/*     |
		       |
		       |     */
	case SINGLE_PROCESS_DAEMON:
		/*     |
		       |
		       V     */

		/* daemonize and start listening for requests... */
		if (fork() == 0) {

			/* we're a daemon - set up a new process group */
			setsid();

			/* handle signals */
			signal(SIGQUIT, sighandler);
			signal(SIGTERM, sighandler);
			signal(SIGHUP, sighandler);
			
			signal(SIGPIPE, SIG_IGN);

			/* close standard file descriptors */
			close(0);
			close(1);
			close(2);

			/* redirect standard descriptors to /dev/null */
			open("/dev/null", O_RDONLY);
			open("/dev/null", O_WRONLY);
			open("/dev/null", O_WRONLY);

			/* get group information before chrooting */
			get_user_info(nsca_user, &uid);
			get_group_info(nsca_group, &gid);

			/* write pid file */
			if (write_pid_file(uid, gid) == ERROR)
				return STATE_CRITICAL;

			/* chroot if configured */
			do_chroot();

			/* drop privileges */
			if (drop_privileges(nsca_user, uid, gid) == ERROR)
				do_exit(STATE_CRITICAL);

			do {

				/* reset flags */
				sigrestart = FALSE;
				sigshutdown = FALSE;

				/* wait for connections */
				wait_for_connections();

				if (sigrestart == TRUE) {

					/* free memory */
					free_memory();

					/* re-read the config file */
					result = read_config_file(config_file);

					/* exit if there are errors... */
					if (result == ERROR) {
						syslog(LOG_ERR, "Config file '%s' contained errors, bailing out...", config_file);
						break;
					}
				}

			} while (sigrestart == TRUE && sigshutdown == FALSE);

			/* remove pid file */
			remove_pid_file();

			syslog(LOG_NOTICE, "Daemon shutdown\n");
		}
		break;

	default:
		break;
	}

	/* we are now running in daemon mode, or the connection handed over by inetd has been completed, so the parent process exits */
	do_exit(STATE_OK);

	/* keep the compilers happy... */
	return STATE_OK;
}