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