diff -upk.orig dhcp-3.0.3.orig/client/dhclient.c dhcp-3.0.3/client/dhclient.c --- dhcp-3.0.3.orig/client/dhclient.c 2005-03-03 16:55:22 +0000 +++ dhcp-3.0.3/client/dhclient.c 2005-10-26 17:15:00 +0000 @@ -112,6 +112,7 @@ int main (argc, argv, envp) } else if (i != -1) close (i); + tzset(); #ifdef SYSLOG_4_2 openlog ("dhclient", LOG_NDELAY); log_priority = LOG_DAEMON; diff -upk.orig dhcp-3.0.3.orig/dhcpctl/omshell.c dhcp-3.0.3/dhcpctl/omshell.c --- dhcp-3.0.3.orig/dhcpctl/omshell.c 2004-09-30 23:11:50 +0000 +++ dhcp-3.0.3/dhcpctl/omshell.c 2005-10-26 17:15:00 +0000 @@ -102,6 +102,7 @@ int main (int argc, char **argv, char ** } /* Initially, log errors to stderr as well as to syslogd. */ + tzset(); #ifdef SYSLOG_4_2 openlog ("omshell", LOG_NDELAY); log_priority = DHCPD_LOG_FACILITY; diff -upk.orig dhcp-3.0.3.orig/includes/cf/linux.h dhcp-3.0.3/includes/cf/linux.h --- dhcp-3.0.3.orig/includes/cf/linux.h 2005-10-26 17:14:40 +0000 +++ dhcp-3.0.3/includes/cf/linux.h 2005-10-26 17:15:00 +0000 @@ -83,11 +83,11 @@ extern int h_errno; directory. */ #ifndef _PATH_DHCPD_DB -#define _PATH_DHCPD_DB "/var/lib/dhcp/dhcpd.leases" +#define _PATH_DHCPD_DB "/state/dhcpd.leases" #endif #ifndef _PATH_DHCLIENT_DB -#define _PATH_DHCLIENT_DB "/var/lib/dhcp/dhclient.leases" +#define _PATH_DHCLIENT_DB "/var/lib/dhcp/dhclient/state/dhclient.leases" #endif /* Varargs stuff... */ diff -upk.orig dhcp-3.0.3.orig/relay/dhcrelay.8 dhcp-3.0.3/relay/dhcrelay.8 --- dhcp-3.0.3.orig/relay/dhcrelay.8 2004-10-04 20:40:07 +0000 +++ dhcp-3.0.3/relay/dhcrelay.8 2005-10-26 17:15:00 +0000 @@ -77,6 +77,14 @@ dhcrelay - Dynamic Host Configuration Pr | .I discard ] +[ +.B -u +.I user +] +[ +.B -j +.I chroot-dir +] .I server0 [ .I ...serverN @@ -139,6 +147,11 @@ This can be unhelpful in a system startu behaviour, specify the .B -q flag. +.PP +Upon startup, this version of dhcrelay will switch to a non-root +pseudo-user and enter a chroot jail. The default username (\fIdhcrelay\fR) +and the default chroot jail directory path (\fI/var/empty\fR) +may be overridden with the \fB-u\fR and \fB-j\fR options, respectively. .SH RELAY AGENT INFORMATION OPTIONS If the .B -a @@ -239,7 +252,12 @@ has been written for Internet Systems Co by Ted Lemon in cooperation with Vixie Enterprises. To learn more about Internet Systems Consortium, see -.B http://www.isc.org/isc. +.BR http://www.isc.org/isc . To learn more about Vixie Enterprises, see -.B http://www.vix.com. +.BR http://www.vix.com . +.PP +This version of dhcrelay has been modified for ALT Linux +.RB ( http://www.altlinux.com/ ). +In particular, the privilege reduction functionality and the \fB-u\fR +and \fB-j\fR options are Openwall/ALT Linux extensions. diff -upk.orig dhcp-3.0.3.orig/relay/dhcrelay.c dhcp-3.0.3/relay/dhcrelay.c --- dhcp-3.0.3.orig/relay/dhcrelay.c 2005-03-03 16:55:24 +0000 +++ dhcp-3.0.3/relay/dhcrelay.c 2005-10-26 17:15:00 +0000 @@ -39,6 +39,12 @@ static char ocopyright[] = #include "dhcpd.h" #include "version.h" +#include +#include +#include +#define group real_group +#include +#undef group static void usage PROTO ((void)); @@ -102,6 +108,32 @@ static char arr [] = "All rights reserve static char message [] = "Internet Systems Consortium DHCP Relay Agent"; static char url [] = "For info, please visit http://www.isc.org/sw/dhcp/"; +static int drop_priv(const char *server_user, const char *server_jail) +{ + struct passwd *pw; + + if (!server_user) + server_user = "dhcrelay"; + if (!server_jail) + server_jail = "/var/empty"; + if (!*server_user || !*server_jail) + return 0; + + if (!(pw = getpwnam(server_user))) + return -1; + + if (initgroups(server_user, pw->pw_gid) || setgid(pw->pw_gid)) + return -1; + + if (chroot(server_jail) || chdir("/")) + return -1; + + if (setuid(pw->pw_uid)) + return -1; + + return 0; +} + int main (argc, argv, envp) int argc; char **argv, **envp; @@ -114,6 +146,9 @@ int main (argc, argv, envp) isc_result_t status; char *s; + char *server_user = NULL; + char *server_jail = NULL; + /* Make sure we have stdin, stdout and stderr. */ i = open ("/dev/null", O_RDWR); if (i == 0) @@ -124,6 +159,7 @@ int main (argc, argv, envp) } else if (i != -1) close (i); + tzset(); #ifdef SYSLOG_4_2 openlog ("dhcrelay", LOG_NDELAY); log_priority = LOG_DAEMON; @@ -185,6 +221,14 @@ int main (argc, argv, envp) if (++i == argc) usage (); dhcp_max_agent_option_packet_length = atoi (argv [i]); + } else if (!strcmp (argv [i], "-u")) { + if (++i == argc) + usage (); + server_user = argv[i]; + } else if (!strcmp (argv [i], "-j")) { + if (++i == argc) + usage (); + server_jail = argv[i]; } else if (!strcmp (argv [i], "-m")) { if (++i == argc) usage (); @@ -316,6 +360,9 @@ int main (argc, argv, envp) pid = setsid (); } + if (drop_priv(server_user, server_jail) < 0) + log_fatal("Failed to lower privileges."); + /* Start dispatching packets and timeouts... */ dispatch (); @@ -455,10 +502,11 @@ void relay (ip, packet, length, from_por static void usage () { - log_fatal ("Usage: dhcrelay [-p ] [-d] [-D] [-i %s%s%s%s", + log_fatal ("Usage: dhcrelay [-p ] [-d] [-D] [-i %s%s%s%s%s", "interface] [-q] [-a]\n ", "[-c count] [-A length] ", "[-m append|replace|forward|discard]\n", + "[-u user] [-j chroot-dir]\n", " [server1 [... serverN]]"); } diff -upk.orig dhcp-3.0.3.orig/server/dhcpd.8 dhcp-3.0.3/server/dhcpd.8 --- dhcp-3.0.3.orig/server/dhcpd.8 2004-09-29 23:01:50 +0000 +++ dhcp-3.0.3/server/dhcpd.8 2005-10-26 17:15:00 +0000 @@ -70,6 +70,14 @@ dhcpd - Dynamic Host Configuration Proto .I trace-playback-file ] [ +.B -u +.I user +] +[ +.B -j +.I chroot-dir +] +[ .I if0 [ .I ...ifN @@ -232,6 +240,12 @@ using the \fB-lf\fR switch, so that the your existing lease file with its test data. The DHCP server will refuse to operate in playback mode unless you specify an alternate lease file. +.PP +Upon startup, this version of the DHCP server will switch to a non-root +pseudo-user and enter a chroot jail. The default username (\fIdhcpd\fR) +and the default chroot jail directory path (\fI/var/lib/dhcp/dhcpd\fR) +may be overridden with the \fB-u\fR and \fB-j\fR options, respectively. +.PP .SH CONFIGURATION The syntax of the dhcpd.conf(5) file is discussed separately. This section should be used as an overview of the configuration process, @@ -732,3 +746,8 @@ Consortium. Version 3 of the DHCP serv Information about Internet Systems Consortium is available at .B http://www.isc.org/\fR. Information about Nominum can be found at \fBhttp://www.nominum.com/\fR. +.PP +This version of dhcpd has been modified for ALT Linux +.RB ( http://www.altlinux.com/ ). +In particular, the privilege reduction functionality and the \fB-u\fR +and \fB-j\fR options are Openwall/ALT Linux extensions. diff -upk.orig dhcp-3.0.3.orig/server/dhcpd.c dhcp-3.0.3/server/dhcpd.c --- dhcp-3.0.3.orig/server/dhcpd.c 2005-03-03 16:55:24 +0000 +++ dhcp-3.0.3/server/dhcpd.c 2005-10-26 17:29:29 +0000 @@ -46,6 +46,12 @@ static char url [] = "For info, please v #include "dhcpd.h" #include "version.h" #include +#include +#include +#include +#define group real_group +#include +#undef group static void usage PROTO ((void)); @@ -193,6 +199,32 @@ static void omapi_listener_start (void * omapi_object_dereference (&listener, MDL); } +static int drop_priv(const char *server_user, const char *server_jail) +{ + struct passwd *pw; + + if (!server_user) + server_user = "dhcpd"; + if (!server_jail) + server_jail = "/var/lib/dhcp/dhcpd"; + if (!*server_user || !*server_jail) + return 0; + + if (!(pw = getpwnam(server_user))) + return -1; + + if (initgroups(server_user, pw->pw_gid) || setgid(pw->pw_gid)) + return -1; + + if (chroot(server_jail) || chdir("/")) + return -1; + + if (setuid(pw->pw_uid)) + return -1; + + return 0; +} + int main (argc, argv, envp) int argc; char **argv, **envp; @@ -226,6 +258,9 @@ int main (argc, argv, envp) char *traceoutfile = (char *)0; #endif + char *server_user = NULL; + char *server_jail = NULL; + /* Make sure we have stdin, stdout and stderr. */ status = open ("/dev/null", O_RDWR); if (status == 0) @@ -252,6 +287,7 @@ int main (argc, argv, envp) dhcp_common_objects_setup (); /* Initially, log errors to stderr as well as to syslogd. */ + tzset(); #ifdef SYSLOG_4_2 openlog ("dhcpd", LOG_NDELAY); log_priority = DHCPD_LOG_FACILITY; @@ -320,6 +356,14 @@ int main (argc, argv, envp) } else if (!strcmp (argv [i], "-q")) { quiet = 1; quiet_interface_discovery = 1; + } else if (!strcmp (argv [i], "-u")) { + if (++i == argc) + usage(); + server_user = argv[i]; + } else if (!strcmp (argv [i], "-j")) { + if (++i == argc) + usage(); + server_jail = argv[i]; } else if (!strcmp (argv [i], "--version")) { log_info ("isc-dhcpd-%s", DHCP_VERSION); exit (0); @@ -499,12 +543,6 @@ int main (argc, argv, envp) group_write_hook = group_writer; - /* Start up the database... */ - db_startup (lftest); - - if (lftest) - exit (0); - /* Discover all the network interfaces and initialize them. */ discover_interfaces (DISCOVER_SERVER); @@ -525,7 +563,11 @@ int main (argc, argv, envp) #if defined (TRACING) trace_seed_stash (trace_srandom, seed + cur_time); #endif - postdb_startup (); + + /* Initialize the omapi listener state. */ + if (omapi_port != -1) { + omapi_listener_start (0); + } #ifndef DEBUG if (daemon) { @@ -560,6 +602,11 @@ int main (argc, argv, envp) } } + if (pidfilewritten) { + if (drop_priv(server_user, server_jail) < 0) + log_fatal("Failed to lower privileges."); + } + /* If we were requested to log to stdout on the command line, keep doing so; otherwise, stop. */ if (log_perror == -1) @@ -588,7 +635,21 @@ int main (argc, argv, envp) close (i); pidfilewritten = 1; } + if (drop_priv(server_user, server_jail) < 0) + log_fatal("Failed to lower privileges."); } + + /* Start up the database... */ + db_startup (lftest); + + if (lftest) + exit (0); + +#if defined (FAILOVER_PROTOCOL) + /* Initialize the failover listener state. */ + dhcp_failover_startup (); +#endif + #endif /* !DEBUG */ #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \ @@ -881,8 +942,9 @@ static void usage () log_info (copyright); log_info (arr); - log_fatal ("Usage: dhcpd [-p ] [-d] [-f]%s%s%s%s", + log_fatal ("Usage: dhcpd [-p ] [-d] [-f]%s%s%s%s%s", "\n [-cf config-file] [-lf lease-file]", + "\n [-u user] [-j chroot-dir]", #if defined (TRACING) "\n [-tf trace-output-file]", "\n [-play trace-input-file]",