On Tue, Mar 3, 2015 at 2:13 PM, Laszlo Papp <lp...@kde.org> wrote:
> Denys, any feedback about this bugfix?

It is whitespace damaged.

>> +        char *cp, *line;
>> +        if (!name && member) {
>> +            struct group* g;
>> +            if ((g = getgrent())) {

Read the file using getgtent?
The rest of the function uses comletely different approach.

I am applying the attached patch.
diff -d -urpN busybox.5/libbb/update_passwd.c busybox.6/libbb/update_passwd.c
--- busybox.5/libbb/update_passwd.c	2015-02-16 14:42:53.000000000 +0100
+++ busybox.6/libbb/update_passwd.c	2015-03-12 15:23:46.359124022 +0100
@@ -62,6 +62,8 @@ static void check_selinux_update_passwd(
     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 *
 	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 *
 		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 -d -urpN busybox.5/loginutils/deluser.c busybox.6/loginutils/deluser.c
--- busybox.5/loginutils/deluser.c	2015-02-16 14:42:53.000000000 +0100
+++ busybox.6/loginutils/deluser.c	2015-03-12 15:28:36.136921651 +0100
@@ -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;
 	}
_______________________________________________
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to