AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi Prüfung effektiver Berechtigungen eines "Extended Right" auf AD-Objekte?
Thema durchsuchen
Ansicht
Themen-Optionen

Prüfung effektiver Berechtigungen eines "Extended Right" auf AD-Objekte?

Offene Frage von "Dezipaitor"
Ein Thema von ogiesen · begonnen am 22. Dez 2011 · letzter Beitrag vom 15. Jan 2012
Antwort Antwort
Benutzerbild von ogiesen
ogiesen

Registriert seit: 25. Okt 2004
Ort: Delmenhorst
43 Beiträge
 
Delphi XE3 Enterprise
 
#1

Prüfung effektiver Berechtigungen eines "Extended Right" auf AD-Objekte?

  Alt 22. Dez 2011, 16:54
N'Abend!

Ich bräuchte da mal etwas Hilfe... (Disclaimer: Das ist mein allererster Ausflug ins Thema Security)
Die Aufgabenstellung ist, zu prüfen, ob der aktuelle Benutzer (d.h. der, der mein Programm, bzw. meine DLL, ausführt) ein bestimmtes "Extended Right" im Active Directory hat. Dabei ist vor allem auch wichtig, dass indirekt erteilte (oder verweigerte) Berechtigungen über Gruppenmitgliedschaften ebenfalls ausgewertet werden, mit anderen Worten, es geht um die "effektiven Berechtigungen".

Ich habe mittlerweile bereits zwei Fragen zum Thema auf StackOverflow gestellt:Auch wenn ich in den Antworten und Kommentaren bereits einige nützliche Hinweise bekommen habe, bin ich (gefühlt) immer noch meilenweit entfernt vom Erreichen meines Ziels. Also dachte ich, ich frag' mal jemanden, der sich damit auskennt (ich weiß, Schande über mich, dass ich nicht zuerst hier gefragt habe)...

Leider bin ich noch nicht wirklich an einem Punkt, wo ich die Grundlagen gut genug verstehe, um einfach kurze und knackige Fragen zu stellen, deswegen hier ein Überblick über das, was ich bisher schon erreicht bzw. ausprobiert habe:
  • Ich kann, mit Hilfe von ADsGetObject und IADs.Get den IADsSecurityDescriptor meines Zielobjektes, sowie die darin enthaltene DACL, auslesen - damit kann ich direkt zugewiesene Extended Rights bereits zuverlässig prüfen - es fehlt aber die Auswertung der Gruppenmitgliedschaften (das könnte ich natürlich auch zu Fuß machen, aber ich bin mir ziemlich sicher, dass es dafür bereits eine fertige Lösung geben muss)
  • Ich habe angefangen, das MSDN-Beispiel zur API AccessCheckByTypeResultList nach Delphi zu übertragen, tue mich dabei aber noch sehr schwer:
    • Wo bekomme ich den ClientToken her, den ich da übergeben muss?
    • Wie übersetze ich die Geschichte mit dem PrivilegeSetBuffer? - Sieht für mich aus, wie das, was man bei Delphi mit dem absolute-Schlüsselwort machen könnte, aber ich bekomm's nicht ans Laufen
    • Was soll die ganze Geschichte mit dem MakeAbsoluteSD und was genau müsste an die Stelle von den ganzen TODOs in dem Abschnitt? Wenn ich das richtig interpretiere, hat das Beispiel an der Stelle auch einen Fehler: der aufwändig generierte pAbsoluteSD wird überhaupt nicht benutzt!
    • Viele der Objekte, die ich prüfen will (z.B. mailaktivierte Öffentliche Ordner) haben kein objectSID-Attribut, das ich als PrincipalSelfSid übergeben könnte. Ist das in dem Fall verzichtbar? Ist so ein Objekt einfach kein "Principal" und braucht hier keine Wert oder bedeutet das, dass ich die AccessCheck*-Routinen nicht für diese Objekte benutzen kann?
    • Brauche ich für meinen Anwendungsfall wirklich AccessCheckByTypeResultList? Würde AccessCheckByType nicht auch ausreichen?
    • Egal, welche AccessCheck*-Variante ich verwende, und egal, wie ich die Parameter aufbereite, der Aufruf schlägt immer fehl und GetLastError gibt mir 87 - "The parameter is incorrect" zurück - leider keinen Hinweis darauf, auf welchen der unzähligen Parameter sich das beziehen könnte...
  • Bei meinen Recherchen zur Übersetzung des o.g. C++-Beispiels bin ich auf die JWSCL gestoßen, welche offensichtlich Wrapper für die o.g. AccessCheck*-Routinen enthält. Beim Versuch, das o.g. Beispiel mit den Objekten und Methoden der JWSCL (z.B. TJwSecureGeneralObject.AccessCheckByTypeResultList) umzusetzen, scheitere aber wieder an verschiedenen Punkten:
    • wenn ich versuche, einen TJwSecurityDescriptor-Wrapper für den PSECURITY_DESCRIPTOR, den ich aus meiner AD-Abfrage erhalten habe, zu erstellen tritt eine EJwsclInvalidSid-Exception auf. Beim Debuggen kann ich sehen, dass dies beim Durcharbeiten der ACEs geschieht (der SD in meinem Beispiel enthält insgesamt 91 davon) - bin ich hiermit vielleicht doch auf dem richtigen Weg und es stimmt nur etwas in unserem AD nicht?

Ist es irgendeiner dieser drei Ansätze wert, weiter verfolgt zu werden? Kann ich damit überhaupt ans Ziel kommen oder gibt es noch einen ganz anderen Weg?

Grüße,

Oliver
Oliver Giesen

People assume that time is a strict progression of cause and effect, but *actually* from a non-linear, non-subjective viewpoint - it's more like a big ball of wibbly-wobbly... timey-wimey... stuff.
The Doctor
  Mit Zitat antworten Zitat
Dezipaitor

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

AW: Prüfung effektiver Berechtigungen eines "Extended Right" auf AD-Objekte?

  Alt 24. Dez 2011, 20:29
Sag mir mal bitte ganz genau, an welcher Stelle die Exception in JWSCL geworfen wird.
Extended Rights (ER) sind eine spezielle Sache, weil eben GUIDs verwendet werden. Aber bei dir scheint ein SID inkorrekt zu sein, was garnichts mit den ER zu tun hat.
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 ogiesen
ogiesen

Registriert seit: 25. Okt 2004
Ort: Delmenhorst
43 Beiträge
 
Delphi XE3 Enterprise
 
#3

AW: Prüfung effektiver Berechtigungen eines "Extended Right" auf AD-Objekte?

  Alt 2. Jan 2012, 09:51
Moin Dezipaitor! Frohes Neues!

Zitat:
Sag mir mal bitte ganz genau, an welcher Stelle die Exception in JWSCL geworfen wird.
Also, ich hab's jetzt gerade nochmal probiert und bekomme zuerst folgende Exception:

Zitat:
---------------------------
Debugger Exception Notification
---------------------------
Project ADACLQuery.exe raised exception class EJwsclWinCallFailedException with message '

An Exception of type EJwsclWinCallFailedException was raised.
(Data was given by programmer and can vary from actual source.)
Source method....: Create(const SIDString : TJwString)
Source class.....: TJwSecurityId
Source file......: JwsclSid.pas
Source line......: 0
GetLastError.....: 1337 ($539)
GetLastErrorMsg..: The security ID structure is invalid.

Message : Call to ConvertStringSidToSid failed.
'.
Ich bin mir absolut sicher, dass es bei früheren Tests eine EJwsclInvalidSid war, aber ich kann nicht mehr nachvollziehen, was ich seitdem geändert habe. Ich vermute aber mal, dass die Ursache die selbe sein dürfte.

In dem Augenblick, wo die Exception auftritt (in diesem Fall beim 22. Aufruf von GetStringSID), ist das hier der Inhalt des fSID-Feldes, das umgewandelt werden soll:
Code:
Name                   Value
----------------------- ----------------------------
fSID                   $1EE3AE8
+ Revision             3
+ SubAuthorityCount    0
+ IdentifierAuthority  ((0, 0, 154, 255, 248, 240))
| + Value              (0, 0, 154, 255, 248, 240)
+ SubAuthority         (0)
(Das ist natürlich nur exemplarisch, aber ich bekomme den Fehler auch für andere Objekte und dann auch für andere SIDs. Die einzige Gemeinsamkeit, die ich bei den fehlgeschlagenen Versuchen bisher feststellen konnte, war dass dort überall die Revision den Wert 3 hatte.)

Der Callstack sieht zu dem Zeitpunkt so aus:
Code:
JwsclSid.TJwSecurityId.GetStringSID
JwsclSid.TJwSecurityId.Create($42D3628)
JwsclAcl.TJwSecurityAccessControlEntry.Create($42D3620)
JwsclAcl.TJwSecurityAccessControlEntry.CreateACE($42D3620)
JwsclAcl.TJwSecurityAccessControlList.Create($42D33B0)
JwsclAcl.TJwDAccessControlList.Create($42D33B0)
JwsclDescriptor.TJwSecurityDescriptor.InitializeSD($318598)
JwsclDescriptor.TJwSecurityDescriptor.Create($318598)
ADACLQueryFo.TForm19.JwButton1Click($1E57C50)
Setze ich die Ausführung dann fort, gibt es noch eine EInvalidPointer-Exception in TObject.FreeInstance, laut Callstack ausgelöst durch TJwSecurityAccessControlList.Destroy. "Invalid Pointer operation" ist dann auch die Meldung, die ich außerhalb des Debuggers zu sehen bekomme.

Hier ist der aufrufende Code:
Delphi-Quellcode:
var
  lObj: IDirectoryObject;
  lAttrs: array of PWideChar;
  lAttrEntries: PAdsAttrInfoArray;
  lAttrCount: Cardinal;
  lSD: PSECURITY_DESCRIPTOR;
// lSDSize: Cardinal;
  lSID: PSID;
  lAbsSD: PSECURITY_DESCRIPTOR;
  lAbsSDSize: Cardinal;
  lDacl: PACL;
  lDaclSize: Cardinal;
  lSacl: PACL;
  lSaclSize: Cardinal;
  lOwner: PSID;
  lOwnerSize: Cardinal;
  lGroup: PSID;
  lGroupSize: Cardinal;
  lJwSD: TJwSecurityDescriptor;
  lJwSelfSid: TJwSecurityId;
  lJwTypes: TJwObjectTypeArray;
  lJwMapping: TJwSecurityGenericMappingClass;
  lJwPrivSet: TJwPrivilegeSet;
  lJwGrantedAccess: TJwAccessMaskArray;
  lJwStatus: TJwCardinalArray;
  lDesiredAccess: Cardinal;
  lItm: TListItem;
  lTypeGUID: TGUID;
begin
  if Failed(ADsGetObject(PWideChar('LDAP://' + ObjDN_CB.Text),
                         IDirectoryObject,
                         Pointer(lObj))) then Exit;

  SetLength(lAttrs, 2);
  lAttrs[0] := 'nTSecurityDescriptor';
  lAttrs[1] := 'objectSID';

  if Failed(lObj.GetObjectAttributes(@lAttrs[0],
                                     Length(lAttrs),
                                     PADS_ATTR_INFO(lAttrEntries),
                                     lAttrCount)) then Exit;

  lSD := PSECURITY_DESCRIPTOR(lAttrEntries[0].pADsValues.SecurityDescriptor.lpValue);
// lSDSize := lAttrEntries[0].pADsValues.SecurityDescriptor.dwLength;
  lSID := PSID(lAttrEntries[1].pADsValues.OctetString.lpValue);

  lAbsSD := nil; lDacl := nil; lSacl := nil; lOwner := nil; lGroup := nil;

  if not MakeAbsoluteSD(lSD, lAbsSD, lAbsSDSize, lDacl, lDaclSize, lSacl, lSaclSize, lOwner, lOwnerSize, lGroup, lGroupSize) then
    begin
      lAbsSD := PSECURITY_DESCRIPTOR(LocalAlloc(0, lAbsSDSize));
      lDacl := PACL(LocalAlloc(0, lDaclSize));
      lSacl := PACL(LocalAlloc(0, lSaclSize));
      lOwner := PSID(LocalAlloc(0, lOwnerSize));
      lGroup := PSID(LocalAlloc(0, lGroupSize));
      if not MakeAbsoluteSD(lSD, lAbsSD, lAbsSDSize, lDacl, lDaclSize, lSacl, lSaclSize, lOwner, lOwnerSize, lGroup, lGroupSize) then
        begin
          FreeAdsMem(Pointer(lAttrEntries));
          Abort;
        end;
    end;

  lDesiredAccess := ADS_RIGHT_DS_CONTROL_ACCESS; // = $00000100

  lJwSD := TJwSecurityDescriptor.Create(lAbsSD); // <<<--- Exception hier
  try
    lJwSelfSid := TJwSecurityId.Create(lSID);
    try
      SetLength(lJwTypes, 1);
      lTypeGUID := StringToGuid(ObjTypeGuid_CB.Text);
      lJwTypes[0].Level := ACCESS_OBJECT_GUID;
      lJwTypes[0].Sbz := 0;
      lJwTypes[0].ObjectType := @lTypeGUID;

      lJwMapping := TJwSecurityGenericMapping;

      TJwSecureGeneralObject.AccessCheckByTypeResultList(lJwSD, lJwSelfSid, nil, lDesiredAccess, lJwTypes, lJwMapping, lJwPrivSet, lJwGrantedAccess, lJwStatus);
    finally
      lJwSelfSid.Free;
    end;
  finally
    lJwSD.Free;
  end;

end;
Es macht übrigens im Hinblick auf den Fehler keinen Unterschied, wenn ich den MakeAbsolute-Abschnitt weglasse.

Der Client auf dem der Code läuft ist Windows 7 Enterprise. Das AD läuft auf einem Windows Server 2008 R2. Das abgefragte Objekt in dem o.g. Beispiel ist ein mailaktivierter Öffentlicher Ordner auf einem Exchange 2007 SP1.

Sag einfach bescheid, wenn Du noch weitere Infos brauchst.
Oliver Giesen

People assume that time is a strict progression of cause and effect, but *actually* from a non-linear, non-subjective viewpoint - it's more like a big ball of wibbly-wobbly... timey-wimey... stuff.
The Doctor

Geändert von ogiesen ( 2. Jan 2012 um 09:57 Uhr)
  Mit Zitat antworten Zitat
Dezipaitor

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

AW: Prüfung effektiver Berechtigungen eines "Extended Right" auf AD-Objekte?

  Alt 14. Jan 2012, 13:38
Die Prüfung der SID schlägt fehl durch Windows. Du hast eine SID angegeben, welche so aussieht : S-3-IA (wobei IA ein 64bit Integer von IdentifierAuthority ist).

Tatsächlich ist die Revisions-ID 3 nicht gültig. Ich habe dies auch noch nie gesehen. Zudem identifiziert die SID keinen Benutzer, sondern alleine die Autorität, welche solche SIDs vergibt. Windows NT vergibt z.B. SIDs mit S-1-5. Damit kann man alleine aber noch keine Prüfung z.B. mit Benutzern machen. Es fehlt also noch die Subautorität, d.h. eine für den Computer oder Domäne eindeutige Nummer. Diese Subautorität vergibt dann nochmals eine relative ID (RID) für die Benutzer.

Sehen denn alle Revision 3 SIDs bei dir so aus (keine SubAuth)? Sonst würde ich vorsichtig sagen, dass man diese vorher entfernen muss (wohl erstmal per Hand). Allerdings kenne ich mich mit AD zu wenig aus, um zu sagen, dass dies ohne Gefahr möglich ist. Auf jeden Fall sollten die AD Funktionen und AccessCheck damit umgehen können, weil sie einfach die SID Strukturen auf Gleichheit prüfen (zumindest AccessCheck). Die Standardfunktionen der WinAPI für die Manipulation von SIDs prüfen jedoch immer die Revision auf 1, so dass es zu diesem Fehler kommt.
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 ogiesen
ogiesen

Registriert seit: 25. Okt 2004
Ort: Delmenhorst
43 Beiträge
 
Delphi XE3 Enterprise
 
#5

AW: Prüfung effektiver Berechtigungen eines "Extended Right" auf AD-Objekte?

  Alt 14. Jan 2012, 14:32
OK, dann werd ich nächste Woche, wenn ich wieder im Büro bin, mal versuchen, herauszufinden, zu was für Objekten diese SIDs gehören.

Verstehe ich Dich aber denn dann grundsätzlich richtig, dass das Problem in diesem Fall nicht in meinem Code, sondern in unserem AD liegt?

Selbst, wenn ich die fehlerhaften(?) Objekte in unserem AD finden und "unschädlich" machen kann, habe ich ja keine Kontrolle über die ADs unserer Kunden... (dieser Code soll irgendwann einmal in einem Shareware-Produkt landen) Gäbe es denn vielleicht irgendeine Möglichkeit, den Code gegen solche Fälle "abzuhärten"? Z.B. indem man diese Einträge einfach ignoriert, statt den Vorgang komplett abzubrechen?
Oliver Giesen

People assume that time is a strict progression of cause and effect, but *actually* from a non-linear, non-subjective viewpoint - it's more like a big ball of wibbly-wobbly... timey-wimey... stuff.
The Doctor
  Mit Zitat antworten Zitat
Dezipaitor

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

AW: Prüfung effektiver Berechtigungen eines "Extended Right" auf AD-Objekte?

  Alt 15. Jan 2012, 19:50
Ich hab noch nirgends eine SID mit revision ungleich 1 gesehen. Natürlich könntest du diese SID ignorieren oder auf 1 setzen, aber was dabei herauskommt (insbesondere ein Sicherheitsloch) kann ich nicht sagen.

Es wäre interessant und vllt wichtig zu wissen, woher diese SID eigentlich stammt. Weil eigentlich bedeutet die Revisionssnummer, dass auch die Struktur irgendwie angepasst wurde und daher ein anderer Algorithmus angewendet werden muss, um z.B. von String auf SID oder zurück zu kommen.
Christian
Windows, Tokens, Access Control List, Dateisicherheit, Desktop, Vista Elevation?
Goto: JEDI API LIB & Windows Security Code Library (JWSCL)
  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 04:18 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