#!/usr/bin/perl -w
#
# Perl hack to add a user/group to a ldap-tree 
#

$UID_START = 6000;
$GID_START = 6000;
$basedn_user = "ou=,dc=";
$basedn_group = "ou=, dc=";

$binddn = "uid=,dc=";

$host = "";

$_userLoginShell = q(/bin/bash);
$_userHomePrefix = q(/home/);
$_userEmailPostfix = q(@FQDN);

$_userSmbHome = q(\\\\server\share);
$_userProfile = q(\\\\server\profiles\default);
$_userHomeDrive = q(E:);
$_userScript = q(scripts\startup.bat);
$_userGecos = q(Default User);

use Getopt::Std;
my %Options;

$ok = getopts('nu:g:d:s:c:e:?', \%Options);

if ( (!$ok) || (@ARGV < 1) || ($Options{'?'}))
{
	print "Usage: $0 [-nugdsce?] username\n";
	print " -n	show what would be done, but don't actually add user\n";
	print " -u	uid\n";
	print " -g	gid\n";
	print " -s	shell\n";
	print " -c	gecos\n";
	print " -e 	email\n";	
	print " -?	show this help message\n";
	exit (-1);
}

$_userUidNumber = $Options{'u'};
if (!defined ($_userUidNumber))
{
	while (defined(getpwuid($UID_START)))
	{
		$UID_START++;
	}
	$_userUidNumber = $UID_START;
}
elsif (getpwuid($_userUidNumber)) 
{
	die "Uid already exists!\n";
}
$_userRid = sprintf ("%x", $_userUidNumber);

$_userGidNumber = $Options{'g'};
if (!defined ($_userGidNumber))
{
	while (defined(getgrgid($GID_START)))
	{
		$GID_START++;
	}
	$_userGidNumber = $GID_START;
}
elsif (getgrgid($_userGidNumber))
{
	die "Gid already exists!\n",
}
$_userGroupRid = sprintf ("%x", $_userGidNumber);

$_userName = $ARGV[0];

if (!defined($_userHomeDirectory = $Options{'d'}))
{
	$_userHomeDirectory = $_userHomePrefix.$_userName;
}

if (!defined($_userEmail = $Options{'e'}))
{
	$_userEmail = $_userName.$_userEmailPostfix;
}

if (defined($tmp = $Options{'s'}))
{
	$_userLoginShell = $tmp;
}

if (defined($tmp = $Options{'c'}))
{
	$_userGecos = $tmp;
}

print "uidnumber = $_userUidNumber\n";
print "rid = $_userRid\n";
print "gidnumber = $_userGidNumber\n";
print "grouprid = $_userGroupRid\n";
print "name = $_userName\n";
print "gecos = $_userGecos\n";
print "homeDirectory = $_userHomeDirectory\n";
print "userloginshell = $_userLoginShell\n";
print "usersmbhome = $_userSmbHome\n";
print "userprofile = $_userProfile\n";
print "userhomedrive = $_userHomeDrive\n";
print "userscript = $_userScript\n";
print "useremail = $_userEmail\n";

system "stty -echo";
print "New password for user $_userName ";
chomp ($pass=<STDIN>);
print "\n";
system "stty echo";

system "stty -echo";
print "Retype new password for user $_userName: ";
chomp ($pass2=<STDIN>);
print "\n";
system "stty echo";

if ($pass ne $pass2)
{
	die "Passwords do not match!\n";
}
else
{
	$random = join '', ('.', '/', 0..9, 'A'..'Z', 'a'..'z') [rand 64, rand 64, rand 64, rand 64, rand 64, rand 64, rand 64, rand 64];
	$bsalt = "\$1\$";
	$esalt = "\$";
	$modsalt = $bsalt.$random.$esalt;
	$_userUserPassword = crypt($pass, $modsalt);

	$ntpwd = `/usr/local/sbin/mkntpwd '$pass'`;
	chomp ($_userLmPassword = substr($ntpwd, 0, index ($ntpwd,':')));
	chomp ($_userNtPassword = substr($ntpwd, index ($ntpwd,':')+1));
}

if (defined($tmp = $Options{'n'}))
{
	$options = '-nv';
}
else 
{
	$options = '';
}

$FILE = "|/usr/bin/ldapadd -h $host $options -D '$binddn' -W";

open FILE or die;

print FILE <<EOF;
dn: uid=$_userName,$basedn_user
objectclass: account
objectclass: posixAccount
objectclass: top
objectclass: shadowAccount
objectclass: sambaAccount
acctFlags: [U          ]
userpassword: {crypt}$_userUserPassword
ntpassword: $_userNtPassword
lmpassword: $_userLmPassword
uid: $_userName
gecos: $_userGecos
uidnumber: $_userUidNumber
gidnumber: $_userGidNumber
cn: $_userName
email: $_userEmail
ntuid: $_userName
rid: $_userRid
grouprid: $_userGroupRid
loginshell: $_userLoginShell
smbhome: $_userSmbHome
profile: $_userProfile
homedrive: $_userHomeDrive
script: $_userScript
homedirectory: $_userHomeDirectory
logontime: 00000000
logofftime: 00000000
pwdlastset: 3A561FEC
pwdcanchange: 00000000
pwdmustchange: FFFFFFFF
shadowmax: 99999
shadowwarning: 7
shadowlastchange: 11270

dn: cn=$_userName, $basedn_group
objectclass: posixgroup
cn: $_userName
gidnumber: $_userGidNumber
memberuid: $_userUidNumber

EOF
close FILE;

exit 0;
