CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Win32 Programming Help:
Using Perl with WMI to set folder level permissions

 



IndiePendent79
New User

Feb 14, 2007, 8:32 AM

Post #1 of 2 (3411 views)
Using Perl with WMI to set folder level permissions Can't Post

In an effort to automate LAN account creation I have designed a Perl script that will take specific information that is input by a user and create a "personal drive" on a network storage device and the automatically set the permissions on the folder so that the user can access it. Unfortunately, I am running into issue with not correctly adding the new ACE back to the existing security descriptor. I have found that it is unnecessary to create an array of the existing ACEs as they are all inherited and will be repopulated if a new array of the single new ACE is added. If anyone has any experience with using WMI to set folder permissions in Perl ANY and ALL advice is welcome as I have reached a dead end with every solution I try. Here is the following applicable code for what I am attempting to accomplish:

Code
use Win32::OLE::Variant; 
$Win32::OLE::Warn = 3;

# ACE access mask, flag, and type constants
our $ADS_ACCESSMASK_READ_WRITE_EXECUTE_DELETE = -536805376;
our $ADS_ACCESSMASK_FULL = 268435456;
our $ADS_ACEFLAG_UNKNOWN = 0x1;
our $ADS_ACEFLAG_INHERIT_ACE = 0x2;
our $ADS_ACEFLAG_INHERITED_ACE = 0x10;
our $ADS_ACETYPE_ACCESS_ALLOWED = 0;
our $ADS_ACETYPE_ACCESS_DENIED = 0x1;
our $ADS_ACETYPE_ACCESS_ALLOWED_OBJECT = 0x5;
our $ADS_ACETYPE_ACCESS_DENIED_OBJECT = 0x6;
our $NTFS_MODIFY = 0x1245631;
our $NTFS_FULL_CONTROL = 0x2032127;

# get a SWbemLocator object
my $objLocator = Win32::OLE->new('WbemScripting.SWbemLocator') or
die "can't create locator object: ".Win32::OLE->LastError( )."\n";

# set the impersonate level to "impersonate"
$objLocator->{Security_}->{impersonationlevel} = 3;
$objLocator->{Security_}->{Privileges}->AddAsString("seRestorePrivileg
+e");

my $server = "servername.domain.com";
# use it to get a an SWbemServices object
my $objServices = $objLocator->ConnectServer($server, 'root\cimv2') or
+
die "can't create server object: ".Win32::OLE->LastError( )."\n";

my $path = "d:\\userdata\\user";

print "Win32_LogicalFileSecuritySetting.Path='$path'\n";
my $objDirectorySecSetting = $objServices->Get("Win32_LogicalFileSecur
+itySetting.Path='$path'");

my $objSecDescriptor = Win32::OLE::Variant-> new (VT_DISPATCH|VT_BYREF
+);

my $retval = $objDirectorySecSetting->GetSecurityDescriptor($objSecDes
+criptor);

# Get the Win32_SecurityDescriptor from the variant.
my $sd = $objSecDescriptor->Get();
print "$sd\n";

# Get the ACL, which is just an array of Win32_ACE objects.
my @dacl = @{$sd->{'DACL'}};

#open local wmi instance
my $wmi = Win32::OLE->GetObject('WinMgmts:{impersonationlevel=imperson
+ate}!root/cimv2');

my $strName = "USER";
my $strDomain = "DOMAIN";

#create instance of Win32_Account bound to user (doing this so we can
+get the user's SID)
my $account = $wmi->Get('Win32_Account.Domain=\'' . $strDomain . '\',N
+ame=\'' . $strName . '\'');

#create instance of Win32_SID populated using account instance from ab
+ove, this lets us get SID in different formats
my $accountSID = Win32::OLE->GetObject('Winmgmts:{impersonationlevel=i
+mpersonate}!root/cimv2:Win32_SID.SID=\'' . $account->SID . '\'');

#create instance of Win32_Trustee and populate (note: uses Sid instanc
+e from above)
my $objTrustee = $wmi->Get("Win32_Trustee")->SpawnInstance_;
$objTrustee->{Domain} = $strDomain;
$objTrustee->{Name} = $strName;
$objTrustee->{SID} = $accountSID->BinaryRepresentation;

#Create instance of Win32_Ace and populate values (note: uses trustee
+instance from above)
my $newACE = $wmi->Get("Win32_Ace").Spawninstance_;
$newACE->{AccessMask} = $NTFS_MODIFY;
$newACE->{AceFlags} = $ADS_ACEFLAG_UNKNOWN | $ADS_ACEFLAG_INHERIT_ACE;
$newACE->{AceType} = $ADS_ACETYPE_ACCESS_ALLOWED;
$newACE->{Trustee} = $objTrustee;

my $ACEArray;

#Add the newACE above to the ACEArray
push(@$ACEArray,$newACE);

print "New ACE list:\n";
foreach my $ace (@ACEArray)
{
$trustee = $ace->{'Trustee'};
$acetype = $ace->{'AceType'};
$aceflag = $ace->{'AceFlags'};
$acemask = $ace->{'AccessMask'};

$name = $trustee->{'Name'};
print "Name: $name\n";
print "$acetype\n";
print "$aceflag\n";
print "$acemask\n";
}
# Replace the DACL with the ACEArray containing the new ACE
$sd->{DACL} = $ACEArray;

#Write DACL back to security descriptor of the folder
my $retval = $objDirectorySecSetting->SetSecurityDescriptor($sd);

My main issue occurs when attempting to write the new security descriptor back out to the folder. Thanks, Derek


KevinR
Veteran


Feb 14, 2007, 2:57 PM

Post #2 of 2 (3400 views)
Re: [IndiePendent79] Using Perl with WMI to set folder level permissions [In reply to] Can't Post

I don't know the answer or even have a suggestion. Maybe davorg (athough he seems to not know the windows stuff too much) or Probulletin (I'm not sure if he does or not), the only two other members that answer questions reliably here, will be able to help. But I see you have this on devshed too so you will more likely get an answer/suggestion there as devshed has more active members on that perl forum. You can also try at perlmonks.com
-------------------------------------------------

 
 


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives