140 lines
3.6 KiB
Text
140 lines
3.6 KiB
Text
- Do not bail if the interface does not have an IP assigned.
|
|
- time_t format string fixes
|
|
- add -u flag, to drop privileges to that user
|
|
|
|
Index: arpwatch.c
|
|
--- arpwatch.c.orig
|
|
+++ arpwatch.c
|
|
@@ -63,6 +63,9 @@ struct rtentry;
|
|
#include <syslog.h>
|
|
#include <unistd.h>
|
|
|
|
+#include <pwd.h>
|
|
+#include <grp.h>
|
|
+
|
|
#include <pcap.h>
|
|
|
|
#include "gnuc.h"
|
|
@@ -141,6 +144,24 @@ int sanity_ether(struct ether_header *, struct ether_a
|
|
int sanity_fddi(struct fddi_header *, struct ether_arp *, int);
|
|
__dead void usage(void) __attribute__((volatile));
|
|
|
|
+void dropprivileges(const char* user)
|
|
+{
|
|
+ struct passwd* pw;
|
|
+ pw = getpwnam( user );
|
|
+ if ( pw ) {
|
|
+ if ( initgroups(pw->pw_name, pw->pw_gid) != 0 || setgid(pw->pw_gid) != 0 ||
|
|
+ setuid(pw->pw_uid) != 0 ) {
|
|
+ syslog(LOG_ERR, "Couldn't change to '%.32s' uid=%d gid=%d", user,pw->pw_uid, pw->pw_gid);
|
|
+ exit(1);
|
|
+ }
|
|
+ }
|
|
+ else {
|
|
+ syslog(LOG_ERR, "Couldn't find user '%.32s' in /etc/passwd", user);
|
|
+ exit(1);
|
|
+ }
|
|
+ syslog(LOG_INFO, "Running as uid=%d gid=%d", getuid(), getgid());
|
|
+}
|
|
+
|
|
int
|
|
main(int argc, char **argv)
|
|
{
|
|
@@ -153,6 +174,7 @@ main(int argc, char **argv)
|
|
register char *interface, *rfilename;
|
|
struct bpf_program code;
|
|
char errbuf[PCAP_ERRBUF_SIZE];
|
|
+ char* username = NULL;
|
|
|
|
if (argv[0] == NULL)
|
|
prog = "arpwatch";
|
|
@@ -170,7 +192,7 @@ main(int argc, char **argv)
|
|
interface = NULL;
|
|
rfilename = NULL;
|
|
pd = NULL;
|
|
- while ((op = getopt(argc, argv, "df:i:n:Nr:")) != EOF)
|
|
+ while ((op = getopt(argc, argv, "df:i:n:Nr:u:")) != EOF)
|
|
switch (op) {
|
|
|
|
case 'd':
|
|
@@ -202,6 +224,19 @@ main(int argc, char **argv)
|
|
rfilename = optarg;
|
|
break;
|
|
|
|
+ case 'u':
|
|
+ if ( optarg ) {
|
|
+ username = strdup(optarg);
|
|
+ if (username == NULL) {
|
|
+ fprintf(stderr, "strdup -u username failed");
|
|
+ exit(1);
|
|
+ }
|
|
+ } else {
|
|
+ fprintf(stderr, "%s: Need username after -u\n", prog);
|
|
+ usage();
|
|
+ }
|
|
+ break;
|
|
+
|
|
default:
|
|
usage();
|
|
}
|
|
@@ -223,9 +258,11 @@ main(int argc, char **argv)
|
|
|
|
/* Determine network and netmask */
|
|
if (pcap_lookupnet(interface, &net, &netmask, errbuf) < 0) {
|
|
- (void)fprintf(stderr, "%s: bad interface %s: %s\n",
|
|
- prog, interface, errbuf);
|
|
- exit(1);
|
|
+ (void)fprintf(stderr,
|
|
+ "%s: WARNING: cannot determine net/mask: %s\n",
|
|
+ prog, errbuf);
|
|
+ net = 0;
|
|
+ netmask = 0;
|
|
}
|
|
|
|
/* Drop into the background if not debugging */
|
|
@@ -279,12 +316,16 @@ main(int argc, char **argv)
|
|
#endif
|
|
}
|
|
|
|
+ if ( username ) {
|
|
+ dropprivileges( username );
|
|
+ } else {
|
|
/*
|
|
* Revert to non-privileged user after opening sockets
|
|
* (not needed on most systems).
|
|
*/
|
|
- setgid(getgid());
|
|
- setuid(getuid());
|
|
+ setgid(getgid());
|
|
+ setuid(getuid());
|
|
+ }
|
|
|
|
/* Must be ethernet or fddi */
|
|
linktype = pcap_datalink(pd);
|
|
@@ -401,7 +442,7 @@ process_ether(register u_char *u, register const struc
|
|
t = h->ts.tv_sec;
|
|
can_checkpoint = 0;
|
|
if (!ent_add(sia, sea, t, NULL))
|
|
- syslog(LOG_ERR, "ent_add(%s, %s, %ld) failed",
|
|
+ syslog(LOG_ERR, "ent_add(%s, %s, %lld) failed",
|
|
intoa(sia), e2str(sea), t);
|
|
can_checkpoint = 1;
|
|
}
|
|
@@ -550,7 +591,7 @@ process_fddi(register u_char *u, register const struct
|
|
t = h->ts.tv_sec;
|
|
can_checkpoint = 0;
|
|
if (!ent_add(sia, sea, t, NULL))
|
|
- syslog(LOG_ERR, "ent_add(%s, %s, %ld) failed",
|
|
+ syslog(LOG_ERR, "ent_add(%s, %s, %lld) failed",
|
|
intoa(sia), e2str(sea), t);
|
|
can_checkpoint = 1;
|
|
}
|
|
@@ -750,7 +791,7 @@ usage(void)
|
|
extern char version[];
|
|
|
|
(void)fprintf(stderr, "Version %s\n", version);
|
|
- (void)fprintf(stderr, "usage: %s [-dN] [-f datafile] [-i interface]"
|
|
+ (void)fprintf(stderr, "usage: %s [-dN] [-f datafile] [-i interface] [-u username]"
|
|
" [-n net[/width]] [-r file]\n", prog);
|
|
exit(1);
|
|
}
|