diff -urk.orig tcpdump-3.8.2.orig/configure.in tcpdump-3.8.2/configure.in --- tcpdump-3.8.2.orig/configure.in 2004-03-23 21:57:33 +0300 +++ tcpdump-3.8.2/configure.in 2004-03-30 03:20:45 +0400 @@ -104,18 +104,18 @@ ;; esac -AC_ARG_WITH(user, [ --with-user=USERNAME drop privileges by default to USERNAME]) +AC_ARG_WITH(user, [ --with-user=USERNAME drop privileges by default to USERNAME], , withval=tcpdump) AC_MSG_CHECKING([whether to drop root privileges by default]) -if test ! -z "$with_user" ; then +if test ! -z "$withval" ; then AC_DEFINE_UNQUOTED(WITH_USER, "$withval") AC_MSG_RESULT(to \"$withval\") else AC_MSG_RESULT(no) fi -AC_ARG_WITH(chroot, [ --with-chroot=DIRECTORY when dropping privileges, chroot to DIRECTORY]) +AC_ARG_WITH(chroot, [ --with-chroot=DIRECTORY when dropping privileges, chroot to DIRECTORY], , withval=/var/resolv) AC_MSG_CHECKING([whether to chroot]) -if test ! -z "$with_chroot" ; then +if test ! -z "$withval" ; then AC_DEFINE_UNQUOTED(WITH_CHROOT, "$withval") AC_MSG_RESULT(to \"$withval\") else diff -urk.orig tcpdump-3.8.2.orig/tcpdump.c tcpdump-3.8.2/tcpdump.c --- tcpdump-3.8.2.orig/tcpdump.c 2004-03-23 21:57:33 +0300 +++ tcpdump-3.8.2/tcpdump.c 2004-03-30 03:19:49 +0400 @@ -46,6 +46,7 @@ #endif #include +#include #ifdef WIN32 #include "getopt.h" @@ -344,32 +345,34 @@ static void droproot(const char *username, const char *chroot_dir) { - struct passwd *pw = NULL; + struct passwd *pw; if (chroot_dir && !username) { fprintf(stderr, "Chroot without dropping root is insecure\n"); exit(1); } - - pw = getpwnam(username); - if (pw) { - 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); - exit(1); - } - } - else { - fprintf(stderr, "Couldn't find user '%.32s'\n", username); - exit(1); - } + + if ((setgroups (0, NULL) < 0)) + error ("setgroups: %s", strerror (errno)); + + pw = getpwnam (username); + if (!pw) + error ("lookup of user \"%s\" failed", username); + + endpwent (); + + if (!pw->pw_uid) + error ("user \"%s\" shouldn't be root", username); + + if (chroot (chroot_dir) < 0 || chdir ("/") < 0) + error ("chroot/chdir to \"%s\" failed: %s", + chroot_dir, strerror (errno)); + + if (setgid (pw->pw_gid) < 0) + error ("setgid: %s", strerror (errno)); + + if (setuid (pw->pw_uid) < 0) + error ("setuid: %s", strerror (errno)); } #endif /* WIN32 */