Was ist die SID?

Beschäftigt man sich mit der Sicherheit unter Windows NT ff, stößt man unweigerlich über den Begriff der SID. Doch was ist diese SID eigentlich genau?

Unter Windows NT ff und dem Dateisystem NTFS können Gruppen oder einzelnen Personen bestimmte Zugriffsrechte auf Dateien zugeordnet werden. Dies ist übrigens nicht nur auf Dateien und Ordner beschränkt, sondern gilt auch allgemein für viele andere Objekte, zum Beispiel Zweige in der Registry oder auch Prozessen. Ein Benutzer oder eine Gruppe wird dabei mittels eines Security-Identifiers (SID) eindeutig identifiziert. Eine SID ist weltweit eindeutig. Dies wird dadurch garantiert, dass es sich um einen 96-Bit Wert handelt, der jeden Rechner eindeutig identifiziert und bei der Installation erzeugt und in der Registry abgelegt wird. Die Eindeutigkeit entsteht dadurch, dass die Wahrscheinlichkeit einer Kollision vernachlässigbar ist. Eine SID hat jetzt folgenden Aufbau: S-R-I-SA-SA-SA. Wobei "S" der Buchstabe "S" ist, "R" die Revisionsnummer (momentan eins), "I" ein 48-Bit Wert, der eine Autorität identifiziert (Dies ist immer der NT-Autorität Namespace mit dem Wert fünf.) und "SA" ist ein 32-Bit Wert, welches den Rechner identifiziert und bei der Installation in der Registry abgelegt wurde. Eine SID könnte dann zum Beispiel so aussehen: S-1-5-21-746137067-113007714-854245398.


Dazu kann man in dem MDSN KnowledgeBase Artikel "Bekannte Sicherheits-IDs in Windows-Betriebssystemen" folgendes lesen:

Ein Sicherheits-ID (Security Identifier = SID) ist ein eindeutiger Wert variabler Länge, der einen Sicherheitsprinzipal oder eine Sicherheitsgruppe in Windows-Betriebssystemen identifiziert. Zu den bekannten SIDs zählt eine Gruppe von SIDs, die Standardbenutzer oder -gruppen bezeichnen. Ihre Werte bleiben über alle Betriebssysteme hinweg konstant.

Dort findet man auch eine Liste aller bekannten (well-known) SIDs.


Hinzu kommt noch eine ID, die ein Konto auf dem Rechner bezeichnet. Wobei das Administratorenkonto, welches bei der Installation standardmäßig angelegt, wird immer die ID 500 hat oder das Gastkonto immer die ID 501. Alle weitere Konten haben dann IDs ab 1000 aufwärts. Die SID eines Benutzers könnte dann zum Beispiel so aussehen: S-1-5-21-746137067-113007714-854245398-1003.

Was kann man nun damit praktisch anfangen? Nun, stellen wir uns vor, wir wollten den Besitzer einer Datei raus finden. Da eine Datei eine SID besitzt müssen wir nur diese SID auslesen und einem Konto zuordnen. Dazu benötigen wir zwei Funktionen: GetNamedSecurityInfo um die SID der Datei zu ermitteln und noch LookupAccountSid, um den Kontonamen zu der SID zu erhalten.

GetNamedSecurityInfo:
The GetNamedSecurityInfo function retrieves a copy of the security descriptor for an object specified by name.
LookupAccountSid:
The LookupAccountSid function accepts a security identifier (SID) as input. It retrieves the name of the account for this SID and the name of the first domain on which this SID is found.

In Delphi-Code umgesetzt könnte dies dann so aussehen:

function GetAccountSIDStrW(sid: PSID; var Name: WideString): DWORD;
var
  UserSize, DomainSize: DWORD;
  snu               : SID_NAME_USE;
  User              : WideString;
  Domain            : WideString;
begin
  result := 0;
  UserSize := 0;
  DomainSize := 0;
  LookupAccountSidW(nil, sid, nil, UserSize, nil, DomainSize, snu);
  if (UserSize <> 0) and (DomainSize <> 0) then
  begin
    SetLength(User, UserSize);
    SetLength(Domain, DomainSize);
    if LookupAccountSidW(nil, sid, PWideChar(User), UserSize, PWideChar(Domain), DomainSize, snu) then
    begin
      User := PWideChar(User);
      Domain := PWideChar(Domain);
      Name := Domain + '\' + User;
    end
    else
      result := GetLastError;
  end
end;

function GetFileOwnerSID(const Filename: WideString): PSID;
var
  sidOwner, sidGroup: PSID;
  dacl, sacl        : PACL;
  psd               : PSECURITY_DESCRIPTOR;
begin
  result := nil;
  if GetNamedSecurityInfoW(PWideChar(Filename), SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION, sidOwner, sidGroup, dacl,
    sacl, psd) = 0 then
  begin
    result := sidOwner;
  end
end;

An bei ein kleines Konsolenprogramm als Demo: FileOwner (26 KB). Es ermittelt einfach den Besitzer von sich selber und gibt noch zusätzlich die SID in lesbarer Form aus mittels der Funktion ConvertSidToStringSid. Eine Ausgabe könnte dann so aussehen:



Quellenangabe:

2010-12-29T23:44:55 +0100, mail+homepage[at]michael-puff.de