--- pdnsd-1.2.4~/src/droppriv.h 1970-01-01 00:00:00 +0000 +++ pdnsd-1.2.4/src/droppriv.h 2005-09-27 15:01:18 +0000 @@ -0,0 +1,6 @@ +#ifndef DROPPRIV_H__ +#define DROPPRIV_H__ + +extern void drop_priv (const char user[], const char dir[]); + +#endif --- pdnsd-1.2.4~/src/droppriv.c 1970-01-01 00:00:00 +0000 +++ pdnsd-1.2.4/src/droppriv.c 2005-09-27 15:01:18 +0000 @@ -0,0 +1,46 @@ +#include +#include +#include +#include +#include +#include + +#include "droppriv.h" + +void +drop_priv (const char user[], const char dir[]) +{ + struct passwd *pw; + + if (geteuid ()) + return; + + if (!(user && *user)) + error (EXIT_FAILURE, 0, "user shouldn't be empty"); + if (!(dir && *dir)) + error (EXIT_FAILURE, 0, "chroot directory shouldn't be empty"); + + if ((setgroups (0, NULL) < 0)) + error (EXIT_FAILURE, errno, "setgroups"); + + pw = getpwnam (user); + if (!pw) + error (EXIT_FAILURE, 0, "lookup of user \"%s\" failed", user); + + endpwent (); + + if (!pw->pw_uid) + error (EXIT_FAILURE, 0, "user \"%s\" shouldn't be root", + user); + + if (chroot (dir) < 0) + error (EXIT_FAILURE, errno, "chroot to \"%s\" failed", dir); + if (chdir ("/") < 0) + error (EXIT_FAILURE, errno, "chroot to \"/\" failed"); + + if (setgid (pw->pw_gid) < 0) + error (EXIT_FAILURE, errno, "setgid"); + + if (setuid (pw->pw_uid) < 0) + error (EXIT_FAILURE, errno, "setuid"); +} --- pdnsd-1.2.4~/src/main.c 2005-08-21 13:08:03 +0000 +++ pdnsd-1.2.4/src/main.c 2005-09-27 15:04:15 +0000 @@ -47,6 +47,8 @@ Boston, MA 02111-1307, USA. */ #include "icmp.h" #include "hash.h" +#include "droppriv.h" + #if !defined(lint) && !defined(NO_RCSIDS) static char rcsid[]="$Id: main.c,v 1.42 2001/05/30 21:04:15 tmm Exp $"; #endif @@ -184,7 +186,10 @@ int final_init() log_error("tcp and udp initialization failed. Exiting."); return 0; } - if (global.strict_suid) { + /* XXX: chroot_dir and strict_setuid=off conflict */ + if (*global.chroot_dir) + drop_priv(global.run_as, global.chroot_dir); + else if (global.strict_suid) { if (!run_as(global.run_as)) { return 0; } @@ -479,10 +484,6 @@ int main(int argc,char *argv[]) if (!init_rng()) exit(1); -#if (TARGET==TARGET_LINUX) - if (!final_init()) - exit(1); -#endif { struct sigaction action; @@ -563,10 +564,6 @@ int main(int argc,char *argv[]) log_info(0,"pdnsd-%s starting.\n",VERSION); DEBUG_MSG("Debug messages activated\n"); -#if (TARGET!=TARGET_LINUX) - if (!final_init()) - _exit(1); -#endif #ifdef ENABLE_IPV4 if (run_ipv4) { DEBUG_MSG("Using IPv4.\n"); @@ -588,6 +585,8 @@ int main(int argc,char *argv[]) if (stat_pipe) init_stat_sock(); + if (!final_init()) + _exit(1); /* Before this point, logging and cache accesses are not locked because we are single-threaded. */ init_log_lock(); --- pdnsd-1.2.4~/src/Makefile.am 2005-03-17 21:08:21 +0000 +++ pdnsd-1.2.4/src/Makefile.am 2005-09-27 15:02:46 +0000 @@ -4,7 +4,7 @@ sbin_PROGRAMS = pdnsd pdnsd_SOURCES = conf-parser.c conff.c consts.c debug.c dns.c dns_answer.c \ dns_query.c error.c helpers.c icmp.c list.c main.c netdev.c rr_types.c \ - status.c servers.c thread.c cache.c hash.c conf-parser.h \ + status.c servers.c thread.c cache.c hash.c droppriv.c conf-parser.h \ conf-keywords.h conff.h consts.h debug.h dns.h dns_answer.h \ dns_query.h error.h helpers.h icmp.h ipvers.h list.h netdev.h \ rr_types.h servers.h status.h thread.h cache.h hash.h pdnsd_assert.h \