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); } }
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); }
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); }
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); }
/* 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); } }
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); }
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); }
/* 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); }
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); }
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); }
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); }
/* 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); }
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); }
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); }
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); } }
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; } }
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); }
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); }
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; }
/* 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); }
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); }
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); }
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); }
/* 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]); } }
/* 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); }
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); } } }
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); }
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); }
void mproc_init(struct mproc *p, int fd) { imsg_init(&p->imsgbuf, fd); }
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); }