Как перевести SID Windows в SQL Server server_user_sid?

8

Есть эта замечательная функция SQL Server, SUSER_SNAMEкоторая переводит server_user_sid в имя пользователя. Это полезно для перевода известных Windows SID (потенциально локализованных) имен пользователей.

Пример:

SELECT SUSER_SNAME(0x01020000000000052000000021020000)

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

С некоторыми поисками в Google и методом проб и ошибок (= создайте пользователя вручную и проверьте sys.server_principalsпозже), я определил следующие эквивалентности:

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

Какой алгоритм для преобразования SID Windows в SQL Server server_user_sids?

Heinzi
источник

Ответы:

12

SID в форме 0x01020000000000052000000021020000не являются SID "SQL Server". Это просто базовое двоичное значение SID. Другой формой, которую он может принимать (и при этом иметь то же значение), является «строковая» форма ( синтаксис формата строки SID ), которая выглядит S-1-5-32-545(называемая форматом «SDDL» в некоторой документации MSDN, хотя SDDL охватывает не только МОРС). Оба идентичных идентификатора Windows. Эта настройка аналогична тому, как GUID имеют строковое представление, которое отличается от базового двоичного значения.

Существует недокументированная встроенная функция, SID_BINARYкоторая выполняет перевод из формы SDDL в двоичную форму:

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

Эта функция должна работать для большинства типов SID. Следующие два запроса показывают, что он работает правильно для сертификатов и асимметричных ключей (вы можете проверить правильность перевода, так как эти два представления системного каталога имеют обе формы 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;

Обратите внимание, что принципалы типов «S» (имя пользователя SQL Server / пользователь SQL Server) и «R» (роль сервера / роль базы данных) не имеют представления SDDL, поскольку они не являются SID Windows. Эти два типа участников имеют соответствующие SID SQL Server, поэтому я предполагаю, что это будут «SID SQL Server», хотя различие (между SID Windows и SID SQL Server) имеет значение, а не форму.

Если вы не хотите использовать недокументированную функцию, это также может быть выполнено с помощью SQLCLR с использованием класса .NET SecurityIdentifier .

Предварительно созданные функции SQLCLR для выполнения этих переводов можно найти в бесплатной версии библиотеки SQL # (которую я создал): Convert_SddlSidToBinary (выполняет тот же перевод, что и SID_BINARY) и Convert_BinarySidToSddl .

Соломон Руцкий
источник
2

sys.server_principals Ваш друг, поскольку он предоставляет версию SID для Windows.

Обратитесь к решению Аарона: сопоставление идентификаторов безопасности SQL Server и идентификаторов безопасности Windows

Для полноты ниже приведен код:

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;
Кин Шах
источник