Tuesday, October 05, 2010

Computing per-service SIDs without sc.exe

How it's done is well known:

When configured to have a per-service SID (i.e. type of SID either "Unrestricted" or "Restricted"), the service SID is computed as S-1-5-80-{SHA-1(service name in uppercase)}

Here's a quick script to do it, that can be the basis for including the computation programmatically into e.g. installer generation.

open System.Security.Cryptography
open System.Security.Principal
open System.Text
open System
// 1st arg (index [0]) is this script
let name = fsi.CommandLineArgs.[1]
let hash = new SHA1CryptoServiceProvider()
let tail = name.ToUpper()
|> Encoding.Unicode.GetBytes
|> (fun x -> hash.ComputeHash(x))
let head = [|1uy; 6uy; 0uy; 0uy; 0uy; 0uy; 0uy; 5uy; 80uy; 0uy; 0uy; 0uy |]
let binary = Array.append head tail
let sid = new SecurityIdentifier(binary, 0)
Console.WriteLine(sid.ToString())
view raw gistfile1.fs hosted with ❤ by GitHub

So running it we get:

>& 'C:\Program Files\FSharp-2.0.0.0\bin\fsi.exe' .\ssid.fsx MyService
S-1-5-80-517257762-1253276234-605902578-3995580692-1133959824
>

which compares nicely with:

>sc showsid MyService

NAME: MyService
SERVICE SID: S-1-5-80-517257762-1253276234-605902578-3995580692-1133959824
>

where each of the 5 trailing facets is just the decimal representation of 4 bytes of the SHA-1 hash taken as a little-endian unsigned integer.

No comments :