tcpdump/tcpdump-3.9.4-ring-buffers.patch

107 lines
3.1 KiB
Diff

--- tcpdump-3.9.4/tcpdump.c.ring 2005-08-23 12:29:41.000000000 +0200
+++ tcpdump-3.9.4/tcpdump.c 2005-12-20 13:32:45.000000000 +0100
@@ -109,7 +109,8 @@
static void ndo_default_print(netdissect_options *, const u_char *, u_int);
static void dump_packet_and_trunc(u_char *, const struct pcap_pkthdr *, const u_char *);
static void dump_packet(u_char *, const struct pcap_pkthdr *, const u_char *);
-static void droproot(const char *, const char *);
+static void droproot(const char *, const char *, int);
+static void setroot(void);
static void ndo_error(netdissect_options *ndo, const char *fmt, ...);
static void ndo_warning(netdissect_options *ndo, const char *fmt, ...);
@@ -295,6 +296,7 @@
char *WFileName;
pcap_t *pd;
pcap_dumper_t *p;
+ char *username;
};
static void
@@ -366,9 +368,10 @@
#ifndef WIN32
/* Drop root privileges and chroot if necessary */
static void
-droproot(const char *username, const char *chroot_dir)
+droproot(const char *username, const char *chroot_dir, int set_uid)
{
struct passwd *pw = NULL;
+ int res;
if (chroot_dir && !username) {
fprintf(stderr, "tcpdump: Chroot without dropping root is insecure\n");
@@ -384,8 +387,11 @@
exit(1);
}
}
- if (initgroups(pw->pw_name, pw->pw_gid) != 0 ||
- setgid(pw->pw_gid) != 0 || setuid(pw->pw_uid) != 0) {
+ res = (initgroups(pw->pw_name, pw->pw_gid) != 0) ||
+ (set_uid ? (setgid(pw->pw_gid) != 0 || setuid(pw->pw_uid) != 0) :
+ (setegid(pw->pw_gid) != 0 || seteuid(pw->pw_uid) != 0));
+
+ if (res) {
fprintf(stderr, "tcpdump: Couldn't change to '%.32s' uid=%lu gid=%lu: %s\n",
username,
(unsigned long)pw->pw_uid,
@@ -400,6 +406,17 @@
exit(1);
}
}
+
+/* Set root privileges */
+static void
+setroot(void)
+{
+ if (setegid(0) != 0 || seteuid(0) != 0) {
+ fprintf(stderr, "tcpdump: Couldn't change to root uid=0 gid=0: %s\n",
+ pcap_strerror(errno));
+ exit(1);
+ }
+}
#endif /* WIN32 */
static int
@@ -463,6 +480,7 @@
int devnum;
#endif
int status;
+ int set_uid = 1;
#ifdef WIN32
u_int UserBufferSize = 1000000;
if(wsockinit() != 0) return 1;
@@ -972,7 +990,9 @@
dumpinfo.WFileName = WFileName;
dumpinfo.pd = pd;
dumpinfo.p = p;
+ dumpinfo.username = username;
pcap_userdata = (u_char *)&dumpinfo;
+ set_uid = 0;
} else {
callback = dump_packet;
pcap_userdata = (u_char *)p;
@@ -998,7 +1018,7 @@
*/
if (getuid() == 0 || geteuid() == 0) {
if (username || chroot_dir)
- droproot(username, chroot_dir);
+ droproot(username, chroot_dir, set_uid);
}
#endif /* WIN32 */
#ifdef SIGINFO
@@ -1181,7 +1201,14 @@
if (name == NULL)
error("dump_packet_and_trunc: malloc");
MakeFilename(name, dump_info->WFileName, Cflag_count, WflagChars);
+#ifndef WIN32
+ setroot();
+#endif /* WIN32 */
dump_info->p = pcap_dump_open(dump_info->pd, name);
+#ifndef WIN32
+ if (dump_info->username)
+ droproot(dump_info->username, NULL, 0);
+#endif /* WIN32 */
free(name);
if (dump_info->p == NULL)
error("%s", pcap_geterr(pd));