/* logs host states */ int log_host_states(int type, time_t *timestamp){ char *temp_buffer=NULL; char *processed_buffer=NULL; host *temp_host=NULL;; /* bail if we shouldn't be logging initial states */ if(type==INITIAL_STATES && log_initial_states==FALSE) return OK; for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){ /* grab the host macros */ clear_volatile_macros(); grab_host_macros(temp_host); asprintf(&temp_buffer,"%s HOST STATE: %s;$HOSTSTATE$;$HOSTSTATETYPE$;$HOSTATTEMPT$;%s\n",(type==INITIAL_STATES)?"INITIAL":"CURRENT",temp_host->name,(temp_host->plugin_output==NULL)?"":temp_host->plugin_output); process_macros(temp_buffer,&processed_buffer,0); write_to_all_logs_with_timestamp(processed_buffer,NSLOG_INFO_MESSAGE,timestamp); my_free(temp_buffer); my_free(processed_buffer); } return OK; }
/* logs service states */ int log_service_states(int type, time_t *timestamp){ char *temp_buffer=NULL; char *processed_buffer=NULL; service *temp_service=NULL; host *temp_host=NULL;; /* bail if we shouldn't be logging initial states */ if(type==INITIAL_STATES && log_initial_states==FALSE) return OK; for(temp_service=service_list;temp_service!=NULL;temp_service=temp_service->next){ /* find the associated host */ if((temp_host=temp_service->host_ptr)==NULL) continue; /* grab service macros */ clear_volatile_macros(); grab_host_macros(temp_host); grab_service_macros(temp_service); asprintf(&temp_buffer,"%s SERVICE STATE: %s;%s;$SERVICESTATE$;$SERVICESTATETYPE$;$SERVICEATTEMPT$;%s\n",(type==INITIAL_STATES)?"INITIAL":"CURRENT",temp_service->host_name,temp_service->description,temp_service->plugin_output); process_macros(temp_buffer,&processed_buffer,0); write_to_all_logs_with_timestamp(processed_buffer,NSLOG_INFO_MESSAGE,timestamp); my_free(temp_buffer); my_free(processed_buffer); } return OK; }
/* write a host problem/recovery to the log file */ int log_host_event(host *hst){ char *temp_buffer=NULL; char *processed_buffer=NULL; unsigned long log_options=0L; /* grab the host macros */ clear_volatile_macros(); grab_host_macros(hst); /* get the log options */ if(hst->current_state==HOST_DOWN) log_options=NSLOG_HOST_DOWN; else if(hst->current_state==HOST_UNREACHABLE) log_options=NSLOG_HOST_UNREACHABLE; else log_options=NSLOG_HOST_UP; asprintf(&temp_buffer,"HOST ALERT: %s;$HOSTSTATE$;$HOSTSTATETYPE$;$HOSTATTEMPT$;%s\n",hst->name,(hst->plugin_output==NULL)?"":hst->plugin_output); process_macros(temp_buffer,&processed_buffer,0); write_to_all_logs(processed_buffer,log_options); my_free(temp_buffer); my_free(processed_buffer); return OK; }
/* write a service problem/recovery to the nagios log file */ int log_service_event(service *svc){ char *temp_buffer=NULL; char *processed_buffer=NULL; unsigned long log_options=0L; host *temp_host=NULL; /* don't log soft errors if the user doesn't want to */ if(svc->state_type==SOFT_STATE && !log_service_retries) return OK; /* get the log options */ if(svc->current_state==STATE_UNKNOWN) log_options=NSLOG_SERVICE_UNKNOWN; else if(svc->current_state==STATE_WARNING) log_options=NSLOG_SERVICE_WARNING; else if(svc->current_state==STATE_CRITICAL) log_options=NSLOG_SERVICE_CRITICAL; else log_options=NSLOG_SERVICE_OK; /* find the associated host */ if((temp_host=svc->host_ptr)==NULL) return ERROR; /* grab service macros */ clear_volatile_macros(); grab_host_macros(temp_host); grab_service_macros(svc); asprintf(&temp_buffer,"SERVICE ALERT: %s;%s;$SERVICESTATE$;$SERVICESTATETYPE$;$SERVICEATTEMPT$;%s\n",svc->host_name,svc->description,(svc->plugin_output==NULL)?"":svc->plugin_output); process_macros(temp_buffer,&processed_buffer,0); write_to_all_logs(processed_buffer,log_options); my_free(temp_buffer); my_free(processed_buffer); return OK; }
/************************************************************************** * returns: * 1 - command executed, repeatable * 0 - command executed but not repeatable, interrupted commands are * always considered not repeatable * -1 - not executed (unrecognized, bootd recursion or too many args) * (If cmd is NULL or "" or longer than CFG_CBSIZE-1 it is * considered unrecognized) * * WARNING: * * We must create a temporary copy of the command since the command we get * may be the result from getenv(), which returns a pointer directly to * the environment data, which may change magicly when the command we run * creates or modifies environment variables (like "bootp" does). *************************************************************************/ int run_command (const char *cmd, int flag) { cmd_tbl_t *cmdtp; char cmdbuf[CFG_CBSIZE]; /* working copy of cmd */ char *token; /* start of token in cmdbuf */ char *sep; /* end of token (separator) in cmdbuf */ char finaltoken[CFG_CBSIZE]; char *str = cmdbuf; char *argv[CFG_MAXARGS + 1]; /* NULL terminated */ int argc, inquotes; int repeatable = 1; int rc = 0; #ifdef DEBUG_PARSER printf ("[RUN_COMMAND] cmd[%p]=\"", cmd); serial_puts (cmd ? cmd : "NULL"); /* use puts - string may be loooong */ serial_puts ("\"\r\n"); #endif clear_ctrlc(); /* forget any previous Control C */ if (!cmd || !*cmd) { return -1; /* empty command */ } if (strlen(cmd) >= CFG_CBSIZE) { serial_puts ("## Command too long!\r\n"); return -1; } strcpy (cmdbuf, cmd); /* Process separators and check for invalid * repeatable commands */ #ifdef DEBUG_PARSER printf ("[PROCESS_SEPARATORS] %s\r\n", cmd); #endif while (*str) { /* * Find separator, or string end * Allow simple escape of ';' by writing "\;" */ for (inquotes = 0, sep = str; *sep; sep++) { if ((*sep=='\'') && (*(sep-1) != '\\')) inquotes=!inquotes; if (!inquotes && (*sep == ';') && /* separator */ ( sep != str) && /* past string start */ (*(sep-1) != '\\')) /* and NOT escaped */ break; } /* * Limit the token to data between separators */ token = str; if (*sep) { str = sep + 1; /* start of command for next pass */ *sep = '\0'; } else str = sep; /* no more commands for next pass */ #ifdef DEBUG_PARSER printf ("token: \"%s\"\n", token); #endif /* find macros in this token and replace them */ process_macros (token, finaltoken); /* Extract arguments */ if ((argc = parse_line (finaltoken, argv)) == 0) { rc = -1; /* no command at all */ continue; } /* Look up command in command table */ if ((cmdtp = find_cmd(argv[0])) == NULL) { printf ("Unknown command '%s' - try 'help'\r\n", argv[0]); rc = -1; /* give up after bad command */ continue; } /* found - check max args */ if (argc > cmdtp->maxargs) { printf ("Usage:\n%s\r\n", cmdtp->usage); rc = -1; continue; } /* OK - call function to do the command */ if ((cmdtp->cmd) (cmdtp, flag, argc, argv) != 0) { rc = -1; } repeatable &= cmdtp->repeatable; /* Did the user stop this? */ if (had_ctrlc ()) return 0; /* if stopped then not repeatable */ } return rc ? rc : repeatable; }
/**************************************************************************** * returns: * 1 - command executed, repeatable * 0 - command executed but not repeatable, interrupted commands are * always considered not repeatable * -1 - not executed (unrecognized, bootd recursion or too many args) * (If cmd is NULL or "" or longer than CONFIG_SYS_CBSIZE-1 it is * considered unrecognized) * * WARNING: * * We must create a temporary copy of the command since the command we get * may be the result from getenv(), which returns a pointer directly to * the environment data, which may change magicly when the command we run * creates or modifies environment variables (like "bootp" does). */ static int builtin_run_command(const char *cmd, int flag) { char cmdbuf[CONFIG_SYS_CBSIZE]; /* working copy of cmd */ char *token; /* start of token in cmdbuf */ char *sep; /* end of token (separator) in cmdbuf */ char finaltoken[CONFIG_SYS_CBSIZE]; char *str = cmdbuf; char *argv[CONFIG_SYS_MAXARGS + 1]; /* NULL terminated */ int argc, inquotes; int repeatable = 1; int rc = 0; debug_parser("[RUN_COMMAND] cmd[%p]=\"", cmd); if (DEBUG_PARSER) { /* use printf - string may be loooong */ printf(cmd ? cmd : "NULL"); printf("\"\n"); } //clear_ctrlc(); /* forget any previous Control C */ if (!cmd || !*cmd) { return -1; /* empty command */ } if (strlen(cmd) >= CONFIG_SYS_CBSIZE) { printf ("## Command too long!\n"); return -1; } strcpy (cmdbuf, cmd); /* Process separators and check for invalid * repeatable commands */ debug_parser("[PROCESS_SEPARATORS] %s\n", cmd); while (*str) { /* * Find separator, or string end * Allow simple escape of ';' by writing "\;" */ for (inquotes = 0, sep = str; *sep; sep++) { if ((*sep=='\'') && (*(sep-1) != '\\')) inquotes=!inquotes; if (!inquotes && (*sep == ';') && /* separator */ ( sep != str) && /* past string start */ (*(sep-1) != '\\')) /* and NOT escaped */ break; } /* * Limit the token to data between separators */ token = str; if (*sep) { str = sep + 1; /* start of command for next pass */ *sep = '\0'; } else str = sep; /* no more commands for next pass */ debug_parser("token: \"%s\"\n", token); /* find macros in this token and replace them */ process_macros (token, finaltoken); /* Extract arguments */ if ((argc = parse_line (finaltoken, argv)) == 0) { rc = -1; /* no command at all */ continue; } if (cmd_process(flag, argc, argv, &repeatable, NULL)) rc = -1; /* Did the user stop this? */ //if (had_ctrlc ()) // return -1; /* if stopped then not repeatable */ } return rc ? rc : repeatable; }
int run_command(const char *cmd) { char cmdbuf[CONFIG_CBSIZE]; /* working copy of cmd */ char *token; /* start of token in cmdbuf */ char *sep; /* end of token (separator) in cmdbuf */ char finaltoken[CONFIG_CBSIZE]; char *str = cmdbuf; char *argv[CONFIG_MAXARGS + 1]; /* NULL terminated */ int argc, inquotes; int rc = 0; #ifdef DEBUG pr_debug("[RUN_COMMAND] cmd[%p]=\"", cmd); puts (cmd ? cmd : "NULL"); /* use puts - string may be loooong */ puts ("\"\n"); #endif if (!cmd || !*cmd) { return -1; /* empty command */ } if (strlen(cmd) >= CONFIG_CBSIZE) { puts ("## Command too long!\n"); return -1; } strcpy (cmdbuf, cmd); /* * Process separators and check for invalid * repeatable commands */ pr_debug("[PROCESS_SEPARATORS] %s\n", cmd); while (*str) { /* * Find separator, or string end * Allow simple escape of ';' by writing "\;" */ for (inquotes = 0, sep = str; *sep; sep++) { if ((*sep=='\'') && (*(sep-1) != '\\')) inquotes=!inquotes; if (!inquotes && (*sep == ';') && /* separator */ ( sep != str) && /* past string start */ (*(sep-1) != '\\')) /* and NOT escaped */ break; } /* * Limit the token to data between separators */ token = str; if (*sep) { str = sep + 1; /* start of command for next pass */ *sep = '\0'; } else { str = sep; /* no more commands for next pass */ } pr_debug("token: \"%s\"\n", token); /* find macros in this token and replace them */ process_macros (token, finaltoken); /* Extract arguments */ if ((argc = parse_line (finaltoken, argv)) == 0) { rc = -1; /* no command at all */ continue; } if (execute_command(argc, argv) != COMMAND_SUCCESS) rc = -1; } return rc; }
/* handles a client connection */ void handle_connection(int sock){ u_int32_t calculated_crc32; command *temp_command; packet receive_packet; packet send_packet; int bytes_to_send; int bytes_to_recv; char buffer[MAX_INPUT_BUFFER]; char raw_command[MAX_INPUT_BUFFER]; char processed_command[MAX_INPUT_BUFFER]; int result=STATE_OK; int early_timeout=FALSE; int rc; int x; #ifdef DEBUG FILE *errfp; #endif #ifdef HAVE_SSL SSL *ssl=NULL; #endif /* log info to syslog facility */ if(debug==TRUE) syslog(LOG_DEBUG,"Handling the connection..."); #ifdef OLDSTUFF /* socket should be non-blocking */ fcntl(sock,F_SETFL,O_NONBLOCK); #endif /* set connection handler */ signal(SIGALRM,my_connection_sighandler); alarm(connection_timeout); #ifdef HAVE_SSL /* do SSL handshake */ if(result==STATE_OK && use_ssl==TRUE){ if((ssl=SSL_new(ctx))!=NULL){ SSL_set_fd(ssl,sock); /* keep attempting the request if needed */ while(((rc=SSL_accept(ssl))!=1) && (SSL_get_error(ssl,rc)==SSL_ERROR_WANT_READ)); if(rc!=1){ syslog(LOG_ERR,"Error: Could not complete SSL handshake. %d\n",SSL_get_error(ssl,rc)); #ifdef DEBUG errfp=fopen("/tmp/err.log","w"); ERR_print_errors_fp(errfp); fclose(errfp); #endif return; } } else{ syslog(LOG_ERR,"Error: Could not create SSL connection structure.\n"); #ifdef DEBUG errfp=fopen("/tmp/err.log","w"); ERR_print_errors_fp(errfp); fclose(errfp); #endif return; } } #endif bytes_to_recv=sizeof(receive_packet); if(use_ssl==FALSE) rc=recvall(sock,(char *)&receive_packet,&bytes_to_recv,socket_timeout); #ifdef HAVE_SSL else{ while(((rc=SSL_read(ssl,&receive_packet,bytes_to_recv))<=0) && (SSL_get_error(ssl,rc)==SSL_ERROR_WANT_READ)); } #endif /* recv() error or client disconnect */ if(rc<=0){ /* log error to syslog facility */ syslog(LOG_ERR,"Could not read request from client, bailing out..."); #ifdef HAVE_SSL if(ssl){ SSL_shutdown(ssl); SSL_free(ssl); syslog(LOG_INFO,"INFO: SSL Socket Shutdown.\n"); } #endif return; } /* we couldn't read the correct amount of data, so bail out */ else if(bytes_to_recv!=sizeof(receive_packet)){ /* log error to syslog facility */ syslog(LOG_ERR,"Data packet from client was too short, bailing out..."); #ifdef HAVE_SSL if(ssl){ SSL_shutdown(ssl); SSL_free(ssl); } #endif return; } #ifdef DEBUG fp=fopen("/tmp/packet","w"); if(fp){ fwrite(&receive_packet,1,sizeof(receive_packet),fp); fclose(fp); } #endif /* make sure the request is valid */ if(validate_request(&receive_packet)==ERROR){ /* log an error */ syslog(LOG_ERR,"Client request was invalid, bailing out..."); /* free memory */ free(command_name); command_name=NULL; for(x=0;x<MAX_COMMAND_ARGUMENTS;x++){ free(macro_argv[x]); macro_argv[x]=NULL; } #ifdef HAVE_SSL if(ssl){ SSL_shutdown(ssl); SSL_free(ssl); } #endif return; } /* log info to syslog facility */ if(debug==TRUE) syslog(LOG_DEBUG,"Host is asking for command '%s' to be run...",receive_packet.buffer); /* disable connection alarm - a new alarm will be setup during my_system */ alarm(0); /* if this is the version check command, just spew it out */ if(!strcmp(command_name,NRPE_HELLO_COMMAND)){ snprintf(buffer,sizeof(buffer),"NRPE v%s",PROGRAM_VERSION); buffer[sizeof(buffer)-1]='\x0'; /* log info to syslog facility */ if(debug==TRUE) syslog(LOG_DEBUG,"Response: %s",buffer); result=STATE_OK; } /* find the command we're supposed to run */ else{ temp_command=find_command(command_name); if(temp_command==NULL){ snprintf(buffer,sizeof(buffer),"NRPE: Command '%s' not defined",command_name); buffer[sizeof(buffer)-1]='\x0'; /* log error to syslog facility */ if(debug==TRUE) syslog(LOG_DEBUG,"%s",buffer); result=STATE_CRITICAL; } else{ /* process command line */ if(command_prefix==NULL) strncpy(raw_command,temp_command->command_line,sizeof(raw_command)-1); else snprintf(raw_command,sizeof(raw_command)-1,"%s %s",command_prefix,temp_command->command_line); raw_command[sizeof(raw_command)-1]='\x0'; process_macros(raw_command,processed_command,sizeof(processed_command)); /* log info to syslog facility */ if(debug==TRUE) syslog(LOG_DEBUG,"Running command: %s",processed_command); /* run the command */ strcpy(buffer,""); result=my_system(processed_command,command_timeout,&early_timeout,buffer,sizeof(buffer)); /* log debug info */ if(debug==TRUE) syslog(LOG_DEBUG,"Command completed with return code %d and output: %s",result,buffer); /* see if the command timed out */ if(early_timeout==TRUE) snprintf(buffer,sizeof(buffer)-1,"NRPE: Command timed out after %d seconds\n",command_timeout); else if(!strcmp(buffer,"")) snprintf(buffer,sizeof(buffer)-1,"NRPE: Unable to read output\n"); buffer[sizeof(buffer)-1]='\x0'; /* check return code bounds */ if((result<0) || (result>3)){ /* log error to syslog facility */ syslog(LOG_ERR,"Bad return code for [%s]: %d", buffer,result); result=STATE_UNKNOWN; } } } /* free memory */ free(command_name); command_name=NULL; for(x=0;x<MAX_COMMAND_ARGUMENTS;x++){ free(macro_argv[x]); macro_argv[x]=NULL; } /* strip newline character from end of output buffer */ if(buffer[strlen(buffer)-1]=='\n') buffer[strlen(buffer)-1]='\x0'; /* clear the response packet buffer */ bzero(&send_packet,sizeof(send_packet)); /* fill the packet with semi-random data */ randomize_buffer((char *)&send_packet,sizeof(send_packet)); /* initialize response packet data */ send_packet.packet_version=(int16_t)htons(NRPE_PACKET_VERSION_2); send_packet.packet_type=(int16_t)htons(RESPONSE_PACKET); send_packet.result_code=(int16_t)htons(result); strncpy(&send_packet.buffer[0],buffer,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 RESPONSE *****/ /* send the response back to the client */ bytes_to_send=sizeof(send_packet); if(use_ssl==FALSE) sendall(sock,(char *)&send_packet,&bytes_to_send); #ifdef HAVE_SSL else SSL_write(ssl,&send_packet,bytes_to_send); #endif #ifdef HAVE_SSL if(ssl){ SSL_shutdown(ssl); SSL_free(ssl); } #endif /* log info to syslog facility */ if(debug==TRUE) syslog(LOG_DEBUG,"Return Code: %d, Output: %s",result,buffer); return; }
/* handle service check events */ static int handle_svc_check( int event_type, void *data ) { host * hst = NULL; service * svc = NULL; char *raw_command=NULL; char *processed_command=NULL; nebstruct_service_check_data * svcdata; int prio = GM_JOB_PRIO_LOW; check_result * chk_result; struct timeval core_time; struct tm next_check; char buffer1[GM_BUFFERSIZE]; gettimeofday(&core_time,NULL); gm_log( GM_LOG_TRACE, "handle_svc_check(%i, data)\n", event_type ); svcdata = ( nebstruct_service_check_data * )data; if ( event_type != NEBCALLBACK_SERVICE_CHECK_DATA ) return NEB_OK; /* ignore non-initiate service checks */ if ( svcdata->type != NEBTYPE_SERVICECHECK_ASYNC_PRECHECK ) return NEB_OK; /* get objects and set target function */ if((svc=svcdata->object_ptr)==NULL) { gm_log( GM_LOG_ERROR, "Service handler received NULL service object pointer.\n" ); return NEBERROR_CALLBACKCANCEL; } /* find the host associated with this service */ if((hst=svc->host_ptr)==NULL) { gm_log( GM_LOG_ERROR, "Service handler received NULL host object pointer.\n" ); return NEBERROR_CALLBACKCANCEL; } set_target_queue( hst, svc ); /* local check? */ if(!strcmp( target_queue, "" )) { gm_log( GM_LOG_DEBUG, "passing by local servicecheck: %s - %s\n", svcdata->host_name, svcdata->service_description); return NEB_OK; } gm_log( GM_LOG_DEBUG, "received job for queue %s: %s - %s\n", target_queue, svcdata->host_name, svcdata->service_description ); temp_buffer[0]='\x0'; /* as we have to intercept service checks so early * (we cannot cancel checks otherwise) * we have to do some service check logic here * taken from checks.c: */ /* clear check options - we don't want old check options retained */ svc->check_options=CHECK_OPTION_NONE; /* unset the freshening flag, otherwise only the first freshness check would be run */ svc->is_being_freshened=FALSE; /* grab the host and service macro variables */ clear_volatile_macros(); grab_host_macros(hst); grab_service_macros(svc); /* get the raw command line */ get_raw_command_line(svc->check_command_ptr,svc->check_command,&raw_command,0); if(raw_command==NULL){ gm_log( GM_LOG_ERROR, "Raw check command for service '%s' on host '%s' was NULL - aborting.\n", svc->description, svc->host_name ); return NEBERROR_CALLBACKCANCEL; } /* process any macros contained in the argument */ process_macros(raw_command, &processed_command, 0); if(processed_command==NULL) { gm_log( GM_LOG_ERROR, "Processed check command for service '%s' on host '%s' was NULL - aborting.\n", svc->description, svc->host_name); my_free(raw_command); return NEBERROR_CALLBACKCANCEL; } /* log latency */ if(mod_gm_opt->debug_level >= GM_LOG_DEBUG) { localtime_r(&svc->next_check, &next_check); strftime(buffer1, sizeof(buffer1), "%Y-%m-%d %H:%M:%S", &next_check ); gm_log( GM_LOG_DEBUG, "service: '%s' - '%s', next_check is at %s, latency so far: %i\n", svcdata->host_name, svcdata->service_description, buffer1, ((int)core_time.tv_sec - (int)svc->next_check)); } /* increment number of service checks that are currently running... */ currently_running_service_checks++; /* set the execution flag */ svc->is_executing=TRUE; gm_log( GM_LOG_TRACE, "cmd_line: %s\n", processed_command ); snprintf( temp_buffer,GM_BUFFERSIZE-1,"type=service\nresult_queue=%s\nhost_name=%s\nservice_description=%s\nstart_time=%i.0\nnext_check=%i.0\ncore_time=%i.%i\ntimeout=%d\ncommand_line=%s\n\n\n", mod_gm_opt->result_queue, svcdata->host_name, svcdata->service_description, (int)svc->next_check, (int)svc->next_check, (int)core_time.tv_sec, (int)core_time.tv_usec, service_check_timeout, processed_command ); uniq[0]='\x0'; snprintf( uniq,GM_BUFFERSIZE-1,"%s-%s", svcdata->host_name, svcdata->service_description); /* execute forced checks with high prio as they are propably user requested */ //if(check_result_info.check_options & CHECK_OPTION_FORCE_EXECUTION) // prio = GM_JOB_PRIO_HIGH; if(add_job_to_queue( &client, mod_gm_opt->server_list, target_queue, (mod_gm_opt->use_uniq_jobs == GM_ENABLED ? uniq : NULL), temp_buffer, prio, GM_DEFAULT_JOB_RETRIES, mod_gm_opt->transportmode, TRUE ) == GM_OK) { gm_log( GM_LOG_TRACE, "handle_svc_check() finished successfully\n" ); } else { my_free(raw_command); my_free(processed_command); /* unset the execution flag */ svc->is_executing=FALSE; /* decrement number of host checks that are currently running */ currently_running_service_checks--; gm_log( GM_LOG_TRACE, "handle_svc_check() finished unsuccessfully\n" ); return NEBERROR_CALLBACKCANCEL; } /* clean up */ my_free(raw_command); my_free(processed_command); /* orphaned check - submit fake result to mark service as orphaned */ if(mod_gm_opt->orphan_service_checks == GM_ENABLED && svc->check_options & CHECK_OPTION_ORPHAN_CHECK) { gm_log( GM_LOG_DEBUG, "service check for %s - %s orphaned\n", svc->host_name, svc->description ); if ( ( chk_result = ( check_result * )malloc( sizeof *chk_result ) ) == 0 ) return NEBERROR_CALLBACKCANCEL; snprintf( temp_buffer,GM_BUFFERSIZE-1,"(service check orphaned, is the mod-gearman worker on queue '%s' running?)\n", target_queue); init_check_result(chk_result); chk_result->host_name = strdup( svc->host_name ); chk_result->service_description = strdup( svc->description ); chk_result->scheduled_check = TRUE; chk_result->reschedule_check = TRUE; chk_result->output_file = 0; chk_result->output_file_fp = NULL; chk_result->output = strdup(temp_buffer); chk_result->return_code = mod_gm_opt->orphan_return; chk_result->check_options = CHECK_OPTION_NONE; chk_result->object_check_type = SERVICE_CHECK; chk_result->check_type = SERVICE_CHECK_ACTIVE; chk_result->start_time.tv_sec = (unsigned long)time(NULL); chk_result->finish_time.tv_sec = (unsigned long)time(NULL); chk_result->latency = 0; mod_gm_add_result_to_list( chk_result ); chk_result = NULL; } /* tell naemon to not execute */ gm_log( GM_LOG_TRACE, "handle_svc_check() finished successfully -> %d\n", NEBERROR_CALLBACKOVERRIDE ); return NEBERROR_CALLBACKOVERRIDE; }
/* handle host check events */ static int handle_host_check( int event_type, void *data ) { nebstruct_host_check_data * hostdata; char *raw_command=NULL; char *processed_command=NULL; host * hst; check_result * chk_result; int check_options; struct timeval core_time; struct tm next_check; char buffer1[GM_BUFFERSIZE]; gettimeofday(&core_time,NULL); gm_log( GM_LOG_TRACE, "handle_host_check(%i)\n", event_type ); if ( mod_gm_opt->do_hostchecks != GM_ENABLED ) return NEB_OK; hostdata = ( nebstruct_host_check_data * )data; gm_log( GM_LOG_TRACE, "---------------\nhost Job -> %i, %i\n", event_type, hostdata->type ); if ( event_type != NEBCALLBACK_HOST_CHECK_DATA ) return NEB_OK; /* ignore non-initiate host checks */ if ( hostdata->type != NEBTYPE_HOSTCHECK_ASYNC_PRECHECK && hostdata->type != NEBTYPE_HOSTCHECK_SYNC_PRECHECK) return NEB_OK; /* get objects and set target function */ if((hst=hostdata->object_ptr)==NULL) { gm_log( GM_LOG_ERROR, "Host handler received NULL host object pointer.\n" ); return NEBERROR_CALLBACKCANCEL; } set_target_queue( hst, NULL ); /* local check? */ if(!strcmp( target_queue, "" )) { gm_log( GM_LOG_DEBUG, "passing by local hostcheck: %s\n", hostdata->host_name ); return NEB_OK; } gm_log( GM_LOG_DEBUG, "received job for queue %s: %s\n", target_queue, hostdata->host_name ); /* as we have to intercept host checks so early * (we cannot cancel checks otherwise) * we have to do some host check logic here * taken from checks.c: */ /* clear check options - we don't want old check options retained */ check_options = hst->check_options; hst->check_options = CHECK_OPTION_NONE; /* unset the freshening flag, otherwise only the first freshness check would be run */ hst->is_being_freshened=FALSE; /* adjust host check attempt */ adjust_host_check_attempt(hst,TRUE); temp_buffer[0]='\x0'; /* grab the host macro variables */ clear_volatile_macros(); grab_host_macros(hst); /* get the raw command line */ get_raw_command_line(hst->check_command_ptr,hst->check_command,&raw_command,0); if(raw_command==NULL){ gm_log( GM_LOG_ERROR, "Raw check command for host '%s' was NULL - aborting.\n",hst->name ); return NEBERROR_CALLBACKCANCEL; } /* process any macros contained in the argument */ process_macros(raw_command,&processed_command,0); if(processed_command==NULL){ gm_log( GM_LOG_ERROR, "Processed check command for host '%s' was NULL - aborting.\n",hst->name); return NEBERROR_CALLBACKCANCEL; } /* log latency */ if(mod_gm_opt->debug_level >= GM_LOG_DEBUG) { localtime_r(&hst->next_check, &next_check); strftime(buffer1, sizeof(buffer1), "%Y-%m-%d %H:%M:%S", &next_check ); gm_log( GM_LOG_DEBUG, "host: '%s', next_check is at %s, latency so far: %i\n", hst->name, buffer1, ((int)core_time.tv_sec - (int)hst->next_check)); } /* increment number of host checks that are currently running */ currently_running_host_checks++; /* set the execution flag */ hst->is_executing=TRUE; gm_log( GM_LOG_TRACE, "cmd_line: %s\n", processed_command ); snprintf( temp_buffer,GM_BUFFERSIZE-1,"type=host\nresult_queue=%s\nhost_name=%s\nstart_time=%i.0\nnext_check=%i.0\ntimeout=%d\ncore_time=%i.%i\ncommand_line=%s\n\n\n", mod_gm_opt->result_queue, hst->name, (int)hst->next_check, (int)hst->next_check, host_check_timeout, (int)core_time.tv_sec, (int)core_time.tv_usec, processed_command ); if(add_job_to_queue( &client, mod_gm_opt->server_list, target_queue, (mod_gm_opt->use_uniq_jobs == GM_ENABLED ? hst->name : NULL), temp_buffer, GM_JOB_PRIO_NORMAL, GM_DEFAULT_JOB_RETRIES, mod_gm_opt->transportmode, TRUE ) == GM_OK) { } else { my_free(raw_command); my_free(processed_command); /* unset the execution flag */ hst->is_executing=FALSE; /* decrement number of host checks that are currently running */ currently_running_host_checks--; gm_log( GM_LOG_TRACE, "handle_host_check() finished unsuccessfully -> %d\n", NEBERROR_CALLBACKCANCEL ); return NEBERROR_CALLBACKCANCEL; } /* clean up */ my_free(raw_command); my_free(processed_command); /* orphaned check - submit fake result to mark host as orphaned */ if(mod_gm_opt->orphan_host_checks == GM_ENABLED && check_options & CHECK_OPTION_ORPHAN_CHECK) { gm_log( GM_LOG_DEBUG, "host check for %s orphaned\n", hst->name ); if ( ( chk_result = ( check_result * )malloc( sizeof *chk_result ) ) == 0 ) return NEBERROR_CALLBACKCANCEL; snprintf( temp_buffer,GM_BUFFERSIZE-1,"(host check orphaned, is the mod-gearman worker on queue '%s' running?)\n", target_queue); init_check_result(chk_result); chk_result->host_name = strdup( hst->name ); chk_result->scheduled_check = TRUE; chk_result->reschedule_check = TRUE; chk_result->output_file = 0; chk_result->output_file_fp = NULL; chk_result->output = strdup(temp_buffer); chk_result->return_code = mod_gm_opt->orphan_return; chk_result->check_options = CHECK_OPTION_NONE; chk_result->object_check_type = HOST_CHECK; chk_result->check_type = HOST_CHECK_ACTIVE; chk_result->start_time.tv_sec = (unsigned long)time(NULL); chk_result->finish_time.tv_sec = (unsigned long)time(NULL); chk_result->latency = 0; mod_gm_add_result_to_list( chk_result ); chk_result = NULL; } /* tell naemon to not execute */ gm_log( GM_LOG_TRACE, "handle_host_check() finished successfully -> %d\n", NEBERROR_CALLBACKOVERRIDE ); return NEBERROR_CALLBACKOVERRIDE; }
int run_command(const char *cmd, int flag){ cmd_tbl_t *cmdtp; char cmdbuf[CFG_CBSIZE]; /* working copy of cmd */ char *token; /* start of token in cmdbuf */ char *sep; /* end of token (separator) in cmdbuf */ char finaltoken[CFG_CBSIZE]; char *str = cmdbuf; char *argv[CFG_MAXARGS + 1]; /* NULL terminated */ int argc, inquotes; int repeatable = 1; int rc = 0; clear_ctrlc(); /* forget any previous Control C */ if(!cmd || !*cmd){ return(-1); /* empty command */ } if(strlen(cmd) >= CFG_CBSIZE){ puts("## Error: command too long!\n"); return(-1); } strcpy(cmdbuf, cmd); /* Process separators and check for invalid * repeatable commands */ while(*str){ /* * Find separator, or string end * Allow simple escape of ';' by writing "\;" */ for(inquotes = 0, sep = str; *sep; sep++){ if((*sep == '\'') && (*(sep - 1) != '\\')){ inquotes = !inquotes; } if(!inquotes && (*sep == ';') && (sep != str) && (*(sep - 1) != '\\')){ break; } } /* * Limit the token to data between separators */ token = str; if(*sep){ str = sep + 1; /* start of command for next pass */ *sep = '\0'; } else { str = sep; /* no more commands for next pass */ } /* find macros in this token and replace them */ process_macros(token, finaltoken); /* Extract arguments */ if((argc = parse_line(finaltoken, argv)) == 0){ rc = -1; /* no command at all */ continue; } /* Look up command in command table */ if((cmdtp = find_cmd(argv[0])) == NULL){ printf("## Error: unknown command '%s' - try 'help'\n\n", argv[0]); rc = -1; /* give up after bad command */ continue; } /* found - check max args */ if(argc > cmdtp->maxargs){ #ifdef CFG_LONGHELP if(cmdtp->help != NULL){ printf("Usage:\n%s %s\n", cmdtp->name, cmdtp->help); } else { printf("Usage:\n%s %s\n", cmdtp->name, cmdtp->usage); } #else printf("Usage:\n%s %s\n", cmdtp->name, cmdtp->usage); #endif rc = -1; continue; } /* OK - call function to do the command */ if((cmdtp->cmd)(cmdtp, flag, argc, argv) != 0){ rc = -1; } repeatable &= cmdtp->repeatable; /* Did the user stop this? */ if(had_ctrlc()){ /* if stopped then not repeatable */ return(0); } } return(rc ? rc : repeatable); }
void send_command(SESSION_STATE * session, char *buff, gsize len) { gchar *sendbuf = NULL; gchar *sb = NULL; len = strlen(buff); //convert semicolons to newlines, if allowed if (config->entry_seperator != NULL) utils_replace(buff, len, config->entry_seperator[0], '\n'); len = strlen(buff); // split into commands, process and send each command gchar **cmds = g_strsplit(buff, "\n", 0); int num = strv_length(cmds); int i; if (num == 0) { // empty command ... sendbuf = g_malloc0(3); sendbuf[0] = '\r'; sendbuf[1] = '\n'; sendbuf[2] = '\0'; network_data_send(session->telnet->fd, (unsigned char *) sendbuf, 2); g_free(sendbuf); return; } for (i = 0; i < num; ++i) { gchar *s = cmds[i]; len = strlen(s); // process macros if needed if (!process_macros(session, s, len)) { // expand variables sb = variables_expand(session->variables, s, len); len = strlen(sb); // report, log if (session->local_echo && session->telnet != NULL && !session->telnet->echo) { interface_echo_user_input(session, sb); interface_echo_user_input(session, "\n"); if ((session->logging) && (session->log_file)) { log_write_in_logfile(session-> log_file, sb, len); log_write_in_logfile(session-> log_file, "\n", 1); } } // send command //attach \r\n to the end sendbuf = g_malloc0(len + 3); g_strlcpy(sendbuf, sb, len + 3); // this is no longer needed - no \n in the middle of the string // utils_LF2CRLF(&sendbuf, &len); // convert \n to \r\n sendbuf[len] = '\r'; sendbuf[len + 1] = '\n'; sendbuf[len + 2] = '\0'; // and send it network_data_send(session->telnet->fd, (unsigned char *) sendbuf, len + 2); g_free(sendbuf); g_free(sb); } } g_strfreev(cmds); }