예제 #1
0
void
control_close(int fd, struct control_sock *cs)
{
	struct ctl_conn	*c;

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

	msgbuf_clear(&c->iev.ibuf.w);
	TAILQ_REMOVE(&ctl_conns, c, entry);

	event_del(&c->iev.ev);
	close(c->iev.ibuf.fd);

	/* Some file descriptors are available again. */
	if (evtimer_pending(&cs->cs_evt, NULL)) {
		evtimer_del(&cs->cs_evt);
		event_add(&cs->cs_ev, NULL);
	}
	npppd_ctl_destroy(c->ctx);

	free(c);
}
예제 #2
0
void
control_close(int fd)
{
	struct ctl_conn	*c;

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

	msgbuf_clear(&c->iev.ibuf.w);
	TAILQ_REMOVE(&ctl_conns, c, entry);

	event_del(&c->iev.ev);
	close(c->iev.ibuf.fd);
	free(c);
	accept_unpause();
}
예제 #3
0
static void
control_imsg(struct imsgev *iev, struct imsg *imsg)
{
	struct ctl_conn	       *c;
	char		       *key;
	struct stat_value	val;

	if (iev->proc == PROC_SMTP) {
		switch (imsg->hdr.type) {
		case IMSG_SMTP_ENQUEUE:
			c = control_connbyfd(imsg->hdr.peerid);
			if (c == NULL)
				return;
			imsg_compose_event(&c->iev, IMSG_CTL_OK, 0, 0,
			    imsg->fd, NULL, 0);
			return;
		}
	}

	switch (imsg->hdr.type) {
	case IMSG_STAT_INCREMENT:
		memmove(&val, imsg->data, sizeof (val));
		key = (char*)imsg->data + sizeof (val);
		if (stat_backend)
			stat_backend->increment(key, val.u.counter);
		return;
	case IMSG_STAT_DECREMENT:
		memmove(&val, imsg->data, sizeof (val));
		key = (char*)imsg->data + sizeof (val);
		if (stat_backend)
			stat_backend->decrement(key, val.u.counter);
		return;
	case IMSG_STAT_SET:
		memmove(&val, imsg->data, sizeof (val));
		key = (char*)imsg->data + sizeof (val);
		if (stat_backend)
			stat_backend->set(key, &val);
		return;
	}

	errx(1, "control_imsg: unexpected %s imsg",
	    imsg_to_str(imsg->hdr.type));
}
예제 #4
0
파일: control.c 프로젝트: jcarnat/OpenSMTPD
void
control_close(int fd)
{
	struct ctl_conn	*c;

	if ((c = control_connbyfd(fd)) == NULL) {
		log_warn("control_close: fd %d: not found", fd);
		return;
	}
	TAILQ_REMOVE(&ctl_conns, c, entry);
	event_del(&c->iev.ev);
	imsg_clear(&c->iev.ibuf);
	close(fd);
	free(c);

	if (stat_decrement(STATS_CONTROL_SESSION) < env->sc_maxconn &&
	    !event_pending(&control_state.ev, EV_READ, NULL)) {
		log_warnx("re-enabling ctl connections");
		event_add(&control_state.ev, NULL);
	}
}
예제 #5
0
파일: control.c 프로젝트: jcarnat/OpenSMTPD
void
control_imsg(struct imsgev *iev, struct imsg *imsg)
{
	struct ctl_conn	*c;

	log_imsg(PROC_CONTROL, iev->proc, imsg);

	if (iev->proc == PROC_SMTP) {
		switch (imsg->hdr.type) {
		case IMSG_SMTP_ENQUEUE:
			c = control_connbyfd(imsg->hdr.peerid);
			if (c == NULL)
				return;
			imsg_compose_event(&c->iev, IMSG_CTL_OK, 0, 0,
			    imsg->fd, NULL, 0);
			return;
		}
	}

	errx(1, "control_imsg: unexpected %s imsg",
	    imsg_to_str(imsg->hdr.type));
}
예제 #6
0
파일: control.c 프로젝트: darksoul42/bitrig
void
control_close(int fd)
{
	struct ctl_conn	*c;

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

	msgbuf_clear(&c->iev.ibuf.w);
	TAILQ_REMOVE(&ctl_conns, c, entry);

	event_del(&c->iev.ev);
	close(c->iev.ibuf.fd);

	/* Some file descriptors are available again. */
	if (evtimer_pending(&control_state.evt, NULL)) {
		evtimer_del(&control_state.evt);
		event_add(&control_state.ev, NULL);
	}

	free(c);
}
예제 #7
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);
}
예제 #8
0
파일: control.c 프로젝트: SylvestreG/bitrig
/* 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);
}
예제 #9
0
파일: control.c 프로젝트: jcarnat/OpenSMTPD
/* 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);
}
예제 #10
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);
}
예제 #11
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);
}
예제 #12
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);
}
예제 #13
0
파일: control.c 프로젝트: darksoul42/bitrig
/* 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_warnx("%s: fd %d: not found", __func__, fd);
		return;
	}

	if (event & EV_READ) {
		if (((n = imsg_read(&c->iev.ibuf)) == -1 && errno != EAGAIN) ||
		    n == 0) {
			control_close(fd);
			return;
		}
	}
	if (event & EV_WRITE) {
		if (msgbuf_write(&c->iev.ibuf.w) <= 0 && 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_FIB_COUPLE:
		case IMSG_CTL_FIB_DECOUPLE:
		case IMSG_CTL_RELOAD:
			c->iev.ibuf.pid = imsg.hdr.pid;
			eigrpe_imsg_compose_parent(imsg.hdr.type, 0, NULL, 0);
			break;
		case IMSG_CTL_KROUTE:
		case IMSG_CTL_IFINFO:
			c->iev.ibuf.pid = imsg.hdr.pid;
			eigrpe_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))
				break;

			memcpy(&ifidx, imsg.data, sizeof(ifidx));
			eigrpe_iface_ctl(c, ifidx);
			imsg_compose_event(&c->iev, IMSG_CTL_END, 0,
			    0, -1, NULL, 0);
			break;
		case IMSG_CTL_SHOW_TOPOLOGY:
			if (imsg.hdr.len != IMSG_HEADER_SIZE +
			    sizeof(struct ctl_show_topology_req))
				break;

			c->iev.ibuf.pid = imsg.hdr.pid;
			eigrpe_imsg_compose_rde(imsg.hdr.type, 0, imsg.hdr.pid,
			    imsg.data, imsg.hdr.len - IMSG_HEADER_SIZE);
			break;
		case IMSG_CTL_SHOW_NBR:
			eigrpe_nbr_ctl(c);
			break;
		case IMSG_CTL_SHOW_STATS:
			eigrpe_stats_ctl(c);
			break;
		case IMSG_CTL_CLEAR_NBR:
			if (imsg.hdr.len != IMSG_HEADER_SIZE +
			    sizeof(struct ctl_nbr))
				break;

			nbr_clear_ctl(imsg.data);
			break;
		case IMSG_CTL_LOG_VERBOSE:
			if (imsg.hdr.len != IMSG_HEADER_SIZE +
			    sizeof(verbose))
				break;

			/* forward to other processes */
			eigrpe_imsg_compose_parent(imsg.hdr.type, imsg.hdr.pid,
			    imsg.data, imsg.hdr.len - IMSG_HEADER_SIZE);
			eigrpe_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("%s: error handling imsg %d", __func__,
			    imsg.hdr.type);
			break;
		}
		imsg_free(&imsg);
	}

	imsg_event_add(&c->iev);
}
예제 #14
0
파일: control.c 프로젝트: ajinkya93/OpenBSD
/* ARGSUSED */
void
control_dispatch_imsg(int fd, short event, void *arg)
{
	struct control_sock	*cs = arg;
	struct ctl_conn		*c;
	struct imsg		 imsg;
	struct ctl_id		 id;
	int			 n;
	int			 verbose;
	struct relayd		*env = cs->cs_env;

	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 && errno != EAGAIN) ||
		    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;

		if (c->waiting) {
			log_debug("%s: unexpected imsg %d",
			    __func__, imsg.hdr.type);
			imsg_free(&imsg);
			control_close(fd, cs);
			return;
		}

		switch (imsg.hdr.type) {
		case IMSG_CTL_SHOW_SUM:
			show(c);
			break;
		case IMSG_CTL_SESSION:
			show_sessions(c);
			break;
		case IMSG_CTL_RDR_DISABLE:
			if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(id))
				fatalx("invalid imsg header len");
			memcpy(&id, imsg.data, sizeof(id));
			if (disable_rdr(c, &id))
				imsg_compose_event(&c->iev, IMSG_CTL_FAIL,
				    0, 0, -1, NULL, 0);
			else {
				memcpy(imsg.data, &id, sizeof(id));
				control_imsg_forward(&imsg);
				imsg_compose_event(&c->iev, IMSG_CTL_OK,
				    0, 0, -1, NULL, 0);
			}
			break;
		case IMSG_CTL_RDR_ENABLE:
			if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(id))
				fatalx("invalid imsg header len");
			memcpy(&id, imsg.data, sizeof(id));
			if (enable_rdr(c, &id))
				imsg_compose_event(&c->iev, IMSG_CTL_FAIL,
				    0, 0, -1, NULL, 0);
			else {
				memcpy(imsg.data, &id, sizeof(id));
				control_imsg_forward(&imsg);
				imsg_compose_event(&c->iev, IMSG_CTL_OK,
				    0, 0, -1, NULL, 0);
			}
			break;
		case IMSG_CTL_TABLE_DISABLE:
			if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(id))
				fatalx("invalid imsg header len");
			memcpy(&id, imsg.data, sizeof(id));
			if (disable_table(c, &id))
				imsg_compose_event(&c->iev, IMSG_CTL_FAIL,
				    0, 0, -1, NULL, 0);
			else {
				memcpy(imsg.data, &id, sizeof(id));
				control_imsg_forward(&imsg);
				imsg_compose_event(&c->iev, IMSG_CTL_OK,
				    0, 0, -1, NULL, 0);
			}
			break;
		case IMSG_CTL_TABLE_ENABLE:
			if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(id))
				fatalx("invalid imsg header len");
			memcpy(&id, imsg.data, sizeof(id));
			if (enable_table(c, &id))
				imsg_compose_event(&c->iev, IMSG_CTL_FAIL,
				    0, 0, -1, NULL, 0);
			else {
				memcpy(imsg.data, &id, sizeof(id));
				control_imsg_forward(&imsg);
				imsg_compose_event(&c->iev, IMSG_CTL_OK,
				    0, 0, -1, NULL, 0);
			}
			break;
		case IMSG_CTL_HOST_DISABLE:
			if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(id))
				fatalx("invalid imsg header len");
			memcpy(&id, imsg.data, sizeof(id));
			if (disable_host(c, &id, NULL))
				imsg_compose_event(&c->iev, IMSG_CTL_FAIL,
				    0, 0, -1, NULL, 0);
			else {
				memcpy(imsg.data, &id, sizeof(id));
				control_imsg_forward(&imsg);
				imsg_compose_event(&c->iev, IMSG_CTL_OK,
				    0, 0, -1, NULL, 0);
			}
			break;
		case IMSG_CTL_HOST_ENABLE:
			if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(id))
				fatalx("invalid imsg header len");
			memcpy(&id, imsg.data, sizeof(id));
			if (enable_host(c, &id, NULL))
				imsg_compose_event(&c->iev, IMSG_CTL_FAIL,
				    0, 0, -1, NULL, 0);
			else {
				memcpy(imsg.data, &id, sizeof(id));
				control_imsg_forward(&imsg);
				imsg_compose_event(&c->iev, IMSG_CTL_OK,
				    0, 0, -1, NULL, 0);
			}
			break;
		case IMSG_CTL_SHUTDOWN:
		case IMSG_CTL_RELOAD:
			proc_forward_imsg(env->sc_ps, &imsg, PROC_PARENT, -1);
			break;
		case IMSG_CTL_POLL:
			proc_compose(env->sc_ps, PROC_HCE, IMSG_CTL_POLL, NULL, 0);
			imsg_compose_event(&c->iev, IMSG_CTL_OK,
			    0, 0, -1, NULL, 0);
			break;
		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, &verbose);

			memcpy(&verbose, imsg.data, sizeof(verbose));

			proc_forward_imsg(env->sc_ps, &imsg, PROC_PARENT, -1);
			proc_forward_imsg(env->sc_ps, &imsg, PROC_HCE, -1);
			proc_forward_imsg(env->sc_ps, &imsg, PROC_RELAY, -1);

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

	imsg_event_add(&c->iev);
}