Changeset 1770 in MondoRescue for branches/stable/mindi-busybox/loginutils/deluser.c
- Timestamp:
- Nov 6, 2007, 11:01:53 AM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/stable/mindi-busybox/loginutils/deluser.c
r821 r1770 1 1 /* vi: set sw=4 ts=4: */ 2 2 /* 3 * deluser (remove lusers from the system ;) for TinyLogin3 * deluser/delgroup implementation for busybox 4 4 * 5 5 * Copyright (C) 1999 by Lineo, inc. and John Beppu 6 6 * Copyright (C) 1999,2000,2001 by John Beppu <beppu@codepoet.org> 7 * Unified with delgroupby Tito Ragusa <farmatito@tiscali.it>7 * Copyright (C) 2007 by Tito Ragusa <farmatito@tiscali.it> 8 8 * 9 * Licensed under GPL v2 or later, see file LICENSE in this tarball for details.9 * Licensed under GPL version 2, see file LICENSE in this tarball for details. 10 10 * 11 11 */ 12 12 13 #include <sys/stat.h> 14 #include <unistd.h> 15 #include <stdio.h> 16 #include <stdlib.h> 17 #include <string.h> 18 #include "busybox.h" 13 #include "libbb.h" 19 14 20 /* where to start and stop deletion */ 21 typedef struct { 22 size_t start; 23 size_t stop; 24 } Bounds; 15 /* Status */ 16 #define STATUS_OK 0 17 #define NAME_NOT_FOUND 1 18 #define MEMBER_NOT_FOUND 2 25 19 26 /* An interesting side-effect of boundary()'s 27 * implementation is that the first user (typically root) 28 * cannot be removed. Let's call it a feature. */ 29 static inline Bounds boundary(const char *buffer, const char *login) 20 static void del_line_matching(char **args, 21 const char *filename, 22 FILE *(*fopen_func)(const char *fileName, const char *mode)) 30 23 { 31 char needle[256]; 32 char *start; 33 char *stop; 34 Bounds b; 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); 35 29 36 snprintf(needle, 256, "\n%s:", login); 37 needle[255] = 0; 38 start = strstr(buffer, needle); 39 if (!start) { 40 b.start = 0; 41 b.stop = 0; 42 return b; 30 passwd = fopen_func(filename, "r"); 31 if (passwd) { 32 while ((line = xmalloc_fgets(passwd))) { 33 int len = strlen(name); 34 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; 67 } 68 } 69 del = new; 70 new = xasprintf("%s%s", new, line); 71 free(del); 72 skip: 73 free(line); 74 } 75 76 if (ENABLE_FEATURE_CLEAN_UP) fclose(passwd); 77 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 } 91 } 43 92 } 44 start++; 45 46 stop = strchr(start, '\n'); 47 b.start = start - buffer; 48 b.stop = stop - buffer; 49 return b; 93 free(new); 50 94 } 51 95 52 /* grep -v ^login (except it only deletes the first match) */ 53 /* ...in fact, I think I'm going to simplify this later */ 54 static void del_line_matching(const char *login, const char *filename) 55 { 56 char *buffer; 57 FILE *passwd; 58 Bounds b; 59 struct stat statbuf; 60 61 62 if ((passwd = bb_wfopen(filename, "r"))) { 63 xstat(filename, &statbuf); 64 buffer = (char *) xmalloc(statbuf.st_size * sizeof(char)); 65 fread(buffer, statbuf.st_size, sizeof(char), passwd); 66 fclose(passwd); 67 /* find the user to remove */ 68 b = boundary(buffer, login); 69 if (b.stop != 0) { 70 /* write the file w/o the user */ 71 if ((passwd = bb_wfopen(filename, "w"))) { 72 fwrite(buffer, (b.start - 1), sizeof(char), passwd); 73 fwrite(&buffer[b.stop], (statbuf.st_size - b.stop), sizeof(char), passwd); 74 fclose(passwd); 75 } 76 } else { 77 bb_error_msg("Can't find '%s' in '%s'", login, filename); 78 } 79 free(buffer); 80 } 81 } 82 96 int deluser_main(int argc, char **argv); 83 97 int deluser_main(int argc, char **argv) 84 98 { 85 if (argc != 2) { 99 if (argc == 2 100 || (ENABLE_FEATURE_DEL_USER_FROM_GROUP 101 && (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_DELUSER 108 || (ENABLE_DELGROUP && ENABLE_DESKTOP) 109 ) { 110 if (ENABLE_DELUSER 111 && (!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 } else 86 124 bb_show_usage(); 87 } else {88 if (ENABLE_DELUSER && bb_applet_name[3] == 'u') {89 del_line_matching(argv[1], bb_path_passwd_file);90 if (ENABLE_FEATURE_SHADOWPASSWDS)91 del_line_matching(argv[1], bb_path_shadow_file);92 }93 del_line_matching(argv[1], bb_path_group_file);94 if (ENABLE_FEATURE_SHADOWPASSWDS)95 del_line_matching(argv[1], bb_path_gshadow_file);96 }97 return (EXIT_SUCCESS);98 125 } 99 100 /* $Id: deluser.c,v 1.4 2003/07/14 20:20:45 andersen Exp $ */
Note:
See TracChangeset
for help on using the changeset viewer.