Blame SOURCES/shadow-4.6-usermod-allow-all-group-types.patch

e157d6
From e481437ab9ebe9a8bf8fbaabe986d42b2f765991 Mon Sep 17 00:00:00 2001
e157d6
From: Iker Pedrosa <ipedrosa@redhat.com>
e157d6
Date: Tue, 3 Aug 2021 08:57:20 +0200
e157d6
Subject: [PATCH] usermod: allow all group types with -G option
e157d6
e157d6
The only way of removing a group from the supplementary list is to use
e157d6
-G option, and list all groups that the user is a member of except for
e157d6
the one that wants to be removed. The problem lies when there's a user
e157d6
that contains both local and remote groups, and the group to be removed
e157d6
is a local one. As we need to include the remote group with -G option
e157d6
the command will fail.
e157d6
e157d6
This reverts commit 140510de9de4771feb3af1d859c09604043a4c9b. This way,
e157d6
it would be possible to remove the remote groups from the supplementary
e157d6
list.
e157d6
e157d6
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1967641
e157d6
Resolves: https://github.com/shadow-maint/shadow/issues/338
e157d6
e157d6
Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
e157d6
---
e157d6
 src/usermod.c | 220 ++++++++++++++++++--------------------------------
e157d6
 1 file changed, 77 insertions(+), 143 deletions(-)
e157d6
e157d6
diff --git a/src/usermod.c b/src/usermod.c
e157d6
index 03bb9b9d..a0c03afa 100644
e157d6
--- a/src/usermod.c
e157d6
+++ b/src/usermod.c
e157d6
@@ -187,7 +187,6 @@ static bool sub_gid_locked = false;
e157d6
 static void date_to_str (/*@unique@*//*@out@*/char *buf, size_t maxsize,
e157d6
                          long int date);
e157d6
 static int get_groups (char *);
e157d6
-static struct group * get_local_group (char * grp_name);
e157d6
 static /*@noreturn@*/void usage (int status);
e157d6
 static void new_pwent (struct passwd *);
e157d6
 static void new_spent (struct spwd *);
e157d6
@@ -201,9 +200,7 @@ static void grp_update (void);
e157d6
 
e157d6
 static void process_flags (int, char **);
e157d6
 static void close_files (void);
e157d6
-static void close_group_files (void);
e157d6
 static void open_files (void);
e157d6
-static void open_group_files (void);
e157d6
 static void usr_update (void);
e157d6
 static void move_home (void);
e157d6
 static void update_lastlog (void);
e157d6
@@ -260,11 +257,6 @@ static int get_groups (char *list)
e157d6
 		return 0;
e157d6
 	}
e157d6
 
e157d6
-	/*
e157d6
-	 * Open the group files
e157d6
-	 */
e157d6
-	open_group_files ();
e157d6
-
e157d6
 	/*
e157d6
 	 * So long as there is some data to be converted, strip off each
e157d6
 	 * name and look it up. A mix of numerical and string values for
e157d6
@@ -284,7 +276,7 @@ static int get_groups (char *list)
e157d6
 		 * Names starting with digits are treated as numerical GID
e157d6
 		 * values, otherwise the string is looked up as is.
e157d6
 		 */
e157d6
-		grp = get_local_group (list);
e157d6
+		grp = prefix_getgr_nam_gid (list);
e157d6
 
e157d6
 		/*
e157d6
 		 * There must be a match, either by GID value or by
e157d6
@@ -334,8 +326,6 @@ static int get_groups (char *list)
e157d6
 		gr_free ((struct group *)grp);
e157d6
 	} while (NULL != list);
e157d6
 
e157d6
-	close_group_files ();
e157d6
-
e157d6
 	user_groups[ngroups] = (char *) 0;
e157d6
 
e157d6
 	/*
e157d6
@@ -348,44 +338,6 @@ static int get_groups (char *list)
e157d6
 	return 0;
e157d6
 }
e157d6
 
e157d6
-/*
e157d6
- * get_local_group - checks if a given group name exists locally
e157d6
- *
e157d6
- *	get_local_group() checks if a given group name exists locally.
e157d6
- *	If the name exists the group information is returned, otherwise NULL is
e157d6
- *	returned.
e157d6
- */
e157d6
-static struct group * get_local_group(char * grp_name)
e157d6
-{
e157d6
-	const struct group *grp;
e157d6
-	struct group *result_grp = NULL;
e157d6
-	long long int gid;
e157d6
-	char *endptr;
e157d6
-
e157d6
-	gid = strtoll (grp_name, &endptr, 10);
e157d6
-	if (   ('\0' != *grp_name)
e157d6
-		&& ('\0' == *endptr)
e157d6
-		&& (ERANGE != errno)
e157d6
-		&& (gid == (gid_t)gid)) {
e157d6
-		grp = gr_locate_gid ((gid_t) gid);
e157d6
-	}
e157d6
-	else {
e157d6
-		grp = gr_locate(grp_name);
e157d6
-	}
e157d6
-
e157d6
-	if (grp != NULL) {
e157d6
-		result_grp = __gr_dup (grp);
e157d6
-		if (NULL == result_grp) {
e157d6
-			fprintf (stderr,
e157d6
-					_("%s: Out of memory. Cannot find group '%s'.\n"),
e157d6
-					Prog, grp_name);
e157d6
-			fail_exit (E_GRP_UPDATE);
e157d6
-		}
e157d6
-	}
e157d6
-
e157d6
-	return result_grp;
e157d6
-}
e157d6
-
e157d6
 #ifdef ENABLE_SUBIDS
e157d6
 struct ulong_range
e157d6
 {
e157d6
@@ -1523,7 +1475,50 @@ static void close_files (void)
e157d6
 	}
e157d6
 
e157d6
 	if (Gflg || lflg) {
e157d6
-		close_group_files ();
e157d6
+		if (gr_close () == 0) {
e157d6
+			fprintf (stderr,
e157d6
+			         _("%s: failure while writing changes to %s\n"),
e157d6
+			         Prog, gr_dbname ());
e157d6
+			SYSLOG ((LOG_ERR,
e157d6
+			         "failure while writing changes to %s",
e157d6
+			         gr_dbname ()));
e157d6
+			fail_exit (E_GRP_UPDATE);
e157d6
+		}
e157d6
+#ifdef SHADOWGRP
e157d6
+		if (is_shadow_grp) {
e157d6
+			if (sgr_close () == 0) {
e157d6
+				fprintf (stderr,
e157d6
+				         _("%s: failure while writing changes to %s\n"),
e157d6
+				         Prog, sgr_dbname ());
e157d6
+				SYSLOG ((LOG_ERR,
e157d6
+				         "failure while writing changes to %s",
e157d6
+				         sgr_dbname ()));
e157d6
+				fail_exit (E_GRP_UPDATE);
e157d6
+			}
e157d6
+		}
e157d6
+#endif
e157d6
+#ifdef SHADOWGRP
e157d6
+		if (is_shadow_grp) {
e157d6
+			if (sgr_unlock () == 0) {
e157d6
+				fprintf (stderr,
e157d6
+				         _("%s: failed to unlock %s\n"),
e157d6
+				         Prog, sgr_dbname ());
e157d6
+				SYSLOG ((LOG_ERR,
e157d6
+				         "failed to unlock %s",
e157d6
+				         sgr_dbname ()));
e157d6
+				/* continue */
e157d6
+			}
e157d6
+		}
e157d6
+#endif
e157d6
+		if (gr_unlock () == 0) {
e157d6
+			fprintf (stderr,
e157d6
+			         _("%s: failed to unlock %s\n"),
e157d6
+			         Prog, gr_dbname ());
e157d6
+			SYSLOG ((LOG_ERR,
e157d6
+			         "failed to unlock %s",
e157d6
+			         gr_dbname ()));
e157d6
+			/* continue */
e157d6
+		}
e157d6
 	}
e157d6
 
e157d6
 	if (is_shadow_pwd) {
e157d6
@@ -1592,60 +1587,6 @@ static void close_files (void)
e157d6
 #endif
e157d6
 }
e157d6
 
e157d6
-/*
e157d6
- * close_group_files - close all of the files that were opened
e157d6
- *
e157d6
- *	close_group_files() closes all of the files that were opened related
e157d6
- *  with groups. This causes any modified entries to be written out.
e157d6
- */
e157d6
-static void close_group_files (void)
e157d6
-{
e157d6
-	if (gr_close () == 0) {
e157d6
-		fprintf (stderr,
e157d6
-					_("%s: failure while writing changes to %s\n"),
e157d6
-					Prog, gr_dbname ());
e157d6
-		SYSLOG ((LOG_ERR,
e157d6
-					"failure while writing changes to %s",
e157d6
-					gr_dbname ()));
e157d6
-		fail_exit (E_GRP_UPDATE);
e157d6
-	}
e157d6
-#ifdef SHADOWGRP
e157d6
-	if (is_shadow_grp) {
e157d6
-		if (sgr_close () == 0) {
e157d6
-			fprintf (stderr,
e157d6
-						_("%s: failure while writing changes to %s\n"),
e157d6
-						Prog, sgr_dbname ());
e157d6
-			SYSLOG ((LOG_ERR,
e157d6
-						"failure while writing changes to %s",
e157d6
-						sgr_dbname ()));
e157d6
-			fail_exit (E_GRP_UPDATE);
e157d6
-		}
e157d6
-	}
e157d6
-#endif
e157d6
-#ifdef SHADOWGRP
e157d6
-	if (is_shadow_grp) {
e157d6
-		if (sgr_unlock () == 0) {
e157d6
-			fprintf (stderr,
e157d6
-						_("%s: failed to unlock %s\n"),
e157d6
-						Prog, sgr_dbname ());
e157d6
-			SYSLOG ((LOG_ERR,
e157d6
-						"failed to unlock %s",
e157d6
-						sgr_dbname ()));
e157d6
-			/* continue */
e157d6
-		}
e157d6
-	}
e157d6
-#endif
e157d6
-	if (gr_unlock () == 0) {
e157d6
-		fprintf (stderr,
e157d6
-					_("%s: failed to unlock %s\n"),
e157d6
-					Prog, gr_dbname ());
e157d6
-		SYSLOG ((LOG_ERR,
e157d6
-					"failed to unlock %s",
e157d6
-					gr_dbname ()));
e157d6
-		/* continue */
e157d6
-	}
e157d6
-}
e157d6
-
e157d6
 /*
e157d6
  * open_files - lock and open the password files
e157d6
  *
e157d6
@@ -1681,7 +1622,38 @@ static void open_files (void)
e157d6
 	}
e157d6
 
e157d6
 	if (Gflg || lflg) {
e157d6
-		open_group_files ();
e157d6
+		/*
e157d6
+		 * Lock and open the group file. This will load all of the
e157d6
+		 * group entries.
e157d6
+		 */
e157d6
+		if (gr_lock () == 0) {
e157d6
+			fprintf (stderr,
e157d6
+			         _("%s: cannot lock %s; try again later.\n"),
e157d6
+			         Prog, gr_dbname ());
e157d6
+			fail_exit (E_GRP_UPDATE);
e157d6
+		}
e157d6
+		gr_locked = true;
e157d6
+		if (gr_open (O_CREAT | O_RDWR) == 0) {
e157d6
+			fprintf (stderr,
e157d6
+			         _("%s: cannot open %s\n"),
e157d6
+			         Prog, gr_dbname ());
e157d6
+			fail_exit (E_GRP_UPDATE);
e157d6
+		}
e157d6
+#ifdef SHADOWGRP
e157d6
+		if (is_shadow_grp && (sgr_lock () == 0)) {
e157d6
+			fprintf (stderr,
e157d6
+			         _("%s: cannot lock %s; try again later.\n"),
e157d6
+			         Prog, sgr_dbname ());
e157d6
+			fail_exit (E_GRP_UPDATE);
e157d6
+		}
e157d6
+		sgr_locked = true;
e157d6
+		if (is_shadow_grp && (sgr_open (O_CREAT | O_RDWR) == 0)) {
e157d6
+			fprintf (stderr,
e157d6
+			         _("%s: cannot open %s\n"),
e157d6
+			         Prog, sgr_dbname ());
e157d6
+			fail_exit (E_GRP_UPDATE);
e157d6
+		}
e157d6
+#endif
e157d6
 	}
e157d6
 #ifdef ENABLE_SUBIDS
e157d6
 	if (vflg || Vflg) {
e157d6
@@ -1717,44 +1689,6 @@ static void open_files (void)
e157d6
 #endif				/* ENABLE_SUBIDS */
e157d6
 }
e157d6
 
e157d6
-/*
e157d6
- * open_group_files - lock and open the group files
e157d6
- *
e157d6
- *	open_group_files() loads all of the group entries.
e157d6
- */
e157d6
-static void open_group_files (void)
e157d6
-{
e157d6
-	if (gr_lock () == 0) {
e157d6
-		fprintf (stderr,
e157d6
-					_("%s: cannot lock %s; try again later.\n"),
e157d6
-					Prog, gr_dbname ());
e157d6
-		fail_exit (E_GRP_UPDATE);
e157d6
-	}
e157d6
-	gr_locked = true;
e157d6
-	if (gr_open (O_CREAT | O_RDWR) == 0) {
e157d6
-		fprintf (stderr,
e157d6
-					_("%s: cannot open %s\n"),
e157d6
-					Prog, gr_dbname ());
e157d6
-		fail_exit (E_GRP_UPDATE);
e157d6
-	}
e157d6
-
e157d6
-#ifdef SHADOWGRP
e157d6
-	if (is_shadow_grp && (sgr_lock () == 0)) {
e157d6
-		fprintf (stderr,
e157d6
-					_("%s: cannot lock %s; try again later.\n"),
e157d6
-					Prog, sgr_dbname ());
e157d6
-		fail_exit (E_GRP_UPDATE);
e157d6
-	}
e157d6
-	sgr_locked = true;
e157d6
-	if (is_shadow_grp && (sgr_open (O_CREAT | O_RDWR) == 0)) {
e157d6
-		fprintf (stderr,
e157d6
-					_("%s: cannot open %s\n"),
e157d6
-					Prog, sgr_dbname ());
e157d6
-		fail_exit (E_GRP_UPDATE);
e157d6
-	}
e157d6
-#endif
e157d6
-}
e157d6
-
e157d6
 /*
e157d6
  * usr_update - create the user entries
e157d6
  *
e157d6
-- 
e157d6
2.31.1
e157d6