/***********************************************************************
*
* CONFIG.C - Nagios Configuration CGI (View Only)
*
*
* This CGI program will display various configuration information.
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* 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 "../include/config.h"
#include "../include/common.h"
#include "../include/objects.h"
#include "../include/macros.h"
#include "../include/cgiutils.h"
#include "../include/cgiauth.h"
#include "../include/getcgi.h"
static nagios_macros *mac;
extern char main_config_file[MAX_FILENAME_LENGTH];
extern char url_html_path[MAX_FILENAME_LENGTH];
extern char url_docs_path[MAX_FILENAME_LENGTH];
extern char url_images_path[MAX_FILENAME_LENGTH];
extern char url_logo_images_path[MAX_FILENAME_LENGTH];
extern char url_stylesheets_path[MAX_FILENAME_LENGTH];
#define DISPLAY_NONE 0
#define DISPLAY_HOSTS 1
#define DISPLAY_HOSTGROUPS 2
#define DISPLAY_CONTACTS 3
#define DISPLAY_CONTACTGROUPS 4
#define DISPLAY_SERVICES 5
#define DISPLAY_TIMEPERIODS 6
#define DISPLAY_COMMANDS 7
#define DISPLAY_HOSTGROUPESCALATIONS 8 /* no longer implemented */
#define DISPLAY_SERVICEDEPENDENCIES 9
#define DISPLAY_SERVICEESCALATIONS 10
#define DISPLAY_HOSTDEPENDENCIES 11
#define DISPLAY_HOSTESCALATIONS 12
#define DISPLAY_SERVICEGROUPS 15
#define DISPLAY_COMMAND_EXPANSION 16211
void document_header(int);
void document_footer(void);
int process_cgivars(void);
void display_options(void);
void display_hosts(void);
void display_hostgroups(void);
void display_servicegroups(void);
void display_contacts(void);
void display_contactgroups(void);
void display_services(void);
void display_timeperiods(void);
void display_commands(void);
void display_servicedependencies(void);
void display_serviceescalations(void);
void display_hostdependencies(void);
void display_hostescalations(void);
void display_command_expansion(void);
void unauthorized_message(void);
authdata current_authdata;
int display_type = DISPLAY_NONE;
char to_expand[MAX_COMMAND_BUFFER];
char hashed_color[8];
int embedded = FALSE;
static void print_expand_input(int type) {
const char *seldesc = "";
if(type == DISPLAY_COMMAND_EXPANSION) return; /* Has its own form, w/ larger */
else if(type == DISPLAY_SERVICES) {
seldesc = " Services Named or on Host";
}
else if(type == DISPLAY_SERVICEDEPENDENCIES) {
seldesc = " Dependencies with Host";
}
else if(type == DISPLAY_SERVICEESCALATIONS) {
seldesc = " Escalations on Host";
}
else if(type == DISPLAY_HOSTDEPENDENCIES) {
seldesc = " Dependencies on/of Host";
}
else if(type == DISPLAY_HOSTESCALATIONS) {
seldesc = " Escalations for Host";
}
printf("
Show Only%s:
\n", seldesc);
printf("
", html_encode(to_expand, FALSE));
}
int main(void) {
mac = get_global_macros();
/* get the arguments passed in the URL */
process_cgivars();
/* reset internal variables */
reset_cgi_vars();
cgi_init(document_header, document_footer, READ_ALL_OBJECT_DATA, 0);
/* initialize macros */
init_macros();
document_header(TRUE);
/* get authentication information */
get_authentication_information(¤t_authdata);
/* begin top table */
printf("
\n");
if(display_type != DISPLAY_NONE) {
printf("\n");
}
/* display context-sensitive help */
switch(display_type) {
case DISPLAY_HOSTS:
display_context_help(CONTEXTHELP_CONFIG_HOSTS);
break;
case DISPLAY_HOSTGROUPS:
display_context_help(CONTEXTHELP_CONFIG_HOSTGROUPS);
break;
case DISPLAY_SERVICEGROUPS:
display_context_help(CONTEXTHELP_CONFIG_SERVICEGROUPS);
break;
case DISPLAY_CONTACTS:
display_context_help(CONTEXTHELP_CONFIG_CONTACTS);
break;
case DISPLAY_CONTACTGROUPS:
display_context_help(CONTEXTHELP_CONFIG_CONTACTGROUPS);
break;
case DISPLAY_SERVICES:
display_context_help(CONTEXTHELP_CONFIG_SERVICES);
break;
case DISPLAY_TIMEPERIODS:
display_context_help(CONTEXTHELP_CONFIG_TIMEPERIODS);
break;
case DISPLAY_COMMANDS:
display_context_help(CONTEXTHELP_CONFIG_COMMANDS);
break;
case DISPLAY_SERVICEDEPENDENCIES:
display_context_help(CONTEXTHELP_CONFIG_SERVICEDEPENDENCIES);
break;
case DISPLAY_SERVICEESCALATIONS:
display_context_help(CONTEXTHELP_CONFIG_HOSTESCALATIONS);
break;
case DISPLAY_HOSTDEPENDENCIES:
display_context_help(CONTEXTHELP_CONFIG_HOSTDEPENDENCIES);
break;
case DISPLAY_HOSTESCALATIONS:
display_context_help(CONTEXTHELP_CONFIG_HOSTESCALATIONS);
break;
case DISPLAY_COMMAND_EXPANSION:
/* Reusing DISPLAY_COMMANDS help until further notice */
display_context_help(CONTEXTHELP_CONFIG_COMMANDS);
break;
default:
display_context_help(CONTEXTHELP_CONFIG_MENU);
break;
}
printf("
\n");
/* end of top table */
printf("
\n");
printf("
\n");
switch(display_type) {
case DISPLAY_HOSTS:
display_hosts();
break;
case DISPLAY_HOSTGROUPS:
display_hostgroups();
break;
case DISPLAY_SERVICEGROUPS:
display_servicegroups();
break;
case DISPLAY_CONTACTS:
display_contacts();
break;
case DISPLAY_CONTACTGROUPS:
display_contactgroups();
break;
case DISPLAY_SERVICES:
display_services();
break;
case DISPLAY_TIMEPERIODS:
display_timeperiods();
break;
case DISPLAY_COMMANDS:
display_commands();
break;
case DISPLAY_SERVICEDEPENDENCIES:
display_servicedependencies();
break;
case DISPLAY_SERVICEESCALATIONS:
display_serviceescalations();
break;
case DISPLAY_HOSTDEPENDENCIES:
display_hostdependencies();
break;
case DISPLAY_HOSTESCALATIONS:
display_hostescalations();
break;
case DISPLAY_COMMAND_EXPANSION:
display_command_expansion();
break;
default:
display_options();
break;
}
document_footer();
return OK;
}
void document_header(int use_stylesheet) {
char date_time[MAX_DATETIME_LENGTH];
time_t t;
if(embedded == TRUE)
return;
time(&t);
get_time_string(&t, date_time, sizeof(date_time), HTTP_DATE_TIME);
printf("Cache-Control: no-store\r\n");
printf("Pragma: no-cache\r\n");
printf("Last-Modified: %s\r\n", date_time);
printf("Expires: %s\r\n", date_time);
printf("Content-type: text/html; charset=utf-8\r\n\r\n");
printf("\n");
printf("\n");
printf("\n", url_images_path);
printf("\n");
printf("\n");
printf("Configuration\n");
printf("\n");
if(use_stylesheet == TRUE) {
printf("\n", url_stylesheets_path, COMMON_CSS);
printf("\n", url_stylesheets_path, CONFIG_CSS);
}
printf("\n");
printf("\n");
/* include user SSI header */
include_ssi_files(CONFIG_CGI, SSI_HEADER);
return;
}
void document_footer(void) {
if(embedded == TRUE)
return;
/* include user SSI footer */
include_ssi_files(CONFIG_CGI, SSI_FOOTER);
printf("\n");
printf("\n");
return;
}
int process_cgivars(void) {
char **variables;
int error = FALSE;
int x;
variables = getcgivars();
to_expand[0] = '\0';
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) {
continue;
}
/* we found the configuration type argument */
else if(!strcmp(variables[x], "type")) {
x++;
if(variables[x] == NULL) {
error = TRUE;
break;
}
/* what information should we display? */
if(!strcmp(variables[x], "hosts"))
display_type = DISPLAY_HOSTS;
else if(!strcmp(variables[x], "hostgroups"))
display_type = DISPLAY_HOSTGROUPS;
else if(!strcmp(variables[x], "servicegroups"))
display_type = DISPLAY_SERVICEGROUPS;
else if(!strcmp(variables[x], "contacts"))
display_type = DISPLAY_CONTACTS;
else if(!strcmp(variables[x], "contactgroups"))
display_type = DISPLAY_CONTACTGROUPS;
else if(!strcmp(variables[x], "services"))
display_type = DISPLAY_SERVICES;
else if(!strcmp(variables[x], "timeperiods"))
display_type = DISPLAY_TIMEPERIODS;
else if(!strcmp(variables[x], "commands"))
display_type = DISPLAY_COMMANDS;
else if(!strcmp(variables[x], "servicedependencies"))
display_type = DISPLAY_SERVICEDEPENDENCIES;
else if(!strcmp(variables[x], "serviceescalations"))
display_type = DISPLAY_SERVICEESCALATIONS;
else if(!strcmp(variables[x], "hostdependencies"))
display_type = DISPLAY_HOSTDEPENDENCIES;
else if(!strcmp(variables[x], "hostescalations"))
display_type = DISPLAY_HOSTESCALATIONS;
else if(!strcmp(variables[x], "command"))
display_type = DISPLAY_COMMAND_EXPANSION;
/* we found the embed option */
else if(!strcmp(variables[x], "embedded"))
embedded = TRUE;
}
/* we found the string-to-expand argument */
else if(!strcmp(variables[x], "expand")) {
x++;
if(variables[x] == NULL) {
error = TRUE;
break;
}
strncpy(to_expand, variables[x], MAX_COMMAND_BUFFER);
to_expand[MAX_COMMAND_BUFFER - 1] = '\0';
}
/* we received an invalid argument */
else
error = TRUE;
}
/* free memory allocated to the CGI variables */
free_cgivars(variables);
return error;
}
void display_hosts(void) {
host *temp_host = NULL;
hostsmember *temp_hostsmember = NULL;
contactsmember *temp_contactsmember = NULL;
contactgroupsmember *temp_contactgroupsmember = NULL;
char *processed_string = NULL;
int options = 0;
int odd = 0;
char time_string[16];
const char *bg_class = "";
int num_contacts = 0;
/* see if user is authorized to view host information... */
if(is_authorized_for_configuration_information(¤t_authdata) == FALSE) {
unauthorized_message();
return;
}
printf("
\n");
}
void display_servicedependencies(void) {
unsigned int i;
/* see if user is authorized to view hostgroup information... */
if(is_authorized_for_configuration_information(¤t_authdata) == FALSE) {
unauthorized_message();
return;
}
printf("
\n");
}
void display_hostdependencies(void) {
unsigned int i;
/* see if user is authorized to view hostdependency information... */
if(is_authorized_for_configuration_information(¤t_authdata) == FALSE) {
unauthorized_message();
return;
}
printf("
It appears as though you do not have permission to view the configuration information you requested...
\n");
printf("
If you believe this is an error, check the HTTP server authentication requirements for accessing this CGI ");
printf("and check the authorization options in your CGI configuration file.
\n");
return;
}
static const char *hash_color(int i) {
char c;
/* This is actually optimized for MAX_COMMAND_ARGUMENTS==32 ... */
if((i % 32) < 16) {
if((i % 32) < 8) c = '7';
else c = '4';
}
else {
if((i % 32) < 24) c = '6';
else c = '5';
}
/* Computation for standard case */
hashed_color[0] = '#';
hashed_color[1] = hashed_color[2] = ((i % 2) ? c : '0');
hashed_color[3] = hashed_color[4] = (((i / 2) % 2) ? c : '0');
hashed_color[5] = hashed_color[6] = (((i / 4) % 2) ? c : '0');
hashed_color[7] = '\0';
/* Override shades of grey */
if((i % 8) == 7) hashed_color[1] = hashed_color[3] = '0';
if((i % 8) == 0) hashed_color[2] = hashed_color[3] = hashed_color[4] = hashed_color[6] = c;
return(hashed_color);
}
void display_command_expansion(void) {
command *temp_command;
int odd = 0;
const char *bg_class = "";
int i, j;
char *c, *cc;
char commandline[MAX_COMMAND_BUFFER];
char *command_args[MAX_COMMAND_ARGUMENTS];
int arg_count[MAX_COMMAND_ARGUMENTS],
lead_space[MAX_COMMAND_ARGUMENTS],
trail_space[MAX_COMMAND_ARGUMENTS];
/* see if user is authorized to view command information... */
if(is_authorized_for_configuration_information(¤t_authdata) == FALSE) {
unauthorized_message();
return;
}
printf("
Command Expansion
\n");
/* Parse to_expand into parts */
for(i = 0; i < MAX_COMMAND_ARGUMENTS; i++) command_args[i] = NULL;
for(i = 0, command_args[0] = cc = c = strdup(to_expand); c && ((*c) != '\0') && (i < MAX_COMMAND_ARGUMENTS); c++, cc++) {
if((*c) == '\\') c++;
else if((*c) == '!') {
(*cc) = '\0';
cc = c++;
command_args[++i] = (c--);
}
(*cc) = (*c);
}
if((*c) == '\0')(*cc) = '\0';
/* Precompute indexes of dangling whitespace */
for(i = 0; i < MAX_COMMAND_ARGUMENTS; i++) {
for(cc = command_args[i], lead_space[i] = 0; cc && isspace(*cc); cc++, lead_space[i]++) ;
trail_space[i] = 0;
for(; cc && ((*cc) != '\0'); cc++) if(isspace(*cc)) trail_space[i]++;
else trail_space[i] = 0;
}
printf("