コード例 #1
0
ファイル: monitor.c プロジェクト: mohammadhamad/mhhgen
/* Privileged: called by monitor_loop.  */
static void
m_priv_setsockopt(void)
{
	int		 sock, level, optname, v;
	int		 err = 0;
	char		*optval = 0;
	socklen_t	 optlen;

	sock = mm_receive_fd(m_state.s);
	if (sock < 0) {
		log_print("m_priv_setsockopt: read/write error");
		return;
	}

	must_read(&level, sizeof level);
	must_read(&optname, sizeof optname);
	must_read(&optlen, sizeof optlen);

	optval = (char *)malloc(optlen);
	if (!optval) {
		log_print("m_priv_setsockopt: malloc failed");
		close(sock);
		return;
	}

	must_read(optval, optlen);

	if (m_priv_check_sockopt(level, optname) != 0) {
		err = EACCES;
		v = -1;
	} else {
		v = setsockopt(sock, level, optname, optval, optlen);
		if (v < 0)
			err = errno;
	}

	close(sock);
	sock = -1;

	must_write(&err, sizeof err);
	must_write(&v, sizeof v);

	free(optval);
	return;
}
コード例 #2
0
ファイル: priv.c プロジェクト: ajufrancis/lldpd
/* Proxies */
static void
priv_ping()
{
	int rc;
	enum priv_cmd cmd = PRIV_PING;
	must_write(&cmd, sizeof(enum priv_cmd));
	must_read(&rc, sizeof(int));
	log_debug("privsep", "monitor ready");
}
コード例 #3
0
ファイル: priv.c プロジェクト: davidmorel/lldpd
static void
asroot_iface_promisc()
{
	char name[IFNAMSIZ];
	int rc;
	must_read(PRIV_PRIVILEGED, &name, sizeof(name));
	name[sizeof(name) - 1] = '\0';
	rc = asroot_iface_promisc_os(name);
	must_write(PRIV_PRIVILEGED, &rc, sizeof(rc));
}
コード例 #4
0
ファイル: monitor.c プロジェクト: mohammadhamad/mhhgen
/* Privileged: called by monitor_loop.  */
static void
m_priv_bind(void)
{
	int		 sock, v, err = 0;
	struct sockaddr *name = 0;
	socklen_t        namelen;

	sock = mm_receive_fd(m_state.s);
	if (sock < 0) {
		log_print("m_priv_bind: read/write error");
		return;
	}

	must_read(&namelen, sizeof namelen);
	name = (struct sockaddr *)malloc(namelen);
	if (!name) {
		log_print("m_priv_bind: malloc failed");
		close(sock);
		return;
	}
	must_read((char *)name, namelen);

	if (m_priv_check_bind(name, namelen) != 0) {
		err = EACCES;
		v = -1;
	} else {
		v = bind(sock, name, namelen);
		if (v < 0) {
			log_error("m_priv_bind: bind(%d,%p,%d) returned %d",
			    sock, name, namelen, v);
			err = errno;
		}
	}

	close(sock);
	sock = -1;

	must_write(&err, sizeof err);
	must_write(&v, sizeof v);

	free(name);
	return;
}
コード例 #5
0
ファイル: priv.c プロジェクト: davidmorel/lldpd
/* Proxies */
static void
priv_ping()
{
	int rc;
	enum priv_cmd cmd = PRIV_PING;
	must_write(PRIV_UNPRIVILEGED, &cmd, sizeof(enum priv_cmd));
	priv_wait();
	must_read(PRIV_UNPRIVILEGED, &rc, sizeof(int));
	log_debug("privsep", "monitor ready");
}
コード例 #6
0
ファイル: monitor.c プロジェクト: mohammadhamad/mhhgen
int
monitor_req_readdir(const char *filename)
{
	int cmd, err;
	size_t len;

	cmd = MONITOR_REQ_READDIR;
	must_write(&cmd, sizeof cmd);

	len = strlen(filename);
	must_write(&len, sizeof len);
	must_write(filename, len);

	must_read(&err, sizeof err);
	if (err == -1)
		must_read(&errno, sizeof errno);

	return err;
}
コード例 #7
0
ファイル: privsep.c プロジェクト: ele7enxxh/dtrace-pf
/*
 * send the snaplength to privileged process
 */
int
priv_set_snaplen(int snaplen)
{
	int cmd, ret;

	if (priv_fd < 0)
		errx(1, "%s: called from privileged portion", __func__);

	cmd = PRIV_SET_SNAPLEN;

	must_write(priv_fd, &cmd, sizeof(int));
	must_write(priv_fd, &snaplen, sizeof(int));

	must_read(priv_fd, &ret, sizeof(int));

	/* also set hpcap->snapshot in child */
	if (ret == 0)
		hpcap->snapshot = snaplen;

	return (ret);
}
コード例 #8
0
ファイル: priv.c プロジェクト: ajufrancis/lldpd
/* Proxy for gethostbyname */
char *
priv_gethostbyname()
{
	static char *buf = NULL;
	int rc;
	enum priv_cmd cmd = PRIV_GET_HOSTNAME;
	must_write(&cmd, sizeof(enum priv_cmd));
	must_read(&rc, sizeof(int));
	if ((buf = (char*)realloc(buf, rc+1)) == NULL)
		fatal("privsep", NULL);
	must_read(buf, rc+1);
	return buf;
}
コード例 #9
0
ファイル: priv.c プロジェクト: ajufrancis/lldpd
static void
asroot_gethostbyname()
{
	struct utsname un;
	struct hostent *hp;
	int len;
	if (uname(&un) < 0)
		fatal("privsep", "failed to get system information");
	if ((hp = gethostbyname(un.nodename)) == NULL) {
		log_info("privsep", "unable to get system name");
#ifdef HAVE_RES_INIT
		res_init();
#endif
                len = strlen(un.nodename);
                must_write(&len, sizeof(int));
                must_write(un.nodename, len + 1);
        } else {
                len = strlen(hp->h_name);
                must_write(&len, sizeof(int));
                must_write(hp->h_name, len + 1);
        }
}
コード例 #10
0
ファイル: privsep.c プロジェクト: ele7enxxh/dtrace-pf
/* Move-away and reopen log-file */
int
priv_move_log(void)
{
	int cmd, ret;

	if (priv_fd < 0)
		errx(1, "%s: called from privileged portion\n", __func__);

	cmd = PRIV_MOVE_LOG;
	must_write(priv_fd, &cmd, sizeof(int));
	must_read(priv_fd, &ret, sizeof(int));

	return (ret);
}
コード例 #11
0
ファイル: privsep.c プロジェクト: SylvestreG/bitrig
/* Bind to allowed privileged ports using privsep, or try to bind locally */
int
isc_priv_bind(int fd, struct sockaddr *sa, socklen_t salen)
{
	int status, er;

	if (priv_fd < 0)
		errx(1, "%s called from privileged portion", __func__);

	if (check_bind(sa, salen)) {
		status = bind(fd, sa, salen);
	} else {
		logmsg(LOG_DEBUG, "Binding privsep");
		write_command(priv_fd, PRIV_BIND);
		send_fd(priv_fd, fd);
		must_write(priv_fd, &salen, sizeof(salen));
		must_write(priv_fd, sa, salen);
		must_read(priv_fd, &er, sizeof(er));
		must_read(priv_fd, &status, sizeof(status));
		errno = er;
	}

	return (status);
}
コード例 #12
0
ファイル: privsep.c プロジェクト: ele7enxxh/dtrace-pf
/* Open log-file */
int
priv_open_log(void)
{
	int cmd, fd;

	if (priv_fd < 0)
		errx(1, "%s: called from privileged portion", __func__);

	cmd = PRIV_OPEN_LOG;
	must_write(priv_fd, &cmd, sizeof(int));
	fd = receive_fd(priv_fd);

	return (fd);
}
コード例 #13
0
ファイル: priv.c プロジェクト: ajufrancis/lldpd
static void
asroot_iface_init()
{
	int rc = -1, fd = -1;
	int ifindex;
	char name[IFNAMSIZ];
	must_read(&ifindex, sizeof(ifindex));
	must_read(&name, sizeof(name));
	name[sizeof(name) - 1] = '\0';

	rc = asroot_iface_init_os(ifindex, name, &fd);
	must_write(&rc, sizeof(rc));
	if (rc == 0 && fd >=0) send_fd(fd);
	if (fd >= 0) close(fd);
}
コード例 #14
0
ファイル: priv.c プロジェクト: davidmorel/lldpd
/* Proxy for gethostname */
char *
priv_gethostname()
{
	static char *buf = NULL;
	int rc;
	enum priv_cmd cmd = PRIV_GET_HOSTNAME;
	must_write(PRIV_UNPRIVILEGED, &cmd, sizeof(enum priv_cmd));
	priv_wait();
	must_read(PRIV_UNPRIVILEGED, &rc, sizeof(int));
	if ((buf = (char*)realloc(buf, rc+1)) == NULL)
		fatal("privsep", NULL);
	must_read(PRIV_UNPRIVILEGED, buf, rc);
	buf[rc] = '\0';
	return buf;
}
コード例 #15
0
ファイル: priv.c プロジェクト: ajufrancis/lldpd
static void
asroot_snmp_socket()
{
	int sock, rc;
	static struct sockaddr_un *addr = NULL;
	struct sockaddr_un bogus;

	if (!addr) {
		addr = (struct sockaddr_un *)malloc(sizeof(struct sockaddr_un));
		must_read(addr, sizeof(struct sockaddr_un));
	} else
		/* We have already been asked to connect to a socket. We will
		 * connect to the same socket. */
		must_read(&bogus, sizeof(struct sockaddr_un));
	if (addr->sun_family != AF_UNIX)
		fatal("privsep", "someone is trying to trick me");
	addr->sun_path[sizeof(addr->sun_path)-1] = '\0';

	if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
		log_warn("privsep", "cannot open socket");
		must_write(&sock, sizeof(int));
		return;
	}
        if ((rc = connect(sock, (struct sockaddr *) addr,
		    sizeof(struct sockaddr_un))) != 0) {
		log_info("privsep", "cannot connect to %s: %s",
                          addr->sun_path, strerror(errno));
		close(sock);
		rc = -1;
		must_write(&rc, sizeof(int));
		return;
        }
	must_write(&rc, sizeof(int));
	send_fd(sock);
	close(sock);
}
コード例 #16
0
ファイル: priv.c プロジェクト: davidmorel/lldpd
static void
asroot_iface_init()
{
	int rc = -1, fd = -1;
	int ifindex;
	char name[IFNAMSIZ];
	must_read(PRIV_PRIVILEGED, &ifindex, sizeof(ifindex));
	must_read(PRIV_PRIVILEGED, &name, sizeof(name));
	name[sizeof(name) - 1] = '\0';

	TRACE(LLDPD_PRIV_INTERFACE_INIT(name));
	rc = asroot_iface_init_os(ifindex, name, &fd);
	must_write(PRIV_PRIVILEGED, &rc, sizeof(rc));
	if (rc == 0 && fd >=0) send_fd(PRIV_PRIVILEGED, fd);
	if (fd >= 0) close(fd);
}
コード例 #17
0
ファイル: priv.c プロジェクト: ajufrancis/lldpd
static void
asroot_iface_description()
{
	char name[IFNAMSIZ];
	char *description;
	int len, rc;
	must_read(&name, sizeof(name));
	name[sizeof(name) - 1] = '\0';
	must_read(&len, sizeof(int));
	if ((description = (char*)malloc(len+1)) == NULL)
		fatal("description", NULL);

	must_read(description, len);
	description[len] = 0;
	rc = asroot_iface_description_os(name, description);
	must_write(&rc, sizeof(rc));
}
コード例 #18
0
ファイル: monitor.c プロジェクト: mohammadhamad/mhhgen
/* Privileged: called by monitor_loop.  */
static void
m_priv_pfkey_open(void)
{
	int	fd, err = 0;

	fd = pf_key_v2_open();
	if (fd < 0)
		err = -1;

	must_write(&err, sizeof err);

	if (fd > 0 && mm_send_fd(m_state.s, fd)) {
		log_error("m_priv_pfkey_open: read/write operation failed");
		close(fd);
		return;
	}
	close(fd);
}
コード例 #19
0
ファイル: priv.c プロジェクト: davidmorel/lldpd
static void
asroot_iface_description()
{
	char name[IFNAMSIZ];
	char *description;
	int len, rc;
	must_read(PRIV_PRIVILEGED, &name, sizeof(name));
	name[sizeof(name) - 1] = '\0';
	must_read(PRIV_PRIVILEGED, &len, sizeof(int));
	if ((description = (char*)malloc(len+1)) == NULL)
		fatal("description", NULL);

	must_read(PRIV_PRIVILEGED, description, len);
	description[len] = 0;
	TRACE(LLDPD_PRIV_INTERFACE_DESCRIPTION(name, description));
	rc = asroot_iface_description_os(name, description);
	must_write(PRIV_PRIVILEGED, &rc, sizeof(rc));
	free(description);
}
コード例 #20
0
ファイル: priv.c プロジェクト: davidmorel/lldpd
static void
asroot_ctl_cleanup()
{
	int len;
	char *ctlname;
	int rc = 0;

	must_read(PRIV_PRIVILEGED, &len, sizeof(int));
	if ((ctlname = (char*)malloc(len+1)) == NULL)
		fatal("ctlname", NULL);

	must_read(PRIV_PRIVILEGED, ctlname, len);
	ctlname[len] = 0;

	ctl_cleanup(ctlname);
	free(ctlname);

	/* Ack */
	must_write(PRIV_PRIVILEGED, &rc, sizeof(int));
}
コード例 #21
0
ファイル: monitor.c プロジェクト: mohammadhamad/mhhgen
/* Privileged: called by monitor_loop.  */
static void
m_priv_getfd(void)
{
	char	path[MAXPATHLEN];
	size_t	len;
	int	v, flags, ret;
	int	err = 0;
	mode_t	mode;

	must_read(&len, sizeof len);
	if (len == 0 || len >= sizeof path)
		log_fatal("m_priv_getfd: invalid pathname length");

	must_read(path, len);
	path[len] = '\0';
	if (strlen(path) != len)
		log_fatal("m_priv_getfd: invalid pathname");

	must_read(&flags, sizeof flags);
	must_read(&mode, sizeof mode);

	if ((ret = m_priv_local_sanitize_path(path, sizeof path, flags))
	    != 0) {
		if (ret == 1)
			log_print("m_priv_getfd: illegal path \"%s\"", path);
		err = EACCES;
		v = -1;
	} else {
		if ((v = open(path, flags, mode)) == -1)
			err = errno;
	}

	must_write(&err, sizeof err);

	if (v != -1) {
		if (mm_send_fd(m_state.s, v) == -1)
			log_error("m_priv_getfd: sending fd failed");
		close(v);
	}
}
コード例 #22
0
ファイル: priv.c プロジェクト: davidmorel/lldpd
static void
asroot_iface_multicast()
{
	int sock = -1, add, rc = 0;
	struct ifreq ifr = { .ifr_name = {} };
	must_read(PRIV_PRIVILEGED, ifr.ifr_name, IFNAMSIZ);
#if defined HOST_OS_LINUX
	must_read(PRIV_PRIVILEGED, ifr.ifr_hwaddr.sa_data, ETHER_ADDR_LEN);
#elif defined HOST_OS_FREEBSD || defined HOST_OS_OSX || defined HOST_OS_DRAGONFLY
	/* Black magic from mtest.c */
	struct sockaddr_dl *dlp = ALIGNED_CAST(struct sockaddr_dl *, &ifr.ifr_addr);
	dlp->sdl_len = sizeof(struct sockaddr_dl);
	dlp->sdl_family = AF_LINK;
	dlp->sdl_index = 0;
	dlp->sdl_nlen = 0;
	dlp->sdl_alen = ETHER_ADDR_LEN;
	dlp->sdl_slen = 0;
	must_read(PRIV_PRIVILEGED, LLADDR(dlp), ETHER_ADDR_LEN);
#elif defined HOST_OS_OPENBSD || defined HOST_OS_NETBSD || defined HOST_OS_SOLARIS
	struct sockaddr *sap = (struct sockaddr *)&ifr.ifr_addr;
#if ! defined HOST_OS_SOLARIS
	sap->sa_len = sizeof(struct sockaddr);
#endif
	sap->sa_family = AF_UNSPEC;
	must_read(PRIV_PRIVILEGED, sap->sa_data, ETHER_ADDR_LEN);
#else
#error Unsupported OS
#endif

	must_read(PRIV_PRIVILEGED, &add, sizeof(int));
	if (((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1) ||
	    ((ioctl(sock, (add)?SIOCADDMULTI:SIOCDELMULTI,
		    &ifr) < 0) && (errno != EADDRINUSE)))
		rc = errno;

	if (sock != -1) close(sock);
	must_write(PRIV_PRIVILEGED, &rc, sizeof(rc));
}
コード例 #23
0
ファイル: inject_randr1.5.c プロジェクト: bsmr-i3/i3
static void read_client_x11_packet_cb(EV_P_ ev_io *w, int revents) {
    struct connstate *connstate = (struct connstate *)w->data;

    void *request = smalloc(sizeof(generic_x11_request_t));
    must_read(readall_into(request, sizeof(generic_x11_request_t), connstate->clientw->fd));
    const size_t len = (((generic_x11_request_t *)request)->length * 4);
    if (len > sizeof(generic_x11_request_t)) {
        request = srealloc(request, len);
        must_read(readall_into(request + sizeof(generic_x11_request_t),
                               len - sizeof(generic_x11_request_t),
                               connstate->clientw->fd));
    }

    // XXX: sequence counter wrapping is not implemented, but should not be
    // necessary given that this tool is scoped for test cases.
    connstate->sequence++;

    /* BEGIN RandR 1.5 specific */
    const uint8_t opcode = ((generic_x11_request_t *)request)->opcode;
    if (opcode == XCB_QUERY_EXTENSION) {
        xcb_query_extension_request_t *req = request;
        const char *name = request + sizeof(xcb_query_extension_request_t);
        if (req->name_len == strlen("RANDR") &&
            strncmp(name, "RANDR", strlen("RANDR")) == 0) {
            connstate->getext_randr = connstate->sequence;
        }
    } else if (opcode == connstate->randr_major_opcode) {
        const uint8_t randr_opcode = ((generic_x11_request_t *)request)->pad0;
        if (randr_opcode == XCB_RANDR_GET_MONITORS) {
            connstate->getmonitors = connstate->sequence;
        }
    }
    /* END RandR 1.5 specific */

    must_write(writeall(connstate->serverw->fd, request, len));
    free(request);
}
コード例 #24
0
ファイル: monitor.c プロジェクト: mohammadhamad/mhhgen
static void
m_priv_req_readdir()
{
	size_t len;
	char path[MAXPATHLEN];
	DIR *dp;
	struct dirent *file;
	struct stat sb;
	int off, size, fd, ret, serrno;

	must_read(&len, sizeof len);
	if (len == 0 || len >= sizeof path)
		log_fatal("m_priv_req_readdir: invalid pathname length");
	must_read(path, len);
	path[len] = '\0';
	if (strlen(path) != len)
		log_fatal("m_priv_req_readdir: invalid pathname");

	off = strlen(path);
	size = sizeof path - off;

	if ((dp = opendir(path)) == NULL) {
		serrno = errno;
		ret = -1;
		must_write(&ret, sizeof ret);
		must_write(&serrno, sizeof serrno);
		return;
	}

	/* report opendir() success */
	ret = 0;
	must_write(&ret, sizeof ret);

	while ((file = readdir(dp)) != NULL) {
		strlcpy(path + off, file->d_name, size);

		if (m_priv_local_sanitize_path(path, sizeof path, O_RDONLY)
		    != 0)
			continue;
		fd = open(path, O_RDONLY, 0);
		if (fd == -1) {
			log_error("m_priv_req_readdir: open "
			    "(\"%s\", O_RDONLY, 0) failed", path);
			continue;
		}
		if ((fstat(fd, &sb) == -1) ||
		    !(S_ISREG(sb.st_mode) || S_ISLNK(sb.st_mode))) {
			close(fd);
			continue;
		}

		len = strlen(path);
		must_write(&len, sizeof len);
		must_write(path, len);

		mm_send_fd(m_state.s, fd);
		close(fd);
	}
	closedir(dp);

	len = 0;
	must_write(&len, sizeof len);
}
コード例 #25
0
ファイル: priv.c プロジェクト: ajufrancis/lldpd
static void
asroot_ping()
{
	int rc = 1;
	must_write(&rc, sizeof(int));
}
コード例 #26
0
ファイル: privsep_pcap.c プロジェクト: ajinkya93/OpenBSD
/*
 * XXX reimplement pcap_open_live with privsep, this is the
 * unprivileged part.
 */
pcap_t *
priv_pcap_live(const char *dev, int slen, int prom, int to_ms,
    char *ebuf, u_int dlt, u_int dirfilt)
{
	int fd, err;
	struct bpf_version bv;
	u_int v;
	pcap_t *p;

	if (priv_fd < 0)
		errx(1, "%s: called from privileged portion", __func__);

	if (dev == NULL) {
		snprintf(ebuf, PCAP_ERRBUF_SIZE, "No interface specified");
		return (NULL);
	}

	p = malloc(sizeof(*p));
	if (p == NULL) {
		snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
		    pcap_strerror(errno));
		return (NULL);
	}

	bzero(p, sizeof(*p));

	write_command(priv_fd, PRIV_OPEN_BPF);
	must_write(priv_fd, &slen, sizeof(int));
	must_write(priv_fd, &prom, sizeof(int));
	must_write(priv_fd, &dlt, sizeof(u_int));
	must_write(priv_fd, &dirfilt, sizeof(u_int));
	write_string(priv_fd, dev);

	fd = receive_fd(priv_fd);
	must_read(priv_fd, &err, sizeof(int));
	if (fd < 0) {
		snprintf(ebuf, PCAP_ERRBUF_SIZE,
		    "Failed to open bpf device for %s: %s",
		    dev, strerror(err));
		goto bad;
	}

	/* fd is locked, can only use 'safe' ioctls */
	if (ioctl(fd, BIOCVERSION, &bv) < 0) {
		snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCVERSION: %s",
		    pcap_strerror(errno));
		goto bad;
	}

	if (bv.bv_major != BPF_MAJOR_VERSION ||
	    bv.bv_minor < BPF_MINOR_VERSION) {
		snprintf(ebuf, PCAP_ERRBUF_SIZE,
		    "kernel bpf filter out of date");
		goto bad;
	}

	p->fd = fd;
	p->snapshot = slen;

	/* Get the data link layer type. */
	if (ioctl(fd, BIOCGDLT, &v) < 0) {
		snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCGDLT: %s",
		    pcap_strerror(errno));
		goto bad;
	}
	p->linktype = v;

	/* XXX hack */
	if (p->linktype == DLT_PFLOG && p->snapshot < 160)
		p->snapshot = 160;

	/* set timeout */
	if (to_ms != 0) {
		struct timeval to;
		to.tv_sec = to_ms / 1000;
		to.tv_usec = (to_ms * 1000) % 1000000;
		if (ioctl(p->fd, BIOCSRTIMEOUT, &to) < 0) {
			snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCSRTIMEOUT: %s",
			    pcap_strerror(errno));
			goto bad;
		}
	}

	if (ioctl(fd, BIOCGBLEN, &v) < 0) {
		snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCGBLEN: %s",
		    pcap_strerror(errno));
		goto bad;
	}
	p->bufsize = v;
	p->buffer = malloc(p->bufsize);
	if (p->buffer == NULL) {
		snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
		    pcap_strerror(errno));
		goto bad;
	}
	return (p);

 bad:
	if (fd >= 0)
		close(fd);
	free(p);
	return (NULL);
}
コード例 #27
0
ファイル: privsep.c プロジェクト: ele7enxxh/dtrace-pf
/* based on syslogd privsep */
int
priv_init(void)
{
	int i, fd, socks[2], cmd;
	int snaplen, ret, olderrno;
	struct passwd *pw;

#ifdef __FreeBSD__
	for (i = 1; i < NSIG; i++)
#else
	for (i = 1; i < _NSIG; i++)
#endif
		signal(i, SIG_DFL);

	/* Create sockets */
	if (socketpair(AF_LOCAL, SOCK_STREAM, PF_UNSPEC, socks) == -1)
		err(1, "socketpair() failed");

	pw = getpwnam("_pflogd");
	if (pw == NULL)
		errx(1, "unknown user _pflogd");
	endpwent();

	child_pid = fork();
	if (child_pid < 0)
		err(1, "fork() failed");

	if (!child_pid) {
		gid_t gidset[1];

		/* Child - drop privileges and return */
		if (chroot(pw->pw_dir) != 0)
			err(1, "unable to chroot");
		if (chdir("/") != 0)
			err(1, "unable to chdir");

		gidset[0] = pw->pw_gid;
		if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) == -1)
			err(1, "setresgid() failed");
		if (setgroups(1, gidset) == -1)
			err(1, "setgroups() failed");
		if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) == -1)
			err(1, "setresuid() failed");
		close(socks[0]);
		priv_fd = socks[1];
		return 0;
	}

	/* Father */
	/* Pass ALRM/TERM/HUP/INT/QUIT through to child, and accept CHLD */
	signal(SIGALRM, sig_pass_to_chld);
	signal(SIGTERM, sig_pass_to_chld);
	signal(SIGHUP,  sig_pass_to_chld);
	signal(SIGINT,  sig_pass_to_chld);
	signal(SIGQUIT,  sig_pass_to_chld);
	signal(SIGCHLD, sig_chld);

	setproctitle("[priv]");
	close(socks[1]);

	while (!gotsig_chld) {
		if (may_read(socks[0], &cmd, sizeof(int)))
			break;
		switch (cmd) {
		case PRIV_SET_SNAPLEN:
			logmsg(LOG_DEBUG,
			    "[priv]: msg PRIV_SET_SNAPLENGTH received");
			must_read(socks[0], &snaplen, sizeof(int));

			ret = set_snaplen(snaplen);
			if (ret) {
				logmsg(LOG_NOTICE,
				   "[priv]: set_snaplen failed for snaplen %d",
				   snaplen);
			}

			must_write(socks[0], &ret, sizeof(int));
			break;

		case PRIV_OPEN_LOG:
			logmsg(LOG_DEBUG,
			    "[priv]: msg PRIV_OPEN_LOG received");
			/* create or append logs but do not follow symlinks */
			fd = open(filename,
			    O_RDWR|O_CREAT|O_APPEND|O_NONBLOCK|O_NOFOLLOW,
			    0600);
			olderrno = errno;
			send_fd(socks[0], fd);
			if (fd < 0)
				logmsg(LOG_NOTICE,
				    "[priv]: failed to open %s: %s",
				    filename, strerror(olderrno));
			else
				close(fd);
			break;

		case PRIV_MOVE_LOG:
			logmsg(LOG_DEBUG,
			    "[priv]: msg PRIV_MOVE_LOG received");
			ret = move_log(filename);
			must_write(socks[0], &ret, sizeof(int));
			break;

		default:
			logmsg(LOG_ERR, "[priv]: unknown command %d", cmd);
			_exit(1);
			/* NOTREACHED */
		}
	}

	_exit(1);
}
コード例 #28
0
ファイル: privsep.c プロジェクト: SylvestreG/bitrig
/* write a command to the peer */
static void
write_command(int fd, int cmd)
{
	must_write(fd, &cmd, sizeof(cmd));
}
コード例 #29
0
ファイル: priv.c プロジェクト: davidmorel/lldpd
static void
asroot_ping()
{
	int rc = 1;
	must_write(PRIV_PRIVILEGED, &rc, sizeof(int));
}