home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / winbase / security / winnt / textsid / textsid.c < prev    next >
C/C++ Source or Header  |  1997-10-05  |  8KB  |  291 lines

  1. /*++
  2.  
  3. Copyright 1996 - 1997 Microsoft Corporation
  4.  
  5. Module Name:
  6.  
  7.     textsid.c
  8.  
  9. Abstract:
  10.  
  11.     This module illustrates how to obtain the textual representation
  12.     of a binary Sid.  This is useful in scenarios where it is not appropriate
  13.     to obtain the name associated with the Sid, or, when the network is not
  14.     available to obtain such information.  The Windows NT event viewer
  15.     utility displays Sids in textual form when the username cannot be
  16.     looked up.  Furthermore, lookup of local user profiles is facilitated
  17.     through conversion of the user Sid to textual form.
  18.  
  19.     This sample obtains the Sid of the current user and then displays the
  20.     Sid in textual notation.
  21.  
  22.     A standardized shorthand notation for SIDs makes it simpler to
  23.     visualize their components:
  24.  
  25.     S-R-I-S-S...
  26.  
  27.     In the notation shown above,
  28.  
  29.     S identifies the series of digits as an SID,
  30.     R is the revision level,
  31.     I is the identifier-authority value,
  32.     S is subauthority value(s).
  33.  
  34.     An SID could be written in this notation as follows:
  35.     S-1-5-32-544
  36.  
  37.     In this example,
  38.     the SID has a revision level of 1,
  39.     an identifier-authority value of 5,
  40.     first subauthority value of 32,
  41.     second subauthority value of 544.
  42.     (Note that the above Sid represents the local Administrators group)
  43.  
  44.     The GetTextualSid() function will convert a binary Sid to a textual
  45.     string.
  46.  
  47.     The resulting string will take one of two forms.  If the
  48.     IdentifierAuthority value is not greater than 2^32, then the SID
  49.     will be in the form:
  50.  
  51.     S-1-5-21-2127521184-1604012920-1887927527-19009
  52.       ^ ^ ^^ ^^^^^^^^^^ ^^^^^^^^^^ ^^^^^^^^^^ ^^^^^
  53.       | | |      |          |          |        |
  54.       +-+-+------+----------+----------+--------+--- Decimal
  55.  
  56.     Otherwise it will take the form:
  57.  
  58.     S-1-0x206C277C6666-21-2127521184-1604012920-1887927527-19009
  59.       ^ ^^^^^^^^^^^^^^ ^^ ^^^^^^^^^^ ^^^^^^^^^^ ^^^^^^^^^^ ^^^^^
  60.       |       |        |      |          |          |        |
  61.       |   Hexidecimal  |      |          |          |        |
  62.       +----------------+------+----------+----------+--------+--- Decimal
  63.  
  64.     If the function succeeds, the return value is TRUE.
  65.     If the function fails, the return value is FALSE.  To get extended
  66.         error information, call the Win32 API GetLastError().
  67.  
  68. Author:
  69.  
  70.     Scott Field (sfield)    13-Apr-96
  71.  
  72. Revision History:
  73.  
  74.     Scott Field (sfield)    11-Jul-95
  75.     Unicode enabled
  76.  
  77.     Scott Field (sfield)    15-May-95
  78. --*/
  79.  
  80. #define RTN_OK 0
  81. #define RTN_ERROR 13
  82.  
  83. #include <windows.h>
  84. #include <stdio.h>
  85.  
  86. BOOL
  87. GetTextualSid(
  88.     PSID pSid,          // binary Sid
  89.     LPTSTR TextualSID,  // buffer for Textual representaion of Sid
  90.     LPDWORD cchSidSize  // required/provided TextualSid buffersize
  91.     );
  92.  
  93. void
  94. DisplayWinError(
  95.     LPSTR szAPI,    // pointer to Ansi function name
  96.     DWORD dwError   // DWORD WinError
  97.     );
  98.  
  99. int
  100. __cdecl
  101. main(
  102.     void
  103.     )
  104. {
  105. #define MY_BUFSIZE 256 // all allocations should be dynamic
  106.     HANDLE hToken;
  107.     BYTE buf[MY_BUFSIZE];
  108.     PTOKEN_USER ptgUser = (PTOKEN_USER)buf;
  109.     DWORD cbBuffer=MY_BUFSIZE;
  110.  
  111.     TCHAR szTextualSid[MY_BUFSIZE];
  112.     DWORD cchSid=MY_BUFSIZE;
  113.  
  114.     BOOL bSuccess;
  115.  
  116.     //
  117.     // obtain current process token
  118.     //
  119.     if(!OpenProcessToken(
  120.                 GetCurrentProcess(), // target current process
  121.                 TOKEN_QUERY,         // TOKEN_QUERY access
  122.                 &hToken              // resultant hToken
  123.                 ))
  124.     {
  125.         DisplayWinError("OpenProcessToken", GetLastError());
  126.         return RTN_ERROR;
  127.     }
  128.  
  129.     //
  130.     // obtain user identified by current process' access token
  131.     //
  132.     bSuccess = GetTokenInformation(
  133.                 hToken,    // identifies access token
  134.                 TokenUser, // TokenUser info type
  135.                 ptgUser,   // retrieved info buffer
  136.                 cbBuffer,  // size of buffer passed-in
  137.                 &cbBuffer  // required buffer size
  138.                 );
  139.  
  140.     // close token handle.  do this even if error above
  141.     CloseHandle(hToken);
  142.  
  143.     if(!bSuccess) {
  144.         DisplayWinError("GetTokenInformation", GetLastError());
  145.         return RTN_ERROR;
  146.     }
  147.  
  148.     //
  149.     // obtain the textual representaion of the Sid
  150.     //
  151.     if(!GetTextualSid(
  152.                 ptgUser->User.Sid, // user binary Sid
  153.                 szTextualSid,      // buffer for TextualSid
  154.                 &cchSid            // size/required buffer
  155.                 )) {
  156.         DisplayWinError("GetTextualSid", GetLastError());
  157.         return RTN_ERROR;
  158.     }
  159.  
  160.     // display the TextualSid representation
  161.     printf("%s\n", szTextualSid);
  162.  
  163.     return RTN_OK;
  164. }
  165.  
  166. BOOL
  167. GetTextualSid(
  168.     PSID pSid,          // binary Sid
  169.     LPTSTR TextualSid,  // buffer for Textual representaion of Sid
  170.     LPDWORD cchSidSize  // required/provided TextualSid buffersize
  171.     )
  172. {
  173.     PSID_IDENTIFIER_AUTHORITY psia;
  174.     DWORD dwSubAuthorities;
  175.     DWORD dwCounter;
  176.     DWORD cchSidCopy;
  177.  
  178.     //
  179.     // test if Sid passed in is valid
  180.     //
  181.     if(!IsValidSid(pSid)) return FALSE;
  182.  
  183.     // obtain SidIdentifierAuthority
  184.     psia = GetSidIdentifierAuthority(pSid);
  185.  
  186.     // obtain sidsubauthority count
  187.     dwSubAuthorities = *GetSidSubAuthorityCount(pSid);
  188.  
  189.     //
  190.     // compute approximate buffer length
  191.     // S-SID_REVISION- + identifierauthority- + subauthorities- + NULL
  192.     //
  193.     cchSidCopy = (15 + 12 + (12 * dwSubAuthorities) + 1) * sizeof(TCHAR);
  194.  
  195.     //
  196.     // check provided buffer length.
  197.     // If not large enough, indicate proper size and setlasterror
  198.     //
  199.     if(*cchSidSize < cchSidCopy) {
  200.         *cchSidSize = cchSidCopy;
  201.         SetLastError(ERROR_INSUFFICIENT_BUFFER);
  202.         return FALSE;
  203.     }
  204.  
  205.     //
  206.     // prepare S-SID_REVISION-
  207.     //
  208.     cchSidCopy = wsprintf(TextualSid, TEXT("S-%lu-"), SID_REVISION );
  209.  
  210.     //
  211.     // prepare SidIdentifierAuthority
  212.     //
  213.     if ( (psia->Value[0] != 0) || (psia->Value[1] != 0) ) {
  214.         cchSidCopy += wsprintf(TextualSid + cchSidCopy,
  215.                     TEXT("0x%02hx%02hx%02hx%02hx%02hx%02hx"),
  216.                     (USHORT)psia->Value[0],
  217.                     (USHORT)psia->Value[1],
  218.                     (USHORT)psia->Value[2],
  219.                     (USHORT)psia->Value[3],
  220.                     (USHORT)psia->Value[4],
  221.                     (USHORT)psia->Value[5]);
  222.     } else {
  223.         cchSidCopy += wsprintf(TextualSid + cchSidCopy,
  224.                     TEXT("%lu"),
  225.                     (ULONG)(psia->Value[5]      )   +
  226.                     (ULONG)(psia->Value[4] <<  8)   +
  227.                     (ULONG)(psia->Value[3] << 16)   +
  228.                     (ULONG)(psia->Value[2] << 24)   );
  229.     }
  230.  
  231.     //
  232.     // loop through SidSubAuthorities
  233.     //
  234.     for(dwCounter = 0 ; dwCounter < dwSubAuthorities ; dwCounter++) {
  235.         cchSidCopy += wsprintf(TextualSid + cchSidCopy, TEXT("-%lu"),
  236.                     *GetSidSubAuthority(pSid, dwCounter) );
  237.     }
  238.  
  239.     //
  240.     // tell the caller how many chars we provided, not including NULL
  241.     //
  242.     *cchSidSize = cchSidCopy;
  243.  
  244.     return TRUE;
  245. }
  246.  
  247. void
  248. DisplayWinError(
  249.     LPSTR szAPI,    // pointer to Ansi function name
  250.     DWORD dwError   // DWORD WinError
  251.     )
  252. {
  253.     LPSTR MessageBuffer;
  254.     DWORD dwBufferLength;
  255.  
  256.     //
  257.     // TODO get this fprintf out of here!
  258.     //
  259.     fprintf(stderr,"%s error!\n", szAPI);
  260.  
  261.     if(dwBufferLength=FormatMessageA(
  262.             FORMAT_MESSAGE_ALLOCATE_BUFFER |
  263.             FORMAT_MESSAGE_FROM_SYSTEM,
  264.             NULL,
  265.             dwError,
  266.             MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  267.             (LPSTR) &MessageBuffer,
  268.             0,
  269.             NULL
  270.             ))
  271.     {
  272.         DWORD dwBytesWritten; // unused
  273.  
  274.         //
  275.         // Output message string on stderr
  276.         //
  277.         WriteFile(
  278.                 GetStdHandle(STD_ERROR_HANDLE),
  279.                 MessageBuffer,
  280.                 dwBufferLength,
  281.                 &dwBytesWritten,
  282.                 NULL
  283.                 );
  284.  
  285.         //
  286.         // free the buffer allocated by the system
  287.         //
  288.         LocalFree(MessageBuffer);
  289.     }
  290. }
  291.