+++ /dev/null
-Index: arpwatch/arpwatch.8
-diff -u arpwatch/arpwatch.8:1.1.1.1.2.2 arpwatch/arpwatch.8:1.1.1.1.20.3
---- arpwatch/arpwatch.8:1.1.1.1.2.2 Thu Aug 12 22:31:09 2004
-+++ arpwatch/arpwatch.8 Sat Aug 14 02:21:59 2004
-@@ -63,6 +63,20 @@
- ]
- .\" **
- .\" **
-+.br
-+.ti +8
-+[
-+.B -u
-+.I username
-+]
-+.br
-+.ti +8
-+[
-+.B -R
-+.I seconds
-+]
-+.\" **
-+.\" **
- .ad
- .SH DESCRIPTION
- .B Arpwatch
-@@ -127,6 +141,34 @@
- .\" **
- .\" **
- .LP
-+(Debian) The
-+.B -u
-+flag instructs
-+.B arpwatch
-+to drop root privileges and change the UID to
-+.I username
-+and GID to the primary group of
-+.I username .
-+This is recommended for security reasons, but
-+.I username
-+has to have write access to the default directory.
-+.LP
-+(Debian) The
-+.B -R
-+flag instructs
-+.B arpwatch
-+to restart in
-+.I seconds
-+seconds after the interface went down. By default, in such cases
-+arpwatch would print an error message and exit. This option is
-+ignored if either the
-+.B -r
-+or
-+.B -u
-+flags are used.
-+.\" **
-+.\" **
-+.LP
- Note that an empty
- .I arp.dat
- file must be created before the first time you run
-Index: arpwatch/arpwatch.c
-diff -u arpwatch/arpwatch.c:1.1.1.1.2.5 arpwatch/arpwatch.c:1.1.1.1.2.1.10.7
---- arpwatch/arpwatch.c:1.1.1.1.2.5 Sat Aug 14 02:33:07 2004
-+++ arpwatch/arpwatch.c Sat Aug 14 02:36:15 2004
-@@ -62,7 +62,8 @@
- #include <string.h>
- #include <syslog.h>
- #include <unistd.h>
--
-+#include <pwd.h>
-+#include <grp.h>
- #include <pcap.h>
-
- #include "gnuc.h"
-@@ -141,6 +142,24 @@
- 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, 0) != 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 +172,8 @@
- register char *interface, *rfilename;
- struct bpf_program code;
- char errbuf[PCAP_ERRBUF_SIZE];
-+ char* username = NULL;
-+ int restart = 0;
- char options[] =
- "d"
- /**/
-@@ -172,6 +193,10 @@
- "r:"
- /**/
- /**/
-+ "u:"
-+ "R:"
-+ /**/
-+ /**/
- ;
-
- if (argv[0] == NULL)
-@@ -223,6 +248,19 @@
- break;
- /**/
- /**/
-+ case 'u':
-+ if ( optarg ) {
-+ username = strdup(optarg);
-+ } else {
-+ fprintf(stderr, "%s: Need username after -u\n", prog);
-+ usage();
-+ }
-+ break;
-+ case 'R':
-+ restart = atoi(optarg);
-+ break;
-+ /**/
-+ /**/
- default:
- usage();
- }
-@@ -233,6 +271,8 @@
- if (rfilename != NULL) {
- net = 0;
- netmask = 0;
-+ interface = "(from file)";
-+ restart = 0;
- } else {
- /* Determine interface if not specified */
- if (interface == NULL &&
-@@ -279,6 +319,7 @@
- syslog(LOG_ERR, "(using current working directory)");
- }
-
-+label_restart:
- if (rfilename != NULL) {
- pd = pcap_open_offline(rfilename, errbuf);
- if (pd == NULL) {
-@@ -293,19 +334,29 @@
- pd = pcap_open_live(interface, snaplen, 1, timeout, errbuf);
- if (pd == NULL) {
- syslog(LOG_ERR, "pcap open %s: %s", interface, errbuf);
-- exit(1);
-+ if (restart) {
-+ syslog(LOG_ERR, "restart in %d secs", restart);
-+ } else {
-+ exit(1);
-+ }
-+ sleep(restart);
-+ goto label_restart;
- }
- #ifdef WORDS_BIGENDIAN
- swapped = 1;
- #endif
- }
-
-+ if ( username && !restart ) {
-+ 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);
-@@ -785,6 +836,10 @@
- "[-r file] "
- /**/
- /**/
-+ "[-u username] "
-+ "[-R seconds ] "
-+ /**/
-+ /**/
- "\n"
- ;
-