![]() |
[JwSCL] Exception bei TJwSecurityDescriptorDialog.SetSecurity
Hallo zusammen,
obwohl ja die JwSCL insgesamt einfach bedienbar ist -wenn man mal den Einstieg geschafft hat- bin ich hier an der Stelle ein wenig festgefahren und weiß nicht, ob es an mangelndem Wissen scheitert, oder ein Fehler in der JwSCL Unit an sich vorhanden ist. Folgender Sachverhalt: Wenn ich mit dem ACL-Editor einen neuen SecurityDescriptor bearbeite, habe ich kein Problem. Wenn ich mit dem ACL-Editor einen SecurityDescriptor ("SD") bearbeite, der geladen wurde (also ein neuer SD, der als Parameter einen Plain-Text-Wert übergeben bekommt) kommt eine Exception, sobald ich den ACL-Editor mit "Ok" beende. Dazu muss man wissen: -Der "geladene" SD ist generell gültig; man kann damit arbeiten und im ACL-Editor werden die geladenen Benutzer & Rechte auch korrekt angezeigt; daran sollte es also nicht liegen. -Im folgenden Beispiel wird der SD mit dem Text "" geladen (also leerer Text, für dieses Beispiel hier). Dies ist meines Wissens ebenfalls gültig und sollte somit nicht die Ursache für das Problem sein. -In der angehängten Funktion "TJwSecurityDescriptorDialog.SetSecurity" gibt es an der Stelle "MergeSD.Free" die Exception Zitat:
Zitat:
Zitat:
-Wenn ich übrigens bei "SD.Free; MergedSD.Free;" try..except drum mache, kann ich das Programm zumindest fortsetzen. -Der ACLEditor schaltet mit dem bearbeiten bei dem SD immer die Variablen "OwnOwner" und "OwnPrimaryGroup" selbständig auf True. Ich kann nicht einschätzen in wie weit das mit dem Problem zusammenhängt, und was man dagegen tun kann/soll. Die Variablen werden ja auch mit dem "neu erzeugtem" SD auf True gesetzt, und dort gibt es das Problem nicht. -Ist das schlimm, wenn ich als behelf einfach die try..except Lösung verwende? Klar, das ist keine saubere Lösung, aber bevor mein Programm gar nicht geht und ich hier nicht weiterkomme ...?
Code:
"Neuer" SD, keine Probleme:
SD-Variable vor dem ACL Editor: (nil, $2A3ABA0, $2A3ABA0, False, (JwsclDescriptor.TJwSecurityDescriptor.hashCode,$5301D4), False, False, False, False, False, False, False, False, [], $2A8AD60, $9B98B70, True, aclpUnprotected, aclpUnprotected, 0) SD-Variable nach dem ACL-Editor: (nil, $2A3C3A0, $2A3E410, False, (JwsclDescriptor.TJwSecurityDescriptor.hashCode,$5301D4), True, True, False, False, False, False, False, False, [], $2A8AD60, $9B98B70, True, aclpUnprotected, aclpUnprotected, 0) "Geladener" SD, Problem: SD-Variable vor dem ACL Editor: (nil, $27ABB30, $27ABB90, False, (JwsclDescriptor.TJwSecurityDescriptor.hashCode,$5301D4), False, False, False, False, False, False, False, False, [], nil, $9918B70, True, aclpUnprotected, aclpUnprotected, 0) SD-Variable nach dem ACL-Editor: (nil, $27AAE70, $27AC400, False, (JwsclDescriptor.TJwSecurityDescriptor.hashCode,$5301D4), True, True, False, False, False, False, False, False, [], $99A6698, $9918B70, True, aclpUnprotected, aclpUnprotected, 0)
Delphi-Quellcode:
procedure TfrmZugriffsrechte.Button1Click(Sender: TObject);
var sd: TjwSecurityDescriptor; ACLEditor : TJwSecurityDescriptorDialog; begin // Funktioniert ohne Probleme sd := TjwSecurityDescriptor.Create; // Problem mit ACLEditor sd := TjwSecurityDescriptor.Create(''); with sd do begin PrimaryGroup := JwNullSID; Owner := JwNullSID; OwnDACL := False; OwnOwner := False; OwnPrimaryGroup := False; DACLInherited := False; AuditInherited := False; Control := []; end; // Editor erzeugen ACLEditor := TJwSecurityDescriptorDialog.Create(GetActiveWindow); // Zum testen in dieser Demo erstmal Alles freischalten (Erweitert-Button, alle Karteikarten, etc.) ACLEditor.Flags := [sdfEditOwner]; // sdfAdvanced, sdfEditDacl, sdfEditEffective, sdfNoAdditionalPermission, sdfEditSacl // Caption des Dialogs, bzw. der "Objektes", für das gerade die Sicherheit verändert wird. Nehmt zur Not euren Programmnamen oder so... ACLEditor.ObjectName := Caption; ACLEditor.ServerName := ''; try try ACLEditor.Mapping := TMyMapping; ACLEditor.SecurityDescriptor.Assign(sd); ACLEditor.OnSetSecurity := OnSetSecurity; // Editor anzeigen. Das Programm pausiert, bis der Dialog geschlossen wird. // Wenn der Dialog mit "Ok" beendet wurde: if ACLEditor.ShowModal then begin Sleep(0); // wenn wir hier ankommen, alles Ok! // Den kompletten SD wieder in unsere Variable zurückkopieren sd.Assign(ACLEditor.SecurityDescriptor); end; except sleep(0); // Keine Chance, das Problem hierüber zu behandeln! end; finally try ACLEditor.Free; except sleep(0); // Keine Chance, das Problem hierüber zu behandeln! end; end; end; procedure TfrmZugriffsrechte.OnSetSecurity(Sender: TJwSecurityDescriptorDialog; SecurityType: TJwSecurityInformationFlagSet; SecurityDialogFlags: TJwSecurityDialogFlags; SecurityResetType: TJwSecurityResetTypes; Settings: TJwSecurityDescriptorControlSet; NewSecurityDescriptor, MergedSecurityDescriptor: TJwSecurityDescriptor; var bSuccess: boolean); begin bSuccess := true; end;
Delphi-Quellcode:
function TJwSecurityDescriptorDialog.SetSecurity(
SecurityInformation: SECURITY_INFORMATION; pSecurityDescriptor: PSECURITY_DESCRIPTOR): HRESULT; var secInfo: TJwSecurityInformationFlagSet; secControl: TJwSecurityDescriptorControlSet; MergedSD, SD: TJwSecurityDescriptor; SecurityResetTypes: TJwSecurityResetTypes; secInfoEx: TJwSecurityDialogFlags; bSuccess: boolean; begin secInfo := TJwEnumMap.ConvertSecurityInformation( SecurityInformation); secControl := TJwEnumMap.ConvertSecurityControl( pSecurityDescriptor.Control); secInfoEx := TJwEnumMap.ConvertFlags(SecurityInformation); //create new SD that contains the changed security information SD := TJwSecurityDescriptor.Create(pSecurityDescriptor); //create new SD that contains the default SD and will receive the new one MergedSD := TJwSecurityDescriptor.Create(fSD); //replace Owner if siOwnerSecurityInformation in secInfo then begin MergedSD.OwnOwner := True; MergedSD.Owner := SD.Owner; //simply copy owner end; //replace group if siGroupSecurityInformation in secInfo then begin MergedSD.OwnPrimaryGroup := True; MergedSD.PrimaryGroup := SD.PrimaryGroup; //simply copy group end; //replace DACL if siDaclSecurityInformation in secInfo then begin MergedSD.OwnDACL := True; MergedSD.DACL := SD.DACL; //simply copy DACL end; //replace SACL if siSaclSecurityInformation in secInfo then begin MergedSD.SACL := SD.SACL; //simply copy SACL end; if siDaclSecurityInformation in secInfo then begin //protect DACL from inheritance if sdcDaclProtected in SD.Control then begin Include(secInfo, siProtectedDaclSecurityInformation); MergedSD.Control := MergedSD.Control + [sdcDaclProtected]; end; //unprotect DACL so inheritance can flow if sdcDaclAutoInheritReq in SD.Control then begin Include(secInfo, siUnprotectedDaclSecurityInformation); MergedSD.Control := MergedSD.Control + [sdcDaclAutoInheritReq]; end; end; if siSaclSecurityInformation in secInfo then begin //protect SACL from inheritance if sdcSaclProtected in SD.Control then begin Include(secInfo, siProtectedSaclSecurityInformation); MergedSD.Control := MergedSD.Control + [sdcSaclProtected]; end; //unprotect SACL so inheritance can flow if sdcSaclAutoInheritReq in SD.Control then begin Include(secInfo, siUnprotectedSaclSecurityInformation); MergedSD.Control := MergedSD.Control + [sdcSaclAutoInheritReq]; end; end; //set reset state, so user can easily see whether he must reset all children SecurityResetTypes := []; if (SecurityInformation and SI_OWNER_RECURSE = SI_OWNER_RECURSE) then Include(SecurityResetTypes, srtOwner); if (SecurityInformation and SI_RESET_DACL_TREE = SI_RESET_DACL_TREE) then Include(SecurityResetTypes, srtDacl); if (SecurityInformation and SI_RESET_SACL_TREE = SI_RESET_SACL_TREE) then Include(SecurityResetTypes, srtSacl); bSuccess := False; try if Assigned(fOnSetSecurity) then fOnSetSecurity(Self, secInfo, secInfoEx, SecurityResetTypes, SD.Control, SD, MergedSD, bSuccess); if bSuccess then fSD.Assign(MergedSD); finally // try SD.Free; MergedSD.Free; // <-- hier gibt es die eigentliche Exception // except end; end; if bSuccess then Result := S_OK else Result := S_FALSE; end; |
AW: [JwSCL] Exception bei TJwSecurityDescriptorDialog.SetSecurity
Hi,
ist wohl leider ein Bug in JWSCL. Ohne es ausprobiert zu haben, der Lösung könnte folgende sein: Ändere mal den folgenden Code : in JwsclSecurityDialogs.pas
Delphi-Quellcode:
zu
//replace DACL
if siDaclSecurityInformation in secInfo then begin MergedSD.OwnDACL := True; MergedSD.DACL := SD.DACL; //simply copy DACL end;
Delphi-Quellcode:
Das sollte dir helfen.
//replace DACL
if siDaclSecurityInformation in secInfo then begin MergedSD.OwnDACL := false; MergedSD.DACL := SD.DACL; //simply copy DACL MergedSD.OwnDACL := true; end; |
AW: [JwSCL] Exception bei TJwSecurityDescriptorDialog.SetSecurity
Das scheint geklappt zu haben, Thema gelöst :thumb:
Die DACL hat nun zum Zeitpunkt des .Free-Vorgangs bei SD und MergedSD eine andere Pointer-Adresse, somit verwenden beide ein anderes Objekt und es gibt keine Exception mehr. Vielen Dank! |
AW: [JwSCL] Exception bei TJwSecurityDescriptorDialog.SetSecurity
Zitat:
Wären dann also 3 Fehler nicht nur einer.
Delphi-Quellcode:
gruss
//replace Owner
if siOwnerSecurityInformation in secInfo then begin MergedSD.OwnOwner := True; MergedSD.Owner := SD.Owner; //simply copy owner end; //replace group if siGroupSecurityInformation in secInfo then begin MergedSD.OwnPrimaryGroup := True; MergedSD.PrimaryGroup := SD.PrimaryGroup; //simply copy group end; //replace DACL if siDaclSecurityInformation in secInfo then begin MergedSD.OwnDACL := True; MergedSD.DACL := SD.DACL; //simply copy DACL end; |
AW: [JwSCL] Exception bei TJwSecurityDescriptorDialog.SetSecurity
Ich hab mich jetzt im detail noch nicht mit den "Own..." Eigenschaften auseinandergesetzt, aber rein von der Optik hast du wohl recht?
Die andere Frage wäre, ob man nicht den "Status-quo" zwischenspeichern und nach wieder setzt, statt diese Eigenschaften auf "True" zu erzwingen? |
AW: [JwSCL] Exception bei TJwSecurityDescriptorDialog.SetSecurity
Zitat:
Ich würde es aber eher so lösen ohne im Quelltext geschaut zu haben.
Delphi-Quellcode:
Wenn SD.DACL beim Initialisieren FALSE ist.
if Assigned(SD.DACL) then
begin MergedSD.OwnDACL := True; MergedSD.DACL := SD.DACL; end; gruss |
AW: [JwSCL] Exception bei TJwSecurityDescriptorDialog.SetSecurity
Soweit ich dich verstanden habe, ist das definitiv falsch.
Das Problem beim Beenden des Dialogs ist ja, dass die DACL Variable/Pointer von SD und MergedSD beide auf das selbe Objekt im Ram verweisen, was ja mit Christians Lösung nun nicht mehr passiert. (Beim Freigeben wird sonst das Objekt im Ram 2x gelöscht, das gibt Probleme). Mit deinem Quelltext tritt das Problem zwar "nur dann" auf, wenn DACL <> NIL ist (was zwar nicht immer, aber meistenst und auch speziell in dieser Prozedur der Fall ist!), aber es bietet keine Lösung dafür? Wenn dann könnte man sagen MergedSD.DACL.Assign(SD.DACL) (falls das mit DACL geht), dann wäre einfach nur rüberkopiert und alles wäre gut... |
AW: [JwSCL] Exception bei TJwSecurityDescriptorDialog.SetSecurity
Zitat:
Daher war es nur die nächstliegende Vermutung. gruss |
AW: [JwSCL] Exception bei TJwSecurityDescriptorDialog.SetSecurity
Alle Beiträge herzlich willkommen, ich kann ja nicht erwarten dass jeder gerade 100% in meiner Thematik drinnen ist :wink:
Danke für die Beteiligung. |
AW: [JwSCL] Exception bei TJwSecurityDescriptorDialog.SetSecurity
Ich gebs zu, dass ist ganz offensichtlich ein Designfehler.
* Bei Owner und OwnOwner = true wird eine Kopie bei Zuweisung von Owner im Objekt angelegt, die dann auch wieder gelöscht wird, wenn OwnOwner = true ist. * Wenn also OwnOwner = false ist und ein Owner zugewiesen wird, dann wird einfach intern das zugewiesene Objekt verwendet und am Ende auch nicht gelöscht. * Bei DACL und OwnDACL = true sowie einer Zuweisung von DACL ist es hingegen so, dass direkt die Variable intern verwendet wird und sogar am Ende freigegeben wird --> völliger Blödsinn von mir! * Wenn eine DACL zugewiesen wird und zuerst OwnDACL = false und nach der Zuweisung auf true gesetzt wird, dann wird eine Kopie erzeugt, die am Ende freigegeben wird. Das ist leider uneinheitlich und ziemlich verwirrend. ALLERDINGS: steht es in der Doku (im Codekommentar von Owner und DACL) genauso beschrieben! Änderungen sind allerdings so tief ausgeschlossen. Es ist offiziell und Änderungen brechen Code, der dies nach Doku verwendet. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:25 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz