Cover V04, I02
Article
Figure 1
Figure 2
Figure 3
Figure 4
Listing 1

mar95.tar


Listing 1: mkuser script

#!/usr/local/bin/perl
#
#  make user
#
#  12 December 1994 - Russ Hill
#
#usage
#./mkuser
#./mkuser joe smith jsmith jsmith next workgroup home /bin/csh
#./mkuser tom thibodeaux tthibode tthibodeaux next gen home /bin/ksh
#./mkuser tom thibodeaux tthibode tthibodeaux next gen home /bin/ksh o,iltay
#
# note:
# logname is always 8 characters
# username can be the full name if you wish
# password is the logname if not specified or generated

#read from the command line
($firstname,$lastname,$logname,$username,$uid,$group,$home,
$shell,$passworddef) = @ARGV;

#uncomment to debug script
#$debug = 1;

#set defaults
$homedef = "home";
$groupdef = "staff";
$defaultcshdef = "/usr/local/adm/cshuser";
$defaultkshdef = "/usr/local/adm/kshuser";

#uncomment to use password generator
#$passwordgenerate = do pwgen() ;

$output = $shell;

#exit if not root
$id = system ("/bin/id | grep 'uid=0' > /dev/null 2>&1");
if ( $id )
{
die ("ERROR: This script must be run as root.\n");
}

#Get name if not already set
if ( ! $firstname || ! $lastname )
{
print;
print("What is the new user's first name?\n");
chop($firstname = <STDIN>);
$firstname =~ tr/A-Z/a-z/;
print("What is the new user's last name?\n");
chop($lastname = <STDIN>);
$lastname =~ tr/A-Z/a-z/;
}

$first = substr($firstname,0,1);

#set username
if ( ! $username )
{
$username = $first . $lastname;
}

#set logname and password
if ( $logname )
{
$password = $logname;
}
else
{
$logname = substr($username,0,8);
$password = $logname;
print("Use ${logname} as ${firstname} ${lastname}'s login name [yn]?\n");
chop($answer = <STDIN>);
$answer =~ tr/A-Z/a-z/;
if ($answer eq "n" || $answer eq "no")
{
print ("What is the new user's login name?\n");
chop($logname = <STDIN>);
$logname =~ tr/A-Z/a-z/;
$logname = substr($logname,0,8);
$password = $logname;
}
print("Use ${username} as ${firstname} ${lastname}'s user name (basename home directory)
[yn]?\n");
chop($answer = <STDIN>);
$answer =~ tr/A-Z/a-z/;
if ($answer eq "n" || $answer eq "no")
{
print ("What is the new user's user name (basename home directory name)?\n");
chop($username = <STDIN>);
$username =~ tr/A-Z/a-z/;
}
print("Use $password as $firstname ${lastname}'s password [yn]?\n");
chop($answer = <STDIN>);
$answer =~ tr/A-Z/a-z/;
if ($answer eq "n" || $answer eq "no" )
{
print ("What is the new user's password?\n");
chop($password = <STDIN>);
$password =~ tr/A-Z/a-z/;
}
}

#check to see if logname already exists
if ( getpwnam($logname) )
{
die ("ERROR: Account $logname already exists.\n");
}

#get next available uid
if ( ! $uid || $uid eq "next" )
{
setpwent;
while (@passwduser = getpwent)
{
push (@passwduidlist,@passwduser[2]);
}
endpwent;

@passwduidlist = reverse sort numerically (@passwduidlist);
#$uid = @passwduidlist[1] + 1;
$uid = @passwduidlist[0] + 1;
}

#check if uid is already used
if ( getpwuid($uid) )
{
die  ("ERROR: uid $uid is already used. \n");
}

#set group
if ( ! $group )
{
$group = $groupdef;
print ("Put $firstname $lastname in the $group group [yn]?\n");
chop($answer = <STDIN>);
$answer =~ tr/A-Z/a-z/;
if ($answer eq "n" || $answer eq "no" )
{
print ("What is the new user's group?\n");
chop($group = <STDIN>);
$group =~ tr/A-Z/a-z/;
}
}

#get gid
($groupname,$grouppasswd,$gid,$groupmembers) = getgrnam($group);
if ( ! $gid  )
{
die ("ERROR: group $group does not exist. \n");
}

#set home directory
if ( ! $home )
{
$home = "/" . $homedef . "/" . $username;
}
else
{
$home = "/" . $home . "/" . $username;
}


#set shell
if ( ! $shell )
{
$shell = "/bin/csh";
print ("Use $shell for $firstname ${lastname}'s login shell [yn]?\n");
chop($answer = <STDIN>);
$answer =~ tr/A-Z/a-z/;
if ( $answer eq "n" || $answer eq "no" )
{
print ("What is the new user's shell?\n");
chop($shell = <STDIN>);
$shell =~ tr/A-Z/a-z/;
}
}

#set defaults for new account
if ( $shell eq "/bin/ksh" )
{
$default = $defaultkshdef;
}
else
{
$default = $defaultcshdef;
}

#get pid
$pid = getppid;

#make first character uppercase
substr($firstname,0,1) =~ tr/a-z/A-Z/;
substr($lastname,0,1) =~ tr/a-z/A-Z/;

#set password
if ( $passworddef )
{
$password = $passworddef;
}

if ( $passwordgenerate )
{
$password = $passwordgenerate;
print ("${logname} password is: $password \n");
}

#crypt password
$cryptpassword = crypt($password,$password);

#make shell script to finish
$TEMP = "/tmp/mkuser.$pid";
open (FILE, ">$TEMP");
print FILE "#!/bin/sh \n\n";

#no shadow file
print FILE "echo
\"${logname}:${cryptpassword}:${uid}:${gid}:${firstname}${lastname}:${home}:${shell}\" >>
/etc/passwd \n";

#with shadow file
#printFILE"echo\"${logname}:x:${uid}:${gid}:${firstname}${lastname}:${home}:${shell}\"
>> /etc/passwd \n";
#print FILE "echo \"${logname}:${cryptpassword}:8793:0:6993:7:::\" >> /etc/shadow
\n";
#print FILE "/usr/sbin/pwconv \n";

#make directory
print FILE "cp -r ${default} ${home} \n";
print FILE "chown -R $logname ${home} \n";

#print FILE "find ${home} -type f -exec chmod 755 {} \\\; \n";
#print FILE "find ${home} -type d -exec chown ${logname} {} \\\; \n";
#print FILE "find ${home} -type f -exec chmod ${logname} {} \\\; \n";

print FILE "cd /var/yp \n";
print FILE "make passwd  > /dev/null \n";
print FILE "\n\n";
close FILE;

chmod 0755, $TEMP;

if ( ! $debug )
{
#actually make the user
#run and remove $TEMP shell script
system "$TEMP";
unlink $TEMP;
}
else
{
#debug - print out
#print("${logname}:${cryptpassword}:${uid}:${gid}:${firstname}${lastname}:${home}:${shell}\n");
system "cat $TEMP";
unlink $TEMP;
}

#print out -- complete
if ( ! $output )
{
print ("\nAccount ${logname} added. \n");
print ("Add completed. \n");
}

#------------------------------------------------------------------
# functions

#sort numerically
sub numerically { $a <=> $b; }

sub pwgen {
#
# password generator
#
# Make up passwords which have similar letter digraph frequencies to
# english. frequency of English digraphs (from D Edwards 1/27/66)
#
# note:
# Rewrite this subroutine when perl generally has
# multidimensional arrays.

$PASSWD_LENGTH = 8;

# fake 2 dim-array,
@array =
(4,20,28,52,2,11,28,4,32,4,6,62,23,167,2,14,0,83,76,127,7,25,8,1,9,1,
13,0,0,0,55,0,0,0,8,2,0,22,0,0,11,0,0,15,4,2,13,0,0,0,15,0,
32,0,7,1,69,0,0,33,17,0,10,9,1,0,50,3,0,10,0,28,11,0,0,0,3,0,
40,16,9,5,65,18,3,9,56,0,1,4,15,6,16,4,0,21,18,53,19,5,15,0,3,0,
84,20,55,125,51,40,19,16,50,1,4,55,54,146,35,37,6,191,149,65,9,26,21,12,5,0,
19,3,5,1,19,21,1,3,30,2,0,11,1,0,51,0,0,26,8,47,6,3,3,0,2,0,
20,4,3,2,35,1,3,15,18,0,0,5,1,4,21,1,1,20,9,21,9,0,5,0,1,0,
101,1,3,0,270,5,1,6,57,0,0,0,3,2,44,1,0,3,10,18,6,0,5,0,3,0,
40,7,51,23,25,9,11,3,0,0,2,38,25,202,56,12,1,46,79,117,1,22,0,4,0,3,
3,0,0,0,5,0,0,0,1,0,0,0,0,0,4,0,0,0,0,0,3,0,0,0,0,0,
1,0,0,0,11,0,0,0,13,0,0,0,0,2,0,0,0,0,6,2,1,0,2,0,1,0,
44,2,5,12,62,7,5,2,42,1,1,53,2,2,25,1,1,2,16,23,9,0,1,0,33,0,
52,14,1,0,64,0,0,3,37,0,0,0,7,1,17,18,1,2,12,3,8,0,1,0,2,0,
42,10,47,122,63,19,106,12,30,1,6,6,9,7,54,7,1,7,44,124,6,1,15,0,12,0,
7,12,14,17,5,95,3,5,14,0,0,19,41,134,13,23,0,91,23,42,55,16,28,0,4,1,
19,1,0,0,37,0,0,4,8,0,0,15,1,0,27,9,0,33,14,7,6,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17,0,0,0,0,0,
83,8,16,23,169,4,8,8,77,1,10,5,26,16,60,4,0,24,37,55,6,11,4,0,28,0,
65,9,17,9,73,13,1,47,75,3,0,7,11,12,56,17,6,9,48,116,35,1,28,0,4,0,
57,22,3,1,76,5,2,330,126,1,0,14,10,6,79,7,0,49,50,56,21,2,27,0,24,0,
11,5,9,6,9,1,6,0,9,0,1,19,5,31,1,15,0,47,39,31,0,3,0,0,0,0,
7,0,0,0,72,0,0,0,28,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,3,0,
36,1,1,0,38,0,0,33,36,0,0,4,1,8,15,0,0,0,4,2,0,0,1,0,0,0,
1,0,2,0,0,1,0,0,3,0,0,0,0,0,1,5,0,0,0,3,0,0,1,0,0,0,
14,5,4,2,7,12,12,6,10,0,0,3,7,5,17,3,0,4,16,30,0,0,5,0,0,0,
1,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);

@rowsums =
(796,   160,    284,    401,    1276,   262,
199,    539,    777,     16,      39,   351,
243,    751,    662,    181,      17,   683,
662,    968,    248,    115,     180,    17,
162,    5);

# Frequencies of starting characters
@startfreq =
(1299,     425,    725,    271,    375,    470,
93,        223,   1009,     24,     20,    355,
379,       319,    823,    618,     21,    317,
962,      1991,    271,    104,    516,      6,
16,       14);

@alpha =
( 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
't', 'u', 'v', 'w', 'x', 'y', 'z');

$total_sum = 11646;

($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = gmtime(time);

srand( $sec * $min |  $$ );
$rand = rand($total_sum);
$position = ($rand % $total_sum);
$j = 0;
for ( $row = 0 ; $position >= $row; $row = $row + $startfreq[$j] )
{
$j++;
$j = 0 if $j eq 27;
}

$password = $password . @alpha[ ($j - 1) ];

for ( $char = ($PASSWD_LENGTH - 1); $char; --$char)
{
$i = $j;
$rand = rand($total_sum);
$position = ($rand % $rowsums[$i]);
$j = 0;

for ($row = 0; $position >= $row;
$row += $addition   )
{

@frequency = @array[ ($i * 26) .. (($i * 26) + 25) ];

$addition = $frequency[$j];
$j++;
$j = 0 if $j eq 27;
}
$password = $password . @alpha[ ($j - 1) ];

}

#generated password
return $password;
}