changeset 4867:1120c8b667e5 HEAD

restrict_gid_first/last wasn't working correctly for non-primary groups. Also restrict_gid_first=0 caused failures if user had 0 in non-primary groups.
author Timo Sirainen <tss@iki.fi>
date Sun, 03 Dec 2006 17:45:10 +0200
parents 4ec6ceb0934a
children 3066b42c4b98
files src/lib/restrict-access.c
diffstat 1 files changed, 10 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib/restrict-access.c	Sun Dec 03 17:21:29 2006 +0200
+++ b/src/lib/restrict-access.c	Sun Dec 03 17:45:10 2006 +0200
@@ -53,7 +53,7 @@
 	return gid_list;
 }
 
-static void drop_restricted_groups(void)
+static void drop_restricted_groups(bool *have_root_group)
 {
 	/* @UNSAFE */
 	const char *env;
@@ -73,13 +73,16 @@
 
 	for (i = 0, used = 0; i < gid_count; i++) {
 		if (gid_list[i] >= first_valid_gid &&
-		    (last_valid_gid == 0 || gid_list[i] <= last_valid_gid))
+		    (last_valid_gid == 0 || gid_list[i] <= last_valid_gid)) {
+			if (gid_list[i] == 0)
+				*have_root_group = TRUE;
 			gid_list[used++] = gid_list[i];
+		}
 	}
 
 	if (used != gid_count) {
 		/* it did contain restricted groups, remove it */
-		if (setgroups(gid_count, gid_list) < 0)
+		if (setgroups(used, gid_list) < 0)
 			i_fatal("setgroups() failed: %m");
 	}
 	t_pop();
@@ -127,12 +130,14 @@
 	const char *env;
 	gid_t gid;
 	uid_t uid;
+	bool have_root_group;
 
 	/* groups - the getgid() checks are just so we don't fail if we're
 	   not running as root and try to just use our own GID. Do this
 	   before chrooting so initgroups() actually works. */
 	env = getenv("RESTRICT_SETGID");
 	gid = env == NULL ? 0 : (gid_t)strtoul(env, NULL, 10);
+	have_root_group = gid == 0;
 	if (gid != 0 && (gid != getgid() || gid != getegid())) {
 		if (setgid(gid) != 0)
 			i_fatal("setgid(%s) failed: %m", dec2str(gid));
@@ -150,7 +155,7 @@
 					env, dec2str(gid));
 			}
 
-                        drop_restricted_groups();
+                        drop_restricted_groups(&have_root_group);
 		}
 	}
 
@@ -192,7 +197,7 @@
 	}
 
 	env = getenv("RESTRICT_GID_FIRST");
-	if ((gid != 0 || (env != NULL && atoi(env) != 0)) && uid != 0) {
+	if ((!have_root_group || (env != NULL && atoi(env) != 0)) && uid != 0) {
 		if (getgid() == 0 || getegid() == 0 || setgid(0) == 0) {
 			if (gid == 0)
 				i_fatal("GID 0 isn't permitted");