--- src/lib-storage/mailbox-list.c.orig	2010-09-14 11:03:18.000000000 -0400
+++ src/lib-storage/mailbox-list.c	2010-10-14 15:20:15.000000000 -0400
@@ -25,6 +25,9 @@
 #include <unistd.h>
 #include <dirent.h>
 #include <sys/stat.h>
+#include <stdlib.h>
+#include <grp.h>
+#include <pwd.h>
 
 /* 20 * (200+1) < 4096 which is the standard PATH_MAX. Having these settings
    prevents malicious user from creating eg. "a/a/a/.../a" mailbox name and
@@ -450,7 +453,7 @@
 		}
 
 		if (S_ISDIR(st.st_mode) && (st.st_mode & S_ISGID) != 0) {
-			/* directory's GID is used automatically for new
+			/* directory is sgid, so GID is used automatically for new
 			   files */
 			*gid_r = (gid_t)-1;
 		} else if ((st.st_mode & 0070) >> 3 == (st.st_mode & 0007)) {
@@ -460,8 +463,39 @@
 		} else if (getegid() == st.st_gid) {
 			/* using our own gid, no need to change it */
 			*gid_r = (gid_t)-1;
-		} else {
-			*gid_r = st.st_gid;
+		}
+
+		else {
+                	/* test for unusable inheritance. logic sets fgid_me to st.gid
+			   for unlikely case of lookup failure and we just fall through */
+			int j, ngroups = 999;
+			gid_t *groups;
+			gid_t fgid_me = st.st_gid;
+
+			groups = malloc(ngroups * sizeof (gid_t));
+			if (groups != NULL) {
+				uid_t egid = getegid();
+                        	struct passwd *pw = getpwuid(geteuid());
+				if (pw != NULL) {
+					/* get pw entry for test using my current effective uid */
+					if (getgrouplist(pw->pw_name, egid, groups, &ngroups) != -1) {
+						/* get list of group IDs my euid belongs to, ngroups
+						   will be set to the number of groups I belong to */
+						fgid_me = egid;
+						for (j = 0; j < ngroups; j++) {
+							/* enumerate list, test to see if i belong
+							   to gid of parent directory */
+							if (st.st_gid == groups[j]) {
+								/* if so, switch to parent gid */
+								fgid_me = st.st_gid;
+							}
+						}
+					}
+				}
+				free(groups);
+			}
+
+			*gid_r = fgid_me;
 		}
 	}
 