Como converter um SID do Windows em um SQL Server server_user_sid?

8

Existe essa boa função do SQL Server SUSER_SNAMEque traduz um server_user_sid em um nome de usuário. Isso é útil para converter SIDs do Windows conhecidos em nomes de usuário (potencialmente localizados).

Exemplo:

SELECT SUSER_SNAME(0x01020000000000052000000021020000)

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

Com algumas pesquisas no Google e tentativa e erro (= crie o usuário manualmente e verifique sys.server_principalsdepois), determinei as seguintes equivalências:

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

Qual é o algoritmo para converter SIDs do Windows em SQL Server server_user_sids?

Heinzi
fonte

Respostas:

12

SIDs na forma de 0x01020000000000052000000021020000não são SIDs "SQL Server". Esse é simplesmente o valor binário subjacente do SID. Outro formato que pode assumir (e ainda ter o mesmo valor) é o formato "string" ( SID String Format Syntax ), que parece S-1-5-32-545(referido como sendo o formato "SDDL" em algumas documentações do MSDN, embora o SDDL cubra mais do que apenas SIDs). Ambos são os mesmos Windows SID. Essa configuração é semelhante à maneira como os GUIDs têm uma representação de sequência diferente do valor binário subjacente.

Há uma função interna não documentada SID_BINARY, que faz essa conversão do formulário SDDL para o formato binário:

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

Essa função deve funcionar na maioria dos tipos de SID. As duas consultas a seguir mostram que ele funciona corretamente para certificados e chaves assimétricas (você pode verificar a tradução adequada, pois essas duas visualizações de catálogo do sistema têm as duas formas do SID). E funcionaria para todos os logins criados a partir de certificados e chaves assimétricas, pois os SIDs desses (logins e usuários) são os SIDs de certificado / chave:

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;

Observe que os princípios dos tipos "S" (Logon do SQL Server / Usuário do SQL Server) e "R" (Função do servidor / Função do banco de dados) não possuem uma representação SDDL, pois não são SIDs do Windows. Estes dois tipos de diretores têm SQL Server SID properietary, então eu acho que estes seriam "Servidor SID SQL", embora a distinção (entre o Windows SID e SQL Server SID) é de valor e não a forma.

Se você não deseja usar uma função não documentada, isso também pode ser realizado via SQLCLR usando a classe SecurityIdentifier do .NET .

As funções SQLCLR pré-fabricadas para fazer essas traduções podem ser encontradas na versão gratuita da biblioteca SQL # (que eu criei): Convert_SddlSidToBinary (faz a mesma tradução que SID_BINARY) e Convert_BinarySidToSddl .

Solomon Rutzky
fonte
2

sys.server_principals é seu amigo, pois expõe a versão Windows do SID.

Consulte a solução da Aaron: Mapa entre os SIDs do SQL Server e os SIDs do Windows

Para completar, abaixo está o código:

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
fonte