0227lld has asked for the wisdom of the Perl Monks concerning the following question:

I've been scouring the web to see if it can be done but I havent found anything. I wrote a perl script to generate an AD account. Everything works, except the attr homeDirectory and homeDrive. It get's populated, but the folder doesn't get created (if I create the user by hand in windows the folder get's created). Ok, so I do a mkdir on a mount I have, but don't know how to give that new user permission for that folder. I'm binding as an admin, and I'm mounting the shared folder as an admin so I can create the folder. Code below

#!/usr/bin/perl -w use strict; use warnings; use DBI; use Net::LDAP; use Net::LDAP::Util qw(ldap_error_text); use Mail::Sender; use Unicode::String qw(utf8 utf16le); require '/usr/local/Candy/private.pl'; my($ldapbase, $password, $today, $outdir, $outfile, $binddn, $ldap, $m +esg, $searchresult); my($result, $candyconnection, $query, $SQL, @data, $jobcode, $deptcode +, $membrof, $mo, $moquery); my($ou, $lname, $fname, $candyID, $dept_desc, $job_desc, $homeDrive, $ +homeDirectory, $scriptPath); sub init { $ldapbase = "OU=candy Users and Computers,DC=candy,DC=com"; $password = get_password(); $binddn = get_binddn(); $outdir="/tmp"; $outfile="newADusers.csv"; $candyconnection = DBI->connect('DBI:mysql:candyTEST;host=123.123.123 +.123', 'root', 'candy') || die "Could not connect to database: $DBI:: +errstr"; # system("rm $outdir/$outfile*"); } sub chk4newuser { # open(OUTFILE,"> $outdir/$outfile"); $ldap = Net::LDAP->new ( "ds.candy.com" ) or die "$@"; $mesg = $ldap->start_tls( ); die $mesg->error( ) if $mesg->code( ); $mesg = $ldap->bind ( dn => $binddn, password => $password,version => + 3 ); # use for changes/edits if($mesg->code){ die "An error occurred binding to the LDAP server: " +.ldap_error_text($mesg->code)."\n"; } $SQL="SELECT `ou`, `lname`, `fname`, `candyID`, `dept_desc`, `job_des +c` , `homeDrive`, `homeDirectory`, `scriptPath`, `Dept`.`Deptcode`, `Job`.`Jobcode` FROM `AD_Prov`, `Job`, `Dept` WHERE `type` ='TM' and `create_dt` is NULL and `Dept`.`Deptcode` = `AD_Prov`.`Deptcode` and `Job`.`Jobcode` = `AD_Prov`.`Jobcode`;"; $query = $candyconnection->prepare($SQL); # print "$SQL\n"; $query->execute(); while (@data = $query->fetchrow_array()) { $ou = $data[0]; $lname = $data[1]; $fname = $data[2]; $candyID = $data[3]; $dept_desc = $data[4]; $job_desc = $data[5]; $homeDrive = $data[6]; $homeDirectory = $data[7]; $scriptPath = (!defined $data[8] || $data[8] eq "") ? "Main.bat" +: $data[8]; $deptcode = $data[9]; $jobcode = $data[10]; $searchresult = $ldap->search(base => $ldapbase, filter => "(&(objectCategory=person)(objectClass=user)(sAMAccountNa +me=$candyID))", scope => "sub" ); if ($searchresult->entries) { print "Already Exists\n";#Found an AD Account ALREADY } else { EmpaddADaccount(); } } # close(OUTFILE); } sub EmpaddADaccount { my $pass_utf8 = utf8('"pass1234"'); my $pass_win = $pass_utf8->utf16le(); $result = $ldap->add ( "cn=" . $fname . " " . $lname . "," . $ou, attr => [ 'cn' => $fname . " " . $lname, 'sn' => $lname, 'displayName' => $fname . " " . $lname, 'givenName' => $fname, 'mail' => $fname . "." . $lname . "\@candycane.com", 'sAMAccountName' => $candyID, 'employeeID' => $candyID, 'userPrincipalName' => $candyID . "\@candy.com", 'userAccountControl' => '512', 'unicodePwd' => $pass_win, 'pwdLastSet' => '0', 'department' => $dept_desc, 'title' => $job_desc, 'description' => $dept_desc . " - " . $job_desc, 'homeDirectory' => $homeDirectory, 'homeDrive' => $homeDrive, 'company' => 'candy', 'mailNickname' => $candyID, 'telephoneNumber' => '555 123 4567', 'postalCode' => '33458', 'scriptPath' => $scriptPath, 'streetAddress' => '123 Main St', 'l' => 'Anytown', 'st' => 'GA', 'c' => 'US', 'co' => 'United States', 'countryCode' => '840', 'proxyAddresses' => "SMTP:" . $fname . "." . $lname . "\@candyc +ane.com", 'proxyAddresses' => "smtp:" . substr($fname,0,1) . $lname . "\@ +candycane.com", 'objectclass' => [ "top", "person", "organizationalPerson", "user" ] ] ); $result->code && warn "failed to add entry: ", $result->error ; $SQL="SELECT `dn` FROM `AD_memberOf` WHERE (`deptcode` = '999' and `jobcode` = '99') OR (`deptcode` = '$deptcode' and `jobcode` = '99') OR (`deptcode` = '$deptcode' and `jobcode` = '$jobcode');"; $moquery = $candyconnection->prepare($SQL); # print "$SQL\n"; $moquery->execute(); while ($membrof = $moquery->fetchrow_array()) { # print "$membrof\n"; $result = $ldap->modify($membrof, add => { member => [ "cn=" . $fnam +e . " " . $lname . "," . $ou ] } ); $result->code && warn "failed to add entry: ", $result->error ; } mkdir "/mnt/winserver/users/" . $candyID; } &init; &chk4newuser;

Replies are listed 'Best First'.
Re: Giving a window user permission to a windows folder from linux
by soonix (Chancellor) on Jan 23, 2015 at 12:22 UTC

    That's probably not a perl question. If I create a user in AD, I do so on one of our directory servers, and the directory is not created before the user's first login, because the system doesn't know on which server(s) the drive and directory would have to be (a "drive" only makes sense if it is known on which host/system that drive is valid).

    Plus, these "homeAnything" attributes are not listed in the "default enabled AD attributes" on http://support.microsoft.com/kb/257218

    I don't have experience with setting these, and I think you'll have to seek in more microsoftish sites.

      Thanks, but but I don't think that's correct. homeDrive is whatever letter you want the homeDirectory to be (h: or k: etc.), the homeDirectory is a server/folder mapping (\\server\folder) and when I mount a cifs and create a folder, it exist on that server. The question is how to give that new window user permission to use that folder from the perl script that's running on linux. If i was running perl on windows it would be a non issue.

Re: Giving a window user permission to a windows folder from linux
by chacham (Prior) on Jan 23, 2015 at 15:19 UTC

    Side comments on the SQL itself.

    The first query might benefit from qualifying the columns names (with the table names.) Right now, it only qualifies those that are ambiguous, which is fine. Qualifying all of them helps with readability and consistency.

    The second query uses dynamic SQL. Considering the query is being prepared anyway, perhaps you can change the variables to placeholders and specify their values in the execute().

      True, for readability and consistency.