From 936c8809caea5705e26e5d7e06ea3895c28fffd8 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 12 Mar 2015 15:30:46 +0100 Subject: [PATCH] deluser: also remove user from /etc/group function old new delta update_passwd 1270 1470 +200 deluser_main 310 332 +22 Signed-off-by: Denys Vlasenko --- 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 a30af6f72..dc26ebd1d 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 01a9386bc..110cd6310 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; } -- 2.25.1