SetPermissions-UDF: Berechtigungen werden entfernt

  • Hallo alle zusammen,

    ich nutze die Set-acl-permissions-udf aus dem englischen Forum: http://www.autoitscript.com/forum/topic/13…ermissions-udf/
    Damit möchte ich die Berechtigungen für einen Ordner setzen. Bis gestern Nachmittag hat das einwandfrei geklappt. Seit dem löscht er plötzlich alle vorhanden Berechtigungen statt sie zu ergänzen.
    Wie kann ich das so einrichten, dass die neue Berechtigung hinzugefügt wird, ohne Vorhandenes zu überschreiben?
    Vielleicht habe ich irgendwo einen Leichtsinnsfehler :)

    mein Quellcode
    [autoit]


    Local $aBerechtigungen[1][3] = [['Test-Gruppe', 1, $GENERIC_ALL]] ;Erzeugt passendes Berechtigungsarray
    _SetObjectPermissions($sPath, $aBerechtigungen, $SE_FILE_OBJECT, '', 0, 1)

    [/autoit]
    Funktionsbeschreibung von _SetObjectPermissions
    [autoit]


    ; #FUNCTION# ====================================================================================================================
    ; Name...........: _SetObjectPermissions
    ; Description ...: Sets the access permissions for a given object.
    ; Syntax.........: _SetObjectPermissions($oName, $_SE_OBJECT_TYPE, $aPermissions, $SetOwner, $ClearDacl, $Recurse)
    ; Parameters ....: $oName - The handle or name of the object. This can be a path to a file or folder, a registry key, service name,
    ; +a handle to a window or process, etc. See the comments on the _SE_OBJECT_TYPE enum for more info
    ; $aPermissions - A bi-dimensional array containing info on the aces to add. The info must be on the folowing format:
    ; $array[n][0] - The user name or Sid string to add. 'Everyone', 'Administrators', and 'System' are also allowed.
    ; $array[n][1] - The access type to set. A value of 1 grants acecess, 0 denies access.
    ; $array[n][2] - The access mask. This must be one or more of the access mask constants. Use BitOR to combine.
    ; $array[n][3] - (optional) The inheritance flag for the ace. Can not have the $INHERITED_ACE or the $INHERIT_ONLY_ACE flags.
    ; $_SE_OBJECT_TYPE - The type of the object to set permissions. This must be one of the values of the
    ; +_SE_OBJECT_TYPE enum.
    ; $SetOwner - The user name to set as the owner of the object. Leaving blank '' will make no changes to the owner.
    ; $ClearDacl - Whether to clear the existing DACL. If this value is 0, the new aces will be merged to the existing
    ; +inherited aces.
    ; $Recurse - For folders or registry keys, setting this value to 1 will make the function set the same permissions to
    ; +all the sub containers and objects.
    ; $InHerit - The object's inheritance flag. Can be a combination of the inheritance contants.
    ; +The default is 3 ($SUB_CONTAINERS_AND_OBJECTS_INHERIT)
    ; Return values .: Success - 1
    ; Failure - 0 and sets @error: 1- Bad formated array of permissions; 2 - Unable to initialize the Dacl
    ; Author ........: FredAI
    ; Modified.......:
    ; Remarks .......: If using a folder or registry key handle rether than the name, the recursion will be ignored
    ; Related .......: _EditObjectPermissions, _GrantReadAccess, _GrantAllAccess, _DenyAllAccess, _GrantReadDenyWrite
    ; Link ..........:
    ; Example .......:
    ; ===============================================================================================================================
    Func _SetObjectPermissions($oName, $aPermissions, $_SE_OBJECT_TYPE = $SE_FILE_OBJECT, $SetOwner = '', $ClearDacl = 0, $Recurse = 0, $InHerit = 3)
    If $ResourcesState = 0 Then _InitiatePermissionResources()
    If Not IsArray($aPermissions) Or UBound($aPermissions,2) < 3 Then Return SetError(1,0,0)
    Local $DACL = _CreateDaclFromArray($aPermissions,$InHerit)
    Local $HasDeniedAces = @extended
    Local $SECURITY_INFORMATION = 4, $pOwner = 0
    If $SetOwner <> '' Then
    If Not IsDllStruct($SetOwner) Then $SetOwner = _GetSidStruct($SetOwner)
    $pOwner = DllStructGetPtr($SetOwner)
    If $pOwner And _IsValidSid($pOwner) Then
    $SECURITY_INFORMATION = 5
    Else
    $pOwner = 0
    EndIf
    EndIf
    If Not IsPtr($oName) And $_SE_OBJECT_TYPE = $SE_FILE_OBJECT Then
    Return _SetFileObjectSecurity($oName, $DACL, $pOwner, $ClearDacl, $Recurse, $HasDeniedAces, $SECURITY_INFORMATION)
    ElseIf Not IsPtr($oName) And $_SE_OBJECT_TYPE = $SE_REGISTRY_KEY Then
    Return _SetRegObjectSecurity($oName, $DACL, $pOwner, $ClearDacl, $Recurse, $HasDeniedAces, $SECURITY_INFORMATION)
    Else
    If $ClearDacl Then _ClearObjectDacl($oName,$_SE_OBJECT_TYPE)
    Return _SetObjectSecurity($oName, $_SE_OBJECT_TYPE, $SECURITY_INFORMATION, $pOwner, 0, $DACL,0)
    EndIf
    EndFunc ;==>_SetObjectPermissions

    [/autoit]

    Vielen Dank!

    LG

  • Das wird wohl beabsichtigtigt sein und ist eigentlich für den Befehl "SET" auch normal.
    Du setzt ja eine neue Berechtigung für das Object und fügst keine hinzu (wäre dann ADD).

    Die vererbten Rechte betrifft das nicht, weil die Rechte auf dem darüberliegenden Ordner sind und nur vom darunterliegenden Object (dieses hat nur das Flag fürs vererben) übernommen werden.

    Lösung:
    Schauen ob es ein komplementäres Kommando _GetObjectPermissions() gibt, dieses gelesenen Rechte um die gewünschten z.B. erweitern/ändern und mit _SetObjectPermissions() dann neu setzen.

    Ich kann mich irgendwie daran erinnern, das ein "vor langer" Zeit bei mir auch an der oder ähnlicher Stelle gehapert hat. Ich weis aber nicht mehr, ob es mit der gleichen Funktion/UDF war...

    Zur Nutzung dieses Forum's, ist ein Übersetzer für folgende Begriffe unerlässlich:

    "On-Bort, weier, verscheiden, schädliges, Butten steyling, näckstet, Parr, Porblem, scripe, Kompletenz, harken, manuel zu extramieren, geckukt, würglich, excell, acces oder Compilevorgeng"

  • Danke für den Hinweis.
    Es gibt in der Funktion ja einen Parameter ClearDACL. Ich dachte eigentlich, dass die Funktion nur dann den Inhalt löscht, wenn dieser Parameter aktiviert ist.
    Es gibt auch noch den Befehl _EditObjectPermissions, er sollte nach meinem Verständnis, die Berechtigungen auf jeden Fall erhalten. In der Beschreibung steht auch:

    [autoit]


    ; Remarks .......: Unlike _SetObjectPermissions, this function is able to edit the inherithed entries in the DACL, instead of adding new ones.
    ; + For instance if an object has a denied ace entry this function can edit it and make it a granted acces ace.

    [/autoit]

    Ansonsten werde ich versuchen müssen, mit diversen Funktionen das so zusammenzubasteln, wie du das beschrieben hast.

    //edit: Ich habe herausgefunden, dass ich Adminrechte benötige, sonst schlägt die Funktion fehl, die die Größe der DACL herausfinden möchte:

    Spoiler anzeigen
    [autoit]

    ; #FUNCTION# ====================================================================================================================
    ; Name...........: _GetDaclSizeInformation
    ; Description ...: Returns a Dacl size information in an array
    ; Syntax.........: GetDaclSizeInformation(ByRef $Dacl)
    ; Parameters ....: $Dacl - A pointer to a Dacl.
    ; Return values .: Success - An array containing the ace info:
    ; $aRet[0] = The number of aces in the Dacl.
    ; $aRet[1] = The number of bytes used by the dacl
    ; $aRet[2] = The number of free bytes in the dacl
    ; Failure - An empty array and sets @error: 1 - Invalid Dacl.
    ; Author ........: FredAI
    ; Modified.......:
    ; Remarks .......: The total size of the Dacl is obviously $aRet[1] + $aRet[2]
    ; Related .......: _GetAce, _MergeDaclToArray
    ; Link ..........:
    ; Example .......:
    ; ===============================================================================================================================
    Func _GetDaclSizeInformation(ByRef $Dacl)
    Local $aRet[3] = [0,0,0]
    If Not IsPtr($Dacl) Then Return SetError(1,0,$aRet)
    Local $_ACL_SIZE_INFORMATION = DllStructCreate('DWORD AceCount;DWORD AclBytesInUse;WORD AclBytesFree')

    [/autoit] [autoit][/autoit] [autoit]

    Local $aCall = DllCall($h__Advapi32Dll,'bool','GetAclInformation','ptr',$Dacl, _
    'ptr',DllStructGetPtr($_ACL_SIZE_INFORMATION),'dword',DllStructGetSize($_ACL_SIZE_INFORMATION),'dword',2)
    If @error Or $aCall[0] = 0 Then Return SetError(2,0,$aRet)
    $aRet[0] = DllStructGetData($_ACL_SIZE_INFORMATION,'AceCount')
    $aRet[1] = DllStructGetData($_ACL_SIZE_INFORMATION,'AclBytesInUse')
    $aRet[2] = DllStructGetData($_ACL_SIZE_INFORMATION,'AclBytesFree')
    Return $aRet
    EndFunc ;==> _GetDaclSizeInformation

    [/autoit]


    Weiß jemand, warum? Wie kann ich das auch ohne Adminrechte machen kann?