Convertir SID hexadécimal en SID Décimal
DROP FUNCTION ConvertirSidWindows
GO
-- =============================================
-- Author: Florent Mazzone
-- Create date: 03/02/2012
-- Description: Convertit un SID hexadécimal (id de compte utilisateur Windows)
-- en SID décimal (SDDL).
-- Spécifier uniquement le SID dans le format à convertir (hexadécimal ou décimal)
-- =============================================
CREATE FUNCTION [dbo].[ConvertirSidWindows]
(
-- Add the parameters for the function here
@sidHexadecimal VARBINARY(85),
@sidDecimal NVARCHAR(85)
)
RETURNS @sid TABLE(
sidHexadecimal VARBINARY(85) ,
sidDecimal NVARCHAR(85)
)
AS
BEGIN
-- Declare the return variable here
DECLARE @i INTEGER
DECLARE @debutPartieDecimale INTEGER
DECLARE @longueurChaine INTEGER
DECLARE @nbPartiesSid INTEGER
DECLARE @sidBinDecompose VARBINARY(4)
DECLARE @sidBinInverse VARBINARY(4)
DECLARE @partieDecimale BIGINT
-- Add the T-SQL statements to compute the return value here
--Convertir un SID héxadécimal en un SID décimal
IF @sidHexadecimal IS NOT NULL
BEGIN
SET @sidDecimal = 'S-'
--Révision (BIG ENDIAN)
SELECT @sidDecimal = @sidDecimal + CAST(CONVERT(INT,SUBSTRING(@sidHexadecimal,1,1)) AS VARCHAR(MAX))
--Nombre de tirets dans le SID (sans révision et SECURITY_NT_AUTHORITY) (BIG ENDIAN)
SELECT @nbPartiesSid = CONVERT(INT,SUBSTRING(@sidHexadecimal,2,1))
--SECURITY_NT_AUTHORITY (BIG ENDIAN)
SELECT @sidDecimal = @sidDecimal + '-'+ CAST(CONVERT(BIGINT,SUBSTRING(@sidHexadecimal,3,6)) AS VARCHAR(MAX))
--Première partie : SECURITY_NT_NON_UNIQUE (LITTLE ENDIAN)
--Partie intermédiaire : id de la machine (LITTLE ENDIAN)
--Dernière partie : id d'utilisateur unique sur la machine (LITTLE ENDIAN)
--La conversion de BIG ENDIAN en LITTLE ENDIAN est réalisée avec la fonction REVERSE
SET @i = 0
WHILE @i < @nbPartiesSid
BEGIN
SELECT @sidBinDecompose = SUBSTRING(@sidHexadecimal,9 + @i * 4 ,4)
SET @sidBinInverse = CAST(REVERSE(@sidBinDecompose)AS BINARY(4))
SELECT @sidDecimal = @sidDecimal + '-' + CAST(CONVERT(BIGINT,@sidBinInverse) AS VARCHAR(MAX))
SET @i = @i +1
END
--Insérer dans le tableu les SID convertis
INSERT INTO @sid(sidHexadecimal,sidDecimal)
VALUES (@sidHexadecimal,@sidDecimal)
END
--Convertir un SID décimal en SID héxadécimal
ELSE IF @sidDecimal IS NOT NULL
BEGIN
--Compter le nombre de parties du SID décimal
SET @nbPartiesSid = 0
SET @debutPartieDecimale = 1
SELECT @longueurChaine = PATINDEX( '%-%' , @sidDecimal )
WHILE @longueurChaine > 0
BEGIN
SET @nbPartiesSid = @nbPartiesSid +1
SELECT @longueurChaine = PATINDEX( '%-%' ,SUBSTRING(@sidDecimal,@debutPartieDecimale,LEN(@sidDecimal)-@debutPartieDecimale))
SET @debutPartieDecimale = @longueurChaine + @debutPartieDecimale
END
--Conversion de décimal en héxadécimal
SET @debutPartieDecimale = 1
--S
SELECT @longueurChaine = PATINDEX( '%-%' , @sidDecimal )-1
SET @debutPartieDecimale = @longueurChaine+@debutPartieDecimale+1
----Révision (BIG ENDIAN)
SELECT @longueurChaine = PATINDEX( '%-%' , SUBSTRING(@sidDecimal,@debutPartieDecimale,LEN(@sidDecimal)-@debutPartieDecimale))-1
SELECT @partieDecimale = SUBSTRING(@sidDecimal,@debutPartieDecimale,@longueurChaine)
SELECT @sidHexadecimal = CONVERT(VARBINARY(1),CAST(@partieDecimale AS BIGINT))
SET @debutPartieDecimale = @longueurChaine+@debutPartieDecimale+1
--Nombre de tirets dans le SID (sans révision et SECURITY_NT_AUTHORITY) (BIG ENDIAN)
SELECT @sidHexadecimal = @sidHexadecimal+ CONVERT(VARBINARY(1),@nbPartiesSid-3)
--SECURITY_NT_AUTHORITY (BIG ENDIAN)
SELECT @longueurChaine = PATINDEX( '%-%' , SUBSTRING(@sidDecimal,@debutPartieDecimale,LEN(@sidDecimal)-@debutPartieDecimale))-1
SELECT @partieDecimale = SUBSTRING(@sidDecimal,@debutPartieDecimale,@longueurChaine)
SELECT @sidHexadecimal =@sidHexadecimal + CONVERT(VARBINARY(6),CAST(@partieDecimale AS BIGINT),0)
SET @debutPartieDecimale = @longueurChaine+@debutPartieDecimale+1
--Première partie : SECURITY_NT_NON_UNIQUE (LITTLE ENDIAN)
--Partie intermédiaire : id de la machine (LITTLE ENDIAN)
SELECT @longueurChaine = PATINDEX( '%-%' ,SUBSTRING(@sidDecimal,@debutPartieDecimale,LEN(@sidDecimal)-@debutPartieDecimale))-1
WHILE @longueurChaine > 0
BEGIN
SELECT @partieDecimale = SUBSTRING(@sidDecimal,@debutPartieDecimale,@longueurChaine)
SELECT @sidHexadecimal = @sidHexadecimal + CAST(REVERSE( CONVERT(BINARY(4),CAST(@partieDecimale AS BIGINT),0)) AS BINARY(4))
SET @debutPartieDecimale = @longueurChaine+@debutPartieDecimale+1
SELECT @longueurChaine = PATINDEX( '%-%' , SUBSTRING(@sidDecimal,@debutPartieDecimale,LEN(@sidDecimal)-@debutPartieDecimale))-1
END
--Dernière partie : id d'utilisateur unique sur la machine (LITTLE ENDIAN)
SELECT @partieDecimale = SUBSTRING(@sidDecimal,@debutPartieDecimale,LEN(@sidDecimal)-@debutPartieDecimale+1)
SELECT @sidHexadecimal = @sidHexadecimal + CAST(REVERSE( CONVERT(BINARY(4),CAST(@partieDecimale AS BIGINT),0)) AS BINARY(4))
--Insérer dans le tableau les résultats obtenus
INSERT INTO @sid(sidHexadecimal,sidDecimal)
VALUES (@sidHexadecimal,@sidDecimal)
END
-- Return the result of the function
RETURN
END
GO
--Test de la fonction (les valeurs peuvent être comparées en utilisant Regedit HKEY_USERS)
DECLARE @sidHexaDecimalUtilisateur VARBINARY(85)
DECLARE @sidDecimalUtilisateur NVARCHAR(85)
SELECT @sidDecimalUtilisateur = sidDecimal FROM [ConvertirSidWindows] (SUSER_SID(),NULL)
SELECT @sidHexaDecimalUtilisateur = sidHexadecimal FROM [ConvertirSidWindows] (NULL,@sidDecimalUtilisateur)
SELECT SUSER_SNAME(@sidHexaDecimalUtilisateur) AS WindowsLogin,@sidHexaDecimalUtilisateur AS SidHexaDecimal,@sidDecimalUtilisateur AS SidDecimal