paranoia (non-root/chroot) patch for ISC dhcp 2.0 file to patch: dhcp-2.0/server/dhcpd.c Adds 3 options: -user -group -chroot 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 + # include + /* get around the ISC's declaration of group */ + #define group real_group + # include + #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 ] [-d] [-f] [-user ]", appname); + warn (" [-group ] [-chroot ] [-cf config-file]"); + #else warn ("Usage: %s [-p ] [-d] [-f] [-cf config-file]", appname); + #endif error(" [-lf lease-file] [-pf pidfile] [if0 [...ifN]]"); }