Subversion Repositories userdetect2

Rev

Rev 81 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
68 daniel-mar 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;
94
  var dwBufferLen: DWORD): BOOL;
95
var
96
  dwReturnLength: DWORD;
97
  dwTokenUserLength: DWORD;
98
  tic: TTokenInformationClass;
99
  ptu: Pointer;
100
begin
101
  Result := False;
102
  dwReturnLength := 0;
103
  dwTokenUserLength := 0;
104
  tic := TokenUser;
105
  ptu := nil;
106
 
107
  if not GetTokenInformation(hToken, tic, ptu, dwTokenUserLength,
108
    dwReturnLength) then
109
  begin
110
    if GetLastError = ERROR_INSUFFICIENT_BUFFER then
111
    begin
112
      ptu := HeapAlloc(GetProcessHeap, HEAP_ZERO_MEMORY, dwReturnLength);
113
      if ptu = nil then Exit;
114
      dwTokenUserLength := dwReturnLength;
115
      dwReturnLength    := 0;
116
 
117
      if not GetTokenInformation(hToken, tic, ptu, dwTokenUserLength,
118
        dwReturnLength) then Exit;
119
    end
120
    else
121
      Exit;
122
  end;
123
 
124
  if not ConvertSid((PTokenUser(ptu).User).Sid, pszSid, dwBufferLen) then Exit;
125
 
126
  if not HeapFree(GetProcessHeap, 0, ptu) then Exit;
127
 
128
  Result := True;
129
end;
130
 
131
function GetCurrentUserSid: string;
132
var
133
  hAccessToken: THandle;
134
  bSuccess: BOOL;
135
  dwBufferLen: DWORD;
136
  szSid: array[0..260] of Char;
137
begin
138
  Result := '';
139
 
140
  bSuccess := OpenThreadToken(GetCurrentThread, TOKEN_QUERY, True,
141
    hAccessToken);
142
  if not bSuccess then
143
  begin
144
    if GetLastError = ERROR_NO_TOKEN then
145
      bSuccess := OpenProcessToken(GetCurrentProcess, TOKEN_QUERY,
146
        hAccessToken);
147
  end;
148
  if bSuccess then
149
  begin
150
    ZeroMemory(@szSid, SizeOf(szSid));
151
    dwBufferLen := SizeOf(szSid);
152
 
153
    if ObtainTextSid(hAccessToken, szSid, dwBufferLen) then
154
      Result := szSid;
155
    CloseHandle(hAccessToken);
156
  end;
157
end;
158
 
159
end.