]> The Tcpdump Group git mirrors - tcpdump/commitdiff
from Pekka Savola <[email protected]>:
authorhannes <hannes>
Wed, 25 Feb 2004 14:23:32 +0000 (14:23 +0000)
committerhannes <hannes>
Wed, 25 Feb 2004 14:23:32 +0000 (14:23 +0000)
 - add compile time option WITH_CHROOT
 - chroot() when dropping privileges

acconfig.h
configure.in
tcpdump.c

index 5a2b508bd9b3718e419613c9afe37c0471d4e37b..7b682c3ff66d46dcbc6e1a39579b51ce125e409a 100644 (file)
 
 /* define if should drop privileges by default */
 #undef WITH_USER
 
 /* define if should drop privileges by default */
 #undef WITH_USER
+
+/* define if should chroot when dropping privileges */
+#undef WITH_CHROOT
index 609859d1e6b341dfb534270f34918fcc1e1e9a26..2efabe3880fe010e3b6a13a0eebd574270f24e8e 100644 (file)
@@ -1,4 +1,4 @@
-dnl @(#) $Header: /tcpdump/master/tcpdump/configure.in,v 1.175 2004-01-31 05:26:51 guy Exp $ (LBL)
+dnl @(#) $Header: /tcpdump/master/tcpdump/configure.in,v 1.176 2004-02-25 14:23:32 hannes Exp $ (LBL)
 dnl
 dnl Copyright (c) 1994, 1995, 1996, 1997
 dnl    The Regents of the University of California.  All rights reserved.
 dnl
 dnl Copyright (c) 1994, 1995, 1996, 1997
 dnl    The Regents of the University of California.  All rights reserved.
@@ -6,7 +6,7 @@ dnl
 dnl Process this file with autoconf to produce a configure script.
 dnl
 
 dnl Process this file with autoconf to produce a configure script.
 dnl
 
-AC_REVISION($Revision: 1.175 $)
+AC_REVISION($Revision: 1.176 $)
 AC_PREREQ(2.50)
 AC_INIT(tcpdump.c)
 
 AC_PREREQ(2.50)
 AC_INIT(tcpdump.c)
 
@@ -111,6 +111,15 @@ else
        AC_MSG_RESULT(no)
 fi
 
        AC_MSG_RESULT(no)
 fi
 
+AC_ARG_WITH(chroot, [  --with-chroot=DIRECTORY when dropping privileges, chroot to DIRECTORY])
+AC_MSG_CHECKING([whether to chroot])
+if test ! -z "$with_chroot" ; then
+        AC_DEFINE_UNQUOTED(WITH_CHROOT, "$withval")
+       AC_MSG_RESULT(to \"$withval\")
+else
+       AC_MSG_RESULT(no)
+fi
+
 AC_MSG_CHECKING([whether to enable ipv6])
 AC_ARG_ENABLE(ipv6,
 [  --enable-ipv6           enable ipv6 (with ipv4) support
 AC_MSG_CHECKING([whether to enable ipv6])
 AC_ARG_ENABLE(ipv6,
 [  --enable-ipv6           enable ipv6 (with ipv4) support
index 7f751f0e95d5ca19e342781a5680896c28575e9d..e3693e73f2c7992900ffc458e254308c8ee8d36c 100644 (file)
--- a/tcpdump.c
+++ b/tcpdump.c
@@ -30,7 +30,7 @@ static const char copyright[] _U_ =
     "@(#) Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000\n\
 The Regents of the University of California.  All rights reserved.\n";
 static const char rcsid[] _U_ =
     "@(#) Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000\n\
 The Regents of the University of California.  All rights reserved.\n";
 static const char rcsid[] _U_ =
-    "@(#) $Header: /tcpdump/master/tcpdump/tcpdump.c,v 1.231 2004-02-24 08:12:18 hannes Exp $ (LBL)";
+    "@(#) $Header: /tcpdump/master/tcpdump/tcpdump.c,v 1.232 2004-02-25 14:23:32 hannes Exp $ (LBL)";
 #endif
 
 /*
 #endif
 
 /*
@@ -129,7 +129,7 @@ static void show_dlts_and_exit(pcap_t *pd) __attribute__((noreturn));
 static void print_packet(u_char *, const struct pcap_pkthdr *, const u_char *);
 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 print_packet(u_char *, const struct pcap_pkthdr *, const u_char *);
 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 *);
+static void droproot(const char *, const char *);
 
 #ifdef SIGINFO
 RETSIGTYPE requestinfo(int);
 
 #ifdef SIGINFO
 RETSIGTYPE requestinfo(int);
@@ -324,15 +324,26 @@ show_dlts_and_exit(pcap_t *pd)
 #define U_FLAG
 #endif
 
 #define U_FLAG
 #endif
 
-/* Drop root privileges */
+/* Drop root privileges and chroot if necessary */
 static void
 static void
-droproot(const char *username)
+droproot(const char *username, const char *chroot_dir)
 {
        struct passwd *pw = NULL;
 
 {
        struct passwd *pw = NULL;
 
+       if (chroot_dir && !username) {
+               fprintf(stderr, "Chroot without dropping root is insecure\n");
+               exit(1);
+       }
+       
        pw = getpwnam(username);
        if (pw) {
        pw = getpwnam(username);
        if (pw) {
-               if (initgroups(pw->pw_name, 0) != 0 || setgid(pw->pw_gid) != 0 ||
+               if (chroot_dir) {
+                       if (chroot(chroot_dir) != 0 || chdir ("/") != 0) {
+                               fprintf(stderr, "Couldn't chroot/chdir to '%.64s'\n", chroot_dir);
+                               exit(1);
+                       }
+               }
+               if (initgroups(pw->pw_name, pw->pw_gid) != 0 || setgid(pw->pw_gid) != 0 ||
                                 setuid(pw->pw_uid) != 0) {
                        fprintf(stderr, "Couldn't change to '%.32s' uid=%d gid=%d\n", username, 
                                                        pw->pw_uid, pw->pw_gid);
                                 setuid(pw->pw_uid) != 0) {
                        fprintf(stderr, "Couldn't change to '%.32s' uid=%d gid=%d\n", username, 
                                                        pw->pw_uid, pw->pw_gid);
@@ -386,6 +397,7 @@ main(int argc, char **argv)
        u_char *pcap_userdata;
        char ebuf[PCAP_ERRBUF_SIZE];
        char *username = NULL;
        u_char *pcap_userdata;
        char ebuf[PCAP_ERRBUF_SIZE];
        char *username = NULL;
+       char *chroot_dir = NULL;
 #ifdef HAVE_PCAP_FINDALLDEVS
        pcap_if_t *devpointer;
        int devnum;
 #ifdef HAVE_PCAP_FINDALLDEVS
        pcap_if_t *devpointer;
        int devnum;
@@ -704,6 +716,15 @@ main(int argc, char **argv)
        if (tflag > 0)
                thiszone = gmt2local(0);
 
        if (tflag > 0)
                thiszone = gmt2local(0);
 
+#ifdef WITH_CHROOT
+       /* if run as root, prepare for chrooting */
+       if (getuid() == 0 || geteuid() == 0) {
+               /* future extensibility for cmd-line arguments */
+               if (!chroot_dir)
+                       chroot_dir = WITH_CHROOT;
+       }
+#endif
+
 #ifdef WITH_USER
        /* if run as root, prepare for dropping root privileges */
        if (getuid() == 0 || geteuid() == 0) {
 #ifdef WITH_USER
        /* if run as root, prepare for dropping root privileges */
        if (getuid() == 0 || geteuid() == 0) {
@@ -885,9 +906,8 @@ main(int argc, char **argv)
         * We cannot do this earlier, because we want to be able to open
         * the file (if done) for writing before giving up permissions.
         */
         * We cannot do this earlier, because we want to be able to open
         * the file (if done) for writing before giving up permissions.
         */
-       if (username) {
-               droproot(username);
-       }
+       if (username || chroot_dir)
+               droproot(username, chroot_dir);
 #endif /* WIN32 */
 #ifdef SIGINFO
        (void)setsignal(SIGINFO, requestinfo);
 #endif /* WIN32 */
 #ifdef SIGINFO
        (void)setsignal(SIGINFO, requestinfo);