|
Registriert seit: 15. Nov 2003 Ort: Berlin 948 Beiträge Delphi 10.2 Tokyo Professional |
#1
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:
Zu Testzwecken besteht die Möglichkeit einzelne Dateien einzulesen und zu kopieren.
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;
Delphi-Quellcode:
Die Ermittlung der Berechtigungen erfolgt auf diese Art(habe ich mir aus den Beispielen der jwcsl zusammen 'gebastelt')
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;
Delphi-Quellcode:
Das mit dem 'mapping' habe ich nicht verstanden, da letztlich nur der 'SecurityDescriptor'
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; gebraucht wird, sollte auch dies reichen(ungetestet)
Delphi-Quellcode:
Das eigentliche auslesen der Berechtigungen erfolgt so
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;
Delphi-Quellcode:
Nachdem auswählen des Eintrages im ListView kann und soll
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; 1. Das Zielverzeichnis anlegt und die Berechtigungen hinzufügt werden
Delphi-Quellcode:
2. Kopieren der Dateien mittels CopyFile
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; Damit die einfache Zuweisung von ODACL.Add(FileEntry.AccessControlEntry); funktioniert sieht TFileEntry.SetAccessControlEntry so aus
Delphi-Quellcode:
Das Problem:
procedure TFileEntry.SetAccessControlEntry(Value : TJwSecurityAccessControlEntry);
begin if FAccessControlEntry <> Value then FAccessControlEntry := TJwDiscretionaryAccessControlEntryAllow.Create(nil, Value.Flags, Value.AccessMask, Value.SID); end; 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 |
![]() |
Ansicht |
![]() |
![]() |
![]() |
ForumregelnEs 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
|
|
Nützliche Links |
Heutige Beiträge |
Sitemap |
Suchen |
Code-Library |
Wer ist online |
Alle Foren als gelesen markieren |
Gehe zu... |
LinkBack |
![]() |
![]() |