int xml_config_log(const xml_config_t *config) { char *facility = NULL, *level = NULL; int ret = OBIX_ERR_INVALID_ARGUMENT; if (!(level = xml_config_get_str(config, XP_LOG_LEVEL))) { log_error("Failed to get %s settings", XP_LOG_LEVEL); goto failed; } if (!(facility = xml_config_get_str(config, XP_LOG_FACILITY))) { log_error("Failed to get %s settings", XP_LOG_FACILITY); goto failed; } log_useSyslog(get_log_facility(facility)); log_setLevel(get_log_level(level)); ret = OBIX_SUCCESS; /* Fall through */ failed: if (facility) { free(facility); } if (level) { free(level); } return ret; }
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; }
/* read in the configuration file */ int read_config_file(char *filename){ FILE *fp; char config_file[MAX_FILENAME_LENGTH]; char input_buffer[MAX_INPUT_BUFFER]; char *input_line; char *temp_buffer; char *varname; char *varvalue; int line=0; int len=0; int x=0; /* open the config file for reading */ fp=fopen(filename,"r"); /* exit if we couldn't open the config file */ if(fp==NULL){ syslog(LOG_ERR,"Unable to open config file '%s' for reading\n",filename); return ERROR; } while(fgets(input_buffer,MAX_INPUT_BUFFER-1,fp)){ line++; input_line=input_buffer; /* skip leading whitespace */ while(isspace(*input_line)) ++input_line; /* trim trailing whitespace */ len=strlen(input_line); for(x=len-1;x>=0;x--){ if(isspace(input_line[x])) input_line[x]='\x0'; else break; } /* skip comments and blank lines */ if(input_line[0]=='#') continue; if(input_line[0]=='\x0') continue; if(input_line[0]=='\n') continue; /* get the variable name */ varname=strtok(input_line,"="); if(varname==NULL){ syslog(LOG_ERR,"No variable name specified in config file '%s' - Line %d\n",filename,line); return ERROR; } /* get the variable value */ varvalue=strtok(NULL,"\n"); if(varvalue==NULL){ syslog(LOG_ERR,"No variable value specified in config file '%s' - Line %d\n",filename,line); return ERROR; } /* allow users to specify directories to recurse into for config files */ else if(!strcmp(varname,"include_dir")){ strncpy(config_file,varvalue,sizeof(config_file)-1); config_file[sizeof(config_file)-1]='\x0'; /* strip trailing / if necessary */ if(config_file[strlen(config_file)-1]=='/') config_file[strlen(config_file)-1]='\x0'; /* process the config directory... */ if(read_config_dir(config_file)==ERROR) syslog(LOG_ERR,"Continuing with errors..."); } /* allow users to specify individual config files to include */ else if(!strcmp(varname,"include") || !strcmp(varname,"include_file")){ /* process the config file... */ if(read_config_file(varvalue)==ERROR) syslog(LOG_ERR,"Continuing with errors..."); } else if(!strcmp(varname,"server_port")) server_port=strdup(varvalue); else if(!strcmp(varname,"command_prefix")) command_prefix=strdup(varvalue); else if(!strcmp(varname,"server_address")){ server_address=strdup(varvalue); } else if(!strcmp(varname,"allowed_hosts")) allowed_hosts=strdup(varvalue); else if(strstr(input_line,"command[")){ temp_buffer=strtok(varname,"["); temp_buffer=strtok(NULL,"]"); if(temp_buffer==NULL){ syslog(LOG_ERR,"Invalid command specified in config file '%s' - Line %d\n",filename,line); return ERROR; } add_command(temp_buffer,varvalue); } else if(strstr(input_buffer,"debug")){ debug=atoi(varvalue); if(debug>0) debug=TRUE; else debug=FALSE; } else if(!strcmp(varname,"nrpe_user")) nrpe_user=strdup(varvalue); else if(!strcmp(varname,"nrpe_group")) nrpe_group=strdup(varvalue); else if(!strcmp(varname,"dont_blame_nrpe")) allow_arguments=(atoi(varvalue)==1)?TRUE:FALSE; else if(!strcmp(varname,"command_timeout")){ command_timeout=atoi(varvalue); if(command_timeout<1){ syslog(LOG_ERR,"Invalid command_timeout specified in config file '%s' - Line %d\n",filename,line); return ERROR; } } else if(!strcmp(varname,"connection_timeout")){ connection_timeout=atoi(varvalue); if(connection_timeout<1){ syslog(LOG_ERR,"Invalid connection_timeout specified in config file '%s' - Line %d\n",filename,line); return ERROR; } } else if(!strcmp(varname,"allow_weak_random_seed")) allow_weak_random_seed=(atoi(varvalue)==1)?TRUE:FALSE; else if(!strcmp(varname,"pid_file")) pid_file=strdup(varvalue); else if(!strcmp(varname,"log_facility")){ if((get_log_facility(varvalue))==OK){ /* re-open log using new facility */ closelog(); openlog("nrpe",LOG_PID,log_facility); } else syslog(LOG_WARNING,"Invalid log_facility specified in config file '%s' - Line %d\n",filename,line); } else{ syslog(LOG_WARNING,"Unknown option specified in config file '%s' - Line %d\n",filename,line); continue; } } /* close the config file */ fclose(fp); return OK; }
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; }
/* read in the configuration file */ static int read_config_file(char *filename) { FILE *fp; char input_buffer[MAX_INPUT_BUFFER]; char *varname; char *varvalue; int line; int checkresult_test_fd = -1; char *checkresult_test = NULL; /* open the config file for reading */ fp = fopen(filename, "r"); /* exit if we couldn't open the config file */ if (fp == NULL) { syslog(LOG_ERR, "Could not open config file '%s' for reading\n", filename); return ERROR; } line = 0; while (fgets(input_buffer, MAX_INPUT_BUFFER - 1, fp)) { line++; /* skip comments and blank lines */ if (input_buffer[0] == '#') continue; if (input_buffer[0] == '\0') continue; if (input_buffer[0] == '\n') continue; /* get the variable name */ varname = strtok(input_buffer, "="); if (varname == NULL) { syslog(LOG_ERR, "No variable name specified in config file '%s' - Line %d\n", filename, line); return ERROR; } /* get the variable value */ varvalue = strtok(NULL, "\n"); if (varvalue == NULL) { syslog(LOG_ERR, "No variable value specified in config file '%s' - Line %d\n", filename, line); return ERROR; } if (!strcmp(varname, "server_port")) server_port = strdup(varvalue); else if (!strcmp(varname, "server_address")) { server_address = strdup(varvalue); } else if (strstr(input_buffer, "command_file")) { if (strlen(varvalue) > sizeof(command_file) - 1) { syslog(LOG_ERR, "Command file name is too long in config file '%s' - Line %d\n", filename, line); return ERROR; } strncpy(command_file, varvalue, sizeof(command_file) - 1); command_file[sizeof(command_file) - 1] = '\0'; } else if (strstr(input_buffer, "alternate_dump_file")) { if (strlen(varvalue) > sizeof(alternate_dump_file) - 1) { syslog(LOG_ERR, "Alternate dump file name is too long in config file '%s' - Line %d\n", filename, line); return ERROR; } strncpy(alternate_dump_file, varvalue, sizeof(alternate_dump_file) - 1); alternate_dump_file[sizeof(alternate_dump_file) - 1] = '\0'; } else if (strstr(input_buffer, "password")) { if (strlen(varvalue) > sizeof(password) - 1) { syslog(LOG_ERR, "Password is too long in config file '%s' - Line %d\n", filename, line); return ERROR; } strncpy(password, varvalue, sizeof(password) - 1); password[sizeof(password) - 1] = '\0'; } else if (strstr(input_buffer, "decryption_method")) { decryption_method = atoi(varvalue); switch (decryption_method) { case ENCRYPT_NONE: case ENCRYPT_XOR: break; #ifdef HAVE_LIBMCRYPT case ENCRYPT_DES: case ENCRYPT_3DES: case ENCRYPT_CAST128: case ENCRYPT_CAST256: case ENCRYPT_XTEA: case ENCRYPT_3WAY: case ENCRYPT_BLOWFISH: case ENCRYPT_TWOFISH: case ENCRYPT_LOKI97: case ENCRYPT_RC2: case ENCRYPT_ARCFOUR: case ENCRYPT_RIJNDAEL128: case ENCRYPT_RIJNDAEL192: case ENCRYPT_RIJNDAEL256: case ENCRYPT_WAKE: case ENCRYPT_SERPENT: case ENCRYPT_ENIGMA: case ENCRYPT_GOST: case ENCRYPT_SAFER64: case ENCRYPT_SAFER128: case ENCRYPT_SAFERPLUS: break; #endif default: syslog(LOG_ERR, "Invalid decryption method (%d) in config file '%s' - Line %d\n", decryption_method, filename, line); #ifndef HAVE_LIBMCRYPT if (decryption_method >= 2) syslog(LOG_ERR, "Daemon was not compiled with mcrypt library, so decryption is unavailable.\n"); #endif return ERROR; } } else if (strstr(input_buffer, "debug")) { if (atoi(varvalue) > 0) debug = TRUE; else debug = FALSE; } else if (strstr(input_buffer, "aggregate_writes")) { if (atoi(varvalue) > 0) aggregate_writes = TRUE; else aggregate_writes = FALSE; } else if (strstr(input_buffer, "check_result_path")) { if (strlen(varvalue) > MAX_INPUT_BUFFER - 1) { syslog(LOG_ERR, "Check result path is too long in config file '%s' - Line %d\n", filename, line); return ERROR; } check_result_path = strdup(varvalue); asprintf(&checkresult_test, "%s/nsca.test.%i", check_result_path, getpid()); checkresult_test_fd = open(checkresult_test, O_WRONLY | O_CREAT, 0644); if (checkresult_test_fd > 0) { unlink(checkresult_test); free(checkresult_test); } else { syslog(LOG_ERR, "check_result_path config variable found, but directory not writeable.\n"); free(checkresult_test); return ERROR; } } else if (strstr(input_buffer, "append_to_file")) { if (atoi(varvalue) > 0) append_to_file = TRUE; else append_to_file = FALSE; } else if (!strcmp(varname, "max_packet_age")) { max_packet_age = strtoul(varvalue, NULL, 10); if (max_packet_age > 900) { syslog(LOG_ERR, "Max packet age cannot be greater than 15 minutes (900 seconds).\n"); return ERROR; } } else if (!strcmp(varname, "nsca_user")) nsca_user = strdup(varvalue); else if (!strcmp(varname, "nsca_group")) nsca_group = strdup(varvalue); else if (!strcmp(varname, "nsca_chroot")) nsca_chroot = strdup(varvalue); else if (!strcmp(varname, "pid_file")) pid_file = strdup(varvalue); else if (!strcmp(varname, "log_facility")) { if ((get_log_facility(varvalue)) == OK) { /* re-open log using new facility */ closelog(); openlog("nsca", LOG_PID | LOG_NDELAY, log_facility); } else syslog(LOG_WARNING, "Invalid log_facility specified in config file '%s' - Line %d\n", filename, line); } else { syslog(LOG_ERR, "Unknown option specified in config file '%s' - Line %d\n", filename, line); return ERROR; } } /* close the config file */ fclose(fp); return OK; }