/* handles scheduled host or service downtime */
int handle_scheduled_downtime(scheduled_downtime *temp_downtime) {
	scheduled_downtime *this_downtime = NULL;
	host *hst = NULL;
	service *svc = NULL;
	time_t event_time = 0L;
	time_t current_time = 0L;
	unsigned long *new_downtime_id = NULL;
#ifdef USE_EVENT_BROKER
	int attr = 0;
#endif


	log_debug_info(DEBUGL_FUNCTIONS, 0, "handle_scheduled_downtime()\n");

	if (temp_downtime == NULL)
		return ERROR;

	/* find the host or service associated with this downtime */
	if (temp_downtime->type == HOST_DOWNTIME) {
		if ((hst = find_host(temp_downtime->host_name)) == NULL)
			return ERROR;
	} else {
		if ((svc = find_service(temp_downtime->host_name, temp_downtime->service_description)) == NULL)
			return ERROR;
	}

	/* if downtime if flexible and host/svc is in an ok state, don't do anything right now (wait for event handler to kick it off) */
	/* start_flex_downtime variable is set to TRUE by event handler functions */
	if (temp_downtime->fixed == FALSE) {

		/* we're not supposed to force a start of flex downtime... */
		if (temp_downtime->start_flex_downtime == FALSE) {

			/* host is up or service is ok, so we don't really do anything right now */
			if ((temp_downtime->type == HOST_DOWNTIME && hst->current_state == HOST_UP) || (temp_downtime->type == SERVICE_DOWNTIME && svc->current_state == STATE_OK)) {

				/* increment pending flex downtime counter */
				if (temp_downtime->type == HOST_DOWNTIME)
					hst->pending_flex_downtime++;
				else
					svc->pending_flex_downtime++;
				temp_downtime->incremented_pending_downtime = TRUE;

				/*** SINCE THE FLEX DOWNTIME MAY NEVER START, WE HAVE TO PROVIDE A WAY OF EXPIRING UNUSED DOWNTIME... ***/

				schedule_new_event(EVENT_EXPIRE_DOWNTIME, TRUE, (temp_downtime->end_time + 1), FALSE, 0, NULL, FALSE, NULL, NULL, 0);

				return OK;
			}
		}
	}

	time(&current_time);

	/* have we come to the end of the scheduled downtime? */
	if (temp_downtime->is_in_effect == TRUE && ( /* downtime needs to be in effect and ... */
		(temp_downtime->fixed == TRUE && current_time >= temp_downtime->end_time) || /* fixed downtime, endtime means end of downtime */
		(temp_downtime->fixed == FALSE && current_time >= (temp_downtime->trigger_time+temp_downtime->duration)) /* flexible downtime, endtime of downtime is trigger_time+duration */
	)){

		if (temp_downtime->type == HOST_DOWNTIME)
			log_debug_info(DEBUGL_DOWNTIME, 0, "Host '%s' ending %s scheduled downtime (id=%lu) with depth=%d, starttime=%lu, entrytime=%lu, triggertime=%lu, endtime=%lu, duration=%lu.\n", hst->name, (temp_downtime->fixed == TRUE) ? "fixed" : "flexible", temp_downtime->downtime_id, hst->scheduled_downtime_depth, temp_downtime->start_time, temp_downtime->entry_time, temp_downtime->trigger_time, temp_downtime->end_time, temp_downtime->duration);
		else
			log_debug_info(DEBUGL_DOWNTIME, 0, "Service '%s' on host '%s' ending %s scheduled downtime (id=%lu) with depth=%d, starttime=%lu, entrytime=%lu, triggertime=%lu, endtime=%lu, duration=%lu.\n", svc->description, svc->host_name, (temp_downtime->fixed == TRUE) ? "fixed" : "flexible", temp_downtime->downtime_id, svc->scheduled_downtime_depth, temp_downtime->start_time, temp_downtime->entry_time, temp_downtime->trigger_time, temp_downtime->end_time, temp_downtime->duration);


#ifdef USE_EVENT_BROKER
		/* send data to event broker */
		attr = NEBATTR_DOWNTIME_STOP_NORMAL;
		broker_downtime_data(NEBTYPE_DOWNTIME_STOP, NEBFLAG_NONE, attr, temp_downtime->type, temp_downtime->host_name, temp_downtime->service_description, temp_downtime->entry_time, temp_downtime->author, temp_downtime->comment, temp_downtime->start_time, temp_downtime->end_time, temp_downtime->fixed, temp_downtime->triggered_by, temp_downtime->duration, temp_downtime->downtime_id, NULL, temp_downtime->is_in_effect, temp_downtime->trigger_time);
#endif

		/* decrement the downtime depth variable */
		if (temp_downtime->type == HOST_DOWNTIME)
			hst->scheduled_downtime_depth--;
		else
			svc->scheduled_downtime_depth--;

		if (temp_downtime->type == HOST_DOWNTIME && hst->scheduled_downtime_depth == 0) {

			log_debug_info(DEBUGL_DOWNTIME, 0, "Host '%s' has exited from a period of scheduled downtime (id=%lu).\n", hst->name, temp_downtime->downtime_id);

			/* log a notice - this one is parsed by the history CGI */
			logit(NSLOG_INFO_MESSAGE, FALSE, "HOST DOWNTIME ALERT: %s;STOPPED; Host has exited from a period of scheduled downtime", hst->name);

			/* send a notification */
			host_notification(hst, NOTIFICATION_DOWNTIMEEND, temp_downtime->author, temp_downtime->comment, NOTIFICATION_OPTION_NONE);
		}

		else if (temp_downtime->type == SERVICE_DOWNTIME && svc->scheduled_downtime_depth == 0) {

			log_debug_info(DEBUGL_DOWNTIME, 0, "Service '%s' on host '%s' has exited from a period of scheduled downtime (id=%lu).\n", svc->description, svc->host_name, temp_downtime->downtime_id);

			/* log a notice - this one is parsed by the history CGI */
			logit(NSLOG_INFO_MESSAGE, FALSE, "SERVICE DOWNTIME ALERT: %s;%s;STOPPED; Service has exited from a period of scheduled downtime", svc->host_name, svc->description);

			/* send a notification */
			service_notification(svc, NOTIFICATION_DOWNTIMEEND, temp_downtime->author, temp_downtime->comment, NOTIFICATION_OPTION_NONE);
		}


		/* update the status data */
		if (temp_downtime->type == HOST_DOWNTIME)
			update_host_status(hst, FALSE);
		else
			update_service_status(svc, FALSE);

		/* decrement pending flex downtime if necessary */
		if (temp_downtime->fixed == FALSE && temp_downtime->incremented_pending_downtime == TRUE) {
			if (temp_downtime->type == HOST_DOWNTIME) {
				if (hst->pending_flex_downtime > 0)
					hst->pending_flex_downtime--;
			} else {
				if (svc->pending_flex_downtime > 0)
					svc->pending_flex_downtime--;
			}
		}

		/* handle (stop) downtime that is triggered by this one */
		while (1) {

			/* list contents might change by recursive calls, so we use this inefficient method to prevent segfaults */
			for (this_downtime = scheduled_downtime_list; this_downtime != NULL; this_downtime = this_downtime->next) {
				if (this_downtime->triggered_by == temp_downtime->downtime_id) {
					handle_scheduled_downtime(this_downtime);
					break;
				}
			}

			if (this_downtime == NULL)
				break;
		}

		/* delete downtime entry */
		if (temp_downtime->type == HOST_DOWNTIME)
			delete_host_downtime(temp_downtime->downtime_id);
		else
			delete_service_downtime(temp_downtime->downtime_id);
	}

	/* else we are just starting the scheduled downtime */
	else {
		if (temp_downtime->type == HOST_DOWNTIME)
			log_debug_info(DEBUGL_DOWNTIME, 0, "Host '%s' starting %s scheduled downtime (id=%lu) with depth=%d, starttime=%lu, entrytime=%lu, endtime=%lu, duration=%lu.\n", hst->name, (temp_downtime->fixed == TRUE) ? "fixed" : "flexible", temp_downtime->downtime_id, hst->scheduled_downtime_depth, temp_downtime->start_time, temp_downtime->entry_time, temp_downtime->end_time, temp_downtime->duration);
		else
			log_debug_info(DEBUGL_DOWNTIME, 0, "Service '%s' on host '%s' starting %s scheduled downtime (id=%lu) with depth=%d, starttime=%lu, entrytime=%lu, endtime=%lu, duration=%lu.\n", svc->description, svc->host_name, (temp_downtime->fixed == TRUE) ? "fixed" : "flexible", temp_downtime->downtime_id, svc->scheduled_downtime_depth, temp_downtime->start_time, temp_downtime->entry_time, temp_downtime->end_time, temp_downtime->duration);

		/* this happens after restart of icinga */
		if (temp_downtime->is_in_effect != TRUE) {
			if (temp_downtime->type == HOST_DOWNTIME && hst->scheduled_downtime_depth == 0) {

				/* set the trigger time, needed to detect the end of a flexible downtime */
				temp_downtime->trigger_time = current_time;

				log_debug_info(DEBUGL_DOWNTIME, 0, "Host '%s' has entered a period of scheduled downtime (id=%lu) at triggertime=%lu.\n", hst->name, temp_downtime->downtime_id, temp_downtime->trigger_time);

				/* log a notice - this one is parsed by the history CGI */
				logit(NSLOG_INFO_MESSAGE, FALSE, "HOST DOWNTIME ALERT: %s;STARTED; Host has entered a period of scheduled downtime", hst->name);

				/* send a notification */
				host_notification(hst, NOTIFICATION_DOWNTIMESTART, temp_downtime->author, temp_downtime->comment, NOTIFICATION_OPTION_NONE);
			}

			else if (temp_downtime->type == SERVICE_DOWNTIME && svc->scheduled_downtime_depth == 0) {

				/* set the trigger time, needed to detect the end of a flexible downtime */
				temp_downtime->trigger_time = current_time;

				log_debug_info(DEBUGL_DOWNTIME, 0, "Service '%s' on host '%s' has entered a period of scheduled downtime (id=%lu) at triggertime=%lu.\n", svc->description, svc->host_name, temp_downtime->downtime_id, temp_downtime->trigger_time);

				/* log a notice - this one is parsed by the history CGI */
				logit(NSLOG_INFO_MESSAGE, FALSE, "SERVICE DOWNTIME ALERT: %s;%s;STARTED; Service has entered a period of scheduled downtime", svc->host_name, svc->description);

				/* send a notification */
				service_notification(svc, NOTIFICATION_DOWNTIMESTART, temp_downtime->author, temp_downtime->comment, NOTIFICATION_OPTION_NONE);
			}
		}

		/* increment the downtime depth variable */
		if (temp_downtime->type == HOST_DOWNTIME)
			hst->scheduled_downtime_depth++;
		else
			svc->scheduled_downtime_depth++;

		/* set the in effect flag */
		temp_downtime->is_in_effect = TRUE;

#ifdef USE_EVENT_BROKER
		/* send data to broker AFTER we know trigger_time, is_in_effect, and downtime_depth */
		broker_downtime_data(NEBTYPE_DOWNTIME_START, NEBFLAG_NONE, NEBATTR_NONE, temp_downtime->type, temp_downtime->host_name, temp_downtime->service_description, temp_downtime->entry_time, temp_downtime->author, temp_downtime->comment, temp_downtime->start_time, temp_downtime->end_time, temp_downtime->fixed, temp_downtime->triggered_by, temp_downtime->duration, temp_downtime->downtime_id, NULL, temp_downtime->is_in_effect, temp_downtime->trigger_time);
#endif
		/* update the status data */
		if (temp_downtime->type == HOST_DOWNTIME)
			update_host_status(hst, FALSE);
		else
			update_service_status(svc, FALSE);

		/* schedule an event */
		if (temp_downtime->fixed == FALSE)
			event_time = (time_t)((unsigned long)time(NULL) + temp_downtime->duration);
		else
			event_time = temp_downtime->end_time;

		if ((new_downtime_id = (unsigned long *)malloc(sizeof(unsigned long *)))) {
			*new_downtime_id = temp_downtime->downtime_id;
			schedule_new_event(EVENT_SCHEDULED_DOWNTIME, TRUE, event_time, FALSE, 0, NULL, FALSE, (void *)new_downtime_id, NULL, 0);
		}

		/* handle (start) downtime that is triggered by this one */
		for (this_downtime = scheduled_downtime_list; this_downtime != NULL; this_downtime = this_downtime->next) {
			if (this_downtime->triggered_by == temp_downtime->downtime_id)
				handle_scheduled_downtime(this_downtime);
		}
	}

	return OK;
}
Exemple #2
0
static int handle_subscription_request(struct Upnp_Subscription_Request
                                              *sr_event)
{
	struct service *srv;
	int i;
	int eventVarCount = 0, eventVarIdx = 0;
	const char **eventvar_names = NULL;
	char **eventvar_values = NULL;
	int rc;
	int result = -1;

	ENTER();

	srv = find_service(upnp_device, sr_event->ServiceId);
	if (srv == NULL) {
		debug_printf(MSG_ERROR, "%s: Unknown service '%s'\n", __FUNCTION__,
			sr_event->ServiceId);
		goto out;
	}

	ithread_mutex_lock(&(upnp_device->device_mutex));

	/* generate list of eventable variables */
	for(i=0; i<srv->variable_count; i++) {
		struct var_meta *metaEntry;
		metaEntry = &(srv->variable_meta[i]);
		if (metaEntry->sendevents == SENDEVENT_YES) {
			eventVarCount++;
		}
	}
	eventvar_names = malloc((eventVarCount+1) * sizeof(const char *));
	if (NULL == eventvar_names)
	{
	    debug_printf(MSG_ERROR, 
			"eventvar_names malloc fail, eventVarCount:%d\n", 
			eventVarCount);
		return 1;
	}
	eventvar_values = malloc((eventVarCount+1) * sizeof(const char *));
	if (NULL == eventvar_values)
	{
	    debug_printf(MSG_ERROR, 
			"eventvar_values malloc fail, eventVarCount:%d\n", 
			eventVarCount);
		free(eventvar_names);
		return 1;
	}
	//printf("%d evented variables\n", eventVarCount);

	for(i=0; i<srv->variable_count; i++) {
		struct var_meta *metaEntry;
		metaEntry = &(srv->variable_meta[i]);
		if (metaEntry->sendevents == SENDEVENT_YES) {
			eventvar_names[eventVarIdx] = srv->variable_names[i];
			eventvar_values[eventVarIdx] = xmlescape(srv->variable_values[i], 0);
			//printf("Evented: '%s' == '%s'\n",
			//	eventvar_names[eventVarIdx],
			//	eventvar_values[eventVarIdx]);
			eventVarIdx++;
		}
	}
	eventvar_names[eventVarIdx] = NULL;
	eventvar_values[eventVarIdx] = NULL;

	rc = UpnpAcceptSubscription(device_handle,
			       sr_event->UDN, sr_event->ServiceId,
			       (const char **)eventvar_names,
			       (const char **)eventvar_values,
			       eventVarCount,
			       sr_event->Sid);
	if (rc == UPNP_E_SUCCESS) {
		result = 0;
	}

	ithread_mutex_unlock(&(upnp_device->device_mutex));

	for(i=0; i<eventVarCount; i++) {
		free(eventvar_values[i]);
	}
	free(eventvar_names);
	free(eventvar_values);

out:
	LEAVE();
	return result;
}
/* registers scheduled downtime (schedules it, adds comments, etc.) */
int register_downtime(int type, unsigned long downtime_id) {
	char *temp_buffer = NULL;
	char start_time_string[MAX_DATETIME_LENGTH] = "";
	char end_time_string[MAX_DATETIME_LENGTH] = "";
	scheduled_downtime *temp_downtime = NULL;
	host *hst = NULL;
	service *svc = NULL;
	char *type_string = NULL;
	int hours = 0;
	int minutes = 0;
	int seconds = 0;
	unsigned long *new_downtime_id = NULL;

	log_debug_info(DEBUGL_FUNCTIONS, 0, "register_downtime()\n");

	/* find the downtime entry in memory */
	temp_downtime = find_downtime(type, downtime_id);
	if (temp_downtime == NULL)
		return ERROR;

	/* find the host or service associated with this downtime */
	if (temp_downtime->type == HOST_DOWNTIME) {
		if ((hst = find_host(temp_downtime->host_name)) == NULL)
			return ERROR;
	} else {
		if ((svc = find_service(temp_downtime->host_name, temp_downtime->service_description)) == NULL)
			return ERROR;
	}

	/* create the comment */
	get_datetime_string(&(temp_downtime->start_time), start_time_string, MAX_DATETIME_LENGTH, SHORT_DATE_TIME);
	get_datetime_string(&(temp_downtime->end_time), end_time_string, MAX_DATETIME_LENGTH, SHORT_DATE_TIME);
	hours = temp_downtime->duration / 3600;
	minutes = ((temp_downtime->duration - (hours * 3600)) / 60);
	seconds = temp_downtime->duration - (hours * 3600) - (minutes * 60);
	if (temp_downtime->type == HOST_DOWNTIME)
		type_string = "host";
	else
		type_string = "service";
	if (temp_downtime->fixed == TRUE)
		asprintf(&temp_buffer, "This %s has been scheduled for fixed downtime from %s to %s.  Notifications for the %s will not be sent out during that time period.", type_string, start_time_string, end_time_string, type_string);
	else
		asprintf(&temp_buffer, "This %s has been scheduled for flexible downtime starting between %s and %s and lasting for a period of %d hours and %d minutes.  Notifications for the %s will not be sent out during that time period.", type_string, start_time_string, end_time_string, hours, minutes, type_string);


	log_debug_info(DEBUGL_DOWNTIME, 0, "Scheduled Downtime Details:\n");
	if (temp_downtime->type == HOST_DOWNTIME) {
		log_debug_info(DEBUGL_DOWNTIME, 0, " Type:        Host Downtime\n");
		log_debug_info(DEBUGL_DOWNTIME, 0, " Host:        %s\n", hst->name);
	} else {
		log_debug_info(DEBUGL_DOWNTIME, 0, " Type:        Service Downtime\n");
		log_debug_info(DEBUGL_DOWNTIME, 0, " Host:        %s\n", svc->host_name);
		log_debug_info(DEBUGL_DOWNTIME, 0, " Service:     %s\n", svc->description);
	}
	log_debug_info(DEBUGL_DOWNTIME, 0, " Fixed/Flex:  %s\n", (temp_downtime->fixed == TRUE) ? "Fixed" : "Flexible");
	log_debug_info(DEBUGL_DOWNTIME, 0, " Start:       %s\n", start_time_string);
	log_debug_info(DEBUGL_DOWNTIME, 0, " End:         %s\n", end_time_string);
	log_debug_info(DEBUGL_DOWNTIME, 0, " Duration:    %dh %dm %ds\n", hours, minutes, seconds);
	log_debug_info(DEBUGL_DOWNTIME, 0, " Downtime ID: %lu\n", temp_downtime->downtime_id);
	log_debug_info(DEBUGL_DOWNTIME, 0, " Trigger ID:  %lu\n", temp_downtime->triggered_by);
	log_debug_info(DEBUGL_DOWNTIME, 0, " Author:      %s\n", (temp_downtime->author != NULL ? temp_downtime->author : "(Icinga Process)"));


	/* add a non-persistent comment to the host or service regarding the scheduled outage */
	if (temp_downtime->type == SERVICE_DOWNTIME)
		add_new_comment(SERVICE_COMMENT, DOWNTIME_COMMENT, svc->host_name, svc->description, time(NULL), (temp_downtime->author != NULL ? temp_downtime->author : "(Icinga Process)"), temp_buffer, 0, COMMENTSOURCE_INTERNAL, FALSE, (time_t)0, &(temp_downtime->comment_id));
	else
		add_new_comment(HOST_COMMENT, DOWNTIME_COMMENT, hst->name, NULL, time(NULL), (temp_downtime->author != NULL ? temp_downtime->author : "(Icinga Process)"), temp_buffer, 0, COMMENTSOURCE_INTERNAL, FALSE, (time_t)0, &(temp_downtime->comment_id));

	/* free comment buffer */
	my_free(temp_buffer);

	/*** SCHEDULE DOWNTIME - FLEXIBLE (NON-FIXED) DOWNTIME IS HANDLED AT A LATER POINT ***/

	/* only non-triggered downtime is scheduled... */
	if (temp_downtime->triggered_by == 0) {
		if ((new_downtime_id = (unsigned long *)malloc(sizeof(unsigned long *)))) {
			*new_downtime_id = downtime_id;
			schedule_new_event(EVENT_SCHEDULED_DOWNTIME, TRUE, temp_downtime->start_time, FALSE, 0, NULL, FALSE, (void *)new_downtime_id, NULL, 0);
		}
	}

#ifdef PROBABLY_NOT_NEEDED
	/*** FLEXIBLE DOWNTIME SANITY CHECK - ADDED 02/17/2008 ****/

	/* if host/service is in a non-OK/UP state right now, see if we should start flexible time immediately */
	/* this is new logic added in 3.0rc3 */
	if (temp_downtime->fixed == FALSE) {
		if (temp_downtime->type == HOST_DOWNTIME)
			check_pending_flex_host_downtime(hst);
		else
			check_pending_flex_service_downtime(svc);
	}
#endif

	return OK;
}
Exemple #4
0
obs_data_t *obs_service_defaults(const char *id)
{
	const struct obs_service_info *info = find_service(id);
	return (info) ? get_defaults(info) : NULL;
}
Exemple #5
0
static NTSTATUS smbd_smb2_tree_connect(struct smbd_smb2_request *req,
				       const char *in_path,
				       uint8_t *out_share_type,
				       uint32_t *out_share_flags,
				       uint32_t *out_capabilities,
				       uint32_t *out_maximal_access,
				       uint32_t *out_tree_id)
{
	const char *share = in_path;
	char *service = NULL;
	int snum = -1;
	struct smbd_smb2_tcon *tcon;
	connection_struct *compat_conn = NULL;
	user_struct *compat_vuser = req->session->compat_vuser;
	int id;
	NTSTATUS status;

	if (strncmp(share, "\\\\", 2) == 0) {
		const char *p = strchr(share+2, '\\');
		if (p) {
			share = p + 1;
		}
	}

	DEBUG(10,("smbd_smb2_tree_connect: path[%s] share[%s]\n",
		  in_path, share));

	service = talloc_strdup(talloc_tos(), share);
	if(!service) {
		return NT_STATUS_NO_MEMORY;
	}

	strlower_m(service);

	/* TODO: do more things... */
	if (strequal(service,HOMES_NAME)) {
		if (compat_vuser->homes_snum == -1) {
			DEBUG(2, ("[homes] share not available for "
				"user %s because it was not found "
				"or created at session setup "
				"time\n",
				compat_vuser->session_info->unix_name));
			return NT_STATUS_BAD_NETWORK_NAME;
		}
		snum = compat_vuser->homes_snum;
	} else if ((compat_vuser->homes_snum != -1)
                   && strequal(service,
			lp_servicename(compat_vuser->homes_snum))) {
		snum = compat_vuser->homes_snum;
	} else {
		snum = find_service(talloc_tos(), service, &service);
		if (!service) {
			return NT_STATUS_NO_MEMORY;
		}
	}

	if (snum < 0) {
		DEBUG(3,("smbd_smb2_tree_connect: couldn't find service %s\n",
			 service));
		return NT_STATUS_BAD_NETWORK_NAME;
	}

	/* create a new tcon as child of the session */
	tcon = talloc_zero(req->session, struct smbd_smb2_tcon);
	if (tcon == NULL) {
		return NT_STATUS_NO_MEMORY;
	}
	id = idr_get_new_random(req->session->tcons.idtree,
				tcon,
				req->session->tcons.limit);
	if (id == -1) {
		TALLOC_FREE(tcon);
		return NT_STATUS_INSUFFICIENT_RESOURCES;
	}
	tcon->tid = id;
	tcon->snum = snum;

	DLIST_ADD_END(req->session->tcons.list, tcon,
		      struct smbd_smb2_tcon *);
	tcon->session = req->session;
	tcon->session->sconn->num_tcons_open++;
	talloc_set_destructor(tcon, smbd_smb2_tcon_destructor);

	compat_conn = make_connection_smb2(req->sconn,
					tcon,
					req->session->compat_vuser,
					data_blob_null, "???",
					&status);
	if (compat_conn == NULL) {
		TALLOC_FREE(tcon);
		return status;
	}
	tcon->compat_conn = talloc_move(tcon, &compat_conn);

	if (IS_PRINT(tcon->compat_conn)) {
		*out_share_type = SMB2_SHARE_TYPE_PRINT;
	} else if (IS_IPC(tcon->compat_conn)) {
		*out_share_type = SMB2_SHARE_TYPE_PIPE;
	} else {
		*out_share_type = SMB2_SHARE_TYPE_DISK;
	}

	*out_share_flags = SMB2_SHAREFLAG_ALLOW_NAMESPACE_CACHING;

	if (lp_msdfs_root(SNUM(tcon->compat_conn)) && lp_host_msdfs()) {
		*out_share_flags |= (SMB2_SHAREFLAG_DFS|SMB2_SHAREFLAG_DFS_ROOT);
		*out_capabilities = SMB2_SHARE_CAP_DFS;
	} else {
		*out_capabilities = 0;
	}

	switch(lp_csc_policy(SNUM(tcon->compat_conn))) {
	case CSC_POLICY_MANUAL:
		break;
	case CSC_POLICY_DOCUMENTS:
		*out_share_flags |= SMB2_SHAREFLAG_AUTO_CACHING;
		break;
	case CSC_POLICY_PROGRAMS:
		*out_share_flags |= SMB2_SHAREFLAG_VDO_CACHING;
		break;
	case CSC_POLICY_DISABLE:
		*out_share_flags |= SMB2_SHAREFLAG_NO_CACHING;
		break;
	default:
		break;
	}

	*out_maximal_access = tcon->compat_conn->share_access;

	*out_tree_id = tcon->tid;
	return NT_STATUS_OK;
}
Exemple #6
0
/* registers scheduled downtime (schedules it, adds comments, etc.) */
int register_downtime(int type, unsigned long downtime_id) {
	char *temp_buffer = NULL;
	char start_time_string[MAX_DATETIME_LENGTH] = "";
	char flex_start_string[MAX_DATETIME_LENGTH] = "";
	char end_time_string[MAX_DATETIME_LENGTH] = "";
	scheduled_downtime *temp_downtime = NULL;
	host *hst = NULL;
	service *svc = NULL;
	const char *type_string = NULL;
	int hours = 0;
	int minutes = 0;
	int seconds = 0;
	unsigned long *new_downtime_id = NULL;
	int was_in_effect = FALSE;

	log_debug_info(DEBUGL_FUNCTIONS, 0, "register_downtime( %d, %lu)\n", type,
			downtime_id);

	/* find the downtime entry in memory */
	temp_downtime = find_downtime(type, downtime_id);
	if(temp_downtime == NULL) {
		log_debug_info(DEBUGL_DOWNTIME, 0, "Cannot find downtime ID: %lu\n", downtime_id);
		return ERROR;
		}

	/* find the host or service associated with this downtime */
	if(temp_downtime->type == HOST_DOWNTIME) {
		if((hst = find_host(temp_downtime->host_name)) == NULL) {
			log_debug_info(DEBUGL_DOWNTIME, 1,
					"Cannot find host (%s) for downtime ID: %lu\n",
					temp_downtime->host_name, downtime_id);
			return ERROR;
			}
		}
	else {
		if((svc = find_service(temp_downtime->host_name, temp_downtime->service_description)) == NULL) {
			log_debug_info(DEBUGL_DOWNTIME, 1,
					"Cannot find service (%s) for host (%s) for downtime ID: %lu\n",
					temp_downtime->service_description, temp_downtime->host_name,
					downtime_id);
			return ERROR;
			}
		}

	/* create the comment */
	get_datetime_string(&(temp_downtime->start_time), start_time_string, MAX_DATETIME_LENGTH, SHORT_DATE_TIME);
	get_datetime_string(&(temp_downtime->flex_downtime_start), flex_start_string, MAX_DATETIME_LENGTH, SHORT_DATE_TIME);
	get_datetime_string(&(temp_downtime->end_time), end_time_string, MAX_DATETIME_LENGTH, SHORT_DATE_TIME);
	hours = temp_downtime->duration / 3600;
	minutes = ((temp_downtime->duration - (hours * 3600)) / 60);
	seconds = temp_downtime->duration - (hours * 3600) - (minutes * 60);
	if(temp_downtime->type == HOST_DOWNTIME)
		type_string = "host";
	else
		type_string = "service";
	if(temp_downtime->fixed == TRUE)
		asprintf(&temp_buffer, "This %s has been scheduled for fixed downtime from %s to %s.  Notifications for the %s will not be sent out during that time period.", type_string, start_time_string, end_time_string, type_string);
	else
		asprintf(&temp_buffer, "This %s has been scheduled for flexible downtime starting between %s and %s and lasting for a period of %d hours and %d minutes.  Notifications for the %s will not be sent out during that time period.", type_string, start_time_string, end_time_string, hours, minutes, type_string);


	log_debug_info(DEBUGL_DOWNTIME, 0, "Scheduled Downtime Details:\n");
	if(temp_downtime->type == HOST_DOWNTIME) {
		log_debug_info(DEBUGL_DOWNTIME, 0, " Type:        Host Downtime\n");
		log_debug_info(DEBUGL_DOWNTIME, 0, " Host:        %s\n", hst->name);
		}
	else {
		log_debug_info(DEBUGL_DOWNTIME, 0, " Type:        Service Downtime\n");
		log_debug_info(DEBUGL_DOWNTIME, 0, " Host:        %s\n", svc->host_name);
		log_debug_info(DEBUGL_DOWNTIME, 0, " Service:     %s\n", svc->description);
		}
	log_debug_info(DEBUGL_DOWNTIME, 0, " Fixed/Flex:  %s\n", (temp_downtime->fixed == TRUE) ? "Fixed" : "Flexible");
	log_debug_info(DEBUGL_DOWNTIME, 0, " Start:       %s\n", start_time_string);
	if( temp_downtime->flex_downtime_start) {
		log_debug_info(DEBUGL_DOWNTIME, 0, " Flex Start:  %s\n", flex_start_string);
		}
	log_debug_info(DEBUGL_DOWNTIME, 0, " End:         %s\n", end_time_string);
	log_debug_info(DEBUGL_DOWNTIME, 0, " Duration:    %dh %dm %ds\n", hours, minutes, seconds);
	log_debug_info(DEBUGL_DOWNTIME, 0, " Downtime ID: %lu\n", temp_downtime->downtime_id);
	log_debug_info(DEBUGL_DOWNTIME, 0, " Trigger ID:  %lu\n", temp_downtime->triggered_by);


	/* add a non-persistent comment to the host or service regarding the scheduled outage */
	if(temp_downtime->type == SERVICE_DOWNTIME)
		add_new_comment(SERVICE_COMMENT, DOWNTIME_COMMENT, svc->host_name, svc->description, time(NULL), ( NULL == temp_downtime->author ? "(Nagios Process)" : temp_downtime->author), temp_buffer, 0, COMMENTSOURCE_INTERNAL, FALSE, (time_t)0, &(temp_downtime->comment_id));
	else
		add_new_comment(HOST_COMMENT, DOWNTIME_COMMENT, hst->name, NULL, time(NULL), ( NULL == temp_downtime->author ? "(Nagios Process)" : temp_downtime->author), temp_buffer, 0, COMMENTSOURCE_INTERNAL, FALSE, (time_t)0, &(temp_downtime->comment_id));

	my_free(temp_buffer);

	/* only non-triggered downtime is scheduled... */
	if((temp_downtime->triggered_by == 0) && ((TRUE == temp_downtime->fixed) ||
			((FALSE == temp_downtime->fixed) &&
			(TRUE == temp_downtime->is_in_effect)))) {
		/* If this is a fixed downtime, schedule the event to start it. If this
			is a flexible downtime, normally we wait for one of the
			check_pending_flex_*_downtime() functions to start it, but if the
			downtime is already in effect, this means that we are restarting
			Nagios and the downtime was in effect when we last shutdown
			Nagios, so we should restart the flexible downtime now. This
			should work even if the downtime has ended because the
			handle_scheduled_downtime() function will immediately schedule
			another downtime event which will end the downtime. */
		if((new_downtime_id = (unsigned long *)malloc(sizeof(unsigned long)))) {
			*new_downtime_id = downtime_id;
			temp_downtime->start_event = schedule_new_event(EVENT_SCHEDULED_DOWNTIME, TRUE, temp_downtime->start_time, FALSE, 0, NULL, FALSE, (void *)new_downtime_id, NULL, 0);
			/* Turn off is_in_effect flag so handle_scheduled_downtime() will
				handle it correctly */
			was_in_effect = temp_downtime->is_in_effect;
			temp_downtime->is_in_effect = FALSE;
			}
		}

	/* If the downtime is triggered and was in effect, mark it as not in 
		effect so it gets scheduled correctly */
	if((temp_downtime->triggered_by != 0) && 
			(TRUE == temp_downtime->is_in_effect)) {
		was_in_effect = temp_downtime->is_in_effect;
		temp_downtime->is_in_effect = FALSE;
		}

	if((FALSE == temp_downtime->fixed) && (FALSE == was_in_effect)) {
		/* increment pending flex downtime counter */
		if(temp_downtime->type == HOST_DOWNTIME)
			hst->pending_flex_downtime++;
		else
			svc->pending_flex_downtime++;
		temp_downtime->incremented_pending_downtime = TRUE;

		/* Since a flex downtime may never start, schedule an expiring event in
			case the event is never triggered. The expire event will NOT cancel
			a downtime event that is in effect */
		log_debug_info(DEBUGL_DOWNTIME, 1, "Scheduling downtime expire event in case flexible downtime is never triggered\n");
		temp_downtime->stop_event = schedule_new_event(EVENT_EXPIRE_DOWNTIME, TRUE, (temp_downtime->end_time + 1), FALSE, 0, NULL, FALSE, NULL, NULL, 0);
		}

#ifdef PROBABLY_NOT_NEEDED
	/*** FLEXIBLE DOWNTIME SANITY CHECK - ADDED 02/17/2008 ****/

	/* if host/service is in a non-OK/UP state right now, see if we should start flexible time immediately */
	/* this is new logic added in 3.0rc3 */
	if(temp_downtime->fixed == FALSE) {
		if(temp_downtime->type == HOST_DOWNTIME)
			check_pending_flex_host_downtime(hst);
		else
			check_pending_flex_service_downtime(svc);
		}
#endif

	return OK;
	}
Exemple #7
0
/* checks for (and removes) expired downtime entries */
int check_for_expired_downtime(void) {
	scheduled_downtime *temp_downtime = NULL;
	scheduled_downtime *next_downtime = NULL;
	time_t current_time = 0L;
	service *svc = NULL;
	host *hst = NULL;


	log_debug_info(DEBUGL_FUNCTIONS, 0, "check_for_expired_downtime()\n");

	time(&current_time);

	/* check all downtime entries... */
	for(temp_downtime = scheduled_downtime_list; temp_downtime != NULL; temp_downtime = next_downtime) {

		next_downtime = temp_downtime->next;

		/* this entry should be removed */
		if(temp_downtime->is_in_effect == FALSE && temp_downtime->end_time <= current_time) {

			log_debug_info(DEBUGL_DOWNTIME, 0, "Expiring %s downtime (id=%lu)...\n", (temp_downtime->type == HOST_DOWNTIME) ? "host" : "service", temp_downtime->downtime_id);

			/* find the host or service associated with this downtime */
			if(temp_downtime->type == HOST_DOWNTIME) {
				if((hst = find_host(temp_downtime->host_name)) == NULL) {
					log_debug_info(DEBUGL_DOWNTIME, 1, 
							"Unable to find host (%s) for downtime\n", 
							temp_downtime->host_name);
					return ERROR;
					}

					/* send a notification */
					host_notification(hst, NOTIFICATION_DOWNTIMEEND, 
							temp_downtime->author, temp_downtime->comment, 
							NOTIFICATION_OPTION_NONE);
				}
			else {
				if((svc = find_service(temp_downtime->host_name, 
							temp_downtime->service_description)) == NULL) {
					log_debug_info(DEBUGL_DOWNTIME, 1, 
							"Unable to find service (%s) host (%s) for downtime\n", 
							temp_downtime->service_description, 
							temp_downtime->host_name);
					return ERROR;
					}

				/* send a notification */
				service_notification(svc, NOTIFICATION_DOWNTIMEEND, 
							temp_downtime->author, temp_downtime->comment, 
							NOTIFICATION_OPTION_NONE);
			}

			/* delete the downtime entry */
			if(temp_downtime->type == HOST_DOWNTIME)
				delete_host_downtime(temp_downtime->downtime_id);
			else
				delete_service_downtime(temp_downtime->downtime_id);
			}
		}

	return OK;
	}
Exemple #8
0
/* displays problems */
void display_problems(void) {
	host *temp_host;
	service *temp_service;
	hoststatus *temp_hoststatus;
	int total_host_problems = 0;
	servicestatus *temp_servicestatus;
	int total_service_problems = 0;

	/**** MAIN SCREEN (CARD 1) ****/
	printf("<card id='card1' title='%s Problems'>\n", (display_type == DISPLAY_ALL_PROBLEMS) ? "All" : "Unhandled");
	printf("<p align='center' mode='nowrap'>\n");
	printf("<b>%s Problems</b><br/><br/>\n", (display_type == DISPLAY_ALL_PROBLEMS) ? "All" : "Unhandled");

	printf("<b>Host Problems:</b>\n");

	printf("<table columns='2' align='LL'>\n");

	/* check all hosts */
	for (temp_hoststatus = hoststatus_list; temp_hoststatus != NULL; temp_hoststatus = temp_hoststatus->next) {

		temp_host = find_host(temp_hoststatus->host_name);
		if (temp_host == NULL)
			continue;

		if (is_authorized_for_host(temp_host, &current_authdata) == FALSE)
			continue;

		if (temp_hoststatus->status == HOST_UP || temp_hoststatus->status == HOST_PENDING)
			continue;

		if (display_type == DISPLAY_UNHANDLED_PROBLEMS) {
			if (temp_hoststatus->problem_has_been_acknowledged == TRUE)
				continue;
			if (temp_hoststatus->notifications_enabled == FALSE)
				continue;
			if (temp_hoststatus->scheduled_downtime_depth > 0)
				continue;
		}

		total_host_problems++;

		printf("<tr><td><anchor title='%s'>", temp_host->name);
		if (temp_hoststatus->status == HOST_DOWN)
			printf("DWN");
		else if (temp_hoststatus->status == HOST_UNREACHABLE)
			printf("UNR");
		else
			printf("???");
		printf("<go href='%s' method='post'><postfield name='host' value='%s'/></go></anchor></td>", STATUSWML_CGI, temp_host->name);
		printf("<td>%s</td></tr>\n", temp_host->name);
	}

	if (total_host_problems == 0)
		printf("<tr><td>No problems</td></tr>\n");

	printf("</table>\n");

	printf("<br/>\n");


	printf("<b>Svc Problems:</b>\n");

	printf("<table columns='2' align='LL'>\n");

	/* check all services */
	for (temp_servicestatus = servicestatus_list; temp_servicestatus != NULL; temp_servicestatus = temp_servicestatus->next) {

		temp_service = find_service(temp_servicestatus->host_name, temp_servicestatus->description);
		if (temp_service == NULL)
			continue;

		if (is_authorized_for_service(temp_service, &current_authdata) == FALSE)
			continue;

		if (temp_servicestatus->status == SERVICE_OK || temp_servicestatus->status == SERVICE_PENDING)
			continue;

		if (display_type == DISPLAY_UNHANDLED_PROBLEMS) {
			if (temp_servicestatus->problem_has_been_acknowledged == TRUE)
				continue;
			if (temp_servicestatus->notifications_enabled == FALSE)
				continue;
			if (temp_servicestatus->scheduled_downtime_depth > 0)
				continue;
			if ((temp_hoststatus = find_hoststatus(temp_service->host_name))) {
				if (temp_hoststatus->scheduled_downtime_depth > 0)
					continue;
				if (temp_hoststatus->problem_has_been_acknowledged == TRUE)
					continue;
			}
		}

		total_service_problems++;

		printf("<tr><td><anchor title='%s'>", temp_servicestatus->description);
		if (temp_servicestatus->status == SERVICE_CRITICAL)
			printf("CRI");
		else if (temp_servicestatus->status == SERVICE_WARNING)
			printf("WRN");
		else if (temp_servicestatus->status == SERVICE_UNKNOWN)
			printf("UNK");
		else
			printf("???");
		printf("<go href='%s' method='post'><postfield name='host' value='%s'/><postfield name='service' value='%s'/></go></anchor></td>", STATUSWML_CGI, temp_service->host_name, temp_service->description);
		printf("<td>%s/%s</td></tr>\n", temp_service->host_name, temp_service->description);
	}

	if (total_service_problems == 0)
		printf("<tr><td>No problems</td></tr>\n");

	printf("</table>\n");

	printf("</p>\n");

	printf("</card>\n");

	return;
}
Exemple #9
0
int get_rls_from_full_doc(const str_t *uri, 
		/* const str_t *filename,  */
		xcap_query_params_t *xcap_params, 
		const str_t *package, flat_list_t **dst)
{
	char *data = NULL;
	int dsize = 0;
	rls_services_t *rls = NULL;
	service_t *service = NULL;
	str_t curi;
	int res;
	char *xcap_uri = NULL;
	str_t *filename = NULL;

	if (!dst) return RES_INTERNAL_ERR;
	

	/* get basic document */
	xcap_uri = xcap_uri_for_global_document(xcap_doc_rls_services, 
			filename, xcap_params);
	if (!xcap_uri) {
		ERROR_LOG("can't get XCAP uri\n");
		return -1;
	}
	
	res = xcap_query(xcap_uri, xcap_params, &data, &dsize);
	if (res != 0) {
		ERROR_LOG("XCAP problems for uri \'%s\'\n", xcap_uri);
		if (data) {
			cds_free(data);
		}
		cds_free(xcap_uri);
		return RES_XCAP_QUERY_ERR;
	}
	cds_free(xcap_uri);
	
	/* parse document as a service element in rls-sources */
	if (parse_rls_services_xml(data, dsize, &rls) != 0) {
		ERROR_LOG("Parsing problems!\n");
		if (rls) free_rls_services(rls);
		if (data) {
			cds_free(data);
		}
		return RES_XCAP_PARSE_ERR;
	}
/*	DEBUG_LOG("%.*s\n", dsize, data);*/
	if (data) cds_free(data);

	/* try to find given service according to uri */
	canonicalize_uri(uri, &curi);
	service = find_service(rls, &curi); 
	if (!service) DEBUG_LOG("Service %.*s not found!\n", FMT_STR(curi));
	str_free_content(&curi);
	
	if (!service) {
		if (rls) free_rls_services(rls);
		return RES_XCAP_QUERY_ERR;
	}

	/* verify the package */
	if (verify_package(service, package) != 0) {
		free_rls_services(rls);
		return RES_BAD_EVENT_PACKAGE_ERR;
	}
	
	/* create flat document */
	res = create_flat_list(service, xcap_params, dst);
	if (res != RES_OK) {
		ERROR_LOG("Flat list creation error\n");
		free_rls_services(rls);
		free_flat_list(*dst);
		*dst = NULL;
		return res;
	}
	free_rls_services(rls);
	
	return RES_OK;
}
Exemple #10
0
void show_history(void) {
	char image[MAX_INPUT_BUFFER];
	char image_alt[MAX_INPUT_BUFFER];
	char match1[MAX_INPUT_BUFFER];
	char match2[MAX_INPUT_BUFFER];
	char date_time[MAX_DATETIME_LENGTH];
	char last_message_date[MAX_INPUT_BUFFER] = "";
	char current_message_date[MAX_INPUT_BUFFER] = "";
	char *temp_buffer = NULL;
	char *entry_host_name = NULL;
	char *entry_service_desc = NULL;
	char *error_text = NULL;
	int system_message = FALSE;
	int display_line = FALSE;
	int history_type = SERVICE_HISTORY;
	int history_detail_type = HISTORY_SERVICE_CRITICAL;
	int status = READLOG_OK;
	int displayed_entries = 0;
	int total_entries = 0;
	host *temp_host = NULL;
	service *temp_service = NULL;
	hostgroup *temp_hostgroup = NULL;
	servicegroup *temp_servicegroup = NULL;
	logentry *temp_entry = NULL;
	struct tm *time_ptr = NULL;
	logentry *entry_list = NULL;
	logfilter *filter_list = NULL;


	if (display_type == DISPLAY_HOSTGROUPS) {

		temp_hostgroup = find_hostgroup(hostgroup_name);

		if (temp_hostgroup == NULL) {
			print_generic_error_message("There are no host groups with this name defined.", NULL, 0);
			return;
		}
		/* make sure the user is authorized to view this hostgroup */
		if (show_partial_hostgroups == FALSE && is_authorized_for_hostgroup(temp_hostgroup, &current_authdata) == FALSE) {
			print_generic_error_message("It appears as though you do not have permission to view information for the host group you requested...", "If you believe this is an error, check the HTTP server authentication requirements for accessing this CGI and check the authorization options in your CGI configuration file.", 0);
			return;
		}
	}

	if (display_type == DISPLAY_SERVICEGROUPS) {

		temp_servicegroup = find_servicegroup(servicegroup_name);

		if (temp_servicegroup == NULL) {
			print_generic_error_message("There are no service groups with this name defined.", NULL, 0);
			return;
		}
		/* make sure the user is authorized to view this servicegroup */
		if (is_authorized_for_servicegroup(temp_servicegroup, &current_authdata) == FALSE) {
			print_generic_error_message("It appears as though you do not have permission to view information for the service group you requested...", "If you believe this is an error, check the HTTP server authentication requirements for accessing this CGI and check the authorization options in your CGI configuration file.", 0);
			return;
		}
	}

	add_log_filter(&filter_list, LOGENTRY_SERVICE_CRITICAL, LOGFILTER_INCLUDE);
	add_log_filter(&filter_list, LOGENTRY_SERVICE_WARNING, LOGFILTER_INCLUDE);
	add_log_filter(&filter_list, LOGENTRY_SERVICE_UNKNOWN, LOGFILTER_INCLUDE);
	add_log_filter(&filter_list, LOGENTRY_SERVICE_RECOVERY, LOGFILTER_INCLUDE);
	add_log_filter(&filter_list, LOGENTRY_SERVICE_OK, LOGFILTER_INCLUDE);
	add_log_filter(&filter_list, LOGENTRY_SERVICE_FLAPPING_STARTED, LOGFILTER_INCLUDE);
	add_log_filter(&filter_list, LOGENTRY_SERVICE_FLAPPING_STOPPED, LOGFILTER_INCLUDE);
	add_log_filter(&filter_list, LOGENTRY_SERVICE_FLAPPING_DISABLED, LOGFILTER_INCLUDE);
	add_log_filter(&filter_list, LOGENTRY_SERVICE_DOWNTIME_STARTED, LOGFILTER_INCLUDE);
	add_log_filter(&filter_list, LOGENTRY_SERVICE_DOWNTIME_STOPPED, LOGFILTER_INCLUDE);
	add_log_filter(&filter_list, LOGENTRY_SERVICE_DOWNTIME_CANCELLED, LOGFILTER_INCLUDE);

	if (display_type == DISPLAY_HOSTS || display_type == DISPLAY_HOSTGROUPS) {
		add_log_filter(&filter_list, LOGENTRY_HOST_DOWN, LOGFILTER_INCLUDE);
		add_log_filter(&filter_list, LOGENTRY_HOST_UNREACHABLE, LOGFILTER_INCLUDE);
		add_log_filter(&filter_list, LOGENTRY_HOST_RECOVERY, LOGFILTER_INCLUDE);
		add_log_filter(&filter_list, LOGENTRY_HOST_UP, LOGFILTER_INCLUDE);
		add_log_filter(&filter_list, LOGENTRY_HOST_FLAPPING_STARTED, LOGFILTER_INCLUDE);
		add_log_filter(&filter_list, LOGENTRY_HOST_FLAPPING_STOPPED, LOGFILTER_INCLUDE);
		add_log_filter(&filter_list, LOGENTRY_HOST_FLAPPING_DISABLED, LOGFILTER_INCLUDE);
		add_log_filter(&filter_list, LOGENTRY_HOST_FLAPPING_DISABLED, LOGFILTER_INCLUDE);
		add_log_filter(&filter_list, LOGENTRY_HOST_FLAPPING_STOPPED, LOGFILTER_INCLUDE);
		add_log_filter(&filter_list, LOGENTRY_HOST_FLAPPING_DISABLED, LOGFILTER_INCLUDE);
	}

	/* system log entries */
	add_log_filter(&filter_list, LOGENTRY_STARTUP, LOGFILTER_INCLUDE);
	add_log_filter(&filter_list, LOGENTRY_SHUTDOWN, LOGFILTER_INCLUDE);
	add_log_filter(&filter_list, LOGENTRY_BAILOUT, LOGFILTER_INCLUDE);
	add_log_filter(&filter_list, LOGENTRY_RESTART, LOGFILTER_INCLUDE);


	/* scan the log file for archived state data */
	status = get_log_entries(&entry_list, &filter_list, &error_text, NULL, reverse, ts_start, ts_end);


	/* dealing with errors */
	if (status == READLOG_ERROR_WARNING) {
		if (error_text != NULL) {
			print_generic_error_message(error_text, NULL, 0);
			my_free(error_text);
		} else
			print_generic_error_message("Unkown error!", NULL, 0);
	}

	if (status == READLOG_ERROR_MEMORY)
			print_generic_error_message("Out of memory...", "showing all I could get!", 0);


	if (status == READLOG_ERROR_FATAL) {
		if (error_text != NULL) {
			print_generic_error_message(error_text, NULL, 0);
			my_free(error_text);
		}

		return;

	/* now we start displaying the log entries */
	} else {

		printf("<table width='100%%' cellspacing=0 cellpadding=0><tr><td width='33%%'></td><td width='33%%' nowrap>");
		printf("<div class='page_selector' id='hist_page_selector'>\n");
		printf("<div id='page_navigation_copy'></div>");
		page_limit_selector(result_start);
		printf("</div>\n");
		printf("</td><td width='33%%' align='right' style='padding-right:2px'>\n");
		print_export_link(HTML_CONTENT, HISTORY_CGI, NULL);
		printf("</td></tr></table>");

		printf("<DIV CLASS='logEntries'>\n");

		for (temp_entry = entry_list; temp_entry != NULL; temp_entry = temp_entry->next) {

			strcpy(image, "");
			strcpy(image_alt, "");
			system_message = FALSE;

			switch (temp_entry->type) {

				/* service state alerts */
			case LOGENTRY_SERVICE_CRITICAL:
			case LOGENTRY_SERVICE_WARNING:
			case LOGENTRY_SERVICE_UNKNOWN:
			case LOGENTRY_SERVICE_RECOVERY:
			case LOGENTRY_SERVICE_OK:

				history_type = SERVICE_HISTORY;

				/* get host and service names */
				temp_buffer = my_strtok(temp_entry->entry_text, ":");
				temp_buffer = my_strtok(NULL, ";");
				if (temp_buffer)
					entry_host_name = strdup(temp_buffer + 1);
				else
					entry_host_name = NULL;

				temp_buffer = my_strtok(NULL, ";");
				if (temp_buffer)
					entry_service_desc = strdup(temp_buffer);
				else
					entry_service_desc = NULL;

				if (temp_entry->type == LOGENTRY_SERVICE_CRITICAL) {
					strcpy(image, CRITICAL_ICON);
					strcpy(image_alt, CRITICAL_ICON_ALT);
					history_detail_type = HISTORY_SERVICE_CRITICAL;
				} else if (temp_entry->type == LOGENTRY_SERVICE_WARNING) {
					strcpy(image, WARNING_ICON);
					strcpy(image_alt, WARNING_ICON_ALT);
					history_detail_type = HISTORY_SERVICE_WARNING;
				} else if (temp_entry->type == LOGENTRY_SERVICE_UNKNOWN) {
					strcpy(image, UNKNOWN_ICON);
					strcpy(image_alt, UNKNOWN_ICON_ALT);
					history_detail_type = HISTORY_SERVICE_UNKNOWN;
				} else if (temp_entry->type == LOGENTRY_SERVICE_RECOVERY || temp_entry->type == LOGENTRY_SERVICE_OK) {
					strcpy(image, OK_ICON);
					strcpy(image_alt, OK_ICON_ALT);
					history_detail_type = HISTORY_SERVICE_RECOVERY;
				}
				break;

				/* service flapping alerts */
			case LOGENTRY_SERVICE_FLAPPING_STARTED:
			case LOGENTRY_SERVICE_FLAPPING_STOPPED:
			case LOGENTRY_SERVICE_FLAPPING_DISABLED:

				if (display_flapping_alerts == FALSE)
					continue;

				history_type = SERVICE_FLAPPING_HISTORY;

				/* get host and service names */
				temp_buffer = my_strtok(temp_entry->entry_text, ":");
				temp_buffer = my_strtok(NULL, ";");
				if (temp_buffer)
					entry_host_name = strdup(temp_buffer + 1);
				else
					entry_host_name = NULL;
				temp_buffer = my_strtok(NULL, ";");
				if (temp_buffer)
					entry_service_desc = strdup(temp_buffer);
				else
					entry_service_desc = NULL;

				strcpy(image, FLAPPING_ICON);

				if (temp_entry->type == LOGENTRY_SERVICE_FLAPPING_STARTED)
					strcpy(image_alt, "Service started flapping");
				else if (temp_entry->type == LOGENTRY_SERVICE_FLAPPING_STOPPED)
					strcpy(image_alt, "Service stopped flapping");
				else if (temp_entry->type == LOGENTRY_SERVICE_FLAPPING_DISABLED)
					strcpy(image_alt, "Service flap detection disabled");

				break;

				/* service downtime alerts */
			case LOGENTRY_SERVICE_DOWNTIME_STARTED:
			case LOGENTRY_SERVICE_DOWNTIME_STOPPED:
			case LOGENTRY_SERVICE_DOWNTIME_CANCELLED:

				if (display_downtime_alerts == FALSE)
					continue;

				history_type = SERVICE_DOWNTIME_HISTORY;

				/* get host and service names */
				temp_buffer = my_strtok(temp_entry->entry_text, ":");
				temp_buffer = my_strtok(NULL, ";");
				if (temp_buffer)
					entry_host_name = strdup(temp_buffer + 1);
				else
					entry_host_name = NULL;
				temp_buffer = my_strtok(NULL, ";");
				if (temp_buffer)
					entry_service_desc = strdup(temp_buffer);
				else
					entry_service_desc = NULL;

				strcpy(image, DOWNTIME_ICON);

				if (temp_entry->type == LOGENTRY_SERVICE_DOWNTIME_STARTED)
					strcpy(image_alt, "Service entered a period of scheduled downtime");
				else if (temp_entry->type == LOGENTRY_SERVICE_DOWNTIME_STOPPED)
					strcpy(image_alt, "Service exited from a period of scheduled downtime");
				else if (temp_entry->type == LOGENTRY_SERVICE_DOWNTIME_CANCELLED)
					strcpy(image_alt, "Service scheduled downtime has been cancelled");

				break;

				/* host state alerts */
			case LOGENTRY_HOST_DOWN:
			case LOGENTRY_HOST_UNREACHABLE:
			case LOGENTRY_HOST_RECOVERY:
			case LOGENTRY_HOST_UP:

				history_type = HOST_HISTORY;

				/* get host name */
				temp_buffer = my_strtok(temp_entry->entry_text, ":");
				temp_buffer = my_strtok(NULL, ";");
				if (temp_buffer)
					entry_host_name = strdup(temp_buffer + 1);
				else
					entry_host_name = NULL;

				if (temp_entry->type == LOGENTRY_HOST_DOWN) {
					strcpy(image, HOST_DOWN_ICON);
					strcpy(image_alt, HOST_DOWN_ICON_ALT);
					history_detail_type = HISTORY_HOST_DOWN;
				} else if (temp_entry->type == LOGENTRY_HOST_UNREACHABLE) {
					strcpy(image, HOST_UNREACHABLE_ICON);
					strcpy(image_alt, HOST_UNREACHABLE_ICON_ALT);
					history_detail_type = HISTORY_HOST_UNREACHABLE;
				} else if (temp_entry->type == LOGENTRY_HOST_RECOVERY || temp_entry->type == LOGENTRY_HOST_UP) {
					strcpy(image, HOST_UP_ICON);
					strcpy(image_alt, HOST_UP_ICON_ALT);
					history_detail_type = HISTORY_HOST_RECOVERY;
				}

				break;

				/* host flapping alerts */
			case LOGENTRY_HOST_FLAPPING_STARTED:
			case LOGENTRY_HOST_FLAPPING_STOPPED:
			case LOGENTRY_HOST_FLAPPING_DISABLED:

				if (display_flapping_alerts == FALSE)
					continue;

				history_type = HOST_FLAPPING_HISTORY;

				/* get host name */
				temp_buffer = my_strtok(temp_entry->entry_text, ":");
				temp_buffer = my_strtok(NULL, ";");
				if (temp_buffer)
					entry_host_name = strdup(temp_buffer + 1);
				else
					entry_host_name = NULL;

				strcpy(image, FLAPPING_ICON);

				if (temp_entry->type == LOGENTRY_HOST_FLAPPING_STARTED)
					strcpy(image_alt, "Host started flapping");
				else if (temp_entry->type == LOGENTRY_HOST_FLAPPING_STOPPED)
					strcpy(image_alt, "Host stopped flapping");
				else if (temp_entry->type == LOGENTRY_HOST_FLAPPING_DISABLED)
					strcpy(image_alt, "Host flap detection disabled");

				break;

				/* host downtime alerts */
			case LOGENTRY_HOST_DOWNTIME_STARTED:
			case LOGENTRY_HOST_DOWNTIME_STOPPED:
			case LOGENTRY_HOST_DOWNTIME_CANCELLED:

				if (display_downtime_alerts == FALSE)
					continue;

				history_type = HOST_DOWNTIME_HISTORY;

				/* get host name */
				temp_buffer = my_strtok(temp_entry->entry_text, ":");
				temp_buffer = my_strtok(NULL, ";");
				if (temp_buffer)
					entry_host_name = strdup(temp_buffer + 1);
				else
					entry_host_name = NULL;

				strcpy(image, DOWNTIME_ICON);

				if (temp_entry->type == LOGENTRY_HOST_DOWNTIME_STARTED)
					strcpy(image_alt, "Host entered a period of scheduled downtime");
				else if (temp_entry->type == LOGENTRY_HOST_DOWNTIME_STOPPED)
					strcpy(image_alt, "Host exited from a period of scheduled downtime");
				else if (temp_entry->type == LOGENTRY_HOST_DOWNTIME_CANCELLED)
					strcpy(image_alt, "Host scheduled downtime has been cancelled");

				break;


				/* program start */
			case LOGENTRY_STARTUP:
				if (display_system_messages == FALSE)
					continue;
				strcpy(image, START_ICON);
				strcpy(image_alt, START_ICON_ALT);
				system_message = TRUE;
				break;

				/* program termination */
			case LOGENTRY_SHUTDOWN:
			case LOGENTRY_BAILOUT:
				if (display_system_messages == FALSE)
					continue;
				strcpy(image, STOP_ICON);
				strcpy(image_alt, STOP_ICON_ALT);
				system_message = TRUE;
				break;

				/* program restart */
			case LOGENTRY_RESTART:
				if (display_system_messages == FALSE)
					continue;
				strcpy(image, RESTART_ICON);
				strcpy(image_alt, RESTART_ICON_ALT);
				system_message = TRUE;
				break;
			}

			image[sizeof(image) - 1] = '\x0';
			image_alt[sizeof(image_alt) - 1] = '\x0';

			/* get the timestamp */
			time_ptr = localtime(&temp_entry->timestamp);
			strftime(current_message_date, sizeof(current_message_date), "%B %d, %Y %H:00\n", time_ptr);
			current_message_date[sizeof(current_message_date) - 1] = '\x0';

			get_time_string(&temp_entry->timestamp, date_time, sizeof(date_time), SHORT_DATE_TIME);
			strip(date_time);

			if (strcmp(image, "")) {

				display_line = FALSE;

				if (system_message == TRUE)
					display_line = TRUE;

				else if (display_type == DISPLAY_HOSTS || display_type == DISPLAY_HOSTGROUPS) {

					if (history_type == HOST_HISTORY || history_type == SERVICE_HISTORY) {
						snprintf(match1, sizeof(match1), " HOST ALERT: %s;", host_name);
						snprintf(match2, sizeof(match2), " SERVICE ALERT: %s;", host_name);
					} else if (history_type == HOST_FLAPPING_HISTORY || history_type == SERVICE_FLAPPING_HISTORY) {
						snprintf(match1, sizeof(match1), " HOST FLAPPING ALERT: %s;", host_name);
						snprintf(match2, sizeof(match2), " SERVICE FLAPPING ALERT: %s;", host_name);
					} else if (history_type == HOST_DOWNTIME_HISTORY || history_type == SERVICE_DOWNTIME_HISTORY) {
						snprintf(match1, sizeof(match1), " HOST DOWNTIME ALERT: %s;", host_name);
						snprintf(match2, sizeof(match2), " SERVICE DOWNTIME ALERT: %s;", host_name);
					}

					if (show_all_hosts == TRUE)
						display_line = TRUE;
					else if (strstr(temp_entry->entry_text, match1))
						display_line = TRUE;
					else if (strstr(temp_entry->entry_text, match2))
						display_line = TRUE;

					if (display_line == TRUE) {
						if (history_options == HISTORY_ALL)
							display_line = TRUE;
						else if (history_options == HISTORY_HOST_ALL && (history_type == HOST_HISTORY || history_type == HOST_FLAPPING_HISTORY || history_type == HOST_DOWNTIME_HISTORY))
							display_line = TRUE;
						else if (history_options == HISTORY_SERVICE_ALL && (history_type == SERVICE_HISTORY || history_type == SERVICE_FLAPPING_HISTORY || history_type == SERVICE_DOWNTIME_HISTORY))
							display_line = TRUE;
						else if ((history_type == HOST_HISTORY || history_type == SERVICE_HISTORY) && (history_detail_type & history_options))
							display_line = TRUE;
						else
							display_line = FALSE;
					}

					/* check alert state types */
					if (display_line == TRUE && (history_type == HOST_HISTORY || history_type == SERVICE_HISTORY)) {
						if (state_options == STATE_ALL)
							display_line = TRUE;
						else if ((state_options & STATE_SOFT) && strstr(temp_entry->entry_text, ";SOFT;"))
							display_line = TRUE;
						else if ((state_options & STATE_HARD) && strstr(temp_entry->entry_text, ";HARD;"))
							display_line = TRUE;
						else
							display_line = FALSE;
					}
				}

				else if (display_type == DISPLAY_SERVICES || display_type == DISPLAY_SERVICEGROUPS) {

					if (history_type == SERVICE_HISTORY)
						snprintf(match1, sizeof(match1), " SERVICE ALERT: %s;%s;", host_name, service_desc);
					else if (history_type == SERVICE_FLAPPING_HISTORY)
						snprintf(match1, sizeof(match1), " SERVICE FLAPPING ALERT: %s;%s;", host_name, service_desc);
					else if (history_type == SERVICE_DOWNTIME_HISTORY)
						snprintf(match1, sizeof(match1), " SERVICE DOWNTIME ALERT: %s;%s;", host_name, service_desc);

					if (display_type == DISPLAY_SERVICEGROUPS)
						display_line = TRUE;
					else if (strstr(temp_entry->entry_text, match1))
						display_line = TRUE;

					if (history_type != SERVICE_HISTORY && history_type != SERVICE_FLAPPING_HISTORY && history_type != SERVICE_DOWNTIME_HISTORY)
						display_line = FALSE;

					if (display_line == TRUE) {
						if (history_options == HISTORY_ALL || history_options == HISTORY_SERVICE_ALL)
							display_line = TRUE;
						else if (history_options & history_detail_type)
							display_line = TRUE;
						else
							display_line = FALSE;
					}

					/* check alert state type */
					if (display_line == TRUE && history_type == SERVICE_HISTORY) {

						if (state_options == STATE_ALL)
							display_line = TRUE;
						else if ((state_options & STATE_SOFT) && strstr(temp_entry->entry_text, ";SOFT;"))
							display_line = TRUE;
						else if ((state_options & STATE_HARD) && strstr(temp_entry->entry_text, ";HARD;"))
							display_line = TRUE;
						else
							display_line = FALSE;
					}
				}

				/* make sure user is authorized to view this log entry */
				if (display_line == TRUE) {

					if (system_message == TRUE) {
						if (is_authorized_for_system_information(&current_authdata) == FALSE)
							display_line = FALSE;
					} else {
						temp_host = find_host(entry_host_name);

						if (history_type == HOST_HISTORY || history_type == HOST_FLAPPING_HISTORY || history_type == HOST_DOWNTIME_HISTORY) {
							if (is_authorized_for_host(temp_host, &current_authdata) == FALSE)
								display_line = FALSE;
							else if (display_type == DISPLAY_HOSTGROUPS && is_host_member_of_hostgroup(temp_hostgroup, temp_host) == FALSE)
								display_line = FALSE;
						} else {
							temp_service = find_service(entry_host_name, entry_service_desc);
							if (is_authorized_for_service(temp_service, &current_authdata) == FALSE)
								display_line = FALSE;
							else if (display_type == DISPLAY_HOSTGROUPS && is_host_member_of_hostgroup(temp_hostgroup, temp_host) == FALSE)
								display_line = FALSE;
							else if (display_type == DISPLAY_SERVICEGROUPS && is_service_member_of_servicegroup(temp_servicegroup, temp_service) == FALSE)
								display_line = FALSE;
						}
					}
				}

				/* display the entry if we should... */
				if (display_line == TRUE) {

					if (result_limit != 0  && (((total_entries + 1) < result_start) || (total_entries >= ((result_start + result_limit) - 1)))) {
						total_entries++;
						continue;
					}

					displayed_entries++;
					total_entries++;

					if (strcmp(last_message_date, current_message_date) != 0 && display_timebreaks == TRUE) {
						printf("</DIV><BR CLEAR='all' />\n");
						printf("<DIV CLASS='dateTimeBreak'>\n");
						printf("<table border=0 width=95%%><tr>");
						printf("<td width=40%%><hr width=100%%></td>");
						printf("<td align=center CLASS='dateTimeBreak'>%s</td>", current_message_date);
						printf("<td width=40%%><hr width=100%%></td>");
						printf("</tr></table>\n");
						printf("</DIV>\n");
						printf("<BR CLEAR='all' /><DIV CLASS='logEntries'>\n");
						strncpy(last_message_date, current_message_date, sizeof(last_message_date));
						last_message_date[sizeof(last_message_date) - 1] = '\x0';
					}

					if (display_frills == TRUE)
						printf("<img align='left' src='%s%s' alt='%s' title='%s' />", url_images_path, image, image_alt, image_alt);
					printf("[%s] %s", date_time, html_encode(temp_entry->entry_text, FALSE));
					if (enable_splunk_integration == TRUE) {
						printf("&nbsp;&nbsp;&nbsp;");
						display_splunk_generic_url(temp_entry->entry_text, 2);
					}
					printf("<br clear='all' />\n");
				}
			}

			/* free memory */
			free(entry_host_name);
			entry_host_name = NULL;
			free(entry_service_desc);
			entry_service_desc = NULL;
		}
	}

	free_log_entries(&entry_list);

	printf("</DIV>\n");

	if (total_entries == 0) {
		printf("<HR>\n");
		printf("<DIV CLASS='errorMessage' style='text-align:center'>No history information was found ");
		if (display_type == DISPLAY_HOSTS)
			printf("%s", (show_all_hosts == TRUE) ? "" : "for this host ");
		else
			printf("for this service ");
		printf("in log files for selected date.</DIV>");
		printf("<script type='text/javascript'>document.getElementById('hist_page_selector').style.display='none';</script>");
	} else {
		printf("<HR>\n");
		page_num_selector(result_start, total_entries, displayed_entries);
	}

	return;
}
Exemple #11
0
/* displays service status */
void display_service(void) {
	service *temp_service;
	servicestatus *temp_servicestatus;
	char last_check[MAX_DATETIME_LENGTH];
	int days;
	int hours;
	int minutes;
	int seconds;
	time_t current_time;
	time_t t;
	char state_duration[48];
	int found;

	/**** MAIN SCREEN (CARD 1) ****/
	printf("<card id='card1' title='Service Status'>\n");
	printf("<p align='center' mode='nowrap'>\n");
	printf("<b>Service '%s' on host '%s'</b><br/>\n", service_desc, host_name);

	/* find the service */
	temp_service = find_service(host_name, service_desc);
	temp_servicestatus = find_servicestatus(host_name, service_desc);
	if (temp_service == NULL || temp_servicestatus == NULL) {

		printf("<b>Error: Could not find service!</b>\n");
		printf("</p>\n");
		printf("</card>\n");
		return;
	}

	/* check authorization */
	if (is_authorized_for_service(temp_service, &current_authdata) == FALSE) {

		printf("<b>Error: Not authorized for service!</b>\n");
		printf("</p>\n");
		printf("</card>\n");
		return;
	}


	printf("<table columns='2' align='LL'>\n");

	printf("<tr><td>Status:</td><td>");
	if (temp_servicestatus->status == SERVICE_OK)
		printf("OK");
	else if (temp_servicestatus->status == SERVICE_PENDING)
		printf("PENDING");
	else if (temp_servicestatus->status == SERVICE_WARNING)
		printf("WARNING");
	else if (temp_servicestatus->status == SERVICE_UNKNOWN)
		printf("UNKNOWN");
	else if (temp_servicestatus->status == SERVICE_CRITICAL)
		printf("CRITICAL");
	else
		printf("?");
	printf("</td></tr>\n");

	printf("<tr><td>Info:</td><td>%s</td></tr>\n", temp_servicestatus->plugin_output);

	get_time_string(&temp_servicestatus->last_check, last_check, sizeof(last_check) - 1, SHORT_DATE_TIME);
	printf("<tr><td>Last Check:</td><td>%s</td></tr>\n", last_check);

	current_time = time(NULL);
	if (temp_servicestatus->last_state_change == (time_t)0)
		t = current_time - program_start;
	else
		t = current_time - temp_servicestatus->last_state_change;
	get_time_breakdown((unsigned long)t, &days, &hours, &minutes, &seconds);
	snprintf(state_duration, sizeof(state_duration) - 1, "%2dd %2dh %2dm %2ds%s", days, hours, minutes, seconds, (temp_servicestatus->last_state_change == (time_t)0) ? "+" : "");
	printf("<tr><td>Duration:</td><td>%s</td></tr>\n", state_duration);

	printf("<tr><td>Properties:</td><td>");
	found = 0;
	if (temp_servicestatus->checks_enabled == FALSE) {
		printf("%sChecks disabled", (found == 1) ? ", " : "");
		found = 1;
	}
	if (temp_servicestatus->notifications_enabled == FALSE) {
		printf("%sNotifications disabled", (found == 1) ? ", " : "");
		found = 1;
	}
	if (temp_servicestatus->problem_has_been_acknowledged == TRUE) {
		printf("%sProblem acknowledged", (found == 1) ? ", " : "");
		found = 1;
	}
	if (temp_servicestatus->scheduled_downtime_depth > 0) {
		printf("%sIn scheduled downtime", (found == 1) ? ", " : "");
		found = 1;
	}
	if (found == 0)
		printf("N/A");
	printf("</td></tr>\n");

	printf("</table>\n");
	printf("<br/>\n");
	printf("<b><anchor title='View Host'>View Host<go href='%s' method='post'><postfield name='host' value='%s'/></go></anchor></b>\n", STATUSWML_CGI, escape_string(host_name));
	printf("<b><anchor title='Service Commands'>Svc. Commands<go href='#card2'/></anchor></b>\n");
	printf("</p>\n");

	printf("</card>\n");


	/**** COMMANDS SCREEN (CARD 2) ****/
	printf("<card id='card2' title='Service Commands'>\n");
	printf("<p align='center' mode='nowrap'>\n");
	printf("<b>Service Commands</b><br/>\n");

	if (temp_servicestatus->status != SERVICE_OK && temp_servicestatus->status != SERVICE_PENDING)
		printf("<b><anchor title='Acknowledge Problem'>Acknowledge Problem<go href='#card3'/></anchor></b>\n");

	if (temp_servicestatus->checks_enabled == FALSE) {
		printf("<b><anchor title='Enable Checks'>Enable Checks<go href='%s' method='post'><postfield name='host' value='%s'/>", CMD_CGI, escape_string(host_name));
		printf("<postfield name='service' value='%s'/><postfield name='cmd_typ' value='%d'/><postfield name='cmd_mod' value='%d'/><postfield name='content' value='wml'/></go></anchor></b><br/>\n", escape_string(service_desc), CMD_ENABLE_SVC_CHECK, CMDMODE_COMMIT);
	} else {
		printf("<b><anchor title='Disable Checks'>Disable Checks<go href='%s' method='post'><postfield name='host' value='%s'/>", CMD_CGI, escape_string(host_name));
		printf("<postfield name='service' value='%s'/><postfield name='cmd_typ' value='%d'/><postfield name='cmd_mod' value='%d'/><postfield name='content' value='wml'/></go></anchor></b><br/>\n", escape_string(service_desc), CMD_DISABLE_SVC_CHECK, CMDMODE_COMMIT);

		printf("<b><anchor title='Schedule Immediate Check'>Schedule Immediate Check<go href='%s' method='post'><postfield name='host' value='%s'/>", CMD_CGI, escape_string(host_name));
		printf("<postfield name='service' value='%s'/><postfield name='start_time' value='%lu'/><postfield name='cmd_typ' value='%d'/><postfield name='cmd_mod' value='%d'/><postfield name='content' value='wml'/></go></anchor></b><br/>\n", escape_string(service_desc), (unsigned long)current_time, CMD_SCHEDULE_SVC_CHECK, CMDMODE_COMMIT);
	}

	if (temp_servicestatus->notifications_enabled == FALSE) {
		printf("<b><anchor title='Enable Notifications'>Enable Notifications<go href='%s' method='post'><postfield name='host' value='%s'/>", CMD_CGI, escape_string(host_name));
		printf("<postfield name='service' value='%s'/><postfield name='cmd_typ' value='%d'/><postfield name='cmd_mod' value='%d'/><postfield name='content' value='wml'/></go></anchor></b><br/>\n", escape_string(service_desc), CMD_ENABLE_SVC_NOTIFICATIONS, CMDMODE_COMMIT);
	} else {
		printf("<b><anchor title='Disable Notifications'>Disable Notifications<go href='%s' method='post'><postfield name='host' value='%s'/>", CMD_CGI, escape_string(host_name));
		printf("<postfield name='service' value='%s'/><postfield name='cmd_typ' value='%d'/><postfield name='cmd_mod' value='%d'/><postfield name='content' value='wml'/></go></anchor></b><br/>\n", escape_string(service_desc), CMD_DISABLE_SVC_NOTIFICATIONS, CMDMODE_COMMIT);
	}

	printf("</p>\n");

	printf("</card>\n");


	/**** ACKNOWLEDGEMENT SCREEN (CARD 3) ****/
	printf("<card id='card3' title='Acknowledge Problem'>\n");
	printf("<p align='center' mode='nowrap'>\n");
	printf("<b>Acknowledge Problem</b><br/>\n");
	printf("</p>\n");

	printf("<p align='center' mode='wrap'>\n");
	printf("<b>Your Name:</b><br/>\n");
	printf("<input name='name' value='%s' /><br/>\n", ((use_ssl_authentication) ? (getenv("SSL_CLIENT_S_DN_CN")) : (getenv("REMOTE_USER"))));
	printf("<b>Comment:</b><br/>\n");
	printf("<input name='comment' value='acknowledged by WAP'/>\n");

	printf("<do type='accept'>\n");
	printf("<go href='%s' method='post'><postfield name='host' value='%s'/>", CMD_CGI, escape_string(host_name));
	printf("<postfield name='service' value='%s'/><postfield name='com_author' value='$(name)'/><postfield name='com_data' value='$(comment)'/><postfield name='persistent' value=''/><postfield name='send_notification' value=''/><postfield name='cmd_typ' value='%d'/><postfield name='cmd_mod' value='%d'/><postfield name='content' value='wml'/></go>\n", escape_string(service_desc), CMD_ACKNOWLEDGE_SVC_PROBLEM, CMDMODE_COMMIT);
	printf("</do>\n");

	printf("</p>\n");

	printf("</card>\n");

	return;
}
Exemple #12
0
static int hook_external_command(merlin_event *pkt, void *data)
{
	nebstruct_external_command_data *ds = (nebstruct_external_command_data *)data;
	int cb_result = NEB_OK;

	/*
	 * all comments generate two events, but we only want to
	 * send one of them, so focus on NEBTYPE_EXTERNALCOMMAND_START,
	 * since we need to be able to block the execution of the command
	 * in some cases where the command affects a single host or service.
	 */
	if (ds->type != NEBTYPE_EXTERNALCOMMAND_START)
		return NEB_OK;

	switch (ds->command_type) {
		/*
		 * Comments are handled by their respective comment
		 * events, so we mustn't forward them.
		 */
	case CMD_DEL_HOST_COMMENT:
	case CMD_DEL_SVC_COMMENT:
	case CMD_ADD_HOST_COMMENT:
	case CMD_ADD_SVC_COMMENT:
		return NEB_OK;

		/*
		 * These only contain the downtime id, so they're mostly useless,
		 * but potentially dangerous.
		 * We'll forward the downtime_delete event instead.
		 */
	case CMD_DEL_HOST_DOWNTIME:
	case CMD_DEL_SVC_DOWNTIME:
		return NEB_OK;

		/*
		 * these are forwarded and handled specially on the
		 * receiving end
		 */
	case CMD_ACKNOWLEDGE_HOST_PROBLEM:
	case CMD_ACKNOWLEDGE_SVC_PROBLEM:

		/*
		 * downtime is a troll of its own. For now, downtime
		 * commands aren't blocked, but their comments are.
		 * We keep them stashed here though, in case we
		 * want to modify how we handle them later.
		 */
	case CMD_SCHEDULE_HOST_DOWNTIME:
	case CMD_SCHEDULE_SVC_DOWNTIME:
	case CMD_SCHEDULE_AND_PROPAGATE_TRIGGERED_HOST_DOWNTIME:
	case CMD_SCHEDULE_AND_PROPAGATE_HOST_DOWNTIME:
		/* fallthrough */

	case CMD_ENABLE_SVC_CHECK:
	case CMD_DISABLE_SVC_CHECK:
	case CMD_SCHEDULE_SVC_CHECK:
	case CMD_DELAY_SVC_NOTIFICATION:
	case CMD_DELAY_HOST_NOTIFICATION:
	case CMD_ENABLE_HOST_SVC_CHECKS:
	case CMD_DISABLE_HOST_SVC_CHECKS:
	case CMD_SCHEDULE_HOST_SVC_CHECKS:
	case CMD_DELAY_HOST_SVC_NOTIFICATIONS:
	case CMD_DEL_ALL_HOST_COMMENTS:
	case CMD_DEL_ALL_SVC_COMMENTS:
	case CMD_ENABLE_SVC_NOTIFICATIONS:
	case CMD_DISABLE_SVC_NOTIFICATIONS:
	case CMD_ENABLE_HOST_NOTIFICATIONS:
	case CMD_DISABLE_HOST_NOTIFICATIONS:
	case CMD_ENABLE_HOST_SVC_NOTIFICATIONS:
	case CMD_DISABLE_HOST_SVC_NOTIFICATIONS:
	case CMD_ENABLE_PASSIVE_SVC_CHECKS:
	case CMD_DISABLE_PASSIVE_SVC_CHECKS:
	case CMD_ENABLE_HOST_EVENT_HANDLER:
	case CMD_DISABLE_HOST_EVENT_HANDLER:
	case CMD_ENABLE_SVC_EVENT_HANDLER:
	case CMD_DISABLE_SVC_EVENT_HANDLER:
	case CMD_ENABLE_HOST_CHECK:
	case CMD_DISABLE_HOST_CHECK:
	case CMD_START_OBSESSING_OVER_SVC_CHECKS:
	case CMD_STOP_OBSESSING_OVER_SVC_CHECKS:
	case CMD_REMOVE_HOST_ACKNOWLEDGEMENT:
	case CMD_REMOVE_SVC_ACKNOWLEDGEMENT:
	case CMD_SCHEDULE_FORCED_HOST_SVC_CHECKS:
	case CMD_SCHEDULE_FORCED_SVC_CHECK:
	case CMD_ENABLE_HOST_FLAP_DETECTION:
	case CMD_DISABLE_HOST_FLAP_DETECTION:
	case CMD_ENABLE_SVC_FLAP_DETECTION:
	case CMD_DISABLE_SVC_FLAP_DETECTION:
	case CMD_DISABLE_PASSIVE_HOST_CHECKS:
	case CMD_SCHEDULE_HOST_CHECK:
	case CMD_SCHEDULE_FORCED_HOST_CHECK:
	case CMD_CHANGE_HOST_EVENT_HANDLER:
	case CMD_CHANGE_SVC_EVENT_HANDLER:
	case CMD_CHANGE_HOST_CHECK_COMMAND:
	case CMD_CHANGE_SVC_CHECK_COMMAND:
	case CMD_CHANGE_NORMAL_HOST_CHECK_INTERVAL:
	case CMD_CHANGE_NORMAL_SVC_CHECK_INTERVAL:
	case CMD_CHANGE_RETRY_SVC_CHECK_INTERVAL:
	case CMD_CHANGE_MAX_HOST_CHECK_ATTEMPTS:
	case CMD_CHANGE_MAX_SVC_CHECK_ATTEMPTS:
	case CMD_ENABLE_HOST_AND_CHILD_NOTIFICATIONS:
	case CMD_DISABLE_HOST_AND_CHILD_NOTIFICATIONS:
	case CMD_ENABLE_HOST_FRESHNESS_CHECKS:
	case CMD_DISABLE_HOST_FRESHNESS_CHECKS:
	case CMD_SET_HOST_NOTIFICATION_NUMBER:
	case CMD_SET_SVC_NOTIFICATION_NUMBER:
	case CMD_CHANGE_HOST_CHECK_TIMEPERIOD:
	case CMD_CHANGE_SVC_CHECK_TIMEPERIOD:
	case CMD_CHANGE_CUSTOM_HOST_VAR:
	case CMD_CHANGE_CUSTOM_SVC_VAR:
	case CMD_ENABLE_CONTACT_HOST_NOTIFICATIONS:
	case CMD_DISABLE_CONTACT_HOST_NOTIFICATIONS:
	case CMD_ENABLE_CONTACT_SVC_NOTIFICATIONS:
	case CMD_DISABLE_CONTACT_SVC_NOTIFICATIONS:
	case CMD_ENABLE_CONTACTGROUP_HOST_NOTIFICATIONS:
	case CMD_DISABLE_CONTACTGROUP_HOST_NOTIFICATIONS:
	case CMD_ENABLE_CONTACTGROUP_SVC_NOTIFICATIONS:
	case CMD_DISABLE_CONTACTGROUP_SVC_NOTIFICATIONS:
	case CMD_CHANGE_RETRY_HOST_CHECK_INTERVAL:
	case CMD_CHANGE_HOST_NOTIFICATION_TIMEPERIOD:
	case CMD_CHANGE_SVC_NOTIFICATION_TIMEPERIOD:
	case CMD_CHANGE_CONTACT_HOST_NOTIFICATION_TIMEPERIOD:
	case CMD_CHANGE_CONTACT_SVC_NOTIFICATION_TIMEPERIOD:
	case CMD_CHANGE_HOST_MODATTR:
	case CMD_CHANGE_SVC_MODATTR:
		/*
		 * looks like we have everything we need, so get the
		 * selection based on the hostname so the daemon knows
		 * which node(s) to send the command to (could very well
		 * be 'nowhere')
		 */
		if (!merlin_sender)
			pkt->hdr.selection = get_cmd_selection(ds->command_args, 0);
		break;

	case CMD_SEND_CUSTOM_HOST_NOTIFICATION:
	case CMD_PROCESS_HOST_CHECK_RESULT:
		if (!merlin_sender) {
			/* Send to correct node */
			pkt->hdr.selection = get_cmd_selection(ds->command_args, 0);
		}
		/*
		 * Processing check results should only be done by the node owning the
		 * object. Thus, forward to all nodes, but execute it only on the node
		 * owning the object.
		 */
		{
			merlin_node *node;
			char *delim;
			host *this_host;

			delim = strchr(ds->command_args, ';');
			if(delim == NULL) {
				/*
				 * invalid arguments, we shouldn't do anything, but naemon can
				 * result in error later
				 */
				break;
			}

			this_host = find_host(strndupa(ds->command_args, delim - ds->command_args));
			if(this_host == NULL) {
				/*
				 * Unknown host. Thus, nothing we know that we should handle.
				 * Thus block it.
				 */
				cb_result = NEBERROR_CALLBACKCANCEL;
				break;
			}

			node = pgroup_host_node(this_host->id);
			/* If we are handling a custom notification, then we need a few extra
 		 	 * checks to ensure notifications are sent by the master if the
 		 	 * responsible node has notifies=no.
			 */
			if (ds->command_type == CMD_SEND_CUSTOM_HOST_NOTIFICATION) {
				/* if we are a poller, and have masters online, and don't notify */
				if (online_masters && !(ipc.flags & MERLIN_NODE_NOTIFIES)) {
					cb_result = NEBERROR_CALLBACKCANCEL;
				}
				/* Handle notification if we own the object */
				else if (node == &ipc) {
					return NEB_OK;
				}
				/* If a poller (not us) owns the object, either:
				 * Another peer handles the notification
				 * Another poller handles the notication
				 * Or we handle it here
				 */
				else if (node->type == MODE_POLLER) {
					if ((num_peers == 0 || should_run_check(this_host->id)) &&
							pgroup_num_notify(node) == 0) {
						return NEB_OK;
					} else {
						cb_result = NEBERROR_CALLBACKCANCEL;
					}
				}
			}
			else if (node != &ipc) {
				/* We're not responsible, so block this command here */
				cb_result = NEBERROR_CALLBACKCANCEL;
			}
			break;
		}

	case CMD_SEND_CUSTOM_SVC_NOTIFICATION:
	case CMD_PROCESS_SERVICE_CHECK_RESULT:
		if (!merlin_sender) {
			/* Send to correct node */
			pkt->hdr.selection = get_cmd_selection(ds->command_args, 0);
		}
		/*
		 * Processing check results should only be done by the node owning the
		 * object. Thus, forward to all nodes, but execute it only on the node
		 * owning the object.
		 */
		{
			merlin_node *node;
			char *delim_host;
			char *delim_service;
			char *host_name;
			char *service_description;
			service *this_service;

			delim_host = strchr(ds->command_args, ';');
			if(delim_host == NULL) {
				break;
			}
			host_name = strndupa(ds->command_args, delim_host - ds->command_args);

			delim_service = strchr(delim_host+1, ';');
			if(delim_service == NULL) {
				break;
			}
			service_description = strndupa(delim_host+1, delim_service - (delim_host+1));

			this_service = find_service(host_name, service_description);
			if(this_service == NULL) {
				/*
				 * Unknown service. Thus, nothing we know that we should handle.
				 * Thus block it.
				 */
				cb_result = NEBERROR_CALLBACKCANCEL;
				break;
			}

			node = pgroup_service_node(this_service->id);
			/* If we are handling a custom notification, then we need a few extra
 		 	 * checks to ensure notifications are sent by the master if the
 		 	 * responsible node has notifies=no.
			 */
			if (ds->command_type == CMD_SEND_CUSTOM_SVC_NOTIFICATION) {
				/* if we are a poller, and have masters online, and don't notify */
				if (online_masters && !(ipc.flags & MERLIN_NODE_NOTIFIES)) {
					cb_result = NEBERROR_CALLBACKCANCEL;
				}
				/* Handle notification if we own the object */
				else if (node == &ipc) {
					return NEB_OK;
				}
				/* If a poller (not us) owns the object, either:
				 * Another peer handles the notification
				 * Another poller handles the notication
				 * Or we handle it here
				 */
				else if (node->type == MODE_POLLER) {
					if ((num_peers == 0 || should_run_check(this_service->id)) &&
							pgroup_num_notify(node) == 0) {
						return NEB_OK;
					} else {
						cb_result = NEBERROR_CALLBACKCANCEL;
					}
				}
			}
			else if (node != &ipc) {
				/* We're not responsible, so block this command here */
				cb_result = NEBERROR_CALLBACKCANCEL;
			}
			break;
		}

	/* XXX downtime stuff on top */
	/*
	 * service- and hostgroup commands get sent to all peers
	 * and pollers, but not to masters since we can't know if
	 * we'd affect more than our fair share of services on the
	 * master.
	 */
	case CMD_SCHEDULE_HOSTGROUP_HOST_DOWNTIME:
	case CMD_SCHEDULE_HOSTGROUP_SVC_DOWNTIME:
	case CMD_ENABLE_HOSTGROUP_SVC_NOTIFICATIONS:
	case CMD_DISABLE_HOSTGROUP_SVC_NOTIFICATIONS:
	case CMD_ENABLE_HOSTGROUP_HOST_NOTIFICATIONS:
	case CMD_DISABLE_HOSTGROUP_HOST_NOTIFICATIONS:
	case CMD_ENABLE_HOSTGROUP_SVC_CHECKS:
	case CMD_DISABLE_HOSTGROUP_SVC_CHECKS:
	case CMD_ENABLE_HOSTGROUP_HOST_CHECKS:
	case CMD_DISABLE_HOSTGROUP_HOST_CHECKS:
	case CMD_ENABLE_HOSTGROUP_PASSIVE_SVC_CHECKS:
	case CMD_DISABLE_HOSTGROUP_PASSIVE_SVC_CHECKS:
	case CMD_ENABLE_HOSTGROUP_PASSIVE_HOST_CHECKS:
	case CMD_DISABLE_HOSTGROUP_PASSIVE_HOST_CHECKS:
		if (!merlin_sender)
			pkt->hdr.selection = get_cmd_selection(ds->command_args, 1);
		break;
	case CMD_SCHEDULE_SERVICEGROUP_HOST_DOWNTIME:
	case CMD_SCHEDULE_SERVICEGROUP_SVC_DOWNTIME:
	case CMD_ENABLE_SERVICEGROUP_SVC_NOTIFICATIONS:
	case CMD_DISABLE_SERVICEGROUP_SVC_NOTIFICATIONS:
	case CMD_ENABLE_SERVICEGROUP_HOST_NOTIFICATIONS:
	case CMD_DISABLE_SERVICEGROUP_HOST_NOTIFICATIONS:
	case CMD_ENABLE_SERVICEGROUP_SVC_CHECKS:
	case CMD_DISABLE_SERVICEGROUP_SVC_CHECKS:
	case CMD_ENABLE_SERVICEGROUP_HOST_CHECKS:
	case CMD_DISABLE_SERVICEGROUP_HOST_CHECKS:
	case CMD_ENABLE_SERVICEGROUP_PASSIVE_SVC_CHECKS:
	case CMD_DISABLE_SERVICEGROUP_PASSIVE_SVC_CHECKS:
	case CMD_ENABLE_SERVICEGROUP_PASSIVE_HOST_CHECKS:
	case CMD_DISABLE_SERVICEGROUP_PASSIVE_HOST_CHECKS:
		if (num_masters) {
			linfo("Submitting servicegroup commands on pollers isn't necessarily a good idea");
		}
		if (!merlin_sender)
			pkt->hdr.selection = DEST_PEERS_POLLERS;
		break;

	default:
		/*
		 * global commands get filtered in the daemon so only
		 * peers and pollers get them, but we block them right
		 * here if we have neither of those
		 */
		if (!(num_peers + num_pollers)) {
			ldebug("No peers or pollers. Not sending command %d anywhere",
			       ds->command_type);
			return 0;
		}

		if (!merlin_sender) {
			pkt->hdr.selection = DEST_PEERS_POLLERS;
		}
		break;
	}

	if (merlin_sender)
		pkt->hdr.code = MAGIC_NONET;

	if(0 != send_generic(pkt, data)) {
		ldebug("Can't send merlin packet for command %d",
		       ds->command_type);
	}

	return cb_result;
}
Exemple #13
0
static NTSTATUS smbd_smb2_tree_connect(struct smbd_smb2_request *req,
				       const char *in_path,
				       uint8_t *out_share_type,
				       uint32_t *out_share_flags,
				       uint32_t *out_capabilities,
				       uint32_t *out_maximal_access,
				       uint32_t *out_tree_id)
{
	struct smbXsrv_connection *conn = req->sconn->conn;
	const char *share = in_path;
	char *service = NULL;
	int snum = -1;
	struct smbXsrv_tcon *tcon;
	NTTIME now = timeval_to_nttime(&req->request_time);
	connection_struct *compat_conn = NULL;
	struct user_struct *compat_vuser = req->session->compat;
	NTSTATUS status;
	bool encryption_required = req->session->global->encryption_required;
	bool guest_session = false;

	if (strncmp(share, "\\\\", 2) == 0) {
		const char *p = strchr(share+2, '\\');
		if (p) {
			share = p + 1;
		}
	}

	DEBUG(10,("smbd_smb2_tree_connect: path[%s] share[%s]\n",
		  in_path, share));

	service = talloc_strdup(talloc_tos(), share);
	if(!service) {
		return NT_STATUS_NO_MEMORY;
	}

	if (!strlower_m(service)) {
		DEBUG(2, ("strlower_m %s failed\n", service));
		return NT_STATUS_INVALID_PARAMETER;
	}

	/* TODO: do more things... */
	if (strequal(service,HOMES_NAME)) {
		if (compat_vuser->homes_snum == -1) {
			DEBUG(2, ("[homes] share not available for "
				"user %s because it was not found "
				"or created at session setup "
				"time\n",
				compat_vuser->session_info->unix_info->unix_name));
			return NT_STATUS_BAD_NETWORK_NAME;
		}
		snum = compat_vuser->homes_snum;
	} else if ((compat_vuser->homes_snum != -1)
                   && strequal(service,
			lp_servicename(talloc_tos(), compat_vuser->homes_snum))) {
		snum = compat_vuser->homes_snum;
	} else {
		snum = find_service(talloc_tos(), service, &service);
		if (!service) {
			return NT_STATUS_NO_MEMORY;
		}
	}

	if (snum < 0) {
		DEBUG(3,("smbd_smb2_tree_connect: couldn't find service %s\n",
			 service));
		return NT_STATUS_BAD_NETWORK_NAME;
	}

	if (lp_smb_encrypt(snum) == SMB_SIGNING_REQUIRED) {
		encryption_required = true;
	}

	if (security_session_user_level(compat_vuser->session_info, NULL) < SECURITY_USER) {
		guest_session = true;
	}

	if (guest_session && encryption_required) {
		DEBUG(1,("reject guest as encryption is required for service %s\n",
			 service));
		return NT_STATUS_ACCESS_DENIED;
	}

	if (!(conn->smb2.server.capabilities & SMB2_CAP_ENCRYPTION)) {
		if (encryption_required) {
			DEBUG(1,("reject tcon with dialect[0x%04X] "
				 "as encryption is required for service %s\n",
				 conn->smb2.server.dialect, service));
			return NT_STATUS_ACCESS_DENIED;
		}
	}

	/* create a new tcon as child of the session */
	status = smb2srv_tcon_create(req->session, now, &tcon);
	if (!NT_STATUS_IS_OK(status)) {
		return status;
	}

	tcon->global->encryption_required = encryption_required;

	compat_conn = make_connection_smb2(req->sconn,
					tcon, snum,
					req->session->compat,
					"???",
					&status);
	if (compat_conn == NULL) {
		TALLOC_FREE(tcon);
		return status;
	}

	tcon->global->share_name = lp_servicename(tcon->global,
						  SNUM(compat_conn));
	if (tcon->global->share_name == NULL) {
		conn_free(compat_conn);
		TALLOC_FREE(tcon);
		return NT_STATUS_NO_MEMORY;
	}
	tcon->global->session_global_id =
		req->session->global->session_global_id;

	tcon->compat = talloc_move(tcon, &compat_conn);

	tcon->status = NT_STATUS_OK;

	status = smbXsrv_tcon_update(tcon);
	if (!NT_STATUS_IS_OK(status)) {
		TALLOC_FREE(tcon);
		return status;
	}

	if (IS_PRINT(tcon->compat)) {
		*out_share_type = SMB2_SHARE_TYPE_PRINT;
	} else if (IS_IPC(tcon->compat)) {
		*out_share_type = SMB2_SHARE_TYPE_PIPE;
	} else {
		*out_share_type = SMB2_SHARE_TYPE_DISK;
	}

	*out_share_flags = 0;

	if (lp_msdfs_root(SNUM(tcon->compat)) && lp_host_msdfs()) {
		*out_share_flags |= (SMB2_SHAREFLAG_DFS|SMB2_SHAREFLAG_DFS_ROOT);
		*out_capabilities = SMB2_SHARE_CAP_DFS;
	} else {
		*out_capabilities = 0;
	}

	switch(lp_csc_policy(SNUM(tcon->compat))) {
	case CSC_POLICY_MANUAL:
		break;
	case CSC_POLICY_DOCUMENTS:
		*out_share_flags |= SMB2_SHAREFLAG_AUTO_CACHING;
		break;
	case CSC_POLICY_PROGRAMS:
		*out_share_flags |= SMB2_SHAREFLAG_VDO_CACHING;
		break;
	case CSC_POLICY_DISABLE:
		*out_share_flags |= SMB2_SHAREFLAG_NO_CACHING;
		break;
	default:
		break;
	}

	if (lp_hide_unreadable(SNUM(tcon->compat)) ||
	    lp_hide_unwriteable_files(SNUM(tcon->compat))) {
		*out_share_flags |= SMB2_SHAREFLAG_ACCESS_BASED_DIRECTORY_ENUM;
	}

	if (encryption_required) {
		*out_share_flags |= SMB2_SHAREFLAG_ENCRYPT_DATA;
	}

	*out_maximal_access = tcon->compat->share_access;

	*out_tree_id = tcon->global->tcon_wire_id;
	return NT_STATUS_OK;
}
Exemple #14
0
/* handle performance data */
int handle_perfdata(int event_type, void *data) {
    nebstruct_host_check_data *hostchkdata   = NULL;
    nebstruct_service_check_data *srvchkdata = NULL;
    host *hst        = NULL;
    service *svc     = NULL;
    int has_perfdata = FALSE;

    gm_log( GM_LOG_TRACE, "handle_perfdata(%d)\n", event_type );
    if(process_performance_data == 0) {
        gm_log( GM_LOG_TRACE, "handle_perfdata() process_performance_data disabled globally\n" );
        return 0;
    }

    /* what type of event/data do we have? */
    switch (event_type) {

        case NEBCALLBACK_HOST_CHECK_DATA:
            /* an aggregated status data dump just started or ended */
            if ((hostchkdata = (nebstruct_host_check_data *) data)) {

                if (hostchkdata->type != NEBTYPE_HOSTCHECK_PROCESSED || hostchkdata->perf_data == NULL ) {
                    break;
                }

                hst = find_host(hostchkdata->host_name);
                if(hst->process_performance_data == 0) {
                    gm_log( GM_LOG_TRACE, "handle_perfdata() process_performance_data disabled for: %s\n", hst->name );
                    break;
                }

                uniq[0]='\x0';
                snprintf( uniq,GM_BUFFERSIZE-1,"%s", hostchkdata->host_name);

                temp_buffer[0]='\x0';
                snprintf( temp_buffer,GM_BUFFERSIZE-1,
                            "DATATYPE::HOSTPERFDATA\t"
                            "TIMET::%d\t"
                            "HOSTNAME::%s\t"
                            "HOSTPERFDATA::%s\t"
                            "HOSTCHECKCOMMAND::%s!%s\t"
                            "HOSTSTATE::%d\t"
                            "HOSTSTATETYPE::%d\n",
                            (int)hostchkdata->timestamp.tv_sec,
                            hostchkdata->host_name, hostchkdata->perf_data,
                            hostchkdata->command_name, hostchkdata->command_args,
                            hostchkdata->state, hostchkdata->state_type);
                has_perfdata = TRUE;
            }
            break;

        case NEBCALLBACK_SERVICE_CHECK_DATA:
            /* an aggregated status data dump just started or ended */
            if ((srvchkdata = (nebstruct_service_check_data *) data)) {

                if(srvchkdata->type != NEBTYPE_SERVICECHECK_PROCESSED || srvchkdata->perf_data == NULL) {
                    break;
                }

                /* find the nagios service object for this service */
                svc = find_service(srvchkdata->host_name, srvchkdata->service_description);
                if(svc->process_performance_data == 0) {
                    gm_log( GM_LOG_TRACE, "handle_perfdata() process_performance_data disabled for: %s - %s\n", svc->host_name, svc->description );
                    break;
                }

                uniq[0]='\x0';
                snprintf( uniq,GM_BUFFERSIZE-1,"%s-%s", srvchkdata->host_name, srvchkdata->service_description);

                temp_buffer[0]='\x0';
                snprintf( temp_buffer,GM_BUFFERSIZE-1,
                            "DATATYPE::SERVICEPERFDATA\t"
                            "TIMET::%d\t"
                            "HOSTNAME::%s\t"
                            "SERVICEDESC::%s\t"
                            "SERVICEPERFDATA::%s\t"
                            "SERVICECHECKCOMMAND::%s\t"
                            "SERVICESTATE::%d\t"
                            "SERVICESTATETYPE::%d\n\n\n",
                            (int)srvchkdata->timestamp.tv_sec,
                            srvchkdata->host_name, srvchkdata->service_description,
                            srvchkdata->perf_data, svc->service_check_command,
                            srvchkdata->state, srvchkdata->state_type);
                temp_buffer[GM_BUFFERSIZE-1]='\x0';
                has_perfdata = TRUE;
            }
            break;

        default:
            break;
    }

    if(has_perfdata == TRUE) {
        /* add our job onto the queue */
        if(add_job_to_queue( &client,
                             mod_gm_opt->server_list,
                             GM_PERFDATA_QUEUE,
                             (mod_gm_opt->perfdata_mode == GM_PERFDATA_OVERWRITE ? uniq : NULL),
                             temp_buffer,
                             GM_JOB_PRIO_NORMAL,
                             GM_DEFAULT_JOB_RETRIES,
                             mod_gm_opt->transportmode,
                             TRUE
                            ) == GM_OK) {
            gm_log( GM_LOG_TRACE, "handle_perfdata() finished successfully\n" );
        }
        else {
            gm_log( GM_LOG_TRACE, "handle_perfdata() finished unsuccessfully\n" );
        }
    }

    return 0;
}
Exemple #15
0
static int downtime_add(scheduled_downtime *dt)
{
	unsigned long prev_downtime_id;
	scheduled_downtime *trigger = NULL;
	struct host *h;
	struct service *s;

	if (!dt)
		return DT_ENULL;

	log_debug_info(DEBUGL_DOWNTIME, 0, "downtime_add(): id=%lu; type=%s; host=%s; service=%s\n",
				   dt->downtime_id,
				   dt->type == HOST_DOWNTIME ? "host" : "service",
				   dt->host_name, dt->service_description);
	/*
	 * check for errors.
	 * host_name must always be set
	 */
	if (!dt->host_name)
		return DT_EHOST;

	/* service_description should only be set for service downtime */
	if ((dt->type == HOST_DOWNTIME) != (!dt->service_description))
		return DT_ETYPE;
	/* type must be either SERVICE_DOWNTIME or HOST_DOWNTIME */
	if (dt->type != SERVICE_DOWNTIME && dt->type != HOST_DOWNTIME)
		return DT_ETYPE;
	/* triggered downtime must be triggered by an existing downtime */
	if (dt->triggered_by && !(trigger = find_downtime(ANY_DOWNTIME, dt->triggered_by)))
		return DT_ETRIGGER;
	/* non-triggered downtime must have start_time < end_time */
	if (!trigger && dt->start_time >= dt->end_time)
		return DT_ETIME;
	/* flexible downtime must have a duration */
	if (!dt->fixed && !dt->duration)
		return DT_ETIME;

	/* the object we're adding downtime for must exist */
	if (!dt->service_description) {
		if (!(h = find_host(dt->host_name)))
			return DT_EHOST;
	} else if (!(s = find_service(dt->host_name, dt->service_description))) {
		return DT_ESERVICE;
	}

	/* set downtime_id if not already set */
	prev_downtime_id = next_downtime_id;
	if (!dt->downtime_id) {
		dt->downtime_id = next_downtime_id++;
	} else if (dt->downtime_id >= next_downtime_id) {
		next_downtime_id = dt->downtime_id + 1;
	}

	if (fanout_add(dt_fanout, dt->downtime_id, dt) < 0) {
		next_downtime_id = prev_downtime_id;
		return errno;
	}

	if(defer_downtime_sorting || !scheduled_downtime_list ||
	   downtime_compar(&dt, &scheduled_downtime_list) < 0)
	{
		if (scheduled_downtime_list) {
			scheduled_downtime_list->prev = dt;
		}
		dt->next = scheduled_downtime_list;
		scheduled_downtime_list = dt;
		}
	else {
		scheduled_downtime *cur;

		/* add new downtime to downtime list, sorted by start time */
		for(cur = scheduled_downtime_list; cur; cur = cur->next) {
			if(downtime_compar(&dt, &cur) < 0) {
				dt->prev = cur->prev;
				dt->next = cur;
				cur->prev->next = dt;
				cur->prev = dt;
				break;
				}
			if (!cur->next) {
				dt->next = NULL;
				cur->next = dt;
				dt->prev = cur;
				break;
			}
		}
	}
	return OK;
}
Exemple #16
0
void get_history(void) {
	mmapfile *thefile = NULL;
	char image[MAX_INPUT_BUFFER];
	char image_alt[MAX_INPUT_BUFFER];
	char *input = NULL;
	char *input2 = NULL;
	char match1[MAX_INPUT_BUFFER];
	char match2[MAX_INPUT_BUFFER];
	int found_line = FALSE;
	int system_message = FALSE;
	int display_line = FALSE;
	time_t t;
	char date_time[MAX_DATETIME_LENGTH];
	char *temp_buffer = NULL;
	int history_type = SERVICE_HISTORY;
	int history_detail_type = HISTORY_SERVICE_CRITICAL;
	char *entry_host_name = NULL;
	char *entry_service_desc = NULL;
	host *temp_host = NULL;
	service *temp_service = NULL;
	int result = 0;

	char last_message_date[MAX_INPUT_BUFFER] = "";
	char current_message_date[MAX_INPUT_BUFFER] = "";
	struct tm *time_ptr = NULL;


	if(use_lifo == TRUE) {
		result = read_file_into_lifo(log_file_to_use);
		if(result != LIFO_OK) {
			if(result == LIFO_ERROR_MEMORY) {
				printf("<P><DIV CLASS='warningMessage'>Not enough memory to reverse log file - displaying history in natural order...</DIV></P>\n");
				}
			else if(result == LIFO_ERROR_FILE) {
				printf("<HR><P><DIV CLASS='errorMessage'>Error: Cannot open log file '%s' for reading!</DIV></P><HR>", log_file_to_use);
				return;
				}
			use_lifo = FALSE;
			}
		}

	if(use_lifo == FALSE) {

		if((thefile = mmap_fopen(log_file_to_use)) == NULL) {
			printf("<HR><P><DIV CLASS='errorMessage'>Error: Cannot open log file '%s' for reading!</DIV></P><HR>", log_file_to_use);
			return;
			}
		}

	printf("<P><DIV CLASS='logEntries'>\n");

	while(1) {

		my_free(input);
		my_free(input2);

		if(use_lifo == TRUE) {
			if((input = pop_lifo()) == NULL)
				break;
			}
		else {
			if((input = mmap_fgets(thefile)) == NULL)
				break;
			}

		strip(input);

		strcpy(image, "");
		strcpy(image_alt, "");
		system_message = FALSE;

		if((input2 = (char *)strdup(input)) == NULL)
			continue;

		/* service state alerts */
		if(strstr(input, "SERVICE ALERT:")) {

			history_type = SERVICE_HISTORY;

			/* get host and service names */
			temp_buffer = my_strtok(input2, "]");
			temp_buffer = my_strtok(NULL, ":");
			temp_buffer = my_strtok(NULL, ";");
			if(temp_buffer)
				entry_host_name = strdup(temp_buffer + 1);
			else
				entry_host_name = NULL;
			temp_buffer = my_strtok(NULL, ";");
			if(temp_buffer)
				entry_service_desc = strdup(temp_buffer);
			else
				entry_service_desc = NULL;

			if(strstr(input, ";CRITICAL;")) {
				strncpy(image, CRITICAL_ICON, sizeof(image));
				strncpy(image_alt, CRITICAL_ICON_ALT, sizeof(image_alt));
				history_detail_type = HISTORY_SERVICE_CRITICAL;
				}
			else if(strstr(input, ";WARNING;")) {
				strncpy(image, WARNING_ICON, sizeof(image));
				strncpy(image_alt, WARNING_ICON_ALT, sizeof(image_alt));
				history_detail_type = HISTORY_SERVICE_WARNING;
				}
			else if(strstr(input, ";UNKNOWN;")) {
				strncpy(image, UNKNOWN_ICON, sizeof(image));
				strncpy(image_alt, UNKNOWN_ICON_ALT, sizeof(image_alt));
				history_detail_type = HISTORY_SERVICE_UNKNOWN;
				}
			else if(strstr(input, ";RECOVERY;") || strstr(input, ";OK;")) {
				strncpy(image, OK_ICON, sizeof(image));
				strncpy(image_alt, OK_ICON_ALT, sizeof(image_alt));
				history_detail_type = HISTORY_SERVICE_RECOVERY;
				}
			}

		/* service flapping alerts */
		else if(strstr(input, "SERVICE FLAPPING ALERT:")) {

			if(display_flapping_alerts == FALSE)
				continue;

			history_type = SERVICE_FLAPPING_HISTORY;

			/* get host and service names */
			temp_buffer = my_strtok(input2, "]");
			temp_buffer = my_strtok(NULL, ":");
			temp_buffer = my_strtok(NULL, ";");
			if(temp_buffer)
				entry_host_name = strdup(temp_buffer + 1);
			else
				entry_host_name = NULL;
			temp_buffer = my_strtok(NULL, ";");
			if(temp_buffer)
				entry_service_desc = strdup(temp_buffer);
			else
				entry_service_desc = NULL;

			strncpy(image, FLAPPING_ICON, sizeof(image));

			if(strstr(input, ";STARTED;"))
				strncpy(image_alt, "Service started flapping", sizeof(image_alt));
			else if(strstr(input, ";STOPPED;"))
				strncpy(image_alt, "Service stopped flapping", sizeof(image_alt));
			else if(strstr(input, ";DISABLED;"))
				strncpy(image_alt, "Service flap detection disabled", sizeof(image_alt));
			}

		/* service downtime alerts */
		else if(strstr(input, "SERVICE DOWNTIME ALERT:")) {

			if(display_downtime_alerts == FALSE)
				continue;

			history_type = SERVICE_DOWNTIME_HISTORY;

			/* get host and service names */
			temp_buffer = my_strtok(input2, "]");
			temp_buffer = my_strtok(NULL, ":");
			temp_buffer = my_strtok(NULL, ";");
			if(temp_buffer)
				entry_host_name = strdup(temp_buffer + 1);
			else
				entry_host_name = NULL;
			temp_buffer = my_strtok(NULL, ";");
			if(temp_buffer)
				entry_service_desc = strdup(temp_buffer);
			else
				entry_service_desc = NULL;

			strncpy(image, SCHEDULED_DOWNTIME_ICON, sizeof(image));

			if(strstr(input, ";STARTED;"))
				strncpy(image_alt, "Service entered a period of scheduled downtime", sizeof(image_alt));
			else if(strstr(input, ";STOPPED;"))
				strncpy(image_alt, "Service exited from a period of scheduled downtime", sizeof(image_alt));
			else if(strstr(input, ";CANCELLED;"))
				strncpy(image_alt, "Service scheduled downtime has been cancelled", sizeof(image_alt));
			}

		/* host state alerts */
		else if(strstr(input, "HOST ALERT:")) {

			history_type = HOST_HISTORY;

			/* get host name */
			temp_buffer = my_strtok(input2, "]");
			temp_buffer = my_strtok(NULL, ":");
			temp_buffer = my_strtok(NULL, ";");
			if(temp_buffer)
				entry_host_name = strdup(temp_buffer + 1);
			else
				entry_host_name = NULL;

			if(strstr(input, ";DOWN;")) {
				strncpy(image, HOST_DOWN_ICON, sizeof(image));
				strncpy(image_alt, HOST_DOWN_ICON_ALT, sizeof(image_alt));
				history_detail_type = HISTORY_HOST_DOWN;
				}
			else if(strstr(input, ";UNREACHABLE;")) {
				strncpy(image, HOST_UNREACHABLE_ICON, sizeof(image));
				strncpy(image_alt, HOST_UNREACHABLE_ICON_ALT, sizeof(image_alt));
				history_detail_type = HISTORY_HOST_UNREACHABLE;
				}
			else if(strstr(input, ";RECOVERY") || strstr(input, ";UP;")) {
				strncpy(image, HOST_UP_ICON, sizeof(image));
				strncpy(image_alt, HOST_UP_ICON_ALT, sizeof(image_alt));
				history_detail_type = HISTORY_HOST_RECOVERY;
				}
			}

		/* host flapping alerts */
		else if(strstr(input, "HOST FLAPPING ALERT:")) {

			if(display_flapping_alerts == FALSE)
				continue;

			history_type = HOST_FLAPPING_HISTORY;

			/* get host name */
			temp_buffer = my_strtok(input2, "]");
			temp_buffer = my_strtok(NULL, ":");
			temp_buffer = my_strtok(NULL, ";");
			if(temp_buffer)
				entry_host_name = strdup(temp_buffer + 1);
			else
				entry_host_name = NULL;

			strncpy(image, FLAPPING_ICON, sizeof(image));

			if(strstr(input, ";STARTED;"))
				strncpy(image_alt, "Host started flapping", sizeof(image_alt));
			else if(strstr(input, ";STOPPED;"))
				strncpy(image_alt, "Host stopped flapping", sizeof(image_alt));
			else if(strstr(input, ";DISABLED;"))
				strncpy(image_alt, "Host flap detection disabled", sizeof(image_alt));
			}

		/* host downtime alerts */
		else if(strstr(input, "HOST DOWNTIME ALERT:")) {

			if(display_downtime_alerts == FALSE)
				continue;

			history_type = HOST_DOWNTIME_HISTORY;

			/* get host name */
			temp_buffer = my_strtok(input2, "]");
			temp_buffer = my_strtok(NULL, ":");
			temp_buffer = my_strtok(NULL, ";");
			if(temp_buffer)
				entry_host_name = strdup(temp_buffer + 1);
			else
				entry_host_name = NULL;

			strncpy(image, SCHEDULED_DOWNTIME_ICON, sizeof(image));

			if(strstr(input, ";STARTED;"))
				strncpy(image_alt, "Host entered a period of scheduled downtime", sizeof(image_alt));
			else if(strstr(input, ";STOPPED;"))
				strncpy(image_alt, "Host exited from a period of scheduled downtime", sizeof(image_alt));
			else if(strstr(input, ";CANCELLED;"))
				strncpy(image_alt, "Host scheduled downtime has been cancelled", sizeof(image_alt));
			}

		else if(display_system_messages == FALSE)
			continue;

		/* program start */
		else if(strstr(input, " starting...")) {
			strncpy(image, START_ICON, sizeof(image));
			strncpy(image_alt, START_ICON_ALT, sizeof(image_alt));
			system_message = TRUE;
			}

		/* normal program termination */
		else if(strstr(input, " shutting down...")) {
			strncpy(image, STOP_ICON, sizeof(image));
			strncpy(image_alt, STOP_ICON_ALT, sizeof(image_alt));
			system_message = TRUE;
			}

		/* abnormal program termination */
		else if(strstr(input, "Bailing out")) {
			strncpy(image, STOP_ICON, sizeof(image));
			strncpy(image_alt, STOP_ICON_ALT, sizeof(image_alt));
			system_message = TRUE;
			}

		/* program restart */
		else if(strstr(input, " restarting...")) {
			strncpy(image, RESTART_ICON, sizeof(image));
			strncpy(image_alt, RESTART_ICON_ALT, sizeof(image_alt));
			system_message = TRUE;
			}

		image[sizeof(image) - 1] = '\x0';
		image_alt[sizeof(image_alt) - 1] = '\x0';

		/* get the timestamp */
		temp_buffer = strtok(input, "]");
		t = (temp_buffer == NULL) ? 0L : strtoul(temp_buffer + 1, NULL, 10);

		time_ptr = localtime(&t);
		strftime(current_message_date, sizeof(current_message_date), "%B %d, %Y %H:00\n", time_ptr);
		current_message_date[sizeof(current_message_date) - 1] = '\x0';

		get_time_string(&t, date_time, sizeof(date_time), SHORT_DATE_TIME);
		strip(date_time);

		temp_buffer = strtok(NULL, "\n");

		if(strcmp(image, "")) {

			display_line = FALSE;

			if(system_message == TRUE)
				display_line = TRUE;

			else if(display_type == DISPLAY_HOSTS) {

				if(history_type == HOST_HISTORY || history_type == SERVICE_HISTORY) {
					snprintf(match1, sizeof( match1),
							" HOST ALERT: %s;", host_name);
					snprintf(match2, sizeof( match2),
							" SERVICE ALERT: %s;", host_name);
					}
				else if(history_type == HOST_FLAPPING_HISTORY || history_type == SERVICE_FLAPPING_HISTORY) {
					snprintf(match1, sizeof( match1),
							" HOST FLAPPING ALERT: %s;", host_name);
					snprintf(match2, sizeof( match2),
							" SERVICE FLAPPING ALERT: %s;", host_name);
					}
				else if(history_type == HOST_DOWNTIME_HISTORY || history_type == SERVICE_DOWNTIME_HISTORY) {
					snprintf(match1, sizeof( match1),
							" HOST DOWNTIME ALERT: %s;", host_name);
					snprintf(match2, sizeof( match2),
							" SERVICE DOWNTIME ALERT: %s;", host_name);
					}

				if(show_all_hosts == TRUE)
					display_line = TRUE;
				else if(strstr(temp_buffer, match1))
					display_line = TRUE;
				else if(strstr(temp_buffer, match2))
					display_line = TRUE;

				if(display_line == TRUE) {
					if(history_options == HISTORY_ALL)
						display_line = TRUE;
					else if(history_options == HISTORY_HOST_ALL && (history_type == HOST_HISTORY || history_type == HOST_FLAPPING_HISTORY || history_type == HOST_DOWNTIME_HISTORY))
						display_line = TRUE;
					else if(history_options == HISTORY_SERVICE_ALL && (history_type == SERVICE_HISTORY || history_type == SERVICE_FLAPPING_HISTORY || history_type == SERVICE_DOWNTIME_HISTORY))
						display_line = TRUE;
					else if((history_type == HOST_HISTORY || history_type == SERVICE_HISTORY) && (history_detail_type & history_options))
						display_line = TRUE;
					else
						display_line = FALSE;
					}

				/* check alert state types */
				if(display_line == TRUE && (history_type == HOST_HISTORY || history_type == SERVICE_HISTORY)) {
					if(state_options == STATE_ALL)
						display_line = TRUE;
					else if((state_options & STATE_SOFT) && strstr(temp_buffer, ";SOFT;"))
						display_line = TRUE;
					else if((state_options & STATE_HARD) && strstr(temp_buffer, ";HARD;"))
						display_line = TRUE;
					else
						display_line = FALSE;
					}
				}

			else if(display_type == DISPLAY_SERVICES) {

				if(history_type == SERVICE_HISTORY)
					snprintf(match1, sizeof( match1), " SERVICE ALERT: %s;%s;", host_name, svc_description);
				else if(history_type == SERVICE_FLAPPING_HISTORY)
					snprintf(match1, sizeof( match1), " SERVICE FLAPPING ALERT: %s;%s;", host_name, svc_description);
				else if(history_type == SERVICE_DOWNTIME_HISTORY)
					snprintf(match1, sizeof( match1), " SERVICE DOWNTIME ALERT: %s;%s;", host_name, svc_description);

				if(strstr(temp_buffer, match1) && (history_type == SERVICE_HISTORY || history_type == SERVICE_FLAPPING_HISTORY || history_type == SERVICE_DOWNTIME_HISTORY))
					display_line = TRUE;

				if(display_line == TRUE) {
					if(history_options == HISTORY_ALL || history_options == HISTORY_SERVICE_ALL)
						display_line = TRUE;
					else if(history_options & history_detail_type)
						display_line = TRUE;
					else
						display_line = FALSE;
					}

				/* check alert state type */
				if(display_line == TRUE && history_type == SERVICE_HISTORY) {

					if(state_options == STATE_ALL)
						display_line = TRUE;
					else if((state_options & STATE_SOFT) && strstr(temp_buffer, ";SOFT;"))
						display_line = TRUE;
					else if((state_options & STATE_HARD) && strstr(temp_buffer, ";HARD;"))
						display_line = TRUE;
					else
						display_line = FALSE;
					}
				}


			/* make sure user is authorized to view this host or service information */
			if(system_message == FALSE) {

				if(history_type == HOST_HISTORY || history_type == HOST_FLAPPING_HISTORY || history_type == HOST_DOWNTIME_HISTORY) {
					temp_host = find_host(entry_host_name);
					if(is_authorized_for_host(temp_host, &current_authdata) == FALSE)
						display_line = FALSE;

					}
				else {
					temp_service = find_service(entry_host_name, entry_service_desc);
					if(is_authorized_for_service(temp_service, &current_authdata) == FALSE)
						display_line = FALSE;
					}
				}

			/* display the entry if we should... */
			if(display_line == TRUE) {

				if(strcmp(last_message_date, current_message_date) != 0 && display_timebreaks == TRUE) {
					printf("</DIV><BR CLEAR='all' />\n");
					printf("<DIV CLASS='dateTimeBreak'>\n");
					printf("<table border=0 width=95%%><tr>");
					printf("<td width=40%%><hr width=100%%></td>");
					printf("<td align=center CLASS='dateTimeBreak'>%s</td>", current_message_date);
					printf("<td width=40%%><hr width=100%%></td>");
					printf("</tr></table>\n");
					printf("</DIV>\n");
					printf("<BR CLEAR='all' /><DIV CLASS='logEntries'>\n");
					strncpy(last_message_date, current_message_date, sizeof(last_message_date));
					last_message_date[sizeof(last_message_date) - 1] = '\x0';
					}

				if(display_frills == TRUE)
					printf("<img align='left' src='%s%s' alt='%s' title='%s' />", url_images_path, image, image_alt, image_alt);
				printf("[%s] %s", date_time, html_encode(temp_buffer, FALSE));
				if(enable_splunk_integration == TRUE) {
					printf("&nbsp;&nbsp;&nbsp;");
					display_splunk_generic_url(temp_buffer, 2);
					}
				printf("<br clear='all' />\n");

				found_line = TRUE;
				}
			}

		/* free memory */
		free(entry_host_name);
		entry_host_name = NULL;
		free(entry_service_desc);
		entry_service_desc = NULL;
		}

	printf("</DIV></P>\n");

	if(found_line == FALSE) {
		printf("<HR>\n");
		printf("<P><DIV CLASS='warningMessage'>No history information was found ");
		if(display_type == DISPLAY_HOSTS)
			printf("%s", (show_all_hosts == TRUE) ? "" : "for this host ");
		else
			printf("for this service ");
		printf("in %s log file</DIV></P>", (log_archive == 0) ? "the current" : "this archived");
		}

	printf("<HR>\n");

	my_free(input);
	my_free(input2);

	if(use_lifo == TRUE)
		free_lifo_memory();
	else
		mmap_fclose(thefile);

	return;
	}
Exemple #17
0
/* unschedules a host or service downtime */
int unschedule_downtime(int type, unsigned long downtime_id) {
	scheduled_downtime *temp_downtime = NULL;
	scheduled_downtime *next_downtime = NULL;
	host *hst = NULL;
	service *svc = NULL;
#ifdef USE_EVENT_BROKER
	int attr = 0;
#endif

	log_debug_info(DEBUGL_FUNCTIONS, 0, "unschedule_downtime()\n");

	/* find the downtime entry in the list in memory */
	if((temp_downtime = find_downtime(type, downtime_id)) == NULL)
		return ERROR;

	/* find the host or service associated with this downtime */
	if(temp_downtime->type == HOST_DOWNTIME) {
		if((hst = find_host(temp_downtime->host_name)) == NULL)
			return ERROR;
		}
	else {
		if((svc = find_service(temp_downtime->host_name, temp_downtime->service_description)) == NULL)
			return ERROR;
		}

	/* decrement pending flex downtime if necessary ... */
	if(temp_downtime->fixed == FALSE && temp_downtime->incremented_pending_downtime == TRUE) {
		if(temp_downtime->type == HOST_DOWNTIME)
			hst->pending_flex_downtime--;
		else
			svc->pending_flex_downtime--;
		}

	log_debug_info(DEBUGL_DOWNTIME, 0, "Cancelling %s downtime (id=%lu)\n",
	               temp_downtime->type == HOST_DOWNTIME ? "host" : "service",
	               temp_downtime->downtime_id);

	/* decrement the downtime depth variable and update status data if necessary */
	if(temp_downtime->is_in_effect == TRUE) {

#ifdef USE_EVENT_BROKER
		/* send data to event broker */
		attr = NEBATTR_DOWNTIME_STOP_CANCELLED;
		broker_downtime_data(NEBTYPE_DOWNTIME_STOP, NEBFLAG_NONE, attr, temp_downtime->type, temp_downtime->host_name, temp_downtime->service_description, temp_downtime->entry_time, temp_downtime->author, temp_downtime->comment, temp_downtime->start_time, temp_downtime->end_time, temp_downtime->fixed, temp_downtime->triggered_by, temp_downtime->duration, temp_downtime->downtime_id, NULL);
#endif

		if(temp_downtime->type == HOST_DOWNTIME) {

			if (hst->scheduled_downtime_depth > 0)
				hst->scheduled_downtime_depth--;
			update_host_status(hst, FALSE);

			/* log a notice - this is parsed by the history CGI */
			if(hst->scheduled_downtime_depth == 0) {

				logit(NSLOG_INFO_MESSAGE, FALSE, "HOST DOWNTIME ALERT: %s;CANCELLED; Scheduled downtime for host has been cancelled.\n", hst->name);

				/* send a notification */
				host_notification(hst, NOTIFICATION_DOWNTIMECANCELLED, NULL, NULL, NOTIFICATION_OPTION_NONE);
				}
			}

		else {

			if (svc->scheduled_downtime_depth > 0)
				svc->scheduled_downtime_depth--;
			update_service_status(svc, FALSE);

			/* log a notice - this is parsed by the history CGI */
			if(svc->scheduled_downtime_depth == 0) {

				logit(NSLOG_INFO_MESSAGE, FALSE, "SERVICE DOWNTIME ALERT: %s;%s;CANCELLED; Scheduled downtime for service has been cancelled.\n", svc->host_name, svc->description);

				/* send a notification */
				service_notification(svc, NOTIFICATION_DOWNTIMECANCELLED, NULL, NULL, NOTIFICATION_OPTION_NONE);
				}
			}
		}

	/* remove scheduled entries from event queue */
	if (temp_downtime->start_event) {
		remove_event(nagios_squeue, temp_downtime->start_event);
		my_free(temp_downtime->start_event);
		}
	if (temp_downtime->stop_event) {
		remove_event(nagios_squeue, temp_downtime->stop_event);
		my_free(temp_downtime->stop_event);
		}

	/* delete downtime entry */
	if(temp_downtime->type == HOST_DOWNTIME)
		delete_host_downtime(downtime_id);
	else
		delete_service_downtime(downtime_id);

	/*
	 * unschedule all downtime entries that were triggered by this one
	 * @TODO: Fix this algorithm so it uses something sane instead
	 * of this horrible mess of recursive O(n * t), where t is
	 * "downtime triggered by this downtime"
	 */
	while(1) {

		for(temp_downtime = scheduled_downtime_list; temp_downtime != NULL; temp_downtime = next_downtime) {
			next_downtime = temp_downtime->next;
			if(temp_downtime->triggered_by == downtime_id) {
				unschedule_downtime(ANY_DOWNTIME, temp_downtime->downtime_id);
				break;
				}
			}

		if(temp_downtime == NULL)
			break;
		}

	return OK;
	}
Exemple #18
0
/* put back the result into the core */
void *get_results( gearman_job_st *job, void *context, size_t *result_size, gearman_return_t *ret_ptr ) {
    int wsize;
    char workload[GM_BUFFERSIZE];
    char *decrypted_data;
    char *decrypted_data_c;
#ifdef GM_DEBUG
    char *decrypted_orig;
#endif
    struct timeval now, core_start_time;
    check_result * chk_result;
    int active_check = TRUE;
    char *ptr;
    double now_f, core_starttime_f, starttime_f, finishtime_f, exec_time, latency;

    /* for calculating real latency */
    gettimeofday(&now,NULL);

    /* contect is unused */
    context = context;

    /* set size of result */
    *result_size = 0;

    /* set result pointer to success */
    *ret_ptr = GEARMAN_SUCCESS;

    /* get the data */
    wsize = gearman_job_workload_size(job);
    strncpy(workload, (const char*)gearman_job_workload(job), wsize);
    workload[wsize] = '\x0';
    gm_log( GM_LOG_TRACE, "got result %s\n", gearman_job_handle( job ));
    gm_log( GM_LOG_TRACE, "%d +++>\n%s\n<+++\n", strlen(workload), workload );

    /* decrypt data */
    decrypted_data   = malloc(GM_BUFFERSIZE);
    decrypted_data_c = decrypted_data;
    mod_gm_decrypt(&decrypted_data, workload, mod_gm_opt->transportmode);

    if(decrypted_data == NULL) {
        *ret_ptr = GEARMAN_WORK_FAIL;
        return NULL;
    }
    gm_log( GM_LOG_TRACE, "%d --->\n%s\n<---\n", strlen(decrypted_data), decrypted_data );
#ifdef GM_DEBUG
    decrypted_orig   = strdup(decrypted_data);
#endif

    /*
     * save this result to a file, so when nagios crashes,
     * we have at least the crashed package
     */
    if(mod_gm_opt->debug_result == GM_ENABLED) {
        FILE * fd;
        fd = fopen( "/tmp/last_result_received.txt", "w+" );
        if(fd == NULL)
            perror("fopen");
        fputs( decrypted_data, fd );
        fclose( fd );
    }

    /* nagios will free it after processing */
    if ( ( chk_result = ( check_result * )malloc( sizeof *chk_result ) ) == 0 ) {
        *ret_ptr = GEARMAN_WORK_FAIL;
        return NULL;
    }
    init_check_result(chk_result);
    chk_result->scheduled_check     = TRUE;
    chk_result->reschedule_check    = TRUE;
    chk_result->output_file         = 0;
    chk_result->output_file_fd      = -1;

    core_start_time.tv_sec          = 0;
    core_start_time.tv_usec         = 0;

    while ( (ptr = strsep(&decrypted_data, "\n" )) != NULL ) {
        char *key   = strsep( &ptr, "=" );
        char *value = strsep( &ptr, "\x0" );

        if ( key == NULL )
            continue;

        if ( !strcmp( key, "output" ) ) {
            if ( value == NULL ) {
                chk_result->output = strdup("(null)");
            }
            else {
                chk_result->output = strdup( value );
            }
        }

        if ( value == NULL || !strcmp( value, "") )
            break;

        if ( !strcmp( key, "host_name" ) ) {
            chk_result->host_name = strdup( value );
        } else if ( !strcmp( key, "service_description" ) ) {
            chk_result->service_description = strdup( value );
        } else if ( !strcmp( key, "check_options" ) ) {
            chk_result->check_options = atoi( value );
        } else if ( !strcmp( key, "scheduled_check" ) ) {
            chk_result->scheduled_check = atoi( value );
        } else if ( !strcmp( key, "type" ) && !strcmp( value, "passive" ) ) {
            active_check=FALSE;
        } else if ( !strcmp( key, "reschedule_check" ) ) {
            chk_result->reschedule_check = atoi( value );
        } else if ( !strcmp( key, "exited_ok" ) ) {
            chk_result->exited_ok = atoi( value );
        } else if ( !strcmp( key, "early_timeout" ) ) {
            chk_result->early_timeout = atoi( value );
        } else if ( !strcmp( key, "return_code" ) ) {
            chk_result->return_code = atoi( value );
        } else if ( !strcmp( key, "core_start_time" ) ) {
            string2timeval(value, &core_start_time);
        } else if ( !strcmp( key, "start_time" ) ) {
            string2timeval(value, &chk_result->start_time);
        } else if ( !strcmp( key, "finish_time" ) ) {
            string2timeval(value, &chk_result->finish_time);
        } else if ( !strcmp( key, "latency" ) ) {
            chk_result->latency = atof( value );
        }
    }

    if ( chk_result->host_name == NULL || chk_result->output == NULL ) {
        *ret_ptr= GEARMAN_WORK_FAIL;
        gm_log( GM_LOG_ERROR, "discarded invalid result\n" );
        return NULL;
    }

    if ( chk_result->service_description != NULL ) {
        chk_result->object_check_type    = SERVICE_CHECK;
        chk_result->check_type           = SERVICE_CHECK_ACTIVE;
        if(active_check == FALSE )
            chk_result->check_type       = SERVICE_CHECK_PASSIVE;
    } else {
        chk_result->object_check_type    = HOST_CHECK;
        chk_result->check_type           = HOST_CHECK_ACTIVE;
        if(active_check == FALSE )
            chk_result->check_type       = HOST_CHECK_PASSIVE;
    }

    /* fill some maybe missing options */
    if(chk_result->start_time.tv_sec  == 0) {
        chk_result->start_time.tv_sec = (unsigned long)time(NULL);
    }
    if(chk_result->finish_time.tv_sec  == 0) {
        chk_result->finish_time.tv_sec = (unsigned long)time(NULL);
    }
    if(core_start_time.tv_sec  == 0) {
        core_start_time.tv_sec = (unsigned long)time(NULL);
    }

    /* calculate real latency */
    now_f            = (double)now.tv_sec + (double)now.tv_usec / 1000000;
    core_starttime_f = (double)core_start_time.tv_sec + (double)core_start_time.tv_usec / 1000000;
    starttime_f      = (double)chk_result->start_time.tv_sec + (double)chk_result->start_time.tv_usec / 1000000;
    finishtime_f     = (double)chk_result->finish_time.tv_sec + (double)chk_result->finish_time.tv_usec / 1000000;
    exec_time        = finishtime_f - starttime_f;
    latency          = now_f - exec_time - core_starttime_f;

    if(latency < 0)
        latency = 0;
    if(chk_result->latency < 0)
        chk_result->latency = 0;

    chk_result->latency += latency;

#ifdef GM_DEBUG
    if(chk_result->latency > 1000)
        write_debug_file(&decrypted_orig);
#endif

    /* this check is not a freshnes check */
    chk_result->check_options    = chk_result->check_options & ! CHECK_OPTION_FRESHNESS_CHECK;

    if ( chk_result->service_description != NULL ) {
#ifdef GM_DEBUG
        /* does this services exist */
        service * svc = find_service( chk_result->host_name, chk_result->service_description );
        if(svc == NULL) {
            write_debug_file(&decrypted_orig);
            gm_log( GM_LOG_ERROR, "service '%s' on host '%s' could not be found\n", chk_result->service_description, chk_result->host_name );
            return NULL;
        }
#endif
        gm_log( GM_LOG_DEBUG, "service job completed: %s %s: %d\n", chk_result->host_name, chk_result->service_description, chk_result->return_code );
    } else {
#ifdef GM_DEBUG
        /* does this host exist */
        host * hst = find_host( chk_result->host_name );
        if(hst == NULL) {
            write_debug_file(&decrypted_orig);
            gm_log( GM_LOG_ERROR, "host '%s' could not be found\n", chk_result->host_name );
            return NULL;
        }
#endif
        gm_log( GM_LOG_DEBUG, "host job completed: %s: %d\n", chk_result->host_name, chk_result->return_code );
    }

    /* add result to result list */
    mod_gm_add_result_to_list( chk_result );

    /* reset pointer */
    chk_result = NULL;

    free(decrypted_data_c);
#ifdef GM_DEBUG
    free(decrypted_orig);
#endif

    return NULL;
}
Exemple #19
0
/* handles scheduled host or service downtime */
int handle_scheduled_downtime(scheduled_downtime *temp_downtime) {
	scheduled_downtime *this_downtime = NULL;
	host *hst = NULL;
	service *svc = NULL;
	time_t event_time = 0L;
	unsigned long *new_downtime_id = NULL;
#ifdef USE_EVENT_BROKER
	int attr = 0;
#endif


	log_debug_info(DEBUGL_FUNCTIONS, 0, "handle_scheduled_downtime()\n");

	if(temp_downtime == NULL)
		return ERROR;

	/* find the host or service associated with this downtime */
	if(temp_downtime->type == HOST_DOWNTIME) {
		if((hst = find_host(temp_downtime->host_name)) == NULL) {
			log_debug_info(DEBUGL_DOWNTIME, 1, "Unable to find host (%s) for downtime\n", temp_downtime->host_name);
			return ERROR;
			}
		}
	else {
		if((svc = find_service(temp_downtime->host_name, temp_downtime->service_description)) == NULL) {
			log_debug_info(DEBUGL_DOWNTIME, 1, "Unable to find service (%s) host (%s) for downtime\n", temp_downtime->service_description, temp_downtime->host_name);
			return ERROR;
			}
		}

	/* have we come to the end of the scheduled downtime? */
	if(temp_downtime->is_in_effect == TRUE) {

#ifdef USE_EVENT_BROKER
		/* send data to event broker */
		attr = NEBATTR_DOWNTIME_STOP_NORMAL;
		broker_downtime_data(NEBTYPE_DOWNTIME_STOP, NEBFLAG_NONE, attr, temp_downtime->type, temp_downtime->host_name, temp_downtime->service_description, temp_downtime->entry_time, temp_downtime->author, temp_downtime->comment, temp_downtime->start_time, temp_downtime->end_time, temp_downtime->fixed, temp_downtime->triggered_by, temp_downtime->duration, temp_downtime->downtime_id, NULL);
#endif

		/* decrement the downtime depth variable */
		if(temp_downtime->type == HOST_DOWNTIME && hst->scheduled_downtime_depth > 0)
			hst->scheduled_downtime_depth--;
		else if (svc->scheduled_downtime_depth > 0)
			svc->scheduled_downtime_depth--;

		if(temp_downtime->type == HOST_DOWNTIME && hst->scheduled_downtime_depth == 0) {

			log_debug_info(DEBUGL_DOWNTIME, 0, "Host '%s' has exited from a period of scheduled downtime (id=%lu).\n", hst->name, temp_downtime->downtime_id);

			/* log a notice - this one is parsed by the history CGI */
			logit(NSLOG_INFO_MESSAGE, FALSE, "HOST DOWNTIME ALERT: %s;STOPPED; Host has exited from a period of scheduled downtime", hst->name);

			/* send a notification */
			host_notification(hst, NOTIFICATION_DOWNTIMEEND, temp_downtime->author, temp_downtime->comment, NOTIFICATION_OPTION_NONE);
			}

		else if(temp_downtime->type == SERVICE_DOWNTIME && svc->scheduled_downtime_depth == 0) {

			log_debug_info(DEBUGL_DOWNTIME, 0, "Service '%s' on host '%s' has exited from a period of scheduled downtime (id=%lu).\n", svc->description, svc->host_name, temp_downtime->downtime_id);

			/* log a notice - this one is parsed by the history CGI */
			logit(NSLOG_INFO_MESSAGE, FALSE, "SERVICE DOWNTIME ALERT: %s;%s;STOPPED; Service has exited from a period of scheduled downtime", svc->host_name, svc->description);

			/* send a notification */
			service_notification(svc, NOTIFICATION_DOWNTIMEEND, temp_downtime->author, temp_downtime->comment, NOTIFICATION_OPTION_NONE);
			}


		/* update the status data */
		if(temp_downtime->type == HOST_DOWNTIME)
			update_host_status(hst, FALSE);
		else
			update_service_status(svc, FALSE);

		/* decrement pending flex downtime if necessary */
		if(temp_downtime->fixed == FALSE && temp_downtime->incremented_pending_downtime == TRUE) {
			if(temp_downtime->type == HOST_DOWNTIME) {
				if(hst->pending_flex_downtime > 0)
					hst->pending_flex_downtime--;
				}
			else {
				if(svc->pending_flex_downtime > 0)
					svc->pending_flex_downtime--;
				}
			}

		/* handle (stop) downtime that is triggered by this one */
		while(1) {

			/* list contents might change by recursive calls, so we use this inefficient method to prevent segfaults */
			for(this_downtime = scheduled_downtime_list; this_downtime != NULL; this_downtime = this_downtime->next) {
				if(this_downtime->triggered_by == temp_downtime->downtime_id) {
					handle_scheduled_downtime(this_downtime);
					break;
					}
				}

			if(this_downtime == NULL)
				break;
			}

		/* delete downtime entry */
		if(temp_downtime->type == HOST_DOWNTIME)
			delete_host_downtime(temp_downtime->downtime_id);
		else
			delete_service_downtime(temp_downtime->downtime_id);
		}

	/* else we are just starting the scheduled downtime */
	else {

#ifdef USE_EVENT_BROKER
		/* send data to event broker */
		broker_downtime_data(NEBTYPE_DOWNTIME_START, NEBFLAG_NONE, NEBATTR_NONE, temp_downtime->type, temp_downtime->host_name, temp_downtime->service_description, temp_downtime->entry_time, temp_downtime->author, temp_downtime->comment, temp_downtime->start_time, temp_downtime->end_time, temp_downtime->fixed, temp_downtime->triggered_by, temp_downtime->duration, temp_downtime->downtime_id, NULL);
#endif

		if(temp_downtime->type == HOST_DOWNTIME && hst->scheduled_downtime_depth == 0) {

			log_debug_info(DEBUGL_DOWNTIME, 0, "Host '%s' has entered a period of scheduled downtime (id=%lu).\n", hst->name, temp_downtime->downtime_id);

			/* log a notice - this one is parsed by the history CGI */
			logit(NSLOG_INFO_MESSAGE, FALSE, "HOST DOWNTIME ALERT: %s;STARTED; Host has entered a period of scheduled downtime", hst->name);

			/* send a notification */
			if( FALSE == temp_downtime->start_notification_sent) {
				host_notification(hst, NOTIFICATION_DOWNTIMESTART, temp_downtime->author, temp_downtime->comment, NOTIFICATION_OPTION_NONE);
				temp_downtime->start_notification_sent = TRUE;
				}
			}

		else if(temp_downtime->type == SERVICE_DOWNTIME && svc->scheduled_downtime_depth == 0) {

			log_debug_info(DEBUGL_DOWNTIME, 0, "Service '%s' on host '%s' has entered a period of scheduled downtime (id=%lu).\n", svc->description, svc->host_name, temp_downtime->downtime_id);

			/* log a notice - this one is parsed by the history CGI */
			logit(NSLOG_INFO_MESSAGE, FALSE, "SERVICE DOWNTIME ALERT: %s;%s;STARTED; Service has entered a period of scheduled downtime", svc->host_name, svc->description);

			/* send a notification */
			if( FALSE == temp_downtime->start_notification_sent) {
				service_notification(svc, NOTIFICATION_DOWNTIMESTART, temp_downtime->author, temp_downtime->comment, NOTIFICATION_OPTION_NONE);
				temp_downtime->start_notification_sent = TRUE;
				}
			}

		/* increment the downtime depth variable */
		if(temp_downtime->type == HOST_DOWNTIME)
			hst->scheduled_downtime_depth++;
		else
			svc->scheduled_downtime_depth++;

		/* set the in effect flag */
		temp_downtime->is_in_effect = TRUE;

		/* update the status data */
		if(temp_downtime->type == HOST_DOWNTIME)
			update_host_status(hst, FALSE);
		else
			update_service_status(svc, FALSE);

		/* schedule an event to end the downtime */
		if(temp_downtime->fixed == FALSE) {
			event_time = (time_t)((unsigned long)temp_downtime->flex_downtime_start
					+ temp_downtime->duration);
			}
		else {
			event_time = temp_downtime->end_time;
			}
		if((new_downtime_id = (unsigned long *)malloc(sizeof(unsigned long)))) {
			*new_downtime_id = temp_downtime->downtime_id;
			schedule_new_event(EVENT_SCHEDULED_DOWNTIME, TRUE, event_time, FALSE, 0, NULL, FALSE, (void *)new_downtime_id, NULL, 0);
			}

		/* handle (start) downtime that is triggered by this one */
		for(this_downtime = scheduled_downtime_list; this_downtime != NULL; this_downtime = this_downtime->next) {
			if(this_downtime->triggered_by == temp_downtime->downtime_id)
				handle_scheduled_downtime(this_downtime);
			}
		}

	return OK;
	}
static int handle_subscription_request(struct device_private *priv,
                                       struct Upnp_Subscription_Request
                                              *sr_event)
{
	struct service *srv;
	int i;
	int eventVarCount = 0, eventVarIdx = 0;
	const char **eventvar_names;
	const char **eventvar_values;
	int rc;
	int result = -1;

	ENTER();

	assert(priv != NULL);


	printf("Subscription request\n");
	printf("  %s\n", sr_event->UDN);
	printf("  %s\n", sr_event->ServiceId);

	srv = find_service(priv->upnp_device, sr_event->ServiceId);
	if (srv == NULL) {
		fprintf(stderr, "%s: Unknown service '%s'\n", __FUNCTION__,
			sr_event->ServiceId);
		goto out;
	}

	ithread_mutex_lock(&(priv->device_mutex));

	/* generate list of eventable variables */
	for(i=0; i<srv->variable_count; i++) {
		struct var_meta *metaEntry;
		metaEntry = &(srv->variable_meta[i]);
		if (metaEntry->sendevents == SENDEVENT_YES) {
			eventVarCount++;
		}
	}
	eventvar_names = malloc((eventVarCount+1) * sizeof(const char *));
	eventvar_values = malloc((eventVarCount+1) * sizeof(const char *));
	printf("%d evented variables\n", eventVarCount);

	for(i=0; i<srv->variable_count; i++) {
		struct var_meta *metaEntry;
		metaEntry = &(srv->variable_meta[i]);
		if (metaEntry->sendevents == SENDEVENT_YES) {
			eventvar_names[eventVarIdx] = srv->variable_names[i];
			// Do these need to be xml-escpaed ?
			eventvar_values[eventVarIdx] = xmlescape(srv->variable_values[i], 0);
			printf("Subscribe to '%s' == '%s'\n",
			       eventvar_names[eventVarIdx],
			       eventvar_values[eventVarIdx]);
			eventVarIdx++;
		}
	}
	eventvar_names[eventVarIdx] = NULL;
	eventvar_values[eventVarIdx] = NULL;

	rc = UpnpAcceptSubscription(priv->device_handle,
			       sr_event->UDN, sr_event->ServiceId,
			       eventvar_names, eventvar_values, eventVarCount,
			       sr_event->Sid);
	if (rc == UPNP_E_SUCCESS) {
		result = 0;
	}

	ithread_mutex_unlock(&(priv->device_mutex));

	for (i = 0; i < eventVarCount; ++i) {
		// Allocated by xmlescape()
		free((char*)eventvar_values[i]);
	}
	free(eventvar_names);
	free(eventvar_values);

out:
	LEAVE();
	return result;
}
Exemple #21
0
/* removes invalid and old downtime entries from the downtime file */
int xdddefault_validate_downtime_data(void) {
	scheduled_downtime *temp_downtime;
	scheduled_downtime *next_downtime;
	int save = TRUE;

	/* remove stale downtimes */
	for(temp_downtime = scheduled_downtime_list; temp_downtime != NULL; temp_downtime = next_downtime) {

		next_downtime = temp_downtime->next;
		save = TRUE;

		/* delete downtimes with invalid host names */
		if(find_host(temp_downtime->host_name) == NULL) {
			log_debug_info(DEBUGL_DOWNTIME, 1,
					"Deleting downtime with invalid host name: %s\n",
					temp_downtime->host_name);
			save = FALSE;
			}

		/* delete downtimes with invalid service descriptions */
		if(temp_downtime->type == SERVICE_DOWNTIME && find_service(temp_downtime->host_name, temp_downtime->service_description) == NULL) {
			log_debug_info(DEBUGL_DOWNTIME, 1,
					"Deleting downtime with invalid service description: %s\n",
					temp_downtime->service_description);
			save = FALSE;
			}

		/* delete fixed downtimes that have expired */
		if((TRUE == temp_downtime->fixed) &&
				(temp_downtime->end_time < time(NULL))) {
			log_debug_info(DEBUGL_DOWNTIME, 1,
					"Deleting fixed downtime that expired at: %lu\n",
					temp_downtime->end_time);
			save = FALSE;
			}

		/* delete flexible downtimes that never started and have expired */
		if((FALSE == temp_downtime->fixed) &&
				(0 == temp_downtime->flex_downtime_start) &&
				(temp_downtime->end_time < time(NULL))) {
			log_debug_info(DEBUGL_DOWNTIME, 1,
					"Deleting flexible downtime that expired at: %lu\n",
					temp_downtime->end_time);
			save = FALSE;
			}

		/* delete flexible downtimes that started but whose duration
			has completed */
		if((FALSE == temp_downtime->fixed) &&
				(0 != temp_downtime->flex_downtime_start) &&
				((temp_downtime->flex_downtime_start + temp_downtime->duration)
				< time(NULL))) {
			log_debug_info(DEBUGL_DOWNTIME, 1,
					"Deleting flexible downtime whose duration ended at: %lu\n",
					temp_downtime->flex_downtime_start + temp_downtime->duration);
			save = FALSE;
			}

		/* delete the downtime */
		if(save == FALSE) {
			delete_downtime(temp_downtime->type, temp_downtime->downtime_id);
			}
		}

	/* remove triggered downtimes without valid parents */
	for(temp_downtime = scheduled_downtime_list; temp_downtime != NULL; temp_downtime = next_downtime) {

		next_downtime = temp_downtime->next;
		save = TRUE;

		if(temp_downtime->triggered_by == 0)
			continue;

		if(find_host_downtime(temp_downtime->triggered_by) == NULL && find_service_downtime(temp_downtime->triggered_by) == NULL)
			save = FALSE;

		/* delete the downtime */
		if(save == FALSE) {
			delete_downtime(temp_downtime->type, temp_downtime->downtime_id);
			}
		}

	return OK;
	}
Exemple #22
0
void display_notifications(void) {
    mmapfile *thefile=NULL;
    char *input=NULL;
    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("<P><DIV CLASS='warningMessage'>Not enough memory to reverse log file - displaying notifications in natural order...</DIV></P>");
            }
            else if(result==LIFO_ERROR_FILE) {
                printf("<P><DIV CLASS='errorMessage'>Error: Cannot open log file '%s' for reading!</DIV></P>",log_file_to_use);
                return;
            }
            use_lifo=FALSE;
        }
    }

    if(use_lifo==FALSE) {

        if((thefile=mmap_fopen(log_file_to_use))==NULL) {
            printf("<P><DIV CLASS='errorMessage'>Error: Cannot open log file '%s' for reading!</DIV></P>",log_file_to_use);
            return;
        }
    }

    printf("<p>\n");
    printf("<div align='center'>\n");

    printf("<table border=0 CLASS='notifications'>\n");
    printf("<tr>\n");
    printf("<th CLASS='notifications'>Host</th>\n");
    printf("<th CLASS='notifications'>Service</th>\n");
    printf("<th CLASS='notifications'>Type</th>\n");
    printf("<th CLASS='notifications'>Time</th>\n");
    printf("<th CLASS='notifications'>Contact</th>\n");
    printf("<th CLASS='notifications'>Notification Command</th>\n");
    printf("<th CLASS='notifications'>Information</th>\n");
    printf("</tr>\n");

    total_notifications=0;

    while(1) {

        free(input);

        if(use_lifo==TRUE) {
            if((input=pop_lifo())==NULL)
                break;
        }
        else {
            if((input=mmap_fgets(thefile))==NULL)
                break;
        }

        strip(input);

        /* see if this line contains the notification event string */
        if(strstr(input,HOST_NOTIFICATION_STRING)||strstr(input,SERVICE_NOTIFICATION_STRING)) {

            if(strstr(input,HOST_NOTIFICATION_STRING))
                notification_type=HOST_NOTIFICATION;
            else
                notification_type=SERVICE_NOTIFICATION;

            /* get the date/time */
            temp_buffer=(char *)strtok(input,"]");
            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)-1]='\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,"CUSTOM (")) {
                    notification_detail_type=NOTIFICATION_SERVICE_CUSTOM;
                    strcpy(alert_level_class,"CUSTOM");
                }
                else if(strstr(alert_level,"ACKNOWLEDGEMENT (")) {
                    notification_detail_type=NOTIFICATION_SERVICE_ACK;
                    strcpy(alert_level_class,"ACKNOWLEDGEMENT");
                }
                else if(strstr(alert_level,"FLAPPINGSTART (")) {
                    strcpy(alert_level,"FLAPPING START");
                    notification_detail_type=NOTIFICATION_SERVICE_FLAP;
                    strcpy(alert_level_class,"UNKNOWN");
                }
                else if(strstr(alert_level,"FLAPPINGSTOP (")) {
                    strcpy(alert_level,"FLAPPING STOP");
                    notification_detail_type=NOTIFICATION_SERVICE_FLAP;
                    strcpy(alert_level_class,"UNKNOWN");
                }
                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,"CUSTOM (")) {
                    strcpy(alert_level_class,"HOSTCUSTOM");
                    notification_detail_type=NOTIFICATION_HOST_CUSTOM;
                }
                else if(strstr(alert_level,"ACKNOWLEDGEMENT (")) {
                    strcpy(alert_level_class,"HOSTACKNOWLEDGEMENT");
                    notification_detail_type=NOTIFICATION_HOST_ACK;
                }
                else if(strstr(alert_level,"FLAPPINGSTART (")) {
                    strcpy(alert_level,"FLAPPING START");
                    strcpy(alert_level_class,"UNKNOWN");
                    notification_detail_type=NOTIFICATION_HOST_FLAP;
                }
                else if(strstr(alert_level,"FLAPPINGSTOP (")) {
                    strcpy(alert_level,"FLAPPING STOP");
                    strcpy(alert_level_class,"UNKNOWN");
                    notification_detail_type=NOTIFICATION_HOST_FLAP;
                }
            }

            /* 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);
                if(is_authorized_for_host(temp_host,&current_authdata)==FALSE)
                    show_entry=FALSE;
            }
            else {
                temp_service=find_service(host_name,service_name);
                if(is_authorized_for_service(temp_service,&current_authdata)==FALSE)
                    show_entry=FALSE;
            }

            if(show_entry==TRUE) {

                total_notifications++;

                if(odd) {
                    odd=0;
                    printf("<tr CLASS='notificationsOdd'>\n");
                }
                else {
                    odd=1;
                    printf("<tr CLASS='notificationsEven'>\n");
                }
                printf("<td CLASS='notifications%s'><a href='%s?type=%d&host=%s'>%s</a></td>\n",(odd)?"Even":"Odd",EXTINFO_CGI,DISPLAY_HOST_INFO,url_encode(host_name),host_name);
                if(notification_type==SERVICE_NOTIFICATION) {
                    printf("<td CLASS='notifications%s'><a href='%s?type=%d&host=%s",(odd)?"Even":"Odd",EXTINFO_CGI,DISPLAY_SERVICE_INFO,url_encode(host_name));
                    printf("&service=%s'>%s</a></td>\n",url_encode(service_name),service_name);
                }
                else
                    printf("<td CLASS='notifications%s'>N/A</td>\n",(odd)?"Even":"Odd");
                printf("<td CLASS='notifications%s'>%s</td>\n",alert_level_class,alert_level);
                printf("<td CLASS='notifications%s'>%s</td>\n",(odd)?"Even":"Odd",date_time);
                printf("<td CLASS='notifications%s'><a href='%s?type=contacts#%s'>%s</a></td>\n",(odd)?"Even":"Odd",CONFIG_CGI,url_encode(contact_name),contact_name);
                printf("<td CLASS='notifications%s'><a href='%s?type=commands#%s'>%s</a></td>\n",(odd)?"Even":"Odd",CONFIG_CGI,url_encode(method_name),method_name);
                printf("<td CLASS='notifications%s'>%s</td>\n",(odd)?"Even":"Odd",html_encode(temp_buffer,FALSE));
                printf("</tr>\n");
            }
        }
    }


    printf("</table>\n");

    printf("</div>\n");
    printf("</p>\n");

    if(total_notifications==0) {
        printf("<P><DIV CLASS='errorMessage'>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</DIV></P>",(log_archive==0)?"the current":"this archived");
    }

    free(input);

    if(use_lifo==TRUE)
        free_lifo_memory();
    else
        mmap_fclose(thefile);

    return;
}
Exemple #23
0
const char *obs_service_get_display_name(const char *id)
{
	const struct obs_service_info *info = find_service(id);
	return (info != NULL) ? info->get_name() : NULL;
}
Exemple #24
0
connection_struct *make_connection(struct smb_request *req,
				   NTTIME now,
				   const char *service_in,
				   const char *pdev, uint64_t vuid,
				   NTSTATUS *status)
{
	struct smbd_server_connection *sconn = req->sconn;
	uid_t euid;
	struct user_struct *vuser = NULL;
	char *service = NULL;
	fstring dev;
	int snum = -1;

	fstrcpy(dev, pdev);

	/* This must ONLY BE CALLED AS ROOT. As it exits this function as
	 * root. */
	if (!non_root_mode() && (euid = geteuid()) != 0) {
		DEBUG(0,("make_connection: PANIC ERROR. Called as nonroot "
			 "(%u)\n", (unsigned int)euid ));
		smb_panic("make_connection: PANIC ERROR. Called as nonroot\n");
	}

	if (conn_num_open(sconn) > 2047) {
		*status = NT_STATUS_INSUFF_SERVER_RESOURCES;
		return NULL;
	}

	vuser = get_valid_user_struct(sconn, vuid);
	if (!vuser) {
		DEBUG(1,("make_connection: refusing to connect with "
			 "no session setup\n"));
		*status = NT_STATUS_ACCESS_DENIED;
		return NULL;
	}

	/* Logic to try and connect to the correct [homes] share, preferably
	   without too many getpwnam() lookups.  This is particulary nasty for
	   winbind usernames, where the share name isn't the same as unix
	   username.

	   The snum of the homes share is stored on the vuser at session setup
	   time.
	*/

	if (strequal(service_in,HOMES_NAME)) {
		if (vuser->homes_snum == -1) {
			DEBUG(2, ("[homes] share not available for "
				  "this user because it was not found "
				  "or created at session setup "
				  "time\n"));
			*status = NT_STATUS_BAD_NETWORK_NAME;
			return NULL;
		}
		DEBUG(5, ("making a connection to [homes] service "
			  "created at session setup time\n"));
		return make_connection_smb1(req, now,
					    vuser->homes_snum,
					    vuser,
					    dev, status);
	} else if ((vuser->homes_snum != -1)
		   && strequal(service_in,
			       lp_servicename(talloc_tos(), vuser->homes_snum))) {
		DEBUG(5, ("making a connection to 'homes' service [%s] "
			  "created at session setup time\n", service_in));
		return make_connection_smb1(req, now,
					    vuser->homes_snum,
					    vuser,
					    dev, status);
	}

	service = talloc_strdup(talloc_tos(), service_in);
	if (!service) {
		*status = NT_STATUS_NO_MEMORY;
		return NULL;
	}

	if (!strlower_m(service)) {
		DEBUG(2, ("strlower_m %s failed\n", service));
		*status = NT_STATUS_INVALID_PARAMETER;
		return NULL;
	}

	snum = find_service(talloc_tos(), service, &service);
	if (!service) {
		*status = NT_STATUS_NO_MEMORY;
		return NULL;
	}

	if (snum < 0) {
		if (strequal(service,"IPC$") ||
		    (lp_enable_asu_support() && strequal(service,"ADMIN$"))) {
			DEBUG(3,("refusing IPC connection to %s\n", service));
			*status = NT_STATUS_ACCESS_DENIED;
			return NULL;
		}

		DEBUG(3,("%s (%s) couldn't find service %s\n",
			get_remote_machine_name(),
			tsocket_address_string(
				sconn->remote_address, talloc_tos()),
			service));
		*status = NT_STATUS_BAD_NETWORK_NAME;
		return NULL;
	}

	/* Handle non-Dfs clients attempting connections to msdfs proxy */
	if (lp_host_msdfs() && (*lp_msdfs_proxy(talloc_tos(), snum) != '\0'))  {
		DEBUG(3, ("refusing connection to dfs proxy share '%s' "
			  "(pointing to %s)\n", 
			service, lp_msdfs_proxy(talloc_tos(), snum)));
		*status = NT_STATUS_BAD_NETWORK_NAME;
		return NULL;
	}

	DEBUG(5, ("making a connection to 'normal' service %s\n", service));

	return make_connection_smb1(req, now, snum, vuser,
				    dev, status);
}
Exemple #25
0
connection_struct *make_connection(const char *service_in, DATA_BLOB password, 
				   const char *pdev, uint16 vuid,
				   NTSTATUS *status)
{
	uid_t euid;
	user_struct *vuser = NULL;
	fstring service;
	fstring dev;
	int snum = -1;
	char addr[INET6_ADDRSTRLEN];

	fstrcpy(dev, pdev);

	/* This must ONLY BE CALLED AS ROOT. As it exits this function as
	 * root. */
	if (!non_root_mode() && (euid = geteuid()) != 0) {
		DEBUG(0,("make_connection: PANIC ERROR. Called as nonroot "
			 "(%u)\n", (unsigned int)euid ));
		smb_panic("make_connection: PANIC ERROR. Called as nonroot\n");
	}

	if (conn_num_open() > 2047) {
		*status = NT_STATUS_INSUFF_SERVER_RESOURCES;
		return NULL;
	}

	if(lp_security() != SEC_SHARE) {
		vuser = get_valid_user_struct(vuid);
		if (!vuser) {
			DEBUG(1,("make_connection: refusing to connect with "
				 "no session setup\n"));
			*status = NT_STATUS_ACCESS_DENIED;
			return NULL;
		}
	}

	/* Logic to try and connect to the correct [homes] share, preferably
	   without too many getpwnam() lookups.  This is particulary nasty for
	   winbind usernames, where the share name isn't the same as unix
	   username.

	   The snum of the homes share is stored on the vuser at session setup
	   time.
	*/

	if (strequal(service_in,HOMES_NAME)) {
		if(lp_security() != SEC_SHARE) {
			DATA_BLOB no_pw = data_blob_null;
			if (vuser->homes_snum == -1) {
				DEBUG(2, ("[homes] share not available for "
					  "this user because it was not found "
					  "or created at session setup "
					  "time\n"));
				*status = NT_STATUS_BAD_NETWORK_NAME;
				return NULL;
			}
			DEBUG(5, ("making a connection to [homes] service "
				  "created at session setup time\n"));
			return make_connection_snum(vuser->homes_snum,
						    vuser, no_pw, 
						    dev, status);
		} else {
			/* Security = share. Try with
			 * current_user_info.smb_name as the username.  */
			if (*current_user_info.smb_name) {
				fstring unix_username;
				fstrcpy(unix_username,
					current_user_info.smb_name);
				map_username(unix_username);
				snum = find_service(unix_username);
			} 
			if (snum != -1) {
				DEBUG(5, ("making a connection to 'homes' "
					  "service %s based on "
					  "security=share\n", service_in));
				return make_connection_snum(snum, NULL,
							    password,
							    dev, status);
			}
		}
	} else if ((lp_security() != SEC_SHARE) && (vuser->homes_snum != -1)
		   && strequal(service_in,
			       lp_servicename(vuser->homes_snum))) {
		DATA_BLOB no_pw = data_blob_null;
		DEBUG(5, ("making a connection to 'homes' service [%s] "
			  "created at session setup time\n", service_in));
		return make_connection_snum(vuser->homes_snum,
					    vuser, no_pw, 
					    dev, status);
	}
	
	fstrcpy(service, service_in);

	strlower_m(service);

	snum = find_service(service);

	if (snum < 0) {
		if (strequal(service,"IPC$") ||
		    (lp_enable_asu_support() && strequal(service,"ADMIN$"))) {
			DEBUG(3,("refusing IPC connection to %s\n", service));
			*status = NT_STATUS_ACCESS_DENIED;
			return NULL;
		}

		DEBUG(0,("%s (%s) couldn't find service %s\n",
			get_remote_machine_name(),
			client_addr(get_client_fd(),addr,sizeof(addr)),
			service));
		*status = NT_STATUS_BAD_NETWORK_NAME;
		return NULL;
	}

	/* Handle non-Dfs clients attempting connections to msdfs proxy */
	if (lp_host_msdfs() && (*lp_msdfs_proxy(snum) != '\0'))  {
		DEBUG(3, ("refusing connection to dfs proxy share '%s' "
			  "(pointing to %s)\n", 
			service, lp_msdfs_proxy(snum)));
		*status = NT_STATUS_BAD_NETWORK_NAME;
		return NULL;
	}

	DEBUG(5, ("making a connection to 'normal' service %s\n", service));

	return make_connection_snum(snum, vuser,
				    password,
				    dev, status);
}
Exemple #26
0
bool_t
rpcbproc_callit_com(rpcb_rmtcallargs *a, void *result, 
		    ar_svc_req_t *rqstp, arpcvers_t versnum)
{
	rpcblist_ptr rbl;
	ar_netid_t *nconf;
	ar_svc_xprt_t *transp;
	char *uaddr, *m_uaddr = NULL, *local_uaddr = NULL;
	arpcproc_t reply_type;
	arpc_createerr_t cerr;
	struct sockaddr_storage ss;
	struct sockaddr *localsa;
	const char *netidstr;
	struct timespec tlimit;
	arpc_addr_t caller;
	arpc_addr_t tbuf;
	arpc_addr_t *na;
	char *errstr;
	struct finfo *info;
	int err;

	caller.maxlen = sizeof(ss);
	caller.len = sizeof(ss);
	caller.buf = (char *)&ss;

	reply_type = rqstp->rq_proc;
	transp = rqstp->rq_xprt;

	if (!ar_svc_control(rqstp->rq_xprt,  AR_SVCGET_NETID, &netidstr)) {
		ar_svcflgerr_systemerr(rqstp);
		return FALSE;
	}

	if (!check_callit(rqstp, a, versnum)) {
		ar_svcflgerr_weakauth(rqstp);
		return FALSE;
	}

	if (!ar_svc_control(rqstp->rq_xprt, AR_SVCGET_REMOTE_ADDR, &caller)) {
		ar_svcflgerr_systemerr(rqstp);
		return FALSE;
	}
		
#ifdef RPCBIND_DEBUG
	if (debugging) {
		uaddr = rqst2uaddr(rqstp);
		fprintf(stderr, "%s %s req for (%lu, %lu, %lu, %s) from %s : ",
			versnum == PMAPVERS ? "pmap_rmtcall" :
			versnum == RPCBVERS ? "rpcb_rmtcall" :
			versnum == RPCBVERS4 ? "rpcb_indirect" : "unknown",
			reply_type == RPCBPROC_INDIRECT ? "indirect" : 
			"callit",
			(unsigned long)a->rmt_prog, (unsigned long)a->rmt_vers,
			(unsigned long)a->rmt_proc, netidstr,
			uaddr ? uaddr : "unknown");
		if (uaddr) {
			free(uaddr);
		}
		uaddr = NULL;
	}
#endif
	rbl = find_service(a->prog, a->vers, netidstr);

	rpcbs_rmtcall(versnum - 2, reply_type, a->prog, a->vers,
		      a->proc, netidstr, rbl);

	if (rbl == (rpcblist_ptr)NULL) {
#ifdef RPCBIND_DEBUG
		if (debugging) {
			fprintf(stderr, "not found\n");
		}
#endif
		if (reply_type == RPCBPROC_INDIRECT) {
			ar_svcflgerr_noprog(rqstp);
		}
		return FALSE;
	}
	if (rbl->rpcb_map.r_vers != a->vers) {
		if (reply_type == RPCBPROC_INDIRECT) {
			arpcvers_t vers_low, vers_high;

			find_versions(a->prog, netidstr,
				      &vers_low, &vers_high);
			ar_svcflgerr_progvers(rqstp, vers_low, vers_high);
		}
		return FALSE;
	}

#ifdef RPCBIND_DEBUG
	if (debugging) {
		fprintf(stderr, "found at uaddr %s\n", rbl->rpcb_map.r_addr);
	}
#endif
	/*
	 *	Check whether this entry is valid and a server is present
	 *	Mergeaddr() returns NULL if no such entry is present, and
	 *	returns "" if the entry was present but the server is not
	 *	present (i.e., it crashed).
	 */
	if (reply_type == RPCBPROC_INDIRECT) {
		uaddr = mergeaddr(transp, netidstr, 
				  rbl->rpcb_map.r_addr, NULL);
		if (uaddr == NULL || uaddr[0] == '\0') {
			ar_svcflgerr_noprog(rqstp);
			if (uaddr != NULL) {
				free(uaddr);
			}
			uaddr = NULL;
			return FALSE;
		}
		free(uaddr);
		uaddr = NULL;
	}
	nconf = rpcbind_get_conf(netidstr);
	if (nconf == (ar_netid_t *)NULL) {
		if (reply_type == RPCBPROC_INDIRECT) {
			ar_svcflgerr_systemerr(rqstp);
			return FALSE;
		}
		if (debugging) {
			fprintf(stderr, "rpcbproc_callit_com:  "
				"rpcbind_get_conf failed\n");
		}
		return FALSE;
	}

	/* compute local_uaddr with merge (picks port from rbl, local address
	 * that most matches the request's src addr.
	 * 
	 * convert that back to uaddr
	 */

	localsa = local_sa(nconf->an_family, &tbuf.len);
	if (localsa == NULL) {
		if (debugging) {
			fprintf(stderr,
			"rpcbproc_callit_com: no local address\n");
		}
		goto error;
	}
	tbuf.maxlen = tbuf.len;
	tbuf.buf = (char *)localsa;
	local_uaddr = addrmerge(&tbuf, rbl->rpcb_map.r_addr, NULL, netidstr);
	if (!local_uaddr) {
		err = ENOMEM;
		goto error;
	}

	m_uaddr = addrmerge(&caller, rbl->rpcb_map.r_addr, NULL, netidstr);
	if (!m_uaddr) {
		err = ENOMEM;
		goto error;
	}

	err = ar_uaddr2taddr(rpcbind_ioctx, netidstr, local_uaddr, &na);
	if (err != 0) {
		if (reply_type == RPCBPROC_INDIRECT) {
			ar_svcflgerr_systemerr(rqstp);
		}
		goto error;
	}

	/* allocate forward table entry */
	err = forward_register(&info);
	if (err != 0) {
		goto error;
	}

	info->clnt = NULL;
	info->cco = NULL;
	info->sco = NULL;
	info->uaddr = m_uaddr;
	m_uaddr = NULL;

	/* setup/connect clnt. ar_clnt_tli_create() */
	err = ar_clnt_tli_create(rpcbind_ioctx, netidstr, na, 
				 a->prog, a->vers, NULL, &cerr,
				 &info->clnt);
	if (err != 0) {
		if (debugging) {
			errstr = ar_astrcreateerror(&cerr);
			if (errstr) {
				fprintf(stderr, "create clnt failed: %s\n",
					errstr);
				free(errstr);
			}
		}
		goto error;
	}

	tlimit.tv_sec = MAXTIME_OFF;
	tlimit.tv_nsec = 0;
	
	/* issue async rpc through clnt ar_clnt_call_async_copy */
	err = ar_clnt_call_async_copy(info->clnt, a->proc, 
				      (axdrproc_t)&axdr_callit_rmtcallargs,
				      a, (axdrproc_t)&axdr_callit_rmtresult, 
				      sizeof(rpcb_remote_result_t),
				      &rpcb_callit_done, info,
				      &tlimit, &info->cco);
	if (err != 0) {
		goto error;
	}

	/* call is running. Mark original server call as async so we
	 * can finish it when we get the result.
	 */
	err = ar_svc_async(rqstp, &info->sco);
	if (err != 0) {
		goto error;
	}

	/* done */
	info = NULL;
	err = 0;

error:
	if (err != 0 && reply_type == RPCBPROC_INDIRECT) {
		ar_svcflgerr_systemerr(rqstp);
	}

	if (local_uaddr) {
		free(local_uaddr);
		local_uaddr = NULL;
	}
	if (m_uaddr) {
		free(m_uaddr);
		m_uaddr = NULL;
	}

	if (na) {
		if (na->buf) {
			free(na->buf);
		}
		na->buf = NULL;
		free(na);
		na = NULL;
	}
	if (info) {
		if (info->cco) {
			ar_clnt_call_cancel(info->cco);
		}
		info->cco = NULL;
		if (info->sco) {
			ar_svc_async_done(info->sco, err);
		}
		info->sco = NULL;
		if (info->clnt) {
			ar_clnt_destroy(info->clnt);
		}
		info->clnt = NULL;
		if (info->uaddr) {
			free(info->uaddr);
		}
		info->uaddr = NULL;
		info->flag &= ~FINFO_ACTIVE;
		info = NULL;
	}
		
	return FALSE;
}