From e3d74828455179805c8ecd88964241fd20264eb8 Mon Sep 17 00:00:00 2001 From: hno <> Date: Thu, 21 Oct 2004 04:41:03 +0000 Subject: [PATCH] Bug #1021: Supplementary groups membership initialization for children processes By Dimitry V. Ketov, based on code from Apache. --- configure.in | 5 ++-- include/initgroups.h | 17 +++++++++++++ lib/initgroups.c | 60 ++++++++++++++++++++++++++++++++++++++++++++ src/cf.data.pre | 34 +++++++++++++------------ src/squid.h | 6 ++++- src/tools.cc | 34 ++++++++++++++++++------- 6 files changed, 128 insertions(+), 28 deletions(-) create mode 100644 include/initgroups.h create mode 100644 lib/initgroups.c diff --git a/configure.in b/configure.in index 843f0d57d9..3986ebaa94 100644 --- a/configure.in +++ b/configure.in @@ -3,7 +3,7 @@ dnl Configuration input file for Squid dnl dnl Duane Wessels, wessels@nlanr.net, February 1996 (autoconf v2.9) dnl -dnl $Id: configure.in,v 1.361 2004/10/17 22:13:02 hno Exp $ +dnl $Id: configure.in,v 1.362 2004/10/20 22:41:03 hno Exp $ dnl dnl dnl @@ -13,7 +13,7 @@ AC_CONFIG_SRCDIR([src/main.cc]) AC_CONFIG_AUX_DIR(cfgaux) AM_INIT_AUTOMAKE(squid, 3.0-PRE3-CVS) AM_CONFIG_HEADER(include/autoconf.h) -AC_REVISION($Revision: 1.361 $)dnl +AC_REVISION($Revision: 1.362 $)dnl AC_PREFIX_DEFAULT(/usr/local/squid) AM_MAINTAINER_MODE @@ -2260,6 +2260,7 @@ AC_REPLACE_FUNCS(\ drand48 \ tempnam \ strerror \ + initgroups ) dnl Not cached since people are likely to tune this diff --git a/include/initgroups.h b/include/initgroups.h new file mode 100644 index 0000000000..8ac51fb39c --- /dev/null +++ b/include/initgroups.h @@ -0,0 +1,17 @@ +/* + * $Id: initgroups.h,v 1.1 2004/10/20 22:41:03 hno Exp $ + */ +#ifndef SQUID_INITGROUPS_H +#define SQUID_INITGROUPS_H + +/* if you have configure you can use this */ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#if HAVE_SYS_TYPES_H +#include +#endif + +extern int initgroups(const char *user, gid_t group); +#endif /* SQUID_INITGROPS_H */ diff --git a/lib/initgroups.c b/lib/initgroups.c new file mode 100644 index 0000000000..ec84174385 --- /dev/null +++ b/lib/initgroups.c @@ -0,0 +1,60 @@ +#include "config.h" + +#if HAVE_GRP_H +#include +#endif +#if HAVE_SYS_TYPES_H +#include +#endif +#if HAVE_UNISTD_H +#include +#endif +#if HAVE_STRING_H +#include +#endif +#if HAVE_STRINGS_H +#include +#endif +#if HAVE_LIMITS_H +#include +#endif + +int initgroups(const char *name, gid_t basegid) +{ +#ifdef HAVE_SETGROUPS +#ifndef NGROUPS_MAX +#define NGROUPS_MAX 16 +#endif + + gid_t groups[NGROUPS_MAX]; + struct group *g; + int index = 0; + + setgrent(); + + groups[index++] = basegid; + + while (index < NGROUPS_MAX && ((g = getgrent()) != NULL)) { + if (g->gr_gid != basegid) { + char **names; + + for (names = g->gr_mem; *names != NULL; ++names) { + + if (!strcmp(*names, name)) + groups[index++] = g->gr_gid; + + } + } + } + + endgrent(); + + return setgroups(index, groups); + +#else + + return 0; + +#endif /* def HAVE_SETGROUPS */ +} + diff --git a/src/cf.data.pre b/src/cf.data.pre index 4d429dfb3a..84e592b97a 100644 --- a/src/cf.data.pre +++ b/src/cf.data.pre @@ -1,6 +1,6 @@ # -# $Id: cf.data.pre,v 1.360 2004/10/18 12:20:09 hno Exp $ +# $Id: cf.data.pre,v 1.361 2004/10/20 22:41:04 hno Exp $ # # # SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -2828,27 +2828,29 @@ NAME: cache_effective_user TYPE: string DEFAULT: nobody LOC: Config.effectiveUser -DOC_NONE +DOC_START + If you start Squid as root, it will change its effective/real + UID/GID to the user specified below. The default is to change + to UID to nobody. If you define cache_effective_user, but not + cache_effective_group, Squid sets the GID to the effective + user's default group ID (taken from the password file) and + supplementary group list from the from groups membership of + cache_effective_user. +DOC_END + NAME: cache_effective_group TYPE: string DEFAULT: none LOC: Config.effectiveGroup DOC_START - - If you start Squid as root, it will change its effective/real - UID/GID to the UID/GID specified below. The default is to - change to UID to nobody. If you define cache_effective_user, - but not cache_effective_group, Squid sets the GID the - effective user's default group ID (taken from the password - file). - - If Squid is not started as root, the cache_effective_user - value is ignored and the GID value is unchanged by default. - However, you can make Squid change its GID to another group - that the process owner is a member of. Note that if Squid - is not started as root you cannot set http_port to a - value lower than 1024. + If you want Squid to run with a specific GID regardless of + the group memberships of the effective user then set this + to the group (or GID) you want Squid to run as. When set + all other group privileges of the effective user is ignored + and only this GID is effective. If Squid is not started as + root the user starting Squid must be member of the specified + group. DOC_END diff --git a/src/squid.h b/src/squid.h index eae12a7269..bfb15660a6 100644 --- a/src/squid.h +++ b/src/squid.h @@ -1,6 +1,6 @@ /* - * $Id: squid.h,v 1.237 2004/08/30 05:12:31 robertc Exp $ + * $Id: squid.h,v 1.238 2004/10/20 22:41:05 hno Exp $ * * AUTHOR: Duane Wessels * @@ -364,6 +364,10 @@ extern "C" #include "snprintf.h" #endif +#if !HAVE_INITGROUPS +#include "initgroups.h" +#endif + #ifndef min template diff --git a/src/tools.cc b/src/tools.cc index 869b9fc699..4383758a39 100644 --- a/src/tools.cc +++ b/src/tools.cc @@ -1,6 +1,6 @@ /* - * $Id: tools.cc,v 1.243 2004/08/30 05:12:31 robertc Exp $ + * $Id: tools.cc,v 1.244 2004/10/20 22:41:05 hno Exp $ * * DEBUG: section 21 Misc Functions * AUTHOR: Harvest Derived @@ -649,6 +649,19 @@ leave_suid(void) { debug(21, 3) ("leave_suid: PID %d called\n", (int) getpid()); + if (Config.effectiveGroup) { + +#if HAVE_SETGROUPS + + setgroups(1, &Config2.effectiveGroupID); + +#endif + + if (setgid(Config2.effectiveGroupID) < 0) + debug(50, 0) ("ALERT: setgid: %s\n", xstrerror()); + + } + if (geteuid() != 0) return; @@ -656,17 +669,20 @@ leave_suid(void) if (Config.effectiveUser == NULL) return; -#if HAVE_SETGROUPS - - setgroups(1, &Config2.effectiveGroupID); + debug(21, 3) ("leave_suid: PID %d giving up root, becoming '%s'\n", + (int) getpid(), Config.effectiveUser); -#endif + if (!Config.effectiveGroup) { - if (setgid(Config2.effectiveGroupID) < 0) - debug(50, 0) ("ALERT: setgid: %s\n", xstrerror()); + if (setgid(Config2.effectiveGroupID) < 0) + debug(50, 0) ("ALERT: setgid: %s\n", xstrerror()); - debug(21, 3) ("leave_suid: PID %d giving up root, becoming '%s'\n", - (int) getpid(), Config.effectiveUser); + if (initgroups(Config.effectiveUser, Config2.effectiveGroupID) < 0) { + debug(50, 0) ("ALERT: initgroups: unable to set groups for User %s " + "and Group %u", Config.effectiveUser, + (unsigned) Config2.effectiveGroupID); + } + } #if HAVE_SETRESUID -- 2.47.2