#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;
}