]>
Commit | Line | Data |
---|---|---|
e2fb63d0 TP |
1 | Index: arpwatch/arpwatch.8 |
2 | diff -u arpwatch/arpwatch.8:1.1.1.1.2.2 arpwatch/arpwatch.8:1.1.1.1.20.3 | |
3 | --- arpwatch/arpwatch.8:1.1.1.1.2.2 Thu Aug 12 22:31:09 2004 | |
4 | +++ arpwatch/arpwatch.8 Sat Aug 14 02:21:59 2004 | |
5 | @@ -63,6 +63,20 @@ | |
6 | ] | |
7 | .\" ** | |
8 | .\" ** | |
9 | +.br | |
10 | +.ti +8 | |
11 | +[ | |
12 | +.B -u | |
13 | +.I username | |
14 | +] | |
15 | +.br | |
16 | +.ti +8 | |
17 | +[ | |
18 | +.B -R | |
19 | +.I seconds | |
20 | +] | |
21 | +.\" ** | |
22 | +.\" ** | |
23 | .ad | |
24 | .SH DESCRIPTION | |
25 | .B Arpwatch | |
26 | @@ -127,6 +141,34 @@ | |
27 | .\" ** | |
28 | .\" ** | |
29 | .LP | |
30 | +(Debian) The | |
31 | +.B -u | |
32 | +flag instructs | |
33 | +.B arpwatch | |
34 | +to drop root privileges and change the UID to | |
35 | +.I username | |
36 | +and GID to the primary group of | |
37 | +.I username . | |
38 | +This is recommended for security reasons, but | |
39 | +.I username | |
40 | +has to have write access to the default directory. | |
41 | +.LP | |
42 | +(Debian) The | |
43 | +.B -R | |
44 | +flag instructs | |
45 | +.B arpwatch | |
46 | +to restart in | |
47 | +.I seconds | |
48 | +seconds after the interface went down. By default, in such cases | |
49 | +arpwatch would print an error message and exit. This option is | |
50 | +ignored if either the | |
51 | +.B -r | |
52 | +or | |
53 | +.B -u | |
54 | +flags are used. | |
55 | +.\" ** | |
56 | +.\" ** | |
57 | +.LP | |
58 | Note that an empty | |
59 | .I arp.dat | |
60 | file must be created before the first time you run | |
61 | Index: arpwatch/arpwatch.c | |
62 | diff -u arpwatch/arpwatch.c:1.1.1.1.2.5 arpwatch/arpwatch.c:1.1.1.1.2.1.10.7 | |
63 | --- arpwatch/arpwatch.c:1.1.1.1.2.5 Sat Aug 14 02:33:07 2004 | |
64 | +++ arpwatch/arpwatch.c Sat Aug 14 02:36:15 2004 | |
65 | @@ -62,7 +62,8 @@ | |
66 | #include <string.h> | |
67 | #include <syslog.h> | |
68 | #include <unistd.h> | |
69 | - | |
70 | +#include <pwd.h> | |
71 | +#include <grp.h> | |
72 | #include <pcap.h> | |
73 | ||
74 | #include "gnuc.h" | |
75 | @@ -141,6 +142,24 @@ | |
76 | int sanity_fddi(struct fddi_header *, struct ether_arp *, int); | |
77 | __dead void usage(void) __attribute__((volatile)); | |
78 | ||
79 | +void dropprivileges(const char* user) | |
80 | +{ | |
81 | + struct passwd* pw; | |
82 | + pw = getpwnam( user ); | |
83 | + if ( pw ) { | |
84 | + if ( initgroups(pw->pw_name, 0) != 0 || setgid(pw->pw_gid) != 0 || | |
85 | + setuid(pw->pw_uid) != 0 ) { | |
86 | + syslog(LOG_ERR, "Couldn't change to '%.32s' uid=%d gid=%d", user,pw->pw_uid, pw->pw_gid); | |
87 | + exit(1); | |
88 | + } | |
89 | + } | |
90 | + else { | |
91 | + syslog(LOG_ERR, "Couldn't find user '%.32s' in /etc/passwd", user); | |
92 | + exit(1); | |
93 | + } | |
94 | + syslog(LOG_INFO, "Running as uid=%d gid=%d", getuid(), getgid()); | |
95 | +} | |
96 | + | |
97 | int | |
98 | main(int argc, char **argv) | |
99 | { | |
100 | @@ -153,6 +172,8 @@ | |
101 | register char *interface, *rfilename; | |
102 | struct bpf_program code; | |
103 | char errbuf[PCAP_ERRBUF_SIZE]; | |
104 | + char* username = NULL; | |
105 | + int restart = 0; | |
106 | char options[] = | |
107 | "d" | |
108 | /**/ | |
109 | @@ -172,6 +193,10 @@ | |
110 | "r:" | |
111 | /**/ | |
112 | /**/ | |
113 | + "u:" | |
114 | + "R:" | |
115 | + /**/ | |
116 | + /**/ | |
117 | ; | |
118 | ||
119 | if (argv[0] == NULL) | |
120 | @@ -223,6 +248,19 @@ | |
121 | break; | |
122 | /**/ | |
123 | /**/ | |
124 | + case 'u': | |
125 | + if ( optarg ) { | |
126 | + username = strdup(optarg); | |
127 | + } else { | |
128 | + fprintf(stderr, "%s: Need username after -u\n", prog); | |
129 | + usage(); | |
130 | + } | |
131 | + break; | |
132 | + case 'R': | |
133 | + restart = atoi(optarg); | |
134 | + break; | |
135 | + /**/ | |
136 | + /**/ | |
137 | default: | |
138 | usage(); | |
139 | } | |
140 | @@ -233,6 +271,8 @@ | |
141 | if (rfilename != NULL) { | |
142 | net = 0; | |
143 | netmask = 0; | |
144 | + interface = "(from file)"; | |
145 | + restart = 0; | |
146 | } else { | |
147 | /* Determine interface if not specified */ | |
148 | if (interface == NULL && | |
149 | @@ -279,6 +319,7 @@ | |
150 | syslog(LOG_ERR, "(using current working directory)"); | |
151 | } | |
152 | ||
153 | +label_restart: | |
154 | if (rfilename != NULL) { | |
155 | pd = pcap_open_offline(rfilename, errbuf); | |
156 | if (pd == NULL) { | |
157 | @@ -293,19 +334,29 @@ | |
158 | pd = pcap_open_live(interface, snaplen, 1, timeout, errbuf); | |
159 | if (pd == NULL) { | |
160 | syslog(LOG_ERR, "pcap open %s: %s", interface, errbuf); | |
161 | - exit(1); | |
162 | + if (restart) { | |
163 | + syslog(LOG_ERR, "restart in %d secs", restart); | |
164 | + } else { | |
165 | + exit(1); | |
166 | + } | |
167 | + sleep(restart); | |
168 | + goto label_restart; | |
169 | } | |
170 | #ifdef WORDS_BIGENDIAN | |
171 | swapped = 1; | |
172 | #endif | |
173 | } | |
174 | ||
175 | + if ( username && !restart ) { | |
176 | + dropprivileges( username ); | |
177 | + } else { | |
178 | /* | |
179 | * Revert to non-privileged user after opening sockets | |
180 | * (not needed on most systems). | |
181 | */ | |
182 | - setgid(getgid()); | |
183 | - setuid(getuid()); | |
184 | + setgid(getgid()); | |
185 | + setuid(getuid()); | |
186 | + } | |
187 | ||
188 | /* Must be ethernet or fddi */ | |
189 | linktype = pcap_datalink(pd); | |
190 | @@ -785,6 +836,10 @@ | |
191 | "[-r file] " | |
192 | /**/ | |
193 | /**/ | |
194 | + "[-u username] " | |
195 | + "[-R seconds ] " | |
196 | + /**/ | |
197 | + /**/ | |
198 | "\n" | |
199 | ; | |
200 |