3719c98
From ec4e1a40fcf43d96a121a1ead877f2db4953dabb Mon Sep 17 00:00:00 2001
4ea394f
From: rpm-build <rpm-build>
3719c98
Date: Wed, 25 Mar 2015 13:13:49 +0100
3719c98
Subject: [PATCH] Drop root priviledges before opening first savefile if
4ea394f
 running with -Z root
4ea394f
4ea394f
---
4ea394f
 tcpdump.1.in |  7 ++++++-
3719c98
 tcpdump.c    | 35 ++++++++++++++++++++++++++++++++---
3719c98
 2 files changed, 38 insertions(+), 4 deletions(-)
4ea394f
4ea394f
diff --git a/tcpdump.1.in b/tcpdump.1.in
3719c98
index f9522cb..3f1bc5f 100644
4ea394f
--- a/tcpdump.1.in
4ea394f
+++ b/tcpdump.1.in
3719c98
@@ -249,6 +249,9 @@ have the name specified with the
aca9b7a
 flag, with a number after it, starting at 1 and continuing upward.
aca9b7a
 The units of \fIfile_size\fP are millions of bytes (1,000,000 bytes,
aca9b7a
 not 1,048,576 bytes).
aca9b7a
+
aca9b7a
+Note that when used with \fB\-Z\fR option (enabled by default), privileges
aca9b7a
+are dropped before opening first savefile.
aca9b7a
 .TP
aca9b7a
 .B \-d
aca9b7a
 Dump the compiled packet-matching code in a human readable form to
3719c98
@@ -865,7 +868,9 @@ but before opening any savefiles for output, change the user ID to
aca9b7a
 and the group ID to the primary group of
aca9b7a
 .IR user .
aca9b7a
 .IP
aca9b7a
-This behavior can also be enabled by default at compile time.
aca9b7a
+This behavior is enabled by default (\fB\-Z tcpdump\fR), and can
aca9b7a
+be disabled by \fB\-Z root\fR.
aca9b7a
+
aca9b7a
 .IP "\fI expression\fP"
aca9b7a
 .RS
aca9b7a
 selects which packets will be dumped.
4ea394f
diff --git a/tcpdump.c b/tcpdump.c
3719c98
index 2fd1617..4cbeb05 100644
4ea394f
--- a/tcpdump.c
4ea394f
+++ b/tcpdump.c
46ba83f
@@ -1029,6 +1029,7 @@ main(int argc, char **argv)
3719c98
 	cap_rights_t rights;
3719c98
 	int cansandbox;
3719c98
 #endif	/* HAVE_CAPSICUM */
e7083df
+        int chown_flag = 0;
3719c98
3719c98
 #ifdef WIN32
3719c98
 	if(wsockinit() != 0) return 1;
3719c98
@@ -1841,10 +1842,23 @@ main(int argc, char **argv)
3719c98
 		}
3719c98
 		capng_apply(CAPNG_SELECT_BOTH);
3719c98
 #endif /* HAVE_LIBCAP_NG */
aca9b7a
-		if (username || chroot_dir)
3719c98
-			droproot(username, chroot_dir);
3719c98
+		/* If user is running tcpdump as root and wants to write to the savefile,
3719c98
+		 * we will check if -C is set and if it is, we will drop root
3719c98
+		 * privileges right away and consequent call to	pcap_dump_open()
3719c98
+		 * will most likely fail for the first file. If -C flag is not set we
3719c98
+		 * will create file as root then change ownership of file to proper
3719c98
+		 * user(default tcpdump) and drop root privileges.
3719c98
+		 */
3719c98
+		if (WFileName)
3719c98
+			if (Cflag && (username || chroot_dir))
3719c98
+				droproot(username, chroot_dir);
3719c98
+			else
3719c98
+				chown_flag = 1;
3719c98
+		else
3719c98
+			if (username || chroot_dir)
3719c98
+                                droproot(username, chroot_dir);
3719c98
+        }
3719c98
8786a97
-	}
aca9b7a
 #endif /* WIN32 */
3719c98
8786a97
 	if (pcap_setfilter(pd, &fcode) < 0)
3719c98
@@ -1879,6 +1893,21 @@ main(int argc, char **argv)
aca9b7a
 		  MakeFilename(dumpinfo.CurrentFileName, WFileName, 0, 0);
3719c98
aca9b7a
 		p = pcap_dump_open(pd, dumpinfo.CurrentFileName);
8786a97
+
aca9b7a
+		/* Change ownership of file and drop root privileges */
aca9b7a
+		if (chown_flag) {
8786a97
+			struct passwd *pwd;
aca9b7a
+
8786a97
+			pwd = getpwnam(username);
8786a97
+			if (!pwd)
aca9b7a
+				error("Couldn't find user '%s'", username);
aca9b7a
+
d115fc0
+			if (strcmp(WFileName, "-") && chown(dumpinfo.CurrentFileName, pwd->pw_uid, pwd->pw_gid) < 0)
8786a97
+				error("Couldn't change ownership of savefile");
aca9b7a
+
aca9b7a
+			if (username || chroot_dir)
aca9b7a
+				droproot(username, chroot_dir);
aca9b7a
+		}
3719c98
 #ifdef HAVE_LIBCAP_NG
3719c98
 		/* Give up CAP_DAC_OVERRIDE capability.
3719c98
 		 * Only allow it to be restored if the -C or -G flag have been
3719c98
--
3719c98
2.3.4