X-Git-Url: https://git.cameronkatri.com/pw-darwin.git/blobdiff_plain/788534a35335b20f91ba41ffcb295757dd1b717a..9e9dc684797afab66559d22b1d69399d92f3d9f1:/adduser/adduser.perl diff --git a/adduser/adduser.perl b/adduser/adduser.perl index c336009..e70349c 100644 --- a/adduser/adduser.perl +++ b/adduser/adduser.perl @@ -1,7 +1,7 @@ #!/usr/bin/perl # -# Copyright (c) 1995 Wolfram Schneider. All rights reserved. -# Alle Rechte vorbehalten. Es gilt das kontinentaleuropische Urheberrecht. +# Copyright (c) 1995-1996 Wolfram Schneider . Berlin. +# All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions @@ -11,37 +11,31 @@ # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. -# 3. All advertising materials mentioning features or use of this software -# must display the following acknowledgement: -# This product includes software developed by Wolfram Schneider -# 4. The name of the author may not be used to endorse or promote products -# derived from this software without specific prior written permission # -# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# /usr/sbin/adduser - add new user(s) -# -# Email: Wolfram Schneider -# -# $Id: adduser.perl,v 1.12 1996/08/13 21:50:51 wosch Exp $ +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. # +# $FreeBSD$ + # read variables sub variables { $verbose = 1; # verbose = [0-2] - $defaultpasswd = "yes"; # use password for new users + $defaultusepassword = "yes"; # use password authentication for new users + $defaultenableaccount = "yes"; # enable the account by default + $defaultemptypassword = "no"; # don't create an empty password $dotdir = "/usr/share/skel"; # copy dotfiles from this dir $dotdir_bak = $dotdir; - $send_message = "no"; # send message to new user + $send_message = "/etc/adduser.message"; # send message to new user $send_message_bak = '/etc/adduser.message'; $config = "/etc/adduser.conf"; # config file for adduser $config_read = 1; # read config file @@ -61,6 +55,7 @@ sub variables { $defaultshell = 'sh'; # defaultshell if not empty $group_uniq = 'USER'; $defaultgroup = $group_uniq;# login groupname, $group_uniq means username + $defaultclass = ''; $uid_start = 1000; # new users get this uid $uid_end = 32000; # max. uid @@ -72,27 +67,19 @@ sub variables { $pwgid = ''; # $pwgid{pwgid} = username; gid from passwd db $password = ''; # password for new users + $usepassword = ''; # use password-based auth + $useemptypassword = ''; # use an empty password + $enableaccount = ''; # enable or disable account password at creation # group $groupname =''; # $groupname{groupname} = gid $groupmembers = ''; # $groupmembers{gid} = members of group/kommalist $gid = ''; # $gid{gid} = groupname; gid form group db + @group_comments; # Comments in the group file # shell $shell = ''; # $shell{`basename sh`} = sh - # only for me (=Wolfram) - if ($test) { - $home = "/home/w/tmp/adduser/home"; - $etc_shells = "./shells"; - $etc_passwd = "./master.passwd"; - $group = "./group"; - $pwd_mkdb = "pwd_mkdb -p -d ."; - $config = "adduser.conf"; - $send_message = "./adduser.message"; - $logfile = "./log.adduser"; - } - umask 022; # don't give login group write access $ENV{'PATH'} = "/sbin:/bin:/usr/sbin:/usr/bin"; @@ -124,13 +111,13 @@ sub shells_read { } } -# Allow /nonexistant and /bin/date as a valid shell for system utils - push(@list, "/nonexistant"); - push(@shellpref, "no"); - $shell{"no"} = "/nonexistant"; + # Allow /nonexistent and /bin/date as a valid shell for system utils + push(@list, "/nonexistent"); + push(@shellpref, "no") if !grep(/^no$/, @shellpref); + $shell{"no"} = "/nonexistent"; push(@list, "/bin/date"); - push(@shellpref, "date"); + push(@shellpref, "date") if !grep(/^date$/, @shellpref); $shell{"date"} = "/bin/date"; return $err; @@ -143,7 +130,7 @@ sub shells_add { return 1 unless $verbose; foreach $sh (@shellpref) { - # all knowned shells + # all known shells if (!$shell{$sh}) { # shell $sh is not defined as login shell foreach $dir (@path) { @@ -162,7 +149,7 @@ sub shells_add { &append_file($etc_shells, @list) if $#list >= 0; } -# choise your favourite shell an return the shell +# choose your favourite shell and return the shell sub shell_default { local($e,$i,$new_shell); local($sh); @@ -192,7 +179,7 @@ sub shell_default_valid { return $s; } -# return default home partition (f.e. "/home") +# return default home partition (e.g. "/home") # create base directory if nesseccary sub home_partition { local($home) = @_; @@ -225,7 +212,7 @@ sub home_partition_valid { } if (-e $h) { - warn "$h exist, but is it not a directory or symlink!\n" + warn "$h exists, but is not a directory or symlink!\n" unless -d $h || -l $h; warn "$h is not writable!\n" unless -w $h; @@ -239,7 +226,7 @@ sub home_partition_valid { # check for valid passwddb sub passwd_check { - system("$pwd_mkdb $etc_passwd"); + system("$pwd_mkdb -C $etc_passwd"); die "\nInvalid $etc_passwd - cannot add any users!\n" if $?; } @@ -253,18 +240,22 @@ sub passwd_read { while(

) { chop; push(@passwd_backup, $_); + # ignore comments + next if /^\s*$/; + next if /^\s*#/; + ($p_username, $pw, $p_uid, $p_gid, $sh) = (split(/:/, $_))[0..3,9]; - print "$p_username already exist with uid: $username{$p_username}!\n" + print "$p_username already exists with uid: $username{$p_username}!\n" if $username{$p_username} && $verbose; $username{$p_username} = $p_uid; - print "User $p_username: uid $p_uid exist twice: $uid{$p_uid}\n" + print "User $p_username: uid $p_uid exists twice: $uid{$p_uid}\n" if $uid{$p_uid} && $verbose && $p_uid; # don't warn for uid 0 print "User $p_username: illegal shell: ``$sh''\n" if ($verbose && $sh && !$shell{&basename($sh)} && - $p_username !~ /^(bin|uucp|falcon|nobody)$/ && - $sh !~ /\/(pppd|sliplogin)$/); + $p_username !~ /^(news|xten|bin|nobody|uucp)$/ && + $sh !~ /\/(pppd|sliplogin|nologin|nonexistent)$/); $uid{$p_uid} = $p_username; $pwgid{$p_gid} = $p_username; } @@ -280,13 +271,21 @@ sub group_read { while() { chop; push(@group_backup, $_); + # Ignore empty lines + next if /^\s*$/; + # Save comments to restore later + if (/^\s*\#/) { + push(@group_comments, $_); + next; + } + ($g_groupname, $pw, $g_gid, $memb) = (split(/:/, $_))[0..3]; $groupmembers{$g_gid} = $memb; - warn "Groupname exist twice: $g_groupname:$g_gid -> $g_groupname:$groupname{$g_groupname}\n" + warn "Groupname exists twice: $g_groupname:$g_gid -> $g_groupname:$groupname{$g_groupname}\n" if $groupname{$g_groupname} && $verbose; $groupname{$g_groupname} = $g_gid; - warn "Groupid exist twice: $g_groupname:$g_gid -> $gid{$g_gid}:$g_gid\n" + warn "Groupid exists twice: $g_groupname:$g_gid -> $gid{$g_gid}:$g_gid\n" if $gid{$g_gid} && $verbose; $gid{$g_gid} = $g_groupname; } @@ -315,9 +314,9 @@ sub new_users_name { local($name); while(1) { - $name = &confirm_list("Enter username", 1, "a-z0-9", ""); - if (length($name) > 8) { - warn "Username is longer than 8 chars\a\n"; + $name = &confirm_list("Enter username", 1, "a-z0-9_-", ""); + if (length($name) > 16) { + warn "Username is longer than 16 chars\a\n"; next; } last if (&new_users_name_valid($name) eq $name); @@ -328,7 +327,7 @@ sub new_users_name { sub new_users_name_valid { local($name) = @_; - if ($name !~ /^[a-z0-9]+$/) { + if ($name !~ /^[a-z0-9_][a-z0-9_\-]*$/ || $name eq "a-z0-9_-") { warn "Wrong username. " . "Please use only lowercase characters or digits\a\n"; return 0; @@ -368,6 +367,20 @@ sub new_users_shell { return $shell{$sh}; } +# return home (full path) for user +# Note that the home path defaults to $home/$name for batch +sub new_users_home { + local($name) = @_; + local($userhome); + + while(1) { + $userhome = &confirm_list("Enter home directory (full path)", 1, "$home/$name", ""); + last if $userhome =~ /^\//; + warn qq{Home directory "$userhome" is not a full path\a\n}; + } + return $userhome; +} + # return free uid and gid sub new_users_id { local($name) = @_; @@ -380,17 +393,30 @@ sub new_users_id { ! $uid{$u_id_tmp}; if ($uid{$u_id_tmp}) { warn "Uid ``$u_id_tmp'' in use!\a\n"; + $uid_start = $u_id_tmp; + ($u_id, $g_id) = &next_id($name); + next; } else { warn "Wrong uid.\a\n"; } } # use calculated uid - return ($u_id_tmp, $g_id) if $u_id_tmp eq $u_id; + # return ($u_id_tmp, $g_id) if $u_id_tmp eq $u_id; # recalculate gid $uid_start = $u_id_tmp; return &next_id($name); } +# return login class for user +sub new_users_class { + local($def) = @_; + local($class); + + $class = &confirm_list("Enter login class:", 1, $def, ($def, "default")); + $class = "" if $class eq "default"; + return $class; +} + # add user to group sub add_group { local($gid, $name) = @_; @@ -450,29 +476,6 @@ sub new_users_grplogin { return ($group_login, $group_login); } -# return login group -sub new_users_grplogin_batch { - local($name, $defaultgroup) = @_; - local($group_login, $group); - - $group_login = $name; - $group_login = $defaultgroup if $defaultgroup ne $group_uniq; - - if (defined $gid{$group_login}) { - # convert numeric groupname (gid) to groupname - $group_login = $gid{$group_login}; - } - - # if (defined($groupname{$group_login})) { - # &add_group($groupname{$group_login}, $name); - # } - - return $group_login - if defined($groupname{$group_login}) || $group_login eq $name; - warn "Group ``$group_login'' does not exist\a\n"; - return 0; -} - # return other groups (string) sub new_users_groups { local($name, $other_groups) = @_; @@ -524,16 +527,30 @@ sub new_users_groups_valid { # your last change sub new_users_ok { + local ($newpasswd); + # Note that we either show "password disabled" or + # "****" .. we don't show "empty password" since + # the whole point of starring out the password in + # the first place is to stop people looking over your + # shoulder and seeing the password.. -- adrian + if ($usepassword eq "no") { + $newpasswd = "Password disabled"; + } elsif ($enableaccount eq "no") { + $newpasswd = "Password disabled"; + } else { + $newpasswd = "****"; + } print < $crash") || die "Sorry, give up\n"; - $j = join("\n", @passwd_backup); - $j =~ s/\n//; - print R $j . "\n"; - close R; - - system("$pwd_mkdb $crash"); - die "Sorry, give up\n" if $?; - die "Successfully restore $etc_passwd. Exit.\n"; + warn "``$pwd_mkdb'' failed\n"; + exit($? >> 8); } } @@ -576,11 +583,15 @@ sub new_users_group_update { } if ($new_groups || defined($groupname{$group_login}) || - defined($gid{$groupname{$group_login}})) { + defined($gid{$groupname{$group_login}}) && + $gid{$groupname{$group_login}} ne "+") { # new user is member of some groups # new login group is already in name space rename($group, "$group.bak"); #warn "$group_login $groupname{$group_login} $groupmembers{$groupname{$group_login}}\n"; + + # Restore comments from the top of the group file + @a = @group_comments; foreach $e (sort {$a <=> $b} (keys %gid)) { push(@a, "$gid{$e}:*:$e:$groupmembers{$e}"); } @@ -646,20 +657,52 @@ sub sendmessage { sub new_users_password { - # empty password - return "" if $defaultpasswd ne "yes"; - local($password); while(1) { + system("stty -echo"); $password = &confirm_list("Enter password", 1, "", ""); - last if $password ne ""; - last if &confirm_yn("Use an empty password?", "yes"); + system("stty echo"); + print "\n"; + if ($password ne "") { + system("stty -echo"); + $newpass = &confirm_list("Enter password again", 1, "", ""); + system("stty echo"); + print "\n"; + last if $password eq $newpass; + print "They didn't match, please try again\n"; + } + elsif (&confirm_yn("Use an empty password?", "yes")) { + last; + } } return $password; } +sub new_users_use_password { + local ($p) = $defaultusepassword; + $p = &confirm_yn("Use password-based authentication", $defaultusepassword); + return "yes" if (($defaultusepassword eq "yes" && $p) || + ($defaultusepassword eq "no" && !$p)); + return "no"; # otherwise +} + +sub new_users_enable_account { + local ($p) = $defaultenableaccount; + $p = &confirm_yn("Enable account password at creation", $defaultenableaccount); + return "yes" if (($defaultenableaccount eq "yes" && $p) || + ($defaultenableaccount eq "no" && !$p)); + return "no"; # otherwise +} + +sub new_users_empty_password { + local ($p) = $defaultemptypassword; + $p = &confirm_yn("Use an empty password", $defaultemptypassword); + return "yes" if (($defaultemptypassword eq "yes" && $p) || + ($defaultemptypassword eq "no" && !$p)); + return "no"; # otherwise +} sub new_users { @@ -671,11 +714,14 @@ sub new_users { # name: Username # fullname: Full name # sh: shell + # userhome: home path for user # u_id: user id # g_id: group id + # class: login class # group_login: groupname of g_id # new_groups: some other groups - local($name, $group_login, $fullname, $sh, $u_id, $g_id, $new_groups); + local($name, $group_login, $fullname, $sh, $u_id, $g_id, $class, $new_groups); + local($userhome); local($groupmembers_bak, $cryptpwd); local($new_users_ok) = 1; @@ -687,31 +733,72 @@ sub new_users { $name = &new_users_name; $fullname = &new_users_fullname($name); $sh = &new_users_shell; + $userhome = &new_users_home($name); ($u_id, $g_id) = &new_users_id($name); + $class = &new_users_class($defaultclass); ($group_login, $defaultgroup) = &new_users_grplogin($name, $defaultgroup, $new_users_ok); # do not use uniq username and login group $g_id = $groupname{$group_login} if (defined($groupname{$group_login})); + + # The tricky logic: + # If $usepasswd is 0, we use a * as a password + # If $usepasswd is 1, then + # if $enableaccount is 0, we prepend * as a password + # else if $enableaccount is 1 we don't prepend anything + # if $useemptypassword is 0 we ask for a password, + # else we use a blank one + # + # The logic is tasty, I'll give you that, but its flexible and + # it'll stop people shooting themselves in the foot. + $new_groups = &new_users_groups($name, $new_groups); - $password = &new_users_password; + $usepassword = &new_users_use_password; + if ($usepassword eq "no") { + # note that the assignments to enableaccount and + # useemptypassword functionally do the same as + # usepasswd == "no". Just for consistency. + $password = ""; # no password! + $enableaccount = "no"; # doesn't matter here + $useemptypassword = "yes"; # doesn't matter here + } else { + $useemptypassword = &new_users_empty_password; + if ($useemptypassword eq "no") { + $password = &new_users_password; + } + $enableaccount = &new_users_enable_account; + } if (&new_users_ok) { $new_users_ok = 1; $cryptpwd = ""; $cryptpwd = crypt($password, &salt) if $password ne ""; - # obskure perl bug + + if ($usepassword eq "no") { + $cryptpwd = "*"; + } else { + # cryptpwd is valid before this if mess, so if + # blankpasswd is no we don't blank the cryptpwd + if ($useemptypassword eq "yes") { + $cryptpwd = ""; + } + if ($enableaccount eq "no") { + $cryptpwd = "*" . $cryptpwd; + } + } + # obscure perl bug $new_entry = "$name\:" . "$cryptpwd" . - "\:$u_id\:$g_id\::0:0:$fullname:$home/$name:$sh"; + "\:$u_id\:$g_id\:$class\:0:0:$fullname:$userhome:$sh"; &append_file($etc_passwd, "$new_entry"); &new_users_pwdmkdb("$new_entry"); &new_users_group_update; &new_users_passwd_update; print "Added user ``$name''\n"; &new_users_sendmessage; &adduser_log("$name:*:$u_id:$g_id($group_login):$fullname"); - &home_create($name, $group_login); + &home_create($userhome, $name, $group_login); } else { $new_users_ok = 0; } @@ -723,50 +810,42 @@ sub new_users { } } -sub batch { - local($name, $groups, $fullname, $password) = @_; - local($sh); - - $defaultshell = &shell_default_valid($defaultshell); - return 0 unless $home = &home_partition_valid($home); - return 0 if $dotdir ne &dotdir_default_valid($dotdir); - $send_message = &message_default; - - return 0 if $name ne &new_users_name_valid($name); - $sh = $shell{$defaultshell}; - ($u_id, $g_id) = &next_id($name); - $group_login = &new_users_grplogin_batch($name, $defaultgroup); - return 0 unless $group_login; - $g_id = $groupname{$group_login} if (defined($groupname{$group_login})); - ($flag, $new_groups) = &new_users_groups_valid($groups); - return 0 if $flag; - - $cryptpwd = ""; - $cryptpwd = crypt($password, &salt) if $password ne ""; - # obskure perl bug - $new_entry = "$name\:" . "$cryptpwd" . - "\:$u_id\:$g_id\::0:0:$fullname:$home/$name:$sh"; - &append_file($etc_passwd, "$new_entry"); - &new_users_pwdmkdb("$new_entry"); - &new_users_group_update; - &new_users_passwd_update; print "Added user ``$name''\n"; - &sendmessage($name, @message_buffer) if $send_message ne "no"; - &adduser_log("$name:*:$u_id:$g_id($group_login):$fullname"); - &home_create($name, $group_login); -} - # ask for password usage sub password_default { - local($p) = $defaultpasswd; + local($p) = $defaultusepassword; if ($verbose) { - $p = &confirm_yn("Use passwords", $defaultpasswd); + $p = &confirm_yn("Use password-based authentication", $defaultusepassword); $changes++ unless $p; } - return "yes" if (($defaultpasswd eq "yes" && $p) || - ($defaultpasswd eq "no" && !$p)); + return "yes" if (($defaultusepassword eq "yes" && $p) || + ($defaultusepassword eq "no" && !$p)); + return "no"; # otherwise +} + +# ask for account enable usage +sub enable_account_default { + local ($p) = $defaultenableaccount; + if ($verbose) { + $p = &confirm_yn("Enable account password at creation", $defaultenableaccount); + $changes++ unless $p; + } + return "yes" if (($defaultenableaccount eq "yes" && $p) || + ($defaultenableaccount eq "no" && !$p)); return "no"; # otherwise } +# ask for empty password +sub enable_empty_password { + local ($p) = $defaultemptypassword; + if ($verbose) { + $p = &confirm_yn("Use an empty password", $defaultemptypassword); + $changes++ unless $p; + } + return "yes" if (($defaultemptypassword eq "yes" && $p) || + ($defaultemptypassword eq "no" && !$p)); + return "no"; # otherwise +} + # misc sub check_root { die "You are not root!\n" if $< && !$test; @@ -775,8 +854,8 @@ sub check_root { sub usage { warn < 1; # to64 @@ -828,18 +907,16 @@ sub salt { # print banner sub copyright { - print <<'EOF'; -(c) Copyright 1995 Wolfram Schneider -EOF + return; } # hints sub hints { if ($verbose) { - print "Use option ``-silent'' if you don't want see " . - "all warnings & questions.\n\n"; + print "Use option ``-silent'' if you don't want to see " . + "all warnings and questions.\n\n"; } else { - print "Use option ``-verbose'' if you want see more warnings & " . + print "Use option ``-verbose'' if you want to see more warnings and " . "questions \nor try to repair bugs.\n\n"; } } @@ -852,20 +929,22 @@ sub parse_arguments { shift @argv; last if /^--$/; if (/^--?(v|verbose)$/) { $verbose = 1 } - elsif (/^--?(s|silent|q|quit)$/) { $verbose = 0 } + elsif (/^--?(s|silent|q|quiet)$/) { $verbose = 0 } elsif (/^--?(debug)$/) { $verbose = 2 } elsif (/^--?(h|help|\?)$/) { &usage } elsif (/^--?(home)$/) { $home = $argv[0]; shift @argv } elsif (/^--?(shell)$/) { $defaultshell = $argv[0]; shift @argv } elsif (/^--?(dotdir)$/) { $dotdir = $argv[0]; shift @argv } elsif (/^--?(uid)$/) { $uid_start = $argv[0]; shift @argv } + elsif (/^--?(class)$/) { $defaultclass = $argv[0]; shift @argv } elsif (/^--?(group)$/) { $defaultgroup = $argv[0]; shift @argv } elsif (/^--?(check_only)$/) { $check_only = 1 } elsif (/^--?(message)$/) { $send_message = $argv[0]; shift @argv; $sendmessage = 1; } elsif (/^--?(batch)$/) { - @batch = splice(@argv, 0, 4); $verbose = 0; - die "batch: to few arguments\n" if $#batch < 0; + warn "The -batch option is not supported anymore.\n", + "Please use the pw(8) command line tool!\n"; + exit(0); } # see &config_read elsif (/^--?(config_create)$/) { &create_conf; } @@ -925,6 +1004,7 @@ sub adduser_log { return 1 if $logfile eq "no"; local($sec, $min, $hour, $mday, $mon, $year) = localtime; + $year += 1900; $mon++; foreach $e ('sec', 'min', 'hour', 'mday', 'mon', 'year') { @@ -937,17 +1017,28 @@ sub adduser_log { # create HOME directory, copy dotfiles from $dotdir to $HOME sub home_create { - local($name, $group) = @_; - local($homedir) = "$home/$name"; + local($homedir, $name, $group) = @_; + local($rootdir); if (-e "$homedir") { warn "HOME Directory ``$homedir'' already exist\a\n"; return 0; } + # if the home directory prefix doesn't exist, create it + # First, split the directory into a list; then remove the user's dir + @dir = split('/', $homedir); pop(@dir); + # Put back together & strip to get directory prefix + $rootdir = &stripdir(join('/', @dir)); + + if (!&mkdirhier("$rootdir")) { + # warn already displayed + return 0; + } + if ($dotdir eq 'no') { - if (!mkdir("$homedir",0755)) { - warn "mkdir $homedir: $!\n"; return 0; + if (!mkdir("$homedir", 0755)) { + warn "$dir: $!\n"; return 0; } system 'chown', "$name:$group", $homedir; return !$?; @@ -956,7 +1047,7 @@ sub home_create { # copy files from $dotdir to $homedir # rename 'dot.foo' files to '.foo' print "Copy files from $dotdir to $homedir\n" if $verbose; - system("cp -r $dotdir $homedir"); + system("cp -R $dotdir $homedir"); system("chmod -R u+wrX,go-w $homedir"); system("chown -R $name:$group $homedir"); @@ -983,7 +1074,6 @@ sub mkdir_home { local($user_partition) = "/usr"; local($dirname) = &dirname($dir); - -e $dirname || &mkdirhier($dirname); if (((stat($dirname))[0]) == ((stat("/"))[0])){ @@ -1177,15 +1267,15 @@ sub message_create { # # Message file for adduser(8) # comment: ``#'' -# defaultvariables: \$name, \$fullname, \$password +# default variables: \$name, \$fullname, \$password # other variables: see /etc/adduser.conf after # line ``$do_not_delete'' # \$fullname, -your account ``\$name'' was created. Your password is ``\$password''. -Please expire your password. Have fun! +your account ``\$name'' was created. +Have fun! See also chpass(1), finger(1), passwd(1) EOF @@ -1307,7 +1397,9 @@ sub config_write { # prepare some variables $send_message = "no" unless $send_message; - $defaultpasswd = "no" unless $defaultpasswd; + $defaultusepassword = "no" unless $defaultusepassword; + $defaultenableaccount = "yes" unless $defaultenableaccount; + $defaultemptypassword = "no" unless $defaultemptypassword; local($shpref) = "'" . join("', '", @shellpref) . "'"; local($shpath) = "'" . join("', '", @path) . "'"; local($user_var) = join('', @user_variable_list); @@ -1317,16 +1409,25 @@ sub config_write { # $config - automatic generated by adduser(8) # # Note: adduser read *and* write this file. -# You may change values, but don't add new things befor the +# You may change values, but don't add new things before the # line ``$do_not_delete'' # # verbose = [0-2] verbose = $verbose -# use password for new users -# defaultpasswd = yes | no -defaultpasswd = $defaultpasswd +# use password-based authentication for new users +# defaultusepassword = "yes" | "no" +defaultusepassword = "$defaultusepassword" + +# enable account password at creation +# (the password will be prepended with a star if the account isn't enabled) +# defaultenableaccount = "yes" | "no" +defaultenableaccount = "$defaultenableaccount" + +# allow blank passwords +# defaultemptypassword = "yes" | "no" +defaultemptypassword = "$defaultemptypassword" # copy dotfiles from this dir ("/usr/share/skel" or "no") dotdir = "$dotdir" @@ -1354,11 +1455,14 @@ shellpref = ($shpref) # defaultshell if not empty ("bash") defaultshell = "$defaultshell" -# defaultgroup ('USER' for same as username or any other valid group +# defaultgroup ('USER' for same as username or any other valid group) defaultgroup = $defaultgroup +# defaultclass if not empty +defaultclass = "$defaultclass" + # new users get this uid (1000) -uid_start = 1000 +uid_start = "$uid_start" $do_not_delete ## your own variables, see /etc/adduser.message @@ -1380,7 +1484,7 @@ $check_only = 0; &config_read(@ARGV); # read variables form config-file &parse_arguments(@ARGV); # parse arguments -if (!$check_only && $#batch < 0) { +if (!$check_only) { ©right; &hints; } @@ -1393,7 +1497,6 @@ $changes = 0; &group_check; # check for incon* exit 0 if $check_only; # only check consistence and exit -exit(!&batch(@batch)) if $#batch >= 0; # batch mode # interactive # some questions @@ -1402,7 +1505,17 @@ $defaultshell = &shell_default; # enter default shell $home = &home_partition($home); # find HOME partition $dotdir = &dotdir_default; # check $dotdir $send_message = &message_default; # send message to new user -$defaultpasswd = &password_default; # maybe use password +$defaultusepassword = &password_default; # maybe use password +if ($defaultusepassword eq "no") { + if ($verbose) { + print "Creating accounts with a locked password.\n"; + } + $defaultenableaccount = "no"; + $defaultemptypassword = "yes"; +} else { + $defaultenableaccount = &enable_account_default; # enable or disable account + $defaultemptypassword = &enable_empty_password; # use empty password or not +} &config_write(!$verbose); # write variables in file # main loop for creating new users