e83fb19
diff -up dhcp-4.3.0a1/client/dhclient.c.paranoia dhcp-4.3.0a1/client/dhclient.c
e83fb19
--- dhcp-4.3.0a1/client/dhclient.c.paranoia	2013-12-19 16:30:21.401211512 +0100
e83fb19
+++ dhcp-4.3.0a1/client/dhclient.c	2013-12-19 16:30:21.409211401 +0100
e83fb19
@@ -1712,11 +1712,6 @@ int write_host (host)
58a3b6c
 	return 0;
58a3b6c
 }
58a3b6c
 
58a3b6c
-void db_startup (testp)
58a3b6c
-	int testp;
58a3b6c
-{
58a3b6c
-}
58a3b6c
-
58a3b6c
 void bootp (packet)
58a3b6c
 	struct packet *packet;
58a3b6c
 {
e83fb19
diff -up dhcp-4.3.0a1/includes/dhcpd.h.paranoia dhcp-4.3.0a1/includes/dhcpd.h
e83fb19
--- dhcp-4.3.0a1/includes/dhcpd.h.paranoia	2013-12-19 16:30:21.403211484 +0100
e83fb19
+++ dhcp-4.3.0a1/includes/dhcpd.h	2013-12-19 16:30:21.410211387 +0100
e83fb19
@@ -2851,7 +2851,11 @@ void commit_leases_timeout (void *);
58a3b6c
 void commit_leases_readerdry(void *);
58a3b6c
 int commit_leases (void);
58a3b6c
 int commit_leases_timed (void);
58a3b6c
+#if defined (PARANOIA)
58a3b6c
+void db_startup (int, uid_t, gid_t);
58a3b6c
+#else
58a3b6c
 void db_startup (int);
58a3b6c
+#endif /* PARANOIA */
58a3b6c
 int new_lease_file (void);
58a3b6c
 int group_writer (struct group_object *);
58a3b6c
 int write_ia(const struct ia_xx *);
e83fb19
diff -up dhcp-4.3.0a1/server/confpars.c.paranoia dhcp-4.3.0a1/server/confpars.c
e83fb19
--- dhcp-4.3.0a1/server/confpars.c.paranoia	2013-12-19 16:30:21.346212275 +0100
e83fb19
+++ dhcp-4.3.0a1/server/confpars.c	2013-12-19 16:30:21.412211359 +0100
e83fb19
@@ -225,7 +225,11 @@ void trace_conf_input (trace_type_t *tty
58a3b6c
 	}
58a3b6c
 
58a3b6c
 	if (!leaseconf_initialized && ttype == trace_readleases_type) {
58a3b6c
+#if defined (PARANOIA)
58a3b6c
+		db_startup (0, 0, 0);
58a3b6c
+#else
58a3b6c
 		db_startup (0);
58a3b6c
+#endif /* PARANOIA */
58a3b6c
 		leaseconf_initialized = 1;
58a3b6c
 		postdb_startup ();
58a3b6c
 	}
e83fb19
diff -up dhcp-4.3.0a1/server/db.c.paranoia dhcp-4.3.0a1/server/db.c
e83fb19
--- dhcp-4.3.0a1/server/db.c.paranoia	2013-12-19 16:30:21.346212275 +0100
e83fb19
+++ dhcp-4.3.0a1/server/db.c	2013-12-19 16:30:21.412211359 +0100
e83fb19
@@ -48,6 +48,10 @@ static int counting = 0;
58a3b6c
 static int count = 0;
58a3b6c
 TIME write_time;
58a3b6c
 int lease_file_is_corrupt = 0;
58a3b6c
+#if defined (PARANOIA)
58a3b6c
+uid_t global_set_uid = 0;
58a3b6c
+gid_t global_set_gid = 0;
58a3b6c
+#endif /* PARANOIA */
58a3b6c
 
58a3b6c
 /* Write a single binding scope value in parsable format.
58a3b6c
  */
e83fb19
@@ -1052,8 +1056,11 @@ int commit_leases_timed()
58a3b6c
 	return (1);
58a3b6c
 }
58a3b6c
 
58a3b6c
-void db_startup (testp)
58a3b6c
-	int testp;
58a3b6c
+#if defined (PARANOIA)
58a3b6c
+void db_startup (int testp, uid_t set_uid, gid_t set_gid)
58a3b6c
+#else
58a3b6c
+void db_startup (int testp)
58a3b6c
+#endif /* PARANOIA */
58a3b6c
 {
58a3b6c
 	isc_result_t status;
58a3b6c
 
e83fb19
@@ -1072,6 +1079,11 @@ void db_startup (testp)
58a3b6c
 	}
58a3b6c
 #endif
58a3b6c
 
58a3b6c
+#if defined (PARANOIA)
58a3b6c
+	global_set_uid = set_uid;
58a3b6c
+	global_set_gid = set_gid;
58a3b6c
+#endif /* PARANOIA */
58a3b6c
+
58a3b6c
 #if defined (TRACING)
58a3b6c
 	/* If we're playing back, there is no lease file, so we can't
58a3b6c
 	   append it, so we create one immediately (maybe this isn't
e83fb19
@@ -1134,6 +1146,17 @@ int new_lease_file ()
58a3b6c
 		log_error ("Can't create new lease file: %m");
58a3b6c
 		return 0;
58a3b6c
 	}
58a3b6c
+
58a3b6c
+#if defined (PARANOIA)
58a3b6c
+	if (global_set_uid && !geteuid() &&
58a3b6c
+	    global_set_gid && !getegid())
58a3b6c
+		if (fchown(db_fd, global_set_uid, global_set_gid)) {
58a3b6c
+			log_fatal ("Can't chown new lease file: %m");
58a3b6c
+			close(db_fd);
58a3b6c
+			goto fdfail;
58a3b6c
+	}
58a3b6c
+#endif /* PARANOIA */
58a3b6c
+
58a3b6c
 	if ((new_db_file = fdopen(db_fd, "we")) == NULL) {
58a3b6c
 		log_error("Can't fdopen new lease file: %m");
58a3b6c
 		close(db_fd);
e83fb19
diff -up dhcp-4.3.0a1/server/dhcpd.8.paranoia dhcp-4.3.0a1/server/dhcpd.8
e83fb19
--- dhcp-4.3.0a1/server/dhcpd.8.paranoia	2013-12-11 01:01:03.000000000 +0100
e83fb19
+++ dhcp-4.3.0a1/server/dhcpd.8	2013-12-19 16:30:21.413211345 +0100
4a364d1
@@ -82,6 +82,18 @@ dhcpd - Dynamic Host Configuration Proto
4a364d1
 .I trace-output-file
4a364d1
 ]
4a364d1
 [
4a364d1
+.B -user
4a364d1
+.I user
4a364d1
+]
4a364d1
+[
4a364d1
+.B -group
4a364d1
+.I group
4a364d1
+]
4a364d1
+[
4a364d1
+.B -chroot
4a364d1
+.I dir
4a364d1
+]
4a364d1
+[
4a364d1
 .B -play
4a364d1
 .I trace-playback-file
4a364d1
 ]
4a364d1
@@ -269,6 +281,15 @@ lease file.
4a364d1
 .TP
4a364d1
 .BI --version
4a364d1
 Print version number and exit.
4a364d1
+.TP
4a364d1
+.BI \-user \ user
4a364d1
+Setuid to user after completing privileged operations, such as creating sockets that listen on privileged ports.
4a364d1
+.TP
4a364d1
+.BI \-group \ group
4a364d1
+Setgid to group after completing privileged operations, such as creating sockets that listen on privileged ports.
4a364d1
+.TP
4a364d1
+.BI \-chroot \ dir
4a364d1
+Chroot to directory after processing the command line arguments, but before reading the configuration file.
4a364d1
 .PP
4a364d1
 .I Modifying default file locations:
4a364d1
 The following options can be used to modify the locations 
e83fb19
diff -up dhcp-4.3.0a1/server/dhcpd.c.paranoia dhcp-4.3.0a1/server/dhcpd.c
e83fb19
--- dhcp-4.3.0a1/server/dhcpd.c.paranoia	2013-12-19 16:30:21.347212261 +0100
e83fb19
+++ dhcp-4.3.0a1/server/dhcpd.c	2013-12-19 16:30:21.414211331 +0100
e83fb19
@@ -623,7 +623,11 @@ main(int argc, char **argv) {
58a3b6c
 	group_write_hook = group_writer;
58a3b6c
 
58a3b6c
 	/* Start up the database... */
58a3b6c
+#if defined (PARANOIA)
58a3b6c
+	db_startup (lftest, set_uid, set_gid);
58a3b6c
+#else
58a3b6c
 	db_startup (lftest);
58a3b6c
+#endif /* PARANOIA */
58a3b6c
 
58a3b6c
 	if (lftest)
58a3b6c
 		exit (0);
e83fb19
@@ -694,22 +698,6 @@ main(int argc, char **argv) {
58a3b6c
 			exit (0);
58a3b6c
 	}
58a3b6c
  
58a3b6c
-#if defined (PARANOIA)
58a3b6c
-	/* change uid to the specified one */
58a3b6c
-
58a3b6c
-	if (set_gid) {
58a3b6c
-		if (setgroups (0, (void *)0))
58a3b6c
-			log_fatal ("setgroups: %m");
58a3b6c
-		if (setgid (set_gid))
58a3b6c
-			log_fatal ("setgid(%d): %m", (int) set_gid);
58a3b6c
-	}	
58a3b6c
-
58a3b6c
-	if (set_uid) {
58a3b6c
-		if (setuid (set_uid))
58a3b6c
-			log_fatal ("setuid(%d): %m", (int) set_uid);
58a3b6c
-	}
58a3b6c
-#endif /* PARANOIA */
58a3b6c
-
58a3b6c
 	/*
58a3b6c
 	 * Deal with pid files.  If the user told us
58a3b6c
 	 * not to write a file we don't read one either
e83fb19
@@ -746,6 +734,22 @@ main(int argc, char **argv) {
58a3b6c
 		}
58a3b6c
 	}
58a3b6c
 
58a3b6c
+#if defined (PARANOIA)
58a3b6c
+	/* change uid to the specified one */
58a3b6c
+
58a3b6c
+	if (set_gid) {
58a3b6c
+		if (setgroups (0, (void *)0))
58a3b6c
+			log_fatal ("setgroups: %m");
58a3b6c
+		if (setgid (set_gid))
58a3b6c
+			log_fatal ("setgid(%d): %m", (int) set_gid);
58a3b6c
+	}	
58a3b6c
+
58a3b6c
+	if (set_uid) {
58a3b6c
+		if (setuid (set_uid))
58a3b6c
+			log_fatal ("setuid(%d): %m", (int) set_uid);
58a3b6c
+	}
58a3b6c
+#endif /* PARANOIA */
58a3b6c
+
58a3b6c
 	/* If we were requested to log to stdout on the command line,
58a3b6c
 	   keep doing so; otherwise, stop. */
58a3b6c
 	if (log_perror == -1)