diff options
author | Scott Garman <scott.a.garman@intel.com> | 2011-05-09 23:02:39 -0700 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2011-06-06 15:58:41 +0100 |
commit | 20ef3425b2788407ac53dff5403c6c10a58bab7f (patch) | |
tree | 63d210b0ad31ef64fae24ff58ae0830edce76604 /meta/recipes-extended/shadow | |
parent | 109aa5c860fa5ba453e2add8fc18096774a40e39 (diff) | |
download | poky-20ef3425b2788407ac53dff5403c6c10a58bab7f.tar.gz |
shadow: add a -native recipe with customized utilities
This adds a -native recipe for the shadow utilities.
The custom --root option allows the the following utilities to be
run within a chroot when invoked under pseudo:
* useradd
* groupadd
* usermod
* groupmod
* userdel
* groupdel
* passwd
* gpasswd
* pwconv
* pwunconv
* grpconv
* grpunconv
They can then be used to manipulate user and group account information
in target sysroots.
useradd was also modified to create home directories recursively when
necessary.
(From OE-Core rev: 37b8c18a3c2f3e77a9810a56a8ee786855ae1ba3)
Signed-off-by: Scott Garman <scott.a.garman@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta/recipes-extended/shadow')
-rw-r--r-- | meta/recipes-extended/shadow/files/add_root_cmd_options.patch | 1296 | ||||
-rw-r--r-- | meta/recipes-extended/shadow/shadow-native_4.1.4.3.bb | 66 |
2 files changed, 1362 insertions, 0 deletions
diff --git a/meta/recipes-extended/shadow/files/add_root_cmd_options.patch b/meta/recipes-extended/shadow/files/add_root_cmd_options.patch new file mode 100644 index 0000000000..db969bbb60 --- /dev/null +++ b/meta/recipes-extended/shadow/files/add_root_cmd_options.patch | |||
@@ -0,0 +1,1296 @@ | |||
1 | Add a --root command option to the following utilties: | ||
2 | |||
3 | * useradd | ||
4 | * groupadd | ||
5 | * usermod | ||
6 | * groupmod | ||
7 | * userdel | ||
8 | * groupdel | ||
9 | * passwd | ||
10 | * gpasswd | ||
11 | * pwconv | ||
12 | * pwunconv | ||
13 | * grpconv | ||
14 | * grpunconv | ||
15 | |||
16 | This option allows the utilities to be chrooted when run under pseudo. | ||
17 | They can then be used to manipulate user and group account information | ||
18 | in target sysroots. | ||
19 | |||
20 | The useradd utility was also modified to create home directories | ||
21 | recursively when necessary. | ||
22 | |||
23 | Upstream-Status: Inappropriate [Other] | ||
24 | Workaround is specific to our build system. | ||
25 | |||
26 | Signed-off-by: Scott Garman <scott.a.garman@intel.com> | ||
27 | |||
28 | diff -urN shadow-4.1.4.3.orig//src/gpasswd.c shadow-4.1.4.3//src/gpasswd.c | ||
29 | --- shadow-4.1.4.3.orig//src/gpasswd.c 2011-02-13 09:58:16.000000000 -0800 | ||
30 | +++ shadow-4.1.4.3//src/gpasswd.c 2011-05-28 17:09:52.346013331 -0700 | ||
31 | @@ -63,6 +63,7 @@ | ||
32 | * (/etc/gshadow present) */ | ||
33 | static bool is_shadowgrp; | ||
34 | #endif | ||
35 | +static const char *newroot = ""; | ||
36 | |||
37 | /* Flags set by options */ | ||
38 | static bool aflg = false; | ||
39 | @@ -97,6 +98,7 @@ | ||
40 | static void usage (void); | ||
41 | static RETSIGTYPE catch_signals (int killed); | ||
42 | static bool is_valid_user_list (const char *users); | ||
43 | +static void process_root_flag (int argc, char **argv); | ||
44 | static void process_flags (int argc, char **argv); | ||
45 | static void check_flags (int argc, int opt_index); | ||
46 | static void open_files (void); | ||
47 | @@ -136,6 +138,7 @@ | ||
48 | "Options:\n" | ||
49 | " -a, --add USER add USER to GROUP\n" | ||
50 | " -d, --delete USER remove USER from GROUP\n" | ||
51 | + " -Q --root CHROOT_DIR directory to chroot into\n" | ||
52 | " -r, --remove-password remove the GROUP's password\n" | ||
53 | " -R, --restrict restrict access to GROUP to its members\n" | ||
54 | " -M, --members USER,... set the list of members of GROUP\n" | ||
55 | @@ -226,6 +229,55 @@ | ||
56 | } | ||
57 | |||
58 | /* | ||
59 | + * process_root_flag - chroot if given the --root option | ||
60 | + * | ||
61 | + * We do this outside of process_flags() because | ||
62 | + * the is_shadow_pwd boolean needs to be set before | ||
63 | + * process_flags(), and if we do need to chroot() we | ||
64 | + * must do so before is_shadow_pwd gets set. | ||
65 | + */ | ||
66 | +static void process_root_flag (int argc, char **argv) | ||
67 | +{ | ||
68 | + /* | ||
69 | + * Parse the command line options. | ||
70 | + */ | ||
71 | + int flag; | ||
72 | + int option_index = 0; | ||
73 | + static struct option long_options[] = { | ||
74 | + {"root", required_argument, NULL, 'Q'}, | ||
75 | + {NULL, 0, NULL, '\0'} | ||
76 | + }; | ||
77 | + | ||
78 | + while ((flag = getopt_long (argc, argv, "a:A:d:gM:Q:rR", long_options, &option_index)) != -1) { | ||
79 | + switch (flag) { | ||
80 | + case 'Q': | ||
81 | + if ('/' != optarg[0]) { | ||
82 | + fprintf (stderr, | ||
83 | + _("%s: invalid chroot path '%s'\n"), | ||
84 | + Prog, optarg); | ||
85 | + exit (E_BAD_ARG); | ||
86 | + } | ||
87 | + newroot = optarg; | ||
88 | + | ||
89 | + if (access (newroot, F_OK) != 0) { | ||
90 | + fprintf(stderr, | ||
91 | + _("%s: chroot directory %s does not exist\n"), | ||
92 | + Prog, newroot); | ||
93 | + exit (E_BAD_ARG); | ||
94 | + } | ||
95 | + if ( chroot(newroot) != 0 ) { | ||
96 | + fprintf(stderr, | ||
97 | + _("%s: unable to chroot to directory %s\n"), | ||
98 | + Prog, newroot); | ||
99 | + exit (E_BAD_ARG); | ||
100 | + } | ||
101 | + break; | ||
102 | + /* no-op on everything else - they will be hanled by process_flags() */ | ||
103 | + } | ||
104 | + } | ||
105 | +} | ||
106 | + | ||
107 | +/* | ||
108 | * process_flags - process the command line options and arguments | ||
109 | */ | ||
110 | static void process_flags (int argc, char **argv) | ||
111 | @@ -235,6 +287,7 @@ | ||
112 | static struct option long_options[] = { | ||
113 | {"add", required_argument, NULL, 'a'}, | ||
114 | {"delete", required_argument, NULL, 'd'}, | ||
115 | + {"root", required_argument, NULL, 'Q'}, | ||
116 | {"remove-password", no_argument, NULL, 'r'}, | ||
117 | {"restrict", no_argument, NULL, 'R'}, | ||
118 | {"administrators", required_argument, NULL, 'A'}, | ||
119 | @@ -242,7 +295,7 @@ | ||
120 | {NULL, 0, NULL, '\0'} | ||
121 | }; | ||
122 | |||
123 | - while ((flag = getopt_long (argc, argv, "a:A:d:gM:rR", long_options, &option_index)) != -1) { | ||
124 | + while ((flag = getopt_long (argc, argv, "a:A:d:gM:Q:rR", long_options, &option_index)) != -1) { | ||
125 | switch (flag) { | ||
126 | case 'a': /* add a user */ | ||
127 | aflg = true; | ||
128 | @@ -283,6 +336,9 @@ | ||
129 | } | ||
130 | Mflg = true; | ||
131 | break; | ||
132 | + case 'Q': | ||
133 | + /* no-op since we handled this in process_root_flag() earlier */ | ||
134 | + break; | ||
135 | case 'r': /* remove group password */ | ||
136 | rflg = true; | ||
137 | break; | ||
138 | @@ -995,6 +1051,8 @@ | ||
139 | setbuf (stdout, NULL); | ||
140 | setbuf (stderr, NULL); | ||
141 | |||
142 | + process_root_flag (argc, argv); | ||
143 | + | ||
144 | #ifdef SHADOWGRP | ||
145 | is_shadowgrp = sgr_file_present (); | ||
146 | #endif | ||
147 | diff -urN shadow-4.1.4.3.orig//src/groupadd.c shadow-4.1.4.3//src/groupadd.c | ||
148 | --- shadow-4.1.4.3.orig//src/groupadd.c 2011-02-13 09:58:16.000000000 -0800 | ||
149 | +++ shadow-4.1.4.3//src/groupadd.c 2011-05-28 17:09:52.346013331 -0700 | ||
150 | @@ -76,6 +76,7 @@ | ||
151 | static gid_t group_id; | ||
152 | static /*@null@*/char *group_passwd; | ||
153 | static /*@null@*/char *empty_list = NULL; | ||
154 | +static const char *newroot = ""; | ||
155 | |||
156 | static bool oflg = false; /* permit non-unique group ID to be specified with -g */ | ||
157 | static bool gflg = false; /* ID value for the new group */ | ||
158 | @@ -120,6 +121,7 @@ | ||
159 | (void) fputs (_(" -o, --non-unique allow to create groups with duplicate\n" | ||
160 | " (non-unique) GID\n"), stderr); | ||
161 | (void) fputs (_(" -p, --password PASSWORD use this encrypted password for the new group\n"), stderr); | ||
162 | + (void) fputs (_(" -R, --root CHROOT_DIR directory to chroot into\n"), stderr); | ||
163 | (void) fputs (_(" -r, --system create a system account\n"), stderr); | ||
164 | (void) fputs ("\n", stderr); | ||
165 | exit (E_USAGE); | ||
166 | @@ -383,12 +385,13 @@ | ||
167 | {"key", required_argument, NULL, 'K'}, | ||
168 | {"non-unique", no_argument, NULL, 'o'}, | ||
169 | {"password", required_argument, NULL, 'p'}, | ||
170 | + {"root", required_argument, NULL, 'R'}, | ||
171 | {"system", no_argument, NULL, 'r'}, | ||
172 | {NULL, 0, NULL, '\0'} | ||
173 | }; | ||
174 | |||
175 | while ((c = | ||
176 | - getopt_long (argc, argv, "fg:hK:op:r", long_options, | ||
177 | + getopt_long (argc, argv, "fg:hK:op:R:r", long_options, | ||
178 | &option_index)) != -1) { | ||
179 | switch (c) { | ||
180 | case 'f': | ||
181 | @@ -440,6 +443,28 @@ | ||
182 | pflg = true; | ||
183 | group_passwd = optarg; | ||
184 | break; | ||
185 | + case 'R': | ||
186 | + if ('/' != optarg[0]) { | ||
187 | + fprintf (stderr, | ||
188 | + _("%s: invalid chroot path '%s'\n"), | ||
189 | + Prog, optarg); | ||
190 | + exit (E_BAD_ARG); | ||
191 | + } | ||
192 | + newroot = optarg; | ||
193 | + | ||
194 | + if (access (newroot, F_OK) != 0) { | ||
195 | + fprintf(stderr, | ||
196 | + _("%s: chroot directory %s does not exist\n"), | ||
197 | + Prog, newroot); | ||
198 | + exit (E_BAD_ARG); | ||
199 | + } | ||
200 | + if ( chroot(newroot) != 0 ) { | ||
201 | + fprintf(stderr, | ||
202 | + _("%s: unable to chroot to directory %s\n"), | ||
203 | + Prog, newroot); | ||
204 | + exit (E_BAD_ARG); | ||
205 | + } | ||
206 | + break; | ||
207 | case 'r': | ||
208 | rflg = true; | ||
209 | break; | ||
210 | diff -urN shadow-4.1.4.3.orig//src/groupdel.c shadow-4.1.4.3//src/groupdel.c | ||
211 | --- shadow-4.1.4.3.orig//src/groupdel.c 2011-02-13 09:58:16.000000000 -0800 | ||
212 | +++ shadow-4.1.4.3//src/groupdel.c 2011-05-28 17:09:52.346013331 -0700 | ||
213 | @@ -36,6 +36,7 @@ | ||
214 | |||
215 | #include <ctype.h> | ||
216 | #include <fcntl.h> | ||
217 | +#include <getopt.h> | ||
218 | #include <grp.h> | ||
219 | #include <pwd.h> | ||
220 | #ifdef ACCT_TOOLS_SETUID | ||
221 | @@ -59,6 +60,7 @@ | ||
222 | |||
223 | static char *group_name; | ||
224 | static gid_t group_id = -1; | ||
225 | +static const char *newroot = ""; | ||
226 | |||
227 | #ifdef SHADOWGRP | ||
228 | static bool is_shadow_grp; | ||
229 | @@ -70,12 +72,14 @@ | ||
230 | /*@-exitarg@*/ | ||
231 | #define E_SUCCESS 0 /* success */ | ||
232 | #define E_USAGE 2 /* invalid command syntax */ | ||
233 | +#define E_BAD_ARG 3 /* invalid argument to option */ | ||
234 | #define E_NOTFOUND 6 /* specified group doesn't exist */ | ||
235 | #define E_GROUP_BUSY 8 /* can't remove user's primary group */ | ||
236 | #define E_GRP_UPDATE 10 /* can't update group file */ | ||
237 | |||
238 | /* local function prototypes */ | ||
239 | static void usage (void); | ||
240 | +static void process_flags (int argc, char **argv); | ||
241 | static void grp_update (void); | ||
242 | static void close_files (void); | ||
243 | static void open_files (void); | ||
244 | @@ -86,11 +90,78 @@ | ||
245 | */ | ||
246 | static void usage (void) | ||
247 | { | ||
248 | - fputs (_("Usage: groupdel group\n"), stderr); | ||
249 | + (void) fprintf (stderr, | ||
250 | + _("Usage: groupdel [options]\n" | ||
251 | + "\n" | ||
252 | + "Options:\n"), | ||
253 | + Prog); | ||
254 | + (void) fputs (_(" -g, --group GROUP group name to delete\n"), stderr); | ||
255 | + (void) fputs (_(" -h, --help display this help message and exit\n"), stderr); | ||
256 | + (void) fputs (_(" -R, --root CHROOT_DIR directory to chroot into\n"), stderr); | ||
257 | + (void) fputs ("\n", stderr); | ||
258 | exit (E_USAGE); | ||
259 | } | ||
260 | |||
261 | /* | ||
262 | + * process_flags - perform command line argument setting | ||
263 | + * | ||
264 | + * process_flags() interprets the command line arguments and sets | ||
265 | + * the values that the user will be created with accordingly. The | ||
266 | + * values are checked for sanity. | ||
267 | + */ | ||
268 | +static void process_flags (int argc, char **argv) | ||
269 | +{ | ||
270 | + { | ||
271 | + /* | ||
272 | + * Parse the command line options. | ||
273 | + */ | ||
274 | + int c; | ||
275 | + static struct option long_options[] = { | ||
276 | + {"group", required_argument, NULL, 'g'}, | ||
277 | + {"help", no_argument, NULL, 'h'}, | ||
278 | + {"root", required_argument, NULL, 'R'}, | ||
279 | + {NULL, 0, NULL, '\0'} | ||
280 | + }; | ||
281 | + while ((c = getopt_long (argc, argv, | ||
282 | + "g:R:", | ||
283 | + long_options, NULL)) != -1) { | ||
284 | + switch (c) { | ||
285 | + case 'g': | ||
286 | + group_name = optarg; | ||
287 | + break; | ||
288 | + case 'h': | ||
289 | + usage (); | ||
290 | + break; | ||
291 | + case 'R': | ||
292 | + if ('/' != optarg[0]) { | ||
293 | + fprintf (stderr, | ||
294 | + _("%s: invalid chroot path '%s'\n"), | ||
295 | + Prog, optarg); | ||
296 | + exit (E_BAD_ARG); | ||
297 | + } | ||
298 | + newroot = optarg; | ||
299 | + | ||
300 | + if (access (newroot, F_OK) != 0) { | ||
301 | + fprintf(stderr, | ||
302 | + _("%s: chroot directory %s does not exist\n"), | ||
303 | + Prog, newroot); | ||
304 | + exit (E_BAD_ARG); | ||
305 | + } | ||
306 | + if ( chroot(newroot) != 0 ) { | ||
307 | + fprintf(stderr, | ||
308 | + _("%s: unable to chroot to directory %s\n"), | ||
309 | + Prog, newroot); | ||
310 | + exit (E_BAD_ARG); | ||
311 | + } | ||
312 | + break; | ||
313 | + default: | ||
314 | + usage (); | ||
315 | + } | ||
316 | + } | ||
317 | + } | ||
318 | +} | ||
319 | + | ||
320 | +/* | ||
321 | * grp_update - update group file entries | ||
322 | * | ||
323 | * grp_update() writes the new records to the group files. | ||
324 | @@ -328,14 +399,14 @@ | ||
325 | (void) bindtextdomain (PACKAGE, LOCALEDIR); | ||
326 | (void) textdomain (PACKAGE); | ||
327 | |||
328 | - if (argc != 2) { | ||
329 | + if (argc == 1) { | ||
330 | usage (); | ||
331 | } | ||
332 | |||
333 | - group_name = argv[1]; | ||
334 | - | ||
335 | OPENLOG ("groupdel"); | ||
336 | |||
337 | + process_flags (argc, argv); | ||
338 | + | ||
339 | #ifdef ACCT_TOOLS_SETUID | ||
340 | #ifdef USE_PAM | ||
341 | { | ||
342 | diff -urN shadow-4.1.4.3.orig//src/groupmod.c shadow-4.1.4.3//src/groupmod.c | ||
343 | --- shadow-4.1.4.3.orig//src/groupmod.c 2011-02-13 09:58:16.000000000 -0800 | ||
344 | +++ shadow-4.1.4.3//src/groupmod.c 2011-05-28 17:09:52.346013331 -0700 | ||
345 | @@ -79,6 +79,7 @@ | ||
346 | static char *group_passwd; | ||
347 | static gid_t group_id; | ||
348 | static gid_t group_newid; | ||
349 | +static char *newroot = ""; | ||
350 | |||
351 | struct cleanup_info_mod info_passwd; | ||
352 | struct cleanup_info_mod info_group; | ||
353 | @@ -126,6 +127,7 @@ | ||
354 | (void) fputs (_(" -o, --non-unique allow to use a duplicate (non-unique) GID\n"), stderr); | ||
355 | (void) fputs (_(" -p, --password PASSWORD change the password to this (encrypted)\n" | ||
356 | " PASSWORD\n"), stderr); | ||
357 | + (void) fputs (_(" -R, --root CHROOT_DIR directory to chroot into\n"), stderr); | ||
358 | (void) fputs ("\n", stderr); | ||
359 | exit (E_USAGE); | ||
360 | } | ||
361 | @@ -346,10 +348,11 @@ | ||
362 | {"new-name", required_argument, NULL, 'n'}, | ||
363 | {"non-unique", no_argument, NULL, 'o'}, | ||
364 | {"password", required_argument, NULL, 'p'}, | ||
365 | + {"root", required_argument, NULL, 'R'}, | ||
366 | {NULL, 0, NULL, '\0'} | ||
367 | }; | ||
368 | while ((c = | ||
369 | - getopt_long (argc, argv, "g:hn:op:", | ||
370 | + getopt_long (argc, argv, "g:hn:op:R:", | ||
371 | long_options, &option_index)) != -1) { | ||
372 | switch (c) { | ||
373 | case 'g': | ||
374 | @@ -373,6 +376,28 @@ | ||
375 | group_passwd = optarg; | ||
376 | pflg = true; | ||
377 | break; | ||
378 | + case 'R': | ||
379 | + if ('/' != optarg[0]) { | ||
380 | + fprintf (stderr, | ||
381 | + _("%s: invalid chroot path '%s'\n"), | ||
382 | + Prog, optarg); | ||
383 | + exit (E_BAD_ARG); | ||
384 | + } | ||
385 | + newroot = optarg; | ||
386 | + | ||
387 | + if (access (newroot, F_OK) != 0) { | ||
388 | + fprintf(stderr, | ||
389 | + _("%s: chroot directory %s does not exist\n"), | ||
390 | + Prog, newroot); | ||
391 | + exit (E_BAD_ARG); | ||
392 | + } | ||
393 | + if ( chroot(newroot) != 0 ) { | ||
394 | + fprintf(stderr, | ||
395 | + _("%s: unable to chroot to directory %s\n"), | ||
396 | + Prog, newroot); | ||
397 | + exit (E_BAD_ARG); | ||
398 | + } | ||
399 | + break; | ||
400 | default: | ||
401 | usage (); | ||
402 | } | ||
403 | diff -urN shadow-4.1.4.3.orig//src/grpconv.c shadow-4.1.4.3//src/grpconv.c | ||
404 | --- shadow-4.1.4.3.orig//src/grpconv.c 2011-02-13 09:58:16.000000000 -0800 | ||
405 | +++ shadow-4.1.4.3//src/grpconv.c 2011-05-28 17:09:52.346013331 -0700 | ||
406 | @@ -39,6 +39,7 @@ | ||
407 | |||
408 | #include <errno.h> | ||
409 | #include <fcntl.h> | ||
410 | +#include <getopt.h> | ||
411 | #include <grp.h> | ||
412 | #include <stdio.h> | ||
413 | #include <stdlib.h> | ||
414 | @@ -50,6 +51,14 @@ | ||
415 | #ifdef SHADOWGRP | ||
416 | #include "groupio.h" | ||
417 | #include "sgroupio.h" | ||
418 | + | ||
419 | +/* | ||
420 | + * exit status values | ||
421 | + */ | ||
422 | +/*@-exitarg@*/ | ||
423 | +#define E_USAGE 2 /* invalid command syntax */ | ||
424 | +#define E_BAD_ARG 3 /* invalid argument to option */ | ||
425 | + | ||
426 | /* | ||
427 | * Global variables | ||
428 | */ | ||
429 | @@ -57,9 +66,12 @@ | ||
430 | |||
431 | static bool gr_locked = false; | ||
432 | static bool sgr_locked = false; | ||
433 | +static const char *newroot = ""; | ||
434 | |||
435 | /* local function prototypes */ | ||
436 | static void fail_exit (int status); | ||
437 | +static void usage (void); | ||
438 | +static void process_flags (int argc, char **argv); | ||
439 | |||
440 | static void fail_exit (int status) | ||
441 | { | ||
442 | @@ -82,6 +94,77 @@ | ||
443 | exit (status); | ||
444 | } | ||
445 | |||
446 | +/* | ||
447 | + * usage - display usage message and exit | ||
448 | + */ | ||
449 | +static void usage (void) | ||
450 | +{ | ||
451 | + (void) fprintf (stderr, | ||
452 | + _("Usage: grpconv [options]\n" | ||
453 | + "\n" | ||
454 | + "Options:\n"), | ||
455 | + Prog); | ||
456 | + (void) fputs (_(" -h, --help display this help message and exit\n"), stderr); | ||
457 | + (void) fputs (_(" -R, --root CHROOT_DIR directory to chroot into\n"), stderr); | ||
458 | + (void) fputs ("\n", stderr); | ||
459 | + exit (E_USAGE); | ||
460 | +} | ||
461 | + | ||
462 | +/* | ||
463 | + * process_flags - perform command line argument setting | ||
464 | + * | ||
465 | + * process_flags() interprets the command line arguments and sets | ||
466 | + * the values that the user will be created with accordingly. The | ||
467 | + * values are checked for sanity. | ||
468 | + */ | ||
469 | +static void process_flags (int argc, char **argv) | ||
470 | +{ | ||
471 | + { | ||
472 | + /* | ||
473 | + * Parse the command line options. | ||
474 | + */ | ||
475 | + int c; | ||
476 | + static struct option long_options[] = { | ||
477 | + {"help", no_argument, NULL, 'h'}, | ||
478 | + {"root", required_argument, NULL, 'R'}, | ||
479 | + {NULL, 0, NULL, '\0'} | ||
480 | + }; | ||
481 | + while ((c = getopt_long (argc, argv, | ||
482 | + "R:", | ||
483 | + long_options, NULL)) != -1) { | ||
484 | + switch (c) { | ||
485 | + case 'h': | ||
486 | + usage (); | ||
487 | + break; | ||
488 | + case 'R': | ||
489 | + if ('/' != optarg[0]) { | ||
490 | + fprintf (stderr, | ||
491 | + _("%s: invalid chroot path '%s'\n"), | ||
492 | + Prog, optarg); | ||
493 | + exit (E_BAD_ARG); | ||
494 | + } | ||
495 | + newroot = optarg; | ||
496 | + | ||
497 | + if (access (newroot, F_OK) != 0) { | ||
498 | + fprintf(stderr, | ||
499 | + _("%s: chroot directory %s does not exist\n"), | ||
500 | + Prog, newroot); | ||
501 | + exit (E_BAD_ARG); | ||
502 | + } | ||
503 | + if ( chroot(newroot) != 0 ) { | ||
504 | + fprintf(stderr, | ||
505 | + _("%s: unable to chroot to directory %s\n"), | ||
506 | + Prog, newroot); | ||
507 | + exit (E_BAD_ARG); | ||
508 | + } | ||
509 | + break; | ||
510 | + default: | ||
511 | + usage (); | ||
512 | + } | ||
513 | + } | ||
514 | + } | ||
515 | +} | ||
516 | + | ||
517 | int main (int argc, char **argv) | ||
518 | { | ||
519 | const struct group *gr; | ||
520 | @@ -100,6 +183,8 @@ | ||
521 | |||
522 | OPENLOG ("grpconv"); | ||
523 | |||
524 | + process_flags (argc, argv); | ||
525 | + | ||
526 | if (gr_lock () == 0) { | ||
527 | fprintf (stderr, | ||
528 | _("%s: cannot lock %s; try again later.\n"), | ||
529 | diff -urN shadow-4.1.4.3.orig//src/grpunconv.c shadow-4.1.4.3//src/grpunconv.c | ||
530 | --- shadow-4.1.4.3.orig//src/grpunconv.c 2011-02-13 09:58:16.000000000 -0800 | ||
531 | +++ shadow-4.1.4.3//src/grpunconv.c 2011-05-28 17:09:52.346013331 -0700 | ||
532 | @@ -43,6 +43,7 @@ | ||
533 | #include <stdlib.h> | ||
534 | #include <string.h> | ||
535 | #include <fcntl.h> | ||
536 | +#include <getopt.h> | ||
537 | #include <time.h> | ||
538 | #include <unistd.h> | ||
539 | #include <grp.h> | ||
540 | @@ -51,6 +52,14 @@ | ||
541 | #ifdef SHADOWGRP | ||
542 | #include "groupio.h" | ||
543 | #include "sgroupio.h" | ||
544 | + | ||
545 | +/* | ||
546 | + * exit status values | ||
547 | + */ | ||
548 | +/*@-exitarg@*/ | ||
549 | +#define E_USAGE 2 /* invalid command syntax */ | ||
550 | +#define E_BAD_ARG 3 /* invalid argument to option */ | ||
551 | + | ||
552 | /* | ||
553 | * Global variables | ||
554 | */ | ||
555 | @@ -58,9 +67,12 @@ | ||
556 | |||
557 | static bool gr_locked = false; | ||
558 | static bool sgr_locked = false; | ||
559 | +static const char *newroot = ""; | ||
560 | |||
561 | /* local function prototypes */ | ||
562 | static void fail_exit (int status); | ||
563 | +static void usage (void); | ||
564 | +static void process_flags (int argc, char **argv); | ||
565 | |||
566 | static void fail_exit (int status) | ||
567 | { | ||
568 | @@ -83,6 +95,77 @@ | ||
569 | exit (status); | ||
570 | } | ||
571 | |||
572 | +/* | ||
573 | + * usage - display usage message and exit | ||
574 | + */ | ||
575 | +static void usage (void) | ||
576 | +{ | ||
577 | + (void) fprintf (stderr, | ||
578 | + _("Usage: grpunconv [options]\n" | ||
579 | + "\n" | ||
580 | + "Options:\n"), | ||
581 | + Prog); | ||
582 | + (void) fputs (_(" -h, --help display this help message and exit\n"), stderr); | ||
583 | + (void) fputs (_(" -R, --root CHROOT_DIR directory to chroot into\n"), stderr); | ||
584 | + (void) fputs ("\n", stderr); | ||
585 | + exit (E_USAGE); | ||
586 | +} | ||
587 | + | ||
588 | +/* | ||
589 | + * process_flags - perform command line argument setting | ||
590 | + * | ||
591 | + * process_flags() interprets the command line arguments and sets | ||
592 | + * the values that the user will be created with accordingly. The | ||
593 | + * values are checked for sanity. | ||
594 | + */ | ||
595 | +static void process_flags (int argc, char **argv) | ||
596 | +{ | ||
597 | + { | ||
598 | + /* | ||
599 | + * Parse the command line options. | ||
600 | + */ | ||
601 | + int c; | ||
602 | + static struct option long_options[] = { | ||
603 | + {"help", no_argument, NULL, 'h'}, | ||
604 | + {"root", required_argument, NULL, 'R'}, | ||
605 | + {NULL, 0, NULL, '\0'} | ||
606 | + }; | ||
607 | + while ((c = getopt_long (argc, argv, | ||
608 | + "R:", | ||
609 | + long_options, NULL)) != -1) { | ||
610 | + switch (c) { | ||
611 | + case 'h': | ||
612 | + usage (); | ||
613 | + break; | ||
614 | + case 'R': | ||
615 | + if ('/' != optarg[0]) { | ||
616 | + fprintf (stderr, | ||
617 | + _("%s: invalid chroot path '%s'\n"), | ||
618 | + Prog, optarg); | ||
619 | + exit (E_BAD_ARG); | ||
620 | + } | ||
621 | + newroot = optarg; | ||
622 | + | ||
623 | + if (access (newroot, F_OK) != 0) { | ||
624 | + fprintf(stderr, | ||
625 | + _("%s: chroot directory %s does not exist\n"), | ||
626 | + Prog, newroot); | ||
627 | + exit (E_BAD_ARG); | ||
628 | + } | ||
629 | + if ( chroot(newroot) != 0 ) { | ||
630 | + fprintf(stderr, | ||
631 | + _("%s: unable to chroot to directory %s\n"), | ||
632 | + Prog, newroot); | ||
633 | + exit (E_BAD_ARG); | ||
634 | + } | ||
635 | + break; | ||
636 | + default: | ||
637 | + usage (); | ||
638 | + } | ||
639 | + } | ||
640 | + } | ||
641 | +} | ||
642 | + | ||
643 | int main (int argc, char **argv) | ||
644 | { | ||
645 | const struct group *gr; | ||
646 | @@ -100,6 +183,8 @@ | ||
647 | |||
648 | OPENLOG ("grpunconv"); | ||
649 | |||
650 | + process_flags (argc, argv); | ||
651 | + | ||
652 | if (sgr_file_present () == 0) { | ||
653 | exit (0); /* no /etc/gshadow, nothing to do */ | ||
654 | } | ||
655 | diff -urN shadow-4.1.4.3.orig//src/passwd.c shadow-4.1.4.3//src/passwd.c | ||
656 | --- shadow-4.1.4.3.orig//src/passwd.c 2011-02-13 09:58:16.000000000 -0800 | ||
657 | +++ shadow-4.1.4.3//src/passwd.c 2011-05-28 17:09:52.346013331 -0700 | ||
658 | @@ -75,6 +75,7 @@ | ||
659 | static char *name; /* The name of user whose password is being changed */ | ||
660 | static char *myname; /* The current user's name */ | ||
661 | static bool amroot; /* The caller's real UID was 0 */ | ||
662 | +static const char *newroot = ""; | ||
663 | |||
664 | static bool | ||
665 | aflg = false, /* -a - show status for all users */ | ||
666 | @@ -174,6 +175,7 @@ | ||
667 | " -n, --mindays MIN_DAYS set minimum number of days before password\n" | ||
668 | " change to MIN_DAYS\n" | ||
669 | " -q, --quiet quiet mode\n" | ||
670 | + " -R, --root CHROOT_DIR directory to chroot into\n" | ||
671 | " -r, --repository REPOSITORY change password in REPOSITORY repository\n" | ||
672 | " -S, --status report password status on the named account\n" | ||
673 | " -u, --unlock unlock the password of the named account\n" | ||
674 | @@ -803,6 +805,7 @@ | ||
675 | {"lock", no_argument, NULL, 'l'}, | ||
676 | {"mindays", required_argument, NULL, 'n'}, | ||
677 | {"quiet", no_argument, NULL, 'q'}, | ||
678 | + {"root", required_argument, NULL, 'R'}, | ||
679 | {"repository", required_argument, NULL, 'r'}, | ||
680 | {"status", no_argument, NULL, 'S'}, | ||
681 | {"unlock", no_argument, NULL, 'u'}, | ||
682 | @@ -811,7 +814,7 @@ | ||
683 | {NULL, 0, NULL, '\0'} | ||
684 | }; | ||
685 | |||
686 | - while ((c = getopt_long (argc, argv, "adei:kln:qr:Suw:x:", | ||
687 | + while ((c = getopt_long (argc, argv, "adei:kln:qR:r:Suw:x:", | ||
688 | long_options, &option_index)) != -1) { | ||
689 | switch (c) { | ||
690 | case 'a': | ||
691 | @@ -858,6 +861,28 @@ | ||
692 | case 'q': | ||
693 | qflg = true; /* ok for users */ | ||
694 | break; | ||
695 | + case 'R': | ||
696 | + if ('/' != optarg[0]) { | ||
697 | + fprintf (stderr, | ||
698 | + _("%s: invalid chroot path '%s'\n"), | ||
699 | + Prog, optarg); | ||
700 | + exit (E_BAD_ARG); | ||
701 | + } | ||
702 | + newroot = optarg; | ||
703 | + | ||
704 | + if (access (newroot, F_OK) != 0) { | ||
705 | + fprintf(stderr, | ||
706 | + _("%s: chroot directory %s does not exist\n"), | ||
707 | + Prog, newroot); | ||
708 | + exit (E_BAD_ARG); | ||
709 | + } | ||
710 | + if ( chroot(newroot) != 0 ) { | ||
711 | + fprintf(stderr, | ||
712 | + _("%s: unable to chroot to directory %s\n"), | ||
713 | + Prog, newroot); | ||
714 | + exit (E_BAD_ARG); | ||
715 | + } | ||
716 | + break; | ||
717 | case 'r': | ||
718 | /* -r repository (files|nis|nisplus) */ | ||
719 | /* only "files" supported for now */ | ||
720 | diff -urN shadow-4.1.4.3.orig//src/pwconv.c shadow-4.1.4.3//src/pwconv.c | ||
721 | --- shadow-4.1.4.3.orig//src/pwconv.c 2011-02-13 09:58:16.000000000 -0800 | ||
722 | +++ shadow-4.1.4.3//src/pwconv.c 2011-05-28 17:09:52.346013331 -0700 | ||
723 | @@ -59,6 +59,7 @@ | ||
724 | |||
725 | #include <errno.h> | ||
726 | #include <fcntl.h> | ||
727 | +#include <getopt.h> | ||
728 | #include <pwd.h> | ||
729 | #include <stdio.h> | ||
730 | #include <stdlib.h> | ||
731 | @@ -79,6 +80,7 @@ | ||
732 | #define E_SUCCESS 0 /* success */ | ||
733 | #define E_NOPERM 1 /* permission denied */ | ||
734 | #define E_USAGE 2 /* invalid command syntax */ | ||
735 | +#define E_BAD_ARG 3 /* invalid argument to option */ | ||
736 | #define E_FAILURE 3 /* unexpected failure, nothing done */ | ||
737 | #define E_MISSING 4 /* unexpected failure, passwd file missing */ | ||
738 | #define E_PWDBUSY 5 /* passwd file(s) busy */ | ||
739 | @@ -90,9 +92,12 @@ | ||
740 | |||
741 | static bool spw_locked = false; | ||
742 | static bool pw_locked = false; | ||
743 | +static const char *newroot = ""; | ||
744 | |||
745 | /* local function prototypes */ | ||
746 | static void fail_exit (int status); | ||
747 | +static void usage (void); | ||
748 | +static void process_flags (int argc, char **argv); | ||
749 | |||
750 | static void fail_exit (int status) | ||
751 | { | ||
752 | @@ -115,6 +120,77 @@ | ||
753 | exit (status); | ||
754 | } | ||
755 | |||
756 | +/* | ||
757 | + * usage - display usage message and exit | ||
758 | + */ | ||
759 | +static void usage (void) | ||
760 | +{ | ||
761 | + (void) fprintf (stderr, | ||
762 | + _("Usage: pwconv [options]\n" | ||
763 | + "\n" | ||
764 | + "Options:\n"), | ||
765 | + Prog); | ||
766 | + (void) fputs (_(" -h, --help display this help message and exit\n"), stderr); | ||
767 | + (void) fputs (_(" -R, --root CHROOT_DIR directory to chroot into\n"), stderr); | ||
768 | + (void) fputs ("\n", stderr); | ||
769 | + exit (E_USAGE); | ||
770 | +} | ||
771 | + | ||
772 | +/* | ||
773 | + * process_flags - perform command line argument setting | ||
774 | + * | ||
775 | + * process_flags() interprets the command line arguments and sets | ||
776 | + * the values that the user will be created with accordingly. The | ||
777 | + * values are checked for sanity. | ||
778 | + */ | ||
779 | +static void process_flags (int argc, char **argv) | ||
780 | +{ | ||
781 | + { | ||
782 | + /* | ||
783 | + * Parse the command line options. | ||
784 | + */ | ||
785 | + int c; | ||
786 | + static struct option long_options[] = { | ||
787 | + {"help", no_argument, NULL, 'h'}, | ||
788 | + {"root", required_argument, NULL, 'R'}, | ||
789 | + {NULL, 0, NULL, '\0'} | ||
790 | + }; | ||
791 | + while ((c = getopt_long (argc, argv, | ||
792 | + "R:", | ||
793 | + long_options, NULL)) != -1) { | ||
794 | + switch (c) { | ||
795 | + case 'h': | ||
796 | + usage (); | ||
797 | + break; | ||
798 | + case 'R': | ||
799 | + if ('/' != optarg[0]) { | ||
800 | + fprintf (stderr, | ||
801 | + _("%s: invalid chroot path '%s'\n"), | ||
802 | + Prog, optarg); | ||
803 | + exit (E_BAD_ARG); | ||
804 | + } | ||
805 | + newroot = optarg; | ||
806 | + | ||
807 | + if (access (newroot, F_OK) != 0) { | ||
808 | + fprintf(stderr, | ||
809 | + _("%s: chroot directory %s does not exist\n"), | ||
810 | + Prog, newroot); | ||
811 | + exit (E_BAD_ARG); | ||
812 | + } | ||
813 | + if ( chroot(newroot) != 0 ) { | ||
814 | + fprintf(stderr, | ||
815 | + _("%s: unable to chroot to directory %s\n"), | ||
816 | + Prog, newroot); | ||
817 | + exit (E_BAD_ARG); | ||
818 | + } | ||
819 | + break; | ||
820 | + default: | ||
821 | + usage (); | ||
822 | + } | ||
823 | + } | ||
824 | + } | ||
825 | +} | ||
826 | + | ||
827 | int main (int argc, char **argv) | ||
828 | { | ||
829 | const struct passwd *pw; | ||
830 | @@ -122,9 +198,6 @@ | ||
831 | const struct spwd *sp; | ||
832 | struct spwd spent; | ||
833 | |||
834 | - if (1 != argc) { | ||
835 | - (void) fputs (_("Usage: pwconv\n"), stderr); | ||
836 | - } | ||
837 | Prog = Basename (argv[0]); | ||
838 | |||
839 | (void) setlocale (LC_ALL, ""); | ||
840 | @@ -133,6 +206,8 @@ | ||
841 | |||
842 | OPENLOG ("pwconv"); | ||
843 | |||
844 | + process_flags (argc, argv); | ||
845 | + | ||
846 | if (pw_lock () == 0) { | ||
847 | fprintf (stderr, | ||
848 | _("%s: cannot lock %s; try again later.\n"), | ||
849 | diff -urN shadow-4.1.4.3.orig//src/pwunconv.c shadow-4.1.4.3//src/pwunconv.c | ||
850 | --- shadow-4.1.4.3.orig//src/pwunconv.c 2011-02-13 09:58:16.000000000 -0800 | ||
851 | +++ shadow-4.1.4.3//src/pwunconv.c 2011-05-28 17:09:52.356013600 -0700 | ||
852 | @@ -35,6 +35,7 @@ | ||
853 | #ident "$Id: pwunconv.c 2852 2009-04-30 21:44:35Z nekral-guest $" | ||
854 | |||
855 | #include <fcntl.h> | ||
856 | +#include <getopt.h> | ||
857 | #include <pwd.h> | ||
858 | #include <stdio.h> | ||
859 | #include <sys/types.h> | ||
860 | @@ -46,15 +47,24 @@ | ||
861 | #include "shadowio.h" | ||
862 | |||
863 | /* | ||
864 | + * exit status values | ||
865 | + */ | ||
866 | +/*@-exitarg@*/ | ||
867 | +#define E_USAGE 2 /* invalid command syntax */ | ||
868 | +#define E_BAD_ARG 3 /* invalid argument to option */ | ||
869 | +/* | ||
870 | * Global variables | ||
871 | */ | ||
872 | char *Prog; | ||
873 | |||
874 | static bool spw_locked = false; | ||
875 | static bool pw_locked = false; | ||
876 | +static const char *newroot = ""; | ||
877 | |||
878 | /* local function prototypes */ | ||
879 | static void fail_exit (int status); | ||
880 | +static void usage (void); | ||
881 | +static void process_flags (int argc, char **argv); | ||
882 | |||
883 | static void fail_exit (int status) | ||
884 | { | ||
885 | @@ -75,6 +85,76 @@ | ||
886 | exit (status); | ||
887 | } | ||
888 | |||
889 | +/* | ||
890 | + * usage - display usage message and exit | ||
891 | + */ | ||
892 | +static void usage (void) | ||
893 | +{ | ||
894 | + (void) fprintf (stderr, | ||
895 | + _("Usage: pwunconv [options]\n" | ||
896 | + "\n" | ||
897 | + "Options:\n"), | ||
898 | + Prog); | ||
899 | + (void) fputs (_(" -h, --help display this help message and exit\n"), stderr); | ||
900 | + (void) fputs (_(" -R, --root CHROOT_DIR directory to chroot into\n"), stderr); | ||
901 | + (void) fputs ("\n", stderr); | ||
902 | + exit (E_USAGE); | ||
903 | +} | ||
904 | + | ||
905 | +/* | ||
906 | + * process_flags - perform command line argument setting | ||
907 | + * | ||
908 | + * process_flags() interprets the command line arguments and sets | ||
909 | + * the values that the user will be created with accordingly. The | ||
910 | + * values are checked for sanity. | ||
911 | + */ | ||
912 | +static void process_flags (int argc, char **argv) | ||
913 | +{ | ||
914 | + { | ||
915 | + /* | ||
916 | + * Parse the command line options. | ||
917 | + */ | ||
918 | + int c; | ||
919 | + static struct option long_options[] = { | ||
920 | + {"help", no_argument, NULL, 'h'}, | ||
921 | + {"root", required_argument, NULL, 'R'}, | ||
922 | + {NULL, 0, NULL, '\0'} | ||
923 | + }; | ||
924 | + while ((c = getopt_long (argc, argv, | ||
925 | + "R:", | ||
926 | + long_options, NULL)) != -1) { | ||
927 | + switch (c) { | ||
928 | + case 'h': | ||
929 | + usage (); | ||
930 | + break; | ||
931 | + case 'R': | ||
932 | + if ('/' != optarg[0]) { | ||
933 | + fprintf (stderr, | ||
934 | + _("%s: invalid chroot path '%s'\n"), | ||
935 | + Prog, optarg); | ||
936 | + exit (E_BAD_ARG); | ||
937 | + } | ||
938 | + newroot = optarg; | ||
939 | + | ||
940 | + if (access (newroot, F_OK) != 0) { | ||
941 | + fprintf(stderr, | ||
942 | + _("%s: chroot directory %s does not exist\n"), | ||
943 | + Prog, newroot); | ||
944 | + exit (E_BAD_ARG); | ||
945 | + } | ||
946 | + if ( chroot(newroot) != 0 ) { | ||
947 | + fprintf(stderr, | ||
948 | + _("%s: unable to chroot to directory %s\n"), | ||
949 | + Prog, newroot); | ||
950 | + exit (E_BAD_ARG); | ||
951 | + } | ||
952 | + break; | ||
953 | + default: | ||
954 | + usage (); | ||
955 | + } | ||
956 | + } | ||
957 | + } | ||
958 | +} | ||
959 | |||
960 | int main (int argc, char **argv) | ||
961 | { | ||
962 | @@ -93,6 +173,8 @@ | ||
963 | |||
964 | OPENLOG ("pwunconv"); | ||
965 | |||
966 | + process_flags (argc, argv); | ||
967 | + | ||
968 | if (!spw_file_present ()) { | ||
969 | /* shadow not installed, do nothing */ | ||
970 | exit (0); | ||
971 | diff -urN shadow-4.1.4.3.orig//src/useradd.c shadow-4.1.4.3//src/useradd.c | ||
972 | --- shadow-4.1.4.3.orig//src/useradd.c 2011-02-13 09:58:16.000000000 -0800 | ||
973 | +++ shadow-4.1.4.3//src/useradd.c 2011-05-28 17:10:25.446909971 -0700 | ||
974 | @@ -112,6 +112,7 @@ | ||
975 | #ifdef WITH_SELINUX | ||
976 | static const char *user_selinux = ""; | ||
977 | #endif | ||
978 | +static const char *newroot = ""; | ||
979 | |||
980 | static long user_expire = -1; | ||
981 | static bool is_shadow_pwd; | ||
982 | @@ -189,6 +190,7 @@ | ||
983 | static void new_spent (struct spwd *); | ||
984 | static void grp_update (void); | ||
985 | |||
986 | +static void process_root_flag (int argc, char **argv); | ||
987 | static void process_flags (int argc, char **argv); | ||
988 | static void close_files (void); | ||
989 | static void open_files (void); | ||
990 | @@ -711,6 +713,7 @@ | ||
991 | (void) fputs (_(" -o, --non-unique allow to create users with duplicate\n" | ||
992 | " (non-unique) UID\n"), stderr); | ||
993 | (void) fputs (_(" -p, --password PASSWORD encrypted password of the new account\n"), stderr); | ||
994 | + (void) fputs (_(" -R, --root CHROOT_DIR directory to chroot into\n"), stderr); | ||
995 | (void) fputs (_(" -r, --system create a system account\n"), stderr); | ||
996 | (void) fputs (_(" -s, --shell SHELL login shell of the new account\n"), stderr); | ||
997 | (void) fputs (_(" -u, --uid UID user ID of the new account\n"), stderr); | ||
998 | @@ -943,6 +946,59 @@ | ||
999 | } | ||
1000 | |||
1001 | /* | ||
1002 | + * process_root_flag - chroot if given the --root option | ||
1003 | + * | ||
1004 | + * We do this outside of process_flags() because | ||
1005 | + * the is_shadow_pwd boolean needs to be set before | ||
1006 | + * process_flags(), and if we do need to chroot() we | ||
1007 | + * must do so before is_shadow_pwd gets set. | ||
1008 | + */ | ||
1009 | +static void process_root_flag (int argc, char **argv) | ||
1010 | +{ | ||
1011 | + /* | ||
1012 | + * Parse the command line options. | ||
1013 | + */ | ||
1014 | + int c; | ||
1015 | + static struct option long_options[] = { | ||
1016 | + {"root", required_argument, NULL, 'R'}, | ||
1017 | + {NULL, 0, NULL, '\0'} | ||
1018 | + }; | ||
1019 | + while ((c = getopt_long (argc, argv, | ||
1020 | +#ifdef WITH_SELINUX | ||
1021 | + "b:c:d:De:f:g:G:k:K:lmMNop:R:rs:u:UZ:", | ||
1022 | +#else | ||
1023 | + "b:c:d:De:f:g:G:k:K:lmMNop:R:rs:u:U", | ||
1024 | +#endif | ||
1025 | + long_options, NULL)) != -1) { | ||
1026 | + switch (c) { | ||
1027 | + case 'R': | ||
1028 | + if ('/' != optarg[0]) { | ||
1029 | + fprintf (stderr, | ||
1030 | + _("%s: invalid chroot path '%s'\n"), | ||
1031 | + Prog, optarg); | ||
1032 | + exit (E_BAD_ARG); | ||
1033 | + } | ||
1034 | + newroot = optarg; | ||
1035 | + | ||
1036 | + if (access (newroot, F_OK) != 0) { | ||
1037 | + fprintf(stderr, | ||
1038 | + _("%s: chroot directory %s does not exist\n"), | ||
1039 | + Prog, newroot); | ||
1040 | + exit (E_BAD_ARG); | ||
1041 | + } | ||
1042 | + if ( chroot(newroot) != 0 ) { | ||
1043 | + fprintf(stderr, | ||
1044 | + _("%s: unable to chroot to directory %s\n"), | ||
1045 | + Prog, newroot); | ||
1046 | + exit (E_BAD_ARG); | ||
1047 | + } | ||
1048 | + break; | ||
1049 | + /* no-op on everything else - they will be hanled by process_flags() */ | ||
1050 | + } | ||
1051 | + } | ||
1052 | +} | ||
1053 | + | ||
1054 | +/* | ||
1055 | * process_flags - perform command line argument setting | ||
1056 | * | ||
1057 | * process_flags() interprets the command line arguments and sets | ||
1058 | @@ -978,6 +1034,7 @@ | ||
1059 | {"no-user-group", no_argument, NULL, 'N'}, | ||
1060 | {"non-unique", no_argument, NULL, 'o'}, | ||
1061 | {"password", required_argument, NULL, 'p'}, | ||
1062 | + {"root", required_argument, NULL, 'R'}, | ||
1063 | {"system", no_argument, NULL, 'r'}, | ||
1064 | {"shell", required_argument, NULL, 's'}, | ||
1065 | #ifdef WITH_SELINUX | ||
1066 | @@ -989,9 +1046,9 @@ | ||
1067 | }; | ||
1068 | while ((c = getopt_long (argc, argv, | ||
1069 | #ifdef WITH_SELINUX | ||
1070 | - "b:c:d:De:f:g:G:k:K:lmMNop:rs:u:UZ:", | ||
1071 | + "b:c:d:De:f:g:G:k:K:lmMNop:R:rs:u:UZ:", | ||
1072 | #else | ||
1073 | - "b:c:d:De:f:g:G:k:K:lmMNop:rs:u:U", | ||
1074 | + "b:c:d:De:f:g:G:k:K:lmMNop:R:rs:u:U", | ||
1075 | #endif | ||
1076 | long_options, NULL)) != -1) { | ||
1077 | switch (c) { | ||
1078 | @@ -1156,6 +1213,9 @@ | ||
1079 | } | ||
1080 | user_pass = optarg; | ||
1081 | break; | ||
1082 | + case 'R': | ||
1083 | + /* no-op since we handled this in process_root_flag() earlier */ | ||
1084 | + break; | ||
1085 | case 'r': | ||
1086 | rflg = true; | ||
1087 | break; | ||
1088 | @@ -1748,8 +1808,16 @@ | ||
1089 | #ifdef WITH_SELINUX | ||
1090 | selinux_file_context (user_home); | ||
1091 | #endif | ||
1092 | - /* XXX - create missing parent directories. --marekm */ | ||
1093 | - if (mkdir (user_home, 0) != 0) { | ||
1094 | + /* shell out to invoke mkdir -p | ||
1095 | + * creating a subshell under pseudo's chroot() breaks the jail | ||
1096 | + * (bug in pseudo), so make sure we include the full host path | ||
1097 | + * to the sysroot when the --root option is in use. | ||
1098 | + */ | ||
1099 | + int sysroot_path_len = strlen(newroot); | ||
1100 | + int home_path_len = strlen(user_home); | ||
1101 | + char cmd[sysroot_path_len + home_path_len + 10]; | ||
1102 | + sprintf(cmd, "mkdir -p %s%s", newroot, user_home); | ||
1103 | + if (system (cmd) != 0) { | ||
1104 | fprintf (stderr, | ||
1105 | _("%s: cannot create directory %s\n"), | ||
1106 | Prog, user_home); | ||
1107 | @@ -1861,6 +1929,7 @@ | ||
1108 | */ | ||
1109 | user_groups[0] = (char *) 0; | ||
1110 | |||
1111 | + process_root_flag (argc, argv); | ||
1112 | |||
1113 | is_shadow_pwd = spw_file_present (); | ||
1114 | #ifdef SHADOWGRP | ||
1115 | diff -urN shadow-4.1.4.3.orig//src/userdel.c shadow-4.1.4.3//src/userdel.c | ||
1116 | --- shadow-4.1.4.3.orig//src/userdel.c 2011-02-13 09:58:16.000000000 -0800 | ||
1117 | +++ shadow-4.1.4.3//src/userdel.c 2011-05-28 17:09:52.356013600 -0700 | ||
1118 | @@ -79,6 +79,7 @@ | ||
1119 | static char *user_name; | ||
1120 | static uid_t user_id; | ||
1121 | static char *user_home; | ||
1122 | +static const char *newroot = ""; | ||
1123 | |||
1124 | static bool fflg = false; | ||
1125 | static bool rflg = false; | ||
1126 | @@ -119,6 +120,7 @@ | ||
1127 | " -f, --force force removal of files,\n" | ||
1128 | " even if not owned by user\n" | ||
1129 | " -h, --help display this help message and exit\n" | ||
1130 | + " -R, --root CHROOT_DIR directory to chroot into\n" | ||
1131 | " -r, --remove remove home directory and mail spool\n" | ||
1132 | "\n"), stderr); | ||
1133 | exit (E_USAGE); | ||
1134 | @@ -768,12 +770,34 @@ | ||
1135 | {"remove", no_argument, NULL, 'r'}, | ||
1136 | {NULL, 0, NULL, '\0'} | ||
1137 | }; | ||
1138 | - while ((c = getopt_long (argc, argv, "fhr", | ||
1139 | + while ((c = getopt_long (argc, argv, "fhR:r", | ||
1140 | long_options, NULL)) != -1) { | ||
1141 | switch (c) { | ||
1142 | case 'f': /* force remove even if not owned by user */ | ||
1143 | fflg = true; | ||
1144 | break; | ||
1145 | + case 'R': | ||
1146 | + if ('/' != optarg[0]) { | ||
1147 | + fprintf (stderr, | ||
1148 | + _("%s: invalid chroot path '%s'\n"), | ||
1149 | + Prog, optarg); | ||
1150 | + exit (E_BAD_ARG); | ||
1151 | + } | ||
1152 | + newroot = optarg; | ||
1153 | + | ||
1154 | + if (access (newroot, F_OK) != 0) { | ||
1155 | + fprintf(stderr, | ||
1156 | + _("%s: chroot directory %s does not exist\n"), | ||
1157 | + Prog, newroot); | ||
1158 | + exit (E_BAD_ARG); | ||
1159 | + } | ||
1160 | + if ( chroot(newroot) != 0 ) { | ||
1161 | + fprintf(stderr, | ||
1162 | + _("%s: unable to chroot to directory %s\n"), | ||
1163 | + Prog, newroot); | ||
1164 | + exit (E_BAD_ARG); | ||
1165 | + } | ||
1166 | + break; | ||
1167 | case 'r': /* remove home dir and mailbox */ | ||
1168 | rflg = true; | ||
1169 | break; | ||
1170 | diff -urN shadow-4.1.4.3.orig//src/usermod.c shadow-4.1.4.3//src/usermod.c | ||
1171 | --- shadow-4.1.4.3.orig//src/usermod.c 2011-02-13 09:58:16.000000000 -0800 | ||
1172 | +++ shadow-4.1.4.3//src/usermod.c 2011-05-28 17:09:52.356013600 -0700 | ||
1173 | @@ -110,6 +110,7 @@ | ||
1174 | static long user_newinactive; | ||
1175 | static long sys_ngroups; | ||
1176 | static char **user_groups; /* NULL-terminated list */ | ||
1177 | +static const char *newroot = ""; | ||
1178 | |||
1179 | static bool | ||
1180 | aflg = false, /* append to existing secondary group set */ | ||
1181 | @@ -164,6 +165,7 @@ | ||
1182 | #endif | ||
1183 | static void grp_update (void); | ||
1184 | |||
1185 | +static void process_root_flag (int, char **); | ||
1186 | static void process_flags (int, char **); | ||
1187 | static void close_files (void); | ||
1188 | static void open_files (void); | ||
1189 | @@ -323,6 +325,7 @@ | ||
1190 | " new location (use only with -d)\n" | ||
1191 | " -o, --non-unique allow using duplicate (non-unique) UID\n" | ||
1192 | " -p, --password PASSWORD use encrypted password for the new password\n" | ||
1193 | + " -R --root CHROOT_DIR directory to chroot into\n" | ||
1194 | " -s, --shell SHELL new login shell for the user account\n" | ||
1195 | " -u, --uid UID new UID for the user account\n" | ||
1196 | " -U, --unlock unlock the user account\n" | ||
1197 | @@ -802,6 +805,60 @@ | ||
1198 | } | ||
1199 | |||
1200 | /* | ||
1201 | + * process_root_flag - chroot if given the --root option | ||
1202 | + * | ||
1203 | + * We do this outside of process_flags() because | ||
1204 | + * the is_shadow_pwd boolean needs to be set before | ||
1205 | + * process_flags(), and if we do need to chroot() we | ||
1206 | + * must do so before is_shadow_pwd gets set. | ||
1207 | + */ | ||
1208 | +static void process_root_flag (int argc, char **argv) | ||
1209 | +{ | ||
1210 | + /* | ||
1211 | + * Parse the command line options. | ||
1212 | + */ | ||
1213 | + int c; | ||
1214 | + static struct option long_options[] = { | ||
1215 | + {"root", required_argument, NULL, 'R'}, | ||
1216 | + {NULL, 0, NULL, '\0'} | ||
1217 | + }; | ||
1218 | + while ((c = getopt_long (argc, argv, | ||
1219 | +#ifdef WITH_SELINUX | ||
1220 | + "ac:d:e:f:g:G:hl:Lmop:R:s:u:UZ:", | ||
1221 | +#else | ||
1222 | + "ac:d:e:f:g:G:hl:Lmop:R:s:u:U", | ||
1223 | +#endif | ||
1224 | + long_options, NULL)) != -1) { | ||
1225 | + switch (c) { | ||
1226 | + case 'R': | ||
1227 | + if ( (!VALID (optarg) ) | ||
1228 | + || ( ('/' != optarg[0]) ) ) { | ||
1229 | + fprintf (stderr, | ||
1230 | + _("%s: invalid chroot path '%s'\n"), | ||
1231 | + Prog, optarg); | ||
1232 | + exit (E_BAD_ARG); | ||
1233 | + } | ||
1234 | + newroot = optarg; | ||
1235 | + | ||
1236 | + if (access (newroot, F_OK) != 0) { | ||
1237 | + fprintf(stderr, | ||
1238 | + _("%s: chroot directory %s does not exist\n"), | ||
1239 | + Prog, newroot); | ||
1240 | + exit (E_BAD_ARG); | ||
1241 | + } | ||
1242 | + if ( chroot(newroot) != 0 ) { | ||
1243 | + fprintf(stderr, | ||
1244 | + _("%s: unable to chroot to directory %s\n"), | ||
1245 | + Prog, newroot); | ||
1246 | + exit (E_BAD_ARG); | ||
1247 | + } | ||
1248 | + break; | ||
1249 | + /* no-op on everything else - they will be hanled by process_flags() */ | ||
1250 | + } | ||
1251 | + } | ||
1252 | +} | ||
1253 | + | ||
1254 | +/* | ||
1255 | * process_flags - perform command line argument setting | ||
1256 | * | ||
1257 | * process_flags() interprets the command line arguments and sets the | ||
1258 | @@ -895,6 +952,7 @@ | ||
1259 | {"move-home", no_argument, NULL, 'm'}, | ||
1260 | {"non-unique", no_argument, NULL, 'o'}, | ||
1261 | {"password", required_argument, NULL, 'p'}, | ||
1262 | + {"root", required_argument, NULL, 'R'}, | ||
1263 | #ifdef WITH_SELINUX | ||
1264 | {"selinux-user", required_argument, NULL, 'Z'}, | ||
1265 | #endif | ||
1266 | @@ -905,9 +963,9 @@ | ||
1267 | }; | ||
1268 | while ((c = getopt_long (argc, argv, | ||
1269 | #ifdef WITH_SELINUX | ||
1270 | - "ac:d:e:f:g:G:hl:Lmop:s:u:UZ:", | ||
1271 | + "ac:d:e:f:g:G:hl:Lmop:R:s:u:UZ:", | ||
1272 | #else | ||
1273 | - "ac:d:e:f:g:G:hl:Lmop:s:u:U", | ||
1274 | + "ac:d:e:f:g:G:hl:Lmop:R:s:u:U", | ||
1275 | #endif | ||
1276 | long_options, NULL)) != -1) { | ||
1277 | switch (c) { | ||
1278 | @@ -999,6 +1057,9 @@ | ||
1279 | user_pass = optarg; | ||
1280 | pflg = true; | ||
1281 | break; | ||
1282 | + case 'R': | ||
1283 | + /* no-op since we handled this in process_root_flag() earlier */ | ||
1284 | + break; | ||
1285 | case 's': | ||
1286 | if (!VALID (optarg)) { | ||
1287 | fprintf (stderr, | ||
1288 | @@ -1715,6 +1776,8 @@ | ||
1289 | |||
1290 | OPENLOG ("usermod"); | ||
1291 | |||
1292 | + process_root_flag (argc, argv); | ||
1293 | + | ||
1294 | is_shadow_pwd = spw_file_present (); | ||
1295 | #ifdef SHADOWGRP | ||
1296 | is_shadow_grp = sgr_file_present (); | ||
diff --git a/meta/recipes-extended/shadow/shadow-native_4.1.4.3.bb b/meta/recipes-extended/shadow/shadow-native_4.1.4.3.bb new file mode 100644 index 0000000000..2f93e051ba --- /dev/null +++ b/meta/recipes-extended/shadow/shadow-native_4.1.4.3.bb | |||
@@ -0,0 +1,66 @@ | |||
1 | SUMMARY = "Tools to change and administer password and group data" | ||
2 | DESCRIPTION = "Tools to change and administer password and group data" | ||
3 | HOMEPAGE = "http://pkg-shadow.alioth.debian.org" | ||
4 | BUGTRACKER = "https://alioth.debian.org/tracker/?group_id=30580" | ||
5 | SECTION = "base utils" | ||
6 | PRIORITY = "optional" | ||
7 | LICENSE = "BSD | Artistic" | ||
8 | LIC_FILES_CHKSUM = "file://COPYING;md5=08c553a87d4e51bbed50b20e0adcaede \ | ||
9 | file://src/passwd.c;firstline=8;endline=30;md5=2899a045e90511d0e043b85a7db7e2fe" | ||
10 | |||
11 | PR = "r0" | ||
12 | |||
13 | SRC_URI = "ftp://pkg-shadow.alioth.debian.org/pub/pkg-shadow/shadow-${PV}.tar.bz2 \ | ||
14 | file://shadow.automake-1.11.patch \ | ||
15 | file://shadow-4.1.3-dots-in-usernames.patch \ | ||
16 | file://shadow-4.1.4.2-env-reset-keep-locale.patch \ | ||
17 | file://add_root_cmd_options.patch" | ||
18 | |||
19 | SRC_URI[md5sum] = "b8608d8294ac88974f27b20f991c0e79" | ||
20 | SRC_URI[sha256sum] = "633f5bb4ea0c88c55f3642c97f9d25cbef74f82e0b4cf8d54e7ad6f9f9caa778" | ||
21 | |||
22 | inherit autotools gettext native | ||
23 | |||
24 | EXTRA_OECONF += "--without-audit \ | ||
25 | --without-libcrack \ | ||
26 | --without-libpam \ | ||
27 | --without-selinux" | ||
28 | |||
29 | do_install_append() { | ||
30 | # Enable CREATE_HOME by default. | ||
31 | sed -i 's/#CREATE_HOME/CREATE_HOME/g' ${D}${sysconfdir}/login.defs | ||
32 | |||
33 | # As we are on an embedded system, ensure the users mailbox is in | ||
34 | # ~/ not /var/spool/mail by default, as who knows where or how big | ||
35 | # /var is. The system MDA will set this later anyway. | ||
36 | sed -i 's/MAIL_DIR/#MAIL_DIR/g' ${D}${sysconfdir}/login.defs | ||
37 | sed -i 's/#MAIL_FILE/MAIL_FILE/g' ${D}${sysconfdir}/login.defs | ||
38 | |||
39 | # Disable checking emails. | ||
40 | sed -i 's/MAIL_CHECK_ENAB/#MAIL_CHECK_ENAB/g' ${D}${sysconfdir}/login.defs | ||
41 | |||
42 | # Now we don't have a mail system. Disable mail creation for now. | ||
43 | sed -i 's:/bin/bash:/bin/sh:g' ${D}${sysconfdir}/default/useradd | ||
44 | sed -i '/^CREATE_MAIL_SPOOL/ s:^:#:' ${D}${sysconfdir}/default/useradd | ||
45 | |||
46 | install -d ${D}${sbindir} ${D}${base_sbindir} ${D}${base_bindir} | ||
47 | for i in passwd chfn newgrp chsh ; do | ||
48 | mv ${D}${bindir}/$i ${D}${bindir}/$i.${PN} | ||
49 | done | ||
50 | |||
51 | mv ${D}${sbindir}/chpasswd ${D}${sbindir}/chpasswd.${PN} | ||
52 | } | ||
53 | |||
54 | pkg_postinst_${PN} () { | ||
55 | update-alternatives --install ${bindir}/passwd passwd passwd.${PN} 200 | ||
56 | update-alternatives --install ${sbindir}/chpasswd chpasswd chpasswd.${PN} 200 | ||
57 | update-alternatives --install ${bindir}/chfn chfn chfn.${PN} 200 | ||
58 | update-alternatives --install ${bindir}/newgrp newgrp newgrp.${PN} 200 | ||
59 | update-alternatives --install ${bindir}/chsh chsh chsh.${PN} 200 | ||
60 | } | ||
61 | |||
62 | pkg_prerm_${PN} () { | ||
63 | for i in passwd chpasswd chfn newgrp chsh ; do | ||
64 | update-alternatives --remove $i $i.${PN} | ||
65 | done | ||
66 | } | ||