1 /* groupadd.c - create a new group
2 *
3 * Copyright 2013 Ashwini Kumar <[email protected]>
4 * Copyright 2013 Kyungwan Han <[email protected]>
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>2R:g#<0>2147483647S", 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 user to a group, or create a new group.
18
19 -g GID Group id
20 -R Operate within chroot
21 -S Create a system group
22 */
23
24 #define FOR_groupadd
25 #include "toys.h"
26
GLOBALS(long g;char * R;)27 GLOBALS(
28 long g;
29 char *R;
30 )
31
32 /* Add a new group to the system, if GID is given then that is validated
33 * to be free, else a free GID is choosen by self.
34 * SYSTEM IDs are considered in the range 100 ... 999
35 * update_group(), updates the entries in /etc/group, /etc/gshadow files
36 */
37
38 void groupadd_main(void)
39 {
40 struct group *grp = 0;
41 char *entry = 0, *s, *gfile = "/etc/group", *gsfile = "/etc/gshadow";
42 int i, len;
43
44 if (TT.R) {
45 gfile = xmprintf("%s%s", TT.R, gfile);
46 gsfile = xmprintf("%s%s", TT.R, gsfile);
47 }
48
49 // Add user to group?
50 if (toys.optc == 2) {
51 if (FLAG(g)|FLAG(S)) help_exit("No -gS with USER+GROUP");
52 if (!(grp = getgrnam(s = toys.optargs[1]))) error_exit("no group '%s'", s);
53 len = strlen(s)+1;
54 xgetpwnam(s = *toys.optargs);
55
56 // Is this user already in this group?
57 for (i = 0; grp->gr_mem[i]; i++) {
58 if (!strcmp(grp->gr_mem[i], s)) return;
59 len += strlen(grp->gr_mem[i])+1;
60 }
61 s = entry = xmalloc(len);
62 for (i = 0;; i++) {
63 if (i) *s++ = ',';
64 if (!grp->gr_mem[i]) {
65 strcpy(s, toys.optargs[1]);
66 break;
67 }
68 s = stpcpy(s, grp->gr_mem[i]);
69 }
70 update_password(gfile, grp->gr_name, entry, 3);
71 update_password(gsfile, grp->gr_name, entry, 3);
72 free(entry);
73
74 return;
75 }
76
77 // create new group
78 if (getgrnam(s = *toys.optargs)) error_exit("'%s' in use", s);
79 if (s[strcspn(s, ":/\n")] || strlen(s)>256) error_exit("bad '%s'", s);
80
81 // Find next unused GID or confirm selected GID isn't in use
82 if (!FLAG(g)) {
83 TT.g = FLAG(S) ? CFG_TOYBOX_UID_SYS : CFG_TOYBOX_UID_USR;
84 while (getgrgid(TT.g)) TT.g++;
85 } else if (getgrgid(TT.g)) error_exit("group '%ld' in use", TT.g);
86
87 sprintf(toybuf, "%s:x:%ld:", s, TT.g);
88 update_password(gfile, s, toybuf, 0);
89 sprintf(toybuf, "%s:!::", s);
90 update_password(gsfile, s, toybuf, 0);
91 }
92