Tomas Janousek d2fd927
diff -Naur cyrus-imapd-2.3.8.orig/configure.in cyrus-imapd-2.3.8/configure.in
Tomas Janousek d2fd927
--- cyrus-imapd-2.3.8.orig/configure.in	Thu Nov 30 18:11:16 2006
Tomas Janousek d2fd927
+++ cyrus-imapd-2.3.8/configure.in	Tue Jun 12 15:40:12 2007
Tomas Janousek d2fd927
@@ -119,7 +119,7 @@
Tomas Janousek d2fd927
 
Tomas Janousek d2fd927
 AC_CHECK_HEADERS(unistd.h sys/select.h sys/param.h stdarg.h)
Tomas Janousek d2fd927
 AC_REPLACE_FUNCS(memmove strcasecmp ftruncate strerror)
Tomas Janousek d2fd927
-AC_CHECK_FUNCS(strlcat strlcpy)
Tomas Janousek d2fd927
+AC_CHECK_FUNCS(strlcat strlcpy getgrouplist)
Tomas Janousek d2fd927
 AC_HEADER_DIRENT
Tomas Janousek d2fd927
 
Tomas Janousek d2fd927
 dnl do this before Berkeley DB/IPv6 detection
Tomas Janousek d2fd927
diff -Naur cyrus-imapd-2.3.8.orig/lib/auth_unix.c cyrus-imapd-2.3.8/lib/auth_unix.c
Tomas Janousek d2fd927
--- cyrus-imapd-2.3.8.orig/lib/auth_unix.c	Thu Nov 30 18:11:22 2006
Tomas Janousek d2fd927
+++ cyrus-imapd-2.3.8/lib/auth_unix.c	Tue Jun 12 15:42:22 2007
Tomas Janousek d2fd927
@@ -224,6 +224,12 @@
Tomas Janousek d2fd927
     struct passwd *pwd;
Tomas Janousek d2fd927
     struct group *grp;
Tomas Janousek d2fd927
     char **mem;
Tomas Janousek d2fd927
+#ifdef HAVE_GETGROUPLIST
Tomas Janousek d2fd927
+    gid_t gid;
Tomas Janousek d2fd927
+    int ret, ngroups;
Tomas Janousek d2fd927
+    gid_t *groupids = 0;
Tomas Janousek d2fd927
+    int i;
Tomas Janousek d2fd927
+#endif
Tomas Janousek d2fd927
 
Tomas Janousek d2fd927
     identifier = mycanonifyid(identifier, 0);
Tomas Janousek d2fd927
     if (!identifier) return 0;
Tomas Janousek d2fd927
@@ -239,7 +245,45 @@
Tomas Janousek d2fd927
 	return newstate;
Tomas Janousek d2fd927
 
Tomas Janousek d2fd927
     pwd = getpwnam(identifier);
Tomas Janousek d2fd927
-	
Tomas Janousek d2fd927
+#ifdef HAVE_GETGROUPLIST
Tomas Janousek d2fd927
+    gid = pwd ? pwd->pw_gid : (gid_t) -1;
Tomas Janousek d2fd927
+
Tomas Janousek d2fd927
+    // get number of groups user is member of into newstate->ngroups
Tomas Janousek d2fd927
+    getgrouplist(identifier, gid, NULL, &(newstate->ngroups));
Tomas Janousek d2fd927
+    // get the actual group ids.
Tomas Janousek d2fd927
+    do {
Tomas Janousek d2fd927
+	if (groupids)
Tomas Janousek d2fd927
+	    free(groupids);
Tomas Janousek d2fd927
+	groupids = (gid_t *)xmalloc(newstate->ngroups * sizeof(gid_t));
Tomas Janousek d2fd927
+
Tomas Janousek d2fd927
+	ngroups = newstate->ngroups;
Tomas Janousek d2fd927
+	ret = getgrouplist(identifier, gid, groupids, &(newstate->ngroups));
Tomas Janousek d2fd927
+	/*
Tomas Janousek d2fd927
+	 * This is tricky. We do this as long as getgrouplist tells us to
Tomas Janousek d2fd927
+	 * realloc _and_ the number of groups changes. It tells us to realloc
Tomas Janousek d2fd927
+	 * also in the case of failure...
Tomas Janousek d2fd927
+	 */
Tomas Janousek d2fd927
+    } while (ret != -1 && ngroups != newstate->ngroups);
Tomas Janousek d2fd927
+
Tomas Janousek d2fd927
+    if (ret == -1) {
Tomas Janousek d2fd927
+	newstate->ngroups = 0;
Tomas Janousek d2fd927
+	newstate->group = NULL;
Tomas Janousek d2fd927
+	goto err;
Tomas Janousek d2fd927
+    }
Tomas Janousek d2fd927
+
Tomas Janousek d2fd927
+    newstate->group = (char **)xmalloc(newstate->ngroups * sizeof(char *));
Tomas Janousek d2fd927
+    for (i = 0; i < newstate->ngroups; ++i ) {
Tomas Janousek d2fd927
+	struct group *group;
Tomas Janousek d2fd927
+
Tomas Janousek d2fd927
+	if (pwd || groupids[i] != gid) {
Tomas Janousek d2fd927
+	    if ((group = getgrgid(groupids[i])))
Tomas Janousek d2fd927
+		newstate->group[i] = xstrdup(group->gr_name);
Tomas Janousek d2fd927
+	}
Tomas Janousek d2fd927
+    }
Tomas Janousek d2fd927
+
Tomas Janousek d2fd927
+err:
Tomas Janousek d2fd927
+    free( groupids );
Tomas Janousek d2fd927
+#else
Tomas Janousek d2fd927
     setgrent();
Tomas Janousek d2fd927
     while ((grp = getgrent())) {
Tomas Janousek d2fd927
 	for (mem = grp->gr_mem; *mem; mem++) {
Tomas Janousek d2fd927
@@ -254,6 +298,8 @@
Tomas Janousek d2fd927
 	}
Tomas Janousek d2fd927
     }
Tomas Janousek d2fd927
     endgrent();
Tomas Janousek d2fd927
+#endif
Tomas Janousek d2fd927
+
Tomas Janousek d2fd927
     return newstate;
Tomas Janousek d2fd927
 }
Tomas Janousek d2fd927