diff -uNr nfs-utils-0.3.3/utils/statd/log.c nfs-utils-0.3.3.drop-privs/utils/statd/log.c
--- nfs-utils-0.3.3/utils/statd/log.c	Sat Feb 17 12:22:53 2001
+++ nfs-utils-0.3.3.drop-privs/utils/statd/log.c	Wed Oct  3 13:58:39 2001
@@ -32,7 +32,7 @@
 void log_init()
 {
 	if (!(run_mode & MODE_LOG_STDERR)) 
-		openlog(name_p, LOG_PID, LOG_DAEMON);
+		openlog(name_p, LOG_PID | LOG_NDELAY, LOG_DAEMON);
 
 	mypid = getpid();
 
diff -uNr nfs-utils-0.3.3/utils/statd/statd.c nfs-utils-0.3.3.drop-privs/utils/statd/statd.c
--- nfs-utils-0.3.3/utils/statd/statd.c	Fri Aug 17 12:12:08 2001
+++ nfs-utils-0.3.3.drop-privs/utils/statd/statd.c	Wed Oct  3 14:29:56 2001
@@ -17,6 +17,10 @@
 #include <rpc/rpc.h>
 #include <rpc/pmap_clnt.h>
 #include <rpcmisc.h>
+#include <pwd.h>
+#include <grp.h>
+#include <sys/types.h>
+#include <fcntl.h>
 #include "statd.h"
 #include "version.h"
 
@@ -53,6 +57,50 @@
 extern void simulator (int, char **);
 #endif
 
+/*
+ * Privilege dropper
+ */
+static void
+drop_privs(void)
+{
+  /* First locate user to jump to */
+  /* Prefer _not_ to use nobody as we'll own some files */
+  struct passwd* pw;
+
+  pw = getpwnam(RUN_AS_USER);
+  if (pw == NULL)
+  {
+    /* i.e. nobody */
+    log (L_WARNING, "Warning: You should really create user %s\n",
+         RUN_AS_USER);
+    pw = getpwnam(RUN_AS_FALLBACK);
+  }
+  if (pw == NULL)
+  {
+    die("Cannot start - cannot drop privs: getpwnam()\n");
+  }
+
+  initgroups(pw->pw_name, pw->pw_gid);
+
+  /* Do chroot() before we lose root privs.. */
+  chroot(".");
+
+  setgid(pw->pw_gid);
+  setuid(pw->pw_uid);
+
+  if (getgid() == 0)
+  {
+    die("Cannot start - cannot drop privs: getgid()\n");
+  }
+  else if (getuid() == 0)
+  {
+    die("Cannot start - cannot drop privs: getuid()\n");
+  }
+
+  /* Good enough */
+}
+
+
 
 #ifdef HAVE_TCP_WRAPPER 
 #include "tcpwrapper.h"
@@ -214,8 +262,6 @@
 						   daemon mode. */
 	}
 
-	log_init (name_p,version_p);
-
 	log_modes();
 
 #ifdef SIMULATIONS
@@ -248,12 +294,39 @@
 		}
 	}
 
+	log_init (name_p, version_p);
+
 	/* Child. */
 	signal (SIGHUP, killer);
 	signal (SIGINT, killer);
 	signal (SIGTERM, killer);
 	/* WARNING: the following works on Linux and SysV, but not BSD! */
 	signal(SIGCHLD, SIG_IGN);
+
+ 
+	/* cevans - we're going to drop root privs, but before we do that,
+	 * make sure to get our port <1024 socket
+	 */
+ 
+	/* Insist on starting as root - this means that when we setuid() away
+	 * from root, we'll keep current->dumpable=0 and prevent being messed
+	 * with (we may revert to user "nobody" - it's better than root
+	 */
+	if (getuid() != 0)
+		die("Startup failed: Please start rpc.statd as root\n");
+ 
+	/* Arm the ****** resolver before chroot() so it doesn't fail
+	 * trying to open /etc/* for the dozenth time
+	 */
+	sethostent(1);
+ 
+	/* Drop privs */
+	drop_privs();
+ 
+	/* After dropping privs, verify we can access all the files we need */
+	if (access(".", R_OK|W_OK|X_OK) != 0)
+		die("Cannot access current directory after dropping privs: access()\n");
+
 
 	/* initialize out_port */
 	statd_get_socket(out_port);
diff -uNr nfs-utils-0.3.3/utils/statd/statd.h nfs-utils-0.3.3.drop-privs/utils/statd/statd.h
--- nfs-utils-0.3.3/utils/statd/statd.h	Thu Oct  5 15:11:39 2000
+++ nfs-utils-0.3.3.drop-privs/utils/statd/statd.h	Wed Oct  3 14:13:40 2001
@@ -10,17 +10,27 @@
 #include "system.h"
 #include "log.h"
 
+/* Users we try and run as (prefer non-nobody because nobody is overloaded */
+/* Also, the user we run as will own some important nfs state files */
+#define RUN_AS_USER	"rpcuser"
+	/* Bah */
+#define RUN_AS_FALLBACK	"nobody"
+
+
 /*
  * Paths and filenames.
  */
+
+#define STATD_PATH_XTN "statd/"
 #if defined(NFS_STATEDIR)
-# define DIR_BASE	NFS_STATEDIR "/"
+# define DIR_BASE	NFS_STATEDIR "/" STATD_PATH_XTN
 #else
-# define DIR_BASE	"/var/lib/nfs/"
+# define DIR_BASE	"/var/lib/nfs/" STATD_PATH_XTN
 #endif
-#define SM_DIR		DIR_BASE "sm"
-#define SM_BAK_DIR	DIR_BASE "sm.bak"
-#define SM_STAT_PATH	DIR_BASE "state"
+
+#define SM_DIR		"sm"
+#define SM_BAK_DIR	"sm.bak"
+#define SM_STAT_PATH	"state"
 
 /*
  * Status definitions.
--- nfs-utils-1.0.1/utils/statd/statd.c.=K0000=.orig	Mon Nov 11 14:33:53 2002
+++ nfs-utils-1.0.1/utils/statd/statd.c	Mon Nov 11 14:33:53 2002
@@ -317,18 +317,17 @@
 	 */
 	sethostent(1);
  
-	/* Drop privs */
-	drop_privs();
- 
 	/* After dropping privs, verify we can access all the files we need */
 	if (access(".", R_OK|W_OK|X_OK) != 0)
 		die("Cannot access current directory after dropping privs: access()\n");
 
-
 	/* initialize out_port */
 	statd_get_socket(out_port);
 
+	/* Drop privs */
+	drop_privs();
+ 
 	for (;;) {
 		pmap_unset (SM_PROG, SM_VERS);
 		change_state ();

diff -uNr nfs-utils-1.0.1/utils/statd/statd.c~ nfs-utils-1.0.1/utils/statd/statd.c 
--- nfs-utils-1.0.1/utils/statd/statd.c~	2002-12-11 11:00:26.000000000 -0500
+++ nfs-utils-1.0.1/utils/statd/statd.c	2002-12-11 11:03:44.000000000 -0500
@@ -317,16 +317,16 @@
 	 */
 	sethostent(1);
  
-	/* After dropping privs, verify we can access all the files we need */
-	if (access(".", R_OK|W_OK|X_OK) != 0)
-		die("Cannot access current directory after dropping privs: access()\n");
-
 	/* initialize out_port */
 	statd_get_socket(out_port);
 
 	/* Drop privs */
 	drop_privs();
  
+	/* After dropping privs, verify we can access all the files we need */
+	if (access(".", R_OK|W_OK|X_OK) != 0)
+		die("Cannot access current directory after dropping privs: access()\n");
+
 	for (;;) {
 		pmap_unset (SM_PROG, SM_VERS);
 		change_state ();
