--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/proftpd/patches/mod_auth_unix_getgrp.patch Fri Jul 13 15:21:02 2012 -0700
@@ -0,0 +1,66 @@
+--- old/modules/mod_auth_unix.c Fri May 25 08:31:35 2012
++++ new/modules/mod_auth_unix.c Fri May 25 08:31:35 2012
+@@ -896,6 +896,13 @@
+
+ return gr ? mod_create_data(cmd, (void *) &gr->gr_gid) : PR_DECLINED(cmd);
+ }
++#ifdef HAVE__GETGRPSBYMEMBER
++ extern int _getgroupsbymember
++ (
++ const char* username, gid_t gid_array[],
++ int maxgids, int numgids
++ );
++#endif /* HAVE__GETGRPSBYMEMBER */
+
+ /* cmd->argv[0] = name
+ * cmd->argv[1] = (array_header **) group_ids
+@@ -1065,7 +1072,40 @@
+ }
+
+ free(ptr);
+-#else
++#else /* !HAVE_GETGRSET */
++#ifdef HAVE__GETGRPSBYMEMBER
++ gid_t group_ids[NGROUPS_MAX];
++ int ngroups = NGROUPS_MAX;
++ register unsigned int i;
++
++ pr_trace_msg("auth", 4,
++ "using _getgroupsbymember() to look up group membership");
++
++ memset(group_ids, 0, sizeof(group_ids));
++
++ group_ids[0]=pw->pw_gid;
++ ngroups=
++ _getgroupsbymember(pw->pw_name, group_ids, NGROUPS_MAX, 1);
++
++ if (ngroups < 0) {
++ pr_log_pri(PR_LOG_ERR,
++ "_getgroupsbymember error: %s", strerror(errno));
++ return PR_DECLINED(cmd);
++ }
++
++ for (i = 0; i < ngroups; i++) {
++ gr = my_getgrgid(group_ids[i]);
++ if (gr) {
++ if (gids && pw->pw_gid != gr->gr_gid)
++ *((gid_t *) push_array(gids)) = gr->gr_gid;
++
++ if (groups && pw->pw_gid != gr->gr_gid) {
++ *((char **) push_array(groups)) = pstrdup(session.pool,
++ gr->gr_name);
++ }
++ }
++ }
++#else /* !HAVE__GETGRPSBYMEMBER */
+ char **gr_member = NULL;
+
+ /* This is where things get slow, expensive, and ugly. Loop through
+@@ -1091,6 +1131,7 @@
+ }
+ }
+ }
++#endif /* !HAVE__GETGROUPSBYMEMBER */
+ #endif /* !HAVE_GETGRSET */
+ }
+