Per this TechNet blog post, the non-well-known portion of a service SID is generated by taking a SHA1 hash of the uppercase service name, and then splitting apart the results into five unsigned 4-byte numbers. The following code performs this computation and returns the SID as displayed in Windows:
DECLARE @serviceName nvarchar(128) = 'MSSQL$SQL2008R2DEV';
SELECT
'S-1-5-80' +
'-' + CONVERT(varchar(20), CONVERT(bigint, CONVERT(varbinary(4), sys.fn_varbintohexsubstring(0, a.BinSid, 17, 4), 2))) +
'-' + CONVERT(varchar(20), CONVERT(bigint, CONVERT(varbinary(4), sys.fn_varbintohexsubstring(0, a.BinSid, 13, 4), 2))) +
'-' + CONVERT(varchar(20), CONVERT(bigint, CONVERT(varbinary(4), sys.fn_varbintohexsubstring(0, a.BinSid, 9, 4), 2))) +
'-' + CONVERT(varchar(20), CONVERT(bigint, CONVERT(varbinary(4), sys.fn_varbintohexsubstring(0, a.BinSid, 5, 4), 2))) +
'-' + CONVERT(varchar(20), CONVERT(bigint, CONVERT(varbinary(4), sys.fn_varbintohexsubstring(0, a.BinSid, 1, 4), 2)))
FROM
(
SELECT
CONVERT(varbinary(20), REVERSE(HASHBYTES('SHA1', UPPER(@serviceName)))) AS BinSid
) a;
The binary SID can also be obtained by using the SUSER_SID
function (with some extra processing to handle the fixed portion) in lieu of HASHBYTES
. (Note that the raw binary SID must have its endianness reversed before conversion and output. Also, the @serviceName
variable being nvarchar is important.)
If you have .NET available, doing the hash calculation is trivial. Here's the C# code to do it:
using System.Security.Cryptography;
...
string serviceName = "MSSQL$SQL2008R2DEV";
HashAlgorithm ha = HashAlgorithm.Create("SHA1");
byte[] hash = ha.ComputeHash(serviceName.ToUpper().SelectMany(c => BitConverter.GetBytes(c)).ToArray());
string sid = "S-1-5-80";
for (int i = 0; i < 5; i++)
sid += "-" + BitConverter.ToUInt32(hash, i * 4);
Best Answer
There are a couple of possibilities.
First if the orphaned user is a windows login/group (type U or G) then no problem.
If it's a "SQL Login" (type S) and the login exists then again no problem.
If the login does not exist for a "SQL Login" then you have to create the login and that will require knowing the password.
Don't forget to make sure your password meets your windows policy requirements. If you still have the old server you can copy the login pretty easily from the other server including the password by getting the HASH of the password from the other server. (There may be some issues depending on if the two servers are different versions).
I did a post on this here: http://sqlstudies.com/2013/03/25/how-do-i-move-a-sql-login-from-one-server-to-another-without-the-password/