Blame SOURCES/shadow-4.1.5.1-ingroup.patch

827aa9
diff -up shadow-4.1.5.1/src/newgrp.c.ingroup shadow-4.1.5.1/src/newgrp.c
57b0e3
--- shadow-4.1.5.1/src/newgrp.c.ingroup	2018-04-24 16:55:24.546677529 +0200
57b0e3
+++ shadow-4.1.5.1/src/newgrp.c	2018-04-24 16:58:17.113445562 +0200
827aa9
@@ -83,15 +83,29 @@ static void usage (void)
827aa9
 	}
827aa9
 }
827aa9
 
827aa9
+static bool ingroup(const char *name, struct group *gr)
827aa9
+{
827aa9
+	char **look;
827aa9
+	bool notfound = true;
827aa9
+
827aa9
+	look = gr->gr_mem;
827aa9
+	while (*look && notfound)
827aa9
+		notfound = strcmp (*look++, name);
827aa9
+
827aa9
+	return !notfound;
827aa9
+}
827aa9
+
827aa9
 /*
827aa9
- * find_matching_group - search all groups of a given group id for
827aa9
+ * find_matching_group - search all groups of a gr's group id for
827aa9
  *                       membership of a given username
827aa9
+ *                       but check gr itself first
827aa9
  */
827aa9
-static /*@null@*/struct group *find_matching_group (const char *name, gid_t gid)
827aa9
+static /*@null@*/struct group *find_matching_group (const char *name, struct group *gr)
827aa9
 {
827aa9
-	struct group *gr;
827aa9
-	char **look;
827aa9
-	bool notfound = true;
827aa9
+	gid_t gid = gr->gr_gid;
827aa9
+
827aa9
+	if (ingroup(name, gr))
827aa9
+		return gr;
827aa9
 
827aa9
 	setgrent ();
827aa9
 	while ((gr = getgrent ()) != NULL) {
827aa9
@@ -103,14 +117,8 @@ static /*@null@*/struct group *find_matc
827aa9
 		 * A group with matching GID was found.
827aa9
 		 * Test for membership of 'name'.
827aa9
 		 */
827aa9
-		look = gr->gr_mem;
827aa9
-		while ((NULL != *look) && notfound) {
827aa9
-			notfound = (strcmp (*look, name) != 0);
827aa9
-			look++;
827aa9
-		}
827aa9
-		if (!notfound) {
827aa9
+		if (ingroup(name, gr))
827aa9
 			break;
827aa9
-		}
827aa9
 	}
827aa9
 	endgrent ();
827aa9
 	return gr;
57b0e3
@@ -373,6 +381,7 @@ int main (int argc, char **argv)
57b0e3
 {
57b0e3
 	bool initflag = false;
57b0e3
 	int i;
57b0e3
+	bool is_member = false;
57b0e3
 	bool cflag = false;
57b0e3
 	int err = 0;
57b0e3
 	gid_t gid;
57b0e3
@@ -611,22 +620,36 @@ int main (int argc, char **argv)
57b0e3
 		goto failure;
57b0e3
 	}
57b0e3
 
57b0e3
+#ifdef HAVE_SETGROUPS
57b0e3
+	/* when using pam_group, she will not be listed in the groups
57b0e3
+	 * database. However getgroups() will return the group. So
57b0e3
+	 * if she is listed there already it is ok to grant membership.
57b0e3
+	 */
57b0e3
+	for (i = 0; i < ngroups; i++) {
57b0e3
+		if (grp->gr_gid == grouplist[i]) {
57b0e3
+			is_member = true;
57b0e3
+			break;
57b0e3
+		}
57b0e3
+	}
57b0e3
+#endif                          /* HAVE_SETGROUPS */
57b0e3
 	/*
57b0e3
 	 * For splitted groups (due to limitations of NIS), check all 
827aa9
 	 * groups of the same GID like the requested group for
827aa9
 	 * membership of the current user.
827aa9
 	 */
827aa9
-	grp = find_matching_group (name, grp->gr_gid);
57b0e3
-	if (NULL == grp) {
57b0e3
-		/*
57b0e3
-		 * No matching group found. As we already know that
57b0e3
-		 * the group exists, this happens only in the case
57b0e3
-		 * of a requested group where the user is not member.
57b0e3
-		 *
57b0e3
-		 * Re-read the group entry for further processing.
57b0e3
-		 */
57b0e3
-		grp = xgetgrnam (group);
57b0e3
-		assert (NULL != grp);
57b0e3
+	if (!is_member) {
57b0e3
+		grp = find_matching_group (name, grp);
57b0e3
+		if (NULL == grp) {
57b0e3
+			/*
57b0e3
+			 * No matching group found. As we already know that
57b0e3
+			 * the group exists, this happens only in the case
57b0e3
+			 * of a requested group where the user is not member.
57b0e3
+			 *
57b0e3
+			 * Re-read the group entry for further processing.
57b0e3
+			 */
57b0e3
+			grp = xgetgrnam (group);
57b0e3
+			assert (NULL != grp);
57b0e3
+		}
57b0e3
 	}
57b0e3
 #ifdef SHADOWGRP
57b0e3
 	sgrp = getsgnam (group);
57b0e3
@@ -639,7 +662,9 @@ int main (int argc, char **argv)
57b0e3
 	/*
57b0e3
 	 * Check if the user is allowed to access this group.
57b0e3
 	 */
57b0e3
-	check_perms (grp, pwd, group);
57b0e3
+	if (!is_member) {
57b0e3
+		check_perms (grp, pwd, group);
57b0e3
+	}
57b0e3
 
57b0e3
 	/*
57b0e3
 	 * all successful validations pass through this point. The group id