[git commit] deluser: also remove user from /etc/group

Denys Vlasenko vda.linux at googlemail.com
Thu Mar 12 14:30:46 UTC 2015


commit: http://git.busybox.net/busybox/commit/?id=936c8809caea5705e26e5d7e06ea3895c28fffd8
branch: http://git.busybox.net/busybox/commit/?id=refs/heads/master

function                                             old     new   delta
update_passwd                                       1270    1470    +200
deluser_main                                         310     332     +22

Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 libbb/update_passwd.c |   38 ++++++++++++++++++++++++++++++++++++--
 loginutils/deluser.c  |   18 ++++++++++++------
 2 files changed, 48 insertions(+), 8 deletions(-)

diff --git a/libbb/update_passwd.c b/libbb/update_passwd.c
index a30af6f..dc26ebd 100644
--- a/libbb/update_passwd.c
+++ b/libbb/update_passwd.c
@@ -62,6 +62,8 @@ static void check_selinux_update_passwd(const char *username)
     only if CONFIG_PASSWD=y and applet_name[0] == 'p' like in passwd
     or if CONFIG_CHPASSWD=y and applet_name[0] == 'c' like in chpasswd
 
+ 8) delete a user from all groups: update_passwd(FILE, NULL, NULL, MEMBER)
+
  This function does not validate the arguments fed to it
  so the calling program should take care of that.
 
@@ -99,12 +101,13 @@ int FAST_FUNC update_passwd(const char *filename,
 	if (filename == NULL)
 		return ret;
 
-	check_selinux_update_passwd(name);
+	if (name)
+		check_selinux_update_passwd(name);
 
 	/* New passwd file, "/etc/passwd+" for now */
 	fnamesfx = xasprintf("%s+", filename);
 	sfx_char = &fnamesfx[strlen(fnamesfx)-1];
-	name_colon = xasprintf("%s:", name);
+	name_colon = xasprintf("%s:", name ? name : "");
 	user_len = strlen(name_colon);
 
 	if (shadow)
@@ -167,6 +170,37 @@ int FAST_FUNC update_passwd(const char *filename,
 		line = xmalloc_fgetline(old_fp);
 		if (!line) /* EOF/error */
 			break;
+
+		if (!name && member) {
+			/* Delete member from all groups */
+			/* line is "GROUP:PASSWD:[member1[,member2]...]" */
+			unsigned member_len = strlen(member);
+			char *list = strrchr(line, ':');
+			while (list) {
+				list++;
+ next_list_element:
+				if (strncmp(list, member, member_len) == 0) {
+					char c;
+					changed_lines++;
+					c = list[member_len];
+					if (c == '\0') {
+						if (list[-1] == ',')
+							list--;
+						*list = '\0';
+						break;
+					}
+					if (c == ',') {
+						overlapping_strcpy(list, list + member_len + 1);
+						goto next_list_element;
+					}
+					changed_lines--;
+				}
+				list = strchr(list, ',');
+			}
+			fprintf(new_fp, "%s\n", line);
+			goto next;
+		}
+
 		if (strncmp(name_colon, line, user_len) != 0) {
 			fprintf(new_fp, "%s\n", line);
 			goto next;
diff --git a/loginutils/deluser.c b/loginutils/deluser.c
index 01a9386..110cd63 100644
--- a/loginutils/deluser.c
+++ b/loginutils/deluser.c
@@ -114,16 +114,22 @@ int deluser_main(int argc, char **argv)
 			}
 		} while (ENABLE_FEATURE_SHADOWPASSWDS && pfile);
 
-		if (ENABLE_DELGROUP && do_deluser > 0) {
-			/* "deluser USER" also should try to delete
-			 * same-named group. IOW: do "delgroup USER"
-			 */
+		if (do_deluser > 0) {
+			/* Delete user from all groups */
+			if (update_passwd(bb_path_group_file, NULL, NULL, name) == -1)
+				return EXIT_FAILURE;
+
+			if (ENABLE_DELGROUP) {
+				/* "deluser USER" also should try to delete
+				 * same-named group. IOW: do "delgroup USER"
+				 */
 // On debian deluser is a perl script that calls userdel.
 // From man userdel:
 //  If USERGROUPS_ENAB is defined to yes in /etc/login.defs, userdel will
 //  delete the group with the same name as the user.
-			do_deluser = -1;
-			goto do_delgroup;
+				do_deluser = -1;
+				goto do_delgroup;
+			}
 		}
 		return EXIT_SUCCESS;
 	}


More information about the busybox-cvs mailing list