Jump to content

Set Acl permissions UDF


FredAI
 Share

Recommended Posts

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.

Link to comment
Share on other sites

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.

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

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 editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Link to comment
Share on other sites

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

it is possible to add these function ...

Well, here they are:

#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.

Link to comment
Share on other sites

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

apps-odrive.pngdrive_app_badge.png box-logo.png new_logo.png MEGA_Logo.png

Link to comment
Share on other sites

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

apps-odrive.pngdrive_app_badge.png box-logo.png new_logo.png MEGA_Logo.png

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

Ok Here it is:

#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.

Link to comment
Share on other sites

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

apps-odrive.pngdrive_app_badge.png box-logo.png new_logo.png MEGA_Logo.png

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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)

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...