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