Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Zurgiffsrechte bestimmen bzw. testen (https://www.delphipraxis.net/122461-zurgiffsrechte-bestimmen-bzw-testen.html)

LokutusvB 16. Okt 2008 14:48


Zurgiffsrechte bestimmen bzw. testen
 
Hallo Leute,

wenn man nach Zugriffsrechten für Ordner bzw. Verzeichnisse googelt, bekommt man fast nur ellenlange Funktionen als Ergebnis geliefert. TSearchRec, FindFirst und co. durchsucht ja nur Ordnerstrukturen ja nach dem, wie ich es definiere. Oder gibt es hier schon eine Möglichkeit, wie ich die Rechte mit Hilfe von FindNext/FindFirst auslesen kann?

Was ist denn die kürzeste und schnellste Möglichkeit zu testen, ob ein Nutzer Zugriff auf einen Ordner hat (Lese- und /oder Schreibzugriff ist dabei egal)?

Ist es schneller, wenn ich versuche, etwas in den Ordner zu kopieren und wieder zu löschen oder gibt es hierfür eine kleine schnelle Funktion?

Luckie 16. Okt 2008 15:10

Re: Zurgiffsrechte bestimmen bzw. testen
 
Du könntest die Zugriffsrechte auslesen: http://www.michael-puff.de/Programmi...ileAccess.html

Oder eben versuchen eine Datei dort zu erstellen und den fehlercode dann auswerten. Wobei das auslesen der Zugriffsrechte eleganter ist.

LokutusvB 16. Okt 2008 15:26

Re: Zurgiffsrechte bestimmen bzw. testen
 
Danke für den Link. :)
So etwas ähnliches habe ich auch schon bei meiner Suche in einem Beitrag gefunden, wo es darum ging, Zugriffsrechte zu ändern. Eventuell kann ich das ganze ja noch ein wenig kürzen.

Luckie 17. Okt 2008 08:14

Re: Zurgiffsrechte bestimmen bzw. testen
 
Zitat:

Zitat von LokutusvB
Eventuell kann ich das ganze ja noch ein wenig kürzen.

Das glaube ich kaum. Oder warum denkst du, dass Nico dort unnötigen Code rein geschrieben haben sollte? Und warum willst du ihn überhaupt kürzer haben? Was macht das für einen Unterschied, ob du nun 10 oder 50 Zeilen Code kopierst und aufrufst?

Dezipaitor 17. Okt 2008 09:56

Re: Zurgiffsrechte bestimmen bzw. testen
 
So kürzen? :)

http://blog.delphi-jedi.net/2007/10/21/why-jwscl/
Delphi-Quellcode:
function CheckAccessToFile(
  DesiredAccess: DWORD; const FileName: WideString): Boolean;
var FileObject : TJwSecureFileObject;
begin
  FileObject := TJwSecureFileObject.Create(FileName);
  try
    result := FileObject.AccessCheck(DesiredAccess);
  finally
    FileObject.Free;
  end;
end;
Das Erstellen einer Datei hat Unterschiede zum Auslesen der Zugriffsrechte:
1. Das Erstellen der Datei kann eine Überwachungslog (Audit) generieren. AccessCheck selbst macht das nicht. Es gibt extra AccessCheck Funktionen dafür.
2. Eine lokale Überprüfen der Zugriffsrechte auf einem entfernten System kann ein unterschiedliches Ergebnis ergeben, weil der Zugriff nur auf dem entfernten Rechner geschieht.

Dezipaitor 17. Okt 2008 10:08

Re: Zurgiffsrechte bestimmen bzw. testen
 
@Luckie: Kennst du Gründe warum ImpersonateSelf verwendet wurde, abseits meinem Grund, dass der Code threadsicher(er) ist?

LokutusvB 17. Okt 2008 10:25

Re: Zurgiffsrechte bestimmen bzw. testen
 
An Luckie:
Die Idee des Kürzens hatte ich, bevor ich den Quelltext genauer gelesen hatte. Es hätte ja gut sein können, das zusätzliche Informationen ausgelesen werde, die ich nicht benötige. Denn was bei meinem Programm zählt, ist die Zeit, da das ganze über das Netzwerk bzw. Internet läuft und so schon genug gebremst wird.

An Dezipaitor:
Ein sehr interessanter Link. das werde ich zumindest noch ausprobieren. CheckAccessToFile funktioniert so weit sehr gut :), ohne einen spürbaren zusätzlichen Zeitfaktor beim Durchsuchen der Laufwerke und Ordner.

Danke für die Hilfe :)

Dezipaitor 17. Okt 2008 11:42

Re: Zurgiffsrechte bestimmen bzw. testen
 
Der obige OOP Code wird durch ständiges Erstellen und Zerstören von Objekten und einigen internen Überprüfungen (zur Sicherheit), sowie der aufruf von virtuellen Methoden (ist langsamer) natürlich langsamer ausgeführt als der reine WinAPI Code. JWSCL enthält aber auch Klassenmethoden, die es erlauben schnell die Sicherheitsdaten einer Datei zu lesen und mit AccessCheck (auch eine Methode) zu überprüfen. Da wird dann eben kein Objekt für jede Datei erstellt. Einige interne Sachen sind dann doch noch dabei. Die Klasse ist TJwSecureGeneralObject

Luckie 17. Okt 2008 11:50

Re: Zurgiffsrechte bestimmen bzw. testen
 
Zitat:

Zitat von Dezipaitor
@Luckie: Kennst du Gründe warum ImpersonateSelf verwendet wurde, abseits meinem Grund, dass der Code threadsicher(er) ist?

Da müsstest du dich mal an Nico persönlich wenden. Der Code ist von ihm (Steht ja auch drunter).

nicodex 17. Okt 2008 11:58

Re: Zurgiffsrechte bestimmen bzw. testen
 
Zitat:

Zitat von Dezipaitor
Kennst du Gründe warum ImpersonateSelf verwendet wurde, [...]

Es handelt sich in erster Linie um eine Vereinfachung (damit man nur noch OpenThreadToken braucht), um an das Token zu gelangen (sonst müsste man erstmal prüfen ob der Thread ein eigenes Token hat und alternativ das Token des Prozesses verwenden.

Wenn ich mich recht erinnere, dann handelt es sich um die (Re-)Implementierung einer API, die nicht in allen Versionen von Windows NT zur Verfügung steht...

Dezipaitor 17. Okt 2008 14:29

Re: Zurgiffsrechte bestimmen bzw. testen
 
Naja, der Code ist für normale Zwecke gut geeignet.
Der Vorteil eines Threadtokens besteht darin, dass man unabhängig von den Privilegien des Prozesstokens arbeiten kann. So kann kein anderer Thread Privilegien ändern, so dass im aktuellen Thread eine Ausführung deshalb scheitert.

Das Problem, dass ich jedoch hier sehe, ist dass jemand "Unerfahrener", diesen Code in einem Service einsetzt, der vorher einen Benutzer personifiziert. D.h. also, dass der Code im Service mit ImpersonateSelf das gesetze Threadtoken durch das SYSTEM Token ersetzt und so andere Zugänge schafft.

Ich weiß, dass es sich um ein Beispiel handelt. Aber ich weiß auch, dass (auf den ersten Blick) funktionierende Beispiele immer gern 1:1 übernommen werden ohne weiter darüber nachzudenken.

nicodex 17. Okt 2008 16:48

Re: Zurgiffsrechte bestimmen bzw. testen
 
Zitat:

Zitat von Dezipaitor
Das Problem, dass ich jedoch hier sehe, ist dass jemand "Unerfahrener", diesen Code in einem Service einsetzt, [...]

Ich gehe einfach davon aus, dass Entwickler, die einen Systemdienst schreiben, wissen was sie tun ;)
Zudem gibt es genug Beispiele dafür, wie man auf Serverseite als Client "handelt".
http://msdn.microsoft.com/en-us/libr...48(VS.85).aspx

Dezipaitor 17. Okt 2008 17:13

Re: Zurgiffsrechte bestimmen bzw. testen
 
Mir ist grad eingefallen, dass das ClientToken vom Typ "impersonate/thread token" sein muss. Sonst schlägt AccessCheck fehl (1309). D.h. man müsste das Prozesstoken erstmal duplizieren (impersonate) und dann an AccessCheck übergeben. ImpersonateSelf macht aber genau das und zudem verändert es das ThreadToken. D.h. nach dem AccessCheck müsste man es wieder zurücksetzen, sonst fährt man z.B. mit SYSTEM. D.h. ein Zurücksetzen sollte nur gemacht werden, wenn vorher kein Threadtoken existierte.

Dezipaitor 19. Okt 2008 17:01

Re: Zurgiffsrechte bestimmen bzw. testen
 
Ich habe das mal angepasst, so dass man durch setzen des Threadtokens ein AccessCheck machen kann.

Delphi-Quellcode:
uses
  JwaWindows;

var
  GenericFileMapping    : TGenericMapping = (
    GenericRead: FILE_GENERIC_READ;
    GenericWrite: FILE_GENERIC_WRITE;
    GenericExecute: FILE_GENERIC_EXECUTE;
    GenericAll: FILE_ALL_ACCESS
    );

function CheckAccessToFile(DesiredAccess: DWORD; const FileName: WideString;
    const OpenAsSelf : Boolean = true): Boolean;

var
  LengthNeeded          : DWORD;
  SecurityDescriptor    : PSecurityDescriptor;
  ClientToken2,
  ClientToken           : THandle;
  AccessMask            : DWORD;
  PrivilegeSet          : TPrivilegeSet;
  PrivilegeSetLength    : DWORD;
  GrantedAccess         : DWORD;
  AccessStatus          : BOOL;
begin
  Result := False;
  SetLastError(0);

  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;

  GetMem(SecurityDescriptor, LengthNeeded);
  try
    if not GetFileSecurityW(PWideChar(FileName), OWNER_SECURITY_INFORMATION or
      GROUP_SECURITY_INFORMATION or DACL_SECURITY_INFORMATION,
      SecurityDescriptor, LengthNeeded, LengthNeeded) then
      Exit;

    //first try token assigned to the current thread
    if not OpenThreadToken(GetCurrentThread, TOKEN_QUERY or
        TOKEN_IMPERSONATE or TOKEN_DUPLICATE, OpenAsSelf, ClientToken) then
    begin
      //otherwise use process token
      if (GetLastError() = ERROR_NO_TOKEN) and
         (not OpenProcessToken(GetCurrentProcess, TOKEN_QUERY or
        TOKEN_IMPERSONATE or TOKEN_DUPLICATE, ClientToken)) then
        Exit;

      //convert to thread token.
      if not DuplicateToken(ClientToken, SecurityImpersonation, @ClientToken2) then
        exit;

      //close process token and switch them for further processing
      CloseHandle(ClientToken);

      ClientToken := ClientToken2;
    end;

    AccessMask := DesiredAccess;
    MapGenericMask(AccessMask, GenericFileMapping);
    PrivilegeSetLength := SizeOf(TPrivilegeSet);

    if AccessCheck(SecurityDescriptor, ClientToken, AccessMask,
      GenericFileMapping, PrivilegeSet, PrivilegeSetLength, GrantedAccess,
      AccessStatus) then
      Result := AccessStatus;

    CloseHandle(ClientToken);
  finally
    FreeMem(SecurityDescriptor);
  end;
end;

MaBuSE 15. Nov 2010 13:37

AW: Re: Zurgiffsrechte bestimmen bzw. testen
 
Zitat:

Zitat von Dezipaitor (Beitrag 837437)
Delphi-Quellcode:
function CheckAccessToFile(DesiredAccess: DWORD; const FileName: WideString;
    const OpenAsSelf : Boolean = true): Boolean;

Hallo, ich habe mal eine Frage zu dem Quelltext.

Welche Funktion genau hat OpenAsSelf.

Aus der Beschreibung im MSDN werde ich nicht ganz schlau:

True - Rechte vom Prozess werden ausgelesen
False - Rechte vom Thread werden ausgelesen

Aber mit der Beschreibung darunter kann ich nichts anfangen.
Ohne diesen Parameter (also Parameter = False -> Rechte vom Thread) kann er nicht auf das access Token des Theads zugreifen ???
Bahnhof :stupid:

Zitat:

OpenAsSelf [in]
TRUE if the access check is to be made against the process-level security context.

FALSE if the access check is to be made against the current security context of the thread calling the OpenThreadToken function.

The OpenAsSelf parameter allows the caller of this function to open the access token of a specified thread when the caller is impersonating a token at SecurityIdentification level. Without this parameter, the calling thread cannot open the access token on the specified thread because it is impossible to open executive-level objects by using the SecurityIdentification impersonation level.


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:15 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz