/[adduser]/trunk/adduser
ViewVC logotype

Contents of /trunk/adduser

Parent Directory Parent Directory | Revision Log Revision Log


Revision 136 - (show annotations) (download)
Sat Mar 27 14:51:17 2004 UTC (9 years, 1 month ago) by zugschlus
File size: 29225 byte(s)
roll back --group --ingroup change because the code is different from
what I thought.
1 #!/usr/bin/perl
2 #
3 # adduser VERSION
4 #
5 # adduser: a utility to add users to the system
6 # addgroup: a utility to add groups to the system
7
8 # Copyright (C) 1997, 1998, 1999 Guy Maor <maor@debian.org>
9 # Copyright (C) 1995 Ted Hajek <tedhajek@boombox.micro.umn.edu>
10 # Ian A. Murdock <imurdock@gnu.ai.mit.edu>
11 # Bugfixes and other improvements Roland Bauerschmidt <rb@debian.org>
12 # General scheme of the program adapted by the original debian 'adduser'
13 # program by Ian A. Murdock <imurdock@gnu.ai.mit.edu>.
14 #
15 # This program is free software; you can redistribute it and/or modify
16 # it under the terms of the GNU General Public License as published by
17 # the Free Software Foundation; either version 2 of the License, or
18 # (at your option) any later version.
19 #
20 # This program is distributed in the hope that it will be useful,
21 # but WITHOUT ANY WARRANTY; without even the implied warranty of
22 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 # GNU General Public License for more details.
24 #
25 # You should have received a copy of the GNU General Public License
26 # along with this program; if not, write to the Free Software
27 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 #
29 #
30 ####################
31 # the program can be called as:
32 #
33 # adduser [--home DIR] [--shell SHELL] [--uid ID] [--firstuid ID]
34 # [--lastuid ID] [--ingroup GROUP | --gid ID] [--disabled-password]
35 # [--disabled-login] [--gecos GECOS] [--no-create-home] user
36 # add a normal user to the system
37 # example: adduser fred
38 # $action = "adduser"
39 #
40 # adduser --group [--gid ID] group
41 # addgroup [--gid ID] group
42 # add a user group
43 # example: addgroup powerusers
44 # $action = "addgroup"
45 #
46 # adduser --group --system [--gid GID] group
47 # addgroup --system [--gid GID] group
48 # add a system group
49 # example: addgroup --system --quiet www-data
50 # $action = "addsysgroup"
51 #
52 # adduser --system [--home DIR] [--shell SHELL] [--uid ID] [--group |
53 # --ingroup GROUP | --gid ID] [--disabled-password] [--disabled-login]
54 # [--gecos GECOS] [--no-create-home] user
55 # add a system user. Create a like-named, like-id'd group with
56 # --group, add to an existing group with --ingroup or --gid. Add
57 # to "nogroup" with neither.
58 # example: adduser --system --home /home/gopher-data --group gopher
59 # $action = "addsysuser"
60 #
61 # adduser user group
62 # add the existing user to an existing group.
63 # $action = "addusertogroup"
64 #
65 # all commands take the following options:
66 # --quiet don't give progress information on STDOUT
67 # --force-badname disable checking of names for funny characters
68 # --help usage message
69 # --version version number and copyright
70 # --conf FILE use FILE instead of /etc/adduser.conf
71 ############
72
73 use warnings;
74 use Debian::AdduserCommon;
75
76 BEGIN {
77 eval 'use Locale::gettext';
78 if ($@) {
79 *gettext = sub { shift };
80 *textdomain = sub { "" };
81 *LC_MESSAGES = sub { 5 };
82 }
83 eval {
84 require POSIX;
85 import POSIX qw(setlocale);
86 };
87 if ($@) {
88 *setlocale = sub { 1 };
89 }
90 }
91
92 setlocale(LC_MESSAGES, "");
93 textdomain("adduser");
94
95 $verbose = 1; # should we be verbose?
96 $allow_badname = 0; # should we allow bad names?
97 $ask_passwd = 1; # ask for a passwd?
98
99 $defaults = "/etc/adduser.conf";
100 $nogroup_id = getgrnam("nogroup") || 65534;
101 $0 =~ s+.*/++;
102
103 $config{"dshell"} = "/bin/bash";
104 $config{"first_system_uid"} = 100;
105 $config{"last_system_uid"} = 999;
106 $config{"first_uid"} = 1000;
107 $config{"last_uid"} = 29999;
108 $config{"first_system_gid"} = 100;
109 $config{"last_system_gid"} = 999;
110 $config{"first_gid"} = 1000;
111 $config{"last_gid"} = 29999;
112 $config{"dhome"} = "/home";
113 $config{"skel"} = "/etc/skel";
114 $config{"usergroups"} = "yes";
115 $config{"users_gid"} = "100";
116 $config{"grouphomes"} = "no";
117 $config{"letterhomes"} = "no";
118 $config{"quotauser"} = "";
119 $config{"dir_mode"} = "0755";
120 $config{"setgid_home"} = "no";
121
122 $action = $0 eq "addgroup" ? "addgroup" : "adduser";
123
124 while (defined($arg = shift(@ARGV))) {
125 die "$0: ",_("No options allowed after names.\n")
126 if (defined($names[0]) && $arg =~ /^--/);
127 if ($arg eq "--quiet") {
128 $verbose = 0;
129 } elsif ($arg eq "--force-badname") {
130 $allow_badname = 1;
131 } elsif ($arg eq "--help" || $arg eq "-h") {
132 &usage();
133 exit 0;
134 } elsif ($arg eq "--version") {
135 &version();
136 exit 0;
137 } elsif ($arg eq "--system") {
138 $found_sys_opt = 1;
139 $action = "addsysuser" if ($action eq "adduser");
140 $action = "addsysgroup" if ($action eq "addgroup");
141 } elsif ($arg eq "--group") {
142 $found_group_opt = 1;
143 } elsif ($arg eq "--ingroup") {
144 die "$0: ",_("--ingroup requires an argument.\n")
145 if (!defined($ingroup_name = shift(@ARGV)));
146 } elsif ($arg eq "--home") {
147 die "$0: ",_("--home requires an argument.\n")
148 if (!defined($special_home = shift(@ARGV)));
149 die "$0: ",_("The home dir must be an absolute path.\n")
150 if ($special_home !~ m+^/+ );
151 } elsif ($arg eq "--gecos") {
152 die "$0: ",_("--gecos requires an argument.\n")
153 if (!defined($new_gecos = shift(@ARGV)));
154 } elsif ($arg eq "--shell") {
155 die "$0: ",_("--shell requires an argument.\n")
156 if (!defined($special_shell = shift(@ARGV)));
157 } elsif ($arg eq "--disabled-password") {
158 $ask_passwd = 0;
159 $disabled_login = 0;
160 } elsif ($arg eq "--disabled-login") {
161 $ask_passwd = 0;
162 $disabled_login = 1;
163 } elsif ($arg eq "--uid") {
164 die "$0: ",_("--uid requires a numeric argument.\n")
165 if (!defined ($new_uid = shift(@ARGV)) || $new_uid !~ /^\-?\d+$/);
166 } elsif ($arg eq "--firstuid") {
167 die "$0: ",_("--firstuid requires a numeric argument.\n")
168 if (!defined ($new_firstuid = shift(@ARGV)) || $new_firstuid !~ /^\-?\d+$/);
169 } elsif ($arg eq "--lastuid") {
170 die "$0: ",_("--lastuid requires a numeric argument.\n")
171 if (!defined ($new_lastuid = shift(@ARGV)) || $new_lastuid !~ /^\-?\d+$/);
172 } elsif ($arg eq "--gid") {
173 die "$0: ",_("--gid requires a numeric argument.\n")
174 if (!defined ($new_gid = shift(@ARGV)) || $new_gid !~ /^\-?\d+$/);
175 } elsif ($arg eq "--conf") {
176 die "$0: ",_("--conf requires an argument.\n")
177 if (!defined($defaults = shift(@ARGV)));
178 dief (_("`%s' doesn't exist.\n",$defaults))
179 if (! -f $defaults);
180 } elsif ($arg eq "--no-create-home") {
181 $no_create_home = 1;
182 } elsif ($arg eq "--debug") {
183 $debugging = 1;
184 } elsif ($arg =~ /^--/) { # bad argument!
185 dief (_("Unknown argument `%s'.\n"),$arg);
186 } else { # it's a username
187 push (@names, $arg);
188 }
189 }
190
191 die "$0: ",_("Only root may add a user or group to the system.\n") if ($> != 0);
192
193 if (defined($special_home) && $verbose) {
194 print "$0: ",_("Warning: The home dir you specified already exists.\n")
195 if (!defined($no_create_home) && -d $special_home);
196 print "$0: ",_("Warning: The home dir you specified does not exist.\n")
197 if (defined($no_create_home) && ! -d $special_home);
198 }
199
200 if (@names == 0) {
201 if($found_group_opt || $action eq "addgroup" || $action eq "addsysgroup")
202 {
203 print _("Enter a groupname to add: ");
204 }
205 else
206 {
207 print _("Enter a username to add: ");
208 }
209 chomp($answer=<STDIN>);
210 push(@names, $answer);
211 }
212 die "$0: ",_("I need a name to add.\n") if (length($names[0]) == 0);
213 die "$0: ",_("No more than two names.\n") if (@names > 2);
214 if (@names == 2) { # must be addusertogroup
215 die "$0: ",_("Specify only one name in this mode.\n")
216 if ($action eq "addsysuser" || $found_group_opt);
217 $action = "addusertogroup";
218 $existing_user = shift (@names);
219 $existing_group = shift (@names);
220 }
221 else {
222 $new_name = shift (@names);
223 }
224
225 if ($found_group_opt) {
226 if ($action eq "addsysuser") {
227 $make_group_also = 1;
228 }
229 elsif ($found_sys_opt) {
230 $action = "addsysgroup";
231 }
232 else {
233 $action = "addgroup";
234 }
235 }
236 die "$0: ",_("--group, --ingroup, and --gid options are mutually exclusive.\n") if
237 ($action ne "addgroup" &&
238 defined($found_group_opt) +defined($ingroup_name) +defined($new_gid) > 1);
239
240 if( $verbose ) {
241 $ENV{"VERBOSE"}="1"
242 }
243
244 if( $debugging ) {
245 $ENV{"DEBUG"}="1"
246 }
247
248
249 #####
250 # OK, we've processed the arguments. $action equals one of the following,
251 # and the appropriate variables have been set:
252 #
253 # $action = "adduser"
254 # $new_name - the name of the new user.
255 # $ingroup_name | $new_gid - the group to add the user to
256 # $special_home, $new_uid, $new_gecos - optional overrides
257 # $action = "addgroup"
258 # $new_name - the name of the new group
259 # $new_gid - optional override
260 # $action = "addsysgroup"
261 # $new_name - the name of the new group
262 # $new_gid - optional override
263 # $action = "addsysuser"
264 # $new_name - the name of the new user
265 # $make_group_also | $ingroup_name | $new_gid | 0 - which group
266 # $special_home, $new_uid, $new_gecos - optional overrides
267 # $action = "addusertogroup"
268 # $existing_user - the user to be added
269 # $existing_group - the group to add her to
270 #####
271
272 &read_config($defaults);
273 &checkname($new_name) if defined $new_name;
274 $SIG{'INT'} = $SIG{'QUIT'} = $SIG{'HUP'} = 'handler';
275
276 #################
277 ## addsysgroup ##
278 #################
279 if ($action eq "addsysgroup") {
280 # Check if requested group already exists and we can exit safely
281 if (existing_group_ok($new_name, $new_gid)) {
282 printf (_("Group %s does already exist as a system group. Exiting...\n"), $new_name) if $verbose;
283 exit 0;
284 }
285 dief (_("The group `%s' already exists.\n"),$new_name)
286 if (defined getgrnam($new_name));
287 dief (_("The GID `%s' is already in use.\n"),$new_gid)
288 if (defined($new_gid) && defined(getgrgid($new_gid)));
289 if (!defined($new_gid)) {
290 $new_gid = &first_avail_id($config{"first_system_gid"},
291 $config{"last_system_gid"},
292 &get_current_gids);
293
294 if ($new_gid == -1) {
295 print STDERR "$0: ",_("No GID is available in the range "),
296 "$config{\"first_system_gid\"} - $config{\"last_system_gid\"}\n",
297 "(FIRST_SYS_GID - LAST_SYS_GID). ";
298 dief (_("Group `%s' not created.\n"),$new_name);
299 }
300 }
301
302 printf (_("Adding group %s (%s)...\n"),$new_name,$new_gid) if $verbose;
303 &invalidate_nscd("group");
304 &systemcall('/usr/sbin/groupadd', '-g', $new_gid, $new_name);
305 &invalidate_nscd("group");
306 print _("Done.\n") if $verbose;
307 exit 0;
308 }
309
310
311 ##############
312 ## addgroup ##
313 ##############
314 if ($action eq "addgroup") {
315 dief (_("The group `%s' already exists.\n"),$new_name)
316 if (defined getgrnam($new_name));
317 dief (_("The GID `%s' is already in use.\n"),$new_gid)
318 if (defined($new_gid) && defined(getgrgid($new_gid)));
319 if (!defined($new_gid)) {
320 $new_gid = &first_avail_id($config{"first_gid"},
321 $config{"last_gid"},
322 &get_current_gids);
323
324 if ($new_gid == -1) {
325 print STDERR "$0: ",_("No GID is available in the range "),
326 "$config{\"first_gid\"} - $config{\"last_gid\"}\n",
327 "(FIRST_GID - LAST_GID). ";
328 dief (_("Group `%s' not created.\n"),$new_name);
329 }
330 }
331
332 printf (_("Adding group %s (%s)...\n"),$new_name,$new_gid) if $verbose;
333 &invalidate_nscd("group");
334 &systemcall('/usr/sbin/groupadd', '-g', $new_gid, $new_name);
335 &invalidate_nscd("group");
336 print _("Done.\n") if $verbose;
337 exit 0;
338 }
339
340
341 ####################
342 ## addusertogroup ##
343 ####################
344 elsif ($action eq "addusertogroup") {
345 dief (_("The user `%s' doesn't exist.\n"),$existing_user)
346 if (!defined getpwnam($existing_user));
347 dief (_("The group `%s' doesn't exist.\n"),$existing_group)
348 if (!defined getgrnam($existing_group));
349 if (&user_is_member($existing_user, $existing_group)) {
350 printf _("The user `%s' is already a member of %s.\n"),
351 $existing_user,$existing_group if $verbose;
352 exit 0; # not really an error
353 }
354
355 printf _("Adding user %s to group %s...\n"),$existing_user,$existing_group
356 if $verbose;
357 &invalidate_nscd();
358 # FIXME - the next line has a race condition.
359 #&systemcall('usermod', '-G',
360 #join(",", get_users_groups($existing_user), $existing_group),
361 #$existing_user);
362 &systemcall('/usr/bin/gpasswd', '-M',
363 join(',', get_group_members($existing_group), $existing_user),
364 $existing_group);
365 #&systemcall('gpasswd', '-a',$existing_user,$existing_group);
366 &invalidate_nscd();
367 print _("Done.\n") if $verbose;
368 exit 0;
369 }
370
371
372 ################
373 ## addsysuser ##
374 ################
375 elsif ($action eq "addsysuser") {
376 if (existing_user_ok($new_name, $new_uid)) {
377 printf (_("User %s does already exist as a system user. Exiting...\n"), $new_name) if $verbose;
378 exit 0;
379 }
380 $new_gid = $nogroup_id
381 if (!$ingroup_name && !defined($new_gid) && !$make_group_also);
382 check_user_group(1);
383 printf (_("Adding system user %s...\n"),$new_name) if $verbose;
384
385 if (!defined($new_uid) && $make_group_also) {
386 $new_uid = &first_avail_id($config{"first_system_uid"},
387 $config{"last_system_uid"},
388 &get_current_uids, &get_current_gids);
389 if ($new_uid == -1) {
390 print STDERR "$0: ",_("No UID/GID pair is available in the range "),
391 "$config{\"first_system_uid\"} - $config{\"last_system_uid\"}\n",
392 "(FIRST_SYS_UID - LAST_SYS_UID). ";
393 dief (_("User `%s' not created.\n"),$new_name);
394 }
395 $new_gid = $new_uid;
396 $ingroup_name = $new_name;
397 }
398 elsif (!defined($new_uid) && !$make_group_also) {
399 $new_uid = &first_avail_id($config{"first_system_uid"},
400 $config{"last_system_uid"},
401 &get_current_uids);
402 if ($new_uid == -1) {
403 print STDERR "$0: ",_("No UID is available in the range "),
404 "$config{\"first_system_uid\"} - $config{\"last_system_uid\"}\n",
405 "(FIRST_SYS_UID - LAST_SYS_UID). ";
406 &dief (_("User `%s' not created.\n"),$new_name);
407 }
408 if (defined($new_gid)) { $ingroup_name = getgrgid($new_gid); }
409 elsif ($ingroup_name) { $new_gid = getgrnam($ingroup_name); }
410 else { die _("Internal error"); }
411 }
412 else {
413 if (defined($new_gid)) { $ingroup_name = getgrgid($new_gid); }
414 elsif ($ingroup_name) { $new_gid = getgrnam($ingroup_name); }
415 elsif ($make_group_also){ $new_gid=$new_uid; $ingroup_name=$new_name; }
416 else { die _("Internal error"); }
417 }
418
419 &invalidate_nscd();
420 # if we reach this point, and the group does already exist, we can use it.
421 if ($make_group_also && !getgrnam($new_name)) {printf _("Adding new group %s (%s).\n"),$new_name,$new_gid if $verbose;
422 $undogroup = $new_name;
423 &systemcall('/usr/sbin/groupadd', '-g', $new_gid, $new_name);
424 &invalidate_nscd("group");
425 }
426
427 printf _("Adding new user %s (%s) with group %s.\n"),$new_name,$new_uid,$ingroup_name
428 if $verbose;
429 $home_dir = $special_home || &homedir($new_name, $ingroup_name);
430 $shell = $special_shell || '/bin/false';
431 $undouser = $new_name;
432 &systemcall('/usr/sbin/useradd', '-d', $home_dir, '-g', $ingroup_name, '-s',
433 $shell, '-u', $new_uid, $new_name);
434 &invalidate_nscd();
435
436 if(defined($new_gecos)) {
437 &ch_gecos($new_gecos);
438 }
439
440 if ($no_create_home) {
441 print _("Not creating home directory.\n") if $verbose;
442 } elsif (-e $home_dir) {
443 printf _("Home directory %s already exists.\n"),$home_dir if $verbose;
444 } else {
445 printf _("Creating home directory %s.\n"),$home_dir if $verbose;
446 $undohome = $home_dir;
447 &mktree($home_dir) || &cleanup("Couldn't create $home_dir: $!.\n");
448 chown($new_uid, $new_gid, $home_dir)
449 || &cleanup("chown $new_uid:$new_gid $home_dir: $!\n");
450 $dir_mode = get_dir_mode($make_group_also);
451 chmod ($dir_mode, $home_dir) ||
452 &cleanup("chmod $dir_mode $home_dir: $!\n");
453 }
454
455 exit 0;
456 }
457
458
459 #############
460 ## adduser ##
461 #############
462 elsif ($action eq "adduser") {
463 if (!$ingroup_name && !defined($new_gid)) {
464 if ($config{"usergroups"} eq "yes") { $make_group_also = 1; }
465 else { $new_gid = $config{"users_gid"}; }
466 }
467 check_user_group(0);
468 $first_uid = $new_firstuid || $config{"first_uid"};
469 $last_uid = $new_lastuid || $config{"last_uid"};
470 printf _("Adding user %s...\n"),$new_name if $verbose;
471
472 if (!defined($new_uid) && $make_group_also) {
473 $new_uid = &first_avail_id($first_uid,
474 $last_uid,
475 &get_current_uids, &get_current_gids);
476 if ($new_uid == -1) {
477 print STDERR "$0: ",_("No UID/GID pair is available in the range "),
478 "$first_uid - $last_uid\n",
479 "(FIRST_UID - LAST_UID). ";
480 dief(_("User `%s' not created.\n"),$new_name);
481 }
482 $new_gid = $new_uid;
483 $ingroup_name = $new_name;
484 }
485 elsif (!defined($new_uid) && !$make_group_also) {
486 $new_uid = &first_avail_id($first_uid,
487 $last_uid,
488 &get_current_uids);
489 if ($new_uid == -1) {
490 print STDERR "$0: ",_("No UID is available in the range "),
491 "$config{\"first_uid\"} - $config{\"last_uid\"}\n",
492 "(FIRST_UID - LAST_UID). ";
493 dief(_("User `%s' not created.\n"),$new_name);
494 }
495 if (defined($new_gid)) { $ingroup_name = getgrgid($new_gid); }
496 elsif ($ingroup_name) { $new_gid = getgrnam($ingroup_name); }
497 else { die _("Internal error"); }
498 }
499 else {
500 if (defined($new_gid)) { $ingroup_name = getgrgid($new_gid); }
501 elsif ($ingroup_name) { $new_gid = getgrnam($ingroup_name); }
502 elsif ($make_group_also){ $new_gid=$new_uid; $ingroup_name=$new_name; }
503 else { die _("Internal error"); }
504 }
505
506 &invalidate_nscd();
507 if ($make_group_also) {
508 printf _("Adding new group %s (%s).\n"),$new_name,$new_gid if $verbose;
509 $undogroup = $new_name;
510 &systemcall('/usr/sbin/groupadd', '-g', $new_gid, $new_name);
511 &invalidate_nscd();
512 }
513
514 printf _("Adding new user %s (%s) with group %s.\n"),$new_name,$new_uid,$ingroup_name
515 if $verbose;
516 $home_dir = $special_home || &homedir($new_name, $ingroup_name);
517 $shell = $special_shell || $config{"dshell"};
518 $undouser = $new_name;
519 &systemcall('/usr/sbin/useradd', '-d', $home_dir, '-g', $ingroup_name, '-s',
520 $shell, '-u', $new_uid, $new_name);
521 &invalidate_nscd();
522
523 if (-e $home_dir) {
524 printf _("Home directory %s already exists. Not copying from %s\n"),
525 $home_dir,$config{skel} if $verbose && !$no_create_home;
526 } elsif ($no_create_home) {
527 print "Not creating $home_dir.\n" if $verbose;
528 }
529 else {
530 printf _("Creating home directory %s.\n"),$home_dir if $verbose;
531 $undohome = $home_dir;
532 &mktree($home_dir) || &cleanup("Couldn't create $home_dir: $!.\n");
533 chown($new_uid, $new_gid, $home_dir)
534 || &cleanup("chown $new_uid:$new_gid $home_dir: $!\n");
535 $dir_mode = get_dir_mode($make_group_also);
536 chmod ($dir_mode, $home_dir) ||
537 &cleanup("chmod $dir_mode $home_dir: $!\n");
538
539 if ($config{"skel"}) {
540 printf _("Copying files from %s\n"),$config{skel} if $verbose;
541 open(FIND, "cd $config{skel}; find . ! -name '*.dpkg-*' -print |")
542 || &cleanup("fork for find: $!\n");
543 while (<FIND>) {
544 chop;
545 next if ($_ eq ".");
546 &copy_to_dir($config{"skel"}, $_, $home_dir, $new_uid,
547 $new_gid, ($config{"setgid_home"} eq "yes"));
548 }
549 }
550 }
551
552 if ($ask_passwd) {
553 &systemcall('/usr/bin/passwd', $new_name);
554 } else {
555 if(!$disabled_login) {
556 &systemcall('/usr/sbin/usermod', '-p', '*', $new_name);
557 }
558 }
559
560 if (defined($new_gecos)) {
561 &ch_gecos($new_gecos);
562 }
563 else {
564 for (;;) {
565 &systemcall('/usr/bin/chfn', $new_name);
566 print _("Is the information correct? [y/N] ");
567 chop ($answer=<STDIN>);
568 last if ($answer eq _("y"));
569 }
570 }
571
572 if ($config{"quotauser"}) {
573 printf _("Setting quota from %s.\n"),$config{quotauser};
574 &systemcall('/usr/sbin/edquota', '-p', $config{quotauser}, $new_name);
575 }
576
577 &systemcall('/usr/local/sbin/adduser.local', $new_name, $new_uid,
578 $new_gid, $home_dir) if (-x "/usr/local/sbin/adduser.local");
579
580 exit 0;
581 }
582
583
584 # calculate home directory
585 sub homedir {
586 my $dir = $config{"dhome"};
587 $dir .= '/' . $_[1] if ($config{"grouphomes"} =~ /yes/i);
588 $dir .= '/' . substr($_[0],0,1) if ($config{"letterhomes"} =~ /yes/i);
589 $dir .= '/' . $_[0];
590 }
591
592
593 # create a directory and all leading directories
594 sub mktree {
595 my($tree) = @_;
596 my($done, @path);
597 my $default_dir_mode = 0755;
598
599 $tree =~ s:^/*(.*)/*$:$1:; # chop off leading & trailing slashes
600 @path = split(/\//, $tree);
601
602 $done = "";
603 while (@path) {
604 $done .= '/' . shift(@path);
605 -d $done || mkdir($done, $default_dir_mode) || return 0;
606 }
607 1;
608 }
609
610 sub existing_user_ok {
611 # returns 1 if
612 # - the user doesn't exist or
613 # - a system user is to be created
614 # - the account already exists as a system user and
615 # - if an explicit UID is given, that UID matches the existing user.
616 my($new_name,$new_uid) = @_;
617 my ($dummy1,$dummy2,$uid);
618 if (($dummy1,$dummy2,$uid) = getpwnam($new_name)) {
619 if( defined($new_uid) && $uid == $new_uid ) {
620 ##+#print "uid";
621 return 1;
622 }
623 if( $uid >= $config{"first_system_uid"} &&
624 $uid <= $config{"last_system_uid" } ) {
625 ##+#print "range";
626 return 1;
627 }
628 } else {
629 return 0;
630 }
631 }
632
633 sub existing_group_ok {
634 # returns 1 if
635 # - the group doesn't exist or
636 # - a system group is to be created
637 # - the group already exists as a system group and
638 # - if an explicit GID is given, that GID matches the existing group.
639 my($new_name,$new_gid) = @_;
640 my ($dummy1,$dummy2,$gid);
641 if (($dummy1,$dummy2,$gid) = getgrnam($new_name)) {
642 if( defined($new_gid) && $gid == $new_gid ) {
643 return 1;
644 }
645 if( $gid >= $config{"first_system_gid"} &&
646 $gid <= $config{"last_system_gid" } ) {
647 return 1;
648 }
649 } else {
650 return 0;
651 }
652 }
653
654 sub check_user_group {
655 my ($system) = @_;
656 if( !$system || !existing_user_ok($new_name, $new_uid) ) {
657 if( defined getpwnam($new_name) ) {
658 if( $system ) {
659 dief(_("The user %s\' already exists, and is not a system user.\n"),$new_name);
660 } else {
661 dief(_("The user %s\' already exists.\n"),$new_name);
662 }
663 }
664 dief(_("The UID %s' already exists.\n"),$new_uid)
665 if (defined($new_uid) && getpwuid($new_uid));
666 }
667 if ($make_group_also) {
668 if( !$system || !existing_group_ok($new_name, $new_uid) ) {
669 dief(_("The group %s' already exists.\n"),$new_name)
670 if (defined getgrnam($new_name));
671 dief(_("The GID %s' already exists.\n"),$new_uid)
672 if (defined($new_uid) && defined(getgrgid($new_uid)));
673 }
674 }
675 else {
676 dief(_("The group `%s' doesn't exist.\n"),$ingroup_name)
677 if ($ingroup_name && !defined(getgrnam($ingroup_name)));
678 dief(_("The GID `%s' doesn't exist.\n"),$new_gid)
679 if (defined($new_gid) && !defined(getgrgid($new_gid)));
680 }
681 }
682
683
684 # copy files, directories, symlinks
685 sub copy_to_dir {
686 my($fromdir, $file, $todir, $newu, $newg, $sgiddir) = @_;
687
688 if (-l "$fromdir/$file") {
689 symlink(readlink("$fromdir/$file"), "$todir/$file")
690 || &cleanup("symlink: $!\n");
691 return;
692 }
693 elsif (-f "$fromdir/$file") {
694 open (FILE, "$fromdir/$file") || &cleanup("open $fromdir/$file: $!");
695 open (NEWFILE, ">$todir/$file") || &cleanup("open >$todir/$file: $!");
696
697 (print NEWFILE <FILE>) || &cleanup("print $todir/$file: $!");
698 close FILE;
699 close(NEWFILE) || &cleanup("close $todir/$file ");
700
701 }
702 elsif (-d "$fromdir/$file") {
703 mkdir("$todir/$file", 700) || &cleanup("mkdir: $!");
704 }
705 else {
706 &cleanup("Can't deal with $fromdir/$file. "
707 ."Not a dir, file, or symlink.\n");
708 }
709
710 chown($newu, $newg, "$todir/$file")
711 || &cleanup("chown $newu:$newg $todir/$file: $!\n");
712 $perm = (stat("$fromdir/$file"))[2] & 07777;
713 $perm |= 02000 if (-d "$fromdir/$file" && ($perm & 010) && $sgiddir);
714 chmod($perm, "$todir/$file") || &cleanup("chmod $todir/$file: $!\n");
715 }
716
717
718 # is name ok?
719 sub checkname {
720 my ($name) = @_;
721 if ($allow_badname && $name !~ /^[A-Za-z_][-_A-Za-z0-9]*\$?$/) {
722 print STDERR
723 "$0: ",_("To avoid problems, the username should consist of a letter or
724 underscore followed by letters, digits, underscores, and dashes. For
725 compatibility with Samba machine accounts also \$ is supported at the
726 end of the username\n");
727 exit 1;
728 }
729 elsif ($name !~ /^[a-z][a-z0-9\-]*$/) {
730 if (!$allow_badname) {
731 print STDERR
732 "$0: ",_("Please enter a username consisting of a lower case letter
733 followed by lower case letters and numbers. Use the `--force-badname'
734 option to allow underscores, and uppercase.\n");
735 exit 1;
736 }
737 print _("Allowing use of questionable username.\n") if ($verbose);
738 }
739 }
740
741
742 # return the smallest X such that
743 # $min <= X <= $max, and X is not an element of @ids
744 # or -1 if no such X
745 sub first_avail_id {
746 my ($min, $max, @ids) = @_;
747 @ids = sort {$a <=> $b} @ids;
748 printf _("Selecting from %s %s (%s).\n"),$min,$max,join(",",@ids) if $debugging;
749
750 while ($min <= $max) {
751 return $min if ($min < $ids[0] || @ids==0);
752 shift @ids if ($min > $ids[0]);
753 $min++ if ($min == $ids[0]);
754 }
755
756 -1; # nothing available
757 }
758
759
760 # return an array containing all the GIDs
761 sub get_current_gids {
762 my(@gids, $gid);
763 setgrent;
764 push @gids, $gid while defined($gid = (getgrent)[2]);
765 endgrent;
766 @gids;
767 }
768
769
770 # return an array containing all the UIDs
771 sub get_current_uids {
772 my(@uids, $uid);
773 setpwent;
774 push @uids, $uid while defined($uid = (getpwent)[2]);
775 endpwent;
776 @uids;
777 }
778
779 sub ch_gecos {
780 my $gecos = shift;
781 if($gecos =~ /,/)
782 {
783 my($gecos_name,$gecos_room,$gecos_work,$gecos_home,$gecos_other)
784 = split(/,/,$gecos);
785
786 &systemcall('/usr/bin/chfn', '-f', $gecos_name, '-r', $gecos_room, $new_name);
787 &systemcall('/usr/bin/chfn','-w',$gecos_work,$new_name)
788 if(defined($gecos_work));
789 &systemcall('/usr/bin/chfn','-h',$gecos_home,$new_name)
790 if(defined($gecos_home));
791 &systemcall('/usr/bin/chfn','-o',$gecos_other,$new_name)
792 if(defined($gecos_other));
793 }
794 else
795 {
796 &systemcall('/usr/bin/chfn', '-f', $gecos, $new_name);
797 }
798 }
799
800 # user is member of group?
801 sub user_is_member {
802 my($user, $group) = @_;
803 for (split(/ /, (getgrnam($group))[3])) {
804 return 1 if ($user eq $_);
805 }
806 0;
807 }
808
809
810 sub cleanup {
811 print "@{_}Cleaning up.\n";
812 if ($undohome) {
813 printf _("Removing directory `%s'\n"),$undohome;
814 system('rm', '-rf', $undohome);
815 }
816 if ($undouser) {
817 printf _("Removing user `%s'.\n"),$undouser;
818 system('userdel', $undouser);
819 }
820 if ($undogroup) {
821 printf _("Removing group `%s'.\n"),$undogroup;
822 system('groupdel', $undogroup);
823 }
824 # do we need to invalidate the nscd cache here, too?
825 exit 1;
826 }
827
828 sub handler {
829 my($sig) = @_;
830 &cleanup("Caught a SIG$sig.\n");
831 }
832
833
834 sub version {
835 print "$0: add a user or group to the system. Version VERSION
836 Copyright (C) 1997, 1998, 1999 Guy Maor <maor\@debian.org>
837 Copyright (C) 1995 Ian Murdock <imurdock\@gnu.ai.mit.edu>,
838 Ted Hajek <tedhajek\@boombox.micro.umn.edu>,
839
840 This program is free software; you can redistribute it and/or modify
841 it under the terms of the GNU General Public License as published by
842 the Free Software Foundation; either version 2 of the License, or (at
843 your option) any later version.
844
845 This program is distributed in the hope that it will be useful, but
846 WITHOUT ANY WARRANTY; without even the implied warranty of
847 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
848 General Public License, /usr/share/common-licenses/GPL, for more details.
849 ";
850 }
851
852 sub usage {
853 printf _(
854 "adduser [--home DIR] [--shell SHELL] [--no-create-home] [--uid ID]
855 [--firstuid ID] [--lastuid ID] [--gecos GECOS] [--ingroup GROUP | --gid ID]
856 [--disabled-password] [--disabled-login] user
857 Add a normal user
858
859 adduser --system [--home DIR] [--shell SHELL] [--no-create-home] [--uid ID]
860 [--gecos GECOS] [--group | --ingroup GROUP | --gid ID] [--disabled-password]
861 [--disabled-login] user
862 Add a system user
863
864 adduser --group [--gid ID] group
865 addgroup [--gid ID] group
866 Add a user group
867
868 addgroup --system [--gid ID] group
869 Add a system group
870
871 adduser user group
872 Add an existing user to an existing group
873
874 Global configuration is in the file %s.
875 Other options are [--quiet] [--force-badname] [--help] [--version] [--conf
876 FILE].
877 "),$defaults;
878 }
879
880 sub systemcall {
881 my $c = join(' ', @_);
882 print "$c\n" if $debugging;
883 if (system(@_)) {
884 &cleanup("$0: `$c' returned error code " . ($?>>8) . ". Aborting.\n")
885 if ($?>>8);
886 &cleanup("$0: `$c' exited from signal " . ($?&255) . ". Aborting.\n");
887 }
888 }
889
890 sub get_dir_mode
891 {
892 my $setgid = shift;
893 # no longer make home directories setgid per default (closes: #64806)
894 $setgid = 0 unless $config{"setgid_home"} eq "yes";
895
896 my $dir_mode = $config{"dir_mode"};
897 if(!defined($dir_mode) || ! ($dir_mode =~ /[0-7]{3}/ ||
898 $dir_mode =~ /[0-7]{4}/))
899 {
900 $dir_mode = $setgid ? 2755 : 0755;
901 }
902 else
903 {
904 $dir_mode = $config{"dir_mode"};
905 if($setgid && (length($dir_mode) == 3 || $dir_mode =~ /^[0-1|4-5][0-7]{3}$/))
906 {
907 $dir_mode += 2000;
908 }
909 }
910 return oct($dir_mode);
911 }
912
913 # Local Variables:
914 # mode:cperl
915 # cperl-indent-level:4
916 # End:
917
918

Properties

Name Value
svn:executable

  ViewVC Help
Powered by ViewVC 1.1.5