1 | /* vi: set sw=4 ts=4: */
|
---|
2 | /*
|
---|
3 | * addgroup - add users to /etc/passwd and /etc/shadow
|
---|
4 | *
|
---|
5 | * Copyright (C) 1999 by Lineo, inc. and John Beppu
|
---|
6 | * Copyright (C) 1999,2000,2001 by John Beppu <beppu@codepoet.org>
|
---|
7 | *
|
---|
8 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
|
---|
9 | *
|
---|
10 | */
|
---|
11 |
|
---|
12 | #include <stdio.h>
|
---|
13 | #include <string.h>
|
---|
14 | #include <sys/types.h>
|
---|
15 | #include <unistd.h>
|
---|
16 |
|
---|
17 | #include "busybox.h"
|
---|
18 |
|
---|
19 | /* make sure gr_name isn't taken, make sure gid is kosher
|
---|
20 | * return 1 on failure */
|
---|
21 | static int group_study(struct group *g)
|
---|
22 | {
|
---|
23 | FILE *etc_group;
|
---|
24 | gid_t desired;
|
---|
25 |
|
---|
26 | struct group *grp;
|
---|
27 | const int max = 65000;
|
---|
28 |
|
---|
29 | etc_group = bb_xfopen(bb_path_group_file, "r");
|
---|
30 |
|
---|
31 | /* make sure gr_name isn't taken, make sure gid is kosher */
|
---|
32 | desired = g->gr_gid;
|
---|
33 | while ((grp = fgetgrent(etc_group))) {
|
---|
34 | if ((strcmp(grp->gr_name, g->gr_name)) == 0) {
|
---|
35 | bb_error_msg_and_die("%s: group already in use", g->gr_name);
|
---|
36 | }
|
---|
37 | if ((desired) && grp->gr_gid == desired) {
|
---|
38 | bb_error_msg_and_die("%d: gid already in use",
|
---|
39 | desired);
|
---|
40 | }
|
---|
41 | if ((grp->gr_gid > g->gr_gid) && (grp->gr_gid < max)) {
|
---|
42 | g->gr_gid = grp->gr_gid;
|
---|
43 | }
|
---|
44 | }
|
---|
45 | fclose(etc_group);
|
---|
46 |
|
---|
47 | /* gid */
|
---|
48 | if (desired) {
|
---|
49 | g->gr_gid = desired;
|
---|
50 | } else {
|
---|
51 | g->gr_gid++;
|
---|
52 | }
|
---|
53 | /* return 1; */
|
---|
54 | return 0;
|
---|
55 | }
|
---|
56 |
|
---|
57 | /* append a new user to the passwd file */
|
---|
58 | static int addgroup(char *group, gid_t gid, const char *user)
|
---|
59 | {
|
---|
60 | FILE *file;
|
---|
61 | struct group gr;
|
---|
62 |
|
---|
63 | /* make sure gid and group haven't already been allocated */
|
---|
64 | gr.gr_gid = gid;
|
---|
65 | gr.gr_name = group;
|
---|
66 | if (group_study(&gr))
|
---|
67 | return 1;
|
---|
68 |
|
---|
69 | /* add entry to group */
|
---|
70 | file = bb_xfopen(bb_path_group_file, "a");
|
---|
71 | /* group:passwd:gid:userlist */
|
---|
72 | fprintf(file, "%s:%s:%d:%s\n", group, "x", gr.gr_gid, user);
|
---|
73 | fclose(file);
|
---|
74 |
|
---|
75 | #if ENABLE_FEATURE_SHADOWPASSWDS
|
---|
76 | file = bb_xfopen(bb_path_gshadow_file, "a");
|
---|
77 | fprintf(file, "%s:!::\n", group);
|
---|
78 | fclose(file);
|
---|
79 | #endif
|
---|
80 |
|
---|
81 | /* return 1; */
|
---|
82 | return 0;
|
---|
83 | }
|
---|
84 |
|
---|
85 | /*
|
---|
86 | * addgroup will take a login_name as its first parameter.
|
---|
87 | *
|
---|
88 | * gid
|
---|
89 | *
|
---|
90 | * can be customized via command-line parameters.
|
---|
91 | * ________________________________________________________________________ */
|
---|
92 | int addgroup_main(int argc, char **argv)
|
---|
93 | {
|
---|
94 | char *group;
|
---|
95 | gid_t gid = 0;
|
---|
96 |
|
---|
97 | /* check for min, max and missing args and exit on error */
|
---|
98 | bb_opt_complementally = "-1:?2:?";
|
---|
99 |
|
---|
100 | if (bb_getopt_ulflags(argc, argv, "g:", &group)) {
|
---|
101 | gid = bb_xgetlarg(group, 10, 0, LONG_MAX);
|
---|
102 | }
|
---|
103 | /* move past the commandline options */
|
---|
104 | argv += optind;
|
---|
105 |
|
---|
106 | /* need to be root */
|
---|
107 | if(geteuid()) {
|
---|
108 | bb_error_msg_and_die(bb_msg_perm_denied_are_you_root);
|
---|
109 | }
|
---|
110 |
|
---|
111 | /* werk */
|
---|
112 | return addgroup(argv[0], gid, (argv[1]) ? argv[1] : "");
|
---|
113 | }
|
---|