Blame SOURCES/tcpdump-4.4.0-eperm.patch

75b7d9
diff -up tcpdump-4.4.0/tcpdump.1.in.eperm tcpdump-4.4.0/tcpdump.1.in
75b7d9
--- tcpdump-4.4.0/tcpdump.1.in.eperm	2013-10-07 15:21:26.795602764 +0200
75b7d9
+++ tcpdump-4.4.0/tcpdump.1.in	2013-10-07 15:21:26.800602762 +0200
75b7d9
@@ -221,6 +221,9 @@ have the name specified with the
75b7d9
 flag, with a number after it, starting at 1 and continuing upward.
75b7d9
 The units of \fIfile_size\fP are millions of bytes (1,000,000 bytes,
75b7d9
 not 1,048,576 bytes).
75b7d9
+
75b7d9
+Note that when used with \fB\-Z\fR option (enabled by default), privileges
75b7d9
+are dropped before opening first savefile.
75b7d9
 .TP
75b7d9
 .B \-d
75b7d9
 Dump the compiled packet-matching code in a human readable form to
75b7d9
@@ -720,7 +723,9 @@ but before opening any savefiles for out
75b7d9
 and the group ID to the primary group of
75b7d9
 .IR user .
75b7d9
 .IP
75b7d9
-This behavior can also be enabled by default at compile time.
75b7d9
+This behavior is enabled by default (\fB\-Z tcpdump\fR), and can
75b7d9
+be disabled by \fB\-Z root\fR.
75b7d9
+
75b7d9
 .IP "\fI expression\fP"
75b7d9
 .RS
75b7d9
 selects which packets will be dumped.
75b7d9
diff -up tcpdump-4.4.0/tcpdump.c.eperm tcpdump-4.4.0/tcpdump.c
75b7d9
--- tcpdump-4.4.0/tcpdump.c.eperm	2013-03-24 22:49:18.000000000 +0100
75b7d9
+++ tcpdump-4.4.0/tcpdump.c	2013-10-07 15:22:26.360590143 +0200
75b7d9
@@ -1426,11 +1426,24 @@ main(int argc, char **argv)
75b7d9
 	}
75b7d9
 #endif /* HAVE_CAP_NG_H */
75b7d9
 
75b7d9
-	if (getuid() == 0 || geteuid() == 0) {
75b7d9
-		if (username || chroot_dir)
75b7d9
+	/* If user is running tcpdump as root and wants to write to the savefile,
75b7d9
+	 * we will check if -C is set and if it is, we will drop root
75b7d9
+	 * privileges right away and consequent call to	pcap_dump_open()
75b7d9
+	 * will most likely fail for the first file. If -C flag is not set we
75b7d9
+	 * will create file as root then change ownership of file to proper
75b7d9
+	 * user(default tcpdump) and drop root privileges.
75b7d9
+	 */
75b7d9
+	int chown_flag = 0;
75b7d9
+
75b7d9
+	if (WFileName && (getuid() == 0 || geteuid() == 0))
75b7d9
+		if (Cflag && (username || chroot_dir))
75b7d9
+			droproot(username, chroot_dir);
75b7d9
+                else 
75b7d9
+			chown_flag = 1;
75b7d9
+	else
75b7d9
+		if ((getuid() == 0 || geteuid() == 0) && (username || chroot_dir))
75b7d9
 			droproot(username, chroot_dir);
75b7d9
 
75b7d9
-	}
75b7d9
 #endif /* WIN32 */
75b7d9
 
75b7d9
 	if (pcap_setfilter(pd, &fcode) < 0)
75b7d9
@@ -1450,6 +1463,21 @@ main(int argc, char **argv)
75b7d9
 		  MakeFilename(dumpinfo.CurrentFileName, WFileName, 0, 0);
75b7d9
 
75b7d9
 		p = pcap_dump_open(pd, dumpinfo.CurrentFileName);
75b7d9
+
75b7d9
+		/* Change ownership of file and drop root privileges */
75b7d9
+		if (chown_flag) {
75b7d9
+			struct passwd *pwd;
75b7d9
+
75b7d9
+			pwd = getpwnam(username);
75b7d9
+			if (!pwd)
75b7d9
+				error("Couldn't find user '%s'", username);
75b7d9
+
75b7d9
+			if (strcmp(WFileName, "-") && chown(dumpinfo.CurrentFileName, pwd->pw_uid, pwd->pw_gid) < 0)
75b7d9
+				error("Couldn't change ownership of savefile");
75b7d9
+
75b7d9
+			if (username || chroot_dir)
75b7d9
+				droproot(username, chroot_dir);
75b7d9
+		}
75b7d9
 #ifdef HAVE_CAP_NG_H
75b7d9
         /* Give up capabilities, clear Effective set */
75b7d9
         capng_clear(CAPNG_EFFECTIVE);