diff --git a/CHANGES b/CHANGES index 8ab749ead9..f2d723526c 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,8 @@ + 299. [cleanup] Get the user and group information before changing the + root directory, so the administrator does not need to + keep a copy of the user and group databases in the + chroot'ed environment. Suggested by Hakan Olsson. + 298. [bug] A mutex deadlock occurred during shutdown of the interface manager under certain conditions. Digital Unix systems were the most affected. @@ -23,7 +28,7 @@ reverts to "name_current" instead of staying as "name_glue". - 293. [port] Add support for freebsd 4.0 system tests. + 293. [port] Add support for FreeBSD 4.0 system tests. 292. [bug] Due to problems with the way some operating systems handle simultaneous listening on IPv4 and IPv6 @@ -66,7 +71,7 @@ 283. [cleanup] The 'lwresd' program is now a link to 'named'. 282. [bug] The lexer now returns ISC_R_RANGE if parsed integer is - too big for an usigned long. + too big for an unsigned long. 281. [bug] Fixed list of recognized config file category names. diff --git a/bin/named/main.c b/bin/named/main.c index e98430eed8..90e2736f20 100644 --- a/bin/named/main.c +++ b/bin/named/main.c @@ -15,7 +15,7 @@ * SOFTWARE. */ -/* $Id: main.c,v 1.71 2000/06/22 21:49:31 tale Exp $ */ +/* $Id: main.c,v 1.72 2000/07/01 00:48:02 tale Exp $ */ #include @@ -405,6 +405,13 @@ static void setup(void) { isc_result_t result; + /* + * Get the user and group information before changing the root + * directory, so the administrator does not need to keep a copy + * of the user and group databases in the chroot'ed environment. + */ + ns_os_inituserinfo(ns_g_username); + ns_os_chroot(ns_g_chrootdir); /* @@ -415,7 +422,7 @@ setup(void) { * time. (We need to read the config file to know which possibly * privileged ports to bind() to.) */ - ns_os_minprivs(ns_g_username); + ns_os_minprivs(); result = ns_log_init(ISC_TF(ns_g_username != NULL)); if (result != ISC_R_SUCCESS) diff --git a/bin/named/server.c b/bin/named/server.c index 1e1ccf925f..88d923598c 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -15,7 +15,7 @@ * SOFTWARE. */ -/* $Id: server.c,v 1.200 2000/06/23 01:08:29 gson Exp $ */ +/* $Id: server.c,v 1.201 2000/07/01 00:48:03 tale Exp $ */ #include @@ -1334,7 +1334,7 @@ load_configuration(const char *filename, ns_server_t *server, * Relinquish root privileges. */ if (first_time) - ns_os_changeuser(ns_g_username); + ns_os_changeuser(); /* * Configure the logging system. diff --git a/bin/named/unix/include/named/os.h b/bin/named/unix/include/named/os.h index afe7c6d87e..7082dd575d 100644 --- a/bin/named/unix/include/named/os.h +++ b/bin/named/unix/include/named/os.h @@ -15,7 +15,7 @@ * SOFTWARE. */ -/* $Id: os.h,v 1.7 2000/06/22 21:49:58 tale Exp $ */ +/* $Id: os.h,v 1.8 2000/07/01 00:48:06 tale Exp $ */ #ifndef NS_OS_H #define NS_OS_H 1 @@ -32,10 +32,13 @@ void ns_os_chroot(const char *root); void -ns_os_changeuser(const char *username); +ns_os_inituserinfo(const char *username); void -ns_os_minprivs(const char *username); +ns_os_changeuser(void); + +void +ns_os_minprivs(void); void ns_os_writepidfile(const char *filename); diff --git a/bin/named/unix/os.c b/bin/named/unix/os.c index d70997960b..9576c7ce60 100644 --- a/bin/named/unix/os.c +++ b/bin/named/unix/os.c @@ -15,7 +15,7 @@ * SOFTWARE. */ -/* $Id: os.c,v 1.19 2000/06/28 16:26:40 explorer Exp $ */ +/* $Id: os.c,v 1.20 2000/07/01 00:48:05 tale Exp $ */ #include @@ -43,6 +43,8 @@ static isc_boolean_t non_root_caps = ISC_FALSE; static isc_boolean_t non_root = ISC_FALSE; #endif +static uid_t runas_uid = 0; + #ifdef HAVE_LINUX_CAPABILITY_H /* @@ -260,7 +262,7 @@ ns_os_chroot(const char *root) { } void -ns_os_changeuser(const char *username) { +ns_os_inituserinfo(const char *username) { struct passwd *pw; if (username == NULL || getuid() != 0) @@ -277,28 +279,35 @@ ns_os_changeuser(const char *username) { else pw = getpwnam(username); endpwent(); + if (pw == NULL) ns_main_earlyfatal("user '%s' unknown", username); + if (initgroups(pw->pw_name, pw->pw_gid) < 0) ns_main_earlyfatal("initgroups(): %s", strerror(errno)); + if (setgid(pw->pw_gid) < 0) ns_main_earlyfatal("setgid(): %s", strerror(errno)); - if (setuid(pw->pw_uid) < 0) + + runas_uid = pw->pw_uid; +} + +void +ns_os_changeuser(void) { + if (runas_uid != 0 && setuid(runas_uid) < 0) ns_main_earlyfatal("setuid(): %s", strerror(errno)); } void -ns_os_minprivs(const char *username) { +ns_os_minprivs(void) { #ifdef HAVE_LINUX_CAPABILITY_H #if defined(HAVE_LINUX_PRCTL_H) && defined(PR_SET_KEEPCAPS) linux_keepcaps(); - ns_os_changeuser(username); -#else - (void)username; + ns_os_changeuser(); #endif + linux_minprivs(); -#else - (void)username; + #endif /* HAVE_LINUX_CAPABILITY_H */ }