A SID is a large integer which identifies:
printf( "S-%d-%d", version_number, top_level_authority ) ; while ( subauthority ) printf ("-%d", subauthority++ ) ;The version_number is 1. The top_level_authority is:
Users, Local and Global groups follow a containment diagram:
Local Group / \ Local User Global Group in trusted domain \ User in same domainThat is, Local groups can contain either global groups from a trusted domain, or users of the local domain. Global Groups can contain users in the same domain as the global group (the relative part of the sids must match). A user token is derived by taking the sids of all containing groups for the user sid in the above containment diagram.
The purpose of all of this is to accumulate permissions for the token. Permissions are attached to sids, with some restrictions as to the type of permissions appropriate to each type of sid. None of this do I understand. The permission of a token is the union of all permissions of its contained sids, containment considered according to the above diagram.
My token contains these sids:
U: S-1-5-21-1179599015-1994013950-622671684-1841 G: S-1-5-21-1179599015-1994013950-622671684-1202 G: S-1-5-21-1179599015-1994013950-622671684-513 G: S-1-5-21-1179599015-1994013950-622671684-1269 G: S-1-5-32-544 G: S-1-5-32-545 G: S-1-5-5-0-8850 G: S-1-5-4 G: S-1-5-11 G: S-1-1-0 G: S-1-2-0Note that 1179599015-1994013950-622671684 is the develop domain sid. This reads: the user is number 1841 in the develop domain, is a member of groups 1202, 513 and 1269 in this domain, is a member of local groups 544 and 545 (Adminstrators and Users), is assigned logon ID 0-8850, is interactive, is authenticated, is a member of the world and network groups.
#include<stdio.h> #include<string.h> #include<windows.h> #include<assert.h> /* * Burton Rosenberg * 17 March 1999 * */ PVOID getInfoFromToken( HANDLE hToken, TOKEN_INFORMATION_CLASS tokenInfoClass, void ** buffer ) { int len ; PVOID buf ; PVOID p ; *buffer = NULL ; len = 0 ; p = NULL ; GetTokenInformation( hToken, tokenInfoClass, NULL, 0, &len ) ; if ( (len==0) || !(buf = malloc(len)) ) return NULL ; if ( GetTokenInformation( hToken, tokenInfoClass, buf, len, &len ) ) { p = buf ; } *buffer = buf ; return p ; } PTOKEN_GROUPS getGroupsFromToken( HANDLE hToken, void ** buffer ) { return (PTOKEN_GROUPS) getInfoFromToken( hToken, TokenGroups, buffer ) ; } PSID getSidFromGroups( PTOKEN_GROUPS pTokenGroups, int index ) { if ( index<0 || pTokenGroups->GroupCount<=index ) return NULL ; return pTokenGroups->Groups[index].Sid ; } PSID getSidFromToken ( HANDLE hToken, void ** buffer ) { TOKEN_USER * pTokenUser ; PSID pSid ; pSid = NULL ; pTokenUser = (TOKEN_USER *) getInfoFromToken( hToken, TokenUser, buffer ) ; if ( pTokenUser ) { pSid = pTokenUser->User.Sid ; } return pSid ; } #define WIDEST_NUMBER 10 int sprint_Sid ( char * buf, int size, PSID pSid ) { int subAuthCount, i ; int needed_length ; char shortBuf[WIDEST_NUMBER+1] ; subAuthCount = *GetSidSubAuthorityCount(pSid) ; /* room for "S-1-" topauthority ( "-" subauthority ) ** subAuthCount * + NULL * */ needed_length = subAuthCount*WIDEST_NUMBER + WIDEST_NUMBER + subAuthCount + 5 ; if ( !buf || (needed_length>size) ) { if ( buf && size>0 ) buf[0] = '\0' ; return needed_length ; } sprintf( buf, "S-1-%d", GetSidIdentifierAuthority(pSid)->Value[5] ) ; for ( i=0; i<subAuthCount; i++ ) { sprintf( shortBuf, "-%d", *GetSidSubAuthority( pSid, i ) ) ; strcat( buf, shortBuf ) ; } return 0 ; } int main(int argc, char * argv[]) { HANDLE hToken ; PSID pSid ; PVOID buf ; PTOKEN_GROUPS pGroups ; char cs[5000] ; int i ; if ( !OpenProcessToken( GetCurrentProcess(), TOKEN_ALL_ACCESS, &hToken )) { printf("did not get token\n") ; return 0 ; } pSid = getSidFromToken( hToken, &buf ) ; if ( !pSid ) { printf("did not get SID from Token\n") ; return 0 ; } sprint_Sid( cs, sizeof(cs), pSid ) ; printf("U: %s\n", cs ) ; free(buf) ; pGroups = getGroupsFromToken( hToken, &buf ) ; if ( !pGroups ) { printf("did not get Groups from Token\n") ; return 0 ; } i = 0 ; while ( pSid = getSidFromGroups( pGroups, i++ ) ) { sprint_Sid( cs, sizeof(cs), pSid ) ; printf( "G: %s\n", cs ) ; } free(buf) ; }