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