Bagaimana cara menerjemahkan SID Windows ke SQL Server server_user_sid?

8

Ada fungsi SQL Server SUSER_SNAMEyang bagus ini yang menerjemahkan server_user_sid ke nama pengguna. Ini berguna untuk menerjemahkan SID Windows yang terkenal ke nama pengguna (yang berpotensi dilokalkan).

Contoh:

SELECT SUSER_SNAME(0x01020000000000052000000021020000)

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

Dengan beberapa Googling dan coba-coba (= buat pengguna secara manual dan periksa sys.server_principalssesudahnya) saya telah menentukan persamaan berikut:

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

Apa algoritme untuk mengubah SID Windows ke SQL Server server_user_sids?

Heinzi
sumber

Jawaban:

12

SID dalam bentuk 0x01020000000000052000000021020000bukan SID "SQL Server". Itu hanyalah nilai biner yang mendasari SID. Bentuk lain yang dapat diambil (dan masih bernilai sama) adalah bentuk "string" ( SID String Format Syntax ), yang terlihat seperti S-1-5-32-545(disebut sebagai format "SDDL" dalam beberapa dokumentasi MSDN, meskipun SDDL mencakup lebih dari sekadar SID). Keduanya adalah Windows SID yang sama. Setup ini mirip dengan bagaimana GUID memiliki representasi string yang berbeda dari nilai biner yang mendasarinya.

Ada fungsi built-in tidak berdokumen SID_BINARY,, yang melakukan terjemahan ini dari bentuk SDDL ke dalam bentuk biner:

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

Fungsi ini harus bekerja di sebagian besar tipe SID. Dua kueri berikut ini menunjukkan bahwa ia berfungsi dengan benar untuk Sertifikat dan Kunci Asimetris (Anda dapat memverifikasi terjemahan yang tepat karena kedua tampilan katalog sistem ini memiliki kedua bentuk SID di dalamnya). Dan itu akan bekerja untuk setiap Login yang dibuat dari Sertifikat dan Kunci Asimetris sebagai SID untuk mereka (baik Login dan Pengguna) adalah Cert / Kunci SID:

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;

Harap dicatat bahwa prinsipal tipe "S" (SQL Server Login / Pengguna SQL Server) dan "R" (Peran Server / Peran Database) tidak memiliki representasi SDDL karena mereka bukan Windows SID. Kedua jenis prinsipal ini memiliki SIDs layak SQL Server, jadi saya kira ini akan menjadi "SIDs SQL Server", meskipun perbedaannya (antara SID Windows dan SID Server SQL) bernilai dan bukan bentuk.

Jika Anda tidak ingin menggunakan fungsi tidak berdokumen, ini juga dapat dilakukan melalui SQLCLR menggunakan kelas .Identifier SecurityIdent .NET .

Fungsi SQLCLR yang sudah dibuat sebelumnya untuk melakukan terjemahan ini dapat ditemukan di versi gratis dari perpustakaan SQL # (yang saya buat): Convert_SddlSidToBinary (melakukan terjemahan yang sama seperti SID_BINARY) dan Convert_BinarySidToSddl .

Solomon Rutzky
sumber
2

sys.server_principals adalah teman Anda karena memperlihatkan SID versi Windows.

Lihat solusi Aaron: Peta antara SIDs SQL Server dan SID Windows

Untuk kelengkapan, di bawah ini adalah kode:

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
sumber