Zugriffsberechtigungen eines Benutzers für eine Datei



  • Mit Hilfe von AccessCheck kann man überprüfen mittls der DACL, ob bestimmte Zugriffsrechte besitzt oder nicht.

    Folgender Code (Delphi) macht dies mit Hilfe des ProzessTokens für den aktuellen Thread:

    function CheckAccessToFile(DesiredAccess: DWORD; const FileName: WideString): DWORD;
    const
      GenericFileMapping: TGenericMapping = (
        GenericRead: FILE_GENERIC_READ;
        GenericWrite: FILE_GENERIC_WRITE;
        GenericExecute: FILE_GENERIC_EXECUTE;
        GenericAll: FILE_ALL_ACCESS
        );
    var
      LastError         : DWORD;
      LengthNeeded      : DWORD;
      SecurityDescriptor: PSecurityDescriptor;
      ClientToken       : THandle;
      AccessMask        : DWORD;
      PrivilegeSet      : TPrivilegeSet;
      PrivilegeSetLength: DWORD;
      GrantedAccess     : DWORD;
      AccessStatus      : BOOL;
    begin
      Result := 0;
      LastError := GetLastError;
      if not GetFileSecurityW(PWideChar(FileName), OWNER_SECURITY_INFORMATION or GROUP_SECURITY_INFORMATION or
        DACL_SECURITY_INFORMATION, nil, 0, LengthNeeded) and (GetLastError <> ERROR_INSUFFICIENT_BUFFER) then
        Exit;
      SetLastError(LastError);
      Inc(LengthNeeded, $1000);
      SecurityDescriptor := PSecurityDescriptor(LocalAlloc(LPTR, LengthNeeded));
      if not Assigned(SecurityDescriptor) then
        Exit;
      try
        if not GetFileSecurityW(PWideChar(FileName), OWNER_SECURITY_INFORMATION or GROUP_SECURITY_INFORMATION or
          DACL_SECURITY_INFORMATION, SecurityDescriptor, LengthNeeded, LengthNeeded) then
          Exit;
        if not ImpersonateSelf(SecurityImpersonation) then
          Exit;
        try
          if not OpenThreadToken(GetCurrentThread, TOKEN_QUERY or TOKEN_IMPERSONATE or TOKEN_DUPLICATE, False, ClientToken)
            then
            Exit;
          try
            AccessMask := DesiredAccess;
            MapGenericMask(AccessMask, GenericFileMapping);
            PrivilegeSetLength := SizeOf(TPrivilegeSet);
            if AccessCheck(SecurityDescriptor, ClientToken, AccessMask, GenericFileMapping, PrivilegeSet,
              PrivilegeSetLength, GrantedAccess, AccessStatus) then
              Result := GrantedAccess;
          finally
            CloseHandle(ClientToken);
          end;
        finally
          RevertToSelf;
        end;
      finally
        LocalFree(HLOCAL(SecurityDescriptor));
      end;
    end;
    

    Aber wie kann ich das für jeden beliebigen Benutzer machen, so wie es auch Windows kann? Ich habe schon das MSDN durchwühlt und auch schon Google bemüht, aber leider nichts gefunden.


Anmelden zum Antworten