1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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
29GLOBALS(
30 long gid;
31)
32
33
34
35
36
37
38static void new_group()
39{
40 char *entry = NULL;
41
42 if (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 (FLAG(S)) TT.gid = CFG_TOYBOX_UID_SYS;
47 else TT.gid = CFG_TOYBOX_UID_USR;
48
49 while (getgrgid(TT.gid)) TT.gid++;
50 }
51
52 entry = xmprintf("%s:%s:%ld:", *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
60void 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) {
69
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 {
93 char *s = *toys.optargs;
94
95
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