Exemple #1
0
void
imsgev_dispatch(int fd, short ev, void *humppa)
{
	struct imsgev	*iev = humppa;
	struct imsgbuf	*ibuf = &iev->ibuf;
	struct imsg	 imsg;
	ssize_t		 n;

	iev->events = 0;

	if (ev & EV_READ) {
		if ((n = imsg_read(ibuf)) == -1) {
			imsgev_disconnect(iev, IMSGEV_EREAD);
			return;
		}
		if (n == 0) {
			/*
			 * Connection is closed for reading, and we assume
			 * it is also closed for writing, so we error out
			 * if write data is pending.
			 */
			imsgev_disconnect(iev,
			    (iev->ibuf.w.queued) ? IMSGEV_EWRITE : IMSGEV_DONE);
			return;
		}
	}

	if (ev & EV_WRITE) {
		/*
		 * We wanted to write data out but the connection is either
		 * closed, or some error occured. Both case are not recoverable
		 * from the imsg perspective, so we treat it as a WRITE error.
		 */
		if ((n = msgbuf_write(&ibuf->w)) != 0) {
			imsgev_disconnect(iev, IMSGEV_EWRITE);
			return;
		}
	}

	while (iev->terminate == 0) {
		if ((n = imsg_get(ibuf, &imsg)) == -1) {
			imsgev_disconnect(iev, IMSGEV_EIMSG);
			return;
		}
		if (n == 0)
			break;
		iev->callback(iev, IMSGEV_IMSG, &imsg);
		imsg_free(&imsg);
	}

	if (iev->terminate && iev->ibuf.w.queued == 0) {
		imsgev_disconnect(iev, IMSGEV_DONE);
		return;
	}

	imsgev_add(iev);
}
Exemple #2
0
static void
proc_event_cb(unused int fd, short events, void *arg)
{
	struct tmuxpeer	*peer = arg;
	ssize_t		 n;
	struct imsg	 imsg;
	int		 v;

	if (!(peer->flags & PEER_BAD) && (events & EV_READ)) {
		if ((n = imsg_read(&peer->ibuf)) == -1 || n == 0) {
			peer->dispatchcb(NULL, peer->arg);
			return;
		}
		for (;;) {
			if ((n = imsg_get(&peer->ibuf, &imsg)) == -1) {
				peer->dispatchcb(NULL, peer->arg);
				return;
			}
			if (n == 0)
				break;
			log_debug("peer %p message %d", peer, imsg.hdr.type);

			v = imsg.hdr.peerid;
			if (imsg.hdr.type != MSG_VERSION &&
			    v != PROTOCOL_VERSION) {
				log_debug("peer %p bad version %d", peer, v);

				proc_send(peer, MSG_VERSION, -1, NULL, 0);
				peer->flags |= PEER_BAD;

				if (imsg.fd != -1)
					close(imsg.fd);
				imsg_free(&imsg);
				break;
			}

			peer->dispatchcb(&imsg, peer->arg);
			imsg_free(&imsg);
		}
	}

	if (events & EV_WRITE) {
		if (msgbuf_write(&peer->ibuf.w) <= 0 && errno != EAGAIN) {
			peer->dispatchcb(NULL, peer->arg);
			return;
		}
	}

	if ((peer->flags & PEER_BAD) && peer->ibuf.w.queued == 0) {
		peer->dispatchcb(NULL, peer->arg);
		return;
	}

	proc_update_event(peer);
}
Exemple #3
0
static void
proc_event_cb(__unused int fd, short events, void *arg)
{
	struct tmuxpeer	*peer = arg;
	ssize_t		 n;
	struct imsg	 imsg;

	if (!(peer->flags & PEER_BAD) && (events & EV_READ)) {
		if (((n = imsg_read(&peer->ibuf)) == -1 && errno != EAGAIN) ||
		    n == 0) {
			peer->dispatchcb(NULL, peer->arg);
			return;
		}
		for (;;) {
			if ((n = imsg_get(&peer->ibuf, &imsg)) == -1) {
				peer->dispatchcb(NULL, peer->arg);
				return;
			}
			if (n == 0)
				break;
			log_debug("peer %p message %d", peer, imsg.hdr.type);

			if (peer_check_version(peer, &imsg) != 0) {
				if (imsg.fd != -1)
					close(imsg.fd);
				imsg_free(&imsg);
				break;
			}

			peer->dispatchcb(&imsg, peer->arg);
			imsg_free(&imsg);
		}
	}

	if (events & EV_WRITE) {
		if (msgbuf_write(&peer->ibuf.w) <= 0 && errno != EAGAIN) {
			peer->dispatchcb(NULL, peer->arg);
			return;
		}
	}

	if ((peer->flags & PEER_BAD) && peer->ibuf.w.queued == 0) {
		peer->dispatchcb(NULL, peer->arg);
		return;
	}

	proc_update_event(peer);
}
Exemple #4
0
/*
 * Check readability not to spin before calling imsg_read(3).  Wait 'millisec'
 * until it becomes readable.
 */
int
imsg_sync_read(struct imsgbuf *ibuf, int millisec)
{
	struct pollfd	 fds[1];
	int		 retval;

	fds[0].fd = ibuf->fd;
	fds[0].events = POLLIN;
	retval = poll(fds, 1, millisec);
	if (retval == 0) {
		errno = EAGAIN;
		return (-1);
	}
	if (retval > 0 && (fds[0].revents & POLLIN) != 0)
		return imsg_read(ibuf);

	return (-1);
}
Exemple #5
0
void service_exec(struct imsgbuf* ibuf) {
    pledge("stdio proc exec", NULL);

    while(1) {
        int n = imsg_read(ibuf);
        if(n < 0) { die("Error reading ibuf"); }
        if(n == 0) { break; }

        while(1) {
            struct imsg imsg;
            n = imsg_get(ibuf, &imsg);
            if(n <= 0) { break; }

            dispatch(ibuf, imsg.hdr.type, (char* const)imsg.data);
            imsg_free(&imsg);
        }
    }
}
Exemple #6
0
/*
 * The purpose of this function is to handle requests sent by the
 * root privileged process.
 */
int
tnt_dispatch_imsg(struct imsg_data *data) {
    struct imsg imsg;
    ssize_t n;
    int device_fd;
    struct imsgbuf *ibuf = data->ibuf;

    n = imsg_read(ibuf);
    if (n == -1) {
        log_warnx("loose some imsgs");
        imsg_clear(ibuf);
        return -1;
    }

    if (n == 0) {
        log_warnx("pipe closed");
        return -1;
    }

    /* Loops through the queue created by imsg_read */
    while ((n = imsg_get(ibuf, &imsg)) != 0 && n != -1) {
        switch (imsg.hdr.type) {
            case IMSG_CREATE_DEV:
                device_fd = imsg.fd;
                log_info("receive IMSG_CREATE_DEV: fd %i", device_fd);

                server_set_device(data->server, device_fd);

                /* directly ask to configure the tun device */
                imsg_compose(ibuf, IMSG_SET_IP, 0, 0, -1,
                             serv_opts.addr , strlen(serv_opts.addr));
                break;
            default:
                break;
        }
        imsg_free(&imsg);
    }
    if (n == -1) {
        log_warnx("imsg_get");
        return -1;
    }
    return 0;
}
Exemple #7
0
static int
open_connection(void)
{
	struct imsg	imsg;
	int		fd;
	int		n;

	imsg_compose(ibuf, IMSG_SMTP_ENQUEUE, 0, 0, -1, NULL, 0);

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

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

		if ((n = imsg_get(ibuf, &imsg)) == -1)
			errx(1, "imsg_get error");
		if (n == 0)
			continue;

		switch (imsg.hdr.type) {
		case IMSG_CTL_OK:
			break;
		case IMSG_CTL_FAIL:
			errx(1, "server disallowed submission request");
		default:
			errx(1, "unexpected imsg reply type");
		}

		fd = imsg.fd;
		imsg_free(&imsg);

		break;
	}

	return fd;
}
Exemple #8
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);
}
Exemple #9
0
static void
table_proc_call(struct table_proc_priv *p)
{
	ssize_t	n;

	if (imsg_flush(&p->ibuf) == -1) {
		log_warn("warn: table-proc: imsg_flush");
		fatalx("table-proc: exiting");
	}

	while (1) {
		if ((n = imsg_get(&p->ibuf, &imsg)) == -1) {
			log_warn("warn: table-proc: imsg_get");
			break;
		}
		if (n) {
			rlen = imsg.hdr.len - IMSG_HEADER_SIZE;
			rdata = imsg.data;

			if (imsg.hdr.type != PROC_TABLE_OK) {
				log_warnx("warn: table-proc: bad response");
				break;
			}
			return;
		}

		if ((n = imsg_read(&p->ibuf)) == -1) {
			log_warn("warn: table-proc: imsg_read");
			break;
		}

		if (n == 0) {
			log_warnx("warn: table-proc: pipe closed");
			break;
		}
	}

	fatalx("table-proc: exiting");
}
Exemple #10
0
static void
scheduler_proc_call(void)
{
	ssize_t	n;

	if (imsg_flush(&ibuf) == -1) {
		log_warn("warn: scheduler-proc: imsg_flush");
		fatalx("scheduler-proc: exiting");
	}

	while (1) {
		if ((n = imsg_get(&ibuf, &imsg)) == -1) {
			log_warn("warn: scheduler-proc: imsg_get");
			break;
		}
		if (n) {
			rlen = imsg.hdr.len - IMSG_HEADER_SIZE;
			rdata = imsg.data;

			if (imsg.hdr.type != PROC_SCHEDULER_OK) {
				log_warnx("warn: scheduler-proc: bad response");
				break;
			}
			return;
		}

		if ((n = imsg_read(&ibuf)) == -1) {
			log_warn("warn: scheduler-proc: imsg_read");
			break;
		}

		if (n == 0) {
			log_warnx("warn: scheduler-proc: pipe closed");
			break;
		}
	}

	fatalx("scheduler-proc: exiting");
}
Exemple #11
0
int32_t service_pop(struct imsgbuf* ibuf, char* buf, size_t buf_len) {
    if(buf != NULL) { buf[0] = '\0'; }

    int n = imsg_read(ibuf);
    if(n < 0) { die("Error reading"); }
    if(n == 0) { return -1; }

    struct imsg imsg;
    n = imsg_get(ibuf, &imsg);
    if(n <= 0) { die("Got no message"); }

    if(buf != NULL && imsg.data != NULL) {
        // We should only ever pass strings, but just to be safe, always
        // make sure that the buffer we return is nul-terminated.
        const size_t data_len = imsg.hdr.len - IMSG_HEADER_SIZE;
        strlcpy(buf, imsg.data, min(buf_len, data_len));
    }

    u_int32_t type = imsg.hdr.type;
    imsg_free(&imsg);
    return type;
}
Exemple #12
0
/* ARGSUSED */
void
control_dispatch_ext(int fd, short event, void *arg)
{
	struct ctl_conn		*c;
	struct imsg		 imsg;
	int			 n;
	uid_t			 euid;
	gid_t			 egid;

	if (getpeereid(fd, &euid, &egid) == -1)
		fatal("getpeereid");

	if ((c = control_connbyfd(fd)) == NULL) {
		log_warn("control_dispatch_ext: fd %d: not found", fd);
		return;
	}

	if (event & EV_READ) {
		if ((n = imsg_read(&c->iev.ibuf)) == -1 || n == 0) {
			control_close(fd);
			return;
		}
	}

	if (event & EV_WRITE) {
		if (msgbuf_write(&c->iev.ibuf.w) < 0) {
			control_close(fd);
			return;
		}
	}

	for (;;) {
		if ((n = imsg_get(&c->iev.ibuf, &imsg)) == -1) {
			control_close(fd);
			return;
		}

		if (n == 0)
			break;

		switch (imsg.hdr.type) {
		case IMSG_SMTP_ENQUEUE:
			if (env->sc_flags & (SMTPD_SMTP_PAUSED |
			    SMTPD_CONFIGURING | SMTPD_EXITING)) {
				imsg_compose_event(&c->iev, IMSG_CTL_FAIL, 0, 0, -1,
					NULL, 0);
				break;
			}
			imsg_compose_event(env->sc_ievs[PROC_SMTP],
			    IMSG_SMTP_ENQUEUE, fd, 0, -1, &euid, sizeof(euid));
			break;
		case IMSG_STATS:
			if (euid)
				goto badcred;
			imsg_compose_event(&c->iev, IMSG_STATS, 0, 0, -1,
			    env->stats, sizeof(struct stats));
			break;
		case IMSG_CTL_SHUTDOWN:
			/* NEEDS_FIX */
			log_debug("received shutdown request");

			if (euid)
				goto badcred;

			if (env->sc_flags & SMTPD_EXITING) {
				imsg_compose_event(&c->iev, IMSG_CTL_FAIL, 0, 0, -1,
					NULL, 0);
				break;
			}
			env->sc_flags |= SMTPD_EXITING;
			imsg_compose_event(&c->iev, IMSG_CTL_OK, 0, 0, -1, NULL, 0);
			break;
		case IMSG_CTL_VERBOSE: {
			int verbose;

			if (euid)
				goto badcred;

			if (IMSG_DATA_SIZE(&imsg) != sizeof(verbose))
				goto badcred;

			memcpy(&verbose, imsg.data, sizeof(verbose));
			log_verbose(verbose);
			imsg_compose_event(env->sc_ievs[PROC_PARENT], IMSG_CTL_VERBOSE,
			    0, 0, -1, &verbose, sizeof(verbose));
			imsg_compose_event(&c->iev, IMSG_CTL_OK, 0, 0, -1, NULL, 0);
			break;
		}
		case IMSG_QUEUE_PAUSE_MDA:
			if (euid)
				goto badcred;

			if (env->sc_flags & SMTPD_MDA_PAUSED) {
				imsg_compose_event(&c->iev, IMSG_CTL_FAIL, 0, 0, -1,
					NULL, 0);
				break;
			}
			env->sc_flags |= SMTPD_MDA_PAUSED;
			imsg_compose_event(env->sc_ievs[PROC_QUEUE],
			    IMSG_QUEUE_PAUSE_MDA, 0, 0, -1, NULL, 0);
			imsg_compose_event(&c->iev, IMSG_CTL_OK, 0, 0, -1, NULL, 0);
			break;
		case IMSG_QUEUE_PAUSE_MTA:
			if (euid)
				goto badcred;

			if (env->sc_flags & SMTPD_MTA_PAUSED) {
				imsg_compose_event(&c->iev, IMSG_CTL_FAIL, 0, 0, -1,
					NULL, 0);
				break;
			}
			env->sc_flags |= SMTPD_MTA_PAUSED;
			imsg_compose_event(env->sc_ievs[PROC_QUEUE],
			    IMSG_QUEUE_PAUSE_MTA, 0, 0, -1, NULL, 0);
			imsg_compose_event(&c->iev, IMSG_CTL_OK, 0, 0, -1, NULL, 0);
			break;
		case IMSG_SMTP_PAUSE:
			if (euid)
				goto badcred;

			if (env->sc_flags & SMTPD_SMTP_PAUSED) {
				imsg_compose_event(&c->iev, IMSG_CTL_FAIL, 0, 0, -1,
					NULL, 0);
				break;
			}
			env->sc_flags |= SMTPD_SMTP_PAUSED;
			imsg_compose_event(env->sc_ievs[PROC_SMTP], IMSG_SMTP_PAUSE,			
			    0, 0, -1, NULL, 0);
			imsg_compose_event(&c->iev, IMSG_CTL_OK, 0, 0, -1, NULL, 0);
			break;
		case IMSG_QUEUE_RESUME_MDA:
			if (euid)
				goto badcred;

			if (! (env->sc_flags & SMTPD_MDA_PAUSED)) {
				imsg_compose_event(&c->iev, IMSG_CTL_FAIL, 0, 0, -1,
					NULL, 0);
				break;
			}
			env->sc_flags &= ~SMTPD_MDA_PAUSED;
			imsg_compose_event(env->sc_ievs[PROC_QUEUE],
			    IMSG_QUEUE_RESUME_MDA, 0, 0, -1, NULL, 0);
			imsg_compose_event(&c->iev, IMSG_CTL_OK, 0, 0, -1, NULL, 0);
			break;
		case IMSG_QUEUE_RESUME_MTA:
			if (euid)
				goto badcred;

			if (!(env->sc_flags & SMTPD_MTA_PAUSED)) {
				imsg_compose_event(&c->iev, IMSG_CTL_FAIL, 0, 0, -1,
					NULL, 0);
				break;
			}
			env->sc_flags &= ~SMTPD_MTA_PAUSED;
			imsg_compose_event(env->sc_ievs[PROC_QUEUE],
			    IMSG_QUEUE_RESUME_MTA, 0, 0, -1, NULL, 0);
			imsg_compose_event(&c->iev, IMSG_CTL_OK, 0, 0, -1, NULL, 0);
			break;

		case IMSG_SMTP_RESUME:
			if (euid)
				goto badcred;

			if (!(env->sc_flags & SMTPD_SMTP_PAUSED)) {
				imsg_compose_event(&c->iev, IMSG_CTL_FAIL, 0, 0, -1,
					NULL, 0);
				break;
			}
			env->sc_flags &= ~SMTPD_SMTP_PAUSED;
			imsg_compose_event(env->sc_ievs[PROC_SMTP], IMSG_SMTP_RESUME,
			    0, 0, -1, NULL, 0);
			imsg_compose_event(&c->iev, IMSG_CTL_OK, 0, 0, -1, NULL, 0);
			break;

		case IMSG_RUNNER_SCHEDULE: {
			u_int64_t ullval;

			if (euid)
				goto badcred;

			ullval = *(u_int64_t *)imsg.data;

			imsg_compose_event(env->sc_ievs[PROC_RUNNER], IMSG_RUNNER_SCHEDULE,
			    0, 0, -1, &ullval, sizeof(ullval));

			imsg_compose_event(&c->iev, IMSG_CTL_OK, 0, 0, -1, NULL, 0);
			break;
		}

		case IMSG_RUNNER_REMOVE: {
			u_int64_t ullval;

			if (euid)
				goto badcred;

			ullval = *(u_int64_t *)imsg.data;

			imsg_compose_event(env->sc_ievs[PROC_RUNNER], IMSG_RUNNER_REMOVE,
			    0, 0, -1, &ullval, sizeof(ullval));

			imsg_compose_event(&c->iev, IMSG_CTL_OK, 0, 0, -1, NULL, 0);
			break;
		}
		default:
			log_debug("control_dispatch_ext: "
			    "error handling %s imsg",
			    imsg_to_str(imsg.hdr.type));
			break;
		}
		imsg_free(&imsg);
		continue;

badcred:
		imsg_compose_event(&c->iev, IMSG_CTL_FAIL, 0, 0, -1,
		    NULL, 0);
	}

	imsg_event_add(&c->iev);
}
Exemple #13
0
int
client_main(struct client_ctx *cctx)
{
	struct pollfd	 pfd;
	int		 n, nfds;

	siginit();

	logfile("client");

	/*
	 * imsg_read in the first client poll loop (before the terminal has
	 * been initialiased) may have read messages into the buffer after the
	 * MSG_READY switched to here. Process anything outstanding now so poll
	 * doesn't hang waiting for messages that have already arrived.
	 */
	if (client_msg_dispatch(cctx) != 0)
		goto out;

	for (;;) {
		if (sigterm)
			client_write_server(cctx, MSG_EXITING, NULL, 0);
		if (sigchld) {
			waitpid(WAIT_ANY, NULL, WNOHANG);
			sigchld = 0;
		}
		if (sigwinch)
			client_handle_winch(cctx);
		if (sigcont) {
			siginit();
			client_write_server(cctx, MSG_WAKEUP, NULL, 0);
			sigcont = 0;
		}

		pfd.fd = cctx->ibuf.fd;
		pfd.events = POLLIN;
		if (cctx->ibuf.w.queued > 0)
			pfd.events |= POLLOUT;

		if ((nfds = poll(&pfd, 1, INFTIM)) == -1) {
			if (errno == EAGAIN || errno == EINTR)
				continue;
			fatal("poll failed");
		}
		if (nfds == 0)
			continue;

		if (pfd.revents & (POLLERR|POLLHUP|POLLNVAL))
			fatalx("socket error");

		if (pfd.revents & POLLIN) {
			if ((n = imsg_read(&cctx->ibuf)) == -1 || n == 0) {
				cctx->exittype = CCTX_DIED;
				break;
			}
			if (client_msg_dispatch(cctx) != 0)
				break;
		}

		if (pfd.revents & POLLOUT) {
			if (msgbuf_write(&cctx->ibuf.w) < 0) {
				cctx->exittype = CCTX_DIED;
				break;
			}
		}
	}

out:
 	if (sigterm) {
 		printf("[terminated]\n");
 		return (1);
 	}
	switch (cctx->exittype) {
	case CCTX_DIED:
		printf("[lost server]\n");
		return (0);
	case CCTX_SHUTDOWN:
		printf("[server exited]\n");
		return (0);
	case CCTX_EXIT:
		if (cctx->errstr != NULL) {
			printf("[error: %s]\n", cctx->errstr);
			return (1);
		}
		printf("[exited]\n");
		return (0);
	case CCTX_DETACH:
		printf("[detached]\n");
		return (0);
	default:
		printf("[unknown error]\n");
		return (1);
	}
}
Exemple #14
0
/* ARGSUSED */
static void
control_dispatch_ext(int fd, short event, void *arg)
{
	struct ctl_conn		*c;
	struct imsg		 imsg;
	int			 n, verbose;
	uid_t			 euid;
	gid_t			 egid;
	uint64_t		 id;
	struct stat_kv		*kvp;
	char			*key;
	struct stat_value      	 val;
	size_t			 len;

	if (getpeereid(fd, &euid, &egid) == -1)
		fatal("getpeereid");

	if ((c = control_connbyfd(fd)) == NULL) {
		log_warn("control_dispatch_ext: fd %d: not found", fd);
		return;
	}

	if (event & EV_READ) {
		if ((n = imsg_read(&c->iev.ibuf)) == -1 || n == 0) {
			control_close(c);
			return;
		}
	}

	if (event & EV_WRITE) {
		if (msgbuf_write(&c->iev.ibuf.w) < 0) {
			control_close(c);
			return;
		}
	}

	for (;;) {
		if ((n = imsg_get(&c->iev.ibuf, &imsg)) == -1) {
			control_close(c);
			return;
		}

		if (n == 0)
			break;

		switch (imsg.hdr.type) {
		case IMSG_SMTP_ENQUEUE:
			if (env->sc_flags & (SMTPD_SMTP_PAUSED |
			    SMTPD_CONFIGURING | SMTPD_EXITING)) {
				imsg_compose_event(&c->iev, IMSG_CTL_FAIL, 0, 0, -1,
					NULL, 0);
				break;
			}
			imsg_compose_event(env->sc_ievs[PROC_SMTP],
			    IMSG_SMTP_ENQUEUE, fd, 0, -1, &euid, sizeof(euid));
			break;

		case IMSG_STATS:
			if (euid)
				goto badcred;
			imsg_compose_event(&c->iev, IMSG_STATS, 0, 0, -1, NULL, 0);
			break;

		case IMSG_STATS_GET:
			if (euid)
				goto badcred;
			kvp = imsg.data;
			if (! stat_backend->iter(&kvp->iter, &key, &val))
				kvp->iter = NULL;
			else {
				strlcpy(kvp->key, key, sizeof kvp->key);
				kvp->val = val;
			}
			imsg_compose_event(&c->iev, IMSG_STATS_GET, 0, 0, -1,
			    kvp, sizeof *kvp);
			break;

		case IMSG_CTL_SHUTDOWN:
			/* NEEDS_FIX */
			log_debug("received shutdown request");

			if (euid)
				goto badcred;

			if (env->sc_flags & SMTPD_EXITING) {
				imsg_compose_event(&c->iev, IMSG_CTL_FAIL, 0, 0,
				    -1, NULL, 0);
				break;
			}
			env->sc_flags |= SMTPD_EXITING;
			imsg_compose_event(&c->iev, IMSG_CTL_OK, 0, 0, -1,
			    NULL, 0);
			imsg_compose_event(env->sc_ievs[PROC_PARENT],
			    IMSG_CTL_SHUTDOWN, 0, 0, -1, NULL, 0);
			break;

		case IMSG_CTL_VERBOSE:
			if (euid)
				goto badcred;

			if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(verbose))
				goto badcred;

			memcpy(&verbose, imsg.data, sizeof(verbose));
			log_verbose(verbose);
			imsg_compose_event(env->sc_ievs[PROC_PARENT], IMSG_CTL_VERBOSE,
			    0, 0, -1, &verbose, sizeof(verbose));
			imsg_compose_event(&c->iev, IMSG_CTL_OK, 0, 0, -1, NULL, 0);
			break;

		case IMSG_QUEUE_PAUSE_MDA:
			if (euid)
				goto badcred;

			if (env->sc_flags & SMTPD_MDA_PAUSED) {
				imsg_compose_event(&c->iev, IMSG_CTL_FAIL, 0, 0, -1,
					NULL, 0);
				break;
			}
			log_info("mda paused");
			env->sc_flags |= SMTPD_MDA_PAUSED;
			imsg_compose_event(env->sc_ievs[PROC_QUEUE],
			    IMSG_QUEUE_PAUSE_MDA, 0, 0, -1, NULL, 0);
			imsg_compose_event(&c->iev, IMSG_CTL_OK, 0, 0, -1, NULL, 0);
			break;

		case IMSG_QUEUE_PAUSE_MTA:
			if (euid)
				goto badcred;

			if (env->sc_flags & SMTPD_MTA_PAUSED) {
				imsg_compose_event(&c->iev, IMSG_CTL_FAIL, 0, 0, -1,
					NULL, 0);
				break;
			}
			log_info("mta paused");
			env->sc_flags |= SMTPD_MTA_PAUSED;
			imsg_compose_event(env->sc_ievs[PROC_QUEUE],
			    IMSG_QUEUE_PAUSE_MTA, 0, 0, -1, NULL, 0);
			imsg_compose_event(&c->iev, IMSG_CTL_OK, 0, 0, -1, NULL, 0);
			break;

		case IMSG_SMTP_PAUSE:
			if (euid)
				goto badcred;

			if (env->sc_flags & SMTPD_SMTP_PAUSED) {
				imsg_compose_event(&c->iev, IMSG_CTL_FAIL, 0, 0, -1,
					NULL, 0);
				break;
			}
			log_info("smtp paused");
			env->sc_flags |= SMTPD_SMTP_PAUSED;
			imsg_compose_event(env->sc_ievs[PROC_SMTP], IMSG_SMTP_PAUSE,			
			    0, 0, -1, NULL, 0);
			imsg_compose_event(&c->iev, IMSG_CTL_OK, 0, 0, -1, NULL, 0);
			break;

		case IMSG_QUEUE_RESUME_MDA:
			if (euid)
				goto badcred;

			if (! (env->sc_flags & SMTPD_MDA_PAUSED)) {
				imsg_compose_event(&c->iev, IMSG_CTL_FAIL, 0, 0, -1,
					NULL, 0);
				break;
			}
			log_info("mda resumed");
			env->sc_flags &= ~SMTPD_MDA_PAUSED;
			imsg_compose_event(env->sc_ievs[PROC_QUEUE],
			    IMSG_QUEUE_RESUME_MDA, 0, 0, -1, NULL, 0);
			imsg_compose_event(&c->iev, IMSG_CTL_OK, 0, 0, -1, NULL, 0);
			break;

		case IMSG_QUEUE_RESUME_MTA:
			if (euid)
				goto badcred;

			if (!(env->sc_flags & SMTPD_MTA_PAUSED)) {
				imsg_compose_event(&c->iev, IMSG_CTL_FAIL, 0, 0, -1,
					NULL, 0);
				break;
			}
			log_info("mta resumed");
			env->sc_flags &= ~SMTPD_MTA_PAUSED;
			imsg_compose_event(env->sc_ievs[PROC_QUEUE],
			    IMSG_QUEUE_RESUME_MTA, 0, 0, -1, NULL, 0);
			imsg_compose_event(&c->iev, IMSG_CTL_OK, 0, 0, -1, NULL, 0);
			break;

		case IMSG_SMTP_RESUME:
			if (euid)
				goto badcred;

			if (!(env->sc_flags & SMTPD_SMTP_PAUSED)) {
				imsg_compose_event(&c->iev, IMSG_CTL_FAIL, 0, 0, -1,
					NULL, 0);
				break;
			}
			log_info("smtp resumed");
			env->sc_flags &= ~SMTPD_SMTP_PAUSED;
			imsg_compose_event(env->sc_ievs[PROC_SMTP], IMSG_SMTP_RESUME,
			    0, 0, -1, NULL, 0);
			imsg_compose_event(&c->iev, IMSG_CTL_OK, 0, 0, -1, NULL, 0);
			break;

		case IMSG_SCHEDULER_SCHEDULE:
			if (euid)
				goto badcred;

			id = *(uint64_t *)imsg.data;
			imsg_compose_event(env->sc_ievs[PROC_SCHEDULER],
			    IMSG_SCHEDULER_SCHEDULE, 0, 0, -1, &id, sizeof id);
			imsg_compose_event(&c->iev, IMSG_CTL_OK, 0, 0, -1,
			    NULL, 0);
			break;

		case IMSG_SCHEDULER_REMOVE:
			if (euid)
				goto badcred;

			id = *(uint64_t *)imsg.data;
			imsg_compose_event(env->sc_ievs[PROC_SCHEDULER],
			    IMSG_SCHEDULER_REMOVE, 0, 0, -1, &id, sizeof id);
			imsg_compose_event(&c->iev, IMSG_CTL_OK, 0, 0, -1,
			    NULL, 0);
			break;

		case IMSG_LKA_UPDATE_MAP:
			if (euid)
				goto badcred;

			/* map name too long */
			len = strlen(imsg.data);
			if (len >= MAX_LINE_SIZE)
				goto invalid;

			imsg_compose_event(env->sc_ievs[PROC_LKA], IMSG_LKA_UPDATE_MAP,
			    0, 0, -1, imsg.data, len + 1);
			break;

		default:
			log_debug("control_dispatch_ext: "
			    "error handling %s imsg",
			    imsg_to_str(imsg.hdr.type));
			break;
		}
		imsg_free(&imsg);
		continue;

badcred:
invalid:
		imsg_compose_event(&c->iev, IMSG_CTL_FAIL, 0, 0, -1,
		    NULL, 0);
	}

	imsg_event_add(&c->iev);
}
Exemple #15
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);
}
Exemple #16
0
int
main(int argc, char *argv[])
{
	struct sockaddr_un	sun;
	struct parse_result	*res = NULL;
	struct imsg		imsg;
	struct smtpd		smtpd;
	int			ctl_sock;
	int			done = 0;
	int			n, verbose = 0;

	/* parse options */
	if (strcmp(__progname, "sendmail") == 0 || strcmp(__progname, "send-mail") == 0)
		sendmail = 1;
	else if (strcmp(__progname, "mailq") == 0) {
		if (geteuid())
			errx(1, "need root privileges");
		setup_env(&smtpd);
		show_queue(0);
		return 0;
	} else if (strcmp(__progname, "smtpctl") == 0) {

		/* check for root privileges */
		if (geteuid())
			errx(1, "need root privileges");

		setup_env(&smtpd);

		if ((res = parse(argc - 1, argv + 1)) == NULL)
			exit(1);

		/* handle "disconnected" commands */
		switch (res->action) {
		case SHOW_QUEUE:
			show_queue(0);
			break;
		case SHOW_RUNQUEUE:
			break;
		default:
			goto connected;
		}
		return 0;
	} else
		errx(1, "unsupported mode");

connected:
	/* connect to smtpd 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, SMTPD_SOCKET, sizeof(sun.sun_path));
	if (connect(ctl_sock, (struct sockaddr *)&sun, sizeof(sun)) == -1) {
		if (sendmail)
			return enqueue_offline(argc, argv);
		err(1, "connect: %s", SMTPD_SOCKET);
	}

	if ((ibuf = calloc(1, sizeof(struct imsgbuf))) == NULL)
		err(1, NULL);
	imsg_init(ibuf, ctl_sock);

	if (sendmail)
		return enqueue(argc, argv);

	/* process user request */
	switch (res->action) {
	case NONE:
		usage();
		/* not reached */

	case SCHEDULE:
	case REMOVE: {
		u_int64_t ulval;
		char *ep;

		errno = 0;
		ulval = strtoull(res->data, &ep, 16);
		if (res->data[0] == '\0' || *ep != '\0')
			errx(1, "invalid msgid/evpid");
		if (errno == ERANGE && ulval == ULLONG_MAX)
			errx(1, "invalid msgid/evpid");
		if (ulval == 0)
			errx(1, "invalid msgid/evpid");

		if (res->action == SCHEDULE)
			imsg_compose(ibuf, IMSG_SCHEDULER_SCHEDULE, 0, 0, -1, &ulval,
			    sizeof(ulval));
		if (res->action == REMOVE)
			imsg_compose(ibuf, IMSG_SCHEDULER_REMOVE, 0, 0, -1, &ulval,
			    sizeof(ulval));
		break;
	}

	case SCHEDULE_ALL: {
		u_int64_t ulval = 0;

		imsg_compose(ibuf, IMSG_SCHEDULER_SCHEDULE, 0, 0, -1, &ulval,
		    sizeof(ulval));
		break;
	}

	case SHUTDOWN:
		imsg_compose(ibuf, IMSG_CTL_SHUTDOWN, 0, 0, -1, NULL, 0);
		break;
	case PAUSE_MDA:
		imsg_compose(ibuf, IMSG_QUEUE_PAUSE_MDA, 0, 0, -1, NULL, 0);
		break;
	case PAUSE_MTA:
		imsg_compose(ibuf, IMSG_QUEUE_PAUSE_MTA, 0, 0, -1, NULL, 0);
		break;
	case PAUSE_SMTP:
		imsg_compose(ibuf, IMSG_SMTP_PAUSE, 0, 0, -1, NULL, 0);
		break;
	case RESUME_MDA:
		imsg_compose(ibuf, IMSG_QUEUE_RESUME_MDA, 0, 0, -1, NULL, 0);
		break;
	case RESUME_MTA:
		imsg_compose(ibuf, IMSG_QUEUE_RESUME_MTA, 0, 0, -1, NULL, 0);
		break;
	case RESUME_SMTP:
		imsg_compose(ibuf, IMSG_SMTP_RESUME, 0, 0, -1, NULL, 0);
		break;
	case SHOW_STATS:
		imsg_compose(ibuf, IMSG_STATS, 0, 0, -1, NULL, 0);
		break;
	case MONITOR:
		/* XXX */
		break;
	case LOG_VERBOSE:
		verbose = 1;
		/* FALLTHROUGH */
	case LOG_BRIEF:
		imsg_compose(ibuf, IMSG_CTL_VERBOSE, 0, 0, -1, &verbose,
		    sizeof(verbose));
		printf("logging request sent.\n");
		done = 1;
		break;
	default:
		errx(1, "unknown request (%d)", res->action);
	}

	while (ibuf->w.queued)
		if (msgbuf_write(&ibuf->w) < 0)
			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 REMOVE:
			case SCHEDULE:
			case SCHEDULE_ALL:
			case SHUTDOWN:
			case PAUSE_MDA:
			case PAUSE_MTA:
			case PAUSE_SMTP:
			case RESUME_MDA:
			case RESUME_MTA:
			case RESUME_SMTP:
			case LOG_VERBOSE:
			case LOG_BRIEF:
				done = show_command_output(&imsg);
				break;
			case SHOW_STATS:
				done = show_stats_output(&imsg);
				break;
			case NONE:
				break;
			case MONITOR:
				break;
			default:
				err(1, "unexpected reply (%d)", res->action);
			}
			/* insert imsg replies switch here */

			imsg_free(&imsg);
		}
	}
	close(ctl_sock);
	free(ibuf);

	return (0);
}
Exemple #17
0
/* ARGSUSED */
void
control_dispatch_imsg(int fd, short event, void *arg)
{
	struct control_sock	*cs = (struct control_sock *)arg;
	struct ctl_conn		*c;
	struct imsg		 imsg;
	int			 n, retval;

	if ((c = control_connbyfd(fd)) == NULL) {
		log_warn("control_dispatch_imsg: fd %d: not found", fd);
		return;
	}


	if (event & EV_WRITE) {
		if (msgbuf_write(&c->iev.ibuf.w) < 0) {
			control_close(fd, cs);
			return;
		}
		if (!c->iev.ibuf.w.queued)
			npppd_ctl_imsg_compose(c->ctx, &c->iev.ibuf);
		imsg_event_add(&c->iev);
		if (!(event & EV_READ))
			return;
	}
	if (event & EV_READ) {
		if ((n = imsg_read(&c->iev.ibuf)) == -1 || n == 0) {
			control_close(fd, cs);
			return;
		}
	} else
		fatalx("unknown event");

	for (;;) {
		if ((n = imsg_get(&c->iev.ibuf, &imsg)) == -1) {
			control_close(fd, cs);
			return;
		}

		if (n == 0)
			break;

		if (cs->cs_restricted || (c->flags & CTL_CONN_LOCKED)) {
			switch (imsg.hdr.type) {
			default:
				log_debug("control_dispatch_imsg: "
				    "client requested restricted command");
				imsg_free(&imsg);
				control_close(fd, cs);
				return;
			}
		}

		switch (imsg.hdr.type) {
		case IMSG_CTL_NOP:
			imsg_compose(&c->iev.ibuf, IMSG_CTL_OK, 0, 0, -1,
			    NULL, 0);
			break;

		case IMSG_CTL_WHO:
		case IMSG_CTL_MONITOR:
		case IMSG_CTL_WHO_AND_MONITOR:
			if (imsg.hdr.type == IMSG_CTL_WHO)
				retval = npppd_ctl_who(c->ctx);
			else if (imsg.hdr.type == IMSG_CTL_MONITOR)
				retval = npppd_ctl_monitor(c->ctx);
			else
				retval = npppd_ctl_who_and_monitor(c->ctx);
			imsg_compose(&c->iev.ibuf,
			    (retval == 0)? IMSG_CTL_OK : IMSG_CTL_FAIL, 0, 0,
			    -1, NULL, 0);
			break;

		case IMSG_CTL_DISCONNECT:
		    {
			struct npppd_disconnect_request  *req;
			struct npppd_disconnect_response  res;

			req = (struct npppd_disconnect_request *)imsg.data;
			retval = npppd_ctl_disconnect(c->ctx,
			    req->ppp_id, req->count);
			res.count = retval;
			imsg_compose(&c->iev.ibuf, IMSG_CTL_OK, 0, 0,
			    -1, &res, sizeof(res));
			break;
		    }
		default:
			imsg_compose(&c->iev.ibuf, IMSG_CTL_FAIL, 0, 0, -1,
			    NULL, 0);
			break;
		}
		imsg_free(&imsg);
	}
	if (!c->iev.ibuf.w.queued)
		npppd_ctl_imsg_compose(c->ctx, &c->iev.ibuf);
	imsg_event_add(&c->iev);
}
Exemple #18
0
int
main(int argc, char *argv[])
{
	struct sockaddr_un	 sun;
	struct parse_result	*res;
	struct imsg		 imsg;
	unsigned int		 ifidx = 0;
	int			 ctl_sock;
	int			 done = 0, verbose = 0;
	int			 n;
	int			 ch;
	char			*sockname;

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

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

	/* connect to ospf6d 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, sockname, sizeof(sun.sun_path));
	if (connect(ctl_sock, (struct sockaddr *)&sun, sizeof(sun)) == -1)
		err(1, "connect: %s", sockname);

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

	if ((ibuf = malloc(sizeof(struct imsgbuf))) == NULL)
		err(1, NULL);
	imsg_init(ibuf, ctl_sock);
	done = 0;

	/* process user request */
	switch (res->action) {
	case NONE:
		usage();
		/* not reached */
	case SHOW:
	case SHOW_SUM:
		imsg_compose(ibuf, IMSG_CTL_SHOW_SUM, 0, 0, -1, NULL, 0);
		break;
	case SHOW_IFACE:
		printf("%-11s %-29s %-6s %-10s %-10s %-8s\n",
		    "Interface", "Address", "State", "HelloTimer", "Linkstate",
		    "Uptime");
		/*FALLTHROUGH*/
	case SHOW_IFACE_DTAIL:
		if (*res->ifname) {
			ifidx = if_nametoindex(res->ifname);
			if (ifidx == 0)
				errx(1, "no such interface %s", res->ifname);
		}
		imsg_compose(ibuf, IMSG_CTL_SHOW_INTERFACE, 0, 0, -1,
		    &ifidx, sizeof(ifidx));
		break;
	case SHOW_NBR:
		printf("%-15s %-3s %-12s %-9s %-11s %s\n", "ID", "Pri",
		    "State", "DeadTime", "Iface","Uptime");
		/*FALLTHROUGH*/
	case SHOW_NBR_DTAIL:
		imsg_compose(ibuf, IMSG_CTL_SHOW_NBR, 0, 0, -1, NULL, 0);
		break;
	case SHOW_DB:
		imsg_compose(ibuf, IMSG_CTL_SHOW_DATABASE, 0, 0, -1, NULL, 0);
		break;
	case SHOW_DBBYAREA:
		imsg_compose(ibuf, IMSG_CTL_SHOW_DATABASE, 0, 0, -1,
		    &res->addr, sizeof(res->addr));
		break;
	case SHOW_DBEXT:
		imsg_compose(ibuf, IMSG_CTL_SHOW_DB_EXT, 0, 0, -1, NULL, 0);
		break;
	case SHOW_DBLINK:
		imsg_compose(ibuf, IMSG_CTL_SHOW_DB_LINK, 0, 0, -1, NULL, 0);
		break;
	case SHOW_DBNET:
		imsg_compose(ibuf, IMSG_CTL_SHOW_DB_NET, 0, 0, -1, NULL, 0);
		break;
	case SHOW_DBRTR:
		imsg_compose(ibuf, IMSG_CTL_SHOW_DB_RTR, 0, 0, -1, NULL, 0);
		break;
	case SHOW_DBINTRA:
		imsg_compose(ibuf, IMSG_CTL_SHOW_DB_INTRA, 0, 0, -1, NULL, 0);
		break;
	case SHOW_DBSELF:
		imsg_compose(ibuf, IMSG_CTL_SHOW_DB_SELF, 0, 0, -1, NULL, 0);
		break;
	case SHOW_DBSUM:
		imsg_compose(ibuf, IMSG_CTL_SHOW_DB_SUM, 0, 0, -1, NULL, 0);
		break;
	case SHOW_DBASBR:
		imsg_compose(ibuf, IMSG_CTL_SHOW_DB_ASBR, 0, 0, -1, NULL, 0);
		break;
	case SHOW_RIB:
		printf("%-20s %-17s %-12s %-9s %-7s %-8s\n", "Destination",
		    "Nexthop", "Path Type", "Type", "Cost", "Uptime");
		/*FALLTHROUGH*/
	case SHOW_RIB_DTAIL:
		imsg_compose(ibuf, IMSG_CTL_SHOW_RIB, 0, 0, -1, NULL, 0);
		break;
	case SHOW_FIB:
		if (IN6_IS_ADDR_UNSPECIFIED(&res->addr))
			imsg_compose(ibuf, IMSG_CTL_KROUTE, 0, 0, -1,
			    &res->flags, sizeof(res->flags));
		else
			imsg_compose(ibuf, IMSG_CTL_KROUTE_ADDR, 0, 0, -1,
			    &res->addr, sizeof(res->addr));
		show_fib_head();
		break;
	case FIB:
		errx(1, "fib couple|decouple");
		break;
	case FIB_COUPLE:
		imsg_compose(ibuf, IMSG_CTL_FIB_COUPLE, 0, 0, -1, NULL, 0);
		printf("couple request sent.\n");
		done = 1;
		break;
	case FIB_DECOUPLE:
		imsg_compose(ibuf, IMSG_CTL_FIB_DECOUPLE, 0, 0, -1, NULL, 0);
		printf("decouple request sent.\n");
		done = 1;
		break;
	case LOG_VERBOSE:
		verbose = 1;
		/* FALLTHROUGH */
	case LOG_BRIEF:
		imsg_compose(ibuf, IMSG_CTL_LOG_VERBOSE, 0, 0, -1,
		    &verbose, sizeof(verbose));
		printf("logging request sent.\n");
		done = 1;
		break;
	case RELOAD:
		imsg_compose(ibuf, IMSG_CTL_RELOAD, 0, 0, -1, NULL, 0);
		printf("reload request sent.\n");
		done = 1;
		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 SHOW:
			case SHOW_SUM:
				done = show_summary_msg(&imsg);
				break;
			case SHOW_IFACE:
				done = show_interface_msg(&imsg);
				break;
			case SHOW_IFACE_DTAIL:
				done = show_interface_detail_msg(&imsg);
				break;
			case SHOW_NBR:
				done = show_nbr_msg(&imsg);
				break;
			case SHOW_NBR_DTAIL:
				done = show_nbr_detail_msg(&imsg);
				break;
			case SHOW_DB:
			case SHOW_DBBYAREA:
			case SHOW_DBSELF:
				done = show_database_msg(&imsg);
				break;
			case SHOW_DBEXT:
			case SHOW_DBLINK:
			case SHOW_DBNET:
			case SHOW_DBRTR:
			case SHOW_DBINTRA:
			case SHOW_DBSUM:
			case SHOW_DBASBR:
				done = show_db_msg_detail(&imsg);
				break;
			case SHOW_RIB:
				done = show_rib_msg(&imsg);
				break;
			case SHOW_RIB_DTAIL:
				done = show_rib_detail_msg(&imsg);
				break;
			case SHOW_FIB:
				done = show_fib_msg(&imsg);
				break;
			case NONE:
			case FIB:
			case FIB_COUPLE:
			case FIB_DECOUPLE:
			case LOG_VERBOSE:
			case LOG_BRIEF:
			case RELOAD:
				break;
			}
			imsg_free(&imsg);
		}
	}
	close(ctl_sock);
	free(ibuf);

	return (0);
}
Exemple #19
0
void
ctl_main(int argc, char *argv[])
{
	struct sockaddr_un	 sa;
	struct imsg		 imsg;
	struct imsgbuf		*ibuf_ctl;
	int			 fd, n, done, ch, action;
	char			*sockname;

	sockname = CTLSOCKET;

	if (argc < 2) {
		usage();
		/* NOTREACHED */
	}

	while ((ch = getopt(argc, argv, "s:")) != -1) {
		switch (ch) {
		case 's':
			showopt = ctl_lookup_option(optarg, ctl_showopt_list);
			if (showopt == NULL) {
				warnx("Unknown show modifier '%s'", optarg);
				usage();
			}
			break;
		default:
			usage();
			/* NOTREACHED */
		}
	}

	action = -1;
	if (showopt != NULL) {
		switch (*showopt) {
		case 'p':
			action = CTL_SHOW_PEERS;
			break;
		case 's':
			action = CTL_SHOW_STATUS;
			break;
		case 'S':
			action = CTL_SHOW_SENSORS;
			break;
		case 'a':
			action = CTL_SHOW_ALL;
			break;
		}
	}
	if (action == -1)
		usage();
		/* NOTREACHED */

	if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
		err(1, "ntpctl: socket");

	bzero(&sa, sizeof(sa));
	sa.sun_family = AF_UNIX;
	if (strlcpy(sa.sun_path, sockname, sizeof(sa.sun_path)) >=
	    sizeof(sa.sun_path))
		errx(1, "ctl socket name too long");
	if (connect(fd, (struct sockaddr *)&sa, sizeof(sa)) == -1)
		err(1, "connect: %s", sockname);

	if ((ibuf_ctl = malloc(sizeof(struct imsgbuf))) == NULL)
		err(1, NULL);
	imsg_init(ibuf_ctl, fd);

	switch (action) {
	case CTL_SHOW_STATUS:
		imsg_compose(ibuf_ctl, IMSG_CTL_SHOW_STATUS,
		    0, 0, -1, NULL, 0);
		break;
	case CTL_SHOW_PEERS:
		imsg_compose(ibuf_ctl, IMSG_CTL_SHOW_PEERS,
		    0, 0, -1, NULL, 0);
		break;
	case CTL_SHOW_SENSORS:
		imsg_compose(ibuf_ctl, IMSG_CTL_SHOW_SENSORS,
		    0, 0, -1, NULL, 0);
		break;
	case CTL_SHOW_ALL:
		imsg_compose(ibuf_ctl, IMSG_CTL_SHOW_ALL,
		    0, 0, -1, NULL, 0);
		break;
	default:
		errx(1, "invalid action");
		break; /* NOTREACHED */
	}

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

	done = 0;
	while (!done) {
		if ((n = imsg_read(ibuf_ctl)) == -1)
			err(1, "ibuf_ctl: imsg_read error");
		if (n == 0)
			errx(1, "ntpctl: pipe closed");

		while (!done) {
			if ((n = imsg_get(ibuf_ctl, &imsg)) == -1)
				err(1, "ibuf_ctl: imsg_get error");
			if (n == 0)
				break;

			switch (action) {
			case CTL_SHOW_STATUS:
				show_status_msg(&imsg);
				done = 1;
				break;
			case CTL_SHOW_PEERS:
				show_peer_msg(&imsg, 0);
				if (imsg.hdr.type ==
				    IMSG_CTL_SHOW_PEERS_END)
					done = 1;
				break;
			case CTL_SHOW_SENSORS:
				show_sensor_msg(&imsg, 0);
				if (imsg.hdr.type ==
				    IMSG_CTL_SHOW_SENSORS_END)
					done = 1;
				break;
			case CTL_SHOW_ALL:
				switch (imsg.hdr.type) {
				case IMSG_CTL_SHOW_STATUS:
					show_status_msg(&imsg);
					break;
				case IMSG_CTL_SHOW_PEERS:
					show_peer_msg(&imsg, 1);
					break;
				case IMSG_CTL_SHOW_SENSORS:
					show_sensor_msg(&imsg, 1);
					break;
				case IMSG_CTL_SHOW_PEERS_END:
				case IMSG_CTL_SHOW_SENSORS_END:
					/* do nothing */
					break;
				case IMSG_CTL_SHOW_ALL_END:
					done=1;
					break;
				default:
					/* no action taken */
					break;
				}
			default:
				/* no action taken */
				break;
			}
			imsg_free(&imsg);
		}
	}
	close(fd);
	free(ibuf_ctl);
	exit(0);
}
Exemple #20
0
int
table_api_dispatch(void)
{
#if 0
	struct passwd	*pw;
#endif
	ssize_t		 n;

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

	if (rootpath) {
		if (chroot(rootpath) == -1) {
			log_warn("table-api: chroot");
			fatalx("table-api: exiting");
		}
		if (chdir("/") == -1) {
			log_warn("table-api: chdir");
			fatalx("table-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("table-api: cannot drop privileges");
		fatalx("table-api: exiting");
	}
#endif

	imsg_init(&ibuf, 0);

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

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

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

	return (1);
}
Exemple #21
0
static void
mproc_dispatch(int fd, short event, void *arg)
{
	struct mproc	*p = arg;
	struct imsg	 imsg;
	ssize_t		 n;

	p->events = 0;

	if (event & EV_READ) {

		if (p->proc == PROC_CLIENT)
			n = imsg_read_nofd(&p->imsgbuf);
		else
			n = imsg_read(&p->imsgbuf);

		switch (n) {
		case -1:
			if (errno == EAGAIN)
				break;
			log_warn("warn: %s -> %s: imsg_read",
			    proc_name(smtpd_process),  p->name);
			fatal("exiting");
			/* NOTREACHED */
		case 0:
			/* this pipe is dead, so remove the event handler */
			log_debug("debug: %s -> %s: pipe closed",
			    proc_name(smtpd_process),  p->name);
			p->handler(p, NULL);
			return;
		default:
			break;
		}
	}

	if (event & EV_WRITE) {
		n = msgbuf_write(&p->imsgbuf.w);
		if (n == 0 || (n == -1 && errno != EAGAIN)) {
			/* this pipe is dead, so remove the event handler */
			log_debug("debug: %s -> %s: pipe closed",
			    proc_name(smtpd_process),  p->name);
			p->handler(p, NULL);
			return;
		}
	}

	for (;;) {
		if ((n = imsg_get(&p->imsgbuf, &imsg)) == -1) {

			if (smtpd_process == PROC_CONTROL &&
			    p->proc == PROC_CLIENT) {
				log_warnx("warn: client sent invalid imsg "
				    "over control socket");
				p->handler(p, NULL);
				return;
			}
			log_warn("fatal: %s: error in imsg_get for %s",
			    proc_name(smtpd_process),  p->name);
			fatalx(NULL);
		}
		if (n == 0)
			break;

		p->handler(p, &imsg);

		imsg_free(&imsg);
	}

	mproc_event_add(p);
}
Exemple #22
0
void
dns_dispatch_imsg(int fd, short events, void *p)
{
	struct imsg		 imsg;
	int			 n, cnt;
	char			*name;
	struct ypldap_addr_list	hn = TAILQ_HEAD_INITIALIZER(hn);
	struct ypldap_addr	*h;
	struct ibuf		*buf;
	struct env		*env = p;
	struct imsgev		*iev = env->sc_iev;
	struct imsgbuf		*ibuf = &iev->ibuf;
	int			 shut = 0;

	if ((events & (EV_READ | EV_WRITE)) == 0)
		fatalx("unknown event");

	if (events & EV_READ) {
		if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN)
			fatal("imsg_read error");
		if (n == 0)
			shut = 1;
	}
	if (events & EV_WRITE) {
		if ((n = msgbuf_write(&ibuf->w)) == -1 && errno != EAGAIN)
			fatal("msgbuf_write");
		if (n == 0)
			shut = 1;
		goto done;
	}

	for (;;) {
		if ((n = imsg_get(ibuf, &imsg)) == -1)
			fatal("client_dispatch_imsg: imsg_get error");
		if (n == 0)
			break;

		switch (imsg.hdr.type) {
		case IMSG_HOST_DNS:
			name = imsg.data;
			if (imsg.hdr.len < 1 + IMSG_HEADER_SIZE)
				fatalx("invalid IMSG_HOST_DNS received");
			imsg.hdr.len -= 1 + IMSG_HEADER_SIZE;
			if (name[imsg.hdr.len] != '\0' ||
			    strlen(name) != imsg.hdr.len)
				fatalx("invalid IMSG_HOST_DNS received");
			if ((cnt = host_dns(name, &hn)) == -1)
				break;
			buf = imsg_create(ibuf, IMSG_HOST_DNS,
			    imsg.hdr.peerid, 0,
			    cnt * sizeof(struct sockaddr_storage));
			if (buf == NULL)
				break;
			if (cnt > 0) {
				while(!TAILQ_EMPTY(&hn)) {
					h = TAILQ_FIRST(&hn);
					TAILQ_REMOVE(&hn, h, next);
					imsg_add(buf, &h->ss, sizeof(h->ss));
					free(h);
				}
			}

			imsg_close(ibuf, buf);
			break;
		default:
			break;
		}
		imsg_free(&imsg);
	}

done:
	if (!shut)
		imsg_event_add(iev);
	else {
		/* this pipe is dead, so remove the event handler */
		event_del(&iev->ev);
		event_loopexit(NULL);
	}
}
Exemple #23
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);
}
Exemple #24
0
void
proc_dispatch(int fd, short event, void *arg)
{
	struct privsep_proc	*p = (struct privsep_proc *)arg;
	struct privsep		*ps = p->p_ps;
	struct imsgev		*iev;
	struct imsgbuf		*ibuf;
	struct imsg		 imsg;
	ssize_t			 n;
	int			 verbose;
	const char		*title;

	title = ps->ps_title[privsep_process];
	iev = &ps->ps_ievs[p->p_id];
	ibuf = &iev->ibuf;

	if (event & EV_READ) {
		if ((n = imsg_read(ibuf)) == -1)
			fatal(title);
		if (n == 0) {
			/* this pipe is dead, so remove the event handler */
			event_del(&iev->ev);
			event_loopexit(NULL);
			return;
		}
	}

	if (event & EV_WRITE) {
		if (msgbuf_write(&ibuf->w) <= 0 && errno != EAGAIN)
			fatal(title);
	}

	for (;;) {
		if ((n = imsg_get(ibuf, &imsg)) == -1)
			fatal(title);
		if (n == 0)
			break;

		/*
		 * Check the message with the program callback
		 */
		if ((p->p_cb)(fd, p, &imsg) == 0) {
			/* Message was handled by the callback, continue */
			imsg_free(&imsg);
			continue;
		}

		/*
		 * Generic message handling
		 */
		switch (imsg.hdr.type) {
		case IMSG_CTL_VERBOSE:
			IMSG_SIZE_CHECK(&imsg, &verbose);

			memcpy(&verbose, imsg.data, sizeof(verbose));
			log_verbose(verbose);
			break;
		default:
			log_warnx("%s: %s got imsg %d", __func__, p->p_title,
			    imsg.hdr.type);
			fatalx(title);
		}
		imsg_free(&imsg);
	}
	imsg_event_add(iev);
}
Exemple #25
0
/* ARGSUSED */
void
control_dispatch_imsg(int fd, short event, void *arg)
{
	struct control_sock	*cs = arg;
	struct iked		*env = cs->cs_env;
	struct ctl_conn		*c;
	struct imsg		 imsg;
	int			 n, v;

	if ((c = control_connbyfd(fd)) == NULL) {
		log_warn("%s: fd %d: not found", __func__, fd);
		return;
	}

	if (event & EV_READ) {
		if ((n = imsg_read(&c->iev.ibuf)) == -1 || n == 0) {
			control_close(fd, cs);
			return;
		}
	}
	if (event & EV_WRITE) {
		if (msgbuf_write(&c->iev.ibuf.w) <= 0 && errno != EAGAIN) {
			control_close(fd, cs);
			return;
		}
	}

	for (;;) {
		if ((n = imsg_get(&c->iev.ibuf, &imsg)) == -1) {
			control_close(fd, cs);
			return;
		}

		if (n == 0)
			break;

		control_imsg_forward(&imsg);

		switch (imsg.hdr.type) {
		case IMSG_CTL_NOTIFY:
			if (c->flags & CTL_CONN_NOTIFY) {
				log_debug("%s: "
				    "client requested notify more than once",
				    __func__);
				imsg_compose_event(&c->iev, IMSG_CTL_FAIL,
				    0, 0, -1, NULL, 0);
				break;
			}
			c->flags |= CTL_CONN_NOTIFY;
			break;
		case IMSG_CTL_VERBOSE:
			IMSG_SIZE_CHECK(&imsg, &v);

			memcpy(&v, imsg.data, sizeof(v));
			log_verbose(v);

			proc_forward_imsg(&env->sc_ps, &imsg, PROC_PARENT, -1);
			proc_forward_imsg(&env->sc_ps, &imsg, PROC_IKEV2, -1);
			proc_forward_imsg(&env->sc_ps, &imsg, PROC_IKEV1, -1);
			break;
		case IMSG_CTL_RELOAD:
		case IMSG_CTL_RESET:
		case IMSG_CTL_COUPLE:
		case IMSG_CTL_DECOUPLE:
		case IMSG_CTL_ACTIVE:
		case IMSG_CTL_PASSIVE:
			proc_forward_imsg(&env->sc_ps, &imsg, PROC_PARENT, -1);
			break;
		default:
			log_debug("%s: error handling imsg %d",
			    __func__, imsg.hdr.type);
			break;
		}
		imsg_free(&imsg);
	}

	imsg_event_add(&c->iev);
}
Exemple #26
0
/* ARGSUSED */
void
control_dispatch_imsg(int fd, short event, void *bula)
{
	struct ctl_conn	*c;
	struct imsg	 imsg;
	int		 n;
	unsigned int	 ifidx;
	int		 verbose;

	if ((c = control_connbyfd(fd)) == NULL) {
		log_warn("control_dispatch_imsg: fd %d: not found", fd);
		return;
	}

	if (event & EV_READ) {
		if ((n = imsg_read(&c->iev.ibuf)) == -1 || n == 0) {
			control_close(fd);
			return;
		}
	}
	if (event & EV_WRITE) {
		if (msgbuf_write(&c->iev.ibuf.w) == -1 && errno != EAGAIN) {
			control_close(fd);
			return;
		}
	}

	for (;;) {
		if ((n = imsg_get(&c->iev.ibuf, &imsg)) == -1) {
			control_close(fd);
			return;
		}

		if (n == 0)
			break;

		switch (imsg.hdr.type) {
		case IMSG_CTL_MFC_COUPLE:
		case IMSG_CTL_MFC_DECOUPLE:
		case IMSG_CTL_RELOAD:
			dvmrpe_imsg_compose_parent(imsg.hdr.type, 0, NULL, 0);
			break;
		case IMSG_CTL_SHOW_IFACE:
			if (imsg.hdr.len == IMSG_HEADER_SIZE +
			    sizeof(ifidx)) {
				memcpy(&ifidx, imsg.data, sizeof(ifidx));
				dvmrpe_iface_ctl(c, ifidx);
				imsg_compose_event(&c->iev, IMSG_CTL_END, 0,
				    0, -1, NULL, 0);
			}
			break;
		case IMSG_CTL_SHOW_IGMP:
			if (imsg.hdr.len == IMSG_HEADER_SIZE +
			    sizeof(ifidx)) {
				memcpy(&ifidx, imsg.data, sizeof(ifidx));
				dvmrpe_iface_igmp_ctl(c, ifidx);
				imsg_compose_event(&c->iev, IMSG_CTL_END, 0,
				    0, -1, NULL, 0);
			}
			break;
		case IMSG_CTL_SHOW_NBR:
			dvmrpe_nbr_ctl(c);
			break;
		case IMSG_CTL_SHOW_RIB:
		case IMSG_CTL_SHOW_MFC:
		case IMSG_CTL_SHOW_SUM:
			c->iev.ibuf.pid = imsg.hdr.pid;
			dvmrpe_imsg_compose_rde(imsg.hdr.type, 0, imsg.hdr.pid,
			    imsg.data, imsg.hdr.len - IMSG_HEADER_SIZE);
			break;
		case IMSG_CTL_LOG_VERBOSE:
			if (imsg.hdr.len != IMSG_HEADER_SIZE +
			    sizeof(verbose))
				break;

			/* forward to other processes */
			dvmrpe_imsg_compose_parent(imsg.hdr.type, imsg.hdr.pid,
			    imsg.data, imsg.hdr.len - IMSG_HEADER_SIZE);
			dvmrpe_imsg_compose_rde(imsg.hdr.type, 0, imsg.hdr.pid,
			    imsg.data, imsg.hdr.len - IMSG_HEADER_SIZE);

			memcpy(&verbose, imsg.data, sizeof(verbose));
			log_verbose(verbose);
			break;
		default:
			log_debug("control_dispatch_imsg: "
			    "error handling imsg %d", imsg.hdr.type);
			break;
		}
		imsg_free(&imsg);
	}

	imsg_event_add(&c->iev);
}
Exemple #27
0
/* ARGSUSED */
void
control_dispatch_imsg(int fd, short event, void *bula)
{
	struct ctl_conn	*c;
	struct imsg	 imsg;
	ssize_t		 n;
	unsigned int	 ifidx;
	int		 verbose;

	if ((c = control_connbyfd(fd)) == NULL) {
		log_warn("control_dispatch_imsg: fd %d: not found", fd);
		return;
	}

	if (event & EV_READ) {
		if ((n = imsg_read(&c->iev.ibuf)) == -1 || n == 0) {
			control_close(fd);
			return;
		}
	}
	if (event & EV_WRITE) {
		if (msgbuf_write(&c->iev.ibuf.w) == -1) {
			control_close(fd);
			return;
		}
	}

	for (;;) {
		if ((n = imsg_get(&c->iev.ibuf, &imsg)) == -1) {
			control_close(fd);
			return;
		}

		if (n == 0)
			break;

		switch (imsg.hdr.type) {
		case IMSG_CTL_FIB_COUPLE:
		case IMSG_CTL_FIB_DECOUPLE:
			ospfe_fib_update(imsg.hdr.type);
			/* FALLTHROUGH */
		case IMSG_CTL_FIB_RELOAD:
		case IMSG_CTL_RELOAD:
			c->iev.ibuf.pid = imsg.hdr.pid;
			ospfe_imsg_compose_parent(imsg.hdr.type, 0, NULL, 0);
			break;
		case IMSG_CTL_KROUTE:
		case IMSG_CTL_KROUTE_ADDR:
		case IMSG_CTL_IFINFO:
			c->iev.ibuf.pid = imsg.hdr.pid;
			ospfe_imsg_compose_parent(imsg.hdr.type, imsg.hdr.pid,
			    imsg.data, imsg.hdr.len - IMSG_HEADER_SIZE);
			break;
		case IMSG_CTL_SHOW_INTERFACE:
			if (imsg.hdr.len == IMSG_HEADER_SIZE +
			    sizeof(ifidx)) {
				memcpy(&ifidx, imsg.data, sizeof(ifidx));
				ospfe_iface_ctl(c, ifidx);
				imsg_compose_event(&c->iev, IMSG_CTL_END, 0,
				    0, -1, NULL, 0);
			}
			break;
		case IMSG_CTL_SHOW_DATABASE:
		case IMSG_CTL_SHOW_DB_EXT:
		case IMSG_CTL_SHOW_DB_NET:
		case IMSG_CTL_SHOW_DB_RTR:
		case IMSG_CTL_SHOW_DB_SELF:
		case IMSG_CTL_SHOW_DB_SUM:
		case IMSG_CTL_SHOW_DB_ASBR:
		case IMSG_CTL_SHOW_DB_OPAQ:
		case IMSG_CTL_SHOW_RIB:
		case IMSG_CTL_SHOW_SUM:
			c->iev.ibuf.pid = imsg.hdr.pid;
			ospfe_imsg_compose_rde(imsg.hdr.type, 0, imsg.hdr.pid,
			    imsg.data, imsg.hdr.len - IMSG_HEADER_SIZE);
			break;
		case IMSG_CTL_SHOW_NBR:
			ospfe_nbr_ctl(c);
			break;
		case IMSG_CTL_LOG_VERBOSE:
			if (imsg.hdr.len != IMSG_HEADER_SIZE +
			    sizeof(verbose))
				break;

			/* forward to other processes */
			ospfe_imsg_compose_parent(imsg.hdr.type, imsg.hdr.pid,
			    imsg.data, imsg.hdr.len - IMSG_HEADER_SIZE);
			ospfe_imsg_compose_rde(imsg.hdr.type, 0, imsg.hdr.pid,
			    imsg.data, imsg.hdr.len - IMSG_HEADER_SIZE);

			memcpy(&verbose, imsg.data, sizeof(verbose));
			log_verbose(verbose);
			break;
		default:
			log_debug("control_dispatch_imsg: "
			    "error handling imsg %d", imsg.hdr.type);
			break;
		}
		imsg_free(&imsg);
	}

	imsg_event_add(&c->iev);
}
Exemple #28
0
static void
filter_handler(int fd, short event, void *p)
{
	struct imsg		imsg;
	ssize_t			n;
	short			evflags = EV_READ;
	enum filter_status	ret;
	struct filter_msg	fm;

	if (event & EV_READ) {
		n = imsg_read(&fi.ibuf);
		if (n == -1)
			err(1, "imsg_read");
		if (n == 0) {
			event_del(&fi.ev);
			event_loopexit(NULL);
			return;
		}
	}

	if (event & EV_WRITE) {
		if (msgbuf_write(&fi.ibuf.w) == -1)
			err(1, "msgbuf_write");
		if (fi.ibuf.w.queued)
			evflags |= EV_WRITE;
	}

	for (;;) {
		n = imsg_get(&fi.ibuf, &imsg);
		if (n == -1)
			errx(1, "imsg_get");
		if (n == 0)
			break;

		if ((imsg.hdr.len - IMSG_HEADER_SIZE)
		    != sizeof(fm))
			errx(1, "corrupted imsg");

		memcpy(&fm, imsg.data, sizeof (fm));
		if (fm.version != FILTER_API_VERSION)
			errx(1, "API version mismatch");

		switch (imsg.hdr.type) {
		case FILTER_CONNECT:
			if (fi.connect_cb == NULL)
				goto ignore;
			ret = fi.connect_cb(fm.cl_id, &fm.u.connect,
			    fi.connect_cb_arg);
			break;
		case FILTER_HELO:
			if (fi.helo_cb == NULL)
				goto ignore;
			ret = fi.helo_cb(fm.cl_id, &fm.u.helo,
			    fi.helo_cb_arg);
			break;
		case FILTER_EHLO:
			if (fi.ehlo_cb == NULL)
				goto ignore;
			ret = fi.ehlo_cb(fm.cl_id, &fm.u.helo,
			    fi.ehlo_cb_arg);
			break;
		case FILTER_MAIL:
			if (fi.mail_cb == NULL)
				goto ignore;
			ret = fi.mail_cb(fm.cl_id, &fm.u.mail,
			    fi.mail_cb_arg);
			break;
		case FILTER_RCPT:
			if (fi.rcpt_cb == NULL)
				goto ignore;
			ret = fi.rcpt_cb(fm.cl_id, &fm.u.rcpt,
			    fi.rcpt_cb_arg);
			break;
		case FILTER_DATALINE:
			if (fi.dataline_cb == NULL)
				goto ignore;
			ret = fi.dataline_cb(fm.cl_id, &fm.u.dataline,
			    fi.dataline_cb_arg);
			break;
		case FILTER_QUIT:
			if (fi.quit_cb == NULL)
				goto ignore;
			ret = fi.quit_cb(fm.cl_id, fi.quit_cb_arg);
			break;
		case FILTER_CLOSE:
			if (fi.close_cb == NULL)
				goto ignore;
			ret = fi.close_cb(fm.cl_id, fi.close_cb_arg);
			break;
		case FILTER_RSET:
			if (fi.rset_cb == NULL)
				goto ignore;
			ret = fi.rset_cb(fm.cl_id, fi.rset_cb_arg);
 			break;

		default:
			errx(1, "unsupported imsg");
		}

		switch (ret) {
		case STATUS_ACCEPT:
		case STATUS_REJECT:
			fm.code = ret;
			imsg_compose(&fi.ibuf, imsg.hdr.type, 0, 0, -1, &fm,
			    sizeof fm);
			evflags |= EV_WRITE;
			break;
		case STATUS_WAITING:
			/* waiting for asynchronous call ... */
			break;
		}

		imsg_free(&imsg);
	}

	event_set(&fi.ev, 0, evflags, filter_handler, &fi);
	event_add(&fi.ev, NULL);
	return;

ignore:
	imsg_free(&imsg);
	fm.code = STATUS_IGNORE;
	imsg_compose(&fi.ibuf, imsg.hdr.type, 0, 0, -1, &fm, sizeof fm);
	evflags |= EV_WRITE;
	event_set(&fi.ev, 0, evflags, filter_handler, &fi);
	event_add(&fi.ev, NULL);
}
Exemple #29
0
int
scheduler_api_dispatch(void)
{
	struct passwd	*pw = NULL;
	ssize_t		 n;

	if (user) {
		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 (pw &&
	   (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: scheduler-api: imsg_get");
			break;
		}

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

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

	return (1);
}
Exemple #30
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, verbose = 0;

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

	/* connect to relayd 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, RELAYD_SOCKET, 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", RELAYD_SOCKET);
	}

	if ((ibuf = malloc(sizeof(struct imsgbuf))) == NULL)
		err(1, NULL);
	imsg_init(ibuf, ctl_sock);
	done = 0;

	/* process user request */
	switch (res->action) {
	case NONE:
		usage();
		/* not reached */
	case SHOW_SUM:
	case SHOW_HOSTS:
	case SHOW_RDRS:
	case SHOW_RELAYS:
	case SHOW_ROUTERS:
		imsg_compose(ibuf, IMSG_CTL_SHOW_SUM, 0, 0, -1, NULL, 0);
		printf("%-4s\t%-8s\t%-24s\t%-7s\tStatus\n",
		    "Id", "Type", "Name", "Avlblty");
		break;
	case SHOW_SESSIONS:
		imsg_compose(ibuf, IMSG_CTL_SESSION, 0, 0, -1, NULL, 0);
		break;
	case RDR_ENABLE:
		imsg_compose(ibuf, IMSG_CTL_RDR_ENABLE, 0, 0, -1,
		    &res->id, sizeof(res->id));
		break;
	case RDR_DISABLE:
		imsg_compose(ibuf, IMSG_CTL_RDR_DISABLE, 0, 0, -1,
		    &res->id, sizeof(res->id));
		break;
	case TABLE_ENABLE:
		imsg_compose(ibuf, IMSG_CTL_TABLE_ENABLE, 0, 0, -1,
		    &res->id, sizeof(res->id));
		break;
	case TABLE_DISABLE:
		imsg_compose(ibuf, IMSG_CTL_TABLE_DISABLE, 0, 0, -1,
		    &res->id, sizeof(res->id));
		break;
	case HOST_ENABLE:
		imsg_compose(ibuf, IMSG_CTL_HOST_ENABLE, 0, 0, -1,
		    &res->id, sizeof(res->id));
		break;
	case HOST_DISABLE:
		imsg_compose(ibuf, IMSG_CTL_HOST_DISABLE, 0, 0, -1,
		    &res->id, sizeof(res->id));
		break;
	case SHUTDOWN:
		imsg_compose(ibuf, IMSG_CTL_SHUTDOWN, 0, 0, -1, NULL, 0);
		break;
	case POLL:
		imsg_compose(ibuf, IMSG_CTL_POLL, 0, 0, -1, NULL, 0);
		break;
	case LOAD:
		imsg_compose(ibuf, IMSG_CTL_RELOAD, 0, 0, -1,
		    res->path, strlen(res->path));
		done = 1;
		break;
	case RELOAD:
		imsg_compose(ibuf, IMSG_CTL_RELOAD, 0, 0, -1, NULL, 0);
		done = 1;
		break;
	case MONITOR:
		imsg_compose(ibuf, IMSG_CTL_NOTIFY, 0, 0, -1, NULL, 0);
		break;
	case LOG_VERBOSE:
		verbose = 2;
		/* FALLTHROUGH */
	case LOG_BRIEF:
		imsg_compose(ibuf, IMSG_CTL_VERBOSE, 0, 0, -1,
		    &verbose, sizeof(verbose));
		printf("logging request sent.\n");
		done = 1;
		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 SHOW_SUM:
			case SHOW_HOSTS:
			case SHOW_RDRS:
			case SHOW_RELAYS:
			case SHOW_ROUTERS:
				done = show_summary_msg(&imsg, res->action);
				break;
			case SHOW_SESSIONS:
				done = show_session_msg(&imsg);
				break;
			case RDR_DISABLE:
			case RDR_ENABLE:
			case TABLE_DISABLE:
			case TABLE_ENABLE:
			case HOST_DISABLE:
			case HOST_ENABLE:
			case POLL:
			case SHUTDOWN:
				done = show_command_output(&imsg);
				break;
			case NONE:
			case LOG_VERBOSE:
			case LOG_BRIEF:
			case RELOAD:
			case LOAD:
				break;
			case MONITOR:
				done = monitor(&imsg);
				break;
			}
			imsg_free(&imsg);
		}
	}
	close(ctl_sock);
	free(ibuf);

	return (error ? 1 : 0);
}