Microsoft KB Archive/131320

{|
 * width="100%"|

HOWTO: Convert a Binary SID to Textual Form

 * }

Q131320

-

The information in this article applies to:


 * Microsoft Win32 Application Programming Interface (API), used with:
 * Microsoft Windows NT Server versions 3.1, 3.5, 3.51, 4.0
 * Microsoft Windows NT Workstation versions 3.1, 3.5, 3.51, 4.0
 * the operating system: Microsoft Windows 2000

-

SUMMARY
This article demonstrates how to convert a binary security identifier (SID) to a readable, textual form, for display or manipulation purposes.

MORE INFORMATION
One example of an application that makes use of SIDs in textual form is the Windows NT Event Viewer. If the Event Viewer cannot look up the name associated with the SID of a logged event, the Event Viewer displays a textual representation of the SID.

Windows NT uses textual SIDs when loading user configuration hives into the HKEY_USERS registry key.

Applications that obtain domain and user names can display the textual SID representation when the Win32 LookupAccountSid function cannot obtain domain and user information, which can occur if the network is down or the target computer is unavailable.

Sample Code
The following sample code displays the textual representation of the SID associated with the current user. This source code converts a SID by using the same algorithm that the Windows NT operating system components use.

/*++

A standardized shorthand notation for SIDs makes it simpler to visualize their components:

S-R-I-S-S...

In the notation shown above,

S identifies the series of digits as a SID, R is the revision level, I is the identifier-authority value, S is subauthority value(s).

A SID could be written in this notation as follows: S-1-5-32-544

In this example, the SID has a revision level of 1, an identifier-authority value of 5, first subauthority value of 32, second subauthority value of 544. (Note that the SID represents the local Administrators group.)

The GetTextualSid function converts a binary SID to a textual string.

The resulting string takes one of two forms. If the IdentifierAuthority value is not greater than 2^32, then the SID is in the form:

S-1-5-21-2127521184-1604012920-1887927527-19009

^ ^ ^^ ^^^^^^^^^^ ^^^^^^^^^^ ^^^^^^^^^^ ^^^^^ | | |      |          |          |        |  +-+-+--+--+--++--- Decimal

Otherwise, it will take the form:

S-1-0x206C277C6666-21-2127521184-1604012920-1887927527-19009

^ ^^^^^^^^^^^^^^ ^^ ^^^^^^^^^^ ^^^^^^^^^^ ^^^^^^^^^^ ^^^^^ |       |        |      |          |          |        |  |   Hexadecimal  |      |          |          |        | ++--+--+--++--- Decimal

If the function succeeds, the return value is TRUE. If the function fails, the return value is FALSE. To get extended error information, call the Win32 GetLastError function.

Scott Field (sfield)   11-Jul-95

Unicode enabled

Scott Field (sfield)   15-May-95

--*/


 * 1) include 
 * 2) include 

BOOL GetTextualSid(  PSID     pSid,          // binary Sid   LPSTR    szTextualSid,  // buffer for Textual Sid   LPDWORD  dwBufferLen    // required/provided buffer size );

void main(void) {

HANDLE       hToken         = NULL; PTOKEN_USER  ptgUser        = NULL; DWORD        cbBuffer       = 0; LPSTR        szTextualSid   = NULL; DWORD        cbSid          = 0;

__try {

// Obtain current process token. if (!OpenProcessToken(GetCurrentProcess, TOKEN_QUERY, &hToken)) { fprintf(stderr, "OpenProcessToken failed. Error %d\n",               GetLastError); __leave; }

// Obtain user identified by current process's access token. if (GetTokenInformation(hToken, TokenUser, NULL, 0, &cbBuffer)) {

// Call should have failed due to zero-length buffer. __leave; } else {

// Call should have failed due to zero-length buffer. if (GetLastError != ERROR_INSUFFICIENT_BUFFER) __leave; }

// Allocate buffer for token information. ptgUser = HeapAlloc(GetProcessHeap, HEAP_ZERO_MEMORY,            cbBuffer); if (!ptgUser) __leave;

if (!GetTokenInformation(hToken, TokenUser, ptgUser, cbBuffer, &cbBuffer)) {

fprintf(stderr, "GetTokenInformation failed. Error %d\n",               GetLastError); __leave; }

cbSid = 128; szTextualSid = (LPSTR) HeapAlloc(GetProcessHeap,            HEAP_ZERO_MEMORY, cbSid);

if (!szTextualSid) __leave;

// Obtain the textual representation of the SID. if (!GetTextualSid( ptgUser->User.Sid, // user binary Sid szTextualSid,     // buffer for TextualSid &cbSid)) {      // size/required buffer

fprintf(stderr, "GetTextualSid failed. Error %d\n",               GetLastError); __leave; }

// Display the TextualSid representation. fprintf(stdout, "%s\n", szTextualSid); } __finally {

// Free resources. if (hToken) CloseHandle(hToken);

if (ptgUser) HeapFree(GetProcessHeap, 0, ptgUser);

if (szTextualSid) HeapFree(GetProcessHeap, 0, szTextualSid); }

return; }

BOOL GetTextualSid(PSID pSid, LPSTR szTextualSid,      LPDWORD dwBufferLen) {

PSID_IDENTIFIER_AUTHORITY psia; DWORD dwSubAuthorities; DWORD dwSidRev = SID_REVISION; DWORD dwCounter; DWORD dwSidSize;

// Test if SID passed in is valid. if(!IsValidSid(pSid)) return FALSE;

// Obtain SidIdentifierAuthority. psia = GetSidIdentifierAuthority(pSid);

// Obtain sidsubauthority count. dwSubAuthorities = *GetSidSubAuthorityCount(pSid);

// Compute buffer length. // S-SID_REVISION- + identifierauthority- + subauthorities- + NULL dwSidSize = (15 + 12 + (12 * dwSubAuthorities) + 1) * sizeof(TCHAR);

// Check provided buffer length. // If not large enough, indicate proper size and setlasterror if (*dwBufferLen < dwSidSize) {

*dwBufferLen = dwSidSize; SetLastError(ERROR_INSUFFICIENT_BUFFER); return FALSE; }

// Prepare S-SID_REVISION-. dwSidSize = wsprintf(szTextualSid, TEXT("S-%lu-"), dwSidRev);

// Prepare SidIdentifierAuthority. if ((psia->Value[0] != 0) || (psia->Value[1] != 0)) {

dwSidSize += wsprintf(szTextualSid + lstrlen(szTextualSid),           TEXT("0x%02hx%02hx%02hx%02hx%02hx%02hx"),            (USHORT) psia->Value[0],            (USHORT) psia->Value[1],            (USHORT) psia->Value[2],            (USHORT) psia->Value[3],            (USHORT) psia->Value[4],            (USHORT) psia->Value[5]); } else { dwSidSize += wsprintf(szTextualSid + lstrlen(szTextualSid),           TEXT("%lu"),            (ULONG) (psia->Value[5]      ) +            (ULONG) (psia->Value[4] <<  8) +            (ULONG) (psia->Value[3] << 16) +            (ULONG) (psia->Value[2] << 24)); }

// Loop through SidSubAuthorities. for (dwCounter = 0; dwCounter < dwSubAuthorities; dwCounter++) {

dwSidSize += wsprintf(szTextualSid + dwSidSize, TEXT("-%lu"),           *GetSidSubAuthority(pSid, dwCounter)); }

return TRUE; } Additional query words:

Keywords : kbAPI kbKernBase kbDSupport kbGrpDSKernBase

Issue type : kbhowto

Technology : kbAudDeveloper kbWin32sSearch kbWin32API