Comment traduire un SID Windows en SQL Server server_user_sid?


8

Il y a cette belle fonction SQL Server SUSER_SNAMEqui traduit un server_user_sid en un nom d'utilisateur. Ceci est utile pour traduire des SID Windows bien connus en noms d'utilisateur (potentiellement localisés).

Exemple:

SELECT SUSER_SNAME(0x01020000000000052000000021020000)

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

Avec un peu de recherche sur Google et d'essais et d'erreurs (= créer l'utilisateur manuellement et vérifier sys.server_principalsensuite), j'ai déterminé les équivalences suivantes:

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

Quel est l'algorithme pour convertir les SID Windows en SQL Server server_user_sids?

Réponses:


12

Les SID sous forme de 0x01020000000000052000000021020000ne sont pas des SID "SQL Server". Il s'agit simplement de la valeur binaire sous-jacente du SID. Une autre forme qu'il peut prendre (et toujours avoir la même valeur) est la forme "chaîne" ( SID String Format Syntax ), qui ressemble à celle-ci S-1-5-32-545(désignée comme étant le format "SDDL" dans certaines documentations MSDN, bien que SDDL couvre plus que juste SID). Les deux sont le même SID Windows. Cette configuration est similaire à la façon dont les GUID ont une représentation sous forme de chaîne différente de leur valeur binaire sous-jacente.

Il existe une fonction intégrée non documentée SID_BINARY, qui effectue cette traduction du formulaire SDDL au format binaire:

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

Cette fonction devrait fonctionner sur la plupart des types de SID. Les deux requêtes suivantes montrent qu'il fonctionne correctement pour les certificats et les clés asymétriques (vous pouvez vérifier la traduction appropriée car ces deux vues de catalogue système contiennent les deux formes du SID). Et cela fonctionnerait pour toutes les connexions créées à partir de certificats et de clés asymétriques, car les SID pour ceux (à la fois les connexions et les utilisateurs) sont les certificats / clés 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;

Veuillez noter que les principaux des types "S" (connexion SQL Server / utilisateur SQL Server) et "R" (rôle serveur / rôle de base de données) n'ont pas de représentation SDDL car ils ne sont pas des SID Windows. Ces deux types de principaux ont des SID propres à SQL Server, donc je suppose que ce seraient des "SID SQL Server", bien que la distinction (entre les SID Windows et SID SQL Server) soit de valeur et non de forme.

Si vous ne souhaitez pas utiliser une fonction non documentée, cela peut également être accompli via SQLCLR en utilisant la classe SecurityIdentifier de .NET .

Les fonctions SQLCLR pré-faites pour effectuer ces traductions peuvent être trouvées dans la version gratuite de la bibliothèque SQL # (que j'ai créée): Convert_SddlSidToBinary (fait la même traduction que SID_BINARY) et Convert_BinarySidToSddl .


2

sys.server_principals est votre ami car il expose la version Windows du SID.

Reportez-vous à la solution d'Aaron: mappage entre les SID SQL Server et les SID Windows

Pour être complet, voici le 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;
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.