[Pkg-shadow-devel] Bug#295416: Could we propose a patch for the "userdel should not remove the group which is primary for someone else" bug ?

Nicolas François nicolas.francois at centraliens.net
Sun Oct 2 00:35:47 UTC 2005


Hello Tomasz,

Can you have a look at these patches.

The second patch (userdel_2.patch) gives a special return value in this case.

Kind Regards,
-- 
Nekral
-------------- next part --------------
Index: userdel.c
===================================================================
RCS file: /cvsroot/shadow/src/userdel.c,v
retrieving revision 1.50
diff -u -r1.50 userdel.c
--- userdel.c	7 Sep 2005 15:00:45 -0000	1.50
+++ userdel.c	2 Oct 2005 00:16:10 -0000
@@ -116,6 +116,7 @@
 {
 	const struct group *grp;
 	struct group *ngrp;
+	struct passwd *pwd;
 
 #ifdef	SHADOWGRP
 	int deleted_user_group = 0;
@@ -170,18 +171,43 @@
 	if (grp && getdef_bool ("USERGROUPS_ENAB")
 	    && (grp->gr_mem[0] == NULL)) {
 
-		gr_remove (grp->gr_name);
+		/*
+		 * Scan the passwd file to check if this group is still
+		 * used as a primary group.
+		 */
+		setpwent ();
+		while ((pwd = getpwent ())) {
+			if (strcmp (pwd->pw_name, user_name) == 0)
+				continue;
+			if (pwd->pw_gid == grp->gr_gid) {
+				fprintf (stderr,
+					 _("%s: Cannot remove group %s which is a primary group for another user.\n"),
+					 Prog, grp->gr_name);
+				break;
+			}
+		}
+		endpwent();
+
+		if (pwd == NULL) {
+			/*
+			 * We can remove this group, it is not the primary
+			 * group of any remaining user.
+			 */
+			gr_remove (grp->gr_name);
 
 #ifdef SHADOWGRP
-		deleted_user_group = 1;
+			deleted_user_group = 1;
 #endif
 
 #ifdef WITH_AUDIT
-		audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "deleting group",
-			      user_name, user_id, 0);
+			audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
+			              "deleting group",
+			              user_name, user_id, 0);
 #endif
-		SYSLOG ((LOG_INFO, "removed group `%s' owned by `%s'\n",
-			 grp->gr_name, user_name));
+			SYSLOG ((LOG_INFO,
+			        "removed group `%s' owned by `%s'\n",
+			        grp->gr_name, user_name));
+		}
 	}
 #ifdef	SHADOWGRP
 	if (!is_shadow_grp)
@@ -730,6 +756,7 @@
 				break;
 			}
 		}
+		endpwent();
 	}
 #endif
 
-------------- next part --------------
--- src/userdel.c.orig	2005-10-02 02:17:56.000000000 +0200
+++ src/userdel.c	2005-10-02 02:25:45.000000000 +0200
@@ -63,7 +63,10 @@
 #define E_NOTFOUND	6	/* specified user doesn't exist */
 #define E_USER_BUSY	8	/* user currently logged in */
 #define E_GRP_UPDATE	10	/* can't update group file */
-#define E_HOMEDIR	12	/* can't remove home directory */
+#define E_HOMEDIR	16	/* can't remove home directory */
+#define E_GRP_USED	32	/* group used by another user, not removed */
+/* The return value in case of a recoverable error */
+static int return_value = E_SUCCESS;
 static char *user_name;
 static uid_t user_id;
 static char *user_home;
@@ -207,6 +210,8 @@
 			SYSLOG ((LOG_INFO,
 			        "removed group `%s' owned by `%s'\n",
 			        grp->gr_name, user_name));
+		} else {
+			return_value |= E_GRP_USED;
 		}
 	}
 #ifdef	SHADOWGRP
@@ -601,7 +606,6 @@
 {
 	struct passwd *pwd;
 	int arg;
-	int errors = 0;
 
 #ifdef USE_PAM
 	pam_handle_t *pamh = NULL;
@@ -730,7 +734,7 @@
 			 _("%s: %s not owned by %s, not removing\n"),
 			 Prog, user_home, user_name);
 		rflg = 0;
-		errors++;
+		return_value |= E_HOMEDIR;
 	}
 #ifdef EXTRA_CHECK_HOME_DIR
 	/* This may be slow, the above should be good enough. */
@@ -752,7 +756,7 @@
 					 ("%s: not removing directory %s (would remove home of user %s)\n"),
 					 Prog, user_home, pwd->pw_name);
 				rflg = 0;
-				errors++;
+				return_value |= E_HOMEDIR;
 				break;
 			}
 		}
@@ -771,7 +775,7 @@
 				      "deleting home directory", user_name,
 				      user_id, 1);
 #endif
-			errors++;
+			return_value |= E_HOMEDIR;
 		}
 #ifdef WITH_AUDIT
 		audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
@@ -801,10 +805,10 @@
 		pam_end (pamh, PAM_SUCCESS);
 #endif				/* USE_PAM */
 #ifdef WITH_AUDIT
-	if (errors)
+	if (return_value & E_HOMEDIR)
 		audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
 			      "deleting home directory", user_name, -1, 0);
 #endif
-	exit (errors ? E_HOMEDIR : E_SUCCESS);
+	exit (return_value);
 	/* NOT REACHED */
 }


More information about the Pkg-shadow-devel mailing list