Contents of /tags/mkinitrd-6_1_1/busybox/loginutils/adduser.c
Parent Directory | Revision Log
Revision 841 -
(show annotations)
(download)
Mon May 4 16:31:54 2009 UTC (15 years, 4 months ago) by niro
File MIME type: text/plain
File size: 4828 byte(s)
Mon May 4 16:31:54 2009 UTC (15 years, 4 months ago) by niro
File MIME type: text/plain
File size: 4828 byte(s)
tagged 'mkinitrd-6_1_1'
1 | /* vi: set sw=4 ts=4: */ |
2 | /* |
3 | * adduser - 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 the GPL v2 or later, see the file LICENSE in this tarball. |
9 | */ |
10 | |
11 | #include "libbb.h" |
12 | |
13 | #define OPT_DONT_SET_PASS (1 << 4) |
14 | #define OPT_SYSTEM_ACCOUNT (1 << 5) |
15 | #define OPT_DONT_MAKE_HOME (1 << 6) |
16 | |
17 | |
18 | /* remix */ |
19 | /* recoded such that the uid may be passed in *p */ |
20 | static void passwd_study(struct passwd *p) |
21 | { |
22 | int max; |
23 | |
24 | if (getpwnam(p->pw_name)) |
25 | bb_error_msg_and_die("login '%s' is in use", p->pw_name); |
26 | |
27 | if (option_mask32 & OPT_SYSTEM_ACCOUNT) { |
28 | p->pw_uid = 0; |
29 | max = 999; |
30 | } else { |
31 | p->pw_uid = 1000; |
32 | max = 64999; |
33 | } |
34 | |
35 | /* check for a free uid (and maybe gid) */ |
36 | while (getpwuid(p->pw_uid) || (!p->pw_gid && getgrgid(p->pw_uid))) |
37 | p->pw_uid++; |
38 | |
39 | if (!p->pw_gid) { |
40 | /* new gid = uid */ |
41 | p->pw_gid = p->pw_uid; |
42 | if (getgrnam(p->pw_name)) |
43 | bb_error_msg_and_die("group name '%s' is in use", p->pw_name); |
44 | } |
45 | |
46 | if (p->pw_uid > max) |
47 | bb_error_msg_and_die("no free uids left"); |
48 | } |
49 | |
50 | static void addgroup_wrapper(struct passwd *p) |
51 | { |
52 | char *cmd; |
53 | |
54 | cmd = xasprintf("addgroup -g %u '%s'", (unsigned)p->pw_gid, p->pw_name); |
55 | system(cmd); |
56 | free(cmd); |
57 | } |
58 | |
59 | static void passwd_wrapper(const char *login) NORETURN; |
60 | |
61 | static void passwd_wrapper(const char *login) |
62 | { |
63 | static const char prog[] ALIGN1 = "passwd"; |
64 | |
65 | BB_EXECLP(prog, prog, login, NULL); |
66 | bb_error_msg_and_die("cannot execute %s, you must set password manually", prog); |
67 | } |
68 | |
69 | #if ENABLE_FEATURE_ADDUSER_LONG_OPTIONS |
70 | static const char adduser_longopts[] ALIGN1 = |
71 | "home\0" Required_argument "h" |
72 | "gecos\0" Required_argument "g" |
73 | "shell\0" Required_argument "s" |
74 | "ingroup\0" Required_argument "G" |
75 | "disabled-password\0" No_argument "D" |
76 | "empty-password\0" No_argument "D" |
77 | "system\0" No_argument "S" |
78 | "no-create-home\0" No_argument "H" |
79 | ; |
80 | #endif |
81 | |
82 | /* |
83 | * adduser will take a login_name as its first parameter. |
84 | * home, shell, gecos: |
85 | * can be customized via command-line parameters. |
86 | */ |
87 | int adduser_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
88 | int adduser_main(int argc UNUSED_PARAM, char **argv) |
89 | { |
90 | struct passwd pw; |
91 | const char *usegroup = NULL; |
92 | FILE *file; |
93 | |
94 | #if ENABLE_FEATURE_ADDUSER_LONG_OPTIONS |
95 | applet_long_options = adduser_longopts; |
96 | #endif |
97 | |
98 | /* got root? */ |
99 | if (geteuid()) { |
100 | bb_error_msg_and_die(bb_msg_perm_denied_are_you_root); |
101 | } |
102 | |
103 | pw.pw_gecos = (char *)"Linux User,,,"; |
104 | pw.pw_shell = (char *)DEFAULT_SHELL; |
105 | pw.pw_dir = NULL; |
106 | |
107 | /* exactly one non-option arg */ |
108 | opt_complementary = "=1"; |
109 | getopt32(argv, "h:g:s:G:DSH", &pw.pw_dir, &pw.pw_gecos, &pw.pw_shell, &usegroup); |
110 | argv += optind; |
111 | |
112 | /* fill in the passwd struct */ |
113 | pw.pw_name = argv[0]; |
114 | die_if_bad_username(pw.pw_name); |
115 | if (!pw.pw_dir) { |
116 | /* create string for $HOME if not specified already */ |
117 | pw.pw_dir = xasprintf("/home/%s", argv[0]); |
118 | } |
119 | pw.pw_passwd = (char *)"x"; |
120 | pw.pw_gid = usegroup ? xgroup2gid(usegroup) : 0; /* exits on failure */ |
121 | |
122 | /* make sure everything is kosher and setup uid && maybe gid */ |
123 | passwd_study(&pw); |
124 | |
125 | /* add to passwd */ |
126 | file = xfopen(bb_path_passwd_file, "a"); |
127 | //fseek(file, 0, SEEK_END); /* paranoia, "a" should ensure that anyway */ |
128 | if (putpwent(&pw, file) != 0) { |
129 | bb_perror_nomsg_and_die(); |
130 | } |
131 | /* do fclose even if !ENABLE_FEATURE_CLEAN_UP. |
132 | * We will exec passwd, files must be flushed & closed before that! */ |
133 | fclose(file); |
134 | |
135 | #if ENABLE_FEATURE_SHADOWPASSWDS |
136 | /* add to shadow if necessary */ |
137 | file = fopen_or_warn(bb_path_shadow_file, "a"); |
138 | if (file) { |
139 | //fseek(file, 0, SEEK_END); |
140 | fprintf(file, "%s:!:%u:0:99999:7:::\n", |
141 | pw.pw_name, /* username */ |
142 | (unsigned)(time(NULL) / 86400) /* sp->sp_lstchg */ |
143 | /*0,*/ /* sp->sp_min */ |
144 | /*99999,*/ /* sp->sp_max */ |
145 | /*7*/ /* sp->sp_warn */ |
146 | ); |
147 | fclose(file); |
148 | } |
149 | #endif |
150 | |
151 | /* add to group */ |
152 | /* addgroup should be responsible for dealing w/ gshadow */ |
153 | /* if using a pre-existing group, don't create one */ |
154 | if (!usegroup) |
155 | addgroup_wrapper(&pw); |
156 | |
157 | /* Clear the umask for this process so it doesn't |
158 | * screw up the permissions on the mkdir and chown. */ |
159 | umask(0); |
160 | if (!(option_mask32 & OPT_DONT_MAKE_HOME)) { |
161 | /* Set the owner and group so it is owned by the new user, |
162 | then fix up the permissions to 2755. Can't do it before |
163 | since chown will clear the setgid bit */ |
164 | if (mkdir(pw.pw_dir, 0755) |
165 | || chown(pw.pw_dir, pw.pw_uid, pw.pw_gid) |
166 | || chmod(pw.pw_dir, 02755) /* set setgid bit on homedir */ |
167 | ) { |
168 | bb_simple_perror_msg(pw.pw_dir); |
169 | } |
170 | } |
171 | |
172 | if (!(option_mask32 & OPT_DONT_SET_PASS)) { |
173 | /* interactively set passwd */ |
174 | passwd_wrapper(pw.pw_name); |
175 | } |
176 | |
177 | return 0; |
178 | } |