Click here to Skip to main content
15,892,298 members
Articles / Programming Languages / C++

Converting SIDs between strings and binary

Rate me:
Please Sign up or sign in to vote.
4.29/5 (4 votes)
17 Dec 20011 min read 90.5K   742   19  
How to convert SIDs between string and binary representations
#include "stdafx.h"
#include "SidFunc.h"

//***********************************************
PSID GetBinarySid(LPCTSTR szSid)
{
	// This function is based off the KB article Q198907.
	// This function is the same as ConvertStringSidToSid(),
	// except that function is only on Windows 2000 and newer.
	// The calling function must free the returned SID with FreeSid.

	_ASSERTE(szSid);
	_ASSERTE(lstrlen(szSid));

	PSID pSid = NULL;
	LPTSTR szSidCopy = NULL;

	try
	{
		int i;
		LPTSTR ptr, ptr1;
		SID_IDENTIFIER_AUTHORITY sia; ZeroMemory(&sia, sizeof(sia));
		BYTE nByteAuthorityCount = 0;
		DWORD dwSubAuthority[8] = {0, 0, 0, 0, 0, 0, 0, 0};

		szSidCopy = new TCHAR[lstrlen(szSid) + 1];
		lstrcpy(szSidCopy, szSid);

		// S-SID_REVISION- + IdentifierAuthority- + subauthorities- + NULL

		// Skip 'S'
		if(!(ptr = _tcschr(szSidCopy, _T('-'))))
			return NULL;

		// Skip '-'
		ptr++;

		// Skip SID_REVISION
		if(!(ptr = _tcschr(ptr, _T('-'))))
			return NULL;

		// Skip '-'
		ptr++;

		// Skip IdentifierAuthority
		if(!(ptr1 = _tcschr(ptr, _T('-'))))
			return NULL;
		*ptr1= 0;

		if((*ptr == _T('0')) && (*(ptr + 1) == _T('x')))
		{
			_stscanf(ptr, _T("0x%02hx%02hx%02hx%02hx%02hx%02hx"),
				&sia.Value[0],
				&sia.Value[1],
				&sia.Value[2],
				&sia.Value[3],
				&sia.Value[4],
				&sia.Value[5]);
		}
		else
		{
			DWORD dwValue;
			_stscanf(ptr, _T("%lu"), &dwValue);

			sia.Value[5] = (BYTE)(dwValue & 0x000000FF);
			sia.Value[4] = (BYTE)(dwValue & 0x0000FF00) >> 8;
			sia.Value[3] = (BYTE)(dwValue & 0x00FF0000) >> 16;
			sia.Value[2] = (BYTE)(dwValue & 0xFF000000) >> 24;
		}

		// Skip '-'
		*ptr1 = '-';
		ptr = ptr1;
		ptr1++;

		for(i = 0; i < 8; i++)
		{
			// Get subauthority
			if(!(ptr = _tcschr(ptr, _T('-'))))
				break;
			*ptr = 0;
			ptr++;
			nByteAuthorityCount++;
		}

		for(i = 0; i < nByteAuthorityCount; i++)
		{
			// Get subauthority
			_stscanf(ptr1, _T("%lu"), &dwSubAuthority[i]);
			ptr1 += lstrlen(ptr1) + 1;
		}
		delete[] szSidCopy;
		szSidCopy = NULL;

		if(!AllocateAndInitializeSid(&sia,
			nByteAuthorityCount,
			dwSubAuthority[0],
			dwSubAuthority[1],
			dwSubAuthority[2],
			dwSubAuthority[3],
			dwSubAuthority[4],
			dwSubAuthority[5],
			dwSubAuthority[6],
			dwSubAuthority[7],
			&pSid))
		{
			pSid = NULL;
		}
	}
	catch(...)
	{
		delete[] szSidCopy;
		pSid = NULL;
	}

	return pSid;
}

//***********************************************
bool GetTextualSid(const PSID pSid, LPTSTR szSid, DWORD &dwBufferSize)
{
	// This function is based off the KB article Q131320.
	// This function is the same as ConvertSidToStringSid(),
	// except that function is only on Windows 2000 and newer.

	_ASSERTE(pSid);
	_ASSERTE(szSid);

	bool bRtnVal = true;

	try
	{
		PSID_IDENTIFIER_AUTHORITY psia;
		DWORD dwSidSize, dwSubAuthorities;

		// Validate the binary SID
		if(!IsValidSid(pSid))
			return false;

		// Get the identifier authority value from the SID
		psia = GetSidIdentifierAuthority(pSid);

		// Get the number of subauthorities in the SID.
		dwSubAuthorities = *GetSidSubAuthorityCount(pSid);

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

		// Was the provided buffer large enough?
		if(dwBufferSize < dwSidSize)
		{
			dwBufferSize = dwSidSize;
			SetLastError(ERROR_INSUFFICIENT_BUFFER);
			return false;
		}

		// Add 'S' prefix and revision number to the string
		dwSidSize = _stprintf(szSid, _T("S-%lu-"), SID_REVISION);

		// Add SID identifier authority to the string.
		if((psia->Value[0] != 0) || (psia->Value[1] != 0))
		{
			dwSidSize += _stprintf(szSid + lstrlen(szSid),
				_T("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 += _stprintf(szSid + lstrlen(szSid),
				_T("%lu"),
				(ULONG)(psia->Value[5]) +
				(ULONG)(psia->Value[4] << 8) +
				(ULONG)(psia->Value[3] << 16) +
				(ULONG)(psia->Value[2] << 24) );
		}

		// Add SID subauthorities to the string
		for(DWORD dwCounter = 0; dwCounter < dwSubAuthorities; dwCounter++)
		{
			dwSidSize += _stprintf(szSid + dwSidSize, _T("-%lu"),
				*GetSidSubAuthority(pSid, dwCounter));
		}
	}
	catch(...)
	{
		bRtnVal = false;
	}

	return bRtnVal;
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions