From 797e929482f78f0767d04b6d045a19c21f4ed0a8 Mon Sep 17 00:00:00 2001
From: Stephan Bosch <stephan@rename-it.nl>
Date: Wed, 17 Dec 2014 01:12:43 +0100
Subject: [PATCH] lib-sieve: program client: Made sure supplemental group
 privileges are also dropped.

---
 src/lib-sieve/util/program-client-local.c | 35 +++++++++++------------
 1 file changed, 16 insertions(+), 19 deletions(-)

diff --git a/src/lib-sieve/util/program-client-local.c b/src/lib-sieve/util/program-client-local.c
index e79841b38..0300ad9c9 100644
--- a/src/lib-sieve/util/program-client-local.c
+++ b/src/lib-sieve/util/program-client-local.c
@@ -18,7 +18,7 @@
 #include <sys/wait.h>
 #include <unistd.h>
 #include <fcntl.h>
-
+#include <grp.h>
 
 struct program_client_local {
 	struct program_client client;
@@ -186,33 +186,30 @@ static int program_client_local_connect
 			if (seteuid(0) < 0)
 				i_fatal("seteuid(0) failed: %m");
 
-			/* drop gid first */
+			/* drop gids first */
 			gid = getgid();
 			if ( gid == 0 || gid != pclient->set.gid ) {
-				if ( pclient->set.gid != 0 ) {
-					if ( setgid(pclient->set.gid) < 0 )
-						i_fatal("setgid(%d) failed: %m", pclient->set.gid);
-				} else {
+				if ( pclient->set.gid != 0 )
+					gid = pclient->set.gid;
+				else
 					gid = getegid();
-					if (gid != 0 && setgid(gid) < 0) {
-						i_fatal("setgid(%d) failed: %m", gid);
-					}
-				}
 			}
+	    if ( setgroups(1, &gid) < 0 )
+				i_fatal("setgroups(%d) failed: %m", gid);
+			if ( gid != 0 && setgid(gid) < 0 )
+				i_fatal("setgid(%d) failed: %m", gid);
 		
 			/* drop uid */
-			if ( pclient->set.uid != 0 ) {
-				if ( setuid(pclient->set.uid) )
-					i_fatal("setuid(%d) failed: %m", pclient->set.uid);
-			} else {
+			if ( pclient->set.uid != 0 )
+				uid = pclient->set.uid;
+			else
 				uid = geteuid();
-				if ( uid != 0 && setuid(uid) < 0 )
-					i_fatal("setuid(%d) failed: %m", uid);
-			}
+			if ( uid != 0 && setuid(uid) < 0 )
+				i_fatal("setuid(%d) failed: %m", uid);
 		}
 
-		i_assert(getuid() != 0);
-		i_assert(getgid() != 0);
+		i_assert(pclient->set.uid == 0 || getuid() != 0);
+		i_assert(pclient->set.gid == 0 || getgid() != 0);
 
 		if ( array_is_created(&pclient->envs) )
 			envs = array_get(&pclient->envs, &count);
-- 
GitLab