Wie übersetze ich eine Windows-SID in eine SQL Server-Server-Benutzer-ID?

8

Es gibt diese nette SQL Server-Funktion, SUSER_SNAMEdie eine server_user_sid in einen Benutzernamen übersetzt. Dies ist nützlich, um bekannte Windows-SIDs in (möglicherweise lokalisierte) Benutzernamen zu übersetzen.

Beispiel:

SELECT SUSER_SNAME(0x01020000000000052000000021020000)

-- yields 'BUILTIN\USERS' (or, on a German system, 'VORDEFINIERT\Benutzer')

Mit etwas Googeln und Ausprobieren (= Benutzer manuell erstellen und anschließend prüfen sys.server_principals) habe ich folgende Äquivalenzen ermittelt:

Built-in User/Group    Windows SID      SQL Server server_user_sid

BUILTIN\USERS          S-1-5-32-545     0x01020000000000052000000021020000
NT AUTHORITY\SYSTEM    S-1-5-18         0x010100000000000512000000

Was ist der Algorithmus zum Konvertieren von Windows-SIDs in SQL Server server_user_sids?

Heinzi
quelle

Antworten:

12

SIDs in Form von 0x01020000000000052000000021020000sind keine "SQL Server" -SIDs. Das ist einfach der zugrunde liegende Binärwert der SID. Eine andere Form, die es annehmen kann (und immer noch den gleichen Wert hat), ist die "Zeichenfolge" -Form ( SID- Zeichenfolgenformatsyntax ), die aussieht S-1-5-32-545(in einigen MSDN-Dokumentationen als "SDDL" -Format bezeichnet), obwohl SDDL mehr als nur behandelt SIDs). Beide haben dieselbe Windows SID. Dieses Setup ähnelt dem, wie GUIDs eine Zeichenfolgendarstellung haben, die sich von ihrem zugrunde liegenden Binärwert unterscheidet.

Es gibt eine undokumentierte integrierte Funktion, SID_BINARYdie diese Übersetzung vom SDDL-Formular in das Binärformular ausführt:

SELECT SID_BINARY(N'S-1-5-21-408552231-458724953-3089381293-513');
-- 0x01050000000000051500000027035A185996571BAD3724B801020000

Diese Funktion sollte für die meisten SID-Typen funktionieren. Die folgenden beiden Abfragen zeigen, dass es für Zertifikate und asymmetrische Schlüssel ordnungsgemäß funktioniert (Sie können die ordnungsgemäße Übersetzung überprüfen, da diese beiden Systemkatalogansichten beide Formen der SID enthalten). Und es würde für alle Anmeldungen funktionieren, die aus Zertifikaten und asymmetrischen Schlüsseln erstellt wurden, da die SIDs für diese (sowohl Anmeldungen als auch Benutzer) die SIDs für Zertifikate / Schlüssel sind:

SELECT [name], [string_sid], [sid], SID_BINARY([string_sid])
FROM   [master].sys.certificates;

SELECT [name], [string_sid], [sid], SID_BINARY([string_sid])
FROM   [master].sys.asymmetric_keys;

Beachten Sie, dass Principals vom Typ "S" (SQL Server-Anmeldung / SQL Server-Benutzer) und "R" (Serverrolle / Datenbankrolle) keine SDDL-Darstellung haben, da es sich nicht um Windows-SIDs handelt. Diese beiden Arten von Principals haben die entsprechenden SQL Server-SIDs. Ich denke, dies wären "SQL Server-SIDs", obwohl die Unterscheidung (zwischen Windows-SIDs und SQL Server-SIDs) von Wert und nicht von Form ist.

Wenn Sie keine undokumentierte Funktion verwenden möchten, kann dies auch über SQLCLR mithilfe der SecurityIdentifier-Klasse von .NET erfolgen .

Vorgefertigte SQLCLR-Funktionen für diese Übersetzungen finden Sie in der kostenlosen Version der SQL # -Bibliothek (die ich erstellt habe): Convert_SddlSidToBinary (führt dieselbe Übersetzung aus wie SID_BINARY) und Convert_BinarySidToSddl .

Solomon Rutzky
quelle
2

sys.server_principals ist dein Freund, da es die Windows-Version der SID verfügbar macht.

Siehe Aarons Lösung: Zuordnung zwischen SQL Server-SIDs und Windows-SIDs

Der Vollständigkeit halber ist unten der Code:

CREATE TABLE dbo.TinyNumbers(Number TINYINT PRIMARY KEY);

INSERT dbo.TinyNumbers(Number) 
  SELECT TOP (256) ROW_NUMBER() OVER (ORDER BY number)-1 
  FROM master.dbo.spt_values;

CREATE FUNCTION dbo.GetWindowsSID
(
  @sid VARBINARY(85)
)
RETURNS TABLE
WITH SCHEMABINDING
AS
  RETURN 
  (
    SELECT ADsid = STUFF((SELECT '-' + part FROM 
    (
      SELECT Number = -1, part = 'S-' 
        + CONVERT(VARCHAR(30),CONVERT(TINYINT,CONVERT(VARBINARY(30),LEFT(@sid,1)))) 
        + '-' 
        + CONVERT(VARCHAR(30),CONVERT(INT,CONVERT(VARBINARY(30),SUBSTRING(@sid,3,6))))
      UNION ALL
      SELECT TOP ((LEN(@sid)-5)/4) Number, 
     part = CONVERT(VARCHAR(30),CONVERT(BIGINT,CONVERT(VARBINARY(30), 
  REVERSE(CONVERT(VARBINARY(30),SUBSTRING(@sid,9+Number*4,4)))))) 
      FROM dbo.TinyNumbers ORDER BY Number
    ) AS x ORDER BY Number
    FOR XML PATH(''), TYPE).value(N'.[1]','nvarchar(max)'),1,1,'')
  );
GO

CREATE VIEW dbo.server_principal_sids
AS
  SELECT sp.name, sp.[sid], ad.ADsid, sp.type_desc
    FROM sys.server_principals AS sp
    CROSS APPLY dbo.GetWindowsSID(sp.[sid]) AS ad
    WHERE [type] IN ('U','G') 
    AND LEN([sid]) % 4 = 0;

-- select the data
SELECT name,[sid],ADSid,type_desc FROM dbo.server_principal_sids;
Kin Shah
quelle