#------------------------------------------------------ # Script for new user's creation in the Domain. # Operation on WinNT #------------------------------------------------------ use Win32API::Net; use Win32; use Win32::NetAdmin; use Win32::Lanman; use Win32::ODBC; use Win32::Perms; use Win32::MAPI; # $^W = 0; # Disable warnings # ---------------------------- Constants initialisation----------------------------- # Description of the Database + login and pwd # DSN => the name of the DB in the ODBC 32 control panel. $DSN = "DSN=db_name;UID=db_login;PWD=db_pwd;" unless (($DSN) = @ARGV); # Check for the availability of a Domain Controller $dc = undef; unless(Win32::NetAdmin::GetDomainController(undef, undef, $dc)) { die "Can't find a DC for the domain : $!"; } $PDCFull = $dc; @ExistServer = ("fileserver1","fileserver2","fileserver3","fileserver4"); $logFile = "\\\\PDC\\reports\$\\logfiles\\new_user.log"; # ---------------------------- End Constants initialisation ------------------------ #---- Getting the name of the admin using the script %hash = undef; $level = 3; $adminUser = Win32::LoginName; Win32API::Net::UserGetInfo($dc, $adminUser, $level, \%hash) || die Win32::FormatMessage(Win32::GetLastError); $adminFullUser = $hash{fullName}; %hash = undef; #---- Let's begin ! system ("cls"); print "Welcome $adminFullUser, great admin. Please input the user's information\n"; &AskLogin; while ( (Win32::NetAdmin::UsersExist($PDCFull,$LoginUser)) ) { print "User $LoginUser already exists !!\a\n"; &AskLogin; } until (&UserInfo) { system("cls"); &AskLogin; } # ----- Let's Create the user &CreateUser; # ----- Updating the log file &createLog; print "The Job is done, oh ADMIN\n"; sleep(5); #----------------------------------------- # # The Sub Processes # #----------------------------------------- #---- Check the login rulez sub AskLogin { print "Login name : "; $LoginUser = ; chomp($LoginUser); $LoginUser = lc $LoginUser; while ( length($LoginUser) != 7) { print "Error !! The login name $LoginUser doesn't have the good length.\a\n"; print "Login name : "; $LoginUser = ; chomp($LoginUser); $LoginUser = lc $LoginUser; } } # ----- Get the name of the group and the home server sub UserInfo { # Trying to getting the info from the DB ELS &getData; print "Full Name ($NameUser) : "; $_ = ; if ($_ ne "\n") { chomp($_); @name = split(/ /,$_); } else { @name = split(/ /,$NameUser); } $j = $#name; @gName = split(/-/,$name[0]); if ( ($k = $#gName) > 0) { $name0 = ucfirst lc $gName[0]; for ($i = 1; $i <= $k; $i++) { $name0 = $name0 . "-" . ucfirst lc $gName[$i]; } } else { $name0 = ucfirst lc $gName[0]; } $NameUser = $name0; $nameFin = undef; for ($i = 1; $i <= $j; $i++) { $NameUser = $NameUser . " " . ucfirst lc $name[$i]; $nameFin = $nameFin . uc $name[$i] . "-"; } chop($nameFin); print "Unit of the User ($GroupUser) : "; $_ = ; if ($_ ne "\n") { chomp($_); $GroupUser = $_; } $GroupUser = uc $GroupUser; $comment = $GroupUser; $GroupUser = "G-" . $GroupUser; until ( Win32::NetAdmin::GroupGetAttributes($PDCFull,$GroupUser,$Comment) ) { print "The group $GroupUser is not correct. Please retry.\a\n"; print "Unit of the User : "; $GroupUser = ; chomp($GroupUser); $GroupUser = uc $GroupUser; $comment = $GroupUser; $GroupUser = "G-" . $GroupUser; } print "Choose the server where the user home will be placed :\n"; $i = $#ExistServer + 1; foreach $ServerUser (@ExistServer) { print "$ServerUser "; } print " ? Type the number (1-$i) : "; $ServerUser = ; chomp($ServerUser); while( !($ServerUser =~ /[1-$i]/) or (length($ServerUser) > 1) ) { print "Wrong choice ! Please choose from 1 to $i : "; $ServerUser = ; chomp($ServerUser); $ServerUser = uc $ServerUser; } $ServerUser = $ExistServer[$ServerUser-1]; # ---- do the user have an email account ? print "None or Outlook ? (0-[1]) : "; chomp ($mailer = ); if ( $mailer eq "") { $mailer = "1"; } while( !($mailer =~ /[0-1]/) or (length($mailer) > 1) ) { print "Wrong choice ! Please choose between None (0) Outlook \[1\] : "; chomp ($mailer= ); } # ----- Abstract and confirmation print "Login : $LoginUser\n"; print "Name : $NameUser\n"; print "Group: $GroupUser : $Comment\n"; print "Home Server: $ServerUser\n"; if ($mailer eq "1") { print "Mailer : Outlook.\n"; } else { print "No mail configured\n"; } checkLDAP(); print "Do you want to continue ? [y]/n : "; $continue = ; chomp($continue); if ( $continue eq "n" ) { print "Nothing to do ! Stop.\n"; return 0; } else { system ("cls"); print "Let's create the user\n"; return 1; } } # ------- Creation of the user sub CreateUser { $UserShare = "\\\\$ServerUser\\$LoginUser\$"; # Creation of the user in the domain $error = undef; $PwdUser = "Wathever you want"; # Creation of the user in the domain $script = "perl\.bat"; Win32::NetAdmin::UserCreate($dc, $LoginUser, $PwdUser, undef, USER_PRIV_USER, # privilege $UserShare, # Le share path $comment, # Le commentaire UF_NORMAL_ACCOUNT|UF_SCRIPT, $script ) || die Win32::FormatMessage(Win32::GetLastError); # Mise à jour des Champs "Profile path", "HomeDrive Letter" et "Full Name" et change at first login my $level = 3; %hash = undef; Win32API::Net::UserGetInfo($dc, $LoginUser, $level, \%hash) || die Win32::FormatMessage(Win32::GetLastError); $hash{fullName} = $NameUser; $hash{profile} = "$UserShare\\System\\Profile"; $hash{homeDirDrive} = "G:"; $hash{passwordExpired} = 1; # Sinon la commande suivante plante $hash{workstations} = undef; $hash{password} = undef; # foreach $cle (keys (%hash)) { # print "$cle\t$hash{$cle}\n"; # } Win32API::Net::UserSetInfo($dc, $LoginUser, $level, \%hash, $error) || die Win32::FormatMessage(Win32::GetLastError); # Adding to the group Win32::NetAdmin::GroupAddUsers($dc, $GroupUser, $LoginUser) || die Win32::FormatMessage(Win32::GetLastError); print "User $LoginUser successfully created !\n"; # Synchronizing the domain Win32::Lanman::LogonControlPdcReplicate($dc, \%info) or die "Replication Error : error: Win32::Lanman::GetLastError()"; sleep(4); undef %info; # Creation of the home directory &HomeCreation; if ($mailer eq "1") { &OutlookGen; } } # Create the HOME, setting the good ACL's, setting the quota's sub HomeCreation { # Creation of the home directory and the dir on the public $Fletter = substr $LoginUser,0,1; mkdir "\\\\$ServerUser\\private\\User\-$Fletter\\$LoginUser",777 || die "Cannot create the user home directory : \\\\$ServerUser\\private\\User\-$Fletter\\$LoginUser\n"; $UserDir = "\\\\$ServerUser\\private\\User\-$Fletter\\$LoginUser"; $share{path} = "G:\\private\\User\-$Fletter\\$LoginUser"; # physical share path foreach $server (@ExistServer) { if ( -d "\\\\$server\\$comment" ) { mkdir "\\\\$server\\$comment\\$LoginUser",777 || die "Cannot create the Public dir : \\ \\$comment\\$LoginUser\n"; last; } } $share{netname} = "$LoginUser\$"; $share{type} = Win32::Lanman::STYPE_DISKTREE; # share type $share{remark} = "Private share"; # remark $share{permissions} = Win32::Lanman::ACCESS_ALL; # only used for share level security $share{max_uses} = -1; # number of users can connect Win32::Lanman::NetShareAdd( $ServerUser, \%share ) or warn "Share creation error : $^E\n"; # Applying the correct ACE $admin = "Administrators"; $login = "DOMAIN\\$LoginUser"; # Create an empty Security Descriptor on a specified DIR $homePerm = new Win32::Perms ($UserDir) || die "Error creating Perm object : $UserDir"; $homePerm->Remove(-1); $homePerm->Allow($admin, FULL, CONTAINER_INHERIT_ACE ) || die "Error Add"; $homePerm->Allow($admin, FULL, OBJECT_INHERIT_ACE | INHERIT_ONLY ) || die "Error Add"; $homePerm->Allow($login, CHANGE, CONTAINER_INHERIT_ACE ) || die "Error Add"; $homePerm->Allow($login, CHANGE, OBJECT_INHERIT_ACE | INHERIT_ONLY ) || die "Error Add"; $homePerm->Set() || die "Error Set"; $homePerm->Close(); # Copying the config files and the roaming profile system ("xcopy \\\\PDC\\c\$\\lbin\\generic\\system\\*\.\* $UserDir\\system /s /v /e /k /h /q > NUL"); print "Home directory $UserDir successfully created !\n"; } sub createLog { open ( F_LOG, ">>$logFile") || die "Fichier log $logFile innaccessible !!"; print (F_LOG "_________________________\n\n"); print (F_LOG "Created by $adminFullUser on "); open (F_DATE, "date /T |"); # =~ /.+([0-9][0-9])\/([0-9]+)\/([0-9]+)/; $date = ; close (F_DATE); print (F_LOG "$date"); print (F_LOG "Login : $LoginUser\t\tName : $NameUser\nGroup : $GroupUser \tHome Server : $ServerUser\n\n"); close (F_LOG); print "new_user.log successfully updated !\n"; } sub getData { $db = new Win32::ODBC($DSN) || die "Error ODBC : " . Win32::ODBC::Error() . "\n"; # Fourth you execute your SQL command (NOTE: due to backward compatibility with NT::ODBC the # Sql() method returns undef if it was successful and a non zero integer error number if it fails): $login = $LoginUser; $SqlStatement = "SELECT login, fname, lname, div FROM personnel where login like \'$login\'"; !($db->Sql($SqlStatement)) || die "SQL failed.Error: " . $db->Error() . "\n"; # Fifth you fetch the next row of data until there are no more left to fetch. # For each row you retrieve data and process it: while($db->FetchRow()){ undef %Data; %Data = $db->DataHash(); $login = $Data{"LOGIN"}; $surName = $Data{"LNAME"}; $givenName = $Data{"FNAME"}; $GroupUser = $Data{"PER_DIV"}; $NameUser = $givenName . " " . $surName; } $db->Close(); } sub OutlookGen { # This is used to activate the mail of the user. The activation is done trough a mail send to an SQL server. print "Sending Activation.\n"; open (F_OUT, ">c:\\temp\\activation.eum"); print (F_OUT "1\|$LoginUser\|DOMAIN\|$LoginUser\n"); close (F_OUT); my($MAPIobj)=new Win32::MAPI(UseDefProfile=>Yes); $MAPIobj->Logon() || die "Can't logon!"; my %mailData=(); $mailData{Text} = "Automatic Activation"; # message body. $mailData{Subject} = "ACTIVATE"; # the subject of the message $mailData{To} = ["MAIL_ACTIVATOR"]; # an array reference(or anonymous array reference) of recipients addresses $mailData{Attachment} = ["c:\\temp\\activation.eum"]; # an array reference(or anonymous array reference) of messages attachments $mailData{ShowDialog}= 0; # Yes or 1, No or 0 $MAPIobj->Send(\%mailData) || warn "Problem when sending the mail"; # send your email message. $MAPIobj->LastError; # see if Send() was ok $MAPIobj->Logoff(); undef $MAPIobj; # never forget to call the destructor! } sub checkLDAP { # This part is used to chack that the central and local uid are the same use Net::LDAP; $ldap = Net::LDAP->new('your_ldap_server',port => 'your_ldap_port') or die "$@"; $ldap->bind ; # an anonymous bind $mesg = $ldap->search ( # perform a search base => "o=your_organisation", filter => "(uid=$LoginUser)" ); $mesg->code && die $mesg->error; $max = $mesg->count; %hashLDAP = undef; for($i = 0 ; $i < $max ; $i++) { $entry = $mesg->entry($i); %hash = undef; foreach $attr ($entry->attributes) { if ($entry->get($attr) == undef) { $hashLDAP{$attr} = " "; } else { $hashLDAP{$attr} = ($entry->get($attr))->[0]; } } } if ($hashLDAP{givenname} eq undef) { print "Beware !! No $LoginUser in the LDAP !\n"; } else { print "Name of $LoginUser in LDAP : $hashLDAP{givenname} $hashLDAP{sn}\n"; } $ldap->unbind; # take down session }