web-dev-qa-db-ja.com

Windows SIDをSQL Server server_user_sidに変換するにはどうすればよいですか?

この素敵なSQL Server関数があります SUSER_SNAMEserver_user_sidをユーザー名に変換します。これは、よく知られたWindows SIDを(潜在的にローカライズされた)ユーザー名に変換するのに役立ちます。

例:

SELECT SUSER_SNAME(0x01020000000000052000000021020000)

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

いくつかのグーグルと試行錯誤(=手動でユーザーを作成し、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

Windows SIDをSQL Server server_user_sidsに変換するアルゴリズムは何ですか?

8
Heinzi

0x01020000000000052000000021020000形式のSIDは「SQL Server」SIDではありません。これは、SIDの基本的なバイナリ値です。それが取ることができる別の形式(それでも同じ値である)は、「文字列」形式( SID文字列形式構文 )で、S-1-5-32-545(「SDDL」と呼ばれる)のように見えます一部のMSDNドキュメントでフォーマットされていますが、SDDLはSIDだけではありません)。どちらも同じWindows SIDです。このセットアップは、GUIDの基礎となるバイナリ値とは異なる文字列表現を持っている方法に似ています。

文書化されていない組み込み関数SID_BINARYがあり、SDDLフォームからバイナリフォームへのこの変換を実行します。

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

この関数は、ほとんどのSIDタイプで機能します。次の2つのクエリは、証明書と非対称キーに対して正しく機能していることを示しています(これらの2つのシステムカタログビューには両方の形式のSIDがあるため、適切な変換を確認できます)。また、証明書と非対称キーから作成されたすべてのログインに対して機能します(ログインとユーザーの両方の)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"(サーバーロール/データベースロール)のプリンシパルは、Windows SIDではないため、SDDL表現を持たないことに注意してください。これらの2種類のプリンシパルにはSQL Server固有のSIDがあるため、theseは "SQL Server SID"になると思いますが、Windows SIDとSQL Server SIDの違いは重要ではなく、形式ではありません。

ドキュメントに記載されていない関数を使用したくない場合は、.NETの SecurityIdentifier class を使用してSQLCLRでこれを実行することもできます。

これらの変換を行うための既成のSQLCLR関数は、無料バージョンの SQL# ライブラリー(私が作成したもの)にあります:Convert_SddlSidToBinarySID_BINARYと同じ変換を行います)およびConvert_BinarySidToSddl

12
Solomon Rutzky

sys.server_principalsは、WindowsバージョンのSIDを公開するため、あなたの友達です。

アーロンのソリューションを参照してください: SQL Server SIDとWindows SID間のマッピング

完全を期すために、以下にコードを示します。

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