I just ran across a message posted back in October of 2001 that began with:

"I am trying to convert the following vbscript to perl. I am having trouble setting 
the copied ace to the new user and idea on the line $sd->{DiscretionaryAcl} = 
$CopyDacl;"

I recently had the same problem... you cannot apparently assign back to the 
DiscretionaryACL parameter of the SecurityDescriptor object. The error indicates that 
the attribute interface doesn't exist, even though we just used it to retrieve data.

However, I later realized that any manipulations to the $acl object (my $acl = 
$sd->{'DiscretionaryACL'}) resulted in changes to the $sd object itself. The $acl 
object must be an interface that "references" the ACL in the SD object. This isn't how 
the interface is documented, so I'm wondering if it's a kludge in the Perl 
implementation? Makes me wonder what other differences exist out there?

So, the algorithm for adding an ACE to an object is something like:

my $sd = $obj->{'ntSecurityDescriptor'};
my $acl = $sd->{'DiscretionaryACL');
$acl->AddAce($previously_created_ace_object);
$obj->Put('ntSecurityDescriptor',$sd);
$obj->SetInfo();

If you want to add an ACE to the top of the ACL, it gets a bit trickier. Normally you 
would create a brand new ACL, add your ACE to the top, copy all of the ACE's from the 
actual object to the new ACL, and then assign the DiscretionaryACL attribute the value 
of your new ACL. But since it seems you're stuck with referencing the actual ACL only, 
the only way I could think to do it was delete all of the ACE's and re-apply them in 
the order I wanted (since the only methods available are RemoveAce and AddAce).  
Here's the general algorithm I used:

my $sd = $obj->{'ntSecurityDescriptor'}; # get the security descriptor
my $acl = $sd->{'DiscretionaryACL');     # get the acl interface to the sd
my $old_acl = $acl->CopyAccessList();    # make a copy of the ace's
my $enum = Win32::OLE::Enum->new($acl);  # enumerate through the real acl
while (my $ace = $enum->Next()) {
 $acl->RemoveAce($ace);                  # delete all of the ace's
} 
$acl->AddAce($my_ace);                   # add the ace I want at the top of the list
my $enum = Win32::OLE::Enum->new($old_acl); # enumerate through the saved acl
while (my $ace = $enum->Next()) {
  $acl->AddAce($ace);                    # restore the ace's we saved
}  
$obj->Put('ntSecurityDescriptor',$sd);   # store the new sd (with updated acl)
$obj->SetInfo();                         # make changes permanent

The code that I used this for was a routine that would create a Computer object and 
allow a specified third-party user to join it to the domain. If anyone would like a 
copy of the routine once I get it polished up, let me know.

Matt
_______________________________________________
Perl-Win32-Admin mailing list
[EMAIL PROTECTED]
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs

Reply via email to