Index: src/lib/restrict-access.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib/restrict-access.c,v
retrieving revision 1.10
diff -u -3 -p -r1.10 restrict-access.c
--- src/lib/restrict-access.c	4 Mar 2003 04:00:13 -0000	1.10
+++ src/lib/restrict-access.c	15 Apr 2003 17:37:26 -0000
@@ -31,12 +31,14 @@
 #include <grp.h>
 
 void restrict_access_set_env(const char *user, uid_t uid, gid_t gid,
-			     const char *chroot_dir)
+		 	     const char *chroot_dir, int allow_zg)
 {
 	if (user != NULL && *user != '\0')
 		env_put(t_strconcat("RESTRICT_USER=", user, NULL));
 	if (chroot_dir != NULL && *chroot_dir != '\0')
 		env_put(t_strconcat("RESTRICT_CHROOT=", chroot_dir, NULL));
+	if (allow_zg == TRUE)
+		env_put(t_strdup("ALLOW_ZERO_GID=TRUE"));
 
 	env_put(t_strdup_printf("RESTRICT_SETUID=%s", dec2str(uid)));
 	env_put(t_strdup_printf("RESTRICT_SETGID=%s", dec2str(gid)));
@@ -45,6 +47,7 @@ void restrict_access_set_env(const char 
 void restrict_access_by_env(int disallow_root)
 {
 	const char *env;
+	int allow_zero_gid;
 	gid_t gid;
 	uid_t uid;
 
@@ -97,8 +100,14 @@ void restrict_access_by_env(int disallow
 			i_fatal("We couldn't drop root privileges");
 	}
 
-	if ((gid != 0 && uid != 0) || disallow_root) {
+	/* allow users with zero group id permission for BSD */
+	env = getenv("ALLOW_ZERO_GID");
+	allow_zero_gid = env == NULL ? FALSE : TRUE;
+
+	if (allow_zero_gid == FALSE &&
+		((gid != 0 && uid != 0) || disallow_root)) {
 		if (getgid() == 0 || getegid() == 0 || setgid(0) == 0)
 			i_fatal("We couldn't drop root group privileges");
 	}
+
 }
Index: src/lib/restrict-access.h
===================================================================
RCS file: /home/cvs/dovecot/src/lib/restrict-access.h,v
retrieving revision 1.4
diff -u -3 -p -r1.4 restrict-access.h
--- src/lib/restrict-access.h	4 Mar 2003 04:00:13 -0000	1.4
+++ src/lib/restrict-access.h	15 Apr 2003 17:37:26 -0000
@@ -4,7 +4,7 @@
 /* set environment variables so they can be read with
    restrict_access_by_env() */
 void restrict_access_set_env(const char *user, uid_t uid, gid_t gid,
-			     const char *chroot_dir);
+			     const char *chroot_dir, int allow_zg);
 
 /* chroot, setuid() and setgid() based on environment variables.
    If disallow_roots is TRUE, we'll kill ourself if we didn't have the
Index: src/master/auth-process.c
===================================================================
RCS file: /home/cvs/dovecot/src/master/auth-process.c,v
retrieving revision 1.41
diff -u -3 -p -r1.41 auth-process.c
--- src/master/auth-process.c	2 Apr 2003 02:09:41 -0000	1.41
+++ src/master/auth-process.c	15 Apr 2003 17:37:27 -0000
@@ -307,7 +307,7 @@ static pid_t create_auth_process(struct 
 
 	/* setup access environment */
 	restrict_access_set_env(group->set->user, pwd->pw_uid, pwd->pw_gid,
-				group->set->chroot);
+				group->set->chroot, set->allow_zero_gid);
 
 	/* set other environment */
 	env_put(t_strconcat("AUTH_PROCESS=", dec2str(getpid()), NULL));
Index: src/master/login-process.c
===================================================================
RCS file: /home/cvs/dovecot/src/master/login-process.c,v
retrieving revision 1.40
diff -u -3 -p -r1.40 login-process.c
--- src/master/login-process.c	15 Apr 2003 16:58:48 -0000	1.40
+++ src/master/login-process.c	15 Apr 2003 17:37:27 -0000
@@ -384,7 +384,8 @@ static void login_process_init_env(struc
 	   clean_child_process() since it clears environment */
 	restrict_access_set_env(group->set->user,
 				group->set->uid, set->login_gid,
-				set->login_chroot ? set->login_dir : NULL);
+				set->login_chroot ? set->login_dir : NULL,
+				FALSE);
 
 	env_put("DOVECOT_MASTER=1");
 
Index: src/master/mail-process.c
===================================================================
RCS file: /home/cvs/dovecot/src/master/mail-process.c,v
retrieving revision 1.13
diff -u -3 -p -r1.13 mail-process.c
--- src/master/mail-process.c	15 Apr 2003 16:58:48 -0000	1.13
+++ src/master/mail-process.c	15 Apr 2003 17:37:28 -0000
@@ -25,7 +25,7 @@ static int validate_uid_gid(uid_t uid, g
 		return FALSE;
 	}
 
-	if (uid != 0 && gid == 0) {
+	if (set->allow_zero_gid == FALSE && uid != 0 && gid == 0) {
 		i_error("mail process isn't allowed to be in group 0");
 		return FALSE;
 	}
@@ -38,8 +38,9 @@ static int validate_uid_gid(uid_t uid, g
 		return FALSE;
 	}
 
-	if (gid < (gid_t)set->first_valid_gid ||
-	    (set->last_valid_gid != 0 && gid > (gid_t)set->last_valid_gid)) {
+	if (set->allow_zero_gid == FALSE &&
+	    (gid < (gid_t)set->first_valid_gid ||
+	    (set->last_valid_gid != 0 && gid > (gid_t)set->last_valid_gid))) {
 		i_error("mail process isn't allowed to use "
 			"GID %s (UID is %s)", dec2str(gid), dec2str(uid));
 		return FALSE;
@@ -150,7 +151,8 @@ int create_mail_process(int socket, stru
 	   (paranoia about filling up environment without noticing) */
 	restrict_access_set_env(data + reply->system_user_idx,
 				reply->uid, reply->gid,
-				reply->chroot ? data + reply->home_idx : NULL);
+				reply->chroot ? data + reply->home_idx : NULL,
+				set->allow_zero_gid);
 
 	restrict_process_size(process_size, (unsigned int)-1);
 
Index: src/master/master-settings.c
===================================================================
RCS file: /home/cvs/dovecot/src/master/master-settings.c,v
retrieving revision 1.16
diff -u -3 -p -r1.16 master-settings.c
--- src/master/master-settings.c	2 Apr 2003 02:09:41 -0000	1.16
+++ src/master/master-settings.c	15 Apr 2003 17:37:28 -0000
@@ -46,6 +46,7 @@ static struct setting_def setting_defs[]
 	DEF(SET_INT, max_mail_processes),
 	DEF(SET_BOOL, verbose_proctitle),
 
+	DEF(SET_BOOL, allow_zero_gid),
 	DEF(SET_INT, first_valid_uid),
 	DEF(SET_INT, last_valid_uid),
 	DEF(SET_INT, first_valid_gid),
@@ -153,6 +154,7 @@ struct settings default_settings = {
 	MEMBER(max_mail_processes) 1024,
 	MEMBER(verbose_proctitle) FALSE,
 
+	MEMBER(allow_zero_gid) FALSE,
 	MEMBER(first_valid_uid) 500,
 	MEMBER(last_valid_uid) 0,
 	MEMBER(first_valid_gid) 1,
Index: src/master/master-settings.h
===================================================================
RCS file: /home/cvs/dovecot/src/master/master-settings.h,v
retrieving revision 1.10
diff -u -3 -p -r1.10 master-settings.h
--- src/master/master-settings.h	2 Apr 2003 02:09:41 -0000	1.10
+++ src/master/master-settings.h	15 Apr 2003 17:37:29 -0000
@@ -32,6 +32,7 @@ struct settings {
 	unsigned int max_mail_processes;
 	int verbose_proctitle;
 
+	int allow_zero_gid;
 	unsigned int first_valid_uid, last_valid_uid;
 	unsigned int first_valid_gid, last_valid_gid;
 
