diff -up shadow-4.1.5.1/src/newgrp.c.grouplist shadow-4.1.5.1/src/newgrp.c --- shadow-4.1.5.1/src/newgrp.c.grouplist 2016-06-28 10:23:46.686334213 +0200 +++ shadow-4.1.5.1/src/newgrp.c 2017-08-14 10:26:58.300757328 +0200 @@ -382,6 +382,7 @@ int main (int argc, char **argv) { bool initflag = false; int i; + bool is_member = false; bool cflag = false; int err = 0; gid_t gid; @@ -631,22 +632,36 @@ int main (int argc, char **argv) goto failure; } +#ifdef HAVE_SETGROUPS + /* when using pam_group, she will not be listed in the groups + * database. However getgroups() will return the group. So + * if she is listed there already it is ok to grant membership. + */ + for (i = 0; i < ngroups; i++) { + if (grp->gr_gid == grouplist[i]) { + is_member = true; + break; + } + } +#endif /* HAVE_SETGROUPS */ /* * For splitted groups (due to limitations of NIS), check all * groups of the same GID like the requested group for * membership of the current user. */ - grp = find_matching_group (name, grp); - if (NULL == grp) { - /* - * No matching group found. As we already know that - * the group exists, this happens only in the case - * of a requested group where the user is not member. - * - * Re-read the group entry for further processing. - */ - grp = xgetgrnam (group); - assert (NULL != grp); + if (!is_member) { + grp = find_matching_group (name, grp); + if (NULL == grp) { + /* + * No matching group found. As we already know that + * the group exists, this happens only in the case + * of a requested group where the user is not member. + * + * Re-read the group entry for further processing. + */ + grp = xgetgrnam (group); + assert (NULL != grp); + } } #ifdef SHADOWGRP sgrp = getsgnam (group); @@ -659,7 +674,9 @@ int main (int argc, char **argv) /* * Check if the user is allowed to access this group. */ - check_perms (grp, pwd, group); + if (!is_member) { + check_perms (grp, pwd, group); + } /* * all successful validations pass through this point. The group id