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