Changeset 2725 in MondoRescue for branches/2.2.9/mindi-busybox/loginutils/deluser.c
- Timestamp:
- Feb 25, 2011, 9:26:54 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/2.2.9/mindi-busybox/loginutils/deluser.c
r1765 r2725 7 7 * Copyright (C) 2007 by Tito Ragusa <farmatito@tiscali.it> 8 8 * 9 * Licensed under GPL version 2, see file LICENSE in this tarball for details.9 * Licensed under GPLv2, see file LICENSE in this source tree. 10 10 * 11 11 */ 12 13 12 #include "libbb.h" 14 13 15 /* Status */ 16 #define STATUS_OK 0 17 #define NAME_NOT_FOUND 1 18 #define MEMBER_NOT_FOUND 2 14 int deluser_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 15 int deluser_main(int argc, char **argv) 16 { 17 /* User or group name */ 18 char *name; 19 /* Username (non-NULL only in "delgroup USER GROUP" case) */ 20 char *member; 21 /* Name of passwd or group file */ 22 const char *pfile; 23 /* Name of shadow or gshadow file */ 24 const char *sfile; 25 /* Are we deluser or delgroup? */ 26 int do_deluser = (ENABLE_DELUSER && (!ENABLE_DELGROUP || applet_name[3] == 'u')); 19 27 20 static void del_line_matching(char **args, 21 const char *filename, 22 FILE *(*fopen_func)(const char *fileName, const char *mode)) 23 { 24 FILE *passwd; 25 smallint error = NAME_NOT_FOUND; 26 char *name = (ENABLE_FEATURE_DEL_USER_FROM_GROUP && args[2]) ? args[2] : args[1]; 27 char *line, *del; 28 char *new = xzalloc(1); 28 if (geteuid() != 0) 29 bb_error_msg_and_die(bb_msg_perm_denied_are_you_root); 29 30 30 passwd = fopen_func(filename, "r"); 31 if (passwd) { 32 while ((line = xmalloc_fgets(passwd))) { 33 int len = strlen(name); 31 name = argv[1]; 32 member = NULL; 34 33 35 if (strncmp(line, name, len) == 0 36 && line[len] == ':' 37 ) { 38 error = STATUS_OK; 39 if (ENABLE_FEATURE_DEL_USER_FROM_GROUP) { 40 struct group *gr; 41 char *p; 42 if (args[2] 43 /* There were two args on commandline */ 44 && (gr = getgrnam(name)) 45 /* The group was not deleted in the meanwhile */ 46 && (p = strrchr(line, ':')) 47 /* We can find a pointer to the last ':' */ 48 ) { 49 error = MEMBER_NOT_FOUND; 50 /* Move past ':' (worst case to '\0') and cut the line */ 51 p[1] = '\0'; 52 /* Reuse p */ 53 for (p = xzalloc(1); *gr->gr_mem != NULL; gr->gr_mem++) { 54 /* Add all the other group members */ 55 if (strcmp(args[1], *gr->gr_mem) != 0) { 56 del = p; 57 p = xasprintf("%s%s%s", p, p[0] ? "," : "", *gr->gr_mem); 58 free(del); 59 } else 60 error = STATUS_OK; 61 } 62 /* Recompose the line */ 63 line = xasprintf("%s%s\n", line, p); 64 if (ENABLE_FEATURE_CLEAN_UP) free(p); 65 } else 66 goto skip; 34 switch (argc) { 35 case 3: 36 if (!ENABLE_FEATURE_DEL_USER_FROM_GROUP || do_deluser) 37 break; 38 /* It's "delgroup USER GROUP" */ 39 member = name; 40 name = argv[2]; 41 /* Fallthrough */ 42 43 case 2: 44 if (do_deluser) { 45 /* "deluser USER" */ 46 xgetpwnam(name); /* bail out if USER is wrong */ 47 pfile = bb_path_passwd_file; 48 if (ENABLE_FEATURE_SHADOWPASSWDS) 49 sfile = bb_path_shadow_file; 50 } else { 51 struct group *gr; 52 do_delgroup: 53 /* "delgroup GROUP" or "delgroup USER GROUP" */ 54 if (do_deluser < 0) { /* delgroup after deluser? */ 55 gr = getgrnam(name); 56 if (!gr) 57 return EXIT_SUCCESS; 58 } else { 59 gr = xgetgrnam(name); /* bail out if GROUP is wrong */ 60 } 61 if (!member) { 62 /* "delgroup GROUP" */ 63 struct passwd *pw; 64 struct passwd pwent; 65 /* Check if the group is in use */ 66 #define passwd_buf bb_common_bufsiz1 67 while (!getpwent_r(&pwent, passwd_buf, sizeof(passwd_buf), &pw)) { 68 if (pwent.pw_gid == gr->gr_gid) 69 bb_error_msg_and_die("'%s' still has '%s' as their primary group!", pwent.pw_name, name); 67 70 } 71 //endpwent(); 68 72 } 69 del = new; 70 new = xasprintf("%s%s", new, line); 71 free(del); 72 skip: 73 free(line); 73 pfile = bb_path_group_file; 74 if (ENABLE_FEATURE_SHADOWPASSWDS) 75 sfile = bb_path_gshadow_file; 74 76 } 75 77 76 if (ENABLE_FEATURE_CLEAN_UP) fclose(passwd); 78 /* Modify pfile, then sfile */ 79 do { 80 if (update_passwd(pfile, name, NULL, member) == -1) 81 return EXIT_FAILURE; 82 if (ENABLE_FEATURE_SHADOWPASSWDS) { 83 pfile = sfile; 84 sfile = NULL; 85 } 86 } while (ENABLE_FEATURE_SHADOWPASSWDS && pfile); 77 87 78 if (error) { 79 if (ENABLE_FEATURE_DEL_USER_FROM_GROUP && error == MEMBER_NOT_FOUND) { 80 /* Set the correct values for error message */ 81 filename = name; 82 name = args[1]; 83 } 84 bb_error_msg("can't find %s in %s", name, filename); 85 } else { 86 passwd = fopen_func(filename, "w"); 87 if (passwd) { 88 fputs(new, passwd); 89 if (ENABLE_FEATURE_CLEAN_UP) fclose(passwd); 90 } 88 if (ENABLE_DELGROUP && do_deluser > 0) { 89 /* "deluser USER" also should try to delete 90 * same-named group. IOW: do "delgroup USER" 91 */ 92 // On debian deluser is a perl script that calls userdel. 93 // From man userdel: 94 // If USERGROUPS_ENAB is defined to yes in /etc/login.defs, userdel will 95 // delete the group with the same name as the user. 96 do_deluser = -1; 97 goto do_delgroup; 91 98 } 99 return EXIT_SUCCESS; 92 100 } 93 free(new); 101 /* Reached only if number of command line args is wrong */ 102 bb_show_usage(); 94 103 } 95 96 int deluser_main(int argc, char **argv);97 int deluser_main(int argc, char **argv)98 {99 if (argc == 2100 || (ENABLE_FEATURE_DEL_USER_FROM_GROUP101 && (applet_name[3] == 'g' && argc == 3))102 ) {103 if (geteuid())104 bb_error_msg_and_die(bb_msg_perm_denied_are_you_root);105 106 if ((ENABLE_FEATURE_DEL_USER_FROM_GROUP && argc != 3)107 || ENABLE_DELUSER108 || (ENABLE_DELGROUP && ENABLE_DESKTOP)109 ) {110 if (ENABLE_DELUSER111 && (!ENABLE_DELGROUP || applet_name[3] == 'u')112 ) {113 del_line_matching(argv, bb_path_passwd_file, xfopen);114 if (ENABLE_FEATURE_SHADOWPASSWDS)115 del_line_matching(argv, bb_path_shadow_file, fopen_or_warn);116 } else if (ENABLE_DESKTOP && ENABLE_DELGROUP && getpwnam(argv[1]))117 bb_error_msg_and_die("can't remove primary group of user %s", argv[1]);118 }119 del_line_matching(argv, bb_path_group_file, xfopen);120 if (ENABLE_FEATURE_SHADOWPASSWDS)121 del_line_matching(argv, bb_path_gshadow_file, fopen_or_warn);122 return EXIT_SUCCESS;123 } else124 bb_show_usage();125 }
Note:
See TracChangeset
for help on using the changeset viewer.