示例#1
0
/* 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);
}
示例#2
0
/* 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);
	}
}
示例#3
0
int
mm_answer_pty(int sock, Buffer *m)
{
	extern struct monitor *pmonitor;
	Session *s;
	int res, fd0;

	debug3("%s entering", __func__);

	buffer_clear(m);
	s = session_new();
	if (s == NULL)
		goto error;
	s->authctxt = authctxt;
	s->pw = authctxt->pw;
	s->pid = pmonitor->m_pid;
	res = pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty));
	if (res == 0)
		goto error;
	pty_setowner(authctxt->pw, s->tty);

	buffer_put_int(m, 1);
	buffer_put_cstring(m, s->tty);

	/* We need to trick ttyslot */
	if (dup2(s->ttyfd, 0) == -1)
		fatal("%s: dup2", __func__);

	mm_record_login(s, authctxt->pw);

	/* Now we can close the file descriptor again */
	close(0);

	/* send messages generated by record_login */
	buffer_put_string(m, buffer_ptr(&loginmsg), buffer_len(&loginmsg));
	buffer_clear(&loginmsg);

	mm_request_send(sock, MONITOR_ANS_PTY, m);

	mm_send_fd(sock, s->ptyfd);
	mm_send_fd(sock, s->ttyfd);

	/* make sure nothing uses fd 0 */
	if ((fd0 = open(_PATH_DEVNULL, O_RDONLY)) < 0)
		fatal("%s: open(/dev/null): %s", __func__, strerror(errno));
	if (fd0 != 0)
		error("%s: fd0 %d != 0", __func__, fd0);

	/* slave is not needed */
	close(s->ttyfd);
	s->ttyfd = s->ptyfd;
	/* no need to dup() because nobody closes ptyfd */
	s->ptymaster = s->ptyfd;

	debug3("%s: tty %s ptyfd %d",  __func__, s->tty, s->ttyfd);

	return (0);

 error:
	if (s != NULL)
		mm_session_close(s);
	buffer_put_int(m, 0);
	mm_request_send(sock, MONITOR_ANS_PTY, m);
	return (0);
}
示例#4
0
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);
}