Subversion Repositories userdetect2

Rev

Rev 68 | Rev 82 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. (******************************************************************************)
  2. (* SPGetSid - Retrieve the current user's SID in text format                  *)
  3. (*                                                                            *)
  4. (* Copyright (c) 2004 Shorter Path Software                                   *)
  5. (* http://www.shorterpath.com                                                 *)
  6. (******************************************************************************)
  7.  
  8.  
  9. {
  10.   SID is a data structure of variable length that identifies user, group,
  11.   and computer accounts.
  12.   Every account on a network is issued a unique SID when the account is first created.
  13.   Internal processes in Windows refer to an account's SID
  14.   rather than the account's user or group name.
  15. }
  16.  
  17.  
  18. unit SPGetSid;
  19.  
  20. interface
  21.  
  22. uses
  23.   Windows, SysUtils;
  24.  
  25. function GetCurrentUserSid: string;
  26.  
  27. implementation
  28.  
  29. const
  30.   HEAP_ZERO_MEMORY = $00000008;
  31.   SID_REVISION     = 1; // Current revision level
  32.  
  33. type
  34.   PTokenUser = ^TTokenUser;
  35.   TTokenUser = packed record
  36.     User: TSidAndAttributes;
  37.   end;
  38.  
  39. function ConvertSid(Sid: PSID; pszSidText: PChar; var dwBufferLen: DWORD): BOOL;
  40. var
  41.   psia: PSIDIdentifierAuthority;
  42.   dwSubAuthorities: DWORD;
  43.   dwSidRev: DWORD;
  44.   dwCounter: DWORD;
  45.   dwSidSize: DWORD;
  46. begin
  47.   Result := False;
  48.  
  49.   dwSidRev := SID_REVISION;
  50.  
  51.   if not IsValidSid(Sid) then Exit;
  52.  
  53.   psia := GetSidIdentifierAuthority(Sid);
  54.  
  55.   dwSubAuthorities := GetSidSubAuthorityCount(Sid)^;
  56.  
  57.   dwSidSize := (15 + 12 + (12 * dwSubAuthorities) + 1) * SizeOf(Char);
  58.  
  59.   if (dwBufferLen < dwSidSize) then
  60.   begin
  61.     dwBufferLen := dwSidSize;
  62.     SetLastError(ERROR_INSUFFICIENT_BUFFER);
  63.     Exit;
  64.   end;
  65.  
  66.   StrFmt(pszSidText, 'S-%u-', [dwSidRev]);
  67.  
  68.   if (psia.Value[0] <> 0) or (psia.Value[1] <> 0) then
  69.     StrFmt(pszSidText + StrLen(pszSidText),
  70.       '0x%.2x%.2x%.2x%.2x%.2x%.2x',
  71.       [psia.Value[0], psia.Value[1], psia.Value[2],
  72.       psia.Value[3], psia.Value[4], psia.Value[5]])
  73.   else
  74.     StrFmt(pszSidText + StrLen(pszSidText),
  75.       '%u',
  76.       [DWORD(psia.Value[5]) +
  77.       DWORD(psia.Value[4] shl 8) +
  78.       DWORD(psia.Value[3] shl 16) +
  79.       DWORD(psia.Value[2] shl 24)]);
  80.  
  81.   dwSidSize := StrLen(pszSidText);
  82.  
  83.   for dwCounter := 0 to dwSubAuthorities - 1 do
  84.   begin
  85.     StrFmt(pszSidText + dwSidSize, '-%u',
  86.       [GetSidSubAuthority(Sid, dwCounter)^]);
  87.     dwSidSize := StrLen(pszSidText);
  88.   end;
  89.  
  90.   Result := True;
  91. end;
  92.  
  93. function ObtainTextSid(hToken: THandle; pszSid: PChar; var dwBufferLen: DWORD): BOOL;
  94. var
  95.   dwReturnLength: DWORD;
  96.   dwTokenUserLength: DWORD;
  97.   tic: TTokenInformationClass;
  98.   ptu: Pointer;
  99. begin
  100.   Result := False;
  101.   dwReturnLength := 0;
  102.   dwTokenUserLength := 0;
  103.   tic := TokenUser;
  104.   ptu := nil;
  105.  
  106.   if not GetTokenInformation(hToken, tic, ptu, dwTokenUserLength,
  107.     dwReturnLength) then
  108.   begin
  109.     if GetLastError = ERROR_INSUFFICIENT_BUFFER then
  110.     begin
  111.       ptu := HeapAlloc(GetProcessHeap, HEAP_ZERO_MEMORY, dwReturnLength);
  112.       if ptu = nil then Exit;
  113.       dwTokenUserLength := dwReturnLength;
  114.       dwReturnLength    := 0;
  115.  
  116.       if not GetTokenInformation(hToken, tic, ptu, dwTokenUserLength,
  117.         dwReturnLength) then Exit;
  118.     end
  119.     else
  120.       Exit;
  121.   end;
  122.  
  123.   if not ConvertSid((PTokenUser(ptu).User).Sid, pszSid, dwBufferLen) then Exit;
  124.  
  125.   if not HeapFree(GetProcessHeap, 0, ptu) then Exit;
  126.  
  127.   Result := True;
  128. end;
  129.  
  130. function GetCurrentUserSid: string;
  131. var
  132.   hAccessToken: THandle;
  133.   bSuccess: BOOL;
  134.   dwBufferLen: DWORD;
  135.   szSid: array[0..MAX_PATH] of Char;
  136. begin
  137.   Result := '';
  138.  
  139.   bSuccess := OpenThreadToken(GetCurrentThread, TOKEN_QUERY, True,
  140.     hAccessToken);
  141.   if not bSuccess then
  142.   begin
  143.     if GetLastError = ERROR_NO_TOKEN then
  144.       bSuccess := OpenProcessToken(GetCurrentProcess, TOKEN_QUERY,
  145.         hAccessToken);
  146.   end;
  147.   if bSuccess then
  148.   begin
  149.     ZeroMemory(@szSid, SizeOf(szSid));
  150.     dwBufferLen := SizeOf(szSid);
  151.  
  152.     if ObtainTextSid(hAccessToken, szSid, dwBufferLen) then
  153.       Result := szSid;
  154.     CloseHandle(hAccessToken);
  155.   end;
  156. end;
  157.  
  158. end.
  159.