Example #1
0
File: proc.c Project: reyk/snmpd
void
proc_connect(struct privsep *ps)
{
	struct imsgev		*iev;
	unsigned int		 src, dst, inst;

	/* Don't distribute any sockets if we are not really going to run. */
	if (ps->ps_noaction)
		return;

	for (dst = 0; dst < PROC_MAX; dst++) {
		/* We don't communicate with ourselves. */
		if (dst == PROC_PARENT)
			continue;

		for (inst = 0; inst < ps->ps_instances[dst]; inst++) {
			iev = &ps->ps_ievs[dst][inst];
			imsg_init(&iev->ibuf, ps->ps_pp->pp_pipes[dst][inst]);
			event_set(&iev->ev, iev->ibuf.fd, iev->events,
			    iev->handler, iev->data);
			event_add(&iev->ev, NULL);
		}
	}

	/* Distribute the socketpair()s for everyone. */
	for (src = 0; src < PROC_MAX; src++)
		for (dst = src; dst < PROC_MAX; dst++) {
			/* Parent already distributed its fds. */
			if (src == PROC_PARENT || dst == PROC_PARENT)
				continue;

			proc_open(ps, src, dst);
		}
}
Example #2
0
int
snmp_sendsock(struct imsgev *iev)
{
	struct imsgev		 tmpiev;
	struct sockaddr_un	 sun;
	int			 s = -1;

	if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
		goto fail;

	bzero(&sun, sizeof(sun));
	sun.sun_family = AF_UNIX;
	strlcpy(sun.sun_path, SNMP_SOCKET, sizeof(sun.sun_path));
	if (connect(s, (struct sockaddr *)&sun, sizeof(sun)) == -1)
		goto fail;

	/* enable restricted snmp socket mode */
	bzero(&tmpiev, sizeof(tmpiev));
	imsg_init(&tmpiev.ibuf, s);
	imsg_compose_event(&tmpiev, IMSG_SNMP_LOCK, 0, 0, -1, NULL, 0);

	imsg_compose_event(iev, IMSG_SNMPSOCK, 0, 0, s, NULL, 0);
	imsg_flush(&iev->ibuf);	/* need to send the socket now */
	close(s);
	return (0);

 fail:
	if (s != -1)
		close(s);
	imsg_compose_event(iev, IMSG_NONE, 0, 0, -1, NULL, 0);
	return (-1);
}
Example #3
0
File: proc.c Project: reyk/snmpd
void
proc_accept(struct privsep *ps, int fd, enum privsep_procid dst,
    unsigned int n)
{
	struct privsep_pipes	*pp = ps->ps_pp;
	struct imsgev		*iev;

	if (ps->ps_ievs[dst] == NULL) {
#if DEBUG > 1
		log_debug("%s: %s src %d %d to dst %d %d not connected",
		    __func__, ps->ps_title[privsep_process],
		    privsep_process, ps->ps_instance + 1,
		    dst, n + 1);
#endif
		close(fd);
		return;
	}

	if (pp->pp_pipes[dst][n] != -1) {
		log_warnx("%s: duplicated descriptor", __func__);
		close(fd);
		return;
	} else
		pp->pp_pipes[dst][n] = fd;

	iev = &ps->ps_ievs[dst][n];
	imsg_init(&iev->ibuf, fd);
	event_set(&iev->ev, iev->ibuf.fd, iev->events, iev->handler, iev->data);
	event_add(&iev->ev, NULL);
}
Example #4
0
static int
queue_proc_init(struct passwd *pw, int server, const char *conf)
{
	uint32_t	version;
	int		fd;

	fd = fork_proc_backend("queue", conf, "queue-proc");
	if (fd == -1)
		fatalx("queue-proc: exiting");

	imsg_init(&ibuf, fd);

	version = PROC_QUEUE_API_VERSION;
	imsg_compose(&ibuf, PROC_QUEUE_INIT, 0, 0, -1,
	    &version, sizeof(version));

	queue_api_on_close(queue_proc_close);
	queue_api_on_message_create(queue_proc_message_create);
	queue_api_on_message_commit(queue_proc_message_commit);
	queue_api_on_message_delete(queue_proc_message_delete);
	queue_api_on_message_fd_r(queue_proc_message_fd_r);
	queue_api_on_message_corrupt(queue_proc_message_corrupt);
	queue_api_on_envelope_create(queue_proc_envelope_create);
	queue_api_on_envelope_delete(queue_proc_envelope_delete);
	queue_api_on_envelope_update(queue_proc_envelope_update);
	queue_api_on_envelope_load(queue_proc_envelope_load);
	queue_api_on_envelope_walk(queue_proc_envelope_walk);

	queue_proc_call();
	queue_proc_end();

	return (1);
}
Example #5
0
/* ARGSUSED */
void
control_accept(int listenfd, short event, void *arg)
{
	int			 connfd;
	socklen_t		 len;
	struct sockaddr_un	 sun;
	struct ctl_conn		*c;

	len = sizeof(sun);
	if ((connfd = accept(listenfd, (struct sockaddr *)&sun, &len)) == -1) {
		if (errno == EINTR || errno == ECONNABORTED)
			return;
		fatal("control_accept: accept");
	}

	session_socket_blockmode(connfd, BM_NONBLOCK);

	if ((c = calloc(1, sizeof(*c))) == NULL)
		fatal(NULL);
	imsg_init(&c->iev.ibuf, connfd);
	c->iev.handler = control_dispatch_ext;
	c->iev.events = EV_READ;
	event_set(&c->iev.ev, c->iev.ibuf.fd, c->iev.events,
	    c->iev.handler, NULL);
	event_add(&c->iev.ev, NULL);
	TAILQ_INSERT_TAIL(&ctl_conns, c, entry);

	if (stat_increment(STATS_CONTROL_SESSION) >= env->sc_maxconn) {
		log_warnx("ctl client limit hit, disabling new connections");
		event_del(&control_state.ev);
	}
}
Example #6
0
int
queue_api_dispatch(void)
{
	struct passwd	*pw;
	ssize_t		 n;

	pw = getpwnam(user);
	if (pw == NULL) {
		log_warn("queue-api: getpwnam");
		fatalx("queue-api: exiting");
	}

	if (rootpath) {
		if (chroot(rootpath) == -1) {
			log_warn("queue-api: chroot");
			fatalx("queue-api: exiting");
		}
		if (chdir("/") == -1) {
			log_warn("queue-api: chdir");
			fatalx("queue-api: exiting");
		}
	}

	if (setgroups(1, &pw->pw_gid) ||
	    setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) ||
	    setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid)) {
		log_warn("queue-api: cannot drop privileges");
		fatalx("queue-api: exiting");
	}

	imsg_init(&ibuf, 0);

	while (1) {
		n = imsg_get(&ibuf, &imsg);
		if (n == -1) {
			log_warn("warn: queue-api: imsg_get");
			break;
		}

		if (n) {
			rdata = imsg.data;
			rlen = imsg.hdr.len - IMSG_HEADER_SIZE;
			queue_msg_dispatch();
			imsg_flush(&ibuf);
			continue;
		}

		n = imsg_read(&ibuf);
		if (n == -1) {
			log_warn("warn: queue-api: imsg_read");
			break;
		}
		if (n == 0) {
			log_warnx("warn: queue-api: pipe closed");
			break;
		}
	}

	return (1);
}
Example #7
0
static void *
table_proc_open(struct table *table)
{
	struct table_proc_priv	*priv;
	struct table_open_params op;
	int			 fd;

	priv = xcalloc(1, sizeof(*priv), "table_proc_open");

	fd = fork_proc_backend("table", table->t_config, table->t_name);
	if (fd == -1)
		fatalx("table-proc: exiting");

	imsg_init(&priv->ibuf, fd);

	memset(&op, 0, sizeof op);
	op.version = PROC_TABLE_API_VERSION;
	(void)strlcpy(op.name, table->t_name, sizeof op.name);
	imsg_compose(&priv->ibuf, PROC_TABLE_OPEN, 0, 0, -1, &op, sizeof op);

	table_proc_call(priv);
	table_proc_end();

	return (priv);
}
Example #8
0
/* ARGSUSED */
void
control_accept(int listenfd, short event, void *arg)
{
	struct control_sock	*cs = arg;
	int			 connfd;
	socklen_t		 len;
	struct sockaddr_un	 sun;
	struct ctl_conn		*c;

	event_add(&cs->cs_ev, NULL);
	if ((event & EV_TIMEOUT))
		return;

	len = sizeof(sun);
	if ((connfd = accept4(listenfd,
	    (struct sockaddr *)&sun, &len, SOCK_NONBLOCK)) == -1) {
		/*
		 * Pause accept if we are out of file descriptors, or
		 * libevent will haunt us here too.
		 */
		if (errno == ENFILE || errno == EMFILE) {
			struct timeval evtpause = { 1, 0 };

			event_del(&cs->cs_ev);
			evtimer_add(&cs->cs_evt, &evtpause);
		} else if (errno != EWOULDBLOCK && errno != EINTR &&
		    errno != ECONNABORTED)
			log_warn("%s: accept", __func__);
		return;
	}

	if ((c = calloc(1, sizeof(struct ctl_conn))) == NULL) {
		close(connfd);
		log_warn("%s: calloc", __func__);
		return;
	}

	imsg_init(&c->iev.ibuf, connfd);
	if (cs->cs_agentx) {
		c->handle = snmp_agentx_alloc(c->iev.ibuf.fd);
		if (c->handle == NULL) {
			free(c);
			log_warn("%s: agentx", __func__);
			return;
		}
		c->flags |= CTL_CONN_LOCKED;
		c->iev.handler = control_dispatch_agentx;
		TAILQ_INIT(&c->oids);
	} else
		c->iev.handler = control_dispatch_imsg;
	c->iev.events = EV_READ;
	c->iev.data = c;
	c->cs = cs;
	event_set(&c->iev.ev, c->iev.ibuf.fd, c->iev.events,
	    c->iev.handler, c->iev.data);
	event_add(&c->iev.ev, NULL);

	TAILQ_INSERT_TAIL(&ctl_conns, c, entry);
}
Example #9
0
static int
queue_proc_init(struct passwd *pw, int server)
{
	int		sp[2];
	uint32_t	version;

	errno = 0;

	if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, sp) < 0) {
		log_warn("warn: queue-proc: socketpair");
		return (0);
	}

	if ((pid = fork()) == -1) {
		log_warn("warn: queue-proc: fork");
		goto err;
	}

	if (pid == 0) {
		/* child process */
		dup2(sp[0], STDIN_FILENO);
		if (closefrom(STDERR_FILENO + 1) < 0)
			exit(1);

		execl(execpath, "queue_ramproc", NULL);
		err(1, "execl");
	}

	/* parent process */
	close(sp[0]);
	imsg_init(&ibuf, sp[1]);

	version = PROC_QUEUE_API_VERSION;
	imsg_compose(&ibuf, PROC_QUEUE_INIT, 0, 0, -1,
	    &version, sizeof(version));

	queue_api_on_message_create(queue_proc_message_create);
	queue_api_on_message_commit(queue_proc_message_commit);
	queue_api_on_message_delete(queue_proc_message_delete);
	queue_api_on_message_fd_r(queue_proc_message_fd_r);
	queue_api_on_message_corrupt(queue_proc_message_corrupt);
	queue_api_on_envelope_create(queue_proc_envelope_create);
	queue_api_on_envelope_delete(queue_proc_envelope_delete);
	queue_api_on_envelope_update(queue_proc_envelope_update);
	queue_api_on_envelope_load(queue_proc_envelope_load);
	queue_api_on_envelope_walk(queue_proc_envelope_walk);

	queue_proc_call();
	queue_proc_end();

	return (1);

err:
	close(sp[0]);
	close(sp[1]);
	return (0);
}
Example #10
0
pid_t
ypldap_dns(int pipe_ntp[2], struct passwd *pw)
{
	pid_t			 pid;
	struct event	 ev_sigint;
	struct event	 ev_sigterm;
	struct event	 ev_sighup;
	struct env	 env;

	switch (pid = fork()) {
	case -1:
		fatal("cannot fork");
		break;
	case 0:
		break;
	default:
		return (pid);
	}

	setproctitle("dns engine");
	close(pipe_ntp[0]);

	if (setgroups(1, &pw->pw_gid) ||
	    setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) ||
	    setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))
		fatal("can't drop privileges");
	endservent();

	if (pledge("stdio dns", NULL) == -1)
		fatal("pledge");

	event_init();
	signal_set(&ev_sigint, SIGINT, dns_sig_handler, NULL);
	signal_set(&ev_sigterm, SIGTERM, dns_sig_handler, NULL);
	signal_set(&ev_sighup, SIGHUP, dns_sig_handler, NULL);
	signal_add(&ev_sigint, NULL);
	signal_add(&ev_sigterm, NULL);
	signal_add(&ev_sighup, NULL);

	if ((env.sc_iev = calloc(1, sizeof(*env.sc_iev))) == NULL)
		fatal(NULL);

	env.sc_iev->events = EV_READ;
	env.sc_iev->data = &env;
	imsg_init(&env.sc_iev->ibuf, pipe_ntp[1]);
	env.sc_iev->handler = dns_dispatch_imsg;
	event_set(&env.sc_iev->ev, env.sc_iev->ibuf.fd, env.sc_iev->events,
	    env.sc_iev->handler, &env);
	event_add(&env.sc_iev->ev, NULL);

	event_dispatch();
	dns_shutdown();

	return (0);
}
Example #11
0
void
filter_init(void)
{
	bzero(&fi, sizeof (fi));

	imsg_init(&fi.ibuf, 0);

	event_init();
	event_set(&fi.ev, 0, EV_READ, filter_handler, (void *)&fi);
	event_add(&fi.ev, NULL);
}
Example #12
0
/* ARGSUSED */
void
control_accept(int listenfd, short event, void *arg)
{
	struct control_sock	*cs = (struct control_sock *)arg;
	int			 connfd;
	socklen_t		 len;
	struct sockaddr_un	 sun;
	struct ctl_conn		*c;

	event_add(&cs->cs_ev, NULL);
	if ((event & EV_TIMEOUT))
		return;

	len = sizeof(sun);
	if ((connfd = accept(listenfd,
	    (struct sockaddr *)&sun, &len)) == -1) {
		/*
		 * Pause accept if we are out of file descriptors, or
		 * libevent will haunt us here too.
		 */
		if (errno == ENFILE || errno == EMFILE) {
			struct timeval evtpause = { 1, 0 };

			event_del(&cs->cs_ev);
			evtimer_add(&cs->cs_evt, &evtpause);
		} else if (errno != EWOULDBLOCK && errno != EINTR)
			log_warn("control_accept: accept");
		return;
	}

	fd_nonblock(connfd);

	if ((c = calloc(1, sizeof(struct ctl_conn))) == NULL) {
		log_warn("control_accept");
		close(connfd);
		return;
	}
	if ((c->ctx = npppd_ctl_create(cs->cs_ctx)) == NULL) {
		free(c);
		log_warn("control_accept");
		close(connfd);
		return;
	}

	imsg_init(&c->iev.ibuf, connfd);
	c->iev.handler = control_dispatch_imsg;
	c->iev.events = EV_READ;
	c->iev.data = cs;
	event_set(&c->iev.ev, c->iev.ibuf.fd, c->iev.events,
	    c->iev.handler, cs);
	event_add(&c->iev.ev, NULL);

	TAILQ_INSERT_TAIL(&ctl_conns, c, entry);
}
Example #13
0
static void *
table_proc_open(struct table *table)
{
	int			 sp[2];
	struct table_proc_priv	*priv;
	char			*environ_new[2];
	struct table_open_params op;

	errno = 0;

	if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, sp) < 0) {
		log_warn("warn: table-proc: socketpair");
		return (NULL);
	}
	priv = xcalloc(1, sizeof(*priv), "table_proc_open");

	if ((priv->pid = fork()) == -1) {
		log_warn("warn: table-proc: fork");
		goto err;
	}

	if (priv->pid == 0) {
		/* child process */
		dup2(sp[0], STDIN_FILENO);
		if (closefrom(STDERR_FILENO + 1) < 0)
			exit(1);

		environ_new[0] = "PATH=" _PATH_DEFPATH;
		environ_new[1] = (char *)NULL;
		environ = environ_new;
		execle("/bin/sh", "/bin/sh", "-c", table->t_config, (char *)NULL,
		    environ_new);
		fatal("execl");
	}

	/* parent process */
	close(sp[0]);
	imsg_init(&priv->ibuf, sp[1]);

	memset(&op, 0, sizeof op);
	op.version = PROC_TABLE_API_VERSION;
	(void)strlcpy(op.name, table->t_name, sizeof op.name);
	imsg_compose(&priv->ibuf, PROC_TABLE_OPEN, 0, 0, -1, &op, sizeof op);

	table_proc_call(priv);
	table_proc_end();

	return (priv);
err:
	free(priv);
	close(sp[0]);
	close(sp[1]);
	return (NULL);
}
Example #14
0
File: mdnsl.c Project: tty56/mdnsd
int
mdns_open(struct mdns *m)
{
	int sockfd;
	
	bzero(m, sizeof(*m));
	if ((sockfd = mdns_connect()) == -1)
		return (-1);
	imsg_init(&m->ibuf, sockfd);
	
	return (sockfd);
}
Example #15
0
void
proc_config(struct privsep *ps, struct privsep_proc *p, u_int nproc)
{
	u_int	 src, dst, i, j, k, found;

	src = privsep_process;

	/*
	 * close unused pipes
	 */
	for (i = 0; i < PROC_MAX; i++) {
		if (i != privsep_process) {
			for (j = 0; j < PROC_MAX; j++) {
				close(ps->ps_pipes[i][j]);
				ps->ps_pipes[i][j] = -1;
			}
		} else {
			for (j = found = 0; j < PROC_MAX; j++, found = 0) {
				for (k = 0; k < nproc; k++) {
					if (p[k].p_id == j)
						found++;
				}
				if (!found) {
					close(ps->ps_pipes[i][j]);
					ps->ps_pipes[i][j] = -1;
				}
			}
		}
	}

	/*
	 * listen on appropriate pipes
	 */
	for (i = 0; i < nproc; i++, p++) {
		dst = p->p_id;
		p->p_ps = ps;
		p->p_env = ps->ps_env;

		imsg_init(&ps->ps_ievs[dst].ibuf,
		    ps->ps_pipes[src][dst]);
		ps->ps_ievs[dst].handler = proc_dispatch;
		ps->ps_ievs[dst].events = EV_READ;
		ps->ps_ievs[dst].data = p;
		ps->ps_ievs[dst].name = p->p_title;
		event_set(&ps->ps_ievs[dst].ev,
		    ps->ps_ievs[dst].ibuf.fd,
		    ps->ps_ievs[dst].events,
		    ps->ps_ievs[dst].handler,
		    ps->ps_ievs[dst].data);
		event_add(&ps->ps_ievs[dst].ev, NULL);
	}
}
Example #16
0
void spawn_service(struct imsgbuf* ibuf, void(*f)(struct imsgbuf*)) {
    struct imsgbuf child_ibuf;
    int fds[2];
    if(socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, fds) == -1) {
        die("Failed to set up socketpair");
    }

    switch(fork()) {
      case -1: die("Failed to fork service"); break;
      case 0:
        // Child
        close(fds[0]);
        imsg_init(&child_ibuf, fds[1]);
        f(&child_ibuf);
        exit(0);
      default:
        // Parent
        close(fds[1]);
        imsg_init(ibuf, fds[0]);
        break;
    }
}
Example #17
0
static int
scheduler_proc_init(void)
{
	int		sp[2], r;
	uint32_t	version;

	errno = 0;

	if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, sp) < 0) {
		log_warn("warn: scheduler-proc: socketpair");
		goto err;
	}

	if ((pid = fork()) == -1) {
		log_warn("warn: scheduler-proc: fork");
		goto err;
	}

	if (pid == 0) {
		/* child process */
		dup2(sp[0], STDIN_FILENO);
		if (closefrom(STDERR_FILENO + 1) < 0)
			exit(1);

		execl(execpath, "scheduler-proc", NULL);
		err(1, "execl");
	}

	/* parent process */
	close(sp[0]);
	imsg_init(&ibuf, sp[1]);

	version = PROC_SCHEDULER_API_VERSION;
	imsg_compose(&ibuf, PROC_SCHEDULER_INIT, 0, 0, -1,
	    &version, sizeof(version));

	scheduler_proc_call();
	scheduler_proc_read(&r, sizeof(r));
	scheduler_proc_end();

	return (r);

err:
	close(sp[0]);
	close(sp[1]);
	fatalx("scheduler-proc: exiting");

	return (0);
}
Example #18
0
void
imsgev_init(struct imsgev *iev, int fd, void *data,
    void (*callback)(struct imsgev *, int, struct imsg *))
{
	imsg_init(&iev->ibuf, fd);
	iev->terminate = 0;

	iev->data = data;
	iev->handler = imsgev_dispatch;
	iev->callback = callback;

	iev->events = EV_READ;
	event_set(&iev->ev, iev->ibuf.fd, iev->events, iev->handler, iev);
	event_add(&iev->ev, NULL);
}
Example #19
0
static struct event *
init_pipe_endpoint(int imsg_fds[2], struct imsg_data *data) {
    struct event *event = NULL;

    if (close(imsg_fds[0]))
        log_notice("close");

    data->is_ready_write = 0;
    data->is_ready_read = 0;
    imsg_init(data->ibuf, imsg_fds[1]);
    evutil_make_socket_nonblocking(imsg_fds[1]);
    event = event_new(data->evbase, imsg_fds[1],
                      EV_READ | EV_WRITE | EV_ET | EV_PERSIST,
                      &tnt_imsg_callback, data);
    return event;
}
Example #20
0
/* ARGSUSED */
void
control_accept(int listenfd, short event, void *bula)
{
	int			 connfd;
	socklen_t		 len;
	struct sockaddr_un	 sun;
	struct ctl_conn		*c;

	event_add(&control_state.ev, NULL);
	if ((event & EV_TIMEOUT))
		return;

	len = sizeof(sun);
	if ((connfd = accept(listenfd,
	    (struct sockaddr *)&sun, &len)) == -1) {
		/*
		 * Pause accept if we are out of file descriptors, or
		 * libevent will haunt us here too.
		 */
		if (errno == ENFILE || errno == EMFILE) {
			struct timeval evtpause = { 1, 0 };

			event_del(&control_state.ev);
			evtimer_add(&control_state.evt, &evtpause);
		} else if (errno != EWOULDBLOCK && errno != EINTR &&
		    errno != ECONNABORTED)
			log_warn("control_accept: accept");
		return;
	}

	session_socket_blockmode(connfd, BM_NONBLOCK);

	if ((c = calloc(1, sizeof(struct ctl_conn))) == NULL) {
		log_warn("control_accept");
		close(connfd);
		return;
	}

	imsg_init(&c->iev.ibuf, connfd);
	c->iev.handler = control_dispatch_imsg;
	c->iev.events = EV_READ;
	event_set(&c->iev.ev, c->iev.ibuf.fd, c->iev.events,
	    c->iev.handler, &c->iev);
	event_add(&c->iev.ev, NULL);

	TAILQ_INSERT_TAIL(&ctl_conns, c, entry);
}
Example #21
0
struct tmuxpeer *
proc_add_peer(struct tmuxproc *tp, int fd,
    void (*dispatchcb)(struct imsg *, void *), void *arg)
{
	struct tmuxpeer	*peer;

	peer = xcalloc(1, sizeof *peer);
	peer->parent = tp;

	peer->dispatchcb = dispatchcb;
	peer->arg = arg;

	imsg_init(&peer->ibuf, fd);
	event_set(&peer->event, fd, EV_READ, proc_event_cb, peer);

	log_debug("add peer %p: %d (%p)", peer, fd, arg);

	proc_update_event(peer);
	return (peer);
}
Example #22
0
int
snmp_getsock(struct imsgev *iev)
{
	struct imsg	 imsg;
	int		 n, s = -1, done = 0;

	imsg_compose_event(iev, IMSG_SNMPSOCK, 0, 0, -1, NULL, 0);
	imsg_flush(&iev->ibuf);

	while (!done) {
		if ((n = imsg_read(&iev->ibuf)) == -1)
			fatal("snmp_getsock: failed to read imsg");
		if (n == 0)
			fatal("snmp_getsock: pipe closed");
		while (!done) {
			if ((n = imsg_get(&iev->ibuf, &imsg)) == -1)
				fatal("snmp_getsock: failed to get imsg");
			if (n == 0)
				break;
			done = 1;
			switch (imsg.hdr.type) {
			case IMSG_SNMPSOCK:
				s = imsg.fd;
				break;
			default:
				break;
			}
			imsg_free(&imsg);
		}
	}

	if (s != -1) {
		log_debug("%s: got new snmp socket %d", __func__, s);
		if (iev_snmp == NULL && (iev_snmp = (struct imsgev *)
		    calloc(1, sizeof(struct imsgev))) == NULL)
			fatal("snmp_getsock: calloc");
		imsg_init(&iev_snmp->ibuf, s);
	}

	return (s);
}
Example #23
0
static int
m_priv_iked_imsg(u_int cmd)
{
	struct sockaddr_un	 sun;
	int			 fd = -1, ret = -1;
	struct imsgbuf		 ibuf;

	if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
		log_err("m_priv_iked_imsg: socket");
		goto out;
	}

	bzero(&sun, sizeof(sun));
	sun.sun_family = AF_UNIX;
	strlcpy(sun.sun_path, IKED_SOCKET, sizeof(sun.sun_path));

	if (connect(fd, (struct sockaddr *)&sun, sizeof(sun)) == -1) {
		log_err("m_priv_iked_imsg: connect");
		goto out;				
	}

	imsg_init(&ibuf, fd);
	if (imsg_compose(&ibuf, cmd, 0, 0, -1, NULL, 0) == -1) {
		log_err("m_priv_iked_imsg: compose");
		goto err;
	}
	if (imsg_flush(&ibuf) == -1) {
		log_err("m_priv_iked_imsg: flush");
		goto err;
	}

	ret = 0;
 err:
	imsg_clear(&ibuf);
 out:
	if (fd != -1)
		close(fd);

	return (ret);
}
Example #24
0
File: proc.c Project: koue/httpd
/* Inter-connect all process except with ourself. */
void
proc_connect(struct privsep *ps)
{
	unsigned int		 src, i, j;
	struct privsep_pipes	*pp;
	struct imsgev		*iev;

	/* Listen on appropriate pipes. */
	src = privsep_process;
	pp = &ps->ps_pipes[src][ps->ps_instance];

	for (i = 0; i < PROC_MAX; i++) {
		/* Don't listen to ourself. */
		if (i == src)
			continue;

		for (j = 0; j < ps->ps_instances[i]; j++) {
			if (pp->pp_pipes[i][j] == -1)
				continue;

			iev = &ps->ps_ievs[i][j];
			imsg_init(&iev->ibuf, pp->pp_pipes[i][j]);
			event_set(&iev->ev, iev->ibuf.fd, iev->events,
			    iev->handler, iev->data);
			event_add(&iev->ev, NULL);
		}
	}

	/* Exchange pipes between process. */
	for (i = 0; i < PROC_MAX; i++) {
		/* Parent is already connected with everyone. */
		if (i == PROC_PARENT)
			continue;

		for (j = 0; j < ps->ps_instances[i]; j++)
			proc_connectpeer(ps, i, j, &ps->ps_pipes[i][j]);
	}
}
Example #25
0
/* ARGSUSED */
static void
control_accept(int listenfd, short event, void *arg)
{
	int			 connfd;
	socklen_t		 len;
	struct sockaddr_un	 sun;
	struct ctl_conn		*c;

	if (available_fds(CONTROL_FD_RESERVE))
		goto pause;

	len = sizeof(sun);
	if ((connfd = accept(listenfd, (struct sockaddr *)&sun, &len)) == -1) {
		if (errno == ENFILE || errno == EMFILE)
			goto pause;
		if (errno == EINTR || errno == ECONNABORTED)
			return;
		fatal("control_accept: accept");
	}

	session_socket_blockmode(connfd, BM_NONBLOCK);

	c = xcalloc(1, sizeof(*c), "control_accept");
	imsg_init(&c->iev.ibuf, connfd);
	c->iev.handler = control_dispatch_ext;
	c->iev.events = EV_READ;
	event_set(&c->iev.ev, c->iev.ibuf.fd, c->iev.events,
	    c->iev.handler, NULL);
	event_add(&c->iev.ev, NULL);
	TAILQ_INSERT_TAIL(&ctl_conns, c, entry);

	stat_backend->increment("control.session", 1);
	return;

pause:
	log_warnx("ctl client limit hit, disabling new connections");
	event_del(&control_state.ev);
}
Example #26
0
void
config_peers(struct peer *p, uint peercount)
{
	int	count;
	uint	src;
	uint	dst;
	uint	i;
	/*
	 * listen on appropriate pipes
	 */
	for (i = 0; i < peercount; i++) {

		src = smtpd_process;
		dst = p[i].id;

		if (dst == smtpd_process)
			fatal("config_peers: cannot peer with oneself");
		
		env->sc_ievs[dst] = xcalloc(env->sc_instances[dst],
		    sizeof(struct imsgev), "config_peers");

		for (count = 0; count < env->sc_instances[dst]; count++) {
			imsg_init(&(env->sc_ievs[dst][count].ibuf),
			    env->sc_pipes[src][dst][count]);
			env->sc_ievs[dst][count].handler =  p[i].cb;
			env->sc_ievs[dst][count].events = EV_READ;
			env->sc_ievs[dst][count].proc = dst;
			env->sc_ievs[dst][count].data = &env->sc_ievs[dst][count];

			event_set(&(env->sc_ievs[dst][count].ev),
			    env->sc_ievs[dst][count].ibuf.fd,
			    env->sc_ievs[dst][count].events,
			    env->sc_ievs[dst][count].handler,
			    env->sc_ievs[dst][count].data);
			event_add(&(env->sc_ievs[dst][count].ev), NULL);
		}
	}
}
Example #27
0
int
main(int argc, char *argv[])
{
	struct sockaddr_un	 sun;
	struct parse_result	*res;
	struct imsg		 imsg;
	int			 ctl_sock;
	int			 done = 0;
	int			 n;
	int			 ch;
	const char		*sock = SNMPD_SOCKET;

	if ((env = calloc(1, sizeof(struct snmpd))) == NULL)
		err(1, "calloc");
	gettimeofday(&env->sc_starttime, NULL);

	while ((ch = getopt(argc, argv, "ns:")) != -1) {
		switch (ch) {
		case 'n':
			env->sc_flags |= SNMPD_F_NONAMES;
			break;
		case 's':
			sock = optarg;
			break;
		default:
			usage();
			/* NOTREACHED */
		}
	}
	argc -= optind;
	argv += optind;

	smi_init();

	/* parse options */
	if ((res = parse(argc, argv)) == NULL)
		exit(1);

	switch (res->action) {
	case NONE:
		usage();
		break;
	case SHOW_MIB:
		show_mib();
		break;
	case WALK:
	case GET:
	case BULKWALK:
		snmpclient(res);
		break;
	default:
		goto connect;
	}

	free(env);
	return (0);

 connect:
	/* connect to snmpd control socket */
	if ((ctl_sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
		err(1, "socket");

	bzero(&sun, sizeof(sun));
	sun.sun_family = AF_UNIX;
	strlcpy(sun.sun_path, sock, sizeof(sun.sun_path));
 reconnect:
	if (connect(ctl_sock, (struct sockaddr *)&sun, sizeof(sun)) == -1) {
		/* Keep retrying if running in monitor mode */
		if (res->action == MONITOR &&
		    (errno == ENOENT || errno == ECONNREFUSED)) {
			usleep(100);
			goto reconnect;
		}
		err(1, "connect: %s", sock);
	}

	imsg_init(&ibuf, ctl_sock);
	done = 0;

	/* process user request */
	switch (res->action) {
	case MONITOR:
		imsg_compose(&ibuf, IMSG_CTL_NOTIFY, 0, 0, -1, NULL, 0);
		break;
	case NONE:
	case SHOW_MIB:
	case WALK:
	case GET:
	case BULKWALK:
		break;
	case TRAP:
		/* explicitly downgrade the socket */
		imsg_compose(&ibuf, IMSG_SNMP_AGENTX, 0, 0, -1, NULL, 0);
		break;
	}

	while (ibuf.w.queued)
		if (msgbuf_write(&ibuf.w) <= 0 && errno != EAGAIN)
			err(1, "write error");

	while (!done) {
		if ((n = imsg_read(&ibuf)) == -1)
			errx(1, "imsg_read error");
		if (n == 0)
			errx(1, "pipe closed");

		while (!done) {
			if ((n = imsg_get(&ibuf, &imsg)) == -1)
				errx(1, "imsg_get error");
			if (n == 0)
				break;
			switch (res->action) {
			case MONITOR:
				done = monitor(&imsg);
				break;
			case TRAP:
				if (imsg.hdr.type == IMSG_CTL_OK) {
					snmpctl_trap(ctl_sock, res);
					done = 1;
				} else
					errx(1, "snmpd refused connection");
				break;
			case NONE:
			case SHOW_MIB:
			case WALK:
			case GET:
			case BULKWALK:
				break;
			}
			imsg_free(&imsg);
		}
	}
	close(ctl_sock);

	return (0);
}
Example #28
0
struct imsgbuf *
client_init(char *path, int cmdflags, int flags)
{
	struct sockaddr_un	sa;
	size_t			size;
	int			fd, mode;
#ifdef HAVE_SETPROCTITLE
	char		        rpathbuf[MAXPATHLEN];
#endif

#ifdef HAVE_SETPROCTITLE
	if (realpath(path, rpathbuf) == NULL)
		strlcpy(rpathbuf, path, sizeof rpathbuf);
	setproctitle("client (%s)", rpathbuf);
#endif

	memset(&sa, 0, sizeof sa);
	sa.sun_family = AF_UNIX;
	size = strlcpy(sa.sun_path, path, sizeof sa.sun_path);
	if (size >= sizeof sa.sun_path) {
		errno = ENAMETOOLONG;
		goto not_found;
	}

	if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
		fatal("socket failed");

	if (connect(fd, (struct sockaddr *) &sa, SUN_LEN(&sa)) == -1) {
		if (!(cmdflags & CMD_STARTSERVER))
			goto not_found;
		switch (errno) {
		case ECONNREFUSED:
			if (unlink(path) != 0)
				goto not_found;
			/* FALLTHROUGH */
		case ENOENT:
			if ((fd = server_start(path)) == -1)
				goto start_failed;
			goto server_started;
		}
		goto not_found;
	}

server_started:
	if ((mode = fcntl(fd, F_GETFL)) == -1)
		fatal("fcntl failed");
	if (fcntl(fd, F_SETFL, mode|O_NONBLOCK) == -1)
		fatal("fcntl failed");
	if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1)
		fatal("fcntl failed");
	imsg_init(&client_ibuf, fd);

	if (cmdflags & CMD_SENDENVIRON)
		client_send_environ();
	if (isatty(STDIN_FILENO))
		client_send_identify(flags);

	return (&client_ibuf);

start_failed:
	log_warnx("server failed to start");
	return (NULL);

not_found:
	log_warn("server not found");
	return (NULL);
}
Example #29
0
void
mproc_init(struct mproc *p, int fd)
{
	imsg_init(&p->imsgbuf, fd);
}
Example #30
0
int
main(int argc, char *argv[])
{
	struct sockaddr_un	 sun;
	struct parse_result	*res;
	struct imsg		 imsg;
	int			 ctl_sock;
	int			 done = 1;
	int			 n;
	int			 ch;
	int			 v = 0;
	int			 quiet = 0;
	const char		*sock = IKED_SOCKET;

	while ((ch = getopt(argc, argv, "qs:")) != -1) {
		switch (ch) {
		case 'q':
			quiet = 1;
			break;
		case 's':
			sock = optarg;
			break;
		default:
			usage();
			/* NOTREACHED */
		}
	}
	argc -= optind;
	argv += optind;

	/* parse options */
	if ((res = parse(argc, argv)) == NULL)
		exit(1);

	res->quiet = quiet;

	switch (res->action) {
	case CA_CREATE:
	case CA_DELETE:
	case CA_INSTALL:
	case CA_EXPORT:
	case CA_CERT_CREATE:
	case CA_CLIENT:
	case CA_SERVER:
	case CA_OCSP:
	case CA_CERT_DELETE:
	case CA_CERT_INSTALL:
	case CA_CERT_EXPORT:
	case CA_CERT_REVOKE:
	case SHOW_CA:
	case SHOW_CA_CERTIFICATES:
	case CA_KEY_CREATE:
	case CA_KEY_DELETE:
	case CA_KEY_INSTALL:
	case CA_KEY_IMPORT:
	case CA_SUBCA_CREATE:
	case CA_SUBCA_REVOKE:
		if (pledge("stdio proc exec rpath wpath cpath fattr tty", NULL)
		    == -1)
			err(1, "pledge");
		ca_opt(res);
		break;
	case NONE:
		usage();
		break;
	default:
		goto connect;
	}

	return (0);

 connect:
	/* connect to iked control socket */
	if ((ctl_sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
		err(1, "socket");

	bzero(&sun, sizeof(sun));
	sun.sun_family = AF_UNIX;
	strlcpy(sun.sun_path, sock, sizeof(sun.sun_path));
 reconnect:
	if (connect(ctl_sock, (struct sockaddr *)&sun, sizeof(sun)) == -1) {
		/* Keep retrying if running in monitor mode */
		if (res->action == MONITOR &&
		    (errno == ENOENT || errno == ECONNREFUSED)) {
			usleep(100);
			goto reconnect;
		}
		err(1, "connect: %s", sock);
	}

	if (pledge("stdio", NULL) == -1)
		err(1, "pledge");

	if (res->ibuf != NULL)
		ibuf = res->ibuf;
	else
		if ((ibuf = malloc(sizeof(struct imsgbuf))) == NULL)
			err(1, "malloc");
	imsg_init(ibuf, ctl_sock);

	/* process user request */
	switch (res->action) {
	case RESETALL:
		v = RESET_ALL;
		break;
	case RESETCA:
		v = RESET_CA;
		break;
	case RESETPOLICY:
		v = RESET_POLICY;
		break;
	case RESETSA:
		v = RESET_SA;
		break;
	case RESETUSER:
		v = RESET_USER;
		break;
	case LOG_VERBOSE:
		v = 2;
		break;
	case LOG_BRIEF:
	default:
		v = 0;
		break;
	}

	switch (res->action) {
	case NONE:
		usage();
		/* NOTREACHED */
		break;
	case RESETALL:
	case RESETCA:
	case RESETPOLICY:
	case RESETSA:
	case RESETUSER:
		imsg_compose(ibuf, IMSG_CTL_RESET, 0, 0, -1, &v, sizeof(v));
		printf("reset request sent.\n");
		break;
	case LOAD:
		imsg_compose(ibuf, IMSG_CTL_RELOAD, 0, 0, -1,
		    res->path, strlen(res->path));
		break;
	case RELOAD:
		imsg_compose(ibuf, IMSG_CTL_RELOAD, 0, 0, -1, NULL, 0);
		break;
	case MONITOR:
		imsg_compose(ibuf, IMSG_CTL_NOTIFY, 0, 0, -1, NULL, 0);
		done = 0;
		break;
	case COUPLE:
		imsg_compose(ibuf, IMSG_CTL_COUPLE, 0, 0, -1, NULL, 0);
		break;
	case DECOUPLE:
		imsg_compose(ibuf, IMSG_CTL_DECOUPLE, 0, 0, -1, NULL, 0);
		break;
	case ACTIVE:
		imsg_compose(ibuf, IMSG_CTL_ACTIVE, 0, 0, -1, NULL, 0);
		break;
	case PASSIVE:
		imsg_compose(ibuf, IMSG_CTL_PASSIVE, 0, 0, -1, NULL, 0);
		break;
	case LOG_VERBOSE:
	case LOG_BRIEF:
		imsg_compose(ibuf, IMSG_CTL_VERBOSE, 0, 0, -1, &v, sizeof(v));
		printf("logging request sent.\n");
		break;
	default:
		break;
	}

	while (ibuf->w.queued)
		if (msgbuf_write(&ibuf->w) <= 0 && errno != EAGAIN)
			err(1, "write error");

	while (!done) {
		if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN)
			errx(1, "imsg_read error");
		if (n == 0)
			errx(1, "pipe closed");

		while (!done) {
			if ((n = imsg_get(ibuf, &imsg)) == -1)
				errx(1, "imsg_get error");
			if (n == 0)
				break;
			switch (res->action) {
			case MONITOR:
				done = monitor(&imsg);
				break;
			default:
				break;
			}
			imsg_free(&imsg);
		}
	}
	close(ctl_sock);
	free(ibuf);

	return (0);
}