示例#1
0
int
snmp_sendsock(struct imsgev *iev)
{
	struct imsgev		 tmpiev;
	struct sockaddr_un	 sun;
	int			 s = -1;

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

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

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

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

 fail:
	if (s != -1)
		close(s);
	imsg_compose_event(iev, IMSG_NONE, 0, 0, -1, NULL, 0);
	return (-1);
}
示例#2
0
int
queue_api_dispatch(void)
{
	struct passwd	*pw;
	ssize_t		 n;

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

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

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

	imsg_init(&ibuf, 0);

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

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

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

	return (1);
}
示例#3
0
static void
table_proc_close(void *arg)
{
	struct table_proc_priv	*priv = arg;

	imsg_compose(&priv->ibuf, PROC_TABLE_CLOSE, 0, 0, -1, NULL, 0);
	imsg_flush(&priv->ibuf);
}
示例#4
0
static void dispatch(struct imsgbuf* ibuf, enum exec_type program, char* msg) {
    int32_t status = EXEC_RESPONSE_OK;
    char iface[IF_NAMESIZE] = {0};
    static char* buf = NULL;
    if(buf == NULL) { buf = malloc(EXEC_BUF_LEN); }
    if(buf == NULL) { die("Failed to allocate buffer"); }
    buf[0] = '\0';

    // Check if we were provided an interface on which to operate
    bool have_iface = (msg != NULL) &&
                      (msg = (char*)flatjson_next(msg, iface, sizeof(iface), NULL)) != NULL &&
                      validate_iface(iface);

    switch(program) {
        case EXEC_IFCONFIG_LIST_INTERFACES: {
            char* const args[] = {"/sbin/ifconfig", NULL};
            if(run_and_read(args, buf) > 0) { status = EXEC_RESPONSE_ERROR; }
            break;
        }
        case EXEC_IFCONFIG_LIST_PSEUDO_INTERFACES: {
            char* const args[] = {"/sbin/ifconfig", "-C", NULL};
            if(run_and_read(args, buf) > 0) { status = EXEC_RESPONSE_ERROR; }
            break;
        }
        case EXEC_IFCONFIG_DOWN: {
            if(!have_iface) {
                status = EXEC_RESPONSE_ERROR;
                break;
            }

            char* const args[] = {"/sbin/ifconfig", iface, "down", NULL};
            if(run_and_read(args, buf) > 0) { status = EXEC_RESPONSE_ERROR; }
            break;
        }
        case EXEC_NETSTART: {
            if(!have_iface) {
                status = EXEC_RESPONSE_ERROR;
                break;
            }

            char* const args[] = {"/bin/sh", "/etc/netstart", iface, NULL};
            if(run_and_read(args, buf) > 0) { status = EXEC_RESPONSE_ERROR; }
            break;
        }
        case EXEC_LOGEVENT: {
            char* const args[] = {"/usr/libexec/loghwevent", msg, NULL};
            if(run_and_read(args, buf) > 0) { status = EXEC_RESPONSE_ERROR; }
            break;
        }
        default:
            warn("Unknown exec mode");
            break;
    }

    imsg_compose(ibuf, status, 0, 0, -1, buf, strlen(buf) + 1);
    imsg_flush(ibuf);
}
示例#5
0
void
imsg_event_add(struct imsgev *iev)
{
	if (iev->handler == NULL) {
		imsg_flush(&iev->ibuf);
		return;
	}

	iev->events = EV_READ;
	if (iev->ibuf.w.queued)
		iev->events |= EV_WRITE;

	event_del(&iev->ev);
	event_set(&iev->ev, iev->ibuf.fd, iev->events, iev->handler, iev->data);
	event_add(&iev->ev, NULL);
}
示例#6
0
void
m_flush(struct mproc *p)
{
	if (imsg_compose(&p->imsgbuf, p->m_type, p->m_peerid, p->m_pid, p->m_fd,
	    p->m_buf, p->m_pos) == -1)
		fatal("imsg_compose");

	log_trace(TRACE_MPROC, "mproc: %s -> %s : %zu %s (flush)",
	    proc_name(smtpd_process),
	    proc_name(p->proc),
	    p->m_pos,
	    imsg_to_str(p->m_type));

	p->m_pos = 0;

	imsg_flush(&p->imsgbuf);
}
示例#7
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);
}
示例#8
0
/*
 * Check writability not to spin before calling imsg_flush(3).  Wait 'millisec'
 * until it becomes writable.
 */
int
imsg_sync_flush(struct imsgbuf *ibuf, int millisec)
{
	struct pollfd	 fds[1];
	int		 retval;

	if (!ibuf->w.queued)
		return (0);	/* already flushed */

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

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

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

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

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

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

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

	return (ret);
}
示例#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");
}
示例#11
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");
}
示例#12
0
/* ARGSUSED */
void
control_dispatch_imsg(int fd, short event, void *arg)
{
	struct ctl_conn		*c = arg;
	struct control_sock	*cs = c->cs;
	struct snmpd		*env = cs->cs_env;
	struct imsg		 imsg;
	int			 n, v, i;

	if (event & EV_READ) {
		if (((n = imsg_read_nofd(&c->iev.ibuf)) == -1 &&
		    errno != EAGAIN) || n == 0) {
			control_close(c, "could not read imsg", NULL);
			return;
		}
	}
	if (event & EV_WRITE) {
		if (msgbuf_write(&c->iev.ibuf.w) <= 0 && errno != EAGAIN) {
			control_close(c, "could not write imsg", NULL);
			return;
		}
	}

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

		if (n == 0)
			break;

		if (cs->cs_restricted || (c->flags & CTL_CONN_LOCKED)) {
			switch (imsg.hdr.type) {
			case IMSG_SNMP_AGENTX:
			case IMSG_SNMP_ELEMENT:
			case IMSG_SNMP_END:
			case IMSG_SNMP_LOCK:
				break;
			default:
				control_close(c,
				    "client requested restricted command",
				    &imsg);
				return;
			}
		}

		control_imsg_forward(&imsg);

		switch (imsg.hdr.type) {
		case IMSG_CTL_NOTIFY:
			if (IMSG_DATA_SIZE(&imsg))
				return control_close(c, "invalid size", &imsg);

			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_SNMP_LOCK:
			if (IMSG_DATA_SIZE(&imsg))
				return control_close(c, "invalid size", &imsg);

			/* enable restricted control mode */
			c->flags |= CTL_CONN_LOCKED;
			break;

		case IMSG_SNMP_AGENTX:
			if (IMSG_DATA_SIZE(&imsg))
				return control_close(c, "invalid size", &imsg);

			/* rendezvous with the client */
			imsg_compose_event(&c->iev, IMSG_CTL_OK, 0, 0, -1, NULL, 0);
			if (imsg_flush(&c->iev.ibuf) == -1) {
				control_close(c,
				    "could not rendezvous with agentx client",
				    &imsg);
				return;
			}

			/* enable AgentX socket */
			c->handle = snmp_agentx_alloc(c->iev.ibuf.fd);
			if (c->handle == NULL) {
				control_close(c,
				    "could not allocate agentx socket",
				    &imsg);
				return;
			}
			/* disable IMSG notifications */
			c->flags &= ~CTL_CONN_NOTIFY;
			c->flags |= CTL_CONN_LOCKED;
			c->iev.handler = control_dispatch_agentx;
			break;

		case IMSG_CTL_VERBOSE:
			if (IMSG_DATA_SIZE(&imsg) != sizeof(v))
				return control_close(c, "invalid size", &imsg);

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

			for (i = 0; i < PROC_MAX; i++) {
				if (privsep_process == PROC_CONTROL)
					continue;
				proc_forward_imsg(&env->sc_ps, &imsg, i, -1);
			}
			break;
		case IMSG_CTL_RELOAD:
			if (IMSG_DATA_SIZE(&imsg))
				return control_close(c, "invalid size", &imsg);
			proc_forward_imsg(&env->sc_ps, &imsg, PROC_PARENT, -1);
			break;
		default:
			control_close(c, "invalid type", &imsg);
			return;
		}

		imsg_free(&imsg);
	}

	imsg_event_add(&c->iev);
}
示例#13
0
文件: networkd.c 项目: i80and/network
void service_send(struct imsgbuf* ibuf, u_int32_t type, const char* msg) {
    const size_t msg_len = (msg == NULL)? 0 : (strlen(msg) + 1);
    imsg_compose(ibuf, type, 0, 0, -1, msg, msg_len);
    imsg_flush(ibuf);
}
示例#14
0
void
proc_flush_imsg(struct iked *env, enum privsep_procid id)
{
	imsg_flush(&env->sc_ps.ps_ievs[id].ibuf);
}