Jump to content



Photo

Set Acl permissions UDF


  • Please log in to reply
78 replies to this topic

#1 FredAI

FredAI

    Wayfarer

  • Active Members
  • Pip
  • 77 posts

Posted 04 November 2011 - 03:34 PM

*
POPULAR

Hi.

I've been working on this for a while. I think now it's good enough to post it here.

Functions to do most everything with the DACL and ownership on all types of objects: Files or folders, Registry keys, services, Kernel and WMI objects, etc.

Here's a good example to test:
Plain Text         
#include 'Permissions.au3' _InitiatePermissionResources() FileWrite(@ScriptDir&'test.txt','Test') Local $TI = TimerInit() Local $ret = _DenyAllAccess(@ScriptDir&'test.txt',$SE_FILE_OBJECT,@UserName) Local $TD = TimerDiff($TI) MsgBox(0,'','Deny all access to test.txt and take ownership:'&@CRLF&@CRLF& _ '_DenyAllAccesss return value: '&$ret&'   Time: '&Round($TD,2)&' miliseconds.'&@CRLF& _ 'Check the file permissons before closing the message box.') $TI = TimerInit() $ret = _GrantReadAccess(@ScriptDir&'test.txt',$SE_FILE_OBJECT,'Administrators') $TD = TimerDiff($TI) MsgBox(0,'','Grant everyone read access, all access to admins and system, and set the owner: Admins group'&@CRLF&@CRLF& _ '_GrantReadAccesss return value: '&$ret&'   Time: '&Round($TD,2)&' miliseconds.'&@CRLF& _ 'Check the file permissons before closing the message box.') $TI = TimerInit() $ret = _GrantAllAccess(@ScriptDir&'test.txt') $TD = TimerDiff($TI) MsgBox(0,'','Grant everyone access'&@CRLF&@CRLF& _ '_GrantAllAccesss return value: '&$ret&'   Time: '&Round($TD,2)&' miliseconds.'&@CRLF& _ 'Check the file permissons before closing the message box.') $TI = TimerInit() $ret = _CopyFullDacl(@ScriptDir&'test.txt',$SE_FILE_OBJECT,@ScriptDir) $TD = TimerDiff($TI) MsgBox(0,'','Restore all inherited permissions'&@CRLF&@CRLF& _ '_CopyFullDacl return value: '&$ret&'   Time: '&Round($TD,2)&' miliseconds.'&@CRLF& _ 'Check the file permissons before closing the message box.') $TI = TimerInit() Local $aPerm[2][3] = [['Restricted',1,$GENERIC_ALL],['Users',1,$GENERIC_ALL]] $ret = _EditObjectPermissions(@ScriptDir&'test.txt',$aPerm) $TD = TimerDiff($TI) MsgBox(0,'','Add two granted access aces: Restricted and Users'&@CRLF&@CRLF& _ '_EditObjectPermissions return value: '&$ret&'   Time: '&Round($TD,2)&' miliseconds.'&@CRLF& _ 'Check the file permissons before closing the message box.') $TI = TimerInit() Dim $aPerm[2][3] = [['Restricted',1,$GENERIC_READ],['Users',1,$GENERIC_READ]] $ret = _EditObjectPermissions(@ScriptDir&'test.txt',$aPerm) $TD = TimerDiff($TI) MsgBox(0,'','Give only read access to the Restricted and Users groups'&@CRLF&@CRLF& _ '_EditObjectPermissions return value: '&$ret&'   Time: '&Round($TD,2)&' miliseconds.'&@CRLF& _ 'Check the file permissons before closing the message box.') $TI = TimerInit() Dim $aPerm[2][3] = [['Restricted',0,$GENERIC_ALL],['Users',0,$GENERIC_ALL]] $ret = _EditObjectPermissions(@ScriptDir&'test.txt',$aPerm) $TD = TimerDiff($TI) MsgBox(0,'','Deny access to the Restricted and Users groups'&@CRLF&@CRLF& _ '_EditObjectPermissions return value: '&$ret&'   Time: '&Round($TD,2)&' miliseconds.'&@CRLF& _ 'Check the file permissons before closing the message box.') $TI = TimerInit() Local $Hndl = _Permissions_OpenProcess(@AutoItPID) Local $SDBefore = _GetObjectStringSecurityDescriptor($Hndl,$SE_KERNEL_OBJECT) Local $CODRet = _ClearObjectDacl($Hndl,$SE_KERNEL_OBJECT) Local $DARet = _DenyAllAccess($Hndl,$SE_KERNEL_OBJECT) Local $SDAfter = _GetObjectStringSecurityDescriptor($Hndl,$SE_KERNEL_OBJECT) $TD = Round(TimerDiff($TI),2) MsgBox(0,'', 'Deny everyone access to the current process:'&@CRLF&@CRLF& _ '@AutoItPID original security descriptor: '&@CRLF&$SDBefore&@CRLF&@CRLF& _ '_ClearObjectDacl return value: '&$CODRet&@CRLF&@CRLF& _ '_DenyAllAccess_ return value: '&$DARet&@CRLF&@CRLF& _ 'New @AutoItPID security descriptor: '&@CRLF& _ $SDAfter&@CRLF&@CRLF& 'Time taken: '&$TD&' miliseconds.') _Permissions_CloseHandle($Hndl) FileDelete(@ScriptDir&'test.txt') _ClosePermissionResources()

I'm planning to add functions to deal with the Sacl in the future, even though I don't think it's very important.

Edit: Let me know if you need an example for the registry.

Updated: Fixed a bug in the _ClearObjectDacl function. I thought that adding a null DACL would work fine, but it causes problems later when adding a new DACL.
Those who have downloaded, please update.
Shoot! Now it wasn't clearing the DACL at all. Updated again. I think it's fixed now.

Updated 9/11/2011 - Added the security descriptor functions and removed unnecessary constants.

Updated 10/11/2011 - There were some functions missing in the index, and some parameters in the comments. Also removed the "MustDeclareVars" option. (About 50 total downloads before)

Update 12/12/2011 - Added more functions:

Spoiler


New Update 12/12/2011 - Missing declaration keywords in 3 constants. Sorry

Update 16/12/2011 - Added support for all object types, including window and process handles. Added more functions, modified most of them, and removed one.

Here's the new function list:

Spoiler


Updated 22/2/2012.. This time I'm including SecurityConstants.au3 and FileConstants.au3 to prevent constants conflicts. Added a few more functions and fixed a few bugs.

Also added the ability to include the inherited aces in the _EditObjectPermissions function.

Now the permissions array can have four elements (optional). It will still work with three elements arrays though. The fourth element is intended to have the inheritance flag for the corresponding ace.

Here's the new list of functions:

Spoiler



400 previous downloads

Attached Files


Edited by FredAI, 23 February 2012 - 10:31 PM.

  • AdamUL, hehui, KaFu and 3 others like this







#2 DXRW4E

DXRW4E

    Adventurer

  • Active Members
  • PipPip
  • 131 posts

Posted 04 November 2011 - 07:16 PM

Thank You, very useful

Thanks Again

Ciao.

#3 KaFu

KaFu

    Hey, it's just me, KhaFoo...

  • MVPs
  • 3,165 posts

Posted 04 November 2011 - 08:07 PM

Definitely looks good :D , thanks a lot!

#4 FredAI

FredAI

    Wayfarer

  • Active Members
  • Pip
  • 77 posts

Posted 04 November 2011 - 09:54 PM

You're welcome guys! It was my contribution to the community, after taking so much :D
Works much faster than SetAcl, and you can set the owner, clear the DACL and define all the desired permissions with one function call.

#5 BrewManNH

BrewManNH

    באָבקעס מיט קודוצ׳ה

  • MVPs
  • 6,876 posts

Posted 04 November 2011 - 10:23 PM

I really like the look of this UDF, I was looking for something exactly like this earlier today for an automation script I was creating. This will finish it off exactly as I need to.

Thank you for this.

How to ask questions the smart way!

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.

Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.

_FileGetProperty - Retrieve the properties of a file SciTE Toolbar - A toolbar demo for use with the SciTE editorGUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.

GUIToolTip UDF Demo - Demo script to show how to use the GUIToolTip UDF to create and use customized tooltips.

Posted Image


#6 FredAI

FredAI

    Wayfarer

  • Active Members
  • Pip
  • 77 posts

Posted 04 November 2011 - 11:02 PM

You're welcome, BrewManNH.

If any of you find any bugs, please tell.

#7 DXRW4E

DXRW4E

    Adventurer

  • Active Members
  • PipPip
  • 131 posts

Posted 05 November 2011 - 08:43 AM

Hi FredAI, sorry for my english

it is possible to add these function http://msdn.microsoft.com/en-us/library/aa379570%28v=VS.85%29.aspx ConvertSecurityDescriptorToStringSecurityDescriptor and ConvertStringSecurityDescriptorToSecurityDescriptor

Ciao.

#8 IRON

IRON

    Seeker

  • Active Members
  • 8 posts

Posted 05 November 2011 - 09:56 AM

Not yet tested, but it looks good. :D
Thanks a lot

#9 FredAI

FredAI

    Wayfarer

  • Active Members
  • Pip
  • 77 posts

Posted 05 November 2011 - 01:01 PM

I fixed a bug and updated the file. Check the first post.

it is possible to add these function ...

Well, here they are:
Plain Text         
  #include 'Permissions.au3' _InitiatePermissionResources() FileWrite(@ScriptDir&'\test.txt','test') Local $TI = TimerInit() ;************************************************************************************************ Local $ret = _GetObjectStringSecurityDescriptor(@ScriptDir&'\test.txt'); Put here the function to test Local $ret2 = _ConvertStringSecurityDescriptorToSecurityDescriptor($ret) ;************************************************************************************************ Local $TD = TimerDiff($TI) MsgBox(0,'','String security descriptor: '&$ret&@CRLF&'Stecurty descriptor pointer: '&$ret2&@CRLF&'   Time: '&Round($TD,2)&' miliseconds.') FileDelete(@ScriptDir&'\test.txt')  _ClosePermissionResources()    Func  _GetObjectStringSecurityDescriptor($oName, $_SE_OBJECT_TYPE = $SE_FILE_OBJECT) Local $SECURITY_INFORMATION = BitOR($DACL_SECURITY_INFORMATION,$OWNER_SECURITY_INFORMATION) Local $pSecDescriptor = _GetObjectSecurityDescriptor($oName, $_SE_OBJECT_TYPE) Local $strSecDescriptor = _ConvertSecurityDescriptorToStringSecurityDescriptor($pSecDescriptor) DllCall($h__Kernel32Dll,'handle','LocalFree','handle',$pSecDescriptor) Return $strSecDescriptor EndFunc ;==>_GetObjectStringSecurityDescriptor   Func  _ConvertSecurityDescriptorToStringSecurityDescriptor(ByRef $pSecDescriptor) Local $SECURITY_INFORMATION = BitOR($DACL_SECURITY_INFORMATION,$OWNER_SECURITY_INFORMATION) Local $aRet = DllCall($h__Advapi32Dll,'bool','ConvertSecurityDescriptorToStringSecurityDescriptor', _ 'ptr',$pSecDescriptor,'DWORD',1,'DWORD',$SECURITY_INFORMATION,'str*',0,'ptr',0) If @error Then Return SetError(1,0,'') Return $aRet[4] EndFunc ;==>_ConvertSecurityDescriptorToStringSecurityDescriptor   Func  _ConvertStringSecurityDescriptorToSecurityDescriptor(ByRef $strSecDescriptor) Local $aRet = DllCall($h__Advapi32Dll,'bool','ConvertStringSecurityDescriptorToSecurityDescriptor', _ 'str',$strSecDescriptor,'DWORD',1,'ptr*',0,'ptr',0) If @error Then Return SetError(1,0,0) Return $aRet[3] EndFunc ;==>_ConvertStringSecurityDescriptorToSecurityDescriptor   Func _GetObjectSecurityDescriptor($oName, $_SE_OBJECT_TYPE = $SE_FILE_OBJECT) Local $SECURITY_INFORMATION = BitOR($DACL_SECURITY_INFORMATION,$OWNER_SECURITY_INFORMATION) If $ResourcesState = 0 Then _InitiatePermissionResources() If $_SE_OBJECT_TYPE = $SE_REGISTRY_KEY Then $oName = _Security_RegKeyName($oName) Local $aRet = DllCall($h__Advapi32Dll,'DWORD','GetNamedSecurityInfo','str',$oName,'int',$_SE_OBJECT_TYPE,'DWORD',$SECURITY_INFORMATION,'ptr',0,'ptr',0,'ptr',0,'ptr',0,'ptr*',0) If @error Then Return SetError(@error,0,0) Return SetError($aRet[0],0,$aRet[8]) EndFunc ;==>_GetObjectSecurityDescriptor  

I don't know why you need these functions, but if you're planning on using them to set the DACL permissions, let me tell you you don't need them.
You can easily edit the DACL by calling the _SetObjectPermissions function.

Imagine you want to give yourself all granted access to a file, but give everyone else only read and execute access. This can be very useful if you have kids, and you want them to be able to read and execute your files, but you don't want them to edit or delete them.

Take a look at this code:

#include 'Permissions.au3' _InitiatePermissionResources() Local $File = @ScriptDir&'\test.txt' FileWrite($File,'test') Local $TI = TimerInit()   Local $aPerm[2][3] $aPerm[0][0] = @UserName $aPerm[0][1] = 1 $aPerm[0][2] = $GENERIC_ALL $aPerm[1][0] = 'Everyone' $aPerm[1][1] = 1 $aPerm[1][2] = $GENERIC_READ+$GENERIC_EXECUTE Local $ret = _SetObjectPermissions($File,$aPerm,$SE_FILE_OBJECT,@UserName,1,1) Local $TD = TimerDiff($TI) MsgBox(0,'','Function return value: '&$ret&@CRLF&'   Time: '&Round($TD,2)&' miliseconds.') _ClosePermissionResources()  

You just have to create an array with the permissions you want to set:
$array[0][0] - First ace user name or Sid string
$array[0][1] - 1 or 0,whether to grant or deny the permissions defined in the access mask. ($array[0][2])
$array[0][2] - One or more access mask values. e.g. $GENERIC_READ+$GENERIC_EXECUTE

$array[1][0] - Second ace user name or Sid string
$array[1][1] - 1 or 0,whether to grant or deny the permissions defined in the access mask. ($array[1][2])
$array[1][2] - One or more access mask values. e.g. $GENERIC_READ+$GENERIC_EXECUTE

And so on. You can add how many aces you want. The access denied aces have priority over the allowed ones.
Then you can set the owner, clear the DACL and recurse containers and objects (for folders and registry keys), When recursing, the child objects will automatically inherit the permissions from the parent one.

Don't know what else you can do by modifying the security descriptor.

#10 DXRW4E

DXRW4E

    Adventurer

  • Active Members
  • PipPip
  • 131 posts

Posted 05 November 2011 - 07:48 PM

Thank you very much, i needed those functions because I want to have a backup of the security of the registry\file\service (save all the inf file), to give users the possibility to restore the original settings, using Secedit.exe (the way that Microsoft sets everything in windows ect ect)

Sorry again for my English

Ciao

Edited by DXRW4E, 05 November 2011 - 08:59 PM.


#11 DXRW4E

DXRW4E

    Adventurer

  • Active Members
  • PipPip
  • 131 posts

Posted 05 November 2011 - 11:24 PM

I wanted to ask, even for one thing, using the _ConvertSecurityDescriptorToStringSecurityDescriptor, or this line $a = "O:BUD:PAI(A;;FA;;;BU)(A;;0x1200a9;;;WD)"
after using the _ConvertStringSecurityDescriptorToSecurityDescriptor($a), how can I use that to set the _WriteDaclToObject, I'm doing wrong or something?, This is interesting because I shall be able to keep all the original settings, and add admin only right, for example "O:BUD:PAI(A;;FA;;;BU)(A;;0x1200a9;;;WD)(A;;FA;;;BA)" (This explains all about it http://msdn.microsoft.com/en-us/magazine/cc982153.aspx)

I know from experience that this is not the safest way, because if "TrustedInstaller" and present, even if you have full admin right, sometimes "TrustedInstaller" still does not let you do everything there (for example if you want to work with files in "C:\Windows\WinSxS" and better remove remaining TrustedInstaller), so the best way and _SetObjectPermissions, However i am interested also this other way using the _ConvertStringSecurityDescriptorToSecurityDescriptor

sorry for the trouble

Thanks again, Ciao.

Edited by DXRW4E, 05 November 2011 - 11:51 PM.


#12 FredAI

FredAI

    Wayfarer

  • Active Members
  • Pip
  • 77 posts

Posted 06 November 2011 - 12:09 AM

after using the _ConvertStringSecurityDescriptorToSecurityDescriptor($a), how can I use that to set the _WriteDaclToObject,


You have to get the DACL from the security descriptor. I'll take a look at the function and post back in a while.

#13 FredAI

FredAI

    Wayfarer

  • Active Members
  • Pip
  • 77 posts

Posted 06 November 2011 - 10:06 AM

Ok Here it is:


Plain Text         
#include 'Permissions.au3' _InitiatePermissionResources() FileWrite(@ScriptDir&'\test.txt','test') Local $TI = TimerInit() ;************************************************************************************************ Local $ret1 = _GetObjectSecurityDescriptor(@ScriptDir&'\test.txt') Local $ret2 = _ConvertSecurityDescriptorToStringSecurityDescriptor($ret1) Local $ret3 = _ConvertStringSecurityDescriptorToSecurityDescriptor($ret2) Local $ret4 = _GetSecurityDescriptorOwner($ret3) Local $ret5 = _GetSecurityDescriptorDacl($ret3) ;************************************************************************************************ Local $TD = TimerDiff($TI) MsgBox(0,'','Security descriptor pointer: '&$ret1&@CRLF& _ 'Converted to string: '&$ret2&@CRLF& _ 'Re-converted to pointer to security descriptor: '&$ret3&@CRLF& _ 'Owner SID: '&$ret4&@CRLF& _ 'Pointer to the DACL: '&$ret5&@CRLF& _ '   Time: '&Round($TD,2)&' miliseconds.') FileDelete(@ScriptDir&'\test.txt')  _ClosePermissionResources()   Func _GetSecurityDescriptorOwner(ByRef $pSecDescriptor) If Not IsPtr($pSecDescriptor) Then Return SetError(1,0,0) Local $aRet = DllCall($h__Advapi32Dll,'bool','GetSecurityDescriptorOwner', _ 'ptr',$pSecDescriptor,'ptr*',0,'bool*',0) If @error Then Return SetError(@error,0,0) Return _SidToStringSid($aRet[2]) EndFunc ;==>_GetSecurityDescriptorDacl    Func _GetSecurityDescriptorDacl(ByRef $pSecDescriptor) If Not IsPtr($pSecDescriptor) Then Return SetError(1,0,0) Local $aRet = DllCall($h__Advapi32Dll,'bool','GetSecurityDescriptorDacl', _ 'ptr',$pSecDescriptor,'bool*',0,'ptr*',0,'bool*',0) If @error Then Return SetError(@error,0,0) If Not $aRet[2] Then Return SetError(1,0,0) Return $aRet[3] EndFunc ;==>_GetSecurityDescriptorDacl    Func  _GetObjectStringSecurityDescriptor($oName, $_SE_OBJECT_TYPE = $SE_FILE_OBJECT) Local $SECURITY_INFORMATION = BitOR($DACL_SECURITY_INFORMATION,$OWNER_SECURITY_INFORMATION) Local $pSecDescriptor = _GetObjectSecurityDescriptor($oName, $_SE_OBJECT_TYPE) Local $strSecDescriptor = _ConvertSecurityDescriptorToStringSecurityDescriptor($pSecDescriptor) DllCall($h__Kernel32Dll,'handle','LocalFree','handle',$pSecDescriptor) Return $strSecDescriptor EndFunc ;==>_GetObjectStringSecurityDescriptor   Func  _ConvertSecurityDescriptorToStringSecurityDescriptor(ByRef $pSecDescriptor) If Not IsPtr($pSecDescriptor) Then Return SetError(1,0,0) Local $SECURITY_INFORMATION = BitOR($DACL_SECURITY_INFORMATION,$OWNER_SECURITY_INFORMATION) Local $aRet = DllCall($h__Advapi32Dll,'bool','ConvertSecurityDescriptorToStringSecurityDescriptor', _ 'ptr',$pSecDescriptor,'DWORD',1,'DWORD',$SECURITY_INFORMATION,'str*',0,'ptr',0) If @error Then Return SetError(1,0,'') Return $aRet[4] EndFunc ;==>_ConvertSecurityDescriptorToStringSecurityDescriptor   Func  _ConvertStringSecurityDescriptorToSecurityDescriptor(ByRef $strSecDescriptor) If Not IsString($strSecDescriptor) Then Return SetError(1,0,0) Local $aRet = DllCall($h__Advapi32Dll,'bool','ConvertStringSecurityDescriptorToSecurityDescriptor', _ 'str',$strSecDescriptor,'DWORD',1,'ptr*',0,'ptr',0) If @error Then Return SetError(1,0,0) Return $aRet[3] EndFunc ;==>_ConvertStringSecurityDescriptorToSecurityDescriptor   Func _GetObjectSecurityDescriptor($oName, $_SE_OBJECT_TYPE = $SE_FILE_OBJECT) Local $SECURITY_INFORMATION = BitOR($DACL_SECURITY_INFORMATION,$OWNER_SECURITY_INFORMATION) If $ResourcesState = 0 Then _InitiatePermissionResources() If $_SE_OBJECT_TYPE = $SE_REGISTRY_KEY Then $oName = _Security_RegKeyName($oName) Local $aRet = DllCall($h__Advapi32Dll,'DWORD','GetNamedSecurityInfo','str',$oName,'int',$_SE_OBJECT_TYPE, _ 'DWORD',$SECURITY_INFORMATION,'ptr',0,'ptr',0,'ptr',0,'ptr',0,'ptr*',0) If @error Then Return SetError(@error,0,0) Return SetError($aRet[0],0,$aRet[8]) EndFunc ;==>_GetObjectSecurityDescriptor


Now that I know why you need the functions, I'm finding this very interesting, because it allows to make a full backup of the security descriptor, and restore it later. No need for secedit.

When I have more time, I'll document the functions and add them to the UDF.

#14 DXRW4E

DXRW4E

    Adventurer

  • Active Members
  • PipPip
  • 131 posts

Posted 06 November 2011 - 10:10 AM

Thanks so much for all the support

When you add function to UDF,better if you add a direct fuction as the _GetObjectStringSecurityDescriptor (ScriptDir @ & '\ test.txt'), for example add _SetObjectStringSecurityDescriptor(ScriptDir @ & '\ test.txt,',"O:BUD:PAI(A;;FA;;;BU)(A;;0x1200a9;;;WD)(A;;FA;;;BA)"), I do not know, see for yourself how and best

Ciao.

Edited by DXRW4E, 06 November 2011 - 10:42 AM.


#15 JScript

JScript

    Goodbye everybody, I got tired of this system adopted here!

  • Active Members
  • PipPipPipPipPipPip
  • 1,062 posts

Posted 06 November 2011 - 12:31 PM

Very complex, perfect!
Thanks for sharing...

João Carlos.
http://notebook.forumais.com (Forum Maintenance Notebooks and Desktop)http://autoitbrasil.com/ (AutoIt v3 Brazil!!!)
Spoiler

Posted Image Download Dropbox - Simplify your life!Your virtual HD wherever you go, anywhere!       


#16 Spiff59

Spiff59

    Universalist

  • Active Members
  • PipPipPipPipPipPip
  • 1,312 posts

Posted 07 November 2011 - 03:38 AM

I've always found calling icacls.exe very simple for changing permissions. Is the main difference between the UDF and icacls that icacls is restricted to modifying only files and folders?

#17 FredAI

FredAI

    Wayfarer

  • Active Members
  • Pip
  • 77 posts

Posted 07 November 2011 - 08:26 AM

No, this is also much faster, and makes your script independent from external exes, which can be disabled or infected.

Also AFAIK you can't set ownership using icacls.

#18 FredAI

FredAI

    Wayfarer

  • Active Members
  • Pip
  • 77 posts

Posted 09 November 2011 - 12:16 AM

I added the security descriptor functions to the UDF and updated. see the first post.

#19 DXRW4E

DXRW4E

    Adventurer

  • Active Members
  • PipPip
  • 131 posts

Posted 09 November 2011 - 12:57 AM

Thank You

#20 FredAI

FredAI

    Wayfarer

  • Active Members
  • Pip
  • 77 posts

Posted 10 November 2011 - 10:21 PM

I updated again. This time I didn't change the code, just some faults in the comments.

The _SetObjectPermissions function now supports setting the inheritance too, but remember you cannot create an ace with the flag $INHERIT_ONLY_ACE. This type of aces are automatically added from the parent upon the object's creation.

Better use the flags $OBJECT_INHERIT_ACE (1), $CONTAINER_INHERIT_ACE ( 2), $SUB_CONTAINERS_AND_OBJECTS_INHERIT (3) and $NO_PROPAGATE_INHERIT_ACE (4)




1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users