AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Delphi [JwSCL] Exception bei TJwSecurityDescriptorDialog.SetSecurity
Thema durchsuchen
Ansicht
Themen-Optionen

[JwSCL] Exception bei TJwSecurityDescriptorDialog.SetSecurity

Ein Thema von berens · begonnen am 19. Okt 2015 · letzter Beitrag vom 22. Okt 2015
Antwort Antwort
berens

Registriert seit: 3. Sep 2004
434 Beiträge
 
Delphi 10.4 Sydney
 
#1

[JwSCL] Exception bei TJwSecurityDescriptorDialog.SetSecurity

  Alt 19. Okt 2015, 11:41
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:
---------------------------
Benachrichtigung über Debugger-Exception
---------------------------
Im Projekt Beispiel.exe ist eine Exception der Klasse EInvalidPointer mit der Meldung 'Ungültige Zeigeroperation' aufgetreten.
---------------------------
Anhalten Fortsetzen Hilfe
---------------------------
Das Programm ist nun richtig hart abgestürzt und lässt sich auch nicht mehr fortsetzen, da nach jedem "F9" nur noch kommt:
Zitat:
---------------------------
Benachrichtigung über Debugger-Problem
---------------------------
In Projekt ...\Beispiel.exe trat ein Problem mit folgender Meldung auf: 'access violation at 0x00000000: read of address 0x00000000'. Prozess angehalten. Mit Einzelne Anweisung oder Start fortsetzen.
---------------------------
OK
---------------------------
Als Laie vermute ich nun mal, dass es sich hier um ein "Multi-Free"-Problem handelt. Nachdem der Editor mit "Ok" geschlossen werden soll, werden ja alle GUI-Einstellungen auf die Variable übertragen, und die "Erlauben" und "Verweigern"-Listen zu einer kombiniert. Hier scheint das Problem zu sein, dass die Variablen "SD" und "MergeSD" auf die selbe (nicht die gleiche!) DACL im Arbeitsspeicher zugreifen. Wird nun die SD-Variable freigegeben, wird die DACL im RAM gelöscht, und kann nicht nochmal gelöscht werden, wenn die MergeSD freigegeben wird.

Zitat:
In der JwSCL-Unit, direkt vor "SD.Free":
Wert SD:
(nil, nil, nil, True, (JwsclDescriptor.TJwSecurityDescriptor.hashCode,$5 301D4), True, True, False, False, False, True, False, False, [sdcDaclPresent,sdcDaclAutoInheritReq], $9B14FD0, $9E3CE10, True, aclpUnprotected, aclpUnprotected, 0)

Wert MergedSD
(nil, $2B2BDA0, $2B2BE60, True, (JwsclDescriptor.TJwSecurityDescriptor.hashCode,$5 301D4), True, True, False, False, False, False, False, False, [sdcDaclAutoInheritReq], $9B14FD0, $9E3D108, True, aclpUnprotected, aclpUnprotected, 0)
Hier sieht man, dass zumindest $9B14FD0 in beiden Objekten verwendet wird, was die DACL (fDACL: TJwDAccessControlList) ist. Wer jetzt hier der eigentliche Owner ist oder sein sollte, kann ich nicht sagen. Hat das seine Richtigkeit?

-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;
  Mit Zitat antworten Zitat
Dezipaitor

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

AW: [JwSCL] Exception bei TJwSecurityDescriptorDialog.SetSecurity

  Alt 19. Okt 2015, 18:15
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:
//replace DACL
  if siDaclSecurityInformation in secInfo then
  begin
    MergedSD.OwnDACL := True;
    MergedSD.DACL := SD.DACL; //simply copy DACL
  end;
zu
Delphi-Quellcode:
//replace DACL
  if siDaclSecurityInformation in secInfo then
  begin
    MergedSD.OwnDACL := false;
    MergedSD.DACL := SD.DACL; //simply copy DACL
    MergedSD.OwnDACL := true;
  end;
Das sollte dir helfen.
Christian
Windows, Tokens, Access Control List, Dateisicherheit, Desktop, Vista Elevation?
Goto: JEDI API LIB & Windows Security Code Library (JWSCL)

Geändert von Dezipaitor (19. Okt 2015 um 18:47 Uhr) Grund: völliger Quatsch. das ist richtig so
  Mit Zitat antworten Zitat
berens

Registriert seit: 3. Sep 2004
434 Beiträge
 
Delphi 10.4 Sydney
 
#3

AW: [JwSCL] Exception bei TJwSecurityDescriptorDialog.SetSecurity

  Alt 19. Okt 2015, 21:15
Das scheint geklappt zu haben, Thema gelöst

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!
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#4

AW: [JwSCL] Exception bei TJwSecurityDescriptorDialog.SetSecurity

  Alt 19. Okt 2015, 21:24
Zitat:
ist wohl leider ein Bug in JWSCL.
Dann sind wohl diese Abfragen ebenfalls falsch.
Wären dann also 3 Fehler nicht nur einer.

Delphi-Quellcode:
   //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;
gruss
  Mit Zitat antworten Zitat
berens

Registriert seit: 3. Sep 2004
434 Beiträge
 
Delphi 10.4 Sydney
 
#5

AW: [JwSCL] Exception bei TJwSecurityDescriptorDialog.SetSecurity

  Alt 19. Okt 2015, 21:26
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?
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#6

AW: [JwSCL] Exception bei TJwSecurityDescriptorDialog.SetSecurity

  Alt 19. Okt 2015, 21:34
Zitat:
aber rein von der Optik hast du wohl recht?
Jo..
Ich würde es aber eher so lösen ohne im Quelltext geschaut zu haben.

Delphi-Quellcode:
if Assigned(SD.DACL) then
begin
  MergedSD.OwnDACL := True;
  MergedSD.DACL := SD.DACL;
end;
Wenn SD.DACL beim Initialisieren FALSE ist.

gruss
  Mit Zitat antworten Zitat
berens

Registriert seit: 3. Sep 2004
434 Beiträge
 
Delphi 10.4 Sydney
 
#7

AW: [JwSCL] Exception bei TJwSecurityDescriptorDialog.SetSecurity

  Alt 19. Okt 2015, 21:57
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...
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#8

AW: [JwSCL] Exception bei TJwSecurityDescriptorDialog.SetSecurity

  Alt 19. Okt 2015, 22:22
Zitat:
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...
Wie gesagt habe den Quelltext der Klasse nicht angeschaut.
Daher war es nur die nächstliegende Vermutung.

gruss
  Mit Zitat antworten Zitat
berens

Registriert seit: 3. Sep 2004
434 Beiträge
 
Delphi 10.4 Sydney
 
#9

AW: [JwSCL] Exception bei TJwSecurityDescriptorDialog.SetSecurity

  Alt 19. Okt 2015, 22:27
Alle Beiträge herzlich willkommen, ich kann ja nicht erwarten dass jeder gerade 100% in meiner Thematik drinnen ist

Danke für die Beteiligung.
  Mit Zitat antworten Zitat
Dezipaitor

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

AW: [JwSCL] Exception bei TJwSecurityDescriptorDialog.SetSecurity

  Alt 22. Okt 2015, 20:28
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.
Christian
Windows, Tokens, Access Control List, Dateisicherheit, Desktop, Vista Elevation?
Goto: JEDI API LIB & Windows Security Code Library (JWSCL)

Geändert von Dezipaitor (22. Okt 2015 um 20:32 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort


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 00: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