Code:
do {
#prompt administrator for user information
&read_new_user();
# Ask if name is correct and check username. If mk_unique_user results
# False then root decided not to create this user.
if(&mk_unique_user) {
# Pick a initial password.
$rvalue = int(rand(1000));
($uhead) = ( $name[0] =~ /^(.{1,4})/ );
$nv = join('',$uhead,$rvalue);
$pwd = crypt($nv,$SALT);
# scan the passwd list for the first unused uid
for ($uid = $FIRST_UID; $passwd{$uid}; ++$uid) {}
# choose group for new user
&choose_group();
# add user info to passwd map file
$passwd {$uid} ="$username:x:$uid:$gid:@name:/home/$username:$shell";
$uname2uid {$username} = $uid;
# add user info to the shadow map file
$shadow {$uid} = $username . ":" . $pwd . ":::::::";
# save the new passwd file
&save_pass;
# create home dir
&build_dir;
# save the new passwd file
&output_info;
}
# Ask if more users are to be added
do {
print "\nAdd another User (y or n)?";
chop($confirm = <STDIN>);
$confirm =~ tr/YN/yn/;
} while (($confirm ne "y" )&&( $confirm ne "n") &&( $confirm ne ""));
} while ( $confirm eq "y");
### End of loop for users
### Make the NIS database
&build_database;
#end of main -------------------------
#------------------------------------------------------------------
# BUILD_DIR: Create the directory for the new user
sub build_dir {
my $userhome;
print "Creating user's home directory\n";
$userhome = join '', $homedir, $username;
system ("mkdir", $userhome);
system ("cp /etc/skel/local.profile $userhome/.profile");
system ("chown -R $uid:$gid $userhome");
print "\n";
}
#------------------------------------------------------------------
# MK_UNIQUE_USER: Search the passwd database for user
# prompts for new username if name is not unique
sub mk_unique_user {
my ($i,$confirm, $puser, $unique);
my ($line); #line of passwd
#confirm username
do {
print "Allow \"@name\" as \"$username\" (y or n)";
chop($confirm = <STDIN>);
} while (($confirm ne "y" )&&( $confirm ne "n") &&( $confirm ne ""));
if (($confirm eq "n") || ($username eq "")) {
do {
do {
print "(s)kip this entry or (c)hange username: ";
chop($confirm = <STDIN>);
} while (($confirm ne "s" )&&( $confirm ne "c"));
if ($confirm eq "s")
{ return 0; } #skip this user
print "Enter new username: ";
chop($username = <STDIN>);
print "Confirm \"@name\" as \"$username\" (y or n)";
chop($confirm = <STDIN>);
} while (($username ne "") && ($confirm ne 'y') && ($confirm ne ""));
}
#find duplicate usernames
# continue looping until $username is not in the uname2uid list
while ($uname2uid {$username}) {
# print the conflict
print "$username requested for @name but found in:\n$passwd{$uname2uid {
$username}}\n";
# ask if we should not create an account or change the username
do {
print "(s)kip account creation or (c)hange username: ";
chop($confirm = <STDIN>);
} while (($confirm ne "s" )&&( $confirm ne "c"));
# skip this account and exit the function
return 0 if ($confirm eq "s");
do {
#get a new username
print "Enter new username: ";
chop($username = <STDIN>);
#confirm the new name
print "Confirm \"@name\" as \"$username\" (y or n)";
chop($confirm = <STDIN>);
} while (($confirm ne 'y') && ($confirm ne ""));
}
return 1; #do this user
}
#------------------------------------------------------------------
# BUILD_DATABASE: Build yp maps
sub build_database
{
print "Building password database... \n";
system( $MAKE ) == 0
or die "failed to Make password database";
}
#------------------------------------------------------------------
# OUTPUT_INFO: Output new passwd information
sub output_info
{
# make a backup copy of the passwd file
rename("$NISfiles/passwd", "$NISfiles/passwd.old") || die "can't move passwd
";
# write the new passwd file
open PASSWD,">$NISfiles/passwd" or die "ERROR: can't write new passwd: $!\n"
;
for (sort keys %passwd)
{ print PASSWD $passwd{$_}, "\n" }
close PASSWD;
# make a backup copy of the shadow file
rename("$NISfiles/shadow", "$NISfiles/shadow.old") || die "can't move $NISfi
les/shadow to $NISfiles/shadow.old: $!";
# write the new shadow file
open(SHADOW,">$NISfiles/shadow") or die "ERROR: can't write new shadow: $!\n
";
for (sort keys %shadow)
{ print SHADOW $shadow{$_}, "\n" }
close SHADOW;
}
# This saves the username and password from the newly created account
#--------------------------------------------------------------------
sub save_pass
{
open(OUTPUT,">>$PASSWD_FILE");
print OUTPUT "*************************** ";
print OUTPUT (scalar localtime),"\n\n";
printf(OUTPUT " NAME: %20s %20s %20s \n\n",$name[0],$name[1],$name[2]);
printf(OUTPUT " Your username is %15s \n",$username);
printf(OUTPUT " Your password is %15s \n\n",$nv);
print OUTPUT "After you login change your password with passwd \n\n";
print OUTPUT "*************************************************************\n"
;
close(OUTPUT);
}
#--------------------------------------------------------------------
# read_user_name -- read the user info from the keyboard
#--------------------------------------------------------------------
sub read_new_user
{
print "Enter user's first name: ";
$name[0] = <STDIN>;
chop ($name[0]);
print "\nEnter user's middle initial: ";
$name[1] = <STDIN>;
chop ($name[1]);
print "\nEnter user's last name: ";
$name[2] = <STDIN>;
chop ($name[2]);
print "\n";
($firstinital) = ($name[0] =~ /^(.)/);
($middleinital) = ($name[1] =~ /^(.)/);
$lastname = $name[2] ;
#create a username from first inital, middle inital, and last name
$username = join ("",$firstinital,$middleinital,$lastname);
# change username to lowercase
$username =~ tr/A-Z/a-z/;
}
#--------------------------------------------------------------------
# choose_group -- prompt for the user's group membership
#--------------------------------------------------------------------
sub choose_group
{
# by using list context, we read the group file quickly
open GROUP, "<$NISfiles/group" or die "can't open group file in $NISfiles";
@good_group = <GROUP>;
close GROUP;
print "-------------------------------------------\n";
for $group (@good_group) {
@line = split ':', $group;
print $line[2], "\t", $line[0], "\n";
}
print "-------------------------------------------\n";
print "what group should the user be in\n";
$gid = <STDIN>;
chop ($gid);
}
#--------------------------------------------------------------------
# Checks CVS to see if the files are up to date and etc.
# not in use yet -- cbmasters
#--------------------------------------------------------------------
sub save_pass_cvs
{
my $quit = 0;
my ($USER, %CVS_stat);
# check if the USER or LOGNAME enviromental variable is set
# if they are not set then set them. This works since make and cvs
# will inherit this enviroment when they are forked later
unless ($ENV{LOGNAME} or $ENV{USER}) {
print <<EOF
For CVS to properly update, you must set LOGNAME or USER
to your username. Please enter you login name now.
USER=EOF
# read the username from stdin
$USER = <STDIN>;
# set the variables
$ENV{USER} = $USER; $ENV{LOGNAME} = $USER;
# check for CVSROOT and it is NOT defined then
# set it to the default from $CVSROOT
if ($ENV{CVSROOT})
{ $CVSROOT = $ENV{CVSROOT} }
else
{
$ENV{CVSROOT}= $CVSROOT;
print "WARNING: CVSROOT was not defined, so I set it to $CVSROOT\n";
}
# The next set of steps check to see if the files under CVS control
# are up to date.
# run a status on the nis files
open CVS, "$CVS -Q status $NISfiles/passwd $NISfiles/shadow" or die "can't d
o $CVS status $NISfiles/passwd $NISfiles/shadow because $!";
while (<CVS>) {
#skip lines not about status
next unless /^File:/;
#save the Status of the passwd & shadow
$CVS_stat{passwd} = $1 if /passwd\s*Status:\s*(\S+)/;
$CVS_stat{shadow} = $1 if /shadow\s*Status:\s*(\S+)/;
}
close CVS;
#check if status was detected
unless ($CVS_stat{shadow} and $CVS_stat{passwd}) {
print "$CVS -Q status did not return status for passwd and shadow";
exit -1;
}
# let the user know the status
print "$NISfiles/passwd is $CVS_stat{passwd}\n$NISfiles/shadow is $CVS_stat{
shadow}\n";
#if the files are not up to do the update them
if ($CVS_stat{passwd} ne "Up-to-date" or ($CVS_stat{shadow} ne "Up-to-date")
{
print <<EOF
One of the files was not up to date, please run the following command
#$CVS update $CVS_stat{passwd} $NISfiles/shadow
You might need this:
#USER=$USER; export $USER; CVSROOT = $CVSROOT; export $CVSROOT
EOF
}
}
## end of file ##