A logon security identifier (SID) identifies the logon session associated with an access token. A typical use of a logon SID is in an ACE that allows access for the duration of a client's logon session. For example, a Windows service can use the LogonUser function to start a new logon session. The LogonUser function returns an access token from which the service can extract the logon SID. The service can then use the SID in an ACE that allows the client's logon session to access the interactive window station and desktop.
The following example gets the logon SID from an access token. It uses the GetTokenInformation function to fill a TOKEN_GROUPS buffer with an array of the group SIDs from an access token. This array includes the logon SID, which is identified by the SE_GROUP_LOGON_ID attribute. The example function allocates a buffer for the logon SID; it is the caller's responsibility to free the buffer.
BOOL?GetLogonSID?(HANDLE?hToken,?PSID?
*
ppsid)?

{
???BOOL?bSuccess?
=
?FALSE;
???DWORD?dwIndex;
???DWORD?dwLength?
=
?
0
;
???PTOKEN_GROUPS?ptg?
=
?NULL;

//
?Verify?the?parameter?passed?in?is?not?NULL.
????
if
?(NULL?
==
?ppsid)
????????
goto
?Cleanup;

//
?Get?required?buffer?size?and?allocate?the?TOKEN_GROUPS?buffer.
???
if
?(
!
GetTokenInformation(
?????????hToken,?????????
//
?handle?to?the?access?token
?????????TokenGroups,????
//
?get?information?about?the?token's?groups?
?????????(LPVOID)?ptg,???
//
?pointer?to?TOKEN_GROUPS?buffer
?????????
0
,??????????????
//
?size?of?buffer
?????????
&
dwLength???????
//
?receives?required?buffer?size
??????))?

???
{
??????
if
?(GetLastError()?
!=
?ERROR_INSUFFICIENT_BUFFER)?
?????????
goto
?Cleanup;

??????ptg?
=
?(PTOKEN_GROUPS)HeapAlloc(GetProcessHeap(),
?????????HEAP_ZERO_MEMORY,?dwLength);

??????
if
?(ptg?
==
?NULL)
?????????
goto
?Cleanup;
???}
//
?Get?the?token?group?information?from?the?access?token.
???
if
?(
!
GetTokenInformation(
?????????hToken,?????????
//
?handle?to?the?access?token
?????????TokenGroups,????
//
?get?information?about?the?token's?groups?
?????????(LPVOID)?ptg,???
//
?pointer?to?TOKEN_GROUPS?buffer
?????????dwLength,???????
//
?size?of?buffer
?????????
&
dwLength???????
//
?receives?required?buffer?size
?????????))?

???
{
??????
goto
?Cleanup;
???}
//
?Loop?through?the?groups?to?find?the?logon?SID.
???
for
?(dwIndex?
=
?
0
;?dwIndex?
<
?ptg
->
GroupCount;?dwIndex
++
)?
??????
if
?((ptg
->
Groups[dwIndex].Attributes?
&
?SE_GROUP_LOGON_ID)
?????????????
==
??SE_GROUP_LOGON_ID)?

??????
{
??????
//
?Found?the?logon?SID;?make?a?copy?of?it.
?????????dwLength?
=
?GetLengthSid(ptg
->
Groups[dwIndex].Sid);
?????????
*
ppsid?
=
?(PSID)?HeapAlloc(GetProcessHeap(),
?????????????????????HEAP_ZERO_MEMORY,?dwLength);
?????????
if
?(
*
ppsid?
==
?NULL)
?????????????
goto
?Cleanup;
?????????
if
?(
!
CopySid(dwLength,?
*
ppsid,?ptg
->
Groups[dwIndex].Sid))?

?????????
{
?????????????HeapFree(GetProcessHeap(),?
0
,?(LPVOID)
*
ppsid);
?????????????
goto
?Cleanup;
?????????}
?????????
break
;
??????}
???bSuccess?
=
?TRUE;

Cleanup:?

//
?Free?the?buffer?for?the?token?groups.
???
if
?(ptg?
!=
?NULL)
??????HeapFree(GetProcessHeap(),?
0
,?(LPVOID)ptg);

???
return
?bSuccess;
}
The following function frees the buffer allocated by the
GetLogonSID example function.
VOID?FreeLogonSID?(PSID?*ppsid)?


{
????HeapFree(GetProcessHeap(),?0,?(LPVOID)*ppsid);
}
