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 <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko 2015-03-12 15:30:46 +01:00
parent 748fb60f27
commit 936c8809ca
2 changed files with 48 additions and 8 deletions

View File

@ -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 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 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 This function does not validate the arguments fed to it
so the calling program should take care of that. so the calling program should take care of that.
@ -99,12 +101,13 @@ int FAST_FUNC update_passwd(const char *filename,
if (filename == NULL) if (filename == NULL)
return ret; return ret;
check_selinux_update_passwd(name); if (name)
check_selinux_update_passwd(name);
/* New passwd file, "/etc/passwd+" for now */ /* New passwd file, "/etc/passwd+" for now */
fnamesfx = xasprintf("%s+", filename); fnamesfx = xasprintf("%s+", filename);
sfx_char = &fnamesfx[strlen(fnamesfx)-1]; sfx_char = &fnamesfx[strlen(fnamesfx)-1];
name_colon = xasprintf("%s:", name); name_colon = xasprintf("%s:", name ? name : "");
user_len = strlen(name_colon); user_len = strlen(name_colon);
if (shadow) if (shadow)
@ -167,6 +170,37 @@ int FAST_FUNC update_passwd(const char *filename,
line = xmalloc_fgetline(old_fp); line = xmalloc_fgetline(old_fp);
if (!line) /* EOF/error */ if (!line) /* EOF/error */
break; 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) { if (strncmp(name_colon, line, user_len) != 0) {
fprintf(new_fp, "%s\n", line); fprintf(new_fp, "%s\n", line);
goto next; goto next;

View File

@ -114,16 +114,22 @@ int deluser_main(int argc, char **argv)
} }
} while (ENABLE_FEATURE_SHADOWPASSWDS && pfile); } while (ENABLE_FEATURE_SHADOWPASSWDS && pfile);
if (ENABLE_DELGROUP && do_deluser > 0) { if (do_deluser > 0) {
/* "deluser USER" also should try to delete /* Delete user from all groups */
* same-named group. IOW: do "delgroup USER" 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. // On debian deluser is a perl script that calls userdel.
// From man userdel: // From man userdel:
// If USERGROUPS_ENAB is defined to yes in /etc/login.defs, userdel will // If USERGROUPS_ENAB is defined to yes in /etc/login.defs, userdel will
// delete the group with the same name as the user. // delete the group with the same name as the user.
do_deluser = -1; do_deluser = -1;
goto do_delgroup; goto do_delgroup;
}
} }
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }