Magellan Linux

Diff of /trunk/mkinitrd-magellan/busybox/loginutils/addgroup.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 983 by niro, Fri Apr 24 18:33:46 2009 UTC revision 984 by niro, Sun May 30 11:32:42 2010 UTC
# Line 9  Line 9 
9   * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.   * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
10   *   *
11   */   */
   
12  #include "libbb.h"  #include "libbb.h"
13    
14    #if CONFIG_LAST_SYSTEM_ID < CONFIG_FIRST_SYSTEM_ID
15    #error Bad LAST_SYSTEM_ID or FIRST_SYSTEM_ID in .config
16    #endif
17    
18    #define OPT_GID                       (1 << 0)
19    #define OPT_SYSTEM_ACCOUNT            (1 << 1)
20    
21    /* We assume GID_T_MAX == INT_MAX */
22  static void xgroup_study(struct group *g)  static void xgroup_study(struct group *g)
23  {  {
24     unsigned max = INT_MAX;
25    
26   /* Make sure gr_name is unused */   /* Make sure gr_name is unused */
27   if (getgrnam(g->gr_name)) {   if (getgrnam(g->gr_name)) {
28   goto error;   bb_error_msg_and_die("%s '%s' in use", "group", g->gr_name);
29     /* these format strings are reused in adduser and addgroup */
30   }   }
31    
32     /* if a specific gid is requested, the --system switch and */
33     /* min and max values are overridden, and the range of valid */
34     /* gid values is set to [0, INT_MAX] */
35     if (!(option_mask32 & OPT_GID)) {
36     if (option_mask32 & OPT_SYSTEM_ACCOUNT) {
37     g->gr_gid = CONFIG_FIRST_SYSTEM_ID;
38     max = CONFIG_LAST_SYSTEM_ID;
39     } else {
40     g->gr_gid = CONFIG_LAST_SYSTEM_ID + 1;
41     max = 64999;
42     }
43     }
44   /* Check if the desired gid is free   /* Check if the desired gid is free
45   * or find the first free one */   * or find the first free one */
46   while (1) {   while (1) {
47   if (!getgrgid(g->gr_gid)) {   if (!getgrgid(g->gr_gid)) {
48   return; /* found free group: return */   return; /* found free group: return */
49   }   }
50   if (option_mask32) {   if (option_mask32 & OPT_GID) {
51   /* -g N, cannot pick gid other than N: error */   /* -g N, cannot pick gid other than N: error */
52   g->gr_name = itoa(g->gr_gid);   bb_error_msg_and_die("%s '%s' in use", "gid", itoa(g->gr_gid));
53   goto error;   /* this format strings is reused in adduser and addgroup */
54   }   }
55   g->gr_gid++;   if (g->gr_gid == max) {
  if (g->gr_gid <= 0) {  
56   /* overflowed: error */   /* overflowed: error */
57   bb_error_msg_and_die("no gids left");   bb_error_msg_and_die("no %cids left", 'g');
58     /* this format string is reused in adduser and addgroup */
59   }   }
60     g->gr_gid++;
61   }   }
   
  error:  
  /* exit */  
  bb_error_msg_and_die("group %s already exists", g->gr_name);  
62  }  }
63    
64  /* append a new user to the passwd file */  /* append a new user to the passwd file */
65  static void new_group(char *group, gid_t gid)  static void new_group(char *group, gid_t gid)
66  {  {
  FILE *file;  
67   struct group gr;   struct group gr;
68     char *p;
69    
70   /* make sure gid and group haven't already been allocated */   /* make sure gid and group haven't already been allocated */
71   gr.gr_gid = gid;   gr.gr_gid = gid;
# Line 54  static void new_group(char *group, gid_t Line 73  static void new_group(char *group, gid_t
73   xgroup_study(&gr);   xgroup_study(&gr);
74    
75   /* add entry to group */   /* add entry to group */
76   file = xfopen(bb_path_group_file, "a");   p = xasprintf("x:%u:", (unsigned) gr.gr_gid);
77   /* group:passwd:gid:userlist */   if (update_passwd(bb_path_group_file, group, p, NULL) < 0)
78   fprintf(file, "%s:x:%u:\n", group, (unsigned)gr.gr_gid);   exit(EXIT_FAILURE);
79   if (ENABLE_FEATURE_CLEAN_UP)   if (ENABLE_FEATURE_CLEAN_UP)
80   fclose(file);   free(p);
81  #if ENABLE_FEATURE_SHADOWPASSWDS  #if ENABLE_FEATURE_SHADOWPASSWDS
82   file = fopen_or_warn(bb_path_gshadow_file, "a");   /* /etc/gshadow fields:
83   if (file) {   * 1. Group name.
84   fprintf(file, "%s:!::\n", group);   * 2. Encrypted password.
85   if (ENABLE_FEATURE_CLEAN_UP)   *    If set, non-members of the group can join the group
86   fclose(file);   *    by typing the password for that group using the newgrp command.
87   }   *    If the value is of this field ! then no user is allowed
88     *    to access the group using the newgrp command. A value of !!
89     *    is treated the same as a value of ! only it indicates
90     *    that a password has never been set before. If the value is null,
91     *    only group members can log into the group.
92     * 3. Group administrators (comma delimited list).
93     *    Group members listed here can add or remove group members
94     *    using the gpasswd command.
95     * 4. Group members (comma delimited list).
96     */
97     /* Ignore errors: if file is missing we assume admin doesn't want it */
98     update_passwd(bb_path_gshadow_file, group, "!::", NULL);
99  #endif  #endif
100  }  }
101    
102  #if ENABLE_FEATURE_ADDUSER_TO_GROUP  #if ENABLE_FEATURE_ADDGROUP_LONG_OPTIONS
103  static void add_user_to_group(char **args,  static const char addgroup_longopts[] ALIGN1 =
104   const char *path,   "gid\0"                 Required_argument "g"
105   FILE* FAST_FUNC (*fopen_func)(const char *fileName, const char *mode))   "system\0"              No_argument       "S"
106  {   ;
  char *line;  
  int len = strlen(args[1]);  
  llist_t *plist = NULL;  
  FILE *group_file;  
   
  group_file = fopen_func(path, "r");  
   
  if (!group_file) return;  
   
  while ((line = xmalloc_fgetline(group_file)) != NULL) {  
  /* Find the group */  
  if (!strncmp(line, args[1], len)  
  && line[len] == ':'  
  ) {  
  /* Add the new user */  
  line = xasprintf("%s%s%s", line,  
  last_char_is(line, ':') ? "" : ",",  
  args[0]);  
  }  
  llist_add_to_end(&plist, line);  
  }  
   
  if (ENABLE_FEATURE_CLEAN_UP) {  
  fclose(group_file);  
  group_file = fopen_func(path, "w");  
  while ((line = llist_pop(&plist))) {  
  if (group_file)  
  fprintf(group_file, "%s\n", line);  
  free(line);  
  }  
  if (group_file)  
  fclose(group_file);  
  } else {  
  group_file = fopen_func(path, "w");  
  if (group_file)  
  while ((line = llist_pop(&plist)))  
  fprintf(group_file, "%s\n", line);  
  }  
 }  
107  #endif  #endif
108    
109  /*  /*
# Line 125  static void add_user_to_group(char **arg Line 116  static void add_user_to_group(char **arg
116  int addgroup_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;  int addgroup_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
117  int addgroup_main(int argc UNUSED_PARAM, char **argv)  int addgroup_main(int argc UNUSED_PARAM, char **argv)
118  {  {
119   char *group;   unsigned opts;
120   gid_t gid = 0;   unsigned gid = 0;
121    
122   /* need to be root */   /* need to be root */
123   if (geteuid()) {   if (geteuid()) {
124   bb_error_msg_and_die(bb_msg_perm_denied_are_you_root);   bb_error_msg_and_die(bb_msg_perm_denied_are_you_root);
125   }   }
126    #if ENABLE_FEATURE_ADDGROUP_LONG_OPTIONS
127     applet_long_options = addgroup_longopts;
128    #endif
129   /* Syntax:   /* Syntax:
130   *  addgroup group   *  addgroup group
131   *  addgroup -g num group   *  addgroup -g num group
132   *  addgroup user group   *  addgroup user group
133   * Check for min, max and missing args */   * Check for min, max and missing args */
134   opt_complementary = "-1:?2";   opt_complementary = "-1:?2:g+";
135   if (getopt32(argv, "g:", &group)) {   opts = getopt32(argv, "g:S", &gid);
  gid = xatoul_range(group, 0, ((unsigned long)(gid_t)ULONG_MAX) >> 1);  
  }  
136   /* move past the commandline options */   /* move past the commandline options */
137   argv += optind;   argv += optind;
138   //argc -= optind;   //argc -= optind;
# Line 150  int addgroup_main(int argc UNUSED_PARAM, Line 141  int addgroup_main(int argc UNUSED_PARAM,
141   if (argv[1]) {   if (argv[1]) {
142   struct group *gr;   struct group *gr;
143    
144   if (option_mask32) {   if (opts & OPT_GID) {
145   /* -g was there, but "addgroup -g num user group"   /* -g was there, but "addgroup -g num user group"
146   * is a no-no */   * is a no-no */
147   bb_show_usage();   bb_show_usage();
# Line 158  int addgroup_main(int argc UNUSED_PARAM, Line 149  int addgroup_main(int argc UNUSED_PARAM,
149    
150   /* check if group and user exist */   /* check if group and user exist */
151   xuname2uid(argv[0]); /* unknown user: exit */   xuname2uid(argv[0]); /* unknown user: exit */
152   xgroup2gid(argv[1]); /* unknown group: exit */   gr = xgetgrnam(argv[1]); /* unknown group: exit */
153   /* check if user is already in this group */   /* check if user is already in this group */
  gr = getgrnam(argv[1]);  
154   for (; *(gr->gr_mem) != NULL; (gr->gr_mem)++) {   for (; *(gr->gr_mem) != NULL; (gr->gr_mem)++) {
155   if (!strcmp(argv[0], *(gr->gr_mem))) {   if (!strcmp(argv[0], *(gr->gr_mem))) {
156   /* user is already in group: do nothing */   /* user is already in group: do nothing */
157   return EXIT_SUCCESS;   return EXIT_SUCCESS;
158   }   }
159   }   }
160   add_user_to_group(argv, bb_path_group_file, xfopen);   if (update_passwd(bb_path_group_file, argv[1], NULL, argv[0]) < 0) {
161  #if ENABLE_FEATURE_SHADOWPASSWDS   return EXIT_FAILURE;
162   add_user_to_group(argv, bb_path_gshadow_file, fopen_or_warn);   }
163  #endif  # if ENABLE_FEATURE_SHADOWPASSWDS
164     update_passwd(bb_path_gshadow_file, argv[1], NULL, argv[0]);
165    # endif
166   } else   } else
167  #endif /* ENABLE_FEATURE_ADDUSER_TO_GROUP */  #endif /* ENABLE_FEATURE_ADDUSER_TO_GROUP */
168   {   {

Legend:
Removed from v.983  
changed lines
  Added in v.984