AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi Berechtigungen einer Datei setzen (jwscl)
Thema durchsuchen
Ansicht
Themen-Optionen

Berechtigungen einer Datei setzen (jwscl)

Ein Thema von Alter Mann · begonnen am 22. Aug 2008 · letzter Beitrag vom 23. Aug 2008
Antwort Antwort
Seite 1 von 2  1 2      
Alter Mann

Registriert seit: 15. Nov 2003
Ort: Berlin
934 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#1

Berechtigungen einer Datei setzen (jwscl)

  Alt 22. Aug 2008, 17:22
Hallo

Ich habe das 'kleine' Problem nach einem 'Zwischenfall' Dateien
wiederherstellen zu müssen.

Ausgangslage:
Die Dateien und Verzeichnisse befinden sich alle in einem Verzeichnis(ca. 15600 Dateien und ca. 1500 Verzeichnisse mit weiteren Dateien von ca. 300 Usern).
Die Berechtigungen sind alle vorhanden, nur die Namen sind geändert(kein Problem).

Lösungsansatz:
Quell- und Zielverzeichnis festlegen.
Mittels FindFirst/FindNext alle Dateien und Verzeichnisse aus dem Quellverzeichnis in eine Liste eintragen
und dabei die Berechtigungen(AccessControlEntry) erfassen.
Im Zielverzeichnis entsprechend des dem User zu gewiesenen Wertes ein Verzeichnis erstellen und
die Berechtigungen zuweisen(Problem).
Dateien und Verzeichnisse in das Zielverzeichnis kopieren.

Damit man auch etwas sieht gibt es dafür eine Form und die Informationen werden in einer ListView
dargestellt.

Um das ganze praktisch zu umzusetzen, habe ich zum Zwischenspeichern
der Informationen eine Klasse erstellt:
Delphi-Quellcode:
type
  PFileEntry = ^TFileEntry;
  TFileEntry = class(TObject)
  private
    FFilePath : WideString;
    FFileName : WideString;
    FOwnerName : WideString;
    FType : WideString;
    FAttr : Integer;
    FAccessControlEntry : TJwSecurityAccessControlEntry;
    FSecurityDescriptor : TJwSecurityDescriptor;
    function GetFullFileName : WideString;
    procedure SetOwnerName(Value : WideString);
    procedure SetAccessControlEntry(Value : TJwSecurityAccessControlEntry);
    procedure SetSecurityDescriptor(Value : TJwSecurityDescriptor);
  protected
    procedure CheckFile;
  public
    constructor Create(FullFileName : WideString);
    function HasSecurityData : Boolean;
    property FullFileName : WideString read GetFullFileName;
    property FilePath : WideString read FFilePath;
    property FileName : WideString read FFileName;
    property FileTyp : WideString read FType;
    property FileAttr : Integer read FAttr;
    property OwnerName : WideString read FOwnerName write SetOwnerName;
    property AccessControlEntry : TJwSecurityAccessControlEntry read FAccessControlEntry write SetAccessControlEntry;
    property SecurityDescriptor : TJwSecurityDescriptor read FSecurityDescriptor write SetSecurityDescriptor;
  end;
Zu Testzwecken besteht die Möglichkeit einzelne Dateien einzulesen und zu kopieren.

Delphi-Quellcode:
procedure TMainForm.aSingleFileExecute(Sender: TObject);
var
  LI : TListItem;
  FEntry : TFileEntry;
begin
  OpenDlg.InitialDir := FSourceDir;
  if OpenDlg.Execute then
  begin
    FEntry := TFileEntry.Create(OpenDlg.FileName);
    lvData.Items.BeginUpdate;
    lvData.Items.Clear;
    LI := lvData.Items.Add;
    LI.Caption := FEntry.FileName;
    LI.SubItems.Add(FEntry.FileTyp);
    GetAccessRights(FEntry);
    LI.SubItems.Add(FEntry.OwnerName);
    LI.Data := FEntry;
    lvData.Items.EndUpdate;
  end;
end;
Die Ermittlung der Berechtigungen erfolgt auf diese Art(habe ich mir aus den Beispielen der jwcsl zusammen 'gebastelt')
Delphi-Quellcode:
procedure TMainForm.GetSelectedPermissions(out mapping : TJwSecurityGenericMappingClass;
                                           out bAuditAccess : Boolean;
                                           var FileEntry : TFileEntry);
var
  Flags : TJwSecurityInformationFlagSet;
  cExDesiredAccessMask : TJwAccessMask;
  FileObject : TJwSecureFileObject;
begin
  bAuditAccess := JwIsPrivilegeSet(SE_SECURITY_NAME, pqt_Available);

  cExDesiredAccessMask := 0;
  Flags := [siDaclSecurityInformation, siOwnerSecurityInformation];
  if bAuditAccess then
  begin
    Include(Flags, siSaclSecurityInformation);
    JwEnablePrivilege(SE_SECURITY_NAME,pst_Enable); //enable access to SACL generally
    cExDesiredAccessMask := ACCESS_SYSTEM_SECURITY; //add SACL access to handle
  end;
  if (FileEntry.FileAttr and faDirectory) = faDirectory then mapping := TJwSecurityFileFolderMapping
                                                        else mapping := TJwSecurityFileMapping;
  try
    FileObject := TJwSecureFileObject.Create(FileEntry.FullFileName);
    try
       FileEntry.SecurityDescriptor := FileObject.GetSecurityDescriptor(Flags);
    finally
      FreeAndNil(FileObject);
    end;
  finally
    if bAuditAccess then
      JwEnablePrivilege(SE_SECURITY_NAME, pst_Disable);
  end;
end;
Das mit dem 'mapping' habe ich nicht verstanden, da letztlich nur der 'SecurityDescriptor'
gebraucht wird, sollte auch dies reichen(ungetestet)
Delphi-Quellcode:
procedure TMainForm.GetSelectedPermissions(var FileEntry : TFileEntry);
var
   FileObject : TJwSecureFileObject;
begin
  FileObject := TJwSecureFileObject.Create(FileEntry.FullFileName);
  try
     FileEntry.SecurityDescriptor := FileObject.GetSecurityDescriptor(Flags);
  finally
     FreeAndNil(FileObject);
  end;
end;
Das eigentliche auslesen der Berechtigungen erfolgt so
Delphi-Quellcode:
procedure TMainPESForm.GetAccessRights(var FileEntry : TFileEntry);
var
  SD : TJwSecurityDescriptor;
  mapping : TJwSecurityGenericMappingClass;
  ACLEntry : TJwSecurityAccessControlEntry;
  bAuditAccess : Boolean;
  sText : String;
  I : Integer;
begin
    GetSelectedPermissions(mapping, bAuditAccess, FileEntry);

    if Assigned(FileEntry.SecurityDescriptor) then
    try
      if Assigned(FileEntry.SecurityDescriptor.Owner) then
      begin
        if Assigned(FileEntry.SecurityDescriptor.DACL) then
        begin
          for I := 0 to FileEntry.SecurityDescriptor.DACL.Count -1 do
          begin
            ACLEntry := FileEntry.SecurityDescriptor.DACL.Items[I];
            sText := ACLEntry.SID.GetText(true);
            if (POS('@', sText) = 4) then
            begin
              sText := Trim(Copy(sText, POS('@', sText) +1, POS('(', sText)-(POS('@', sText) +1)));
              if IsValue(sText) then
              begin
                FileEntry.OwnerName := sText;
                FileEntry.AccessControlEntry := ACLEntry;
                Break;
              end
              else sText := '';
            end;
          end;
        end;
      end;
    finally
      FreeAndNil(SD);
    end;
end;
Nachdem auswählen des Eintrages im ListView kann und soll
1. Das Zielverzeichnis anlegt und die Berechtigungen hinzufügt werden

Delphi-Quellcode:
procedure TMainForm.aCopyUserExecute(Sender: TObject);
begin
  if lvData.Selected = nil then Exit
  else
  begin
    if CreateFolder(FDestDir, TFileEntry(lvData.Selected.Data)) then
     CopyFile(FDestDir, TFileEntry(lvData.Selected.Data));
  end;
end;

function CreateFolder(DestPath : WideString; FileEntry : TFileEntry) : Boolean;
var
  FileObject : TJwSecureFileObject;
  Flags : TJwSecurityInformationFlagSet;
  ODACL : TJwDAccessControlList;
begin
  Result := false;
  if FileEntry.HasSecurityData then
  begin
    if not DirectoryExists(DestPath + FileEntry.OwnerName) then
    ForceDirectories(DestPath + FileEntry.OwnerName);
    FileObject := TJwSecureFileObject.Create(DestPath + FileEntry.OwnerName);
    try
      ODACL := FileObject.GetDACL;
      if ODACL <> nil then
      begin
        try
          if ODACL.IndexOf(FileEntry.AccessControlEntry) = -1 then
          begin
            ODACL.Add(FileEntry.AccessControlEntry);
            FileObject.SetDACL(ODACL);
          end;
        except
        end;
      end;
    finally
      FileObject.Free;
      FreeAndNil(ODACL);
    end;
    Result := true;
  end;
end;
2. Kopieren der Dateien mittels CopyFile

Damit die einfache Zuweisung von ODACL.Add(FileEntry.AccessControlEntry); funktioniert sieht TFileEntry.SetAccessControlEntry so aus
Delphi-Quellcode:
procedure TFileEntry.SetAccessControlEntry(Value : TJwSecurityAccessControlEntry);
begin
  if FAccessControlEntry <> Value then
    FAccessControlEntry := TJwDiscretionaryAccessControlEntryAllow.Create(nil,
                                                                Value.Flags,
                                                                Value.AccessMask,
                                                                Value.SID);
end;
Das Problem:
Die Routinen laufen alle ohne Fehler durch, nur werden die Berechtigungen des
Zielverzeichnisses nicht gesetzt.
Liegt es an der falsch verstandenen Umsetzung von TFileEntry.SetAccessControlEntry, oder
ist der Fehler in CreateFolder, oder ganz wo anders?

Für Tipps und Anregungen wie immer Dankbar

Alter Mann
  Mit Zitat antworten Zitat
Dezipaitor

Registriert seit: 14. Apr 2003
Ort: Stuttgart
1.701 Beiträge
 
Delphi 7 Professional
 
#2

Re: Berechtigungen einer Datei setzen (jwscl)

  Alt 22. Aug 2008, 19:43
Nur ein Schuss ins Blaue:
In SetAccessControlEntry kopierst du die Flags der anderen ACE. Meiner Meinung nach wird da das Flag afInheritedAce, welches definiert, dass ein ACE vererbt ist, angegeben und dann von Windows ignoriert, da es ungültig ist.


Ein Mapping ist nur notwendig, wenn du generische Rechte verwendest (GENERIC_ALL, GENERIC_READ, usw). Dann wird, wenn ein solches Recht irgendwo in den ACEs gefunden wird, in die explizite Rechte umgewandelt.
z.B. GenericRead -> STANDARD_RIGHTS_READ or READ_CONTROL or SYNCHRONIZE or FILE_READ_EA or FILE_READ_DATA or FILE_READ_EA
Christian
Windows, Tokens, Access Control List, Dateisicherheit, Desktop, Vista Elevation?
Goto: JEDI API LIB & Windows Security Code Library (JWSCL)
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#3

Re: Berechtigungen einer Datei setzen (jwscl)

  Alt 22. Aug 2008, 22:07
Hallo Alter Mann,

Zitat:
nur werden die Berechtigungen des
Zielverzeichnisses nicht gesetzt.
verstehe ich so, daß zwar ein Verzeichnis erstellt wird, aber nicht die von Dir gewünschten Berechtigungen vergeben werden, sondern "nur Standardberechtigungen". Die Berechtigungen der einzelnen Dateien stimmen hingegen.

Da ich (zu meiner Schande) nicht ganz durch Deinen Code durchsteige, erteile ich Dir den (wohl überflüssigen) Rat eine Musterberechtigung für ein Verzeichnis zu erstellen, die einmalig beim Erstellen des Verzeichnisses vergeben wird.

Gruß
K-H
  Mit Zitat antworten Zitat
Alter Mann

Registriert seit: 15. Nov 2003
Ort: Berlin
934 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#4

Re: Berechtigungen einer Datei setzen (jwscl)

  Alt 23. Aug 2008, 09:31
Hi

die Standardberechtigungen werden auf dem Root des Laufwerkes gesetzt, sodass diese auch für das Zielverzeichnis
gelten. Hinzugefügt werden soll nur die Berechtigung für den User. Die Berechtigungen für die Dateien und den weiteren
Verzeichnissen im Zielverzeichnis ergeben sich dadurch automatisch, da sie ohne weitere Berechtigungen kopiert werden.

Gruß
  Mit Zitat antworten Zitat
Dezipaitor

Registriert seit: 14. Apr 2003
Ort: Stuttgart
1.701 Beiträge
 
Delphi 7 Professional
 
#5

Re: Berechtigungen einer Datei setzen (jwscl)

  Alt 23. Aug 2008, 10:12
Wenn du einen neuen User in die ACL einfügst, dann muss dessen ACE angepasst werden. Und wenn Unterordner und -dateien diese Berechtigung auch bekommen sollen, muss einfach nur noch das Container (afContainerInheritAce) und Objekte (afObjectInheritAce) gesetzt werden, denn dann haben alle es andere.
Christian
Windows, Tokens, Access Control List, Dateisicherheit, Desktop, Vista Elevation?
Goto: JEDI API LIB & Windows Security Code Library (JWSCL)
  Mit Zitat antworten Zitat
Alter Mann

Registriert seit: 15. Nov 2003
Ort: Berlin
934 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#6

Re: Berechtigungen einer Datei setzen (jwscl)

  Alt 23. Aug 2008, 14:41
Hi

@Dezipaitor
Das ist schon klar, das Problem ist, dass die Berechtigungen des hinzugefügten Users überhaupt nicht gesetzt werden.
  Mit Zitat antworten Zitat
Dezipaitor

Registriert seit: 14. Apr 2003
Ort: Stuttgart
1.701 Beiträge
 
Delphi 7 Professional
 
#7

Re: Berechtigungen einer Datei setzen (jwscl)

  Alt 23. Aug 2008, 14:48
Wie sind denn die Flags?D.h. sind sie so wie gedacht?

Was ich gerade bemerkt habe ist, dass du SID einfach übergibst. Da Create
jedoch keine Kopie anlegt und du keinen 5 Parameter (ownSid = true) verwendest,
könnte es zu Problemem kommen (doppelt freigegebenes Objekt).
Nutze den Kopierkonstruktor:

Delphi-Quellcode:
procedure TFileEntry.SetAccessControlEntry(Value : TJwSecurityAccessControlEntry);
begin
  if FAccessControlEntry <> Value then
  begin
    FAccessControlEntry := TJwDiscretionaryAccessControlEntryAllow.Create(Value);
    FAccessControlEntry.Flags := [afObjectInheritAce, afContainerInheritAce];
    //dieses ACE ist in keiner Liste!
  end;
end;
Versuch das einfach mal.
Christian
Windows, Tokens, Access Control List, Dateisicherheit, Desktop, Vista Elevation?
Goto: JEDI API LIB & Windows Security Code Library (JWSCL)
  Mit Zitat antworten Zitat
Alter Mann

Registriert seit: 15. Nov 2003
Ort: Berlin
934 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#8

Re: Berechtigungen einer Datei setzen (jwscl)

  Alt 23. Aug 2008, 17:25
Hi,

Habe die Ausführung übernommen und folgende Meldung erhalten:

"Es gibt keine Überladene Version von 'Create', die man mit diesen Argumenten aufrufen kann."

Komisch, in der 'jwsclAcl' steht:
Delphi-Quellcode:
TJwDiscretionaryAccessControlEntry = class(TJwSecurityAccessControlEntry);
TJwDiscretionaryAccessControlEntryAllow = class(TJwDiscretionaryAccessControlEntry);
es sollte also gehen

Gruß
  Mit Zitat antworten Zitat
Dezipaitor

Registriert seit: 14. Apr 2003
Ort: Stuttgart
1.701 Beiträge
 
Delphi 7 Professional
 
#9

Re: Berechtigungen einer Datei setzen (jwscl)

  Alt 23. Aug 2008, 17:34
Ja der Parametertype muss auch TJwDiscretionaryAccessControlEntryAllow sein.
Christian
Windows, Tokens, Access Control List, Dateisicherheit, Desktop, Vista Elevation?
Goto: JEDI API LIB & Windows Security Code Library (JWSCL)
  Mit Zitat antworten Zitat
Alter Mann

Registriert seit: 15. Nov 2003
Ort: Berlin
934 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#10

Re: Berechtigungen einer Datei setzen (jwscl)

  Alt 23. Aug 2008, 18:38
Hi,

Ich habe es hin bekommen.

SetAccessControlEntry sieht jetzt so aus:
Delphi-Quellcode:
procedure TFileEntry.SetAccessControlEntry(Value : TJwSecurityAccessControlEntry);
begin
  if FAccessControlEntry <> Value then
  begin
    FAccessControlEntry := TJwDiscretionaryAccessControlEntryAllow.Create(nil,
                           [afObjectInheritAce, afContainerInheritAce],
                           Value.AccessMask,
                           Value.SID,
                           false);
  end;
end;

@Dezipaitor
Das mit den Flags hat den erwünschten Effekt gehabt. Danke!!!

Gruß
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 02: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