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