tcpdump mailing list archives
Dropping priviledges support
From: Earl Hood <earl () earlhood com>
Date: Tue, 20 Jan 2004 15:20:28 -0600
Since RedHat no longer support 7.3, I went to build tcpdump myself, and noticed that priviledge dropping is not provided (at least from what I saw) as is with the RH version of tcpdump. Therefore, I adapted the patch work that RH did for its releases for tcpdump 3.8.1. One big difference between the RH version and this patch is that RH used -U to specify which user to drop to, but tcpdump 3.8.1 uses -U for something else. Therefore, I went with -o. The patch also does the auto-dropping to pcap user if the process is running as root. Is there any interest in making the priviledge dropping support a default feature in the main distribution? --ewh diff -u --recursive tcpdump-3.8.1-org/VERSION tcpdump-3.8.1/VERSION --- tcpdump-3.8.1-org/VERSION Thu Aug 1 23:43:57 2002 +++ tcpdump-3.8.1/VERSION Sun Jan 18 14:50:21 2004 @@ -1 +1 @@ -3.8 +3.8.1 diff -u --recursive tcpdump-3.8.1-org/tcpdump.1 tcpdump-3.8.1/tcpdump.1 --- tcpdump-3.8.1-org/tcpdump.1 Sun Nov 23 17:43:41 2003 +++ tcpdump-3.8.1/tcpdump.1 Sun Jan 18 14:55:39 2004 @@ -54,6 +54,10 @@ .I module ] [ +.B \-o +.I user +] +[ .B \-r .I file ] @@ -382,6 +386,11 @@ if you give this flag then \fItcpdump\fP will print ``nic'' instead of ``nic.ddn.mil''. .TP +.B \-o +Drop root priviledges and change user ID to \fIuser\fP. +\fBNOTE\fR: This version of tcpdump will automatically drop to the +pcap user if -o is not specified. +.TP .B \-O Do not run the packet-matching code optimizer. This is useful only diff -u --recursive tcpdump-3.8.1-org/tcpdump.c tcpdump-3.8.1/tcpdump.c --- tcpdump-3.8.1-org/tcpdump.c Wed Dec 17 19:22:57 2003 +++ tcpdump-3.8.1/tcpdump.c Sun Jan 18 14:53:35 2004 @@ -61,6 +61,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <pwd.h> #include "interface.h" #include "addrtoname.h" @@ -298,6 +299,49 @@ #define U_FLAG #endif +#ifndef WIN32 +#define DROP_FLAG "o:" +#define DROP_FLAG_OPT "o" +#define DROP_FLAG_UOPT " [ -o user ]" + +#define WITH_USER "pcap" + +/* Drop root privileges */ +static +void droproot(const char *username) +{ + struct passwd *pw = NULL; + + if ((username == NULL) && (getuid() == 0 || geteuid() == 0)) { + username = WITH_USER; + } + if (username == NULL) { + setgid(getgid()); + setuid(getuid()); + return; + } + + pw = getpwnam( username ); + if ( pw ) { + if ( initgroups(pw->pw_name, NULL) != 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); + } +} + +#else +#define DROP_FLAG +#define DROP_FLAG_OPT +#define DROP_FLAG_UOPT +#endif /* WIN32 */ + int main(int argc, char **argv) { @@ -309,6 +353,7 @@ struct bpf_program fcode; #ifndef WIN32 RETSIGTYPE (*oldhandler)(int); + char *username = NULL; #endif struct print_info printinfo; struct dump_info dumpinfo; @@ -343,7 +388,7 @@ opterr = 0; while ( - (op = getopt(argc, argv, "aA" B_FLAG "c:C:d" D_FLAG "eE:fF:i:lLm:nNOpqr:Rs:StT:u" U_FLAG "vw:xXy:Y")) != -1) + (op = getopt(argc, argv, "aA" B_FLAG "c:C:d" D_FLAG "eE:fF:i:lLm:nN" DROP_FLAG "Opqr:Rs:StT:u" U_FLAG "vw:xXy:Y")) != -1) switch (op) { case 'a': @@ -494,7 +539,15 @@ program_name, optarg); (void)fprintf(stderr, "(no libsmi support)\n"); #endif - +#ifndef WIN32 + case 'o': + if (optarg) { + username = strdup(optarg); + } else { + /* NOT REACHED */ + usage(); + } +#endif case 'O': Oflag = 0; break; @@ -628,7 +681,9 @@ * people's trace files (especially if we're set-UID * root). */ - setuid(getuid()); + /* setuid(getuid()); */ + droproot( username ); + #endif /* WIN32 */ pd = pcap_open_offline(RFileName, ebuf); if (pd == NULL) @@ -716,7 +771,9 @@ * Let user own process after socket has been opened. */ #ifndef WIN32 - setuid(getuid()); + /* setuid(getuid()); */ + droproot( username ); + #endif /* WIN32 */ } if (infile) @@ -1126,9 +1183,9 @@ #endif /* WIN32 */ #endif /* HAVE_PCAP_LIB_VERSION */ (void)fprintf(stderr, -"Usage: %s [-aAd" D_FLAG "eflLnNOpqRStu" U_FLAG "vxX]" B_FLAG_USAGE " [-c count] [ -C file_size ]\n", program_name); +"Usage: %s [-aAd" D_FLAG "eflLnNO" DROP_FLAG_OPT "pqRStu" U_FLAG "vxX]" B_FLAG_USAGE " [-c count] [ -C file_size ]\n", program_name); (void)fprintf(stderr, -"\t\t[ -E algo:secret ] [ -F file ] [ -i interface ] [ -r file ]\n"); +"\t\t[ -E algo:secret ] [ -F file ] [ -i interface ]" DROP_FLAG_UOPT " [ -r file ]\n"); (void)fprintf(stderr, "\t\t[ -s snaplen ] [ -T type ] [ -w file ] [ -y datalinktype ]\n"); (void)fprintf(stderr, - This is the TCPDUMP workers list. It is archived at http://www.tcpdump.org/lists/workers/index.html To unsubscribe use mailto:tcpdump-workers-request () tcpdump org?body=unsubscribe
Current thread:
- Dropping priviledges support Earl Hood (Jan 20)