]>
Commit | Line | Data |
---|---|---|
0d9e0091 | 1 | ##dhcp-probe-03-drop-privs.patch - add option to change uid after setup |
c6298b67 JB |
2 | --- src/dhcp_probe.c.orig 2024-04-20 21:59:54.841088526 +0200 |
3 | +++ src/dhcp_probe.c 2024-04-20 22:23:32.870073070 +0200 | |
0d9e0091 JR |
4 | @@ -26,6 +26,9 @@ |
5 | #include "report.h" | |
6 | #include "utils.h" | |
7 | ||
8 | +#include <sys/types.h> | |
9 | +#include <pwd.h> | |
10 | + | |
11 | #ifndef lint | |
12 | static const char rcsid[] = "dhcp_probe version " VERSION; | |
c6298b67 JB |
13 | static const char copyright[] = "Copyright 2000-2021, The Trustees of Princeton University. All rights reserved."; |
14 | @@ -50,6 +53,8 @@ char *capture_file = NULL; | |
0d9e0091 JR |
15 | int snaplen = CAPTURE_BUFSIZE; |
16 | int socket_receive_timeout_feature = 0; | |
17 | int keep_pcap = 0; | |
18 | +int drop_privs = 0; | |
19 | +char *username = NULL; | |
20 | ||
21 | char *prog = NULL; | |
22 | char *logfile_name = NULL; | |
c6298b67 JB |
23 | @@ -183,6 +188,41 @@ reset_pcap() |
24 | pd = NULL; | |
0d9e0091 JR |
25 | } |
26 | ||
27 | +/* drop privileges */ | |
28 | +void | |
29 | +drop_privileges(const char *username) | |
30 | +{ | |
31 | + struct passwd *pw; | |
32 | + pw = getpwnam(username); | |
33 | + if (pw == NULL) { | |
34 | + report(LOG_ERR, "getpwnam: %s", get_errmsg()); | |
35 | + my_exit(1, 1, 1); | |
36 | + } | |
37 | + if (debug > 1) | |
38 | + report(LOG_INFO, "changing to uid %d gid %d", pw->pw_uid, pw->pw_gid); | |
39 | + | |
40 | + if (setregid(pw->pw_gid, pw->pw_gid)) { | |
41 | + report(LOG_ERR, "setregid: %s", get_errmsg()); | |
42 | + my_exit(1, 1, 1); | |
43 | + } | |
44 | + if (setreuid(pw->pw_uid, pw->pw_uid)) { | |
45 | + report(LOG_ERR, "setreuid: %s", get_errmsg()); | |
46 | + my_exit(1, 1, 1); | |
47 | + } | |
48 | +} | |
49 | + | |
50 | +void write_pidfile(void) | |
51 | +{ | |
52 | + FILE *pid_fp; | |
53 | + if ((pid_fp = open_for_writing(pid_file)) == NULL) { | |
54 | + report(LOG_ERR, "could not open pid file %s for writing", pid_file); | |
55 | + my_exit(1, 0, 1); | |
56 | + } else { | |
57 | + fprintf(pid_fp, "%d\n", (int) getpid()); | |
58 | + fclose(pid_fp); | |
59 | + } | |
60 | +} | |
c6298b67 | 61 | + |
0d9e0091 JR |
62 | int |
63 | main(int argc, char **argv) | |
c6298b67 JB |
64 | { |
65 | @@ -190,7 +230,6 @@ main(int argc, char **argv) | |
0d9e0091 JR |
66 | extern char *optarg; |
67 | extern int optind, opterr, optopt; | |
68 | struct sigaction sa; | |
69 | - FILE *pid_fp; | |
70 | char *cwd = CWD; | |
71 | ||
72 | int write_packet_len; | |
c6298b67 | 73 | @@ -210,7 +249,7 @@ main(int argc, char **argv) |
0d9e0091 JR |
74 | else |
75 | prog = argv[0]; | |
76 | ||
77 | - while ((c = getopt(argc, argv, "c:d:fhkl:o:p:Q:s:Tvw:")) != EOF) { | |
78 | + while ((c = getopt(argc, argv, "c:d:fhkl:o:p:Q:s:Tu:vw:")) != EOF) { | |
79 | switch (c) { | |
80 | case 'c': | |
81 | if (optarg[0] != '/') { | |
c6298b67 | 82 | @@ -285,6 +324,10 @@ main(int argc, char **argv) |
0d9e0091 JR |
83 | } |
84 | break; | |
85 | } | |
86 | + case 'u': | |
87 | + drop_privs = 1; | |
88 | + username = optarg; | |
89 | + break; | |
90 | case 'T': | |
91 | socket_receive_timeout_feature = 1; | |
92 | break; | |
c6298b67 | 93 | @@ -353,16 +396,6 @@ main(int argc, char **argv) |
0d9e0091 JR |
94 | my_exit(1, 0, 1); |
95 | } | |
96 | ||
97 | - | |
98 | - /* write pid file as soon as possible after (possibly) forking */ | |
99 | - if ((pid_fp = open_for_writing(pid_file)) == NULL) { | |
100 | - report(LOG_ERR, "could not open pid file %s for writing", pid_file); | |
101 | - my_exit(1, 0, 1); | |
102 | - } else { | |
103 | - fprintf(pid_fp, "%d\n", (int) getpid()); | |
104 | - fclose(pid_fp); | |
105 | - } | |
106 | - | |
107 | if (! read_configfile(config_file)) { | |
108 | my_exit(1, 1, 1); | |
109 | } | |
c6298b67 | 110 | @@ -547,6 +580,12 @@ main(int argc, char **argv) |
0d9e0091 | 111 | if (keep_pcap) |
c6298b67 | 112 | init_pcap(need_promiscuous()); |
0d9e0091 JR |
113 | |
114 | + if (drop_privs) | |
115 | + drop_privileges(username); | |
116 | + | |
117 | + /* write the pid file after dropping privileges to be able to remove it later */ | |
118 | + write_pidfile(); | |
119 | + | |
120 | while (1) { /* MAIN EVENT LOOP */ | |
121 | libnet_t *l; /* to iterate through libnet context queue */ | |
122 | /* struct pcap_stat ps; */ /* to hold pcap stats */ | |
c6298b67 | 123 | @@ -1332,6 +1371,7 @@ usage(void) |
0d9e0091 JR |
124 | fprintf(stderr, " -Q vlan_id tag outgoing frames with an 802.1Q VLAN ID\n"); |
125 | fprintf(stderr, " -s capture_bufsize override default capture bufsize [%d]\n", CAPTURE_BUFSIZE); | |
126 | fprintf(stderr, " -T enable the socket receive timeout feature\n"); | |
127 | + fprintf(stderr, " -u username change uid after setup (use with -k\n"); | |
128 | fprintf(stderr, " -v display version number then exit\n"); | |
129 | fprintf(stderr, " -w cwd override default working directory [%s]\n", CWD); | |
130 | fprintf(stderr, " interface_name name of ethernet interface\n"); |