From 964bd27d3544cf952db1820c0badb79a71227b12 Mon Sep 17 00:00:00 2001 From: rpm-build Date: Mon, 20 Oct 2014 14:32:43 +0200 Subject: [PATCH 3/7] Drop root priviledges before opening first savefile if running with -Z root --- tcpdump.1.in | 7 ++++++- tcpdump.c | 34 +++++++++++++++++++++++++++++++--- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/tcpdump.1.in b/tcpdump.1.in index a966469..e3a6ef4 100644 --- a/tcpdump.1.in +++ b/tcpdump.1.in @@ -241,6 +241,9 @@ have the name specified with the flag, with a number after it, starting at 1 and continuing upward. The units of \fIfile_size\fP are millions of bytes (1,000,000 bytes, not 1,048,576 bytes). + +Note that when used with \fB\-Z\fR option (enabled by default), privileges +are dropped before opening first savefile. .TP .B \-d Dump the compiled packet-matching code in a human readable form to @@ -848,7 +851,9 @@ but before opening any savefiles for output, change the user ID to and the group ID to the primary group of .IR user . .IP -This behavior can also be enabled by default at compile time. +This behavior is enabled by default (\fB\-Z tcpdump\fR), and can +be disabled by \fB\-Z root\fR. + .IP "\fI expression\fP" .RS selects which packets will be dumped. diff --git a/tcpdump.c b/tcpdump.c index 8d615d7..9110ccf 100644 --- a/tcpdump.c +++ b/tcpdump.c @@ -1699,11 +1699,24 @@ main(int argc, char **argv) } #endif /* HAVE_CAP_NG_H */ - if (getuid() == 0 || geteuid() == 0) { - if (username || chroot_dir) + /* If user is running tcpdump as root and wants to write to the savefile, + * we will check if -C is set and if it is, we will drop root + * privileges right away and consequent call to pcap_dump_open() + * will most likely fail for the first file. If -C flag is not set we + * will create file as root then change ownership of file to proper + * user(default tcpdump) and drop root privileges. + */ + int chown_flag = 0; + + if (WFileName && (getuid() == 0 || geteuid() == 0)) + if (Cflag && (username || chroot_dir)) + droproot(username, chroot_dir); + else + chown_flag = 1; + else + if ((getuid() == 0 || geteuid() == 0) && (username || chroot_dir)) droproot(username, chroot_dir); - } #endif /* WIN32 */ if (pcap_setfilter(pd, &fcode) < 0) @@ -1738,6 +1751,21 @@ main(int argc, char **argv) MakeFilename(dumpinfo.CurrentFileName, WFileName, 0, 0); p = pcap_dump_open(pd, dumpinfo.CurrentFileName); + + /* Change ownership of file and drop root privileges */ + if (chown_flag) { + struct passwd *pwd; + + pwd = getpwnam(username); + if (!pwd) + error("Couldn't find user '%s'", username); + + if (strcmp(WFileName, "-") && chown(dumpinfo.CurrentFileName, pwd->pw_uid, pwd->pw_gid) < 0) + error("Couldn't change ownership of savefile"); + + if (username || chroot_dir) + droproot(username, chroot_dir); + } #ifdef HAVE_CAP_NG_H /* Give up capabilities, clear Effective set */ capng_clear(CAPNG_EFFECTIVE); -- 1.8.3.1