What is the maximum length of a SID in SDDL format
Asked Answered
P

4

20

I'm building Active Directory Authentication into my application and I am planning to link my application's internal accounts to a user's domain SID. It is easier for me to work with the string format of the sid than a byte array so I was planning to store it in the database as a string. How long should I make the field to ensure SID's will not get truncated?

Phlegmatic answered 16/7, 2009 at 21:49 Comment(0)
E
35

I had the same question, and I believe the right answer is:

  • ID as string: 184 characters, or varchar(184) in SQL Server
  • SID as string of Hex digits: 136 characters, or varchar(136) in SQL Server
  • SID as binary: 68 bytes, or varbinary(68) in SQL Server

I haven't checked the math myself, but the technique used here looks valid: https://groups.google.com/d/msg/microsoft.public.dotnet.security/NpIi7c2Toi8/31SVhcepY58J

Refer to the program written by Russell Mangel on Aug 19, 2006, also copied here for reference:

So the answer to my question is:

varbinary(68)-- pure binary
varchar(136) -- (68*2) = hexString
varchar(184) -- SID String

I wrote a little program to test, notice that .NET 2.0 has SecurityIdentifier.MaxBinaryLength, I didn't know about this.

Console.WriteLine("SID Min. num Bytes: {0}",
SecurityIdentifier.MinBinaryLength);
Console.WriteLine("SID Max. num Bytes: {0}",
SecurityIdentifier.MaxBinaryLength);
Byte[] bytes = new byte[SecurityIdentifier.MaxBinaryLength];
for (Int32 i = 0; i < bytes.Length; i++)
{
    bytes[i] = 0xFF;
}
bytes[0] = 0x01; // Must be 1
bytes[1] = 0x0F; // Max 15 (base10)
SecurityIdentifier sid = new SecurityIdentifier(bytes, 0);
String sidString = sid.ToString();
Console.WriteLine("Max length of SID in String format: {0} ", sidString.Length);
Console.WriteLine(sidString);

Results

SID Min. num Bytes: 8
SID Max. num Bytes: 68
Max length of SID in String format: 184
S-1-281474976710655-4294967295-4294967295-4294967295-4294967295-4294967295-
  4294967295-4294967295-4294967295-4294967295-4294967295-4294967295-
  4294967295-4294967295-4294967295-4294967295 
Emarie answered 24/11, 2009 at 21:8 Comment(1)
Can you explain, why SQL's SUSER_SID returns VARBINARY(85), not (68)?Dubitation
L
2

According to ntseapi_x.h:

typedef struct _SID_IDENTIFIER_AUTHORITY {
    UCHAR Value[6];
} SID_IDENTIFIER_AUTHORITY, *PSID_IDENTIFIER_AUTHORITY; 

typedef struct _SID {
   UCHAR Revision;
   UCHAR SubAuthorityCount;
   SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
   ULONG SubAuthority[ANYSIZE_ARRAY];
} SID, *PISID;
    
#define SID_MAX_SUB_AUTHORITIES          (15)

A UCHAR is actually an unsigned char which is 1 byte. ULONG is an unsigned long which is 4 bytes.

SID's max data size is 68 bytes: UCHAR + UCHAR + (UCHAR * 6) + (ULONG * 15) = 1 + 1 + 6 + 60 = 68

Converting a SID to a string, like what you would get by calling ConvertSidToStringSid, might look something like this: L"S-1-5-21-66"

  • "S-1" <= is the start of all SIDs
    • 3 characters
  • "5" <= is the identifier authority
    • the numbers are printed as decimals normally. One exception is if the authority is larger 4 bytes, then it is printed as hex, eg. 0x1234...
    • So the max value would be "4294967296" or "0xffffffffffff" or 14 characters
  • "21" & "66" <= are sub-authrities
    • Each can be up "4294967296" or 10 characters, with 15 max sub authorities
  • the sections are delimited by a "-"

SID's max string length is 184: 3 + 1 + 14 + 1 + (10 * 15) + 14 = 183, or 184 counting the null.

You may consider just using MAX_UNICODE_STACK_BUFFER_LENGTH or 256 which fits nicely in memory.

Lamia answered 18/11, 2020 at 22:16 Comment(0)
S
1
  1. For string format, the common answer of 184 isn't correct. If authority is between 32 and the maximum of 48 bits, then it must be represented as a hex string, not decimal, and prepended with '0x'. This means instead of a 15-character string needed to represent the maximum 48 bits in decimal, you actually need a (48 bit / 4 bit + 2) 14 character string, meaning (184 - 15 + 14) 183 characters are required for whole SID string. For less than 32 bits, decimal format is used (maximum 10 decimal characters).
Strohbehn answered 31/12, 2018 at 7:15 Comment(1)
Interestingly, even some of MS own code doesn't honour this. The .NET Security.Principal.SecurityIdentifier constructor accepts the hex format, but the ToString() method always outputs in decimal.Strohbehn
P
1

While 184 looks correct, on the official docs there is a different value:

SID - Specifies the security identifier of the domain account. SID is a string with a maximum length of 256 characters.

https://learn.microsoft.com/en-us/windows-hardware/customize/desktop/unattend/microsoft-windows-shell-setup-offlineuseraccounts-offlinedomainaccounts-offlinedomainaccount-sid#:~:text=SID%20is%20a%20string%20with%20a%20maximum%20length%20of%20256%20characters.

Puzzlement answered 18/1, 2022 at 10:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.