/[adduser]/trunk/adduser
ViewVC logotype

Contents of /trunk/adduser

Parent Directory Parent Directory | Revision Log Revision Log


Revision 4 - (show annotations) (download)
Fri Jun 6 21:34:47 2003 UTC (9 years, 11 months ago) by rb
File size: 20993 byte(s)
Load adduser-3.8 into trunk.
1 #!/usr/bin/perl -w
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 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 # General scheme of the program adapted by the original debian 'adduser'
12 # program by Ian A. Murdock <imurdock@gnu.ai.mit.edu>.
13 #
14 # This program is free software; you can redistribute it and/or modify
15 # it under the terms of the GNU General Public License as published by
16 # the Free Software Foundation; either version 2 of the License, or
17 # (at your option) any later version.
18 #
19 # This program is distributed in the hope that it will be useful,
20 # but WITHOUT ANY WARRANTY; without even the implied warranty of
21 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 # GNU General Public License for more details.
23 #
24 # You should have received a copy of the GNU General Public License
25 # along with this program; if not, write to the Free Software
26 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 #
28 #
29 ####################
30 # the program can be called as:
31 #
32 # adduser [--home DIR] [--uid ID] [--ingroup GROUP | --gid ID]
33 # [--disabled-password] [--gecos GECOS] user
34 # add a normal user to the system
35 # example: adduser fred
36 # $action = "adduser"
37 #
38 # adduser --group [--gid ID] group
39 # addgroup [--gid ID] group
40 # add a system group
41 # example: addgroup --quiet www-data
42 # $action = "addgroup"
43 #
44 # adduser --system [--home DIR] [--uid ID] [--group | --ingroup GROUP
45 # | --gid ID] [--disabled-password] [--gecos GECOS] user
46 # add a system user. Create a like-named, like-id'd group with
47 # --group, add to an existing group with --ingroup or --gid. Add
48 # to "nogroup" with neither.
49 # example: adduser --system --home /home/gopher-data --group gopher
50 # $action = "addsysuser"
51 #
52 # adduser user group
53 # add the existing user to an existing group.
54 # $action = "addusertogroup"
55 #
56 # all commands take the following options:
57 # --quiet don't give progress information on STDOUT
58 # --force-badname disable checking of names for funny characters
59 # --help usage message
60 # --version version number and copyright
61 # --conf FILE use FILE instead of /etc/adduser.conf
62 ############
63
64 $verbose = 1; # should we be verbose?
65 $allow_badname = 0; # should we allow bad names?
66 $ask_passwd = 1; # ask for a passwd?
67
68 $defaults = "/etc/adduser.conf";
69 $nogroup_id = getgrnam("nogroup") || 65534;
70 $0 =~ s+.*/++;
71
72 $config{"dshell"} = "/bin/bash";
73 $config{"first_system_uid"} = 100;
74 $config{"last_system_uid"} = 999;
75 $config{"first_uid"} = 1000;
76 $config{"last_uid"} = 29999;
77 $config{"dhome"} = "/home";
78 $config{"skel"} = "/etc/skel";
79 $config{"usergroups"} = "yes";
80 $config{"users_gid"} = "100";
81 $config{"grouphomes"} = "no";
82 $config{"letterhomes"} = "no";
83 $config{"quotauser"} = "";
84
85 $action = $0 eq "addgroup" ? "addgroup" : "adduser";
86
87 while ($arg = shift(@ARGV)) {
88 die "$0: No options allowed after names.\n"
89 if ($names[0] && $arg =~ /^--/);
90 if ($arg eq "--quiet") {
91 $verbose = 0;
92 } elsif ($arg eq "--force-badname") {
93 $allow_badname = 1;
94 } elsif ($arg eq "--help") {
95 &usage();
96 exit 0;
97 } elsif ($arg eq "--version") {
98 &version();
99 exit 0;
100 } elsif ($arg eq "--system") {
101 $action = "addsysuser";
102 } elsif ($arg eq "--group") {
103 $found_group_opt = 1;
104 } elsif ($arg eq "--ingroup") {
105 die "$0: --ingroup requires an argument.\n"
106 if (!($ingroup_name = shift(@ARGV)));
107 } elsif ($arg eq "--home") {
108 die "$0: --home requires an argument.\n"
109 if (!($special_home = shift(@ARGV)));
110 print "$0: Warning: The home dir you specified already exists.\n"
111 if (-d $special_home && $verbose);
112 die "$0: The home dir must be an absolute path.\n"
113 if ($special_home !~ m+^/+ );
114 } elsif ($arg eq "--gecos") {
115 $new_gecos = shift(@ARGV);
116 } elsif ($arg eq "--disabled-password") {
117 $ask_passwd = 0;
118 } elsif ($arg eq "--uid") {
119 die "$0: --uid requires a numeric argument.\n"
120 if (!($new_uid = shift(@ARGV)) || $new_uid !~ /^\d+$/);
121 } elsif ($arg eq "--gid") {
122 die "$0: --gid requires a numeric argument.\n"
123 if (!($new_gid = shift(@ARGV)) || $new_gid !~ /^\d+$/);
124 } elsif ($arg eq "--conf") {
125 die "$0: --conf requires an argument.\n"
126 if (!($defaults = shift(@ARGV)));
127 die "$0: `$defaults' doesn't exist.\n"
128 if (! -f $defaults);
129 } elsif ($arg eq "--debug") {
130 $debugging = 1;
131 } elsif ($arg =~ /^--/) { # bad argument!
132 die "$0: Unknown argument `$arg'.\n";
133 } else { # it's a username
134 push (@names, $arg);
135 }
136 }
137
138 die "$0: Only root may add a user or group to the system.\n" if ($> != 0);
139
140 die "$0: I need a name to add.\n" if (@names == 0);
141 die "$0: No more than two names.\n" if (@names > 2);
142 if (@names == 2) { # must be addusertogroup
143 die "$0: Specify only one name in this mode.\n"
144 if ($action eq "addsysuser" || $found_group_opt);
145 $action = "addusertogroup";
146 $existing_user = shift (@names);
147 $existing_group = shift (@names);
148 }
149 else {
150 $new_name = shift (@names);
151 }
152
153 if ($found_group_opt) {
154 if ($action eq "addsysuser") {
155 $make_group_also = 1;
156 }
157 else {
158 $action = "addgroup";
159 }
160 }
161 die "$0: --group, --ingroup, and --gid options are mutually exclusive.\n" if
162 ($action ne "addgroup" &&
163 defined($found_group_opt) +defined($ingroup_name) +defined($new_gid) > 1);
164
165
166 #####
167 # OK, we've processed the arguments. $action equals one of the following,
168 # and the appropriate variables have been set:
169 #
170 # $action = "adduser"
171 # $new_name - the name of the new user.
172 # $ingroup_name | $new_gid - the group to add the user to
173 # $special_home, $new_uid, $new_gecos - optional overrides
174 # $action = "addgroup"
175 # $new_name - the name of the new group
176 # $new_gid - optional override
177 # $action = "addsysuser"
178 # $new_name - the name of the new user
179 # $make_group_also | $ingroup_name | $new_gid | 0 - which group
180 # $special_home, $new_uid, $new_gecos - optional overrides
181 # $action = "addusertogroup"
182 # $existing_user - the user to be added
183 # $existing_group - the group to add her to
184 #####
185
186 &read_config($defaults);
187 &checkname($new_name) if $new_name;
188 $SIG{'INT'} = $SIG{'QUIT'} = $SIG{'HUP'} = 'handler';
189
190 ##############
191 ## addgroup ##
192 ##############
193 if ($action eq "addgroup") {
194 die "$0: The group `$new_name' already exists.\n"
195 if (getgrnam($new_name));
196 die "$0: The GID `$new_gid' is already in use.\n"
197 if (defined($new_gid) && getgrgid($new_gid));
198 if (!defined($new_gid)) {
199 $new_gid = &first_avail_id($config{"first_system_uid"},
200 $config{"last_system_uid"},
201 &get_current_gids);
202 die "$0: No GID is available in the range ",
203 "$config{\"first_system_uid\"} - $config{\"last_system_uid\"}\n",
204 "(FIRST_SYS_UID - LAST_SYS_UID). ",
205 "Group `$new_name' not created.\n" if ($new_gid == -1);
206 }
207
208 print "Adding group $new_name ($new_gid)...\n" if $verbose;
209 &systemcall('groupadd', '-g', $new_gid, $new_name);
210 print "Done.\n" if $verbose;
211 exit 0;
212 }
213
214
215 ####################
216 ## addusertogroup ##
217 ####################
218 elsif ($action eq "addusertogroup") {
219 die "$0: The user `$existing_user' doesn't exist.\n"
220 if (!getpwnam($existing_user));
221 die "$0: The group `$existing_group' doesn't exist.\n"
222 if (!getgrnam($existing_group));
223 if (&user_is_member($existing_user, $existing_group)) {
224 print "The user `$existing_user' is already a member of ",
225 "`$existing_group'.\n" if $verbose;
226 exit 0; # not really an error
227 }
228
229 print "Adding user $existing_user to group $existing_group...\n"
230 if $verbose;
231 &systemcall('usermod', '-G',
232 join(",", get_users_groups($existing_user), $existing_group),
233 $existing_user);
234 print "Done.\n" if $verbose;
235 exit 0;
236 }
237
238
239 ################
240 ## addsysuser ##
241 ################
242 elsif ($action eq "addsysuser") {
243 $new_gid = $nogroup_id
244 if (!$ingroup_name && !defined($new_gid) && !$make_group_also);
245 &check_user_group();
246 print "Adding system user $new_name...\n" if $verbose;
247
248 if (!defined($new_uid) && $make_group_also) {
249 $new_uid = &first_avail_id($config{"first_system_uid"},
250 $config{"last_system_uid"},
251 &get_current_uids, &get_current_gids);
252 die "$0: No UID/GID pair is available in the range ",
253 "$config{\"first_system_uid\"} - $config{\"last_system_uid\"}\n",
254 "(FIRST_SYS_UID - LAST_SYS_UID). ",
255 "User `$new_name' not created.\n" if ($new_uid == -1);
256 $new_gid = $new_uid;
257 $ingroup_name = $new_name;
258 }
259 elsif (!defined($new_uid) && !$make_group_also) {
260 $new_uid = &first_avail_id($config{"first_system_uid"},
261 $config{"last_system_uid"},
262 &get_current_uids);
263 die "$0: No UID is available in the range ",
264 "$config{\"first_system_uid\"} - $config{\"last_system_uid\"}\n",
265 "(FIRST_SYS_UID - LAST_SYS_UID). ",
266 "User `$new_name' not created.\n" if ($new_uid == -1);
267 if (defined($new_gid)) { $ingroup_name = getgrgid($new_gid); }
268 elsif ($ingroup_name) { $new_gid = getgrnam($ingroup_name); }
269 else { die "Internal error"; }
270 }
271 else {
272 if (defined($new_gid)) { $ingroup_name = getgrgid($new_gid); }
273 elsif ($ingroup_name) { $new_gid = getgrnam($ingroup_name); }
274 elsif ($make_group_also){ $new_gid=$new_uid; $ingroup_name=$new_name; }
275 else { die "Internal error"; }
276 }
277
278 if ($make_group_also) {
279 print "Adding new group $new_name ($new_gid).\n" if $verbose;
280 $undogroup = $new_name;
281 &systemcall('groupadd', '-g', $new_gid, $new_name);
282 }
283
284 print "Adding new user $new_name ($new_uid) with group $ingroup_name.\n"
285 if $verbose;
286 $home_dir = $special_home || &homedir($new_name, $ingroup_name);
287 $undouser = $new_name;
288 &systemcall('useradd', '-d', $home_dir, '-g', $ingroup_name, '-s',
289 '/bin/false', '-u', $new_uid, $new_name);
290 &systemcall('chfn', '-f', $new_gecos, $new_name) if ($new_gecos);
291
292 if (-d $home_dir) {
293 print "Home directory $home_dir already exists.\n" if $verbose;
294 } else {
295 print "Creating home directory $home_dir.\n" if $verbose;
296 $undohome = $home_dir;
297 &mktree($home_dir) || &cleanup("Couldn't create $home_dir: $!.\n");
298 chown($new_uid, $new_gid, $home_dir)
299 || &cleanup("chown $new_uid:$new_gid $home_dir: $!\n");
300 $dir_mode = $make_group_also ? 02755 : 0755;
301 chmod ($dir_mode, $home_dir) ||
302 &cleanup("chmod $dir_mode $home_dir: $!\n");
303 }
304
305 exit 0;
306 }
307
308
309 #############
310 ## adduser ##
311 #############
312 elsif ($action eq "adduser") {
313 if (!$ingroup_name && !defined($new_gid)) {
314 if ($config{"usergroups"} eq "yes") { $make_group_also = 1; }
315 else { $new_gid = $config{"users_gid"}; }
316 }
317 &check_user_group();
318 print "Adding user $new_name...\n" if $verbose;
319
320 if (!defined($new_uid) && $make_group_also) {
321 $new_uid = &first_avail_id($config{"first_uid"},
322 $config{"last_uid"},
323 &get_current_uids, &get_current_gids);
324 die "$0: No UID/GID pair is available in the range ",
325 "$config{\"first_uid\"} - $config{\"last_uid\"}\n",
326 "(FIRST_UID - LAST_UID). ",
327 "User `$new_name' not created.\n" if ($new_uid == -1);
328 $new_gid = $new_uid;
329 $ingroup_name = $new_name;
330 }
331 elsif (!defined($new_uid) && !$make_group_also) {
332 $new_uid = &first_avail_id($config{"first_uid"},
333 $config{"last_uid"},
334 &get_current_uids);
335 die "$0: No UID is available in the range ",
336 "$config{\"first_uid\"} - $config{\"last_uid\"}\n",
337 "(FIRST_UID - LAST_UID). ",
338 "User `$new_name' not created.\n" if ($new_uid == -1);
339 if (defined($new_gid)) { $ingroup_name = getgrgid($new_gid); }
340 elsif ($ingroup_name) { $new_gid = getgrnam($ingroup_name); }
341 else { die "Internal error"; }
342 }
343 else {
344 if (defined($new_gid)) { $ingroup_name = getgrgid($new_gid); }
345 elsif ($ingroup_name) { $new_gid = getgrnam($ingroup_name); }
346 elsif ($make_group_also){ $new_gid=$new_uid; $ingroup_name=$new_name; }
347 else { die "Internal error"; }
348 }
349
350 if ($make_group_also) {
351 print "Adding new group $new_name ($new_gid).\n" if $verbose;
352 $undogroup = $new_name;
353 &systemcall('groupadd', '-g', $new_gid, $new_name);
354 }
355
356 print "Adding new user $new_name ($new_uid) with group $ingroup_name.\n"
357 if $verbose;
358 $home_dir = $special_home || &homedir($new_name, $ingroup_name);
359 $undouser = $new_name;
360 &systemcall('useradd', '-d', $home_dir, '-g', $ingroup_name, '-s',
361 $config{dshell}, '-u', $new_uid, $new_name);
362
363 if (-d $home_dir) {
364 print "Home directory $home_dir already exists. Not copying from",
365 " $config{skel}\n" if $verbose;
366 }
367 else {
368 print "Creating home directory $home_dir.\n" if $verbose;
369 $undohome = $home_dir;
370 &mktree($home_dir) || &cleanup("Couldn't create $home_dir: $!.\n");
371 chown($new_uid, $new_gid, $home_dir)
372 || &cleanup("chown $new_uid:$new_gid $home_dir: $!\n");
373 $dir_mode = $make_group_also ? 02755 : 0755;
374 chmod ($dir_mode, $home_dir) ||
375 &cleanup("chmod $dir_mode $home_dir: $!\n");
376
377 if ($config{"skel"}) {
378 print "Copying files from $config{skel}\n" if $verbose;
379 open(FIND, "cd $config{skel}; find . -print |")
380 || &cleanup("fork for find: $!\n");
381 while (<FIND>) {
382 chop;
383 next if ($_ eq ".");
384 &copy_to_dir($config{"skel"}, $_, $home_dir, $new_uid,
385 $new_gid, $make_group_also);
386 }
387 }
388 }
389
390 if ($ask_passwd) {
391 &systemcall('passwd', $new_name);
392 }
393
394 if ($new_gecos) {
395 &systemcall('chfn', '-f', $new_gecos, $new_name);
396 }
397 else {
398 for (;;) {
399 &systemcall('chfn', $new_name);
400 print "Is the information correct? [y/n] ";
401 chop ($answer=<STDIN>);
402 last if ($answer =~ /^y/i);
403 }
404 }
405
406 if ($config{"quotauser"}) {
407 print "Setting quota from $config{quotauser}.\n";
408 &systemcall('edquota', '-p', $config{quotauser}, $new_name);
409 }
410
411 &systemcall('/usr/local/sbin/adduser.local', $new_name, $new_uid,
412 $new_gid, $home_dir) if (-x "/usr/local/sbin/adduser.local");
413
414 exit 0;
415 }
416
417
418 # calculate home directory
419 sub homedir {
420 my $dir = $config{"dhome"};
421 $dir .= '/' . $_[1] if ($config{"grouphomes"} =~ /yes/i);
422 $dir .= '/' . substr($_[0],0,1) if ($config{"letterhomes"} =~ /yes/i);
423 $dir .= '/' . $_[0];
424 }
425
426
427 # create a directory and all leading directories
428 sub mktree {
429 my($tree) = @_;
430 my($done, @path);
431 my $default_dir_mode = 0755;
432
433 $tree =~ s:^/*(.*)/*$:$1:; # chop off leading & trailing slashes
434 @path = split(/\//, $tree);
435
436 $done = "";
437 while (@path) {
438 $done .= '/' . shift(@path);
439 -d $done || mkdir($done, $default_dir_mode) || return 0;
440 }
441 1;
442 }
443
444
445 sub check_user_group() {
446 die "$0: The user `$new_name' already exists.\n" if (getpwnam($new_name));
447 die "$0: The UID `$new_uid' already exists.\n"
448 if (defined($new_uid) && getpwuid($new_uid));
449 if ($make_group_also) {
450 die "$0: The group `$new_name' already exists.\n"
451 if (getgrnam($new_name));
452 die "$0: The GID `$new_uid' already exists.\n"
453 if (defined($new_uid) && getgrgid($new_uid));
454 }
455 else {
456 die "$0: The group `$ingroup_name' doesn't exist.\n"
457 if ($ingroup_name && !getgrnam($ingroup_name));
458 die "$0: The GID `$new_gid' doesn't exist.\n"
459 if (defined($new_gid) && !getgrgid($new_gid));
460 }
461 }
462
463
464 # copy files, directories, symlinks
465 sub copy_to_dir {
466 my($fromdir, $file, $todir, $newu, $newg, $sgiddir) = @_;
467
468 if (-l "$fromdir/$file") {
469 symlink(readlink("$fromdir/$file"), "$todir/$file")
470 || &cleanup("symlink: $!\n");
471 }
472 elsif (-f "$fromdir/$file") {
473 open (FILE, "$fromdir/$file") || &cleanup("open $fromdir/$file: $!");
474 open (NEWFILE, ">$todir/$file") || &cleanup("open >$todir/$file: $!");
475
476 (print NEWFILE <FILE>) || &cleanup("print $todir/$file: $!");
477 close FILE;
478 close(NEWFILE) || &cleanup("close $todir/$file ");
479
480 }
481 elsif (-d "$fromdir/$file") {
482 mkdir("$todir/$file", 700) || &cleanup("mkdir: $!");
483 }
484 else {
485 &cleanup("Can't deal with $fromdir/$file. "
486 ."Not a dir, file, or symlink.\n");
487 }
488
489 chown($newu, $newg, "$todir/$file")
490 || &cleanup("chown $newu:$newg $todir/$file: $!\n");
491 $perm = (stat("$fromdir/$file"))[2] & 07777;
492 $perm |= 02000 if (-d "$fromdir/$file" && ($perm & 010) && $sgiddir);
493 chmod($perm, "$todir/$file") || &cleanup("chmod $todir/$file: $!\n");
494 }
495
496
497 # is name ok?
498 sub checkname {
499 my ($name) = @_;
500 if ($allow_badname && $name !~ /^[A-Za-z_][-_A-Za-z0-9]*$/) {
501 print STDERR
502 "$0: To avoid problems, the username should consist of a letter or
503 underscore followed by letters, digits, underscores, and dashes.\n";
504 exit 1;
505 }
506 elsif ($name !~ /^[a-z][a-z0-9]*$/) {
507 if (!$allow_badname) {
508 print STDERR
509 "$0: Please enter a username consisting of a lower case letter
510 followed by lower case letters and numbers. Use the `--force-badname'
511 option to allow underscores, dashes, and uppercase.\n";
512 exit 1;
513 }
514 print "Allowing use of questionable username.\n" if ($verbose);
515 }
516 }
517
518
519 # return the smallest X such that
520 # $min <= X <= $max, and X is not an element of @ids
521 # or -1 if no such X
522 sub first_avail_id {
523 my ($min, $max, @ids) = @_;
524 @ids = sort {$a <=> $b} @ids;
525 print "Selecting from $min $max (" . join(",",@ids) . ").\n" if $debugging;
526
527 while ($min <= $max) {
528 return $min if ($min < $ids[0] || @ids==0);
529 shift @ids if ($min > $ids[0]);
530 $min++ if ($min == $ids[0]);
531 }
532
533 -1; # nothing available
534 }
535
536
537 # return an array containing all the GIDs
538 sub get_current_gids {
539 my(@gids, $gid);
540 setgrent;
541 push @gids, $gid while defined($gid = (getgrent)[2]);
542 endgrent;
543 @gids;
544 }
545
546
547 # return an array containing all the UIDs
548 sub get_current_uids {
549 my(@uids, $uid);
550 setpwent;
551 push @uids, $uid while defined($uid = (getpwent)[2]);
552 endpwent;
553 @uids;
554 }
555
556
557 # return a user's groups
558 sub get_users_groups {
559 my($user) = @_;
560 my($name,$members,@groups);
561 setgrent;
562 while (($name,$members) = (getgrent)[0,3]) {
563 for (split(/ /, $members)) {
564 if ($user eq $_) {
565 push @groups, $name;
566 last;
567 }
568 }
569 }
570 endgrent;
571 @groups;
572 }
573
574
575 # user is member of group?
576 sub user_is_member {
577 my($user, $group) = @_;
578 for (split(/ /, (getgrnam($group))[3])) {
579 return 1 if ($user eq $_);
580 }
581 0;
582 }
583
584
585 # parse the configuration file
586 sub read_config {
587 my ($conf_file) = @_;
588 my ($var, $lcvar, $val);
589
590 if (! -f $conf_file) {
591 print "$0: $conf_file doesn't exist. Using defaults.\n" if $verbose;
592 return;
593 }
594
595 open (CONF, $conf_file) || die "$0: $conf_file: $!\n";
596 while (<CONF>) {
597 chomp;
598 next if /^#/ || /^\s*$/;
599
600 if ((($var, $val) = /^\s*(\S+)\s*=\s*(.*)/) != 2) {
601 warn "$0: Couldn't parse $conf_file:$..\n";
602 next;
603 }
604 $lcvar = lc $var;
605 if (!defined($config{$lcvar})) {
606 warn "$0: Unknown variable `$var' at $conf_file:$..\n";
607 next;
608 }
609
610 $val =~ s/^"(.*)"$/$1/;
611 $val =~ s/^'(.*)'$/$1/;
612
613 $config{$lcvar} = $val;
614 }
615
616 close CONF || die "$!";
617 }
618
619
620 sub systemcall {
621 my $c = join(' ', @_);
622 print "$c\n" if $debugging;
623 system(@_) && &cleanup("$0: `$c' returned error code $?. Aborting.\n");
624 }
625
626
627 sub cleanup {
628 print "@{_}Cleaning up.\n";
629 if ($undohome) {
630 print "Removing directory `$undohome'\n";
631 system('rm', '-rf', $undohome);
632 }
633 if ($undouser) {
634 print "Removing user `$undouser'.\n";
635 system('userdel', $undouser);
636 }
637 if ($undogroup) {
638 print "Removing group `$undogroup'.\n";
639 system('groupdel', $undogroup);
640 }
641 exit 1;
642 }
643
644
645 sub handler {
646 my($sig) = @_;
647 &cleanup("Caught a SIG$sig.\n");
648 }
649
650
651 sub version {
652 print "$0: add a user or group to the system. Version VERSION
653 Copyright (C) 1997 Guy Maor <maor\@debian.org>
654 Copyright (C) 1995 Ian Murdock <imurdock\@gnu.ai.mit.edu>,
655 Ted Hajek <tedhajek\@boombox.micro.umn.edu>,
656
657 This program is free software; you can redistribute it and/or modify
658 it under the terms of the GNU General Public License as published by
659 the Free Software Foundation; either version 2 of the License, or (at
660 your option) any later version.
661
662 This program is distributed in the hope that it will be useful, but
663 WITHOUT ANY WARRANTY; without even the implied warranty of
664 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
665 General Public License, /usr/doc/copyright/GPL, for more details.
666 ";
667 }
668
669
670 sub usage {
671 print "adduser [--home DIR] [--uid ID] [--ingroup GROUP | --gid ID]
672 [--disabled-password] [--gecos GECOS] user
673 Add a normal user
674
675 adduser --system [--home DIR] [--uid ID] [--group | --ingroup GROUP |
676 --gid ID] [--disabled-password] [--gecos GECOS] user
677 Add a system user
678
679 adduser --group [--gid ID] group
680 addgroup [--gid ID] group
681 Add a system group
682
683 adduser user group
684 Add an existing user to an existing group
685
686 Global configuration is in the file $defaults.
687 Other options are [--quiet] [--force-badname] [--help] [--version] [--conf
688 FILE].
689 ";
690 }

Properties

Name Value
svn:executable

  ViewVC Help
Powered by ViewVC 1.1.5