1994-12-30 12:13:08 +00:00
|
|
|
#!/usr/bin/perl
|
|
|
|
#
|
1995-01-03 09:46:14 +00:00
|
|
|
# (c) Copyright 1995 Wolfram Schneider. All rights reserved.
|
|
|
|
#
|
|
|
|
# Redistribution and use in source and binary forms, with or without
|
|
|
|
# modification, are permitted provided that the following conditions
|
|
|
|
# are met:
|
|
|
|
# 1. Redistributions of source code must retain the above copyright
|
|
|
|
# notice, this list of conditions and the following disclaimer.
|
|
|
|
# 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)
|
|
|
|
#
|
|
|
|
# Bugs: sure (my english!)
|
|
|
|
# Email: Wolfram Schneider <wosch@cs.tu-berlin.de>
|
|
|
|
#
|
|
|
|
# $Id: adduser,v 1.17 1995/01/02 00:08:43 w Exp w $
|
1994-12-30 12:13:08 +00:00
|
|
|
#
|
|
|
|
|
1995-01-03 09:46:14 +00:00
|
|
|
sub variables {
|
|
|
|
$verbose = 1;
|
|
|
|
$batch = 0; # batch mode
|
|
|
|
$defaultpasswd = 0;
|
|
|
|
$dotdir = "/usr/share/skel";
|
|
|
|
|
|
|
|
if (1) {
|
|
|
|
$home = "/home";
|
|
|
|
$shells = "/etc/shells";
|
|
|
|
$passwd = "/etc/master.passwd";
|
|
|
|
$group = "/etc/group";
|
|
|
|
$pwd_mkdb = "pwd_mkdb -p";
|
|
|
|
} else {
|
|
|
|
$home = "/home/w/tmp/adduser/home";
|
|
|
|
$shells = "./shells";
|
|
|
|
$passwd = "./master.passwd";
|
|
|
|
$group = "./group";
|
|
|
|
$pwd_mkdb = "pwd_mkdb -p -d .";
|
|
|
|
}
|
|
|
|
|
|
|
|
@path = ('/bin', '/usr/bin', '/usr/local/bin');
|
|
|
|
@shellpref = ('bash', 'tcsh', 'ksh', 'csh', 'sh');
|
|
|
|
$uid_start = 1000; # new users get this uid
|
|
|
|
$uid_end = 32000;
|
|
|
|
|
|
|
|
# global variables
|
|
|
|
$username = ''; # $username{username} = uid
|
|
|
|
$uid = ''; # $uid{uid} = username
|
|
|
|
$pwgid = ''; # $pwgid{pwgid} = username; gid from passwd db
|
|
|
|
$groupname =''; # $groupname{groupname} = gid
|
|
|
|
$gid = ''; # $gid{gid} = groupname; gid form group db
|
|
|
|
$defaultshell = '';
|
|
|
|
@passwd_backup = '';
|
1994-12-30 12:13:08 +00:00
|
|
|
}
|
|
|
|
|
1995-01-03 09:46:14 +00:00
|
|
|
# read shell database
|
|
|
|
# See also: shells(5)
|
|
|
|
sub shells_read {
|
|
|
|
local($s, @dummy);
|
|
|
|
open(S, $shells) || die "$shells:$!\n";
|
|
|
|
while(<S>) {
|
|
|
|
if (/^[ \t]*\//) {
|
|
|
|
($s, @dummy) = split;
|
|
|
|
if (-x $s) {
|
|
|
|
$shell{&basename($s)} = $s;
|
|
|
|
} else {
|
|
|
|
warn "Shell: $s not executable!\n";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
1994-12-30 12:13:08 +00:00
|
|
|
}
|
|
|
|
|
1995-01-03 09:46:14 +00:00
|
|
|
# add new/local shells
|
|
|
|
sub shells_add {
|
|
|
|
local($e,$dir,@list);
|
|
|
|
foreach $e (@shellpref) {
|
|
|
|
if (!$shell{$e}) {
|
|
|
|
foreach $dir (@path) {
|
|
|
|
if (-x "$dir/$e") {
|
|
|
|
push(@list, "$dir/$e") if
|
|
|
|
&confirm_yn("Found shell: $dir/$e. Add to $shells?", "yes");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ($#list >= 0) {
|
|
|
|
foreach $e (@list) {
|
|
|
|
$shell{&basename($e)} = $e;
|
|
|
|
#print "$e\n";
|
|
|
|
}
|
|
|
|
&append_file($shells, @list);
|
|
|
|
}
|
1994-12-30 12:13:08 +00:00
|
|
|
}
|
|
|
|
|
1995-01-03 09:46:14 +00:00
|
|
|
# choise your favourite shell
|
|
|
|
sub shells_pref {
|
|
|
|
local($e,$i,$s);
|
|
|
|
|
|
|
|
$i = 0;
|
|
|
|
while($i < $#shellpref) {
|
|
|
|
last if $shell{$shellpref[$i]};
|
|
|
|
$i++;
|
|
|
|
}
|
|
|
|
$s = &confirm_list("Enter Your default shell:", 0,
|
|
|
|
$shellpref[$i], sort(keys %shell));
|
|
|
|
print "Your default shell is: $s -> $shell{$s}\n" if $verbose;
|
|
|
|
$defaultshell = $s;
|
1994-12-30 12:13:08 +00:00
|
|
|
}
|
|
|
|
|
1995-01-03 09:46:14 +00:00
|
|
|
# return default home partition
|
|
|
|
sub home_partition {
|
|
|
|
local($h);
|
|
|
|
|
|
|
|
$h = &confirm_list("Enter Your default HOME partition:", 1, $home, "");
|
|
|
|
if (-e "$h") {
|
|
|
|
if (!(-d _ || -l $h)) {
|
|
|
|
warn "$h exist, but is it not a directory or symlink!\n";
|
|
|
|
return &home_partition;
|
|
|
|
}
|
|
|
|
if (! -w _) {
|
|
|
|
warn "$h is not writable!\n";
|
|
|
|
return &home_partition;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
return &home_partition unless &mkdirhier($h);
|
|
|
|
}
|
|
|
|
|
|
|
|
$home = $h;
|
|
|
|
return $h;
|
1994-12-30 12:13:08 +00:00
|
|
|
}
|
1995-01-03 09:46:14 +00:00
|
|
|
|
|
|
|
# check for valid passwddb
|
|
|
|
sub passwd_check {
|
|
|
|
print "Check $passwd\n" if $verbose > 0;
|
|
|
|
system("$pwd_mkdb $passwd");
|
|
|
|
die "\nInvalid $passwd - cannot add any users!\n" if $?;
|
1994-12-30 12:13:08 +00:00
|
|
|
}
|
|
|
|
|
1995-01-03 09:46:14 +00:00
|
|
|
# read /etc/passwd
|
|
|
|
sub passwd_read {
|
|
|
|
local($un, $pw, $ui, $gi);
|
|
|
|
|
|
|
|
open(P, "$passwd") || die "$passwd: $!\n";
|
|
|
|
while(<P>) {
|
|
|
|
chop;
|
|
|
|
push(@passwd_backup, $_);
|
|
|
|
($un, $pw, $ui, $gi) = (split(/:/, $_))[0..3];
|
|
|
|
print "$un already exist with uid: $username{$un}!\n"
|
|
|
|
if $username{$un};
|
|
|
|
$username{$un} = $ui;
|
|
|
|
print "User $un: uid $ui exist twice: $uid{$ui}\n"
|
|
|
|
if $uid{$ui} && $verbose;
|
|
|
|
$uid{$ui} = $un;
|
|
|
|
$pwgid{$gi} = $un;
|
|
|
|
}
|
|
|
|
close P;
|
|
|
|
}
|
1994-12-30 12:13:08 +00:00
|
|
|
|
1995-01-03 09:46:14 +00:00
|
|
|
# read /etc/group
|
|
|
|
sub group_read {
|
|
|
|
local($gn,$pw,$gi);
|
|
|
|
|
|
|
|
open(G, "$group") || die "$group: $!\n";
|
|
|
|
while(<G>) {
|
|
|
|
($gn, $pw, $gi) = (split(/:/, $_))[0..2];
|
|
|
|
warn "Groupname exist twice: $gn:$gi -> $gn:$groupname{$gn}\n"
|
|
|
|
if $groupname{$gn};
|
|
|
|
$groupname{$gn} = $gi;
|
|
|
|
warn "Groupid exist twice: $gn:$gi -> $gid{$gi}:$gi\n"
|
|
|
|
if $gid{$gi};
|
|
|
|
$gid{$gi} = $gn;
|
|
|
|
}
|
|
|
|
close G;
|
1994-12-30 12:13:08 +00:00
|
|
|
}
|
|
|
|
|
1995-01-03 09:46:14 +00:00
|
|
|
# check gids /etc/passwd <-> /etc/group
|
|
|
|
sub group_check {
|
|
|
|
local($e, $user, @list);
|
|
|
|
|
|
|
|
foreach $e (keys %pwgid) {
|
|
|
|
if (!$gid{$e}) {
|
|
|
|
$user = $pwgid{$e};
|
|
|
|
warn "Gid $e is defined in $passwd for user ``$user''\n";
|
|
|
|
warn "but not in $group!\n";
|
|
|
|
if ($groupname{$user}) {
|
|
|
|
warn <<EOF;
|
|
|
|
I'm confused! Maybe the gids ($e <-> $groupname{$user}) for user ``$user''
|
|
|
|
in $passwd & $group are wrong.
|
|
|
|
See $passwd ``$user:*:$username{$user}:$e''
|
|
|
|
See $group ``$user:*:$groupname{$user}''
|
|
|
|
EOF
|
|
|
|
} else {
|
|
|
|
push(@list, "$user:*:$e:$user")
|
|
|
|
if (&confirm_yn("Add group``$user'' gid $e to $group?", "y"));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
&append_file($group, @list) if $#list >= 0;
|
|
|
|
}
|
1994-12-30 12:13:08 +00:00
|
|
|
|
1995-01-03 09:46:14 +00:00
|
|
|
sub new_users {
|
|
|
|
local(@userlist) = @_;
|
|
|
|
local($name);
|
|
|
|
local($defaultname) = "a-z0-9";
|
|
|
|
|
|
|
|
print "\nOk, let's go.\n";
|
|
|
|
print "Don't worry about mistakes. I ask You later for " .
|
|
|
|
"correct input.\n" if $verbose;
|
|
|
|
|
|
|
|
while(1) {
|
|
|
|
$name = &confirm_list("Enter username", 1, $defaultname, "");
|
|
|
|
if ($name !~ /^[a-z0-9]+$/) {
|
|
|
|
warn "Wrong username. " .
|
|
|
|
"Please use only lowercase characters or digits\n";
|
|
|
|
} elsif ($username{$name}) {
|
|
|
|
warn "Username ``$name'' already exists!\n";
|
|
|
|
} else {
|
|
|
|
last;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
local($fullname);
|
|
|
|
while(($fullname = &confirm_list("Enter full name", 1, "", "")) =~ /:/) {
|
|
|
|
warn "``:'' is not allowed!\n";
|
|
|
|
}
|
|
|
|
$fullname = $name unless $fullname;
|
|
|
|
local($sh) = &confirm_list("Enter shell", 0, $defaultshell, keys %shell);
|
|
|
|
$sh = $shell{$sh};
|
|
|
|
local($u_id, $g_id) = &next_id($name);
|
|
|
|
print <<EOF;
|
|
|
|
|
|
|
|
Name: $name
|
|
|
|
Passwd: none, is empty
|
|
|
|
Fullname: $fullname
|
|
|
|
Uid: $u_id
|
|
|
|
Gid: $g_id
|
|
|
|
HOME: $home/$name
|
|
|
|
Shell: $sh
|
|
|
|
EOF
|
|
|
|
if (&confirm_yn("Ok?", "yes")) {
|
|
|
|
local($new_entry) =
|
|
|
|
"$name::$u_id:$g_id::0:0:$fullname:$home/$name:$sh";
|
|
|
|
|
|
|
|
&append_file($passwd, $new_entry);
|
|
|
|
|
|
|
|
system("$pwd_mkdb $passwd");
|
|
|
|
if ($?) {
|
|
|
|
local($crash) = "$passwd.crash$$";
|
|
|
|
warn "$pwd_mkdb failed, try to restore ...\n";
|
|
|
|
|
|
|
|
open(R, "> $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 $passwd. Exit.\n";
|
|
|
|
}
|
|
|
|
# Add new group
|
|
|
|
&append_file($group, "$name:*:$g_id:$name")
|
|
|
|
unless $groupname{$name};
|
|
|
|
|
|
|
|
# update passwd/group variables
|
|
|
|
push(@passwd_backup, $new_entry);
|
|
|
|
$username{$name} = $u_id;
|
|
|
|
$uid{$u_id} = $name;
|
|
|
|
$pwgid{$g_id} = $name;
|
|
|
|
$groupname{$name} = $g_id;
|
|
|
|
$gid{$g_id} = $name;
|
|
|
|
|
|
|
|
print "Added user ``$name''\n";
|
|
|
|
local($a) = &confirm_yn("Change password", $defaultpasswd);
|
|
|
|
if (($a && $defaultpasswd) || (!$a && !$defaultpasswd)) {
|
|
|
|
while(1) {
|
|
|
|
system("passwd $name");
|
|
|
|
last unless $?;
|
|
|
|
last unless
|
|
|
|
&confirm_yn("Passwd $name failed. Try again?", "yes");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
&home_create($name);
|
|
|
|
}
|
|
|
|
if (&confirm_yn("Continue with next user?", "yes")) {
|
|
|
|
&new_users;
|
|
|
|
} else {
|
|
|
|
print "Good by.\n" if $verbose;
|
|
|
|
}
|
1994-12-30 12:13:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#
|
1995-01-03 09:46:14 +00:00
|
|
|
sub password_pref {
|
|
|
|
$defaultpasswd = !&confirm_yn("Use empty passwords", "yes");
|
|
|
|
}
|
1994-12-30 12:13:08 +00:00
|
|
|
|
1995-01-03 09:46:14 +00:00
|
|
|
# misc
|
|
|
|
sub check_root {
|
|
|
|
die "You are not root!\n" if $<;
|
|
|
|
}
|
1994-12-30 12:13:08 +00:00
|
|
|
|
1995-01-03 09:46:14 +00:00
|
|
|
sub usage {
|
|
|
|
warn <<USAGE;
|
1994-12-30 12:13:08 +00:00
|
|
|
|
1995-01-03 09:46:14 +00:00
|
|
|
usage: adduser [options]
|
1994-12-30 12:13:08 +00:00
|
|
|
|
1995-01-03 09:46:14 +00:00
|
|
|
OPTIONS:
|
|
|
|
-help this help
|
|
|
|
-silent opposite of verbose
|
|
|
|
-verbose verbose
|
|
|
|
-home home default HOME partition [$home]
|
|
|
|
-shell shell default SHELL
|
|
|
|
-dotdir dir copy files from dir, default $dotdir
|
|
|
|
USAGE
|
|
|
|
exit 1;
|
1994-12-30 12:13:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#
|
1995-01-03 09:46:14 +00:00
|
|
|
sub parse_arguments {
|
|
|
|
local(@argv) = @_;
|
|
|
|
|
|
|
|
while ($_ = $argv[0], /^-/) {
|
|
|
|
shift @argv;
|
|
|
|
last if /^--$/;
|
|
|
|
if (/^--?(debug|verbose)$/) { $verbose = 1 }
|
|
|
|
elsif (/^--?(silent|guru|wizard)$/) { $verbose = 0 }
|
|
|
|
elsif (/^--?(verbose)$/) { $verbose = 1 }
|
|
|
|
elsif (/^--?(h|help|\?)$/) { &usage }
|
|
|
|
elsif (/^--?(home)$/) { $home = $argv[0]; shift @argv }
|
|
|
|
elsif (/^--?(shell)$/) { $shell = $argv[0]; shift @argv }
|
|
|
|
elsif (/^--?(dotdir)$/) { $dotdir = $argv[0]; shift @argv }
|
|
|
|
elsif (/^--?(batch)$/) { $batch = 1; }
|
|
|
|
else { &usage }
|
|
|
|
}
|
|
|
|
#&usage if $#argv < 0;
|
|
|
|
}
|
1994-12-30 12:13:08 +00:00
|
|
|
|
1995-01-03 09:46:14 +00:00
|
|
|
sub basename {
|
|
|
|
local($name) = @_;
|
|
|
|
$name =~ s|.*/||;
|
|
|
|
return $name;
|
1994-12-30 12:13:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#
|
1995-01-03 09:46:14 +00:00
|
|
|
sub home_create {
|
|
|
|
local($name) = @_;
|
|
|
|
local(@list);
|
|
|
|
local($e,$from, $to);
|
|
|
|
|
|
|
|
print "Create HOME directory\n";
|
|
|
|
if(!mkdir("$home/$name", 0755)) {
|
|
|
|
warn "Cannot create HOME directory for $name: $!\n";
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
push(@list, "$home/$name");
|
|
|
|
if ($dotdir) {
|
|
|
|
opendir(D, "$dotdir") || warn "$dotdir: $!\n";
|
|
|
|
foreach $from (readdir(D)) {
|
|
|
|
if ($from !~ /^(\.|\.\.)$/) {
|
|
|
|
$to = $from;
|
|
|
|
$to =~ s/^dot\././;
|
|
|
|
$to = "$home/$name/$to";
|
|
|
|
push(@list, $to);
|
|
|
|
&cp("$dotdir/$from", "$to", 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
closedir D;
|
|
|
|
}
|
|
|
|
#warn "Chown: $name, $name, @list\n";
|
|
|
|
#chown in perl does not work
|
|
|
|
system("chown $name:$name @list") || warn "$!\n" && return 0;
|
|
|
|
return 1;
|
|
|
|
}
|
1994-12-30 12:13:08 +00:00
|
|
|
|
1995-01-03 09:46:14 +00:00
|
|
|
# makes a directory hierarchy
|
|
|
|
sub mkdirhier {
|
|
|
|
local($dir) = @_;
|
|
|
|
|
|
|
|
if ($dir =~ "^/[^/]+$") {
|
|
|
|
print "Create /usr/$dir\n" if $verbose;
|
|
|
|
if (!mkdir("/usr$dir", 0755)) {
|
|
|
|
warn "/usr/$dir: $!\n"; return 0;
|
|
|
|
}
|
|
|
|
print "Create symlink: /usr$dir -> $dir\n" if $verbose;
|
|
|
|
if (!symlink("/usr$dir", $dir)) {
|
|
|
|
warn "$dir: $!\n"; return 0;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
local($d,$p);
|
|
|
|
foreach $d (split('/', $dir)) {
|
|
|
|
$dir = "$p/$d";
|
|
|
|
$dir =~ s|^//|/|;
|
|
|
|
if (! -e "$dir") {
|
|
|
|
print "Create $dir\n" if $verbose;
|
|
|
|
if (!mkdir("$dir", 0755)) {
|
|
|
|
warn "$dir: $!\n"; return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
$p .= "/$d";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
1994-12-30 12:13:08 +00:00
|
|
|
|
1995-01-03 09:46:14 +00:00
|
|
|
|
|
|
|
# Read one of the elements from @list. $confirm is default.
|
|
|
|
# If !$allow accept only elements from @list.
|
|
|
|
sub confirm_list {
|
|
|
|
local($message, $allow, $confirm, @list) = @_;
|
|
|
|
local($read, $c);
|
|
|
|
|
|
|
|
print "$message " if $message;
|
|
|
|
print "@list [$confirm]: ";
|
|
|
|
chop($read = <STDIN>);
|
|
|
|
$read =~ s/^[ \t]*//;
|
|
|
|
$read =~ s/[ \t\n]*$//;
|
|
|
|
return $confirm unless $read;
|
|
|
|
return $read if $allow;
|
|
|
|
|
|
|
|
foreach $c (@list) {
|
|
|
|
return $read if $c eq $read;
|
|
|
|
}
|
|
|
|
warn "$read: is not allowed!\n";
|
|
|
|
return &confirm_list($message, $allow, $confirm, @list);
|
1994-12-30 12:13:08 +00:00
|
|
|
}
|
|
|
|
|
1995-01-03 09:46:14 +00:00
|
|
|
# YES or NO question
|
|
|
|
# $confirm => 'y' or 'n'. Return true if answer 'y' (or 'n')
|
|
|
|
sub confirm_yn {
|
|
|
|
local($message, $confirm) = @_;
|
|
|
|
local($yes) = "^(yes|YES|y|Y)$";
|
|
|
|
local($no) = "^(no|NO|n|N)$";
|
|
|
|
local($read, $c);
|
|
|
|
|
|
|
|
if ($confirm && ($confirm =~ "$yes" || $confirm == 1)) {
|
|
|
|
$confirm = "y";
|
|
|
|
} else {
|
|
|
|
$confirm = "n";
|
|
|
|
}
|
|
|
|
print "$message (y/n) [$confirm]: ";
|
|
|
|
chop($read = <STDIN>);
|
|
|
|
$read =~ s/^[ \t]*//;
|
|
|
|
$read =~ s/[ \t\n]*$//;
|
|
|
|
return 1 unless $read;
|
|
|
|
|
|
|
|
if (($confirm eq "y" && $read =~ "$yes") ||
|
|
|
|
($confirm eq "n" && $read =~ "$no")) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($read !~ "$yes" && $read !~ "$no") {
|
|
|
|
warn "Wrong value. Enter again!\a\n";
|
|
|
|
return &confirm_yn($message, $confirm);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
1994-12-30 12:13:08 +00:00
|
|
|
|
1995-01-03 09:46:14 +00:00
|
|
|
# test if $dotdir exist
|
|
|
|
sub dotdir_check {
|
|
|
|
return 1 if -e $dotdir && -r _ && (-d _ || -l $dotdir);
|
|
|
|
warn "Directory: $dotdir does not exist or unreadable. " .
|
|
|
|
"Cannot copy dotfiles!\n";
|
|
|
|
$dotdir = '';
|
|
|
|
return 0;
|
|
|
|
}
|
1994-12-30 12:13:08 +00:00
|
|
|
|
1995-01-03 09:46:14 +00:00
|
|
|
# write @list to $file with file-locking
|
|
|
|
sub append_file {
|
|
|
|
local($file,@list) = @_;
|
|
|
|
local($e);
|
|
|
|
local($LOCK_EX) = 2;
|
|
|
|
local($LOCK_UN) = 8;
|
|
|
|
|
|
|
|
open(F, ">> $file") || die "$file: $!\n";
|
|
|
|
print "Lock $file.\n" if $verbose > 1;
|
|
|
|
flock(F, $LOCK_EX);
|
|
|
|
print F join("\n", @list) . "\n";
|
|
|
|
close F;
|
|
|
|
print "Unlock $file.\n" if $verbose > 1;
|
|
|
|
flock(F, $LOCK_UN);
|
|
|
|
}
|
1994-12-30 12:13:08 +00:00
|
|
|
|
1995-01-03 09:46:14 +00:00
|
|
|
# return free uid+gid
|
|
|
|
# uid == gid if possible
|
|
|
|
sub next_id {
|
|
|
|
local($group) = @_;
|
|
|
|
|
|
|
|
# looking for next free uid
|
|
|
|
while($uid{$uid_start}) {
|
|
|
|
$uid_start++;
|
|
|
|
print "$uid_start\n" if $verbose > 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
local($gid_start) = $uid_start;
|
|
|
|
# group for user (username==groupname) already exist
|
|
|
|
if ($groupname{$group}) {
|
|
|
|
$gid_start = $groupname{$group};
|
|
|
|
}
|
|
|
|
# gid is in use, looking for another gid.
|
|
|
|
# Note: uid an gid are not equal
|
|
|
|
elsif ($gid{$uid_start}) {
|
|
|
|
while($gid{$gid_start} || $uid{$gid_start}) {
|
|
|
|
$gid_start--;
|
|
|
|
$gid_start = $uid_end if $gid_start < 100;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ($uid_start, $gid_start);
|
|
|
|
}
|
1994-12-30 12:13:08 +00:00
|
|
|
|
1995-01-03 09:46:14 +00:00
|
|
|
sub cp {
|
|
|
|
local($from, $to, $tilde) = @_;
|
|
|
|
|
|
|
|
if (-e "$to") {
|
|
|
|
warn "cp: ``$to'' already exist, do not overwrite\n"; return 0;
|
|
|
|
} elsif (!(-f $from || -l $from)) {
|
|
|
|
warn "$from is not a file or symlink!\n"; return 0;
|
|
|
|
} elsif (!open(F, "$from")) {
|
|
|
|
warn "$from: $!\n"; return 0;
|
|
|
|
} elsif (!open(T, "> $to")) {
|
|
|
|
warn "$to: $!\n"; return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($tilde) {
|
|
|
|
$tilde = $to;
|
|
|
|
$tilde =~ s|.*/([^/]+/[^/]+)$|~$1|;
|
|
|
|
} else {
|
|
|
|
$tilde = $to;
|
|
|
|
}
|
|
|
|
print "copy $from to $tilde\n" if $verbose;
|
|
|
|
while(<F>) {
|
|
|
|
print T $_;
|
|
|
|
}
|
|
|
|
|
|
|
|
close F;
|
|
|
|
close T;
|
|
|
|
return 1;
|
|
|
|
}
|
1994-12-30 12:13:08 +00:00
|
|
|
|
1995-01-03 09:46:14 +00:00
|
|
|
################
|
|
|
|
# main
|
1994-12-30 12:13:08 +00:00
|
|
|
#
|
1995-01-03 09:46:14 +00:00
|
|
|
&check_root; # You must be root to run this script!
|
|
|
|
&variables; # initialize variables
|
|
|
|
&parse_arguments(@ARGV); # parse arguments
|
|
|
|
|
|
|
|
&passwd_check; # check for valid passwdb
|
|
|
|
&passwd_read; # read /etc/master.passwd
|
|
|
|
&group_read; # read /etc/group
|
|
|
|
&group_check; # check for incon*
|
|
|
|
&dotdir_check; # check $dotdir
|
1994-12-30 12:13:08 +00:00
|
|
|
print "\n";
|
1995-01-03 09:46:14 +00:00
|
|
|
&home_partition; # find HOME partition
|
|
|
|
&shells_read; # read /etc/shells
|
|
|
|
&shells_add; # maybe add some new shells
|
|
|
|
&shells_pref; # enter default shell
|
|
|
|
&password_pref; # maybe use password
|
|
|
|
|
|
|
|
&new_users; # add new users
|
1994-12-30 12:13:08 +00:00
|
|
|
|
1995-01-03 09:46:14 +00:00
|
|
|
#end
|