/************************************************************************ * * NOTIFICATIONS.C - NetSaint Notifications CGI * * Copyright (c) 1999-2001 Ethan Galstad (netsaint@netsaint.org) * Last Modified: 06-08-2001 * * This CGI program will display the notification events for * a given host or contact or for all contacts/hosts. * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ***********************************************************************/ #include "../common/config.h" #include "../common/locations.h" #include "../common/common.h" #include "getcgi.h" #include "cgiutils.h" #include "auth.h" #include "lifo.h" extern char main_config_file[MAX_FILENAME_LENGTH]; extern char url_html_path[MAX_FILENAME_LENGTH]; extern char url_images_path[MAX_FILENAME_LENGTH]; extern char url_docs_path[MAX_FILENAME_LENGTH]; extern char url_stylesheets_path[MAX_FILENAME_LENGTH]; extern int log_rotation_method; extern time_t this_scheduled_log_rotation; extern time_t last_scheduled_log_rotation; #define FIND_HOST 1 #define FIND_CONTACT 2 #define FIND_SERVICE 3 #define MAX_QUERYNAME_LENGTH 256 #define SERVICE_NOTIFICATION 0 #define HOST_NOTIFICATION 1 #define SERVICE_NOTIFICATION_STRING "] SERVICE NOTIFICATION:" #define HOST_NOTIFICATION_STRING "] HOST NOTIFICATION:" void display_notifications(void); void document_header(int); void document_footer(void); int process_cgivars(void); authdata current_authdata; char log_file_to_use[MAX_FILENAME_LENGTH]; int log_archive=0; int query_type=FIND_HOST; int find_all=TRUE; char *query_contact_name="all"; char *query_host_name="all"; char *query_svc_description=""; int notification_options=NOTIFICATION_ALL; int use_lifo=TRUE; int embedded=FALSE; int display_header=TRUE; int main(void){ int result=OK; char temp_buffer[MAX_INPUT_BUFFER]; char temp_buffer2[MAX_INPUT_BUFFER]; /* get the arguments passed in the URL */ process_cgivars(); /* reset internal variables */ reset_cgi_vars(); /* read the CGI configuration file */ result=read_cgi_config_file(DEFAULT_CGI_CONFIG_FILE); if(result==ERROR){ document_header(FALSE); printf("

Error: Could not open CGI configuration file '%s' for reading!

\n",DEFAULT_CGI_CONFIG_FILE); document_footer(); return ERROR; } document_header(TRUE); /* read the main configuration file */ result=read_main_config_file(main_config_file); if(result==ERROR){ printf("

Error: Could not open main configuration file '%s' for reading!

\n",main_config_file); document_footer(); return ERROR; } /* read all object configuration data */ result=read_all_object_configuration_data(main_config_file,READ_HOSTGROUPS|READ_CONTACTGROUPS|READ_HOSTS|READ_SERVICES); if(result==ERROR){ printf("

Error: Could not read some or all object configuration data!

\n"); document_footer(); return ERROR; } /* get authentication information */ get_authentication_information(¤t_authdata); /* determine what log file we should use */ get_log_archive_to_use(log_archive,log_file_to_use,(int)sizeof(log_file_to_use)); if(display_header==TRUE){ /* begin top table */ printf("\n"); printf("\n"); /* left column of top row */ printf("\n"); /* middle column of top row */ printf("\n"); /* right hand column of top row */ printf("\n"); /* end of top table */ printf("\n"); printf("
\n"); if(query_type==FIND_SERVICE) snprintf(temp_buffer,sizeof(temp_buffer)-1,"Notifications For Service %s On Host %s",query_svc_description,query_host_name); else{ if(find_all==TRUE) snprintf(temp_buffer,sizeof(temp_buffer)-1,"Notifications For All %s",(query_type==FIND_HOST)?"Hosts":"Contacts"); else snprintf(temp_buffer,sizeof(temp_buffer)-1,"Notifications For %s %s",(query_type==FIND_HOST)?"Host":"Contact",(query_type==FIND_HOST)?query_host_name:query_contact_name); } temp_buffer[sizeof(temp_buffer)-1]='\x0'; display_info_table(temp_buffer,FALSE,¤t_authdata); if(query_type==FIND_HOST || query_type==FIND_SERVICE){ printf("\n"); printf("\n"); printf("\n"); } printf("\n"); if(query_type==FIND_SERVICE){ snprintf(temp_buffer,sizeof(temp_buffer)-1,"%s?%shost=%s&",NOTIFICATIONS_CGI,(use_lifo==FALSE)?"oldestfirst&":"",url_encode(query_host_name)); snprintf(temp_buffer2,sizeof(temp_buffer2)-1,"service=%s&type=%d&",url_encode(query_svc_description),notification_options); strncat(temp_buffer,temp_buffer2,sizeof(temp_buffer)-strlen(temp_buffer)-1); } else snprintf(temp_buffer,sizeof(temp_buffer)-1,"%s?%s%s=%s&type=%d&",NOTIFICATIONS_CGI,(use_lifo==FALSE)?"oldestfirst&":"",(query_type==FIND_HOST)?"host":"contact",(query_type==FIND_HOST)?url_encode(query_host_name):url_encode(query_contact_name),notification_options); temp_buffer[sizeof(temp_buffer)-1]='\x0'; display_nav_table(temp_buffer,log_archive); printf("\n"); printf("\n"); printf("\n",NOTIFICATIONS_CGI); if(query_type==FIND_SERVICE){ printf("\n",query_host_name); printf("\n",query_svc_description); } else printf("\n",(query_type==FIND_HOST)?"host":"contact",(query_type==FIND_HOST)?query_host_name:query_contact_name); printf("\n",log_archive); printf("\n"); if(query_type==FIND_SERVICE) printf(""); else printf("",(find_all==TRUE)?"all":"this",(query_type==FIND_HOST)?"host":"contact",(find_all==TRUE)?"s":""); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("",(use_lifo==FALSE)?"checked":""); printf("\n"); printf("\n"); printf("\n"); printf("
Notification detail level for this service:Notification detail level for %s %s%s:
Older Entries First:
\n"); printf("
\n"); } /* display notifications */ display_notifications(); document_footer(); /* free allocated memory */ free_memory(); return OK; } void document_header(int use_stylesheet){ char date_time[MAX_DATETIME_LENGTH]; time_t current_time; time_t expire_time; printf("Cache-Control: no-store\n"); printf("Pragma: no-cache\n"); time(¤t_time); get_time_string(¤t_time,date_time,(int)sizeof(date_time),HTTP_DATE_TIME); printf("Last-Modified: %s\n",date_time); expire_time=(time_t)0L; get_time_string(&expire_time,date_time,(int)sizeof(date_time),HTTP_DATE_TIME); printf("Expires: %s\n",date_time); printf("Content-type: text/html\r\n\r\n"); if(embedded==TRUE) return; printf("\n"); printf("\n"); printf("\n"); printf("Alert Notifications\n"); printf("\n"); if(use_stylesheet==TRUE) printf("\n",url_stylesheets_path,NOTIFICATIONS_CSS); printf("\n"); printf("\n"); return; } void document_footer(void){ if(embedded==TRUE) return; printf("\n"); printf("\n"); return; } int process_cgivars(void){ char **variables; int error=FALSE; int x; variables=getcgivars(); for(x=0;variables[x]!=NULL;x++){ /* do some basic length checking on the variable identifier to prevent buffer overflows */ if(strlen(variables[x])>=MAX_INPUT_BUFFER-1){ x++; continue; } /* we found the host argument */ else if(!strcmp(variables[x],"host")){ query_type=FIND_HOST; x++; if(variables[x]==NULL){ error=TRUE; break; } query_host_name=variables[x]; if(!strcmp(query_host_name,"all")) find_all=TRUE; else find_all=FALSE; } /* we found the contact argument */ else if(!strcmp(variables[x],"contact")){ query_type=FIND_CONTACT; x++; if(variables[x]==NULL){ error=TRUE; break; } query_contact_name=variables[x]; if(!strcmp(query_contact_name,"all")) find_all=TRUE; else find_all=FALSE; } /* we found the service argument */ else if(!strcmp(variables[x],"service")){ query_type=FIND_SERVICE; x++; if(variables[x]==NULL){ error=TRUE; break; } query_svc_description=variables[x]; } /* we found the notification type argument */ else if(!strcmp(variables[x],"type")){ x++; if(variables[x]==NULL){ error=TRUE; break; } notification_options=atoi(variables[x]); } /* we found the log archive argument */ else if(!strcmp(variables[x],"archive")){ x++; if(variables[x]==NULL){ error=TRUE; break; } log_archive=atoi(variables[x]); if(log_archive<0) log_archive=0; } /* we found the order argument */ else if(!strcmp(variables[x],"oldestfirst")){ use_lifo=FALSE; } /* we found the embed option */ else if(!strcmp(variables[x],"embedded")) embedded=TRUE; /* we found the noheader option */ else if(!strcmp(variables[x],"noheader")) display_header=FALSE; } return error; } void display_notifications(void){ FILE *fp=NULL; char input_buffer[MAX_INPUT_BUFFER]; char *temp_buffer; char date_time[MAX_DATETIME_LENGTH]; char alert_level[MAX_INPUT_BUFFER]; char alert_level_class[MAX_INPUT_BUFFER]; char contact_name[MAX_INPUT_BUFFER]; char service_name[MAX_INPUT_BUFFER]; char host_name[MAX_INPUT_BUFFER]; char method_name[MAX_INPUT_BUFFER]; int show_entry; int total_notifications; int notification_type=SERVICE_NOTIFICATION; int notification_detail_type=NOTIFICATION_SERVICE_CRITICAL; int odd=0; time_t t; host *temp_host; service *temp_service; int result; if(use_lifo==TRUE){ result=read_file_into_lifo(log_file_to_use); if(result!=LIFO_OK){ if(result==LIFO_ERROR_MEMORY){ printf("

Not enough memory to reverse log file - displaying notifications in natural order...

"); } else if(result==LIFO_ERROR_FILE){ printf("

Error: Cannot open log file '%s' for reading!

",log_file_to_use); return; } use_lifo=FALSE; } } if(use_lifo==FALSE){ fp=fopen(log_file_to_use,"r"); if(fp==NULL){ printf("

Error: Cannot open log file '%s' for reading!

",log_file_to_use); return; } } printf("

\n"); printf("

\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); total_notifications=0; while(1){ if(use_lifo==TRUE){ if(pop_lifo(input_buffer,(int)sizeof(input_buffer))!=LIFO_OK) break; } else{ fgets(input_buffer,(int)(sizeof(input_buffer)-1),fp); if(feof(fp)) break; } /* see if this line contains the notification event string */ if(strstr(input_buffer,HOST_NOTIFICATION_STRING)||strstr(input_buffer,SERVICE_NOTIFICATION_STRING)){ if(strstr(input_buffer,HOST_NOTIFICATION_STRING)) notification_type=HOST_NOTIFICATION; else notification_type=SERVICE_NOTIFICATION; /* get the date/time */ temp_buffer=(char *)strtok(input_buffer,"]"); t=(time_t)(temp_buffer==NULL)?0L:strtoul(temp_buffer+1,NULL,10); get_time_string(&t,date_time,(int)sizeof(date_time),SHORT_DATE_TIME); strip(date_time); /* get the contact name */ temp_buffer=(char *)strtok(NULL,":"); temp_buffer=(char *)strtok(NULL,";"); snprintf(contact_name,sizeof(contact_name),"%s",(temp_buffer==NULL)?"":temp_buffer+1); contact_name[sizeof(contact_name)-1]='\x0'; /* get the host name */ temp_buffer=(char *)strtok(NULL,";"); snprintf(host_name,sizeof(host_name),"%s",(temp_buffer==NULL)?"":temp_buffer); host_name[sizeof(host_name)]='\x0'; /* get the service name */ if(notification_type==SERVICE_NOTIFICATION){ temp_buffer=(char *)strtok(NULL,";"); snprintf(service_name,sizeof(service_name),"%s",(temp_buffer==NULL)?"":temp_buffer); service_name[sizeof(service_name)-1]='\x0'; } /* get the alert level */ temp_buffer=(char *)strtok(NULL,";"); snprintf(alert_level,sizeof(alert_level),"%s",(temp_buffer==NULL)?"":temp_buffer); alert_level[sizeof(alert_level)-1]='\x0'; if(notification_type==SERVICE_NOTIFICATION){ if(!strcmp(alert_level,"CRITICAL")){ notification_detail_type=NOTIFICATION_SERVICE_CRITICAL; strcpy(alert_level_class,"CRITICAL"); } else if(!strcmp(alert_level,"WARNING")){ notification_detail_type=NOTIFICATION_SERVICE_WARNING; strcpy(alert_level_class,"WARNING"); } else if(!strcmp(alert_level,"RECOVERY") || !strcmp(alert_level,"OK")){ strcpy(alert_level,"OK"); notification_detail_type=NOTIFICATION_SERVICE_RECOVERY; strcpy(alert_level_class,"OK"); } else if(strstr(alert_level,"ACKNOWLEDGEMENT (")){ notification_detail_type=NOTIFICATION_SERVICE_ACK; strcpy(alert_level_class,"ACKNOWLEDGEMENT"); } else{ strcpy(alert_level,"UNKNOWN"); notification_detail_type=NOTIFICATION_SERVICE_UNKNOWN; strcpy(alert_level_class,"UNKNOWN"); } } else{ if(!strcmp(alert_level,"DOWN")){ strncpy(alert_level,"HOST DOWN",sizeof(alert_level)); strcpy(alert_level_class,"HOSTDOWN"); notification_detail_type=NOTIFICATION_HOST_DOWN; } else if(!strcmp(alert_level,"UNREACHABLE")){ strncpy(alert_level,"HOST UNREACHABLE",sizeof(alert_level)); strcpy(alert_level_class,"HOSTUNREACHABLE"); notification_detail_type=NOTIFICATION_HOST_UNREACHABLE; } else if(!strcmp(alert_level,"RECOVERY") || !strcmp(alert_level,"UP")){ strncpy(alert_level,"HOST UP",sizeof(alert_level)); strcpy(alert_level_class,"HOSTUP"); notification_detail_type=NOTIFICATION_HOST_RECOVERY; } else if(strstr(alert_level,"ACKNOWLEDGEMENT (")){ strcpy(alert_level_class,"HOSTACKNOWLEDGEMENT"); notification_detail_type=NOTIFICATION_HOST_ACK; } } /* get the method name */ temp_buffer=(char *)strtok(NULL,";"); snprintf(method_name,sizeof(method_name),"%s",(temp_buffer==NULL)?"":temp_buffer); method_name[sizeof(method_name)-1]='\x0'; /* move to the informational message */ temp_buffer=strtok(NULL,";"); show_entry=FALSE; /* if we're searching by contact, filter out unwanted contact */ if(query_type==FIND_CONTACT){ if(find_all==TRUE) show_entry=TRUE; else if(!strcmp(query_contact_name,contact_name)) show_entry=TRUE; } else if(query_type==FIND_HOST){ if(find_all==TRUE) show_entry=TRUE; else if(!strcmp(query_host_name,host_name)) show_entry=TRUE; } else if(query_type==FIND_SERVICE){ if(!strcmp(query_host_name,host_name) && !strcmp(query_svc_description,service_name)) show_entry=TRUE; } if(show_entry==TRUE){ if(notification_options==NOTIFICATION_ALL) show_entry=TRUE; else if(notification_options==NOTIFICATION_HOST_ALL && notification_type==HOST_NOTIFICATION) show_entry=TRUE; else if(notification_options==NOTIFICATION_SERVICE_ALL && notification_type==SERVICE_NOTIFICATION) show_entry=TRUE; else if(notification_detail_type & notification_options) show_entry=TRUE; else show_entry=FALSE; } /* make sure user has authorization to view this notification */ if(notification_type==HOST_NOTIFICATION){ temp_host=find_host(host_name,NULL); if(is_authorized_for_host(temp_host,¤t_authdata)==FALSE) show_entry=FALSE; } else{ temp_service=find_service(host_name,service_name,NULL); if(is_authorized_for_service(temp_service,¤t_authdata)==FALSE) show_entry=FALSE; } if(show_entry==TRUE){ total_notifications++; if(odd){ odd=0; printf("\n"); } else{ odd=1; printf("\n"); } printf("\n",(odd)?"Even":"Odd",EXTINFO_CGI,DISPLAY_HOST_INFO,url_encode(host_name),host_name); if(notification_type==SERVICE_NOTIFICATION){ printf("\n",url_encode(service_name),service_name); } else printf("\n",(odd)?"Even":"Odd"); printf("\n",alert_level_class,alert_level); printf("\n",(odd)?"Even":"Odd",date_time); printf("\n",(odd)?"Even":"Odd",CONFIG_CGI,url_encode(contact_name),contact_name); printf("\n",(odd)?"Even":"Odd",CONFIG_CGI,url_encode(method_name),method_name); printf("\n",(odd)?"Even":"Odd",temp_buffer); printf("\n"); } } } printf("
HostServiceTypeTimeContactNotification CommandInformation
%s%sN/A%s%s%s%s%s
\n"); printf("
\n"); printf("

\n"); if(total_notifications==0){ printf("

No notifications have been recorded"); if(find_all==FALSE){ if(query_type==FIND_SERVICE) printf(" for this service"); else if(query_type==FIND_CONTACT) printf(" for this contact"); else printf(" for this host"); } printf(" in %s log file

",(log_archive==0)?"the current":"this archived"); } if(use_lifo==TRUE) free_lifo_memory(); else fclose(fp); return; }