deluser: 2nd attempt at deluser/delgroup size reduction and improvements

Signed-off-by: Tito Ragusa <farmatito@tiscali.it>
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
This commit is contained in:
Tito Ragusa 2010-11-06 22:14:55 +01:00 committed by Denys Vlasenko
parent 0ebafcc5b1
commit 1586c7a92c

View File

@ -14,41 +14,82 @@
int deluser_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int deluser_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int deluser_main(int argc, char **argv) int deluser_main(int argc, char **argv)
{ {
if (argc != 2 /* User or group name */
&& (!ENABLE_FEATURE_DEL_USER_FROM_GROUP char *name;
|| applet_name[3] != 'g' /* Username (non-NULL only in "delgroup USER GROUP" case) */
|| argc != 3) char *member;
) { /* Name of passwd or group file */
bb_show_usage(); const char *pfile;
} /* Name of shadow or gshadow file */
const char *sfile;
/* Are we deluser or delgroup? */
bool do_deluser = (ENABLE_DELUSER && (!ENABLE_DELGROUP || applet_name[3] == 'u'));
if (geteuid()) if (geteuid() != 0)
bb_error_msg_and_die(bb_msg_perm_denied_are_you_root); bb_error_msg_and_die(bb_msg_perm_denied_are_you_root);
if (ENABLE_DELUSER && applet_name[3] == 'u') { name = argv[1];
/* deluser USER */ member = NULL;
if (update_passwd(bb_path_passwd_file, argv[1], NULL, NULL) < 0)
return EXIT_FAILURE; switch (argc) {
case 3:
if (!ENABLE_FEATURE_DEL_USER_FROM_GROUP || do_deluser)
break;
/* It's "delgroup USER GROUP" */
member = name;
name = argv[2];
/* Fallthrough */
case 2:
if (do_deluser) {
/* "deluser USER" */
xgetpwnam(name); /* bail out if USER is wrong */
pfile = bb_path_passwd_file;
if (ENABLE_FEATURE_SHADOWPASSWDS) if (ENABLE_FEATURE_SHADOWPASSWDS)
if (update_passwd(bb_path_shadow_file, argv[1], NULL, NULL) < 0) sfile = bb_path_shadow_file;
return EXIT_FAILURE;
} else if (ENABLE_DELGROUP) {
/* delgroup ... */
if (!ENABLE_FEATURE_DEL_USER_FROM_GROUP || argc != 3) {
/* delgroup GROUP */
if (update_passwd(bb_path_group_file, argv[1], NULL, NULL) < 0)
return EXIT_FAILURE;
if (ENABLE_FEATURE_SHADOWPASSWDS)
if (update_passwd(bb_path_gshadow_file, argv[1], NULL, NULL) < 0)
return EXIT_FAILURE;
} else { } else {
/* delgroup USER GROUP */ do_delgroup:
if (update_passwd(bb_path_group_file, argv[2], NULL, argv[1]) < 0) /* "delgroup GROUP" or "delgroup USER GROUP" */
return EXIT_FAILURE; xgetgrnam(name); /* bail out if GROUP is wrong */
if (ENABLE_FEATURE_SHADOWPASSWDS) if (!member) {
if (update_passwd(bb_path_gshadow_file, argv[2], NULL, argv[1]) < 0) /* "delgroup GROUP".
return EXIT_FAILURE; * If user with tha same name exists,
* bail out.
*/
//BUG: check should be done by GID, not by matching name!
//1. find GROUP's GID
//2. check that /etc/passwd doesn't have lines of the form
// user:pwd:uid:GID:...
//3. bail out if at least one such line exists
if (getpwnam(name) != NULL)
bb_error_msg_and_die("'%s' still has '%s' as their primary group!", name, name);
} }
pfile = bb_path_group_file;
if (ENABLE_FEATURE_SHADOWPASSWDS)
sfile = bb_path_gshadow_file;
}
/* Modify pfile, then sfile */
do {
if (update_passwd(pfile, name, NULL, member) == -1)
return EXIT_FAILURE;
if (ENABLE_FEATURE_SHADOWPASSWDS) {
pfile = sfile;
sfile = NULL;
}
} while (ENABLE_FEATURE_SHADOWPASSWDS && pfile);
if (ENABLE_DELGROUP && do_deluser) {
/* "deluser USER" also should try to delete
* same-named group. IOW: do "delgroup USER"
*/
//TODO: check how it actually works in upstream.
//I suspect it is only done if group has no more members.
do_deluser = 0;
goto do_delgroup;
} }
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
/* Reached only if number of command line args is wrong */
bb_show_usage();
}