HOWTO: Convert a Binary SID to Textual Form |
Q131320
This article demonstrates how to convert a binary security identifier (SID) to a readable, textual form, for display or manipulation purposes.
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.
/*++
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
--*/
#include <windows.h>
#include <stdio.h>
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
|
Last Reviewed: November 22, 2000 © 2001 Microsoft Corporation. All rights reserved. Terms of Use. |