118ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley/* groupadd.c - create a new group
218ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley *
318ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley * Copyright 2013 Ashwini Kumar <ak.ashwini@gmail.com>
418ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley * Copyright 2013 Kyungwan Han <asura321@gmail.com>
518ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley *
618ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley * See http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/groupadd.html
718ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley
818ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob LandleyUSE_GROUPADD(NEWTOY(groupadd, "<1>2g#<0S", TOYFLAG_NEEDROOT|TOYFLAG_SBIN))
9f3e56f4e4ff773de95fa2c9daf979734d826fc33Rob LandleyUSE_GROUPADD(OLDTOY(addgroup, groupadd, TOYFLAG_NEEDROOT|TOYFLAG_SBIN))
1018ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley
1118ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landleyconfig GROUPADD
1218ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley  bool "groupadd"
1318ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley  default n
1418ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley  help
1518ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley    usage: groupadd [-S] [-g GID] [USER] GROUP
1618ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley
1718ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley    Add a group or add a user to a group
1818ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley
1918ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley      -g GID Group id
2018ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley      -S     Create a system group
2118ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley*/
2218ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley
2318ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley#define FOR_groupadd
2418ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley#include "toys.h"
2518ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley
2618ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley#define GROUP_PATH        "/etc/group"
2718ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley#define SECURE_GROUP_PATH "/etc/gshadow"
2818ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley
2918ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob LandleyGLOBALS(
3018ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley  long gid;
3118ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley)
3218ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley
3318ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley/* Add a new group to the system, if GID is given then that is validated
3418ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley * to be free, else a free GID is choosen by self.
3518ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley * SYSTEM IDs are considered in the range 100 ... 999
3618ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley * update_group(), updates the entries in /etc/group, /etc/gshadow files
3718ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley */
3818ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landleystatic void new_group()
3918ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley{
4018ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley  char *entry = NULL;
4118ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley
4218ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley  if (toys.optflags & FLAG_g) {
4318ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley    if (TT.gid > INT_MAX) error_exit("gid should be less than  '%d' ", INT_MAX);
4418ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley    if (getgrgid(TT.gid)) error_exit("group '%ld' is in use", TT.gid);
4518ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley  } else {
46a8bee46cfebcf1ae9c3749b820c483054be81295Rob Landley    if (toys.optflags & FLAG_S) TT.gid = CFG_TOYBOX_UID_SYS;
47a8bee46cfebcf1ae9c3749b820c483054be81295Rob Landley    else TT.gid = CFG_TOYBOX_UID_USR;
4818ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley    //find unused gid
49a8bee46cfebcf1ae9c3749b820c483054be81295Rob Landley    while (getgrgid(TT.gid)) TT.gid++;
5018ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley  }
5118ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley
5259d85e2bb065a3bdc27868acb7a65f89d872c7faRob Landley  entry = xmprintf("%s:%s:%d:", *toys.optargs, "x", TT.gid);
5318ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley  update_password(GROUP_PATH, *toys.optargs, entry);
5418ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley  free(entry);
5559d85e2bb065a3bdc27868acb7a65f89d872c7faRob Landley  entry = xmprintf("%s:%s::", *toys.optargs, "!");
5618ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley  update_password(SECURE_GROUP_PATH, *toys.optargs, entry);
5718ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley  free(entry);
5818ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley}
5918ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley
6018ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landleyvoid groupadd_main(void)
6118ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley{
6218ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley  struct group *grp = NULL;
6318ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley  char *entry = NULL;
6418ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley
65e5354ca12a232b3f97726214254a868771cb70d1Rob Landley  if (toys.optflags && toys.optc == 2)
66e5354ca12a232b3f97726214254a868771cb70d1Rob Landley    help_exit("options, user and group can't be together");
6718ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley
6818ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley  if (toys.optc == 2) {  //add user to group
6918ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley    //toys.optargs[0]- user, toys.optargs[1] - group
705ec4ab3113dcc813b6040d7ded38e297df99dc0eRob Landley    xgetpwnam(*toys.optargs);
7118ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley    if (!(grp = getgrnam(toys.optargs[1])))
7218ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley      error_exit("group '%s' does not exist", toys.optargs[1]);
7359d85e2bb065a3bdc27868acb7a65f89d872c7faRob Landley    if (!grp->gr_mem) entry = xmprintf("%s", *toys.optargs);
7418ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley    else {
7518ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley      int i;
7618ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley
7718ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley      for (i = 0; grp->gr_mem[i]; i++)
7818ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley        if (!strcmp(grp->gr_mem[i], *toys.optargs)) return;
7918ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley
8018ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley      entry = xstrdup("");
8118ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley      for (i=0; grp->gr_mem[i]; i++) {
8218ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley        entry = xrealloc(entry, strlen(entry) + strlen(grp->gr_mem[i]) + 2);
8318ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley        strcat(entry, grp->gr_mem[i]);
8418ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley        strcat(entry, ",");
8518ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley      }
8618ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley      entry = xrealloc(entry, strlen(entry) + strlen(*toys.optargs) + 1);
8718ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley      strcat(entry, *toys.optargs);
8818ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley    }
8918ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley    update_password(GROUP_PATH, grp->gr_name, entry);
9018ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley    update_password(SECURE_GROUP_PATH, grp->gr_name, entry);
9118ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley    free(entry);
9218ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley  } else {    //new group to be created
93e0d8009d76b3a2451cb6c6ed2b241c7eff06ed60Rob Landley    char *s = *toys.optargs;
94e0d8009d76b3a2451cb6c6ed2b241c7eff06ed60Rob Landley
9518ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley    /* investigate the group to be created */
96e0d8009d76b3a2451cb6c6ed2b241c7eff06ed60Rob Landley    if (getgrnam(s)) error_exit("'%s' in use", s);
97e0d8009d76b3a2451cb6c6ed2b241c7eff06ed60Rob Landley    if (s[strcspn(s, ":/\n")] || strlen(s) > LOGIN_NAME_MAX)
98e0d8009d76b3a2451cb6c6ed2b241c7eff06ed60Rob Landley      error_exit("bad name");
9918ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley    new_group();
10018ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley  }
10118ec03543c3731e1ea25182ef72c49ac5ec2d1c7Rob Landley}
102