static int
enable_notifications_for_obj(int sd, const char* obj, const char* rest)
{
  (void)rest;

  host*    hst;
  service* svc;
  nez_find_host_or_service(obj, &hst, &svc);

  if (svc) {
    enable_service_notifications(svc);
    nsock_printf_nul(sd, "NOTIFICATIONS ENABLED FOR SERVICE: %s/%s\n", svc->host_name, svc->display_name);
    return 200;
  }

  if (hst) {
    enable_host_notifications(hst);
    nsock_printf_nul(sd, "NOTIFICATIONS ENABLED FOR HOST (AND ITS SERVICES): %s\n", hst->display_name);

    for (servicesmember* svcmem = hst->services; svcmem; svcmem = svcmem->next) {
      enable_service_notifications(svcmem->service_ptr);
    }

    return 200;
  }

  nsock_printf_nul(sd, "NO HOST OR SERVICE FOUND FOR: %s", obj);
  return 404;
}
Example #2
0
static int qh_help(int sd, char *buf, unsigned int len)
{
	struct query_handler *qh;

	if (!*buf || !strcmp(buf, "help")) {
		nsock_printf_nul(sd,
		                 "  help <name>   show help for handler <name>\n"
		                 "  help list     list registered handlers\n");
		return 0;
	}

	if (!strcmp(buf, "list")) {
		for (qh = qhandlers; qh; qh = qh->next_qh) {
			nsock_printf(sd, "%-10s %s\n", qh->name, qh->description ? qh->description : "(No description available)");
		}
		nsock_printf(sd, "%c", 0);
		return 0;
	}

	if (!(qh = qh_find_handler(buf))) {
		nsock_printf_nul(sd, "No handler named '%s' is registered\n", buf);
	} else if (qh->handler(sd, "help", 4) > 200) {
		nsock_printf_nul(sd, "The handler %s doesn't have any help yet.", buf);
	}

	return 0;
}
Example #3
0
static int worker( const char *path)
{
	int sd, ret;
	char response[128];

	/*set_loadctl_defaults();*/

	sd = nsock_unix( path, NSOCK_TCP | NSOCK_CONNECT);
	if( sd < 0) {
		printf( "Failed to connect to query socket '%s': %s: %s\n",
				path, nsock_strerror( sd), strerror( errno));
		return 1;
	}

	ret = nsock_printf_nul( sd, "@wproc register name=Core Ping Worker %d;pid=%d;plugin=check_ping", getpid(), getpid());
	if( ret < 0) {
		printf( "Failed to register as worker.\n");
		return 1;
	}

	ret = read( sd, response, 3);
	if( ret != 3) {
		printf( "Failed to read response from wproc manager\n");
		return 1;
	}
	if( memcmp( response, "OK", 3)) {
		read( sd, response + 3, sizeof(response) - 4);
		response[ sizeof( response) - 2] = 0;
		printf( "Failed to register with wproc manager: %s\n", response);
		return 1;
	}

	enter_worker( sd, start_cmd);
	return 0;
}
static int
unknown_command(int sd, char* object, char* rest)
{
  (void)object;
  (void)rest;
  nsock_printf_nul(sd, "UNKNOWN COMMAND\n");
  return 404;
}
static int
nez_cmd_frenchman(int sd, char* object, char* rest)
{
  (void)object;
  (void)rest;
  nsock_printf_nul(sd, "http://yolochocin.co/\n");
  return 420;     // easter egg
}
Example #6
0
/* the echo service. stupid, but useful for testing */
static int qh_echo(int sd, char *buf, unsigned int len)
{
	if (!strcmp(buf, "help")) {
		nsock_printf_nul(sd,
		                 "Query handler that simply echoes back what you send it.");
		return 0;
	}
	return nsock_write_all(sd, buf, len);
}
Example #7
0
static int nerd_qh_handler(int sd, char *request, unsigned int len)
{
	char *chan_name, *fmt;
	struct nerd_channel *chan;
	int action;

	if (!*request || !strcmp(request, "help")) {
		nsock_printf_nul(sd, "Manage subscriptions to NERD channels.\n"
			"Valid commands:\n"
			"  list                      list available channels\n"
			"  subscribe <channel>       subscribe to a channel\n"
			"  unsubscribe <channel>     unsubscribe to a channel\n");
		return 0;
	}

	if (!strcmp(request, "list")) {
		unsigned int i;
		for (i = 0; i < num_channels; i++) {
			chan = channels[i];
			nsock_printf(sd, "%-15s %s\n", chan->name, chan->description);
		}
		nsock_printf(sd, "%c", 0);
		return 0;
	}

	chan_name = strchr(request, ' ');
	if(!chan_name)
		return 400;

	*chan_name = 0;
	chan_name++;
	if(!strcmp(request, "subscribe"))
		action = NERD_SUBSCRIBE;
	else if(!strcmp(request, "unsubscribe"))
		action = NERD_UNSUBSCRIBE;
	else {
		return 400;
	}

	/* might have a format-string */
	if((fmt = strchr(chan_name, ':')))
		*(fmt++) = 0;

	chan = find_channel(chan_name);
	if(!chan) {
		return 400;
	}

	if(action == NERD_SUBSCRIBE)
		subscribe(sd, chan, fmt);
	else
		unsubscribe(sd, chan);

	return 0;
}
static int
acknowledge_problem_for_obj(int sd, const char* obj, char* comment)
{
  host*    hst;
  service* svc;
  nez_find_host_or_service(obj, &hst, &svc);

  char* author     = "nagioseasier";
  int   sticky     = 1; // DO NOT send notifications until this service/host recovers
  int   notify     = 1; // DO send a notification that we have ack'd this
  int   persistent = 0; // we don't want persistent comments in Nagios

  if (svc) {
    acknowledge_service_problem(
      svc,
      author,
      comment,
      sticky,
      notify,
      persistent);

    nsock_printf_nul(sd, "ACKNOWLEDGED PROBLEMS ON %s WITH: %s\n", obj, comment);
    return 200;
  }

  if (hst) {
    acknowledge_host_problem(
      hst,
      author,
      comment,
      sticky,
      notify,
      persistent);

    nsock_printf_nul(sd, "ACKNOWLEDGED PROBLEMS ON %s WITH: %s\n", obj, comment);
    return 200;
  }

  nsock_printf_nul(sd, "NO HOST OR SERVICE FOUND FOR %s\n", obj);
  return 404;
}
static int
show_muted_services(int sd)
{
  for (service* svc = service_list; svc; svc = svc->next) {
    if (svc->notifications_enabled == 0) {
      nez_show_status_for_service(sd, svc);
    }
  }

  nsock_printf_nul(sd, "NO SERVICES FOUND");
  return 404;
}
static int
unacknowledge_problem_for_obj(int sd, const char* obj)
{
  host*    hst;
  service* svc;
  nez_find_host_or_service(obj, &hst, &svc);

  if (svc) {
    remove_service_acknowledgement(svc);
    nsock_printf_nul(sd, "REMOVED ACKNOWLEDGEMENT ON %s\n", obj);
    return 200;
  }

  if (hst) {
    remove_host_acknowledgement(hst);
    nsock_printf_nul(sd, "REMOVED ACKNOWLEDGEMENT ON %s\n", obj);
    return 200;
  }

  nsock_printf_nul(sd, "NO HOST OR SERVICE FOUND FOR %s\n", obj);
  return 404;
}
Example #11
0
static int qh_command(int sd, char *buf, unsigned int len)
{
	char *space;
	int mode;

	if (!*buf || !strcmp(buf, "help")) {
		nsock_printf_nul(sd, "Query handler for naemon commands.\n"
		                 "Available commands:\n"
		                 "  run <command>     Run a command\n"
		                 "  runkv <command>   Run a command as escaped kvvec\n"
							  );
		return 0;
	}
	if ((space = memchr(buf, ' ', len)))
		* (space++) = 0;
	if (space) {
		mode = 0;
		if (!strcmp(buf, "run")) {
			mode = COMMAND_SYNTAX_NOKV;
		}
		else if(!strcmp(buf, "runkv")) {
			mode = COMMAND_SYNTAX_KV;
		}
		if(mode != 0) {
			GError *error = NULL;
			int res = process_external_command(space, mode, &error);
			if (res == OK) {
				return 200;
			} else {
				nsock_printf_nul(sd, "400: %s\n", error->message);
				g_clear_error(&error);
				return 0;
			}
		}
	}

	return 404;
}
Example #12
0
int dump_event_stats(int sd)
{
	unsigned int i;

	for (i = 0; i < ARRAY_SIZE(event_count); i++) {
		nsock_printf(sd, "%s=%u;", EVENT_TYPE_STR(i), event_count[i]);
		/*
		 * VERSIONFIX: Make EVENT_SLEEP and EVENT_USER_FUNCTION
		 * appear in linear order in include/nagios.h when we go
		 * from 4.0 -> 4.1, so we can remove this junk.
		 */
		if (i == 16)
			i = 97;
	}
	nsock_printf_nul(sd, "SQUEUE_ENTRIES=%u", squeue_size(nagios_squeue));

	return OK;
}
Example #13
0
static int
display_help(int sd)
{
  nsock_printf_nul(sd, "Query handler for actually doing useful shit with this socket.\n"
       "Available commands:\n"
       "  status <host|service>                          Display the status of a host or service\n"
       "  check <host|service>                           Schedule a re-check of the host or service\n"
       "\n"
       "  enable_notifications <host|service>            Enable notifications for a host or host-service\n"
       "  disable_notifications <host|service>           Disable notifications for a host or host-service\n"
       "\n"
       "  acknowledge <host|service> [<comment>]         Acknowledge a host/service problem (opt. comment)\n"
       "  unacknowledge <host|service>                   Unacknowledge a host/service problem\n"
       "\n"
       "  downtime <host|service> [<minutes> <comment>]  Schedule downtime for a host/service (opt. num minutes, comment)\n"
       "\n"
       "  problems [<svcgroup|hstgroup|host> <state>]    Display all services in a non-OK state\n"
       "  muted                                          Display all services that do not have notifications enabled\n"
       "\n"
       "  stats                                          Display stats about service states as JSON\n"
       );
  return 200;
}
Example #14
0
static int wproc_query_handler(int sd, char *buf, unsigned int len)
{
	char *space, *rbuf = NULL;

	if (!*buf || !strcmp(buf, "help")) {
		nsock_printf_nul(sd, "Control worker processes.\n"
			"Valid commands:\n"
			"  wpstats              Print general job information\n"
			"  register <options>   Register a new worker\n"
			"                       <options> can be name, pid, max_jobs and/or plugin.\n"
			"                       There can be many plugin args.");
		return 0;
	}

	if ((space = memchr(buf, ' ', len)) != NULL)
		*space = 0;

	rbuf = space ? space + 1 : buf;
	len -= (unsigned long)rbuf - (unsigned long)buf;

	if (!strcmp(buf, "register"))
		return register_worker(sd, rbuf, len);
	if (!strcmp(buf, "wpstats")) {
		unsigned int i;

		for (i = 0; i < workers.len; i++) {
			struct wproc_worker *wp = workers.wps[i];
			nsock_printf(sd, "name=%s;pid=%d;jobs_running=%u;jobs_started=%u\n",
						 wp->name, wp->pid,
						 wp->jobs_running, wp->jobs_started);
		}
		return 0;
	}

	return 400;
}
Example #15
0
/* a service for registering workers */
static int register_worker(int sd, char *buf, unsigned int len)
{
	int i, is_global = 1;
	struct kvvec *info;
	struct wproc_worker *worker;

	logit(NSLOG_INFO_MESSAGE, TRUE, "wproc: Registry request: %s\n", buf);
	if (!(worker = calloc(1, sizeof(*worker)))) {
		logit(NSLOG_RUNTIME_ERROR, TRUE, "wproc: Failed to allocate worker: %s\n", strerror(errno));
		return 500;
	}

	info = buf2kvvec(buf, len, '=', ';', 0);
	if (info == NULL) {
		free(worker);
		logit(NSLOG_RUNTIME_ERROR, TRUE, "wproc: Failed to parse registration request\n");
		return 500;
	}

	worker->sd = sd;
	worker->ioc = iocache_create(1 * 1024 * 1024);

	iobroker_unregister(nagios_iobs, sd);
	iobroker_register(nagios_iobs, sd, worker, handle_worker_result);

	for(i = 0; i < info->kv_pairs; i++) {
		struct key_value *kv = &info->kv[i];
		if (!strcmp(kv->key, "name")) {
			worker->name = strdup(kv->value);
		}
		else if (!strcmp(kv->key, "pid")) {
			worker->pid = atoi(kv->value);
		}
		else if (!strcmp(kv->key, "max_jobs")) {
			worker->max_jobs = atoi(kv->value);
		}
		else if (!strcmp(kv->key, "plugin")) {
			struct wproc_list *command_handlers;
			is_global = 0;
			if (!(command_handlers = dkhash_get(specialized_workers, kv->value, NULL))) {
				command_handlers = calloc(1, sizeof(struct wproc_list));
				command_handlers->wps = calloc(1, sizeof(struct wproc_worker**));
				command_handlers->len = 1;
				command_handlers->wps[0] = worker;
				dkhash_insert(specialized_workers, strdup(kv->value), NULL, command_handlers);
			}
			else {
				command_handlers->len++;
				command_handlers->wps = realloc(command_handlers->wps, command_handlers->len * sizeof(struct wproc_worker**));
				command_handlers->wps[command_handlers->len - 1] = worker;
			}
			worker->wp_list = command_handlers;
		}
	}

	if (!worker->max_jobs) {
		/*
		 * each worker uses two filedescriptors per job, one to
		 * connect to the master and about 13 to handle libraries
		 * and memory allocation, so this guesstimate shouldn't
		 * be too far off (for local workers, at least).
		 */
		worker->max_jobs = (iobroker_max_usable_fds() / 2) - 50;
	}
	worker->jobs = fanout_create(worker->max_jobs);

	if (is_global) {
		workers.len++;
		workers.wps = realloc(workers.wps, workers.len * sizeof(struct wproc_worker *));
		workers.wps[workers.len - 1] = worker;
		worker->wp_list = &workers;
	}
	wproc_num_workers_online++;
	kvvec_destroy(info, 0);
	nsock_printf_nul(sd, "OK");

	/* signal query handler to release its iocache for this one */
	return QH_TAKEOVER;
}
Example #16
0
static int qh_input(int sd, int events, void *bq_)
{
	nm_bufferqueue *bq = (nm_bufferqueue *)bq_;
	int result;
	size_t len;
	unsigned int query_len = 0;
	char *buf, *space;
	struct query_handler *qh;
	char *handler = NULL, *query = NULL;

	result = nm_bufferqueue_read(bq, sd);
	/* disconnect? */
	if (result == 0 || (result < 0 && errno == EPIPE)) {
		nm_bufferqueue_destroy(bq);
		iobroker_close(nagios_iobs, sd);
		qh_running--;
		return 0;
	}

	/*
	 * A request looks like this: '[@|#]<qh>[<SP>][<query>]\0'.
	 * That is, optional '#' (oneshot) or '@' (keepalive),
	 * followed by the name of a registered handler, followed by
	 * an optional space and an optional query. If the handler
	 * has no "default" handler, a query is required or an error
	 * will be thrown.
	 */

	/* Use data up to the first nul byte */
	nm_bufferqueue_unshift_to_delim(bq, "\0", 1, &len, (void **)&buf);
	if (!buf)
		return 0;

	/* Identify handler part and any magic query bytes */
	if (*buf == '@' || *buf == '#') {
		handler = buf + 1;
	} else {
		handler = buf;
	}

	/* Locate query (if any) */
	if ((space = strchr(buf, ' '))) {
		*space = 0;
		query = space + 1;
		query_len = len - ((unsigned long)query - (unsigned long)buf);
	} else {
		query = "";
		query_len = 0;
	}

	/* locate the handler */
	if (!(qh = qh_find_handler(handler))) {
		/* not found. that's a 404 */
		nsock_printf(sd, "404: %s: No such handler", handler);
		nm_free(buf);
		iobroker_close(nagios_iobs, sd);
		nm_bufferqueue_destroy(bq);
		return 0;
	}

	/* strip trailing newlines */
	while (query_len > 0 && (query[query_len - 1] == 0 || query[query_len - 1] == '\n'))
		query[--query_len] = 0;

	/* now pass the query to the handler */
	if ((result = qh->handler(sd, query, query_len)) >= 100) {
		nsock_printf_nul(sd, "%d: %s", result, qh_strerror(result));
	}

	if (result >= 300 || *buf != '@') {
		/* error code or one-shot query */
		nm_free(buf);
		iobroker_close(nagios_iobs, sd);
		nm_bufferqueue_destroy(bq);
		return 0;
	}
	nm_free(buf);

	/* check for magic handler codes */
	switch (result) {
	case QH_CLOSE: /* oneshot handler */
	case -1:       /* general error */
		iobroker_close(nagios_iobs, sd);
		/* fallthrough */
	case QH_TAKEOVER: /* handler takes over */
	case 101:         /* switch protocol (takeover + message) */
		nm_bufferqueue_destroy(bq);
		break;
	}
	return 0;
}