
paranoia (non-root/chroot) patch for ISC dhcp 2.0
file to patch: dhcp-2.0/server/dhcpd.c

Adds 3 options:

	-user <user>
	-group <group> 
	-chroot <chroot_dir>

Notes:
	-DPARANOIA must be added to the COPTS variable in server/Makefile
	after configuration.  Otherwise, the paranoia code will not be
	compiled in.

	You may need to change the ownership of the lease directory to the
	user you tell dhcpd to run as.  Otherwise, you may have problems
	rewriting the lease file.


ari edelkind (04/06/2000)
last modified 03/20/2001


*** dhcp-2.0/server/dhcpd.c	Tue Jun 22 09:43:18 1999
--- dhcp-2.0+paranoia/server/dhcpd.c	Tue Mar 20 23:20:34 2001
***************
*** 55,60 ****
--- 55,69 ----
  #include "dhcpd.h"
  #include "version.h"
  
+ #ifdef PARANOIA
+ #	include <errno.h>
+ #	include <pwd.h>
+ /* get around the ISC's declaration of group */
+ #define group  real_group
+ #	include <grp.h>
+ #undef group
+ #endif
+ 
  static void usage PROTO ((char *));
  
  TIME cur_time;
***************
*** 92,98 ****
--- 101,115 ----
  	int daemon = 1;
  #endif
  	int quiet = 0;
+ #ifdef PARANOIA
+ 	char *set_user   = NULL;
+ 	char *set_group  = NULL;
+ 	char *set_chroot = NULL;
  
+ 	uid_t set_uid = 0;
+ 	gid_t set_gid = 0;
+ #endif
+ 
  	appname = strrchr (argv [0], '/');
  	if (!appname)
  		appname = argv [0];
***************
*** 139,144 ****
--- 156,175 ----
  			daemon = 0;
  #endif
  			log_perror = -1;
+ #ifdef PARANOIA
+ 		} else if (!strcmp (argv [i], "-user")) {
+ 			if (++i == argc)
+ 				usage (appname);
+ 			set_user = argv [i];
+ 		} else if (!strcmp (argv [i], "-group")) {
+ 			if (++i == argc)
+ 				usage (appname);
+ 			set_group = argv [i];
+ 		} else if (!strcmp (argv [i], "-chroot")) {
+ 			if (++i == argc)
+ 				usage (appname);
+ 			set_chroot = argv [i];
+ #endif
  		} else if (!strcmp (argv [i], "-cf")) {
  			if (++i == argc)
  				usage (appname);
***************
*** 201,206 ****
--- 232,285 ----
  #endif
  	}
    
+ #ifdef PARANOIA
+ 	/* get user and group info if those options were given */
+ 	if (set_user) {
+ 		struct passwd *tmp_pwd;
+ 
+ 		if (geteuid())
+ 			error ("you must be root to set user");
+ 
+ 		if (!(tmp_pwd = getpwnam(set_user)))
+ 			error ("no such user: %s", set_user);
+ 
+ 		set_uid = tmp_pwd->pw_uid;
+ 
+ 		/* use the user's group as the default gid */
+ 		if (!set_group)
+ 			set_gid = tmp_pwd->pw_gid;
+ 		
+ 	}
+ 
+ 	if (set_group) {
+ /* get around the ISC's declaration of group */
+ #define group real_group
+ 		struct group *tmp_grp;
+ 
+ 		if (geteuid())
+ 			error ("you must be root to set group");
+ 
+ 		if (!(tmp_grp = getgrnam(set_group)))
+ 			error ("no such group: %s", set_group);
+ 
+ 		set_gid = tmp_grp->gr_gid;
+ #undef group
+ 	}
+ 
+ 	if (set_chroot) {
+ 		if (geteuid())
+ 			error ("you must be root to use chroot");
+ 
+ 		if (chroot(set_chroot)) {
+ 			error ("chroot(\"%s\"): %m", set_chroot);
+ 		}
+ 		if (chdir ("/")) {
+ 			/* probably permission denied */
+ 			error ("chdir(\"/\"): %m");
+ 		}
+ 	}
+ #endif /* PARANOIA */
+ 
  	remote_port = htons (ntohs (local_port) + 1);
  
  	/* Get the current time... */
***************
*** 285,290 ****
--- 364,385 ----
  	}
  #endif /* !DEBUG */
  
+ #ifdef PARANOIA
+ 	/* change uid to the specified one */
+ 
+ 	if (set_gid) {
+ 		if (setgroups (0, NULL))
+ 			error ("setgroups: %m");
+ 		if (setgid (set_gid))
+ 			error ("setgid(%d): %m", set_gid);
+ 	}	
+ 
+ 	if (set_uid) {
+ 		if (setuid (set_uid))
+ 			error ("setuid(%d): %m", set_uid);
+ 	}
+ #endif
+ 
  	/* Set up the bootp packet handler... */
  	bootp_packet_handler = do_packet;
  
***************
*** 308,315 ****
--- 403,415 ----
  	note (url);
  	note ("");
  
+ #ifdef PARANOIA
+ 	warn ("Usage: %s [-p <UDP port #>] [-d] [-f] [-user <user>]", appname);
+ 	warn ("            [-group <group>] [-chroot <dir>] [-cf config-file]");
+ #else
  	warn ("Usage: %s [-p <UDP port #>] [-d] [-f] [-cf config-file]",
  	      appname);
+ #endif
  	error("            [-lf lease-file] [-pf pidfile] [if0 [...ifN]]");
  }
  
