Пример #1
0
/* Main loop, run as root */
static void
priv_loop(int privileged, int once)
{
	enum priv_cmd cmd;
	struct dispatch_actions *a;

#ifdef ENABLE_PRIVSEP
	setproctitle("monitor");
#ifdef USE_SECCOMP
	if (priv_seccomp_init(privileged, monitored) != 0)
	   fatal("privsep", "cannot continue without seccomp setup");
#endif
#endif
	while (!may_read(PRIV_PRIVILEGED, &cmd, sizeof(enum priv_cmd))) {
		log_debug("privsep", "received command %d", cmd);
		for (a = actions; a->function != NULL; a++) {
			if (cmd == a->msg) {
				a->function();
				break;
			}
		}
		if (a->function == NULL)
			fatalx("privsep", "bogus message received");
		if (once) break;
	}
}
Пример #2
0
int
isc_priv_init(int lstderr)
{
	int i, socks[2], cmd;

	logmsg(LOG_NOTICE, "Starting privilege separation");

	log_stderr = lstderr;

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

	switch (child_pid = fork()) {
	case -1:
		fatal("failed to fork() for privsep");
	case 0:
		close(socks[0]);
		priv_fd = socks[1];
		return (0);
	default:
		break;
	}

	for (i = 1; i < _NSIG; i++)
		signal(i, SIG_DFL);

	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(SIGCHLD, sig_got_chld);

	/* Father - close unneeded sockets */
	for (i = STDERR_FILENO + 1; i < socks[0]; i++)
		close(i);
	closefrom(socks[0] + 1);

	setproctitle("[priv]");

	while (cur_state != STATE_QUIT) {
		if (may_read(socks[0], &cmd, sizeof(int)))
			break;
		switch (cmd) {
		case PRIV_BIND:
			parent_bind(socks[0]);
			break;
		default:
			logmsg(LOG_ERR, "[priv]: unknown command %d", cmd);
			_exit(1);
			/* NOTREACHED */
		}
	}

	_exit(0);
}
Пример #3
0
/* Main loop, run as root */
static void
priv_loop()
{
	enum priv_cmd cmd;
	struct dispatch_actions *a;

	setproctitle("monitor");
	while (!may_read(&cmd, sizeof(enum priv_cmd))) {
		for (a = actions; a->function != NULL; a++) {
			if (cmd == a->msg) {
				a->function();
				break;
			}
		}
		if (a->function == NULL)
			fatal("privsep", "bogus message received");
	}
	/* Should never be there */
}
Пример #4
0
/* 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);
}