Changeset 1770 in MondoRescue for branches/stable/mindi-busybox/loginutils/addgroup.c
- Timestamp:
- Nov 6, 2007, 11:01:53 AM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/stable/mindi-busybox/loginutils/addgroup.c
r821 r1770 1 1 /* vi: set sw=4 ts=4: */ 2 2 /* 3 * addgroup - add users to /etc/passwd and /etc/shadow3 * addgroup - add groups to /etc/group and /etc/gshadow 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 * Copyright (C) 2007 by Tito Ragusa <farmatito@tiscali.it> 7 8 * 8 9 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. … … 10 11 */ 11 12 12 #include <stdio.h> 13 #include <string.h> 14 #include <sys/types.h> 15 #include <unistd.h> 13 #include "libbb.h" 16 14 17 #include "busybox.h" 15 static void xgroup_study(struct group *g) 16 { 17 /* Make sure gr_name is unused */ 18 if (getgrnam(g->gr_name)) { 19 goto error; 20 } 18 21 19 /* make sure gr_name isn't taken, make sure gid is kosher 20 * return 1 on failure */ 21 static int group_study(struct group *g) 22 { 23 FILE *etc_group; 24 gid_t desired; 25 26 struct group *grp; 27 const int max = 65000; 28 29 etc_group = bb_xfopen(bb_path_group_file, "r"); 30 31 /* make sure gr_name isn't taken, make sure gid is kosher */ 32 desired = g->gr_gid; 33 while ((grp = fgetgrent(etc_group))) { 34 if ((strcmp(grp->gr_name, g->gr_name)) == 0) { 35 bb_error_msg_and_die("%s: group already in use", g->gr_name); 22 /* Check if the desired gid is free 23 * or find the first free one */ 24 while (1) { 25 if (!getgrgid(g->gr_gid)) { 26 return; /* found free group: return */ 36 27 } 37 if ((desired) && grp->gr_gid == desired) { 38 bb_error_msg_and_die("%d: gid already in use", 39 desired); 28 if (option_mask32) { 29 /* -g N, cannot pick gid other than N: error */ 30 g->gr_name = itoa(g->gr_gid); 31 goto error; 40 32 } 41 if ((grp->gr_gid > g->gr_gid) && (grp->gr_gid < max)) { 42 g->gr_gid = grp->gr_gid; 33 g->gr_gid++; 34 if (g->gr_gid <= 0) { 35 /* overflowed: error */ 36 bb_error_msg_and_die("no gids left"); 43 37 } 44 38 } 45 fclose(etc_group);46 39 47 /* gid */ 48 if (desired) { 49 g->gr_gid = desired; 50 } else { 51 g->gr_gid++; 52 } 53 /* return 1; */ 54 return 0; 40 error: 41 /* exit */ 42 bb_error_msg_and_die("group %s already exists", g->gr_name); 55 43 } 56 44 57 45 /* append a new user to the passwd file */ 58 static int addgroup(char *group, gid_t gid, const char *user)46 static void new_group(char *group, gid_t gid) 59 47 { 60 48 FILE *file; … … 64 52 gr.gr_gid = gid; 65 53 gr.gr_name = group; 66 if (group_study(&gr)) 67 return 1; 54 xgroup_study(&gr); 68 55 69 56 /* add entry to group */ 70 file = bb_xfopen(bb_path_group_file, "a");57 file = xfopen(bb_path_group_file, "a"); 71 58 /* group:passwd:gid:userlist */ 72 fprintf(file, "%s:%s:%d:%s\n", group, "x", gr.gr_gid, user); 73 fclose(file); 59 fprintf(file, "%s:x:%d:\n", group, gr.gr_gid); 60 if (ENABLE_FEATURE_CLEAN_UP) 61 fclose(file); 62 #if ENABLE_FEATURE_SHADOWPASSWDS 63 file = fopen_or_warn(bb_path_gshadow_file, "a"); 64 if (file) { 65 fprintf(file, "%s:!::\n", group); 66 if (ENABLE_FEATURE_CLEAN_UP) 67 fclose(file); 68 } 69 #endif 70 } 74 71 75 #if ENABLE_FEATURE_SHADOWPASSWDS 76 file = bb_xfopen(bb_path_gshadow_file, "a"); 77 fprintf(file, "%s:!::\n", group); 78 fclose(file); 72 #if ENABLE_FEATURE_ADDUSER_TO_GROUP 73 static void add_user_to_group(char **args, 74 const char *path, 75 FILE *(*fopen_func)(const char *fileName, const char *mode)) 76 { 77 char *line; 78 int len = strlen(args[1]); 79 llist_t *plist = NULL; 80 FILE *group_file; 81 82 group_file = fopen_func(path, "r"); 83 84 if (!group_file) return; 85 86 while ((line = xmalloc_getline(group_file))) { 87 /* Find the group */ 88 if (!strncmp(line, args[1], len) 89 && line[len] == ':' 90 ) { 91 /* Add the new user */ 92 line = xasprintf("%s%s%s", line, 93 last_char_is(line, ':') ? "" : ",", 94 args[0]); 95 } 96 llist_add_to_end(&plist, line); 97 } 98 99 if (ENABLE_FEATURE_CLEAN_UP) { 100 fclose(group_file); 101 group_file = fopen_func(path, "w"); 102 while ((line = llist_pop(&plist))) { 103 if (group_file) 104 fprintf(group_file, "%s\n", line); 105 free(line); 106 } 107 if (group_file) 108 fclose(group_file); 109 } else { 110 group_file = fopen_func(path, "w"); 111 if (group_file) 112 while ((line = llist_pop(&plist))) 113 fprintf(group_file, "%s\n", line); 114 } 115 } 79 116 #endif 80 81 /* return 1; */82 return 0;83 }84 117 85 118 /* 86 119 * addgroup will take a login_name as its first parameter. 87 120 * 88 * gid 89 * 90 * can be customized via command-line parameters. 91 * ________________________________________________________________________ */ 121 * gid can be customized via command-line parameters. 122 * If called with two non-option arguments, addgroup 123 * will add an existing user to an existing group. 124 */ 125 int addgroup_main(int argc, char **argv); 92 126 int addgroup_main(int argc, char **argv) 93 127 { 94 128 char *group; 95 129 gid_t gid = 0; 96 97 /* check for min, max and missing args and exit on error */98 bb_opt_complementally = "-1:?2:?";99 130 100 if (bb_getopt_ulflags(argc, argv, "g:", &group)) { 101 gid = bb_xgetlarg(group, 10, 0, LONG_MAX); 131 /* need to be root */ 132 if (geteuid()) { 133 bb_error_msg_and_die(bb_msg_perm_denied_are_you_root); 134 } 135 136 /* Syntax: 137 * addgroup group 138 * addgroup -g num group 139 * addgroup user group 140 * Check for min, max and missing args */ 141 opt_complementary = "-1:?2"; 142 if (getopt32(argv, "g:", &group)) { 143 gid = xatoul_range(group, 0, ((unsigned long)(gid_t)ULONG_MAX) >> 1); 102 144 } 103 145 /* move past the commandline options */ 104 146 argv += optind; 147 argc -= optind; 105 148 106 /* need to be root */ 107 if(geteuid()) { 108 bb_error_msg_and_die(bb_msg_perm_denied_are_you_root); 109 } 149 #if ENABLE_FEATURE_ADDUSER_TO_GROUP 150 if (argc == 2) { 151 struct group *gr; 110 152 111 /* werk */ 112 return addgroup(argv[0], gid, (argv[1]) ? argv[1] : ""); 153 if (option_mask32) { 154 /* -g was there, but "addgroup -g num user group" 155 * is a no-no */ 156 bb_show_usage(); 157 } 158 159 /* check if group and user exist */ 160 xuname2uid(argv[0]); /* unknown user: exit */ 161 xgroup2gid(argv[1]); /* unknown group: exit */ 162 /* check if user is already in this group */ 163 gr = getgrnam(argv[1]); 164 for (; *(gr->gr_mem) != NULL; (gr->gr_mem)++) { 165 if (!strcmp(argv[0], *(gr->gr_mem))) { 166 /* user is already in group: do nothing */ 167 return EXIT_SUCCESS; 168 } 169 } 170 add_user_to_group(argv, bb_path_group_file, xfopen); 171 #if ENABLE_FEATURE_SHADOWPASSWDS 172 add_user_to_group(argv, bb_path_gshadow_file, fopen_or_warn); 173 #endif /* ENABLE_FEATURE_SHADOWPASSWDS */ 174 } else 175 #endif /* ENABLE_FEATURE_ADDUSER_TO_GROUP */ 176 new_group(argv[0], gid); 177 178 /* Reached only on success */ 179 return EXIT_SUCCESS; 113 180 }
Note:
See TracChangeset
for help on using the changeset viewer.