Home | History | Annotate | Download | only in pending
      1 /* groupadd.c - create a new group
      2  *
      3  * Copyright 2013 Ashwini Kumar <ak.ashwini (at) gmail.com>
      4  * Copyright 2013 Kyungwan Han <asura321 (at) gmail.com>
      5  *
      6  * See http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/groupadd.html
      7 
      8 USE_GROUPADD(NEWTOY(groupadd, "<1>2g#<0S", TOYFLAG_NEEDROOT|TOYFLAG_SBIN))
      9 USE_GROUPADD(OLDTOY(addgroup, groupadd, TOYFLAG_NEEDROOT|TOYFLAG_SBIN))
     10 
     11 config GROUPADD
     12   bool "groupadd"
     13   default n
     14   help
     15     usage: groupadd [-S] [-g GID] [USER] GROUP
     16 
     17     Add a group or add a user to a group
     18 
     19       -g GID Group id
     20       -S     Create a system group
     21 */
     22 
     23 #define FOR_groupadd
     24 #include "toys.h"
     25 
     26 #define GROUP_PATH        "/etc/group"
     27 #define SECURE_GROUP_PATH "/etc/gshadow"
     28 
     29 GLOBALS(
     30   long gid;
     31 )
     32 
     33 /* Add a new group to the system, if GID is given then that is validated
     34  * to be free, else a free GID is choosen by self.
     35  * SYSTEM IDs are considered in the range 100 ... 999
     36  * update_group(), updates the entries in /etc/group, /etc/gshadow files
     37  */
     38 static void new_group()
     39 {
     40   char *entry = NULL;
     41 
     42   if (toys.optflags & FLAG_g) {
     43     if (TT.gid > INT_MAX) error_exit("gid should be less than  '%d' ", INT_MAX);
     44     if (getgrgid(TT.gid)) error_exit("group '%ld' is in use", TT.gid);
     45   } else {
     46     if (toys.optflags & FLAG_S) TT.gid = CFG_TOYBOX_UID_SYS;
     47     else TT.gid = CFG_TOYBOX_UID_USR;
     48     //find unused gid
     49     while (getgrgid(TT.gid)) TT.gid++;
     50   }
     51 
     52   entry = xmprintf("%s:%s:%d:", *toys.optargs, "x", TT.gid);
     53   update_password(GROUP_PATH, *toys.optargs, entry);
     54   free(entry);
     55   entry = xmprintf("%s:%s::", *toys.optargs, "!");
     56   update_password(SECURE_GROUP_PATH, *toys.optargs, entry);
     57   free(entry);
     58 }
     59 
     60 void groupadd_main(void)
     61 {
     62   struct group *grp = NULL;
     63   char *entry = NULL;
     64 
     65   if (toys.optflags && toys.optc == 2)
     66     help_exit("options, user and group can't be together");
     67 
     68   if (toys.optc == 2) {  //add user to group
     69     //toys.optargs[0]- user, toys.optargs[1] - group
     70     xgetpwnam(*toys.optargs);
     71     if (!(grp = getgrnam(toys.optargs[1])))
     72       error_exit("group '%s' does not exist", toys.optargs[1]);
     73     if (!grp->gr_mem) entry = xmprintf("%s", *toys.optargs);
     74     else {
     75       int i;
     76 
     77       for (i = 0; grp->gr_mem[i]; i++)
     78         if (!strcmp(grp->gr_mem[i], *toys.optargs)) return;
     79 
     80       entry = xstrdup("");
     81       for (i=0; grp->gr_mem[i]; i++) {
     82         entry = xrealloc(entry, strlen(entry) + strlen(grp->gr_mem[i]) + 2);
     83         strcat(entry, grp->gr_mem[i]);
     84         strcat(entry, ",");
     85       }
     86       entry = xrealloc(entry, strlen(entry) + strlen(*toys.optargs) + 1);
     87       strcat(entry, *toys.optargs);
     88     }
     89     update_password(GROUP_PATH, grp->gr_name, entry);
     90     update_password(SECURE_GROUP_PATH, grp->gr_name, entry);
     91     free(entry);
     92   } else {    //new group to be created
     93     char *s = *toys.optargs;
     94 
     95     /* investigate the group to be created */
     96     if (getgrnam(s)) error_exit("'%s' in use", s);
     97     if (s[strcspn(s, ":/\n")] || strlen(s) > LOGIN_NAME_MAX)
     98       error_exit("bad name");
     99     new_group();
    100   }
    101 }
    102