diff options
Diffstat (limited to 'contrib/pf/pflogd/privsep.c')
-rw-r--r-- | contrib/pf/pflogd/privsep.c | 84 |
1 files changed, 71 insertions, 13 deletions
diff --git a/contrib/pf/pflogd/privsep.c b/contrib/pf/pflogd/privsep.c index 33d6b9c..1139cb4 100644 --- a/contrib/pf/pflogd/privsep.c +++ b/contrib/pf/pflogd/privsep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: privsep.c,v 1.13 2004/12/22 09:21:02 otto Exp $ */ +/* $OpenBSD: privsep.c,v 1.16 2006/10/25 20:55:04 moritz Exp $ */ /* * Copyright (c) 2003 Can Erkin Acar @@ -16,7 +16,6 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include <sys/ioctl.h> #include <sys/types.h> #include <sys/time.h> #include <sys/socket.h> @@ -28,6 +27,7 @@ #include <err.h> #include <errno.h> #include <fcntl.h> +#include <limits.h> #include <pcap.h> #include <pcap-int.h> #include <pwd.h> @@ -41,6 +41,7 @@ enum cmd_types { PRIV_SET_SNAPLEN, /* set the snaplength */ + PRIV_MOVE_LOG, /* move logfile away */ PRIV_OPEN_LOG /* open logfile for appending */ }; @@ -55,10 +56,8 @@ static int may_read(int, void *, size_t); static void must_read(int, void *, size_t); static void must_write(int, void *, size_t); static int set_snaplen(int snap); +static int move_log(const char *name); -/* bpf filter expression common to parent and child */ -extern char *filter; -extern char *errbuf; extern char *filename; extern pcap_t *hpcap; @@ -96,16 +95,12 @@ priv_init(void) 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 (setegid(pw->pw_gid) == -1) - err(1, "setegid() failed"); - if (setgid(pw->pw_gid) == -1) - err(1, "setgid() failed"); - if (seteuid(pw->pw_uid) == -1) - err(1, "seteuid() failed"); - if (setuid(pw->pw_uid) == -1) - err(1, "setuid() 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; @@ -159,6 +154,13 @@ priv_init(void) 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); @@ -182,6 +184,47 @@ set_snaplen(int snap) return 0; } +static int +move_log(const char *name) +{ + char ren[PATH_MAX]; + int len; + + for (;;) { + int fd; + + len = snprintf(ren, sizeof(ren), "%s.bad.%08x", + name, arc4random()); + if (len >= sizeof(ren)) { + logmsg(LOG_ERR, "[priv] new name too long"); + return (1); + } + + /* lock destinanion */ + fd = open(ren, O_CREAT|O_EXCL, 0); + if (fd >= 0) { + close(fd); + break; + } + /* if file exists, try another name */ + if (errno != EEXIST && errno != EINTR) { + logmsg(LOG_ERR, "[priv] failed to create new name: %s", + strerror(errno)); + return (1); + } + } + + if (rename(name, ren)) { + logmsg(LOG_ERR, "[priv] failed to rename %s to %s: %s", + name, ren, strerror(errno)); + return (1); + } + + logmsg(LOG_NOTICE, + "[priv]: log file %s moved to %s", name, ren); + + return (0); +} /* * send the snaplength to privileged process @@ -223,6 +266,21 @@ priv_open_log(void) return (fd); } +/* 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); +} /* If priv parent gets a TERM or HUP, pass it through to child instead */ static void |