web-dev-qa-db-fra.com

Comment traduire un SID Windows en SQL Server server_user_sid?

Il y a cette fonction Nice SQL Server SUSER_SNAME qui traduit un server_user_sid en 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 quelques recherches sur Google et essais et erreurs (= créez l'utilisateur manuellement et cochez sys.server_principals après) 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?

8
Heinzi

SID sous la forme de 0x01020000000000052000000021020000 ne sont pas des SID "SQL Server". Il s'agit simplement de la valeur binaire sous-jacente du SID. Une autre forme qu'elle peut prendre (et avoir toujours la même valeur) est la forme "chaîne" ( SID String Format Syntax ), qui ressemble à S-1-5-32-545 (désigné comme étant le format "SDDL" dans certaines documentations MSDN, bien que SDDL couvre plus que les 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 fait 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 de 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 mandants ont des SID propres à SQL Server, donc je suppose que ceux-ci serait "SID SQL Server", bien que la distinction (entre Windows SID et SQL Server SID) soit de valeur et non de forme .

Si vous ne voulez pas utiliser une fonction non documentée, cela peut également être accompli via SQLCLR en utilisant SecurityIdentifier class 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 .

12
Solomon Rutzky

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;
2
Kin Shah