Subversion Repositories userdetect2

Rev

Rev 68 | Rev 82 | Go to most recent revision | Details | Compare with Previous | 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
 
81 daniel-mar 93
function ObtainTextSid(hToken: THandle; pszSid: PChar; var dwBufferLen: DWORD): BOOL;
68 daniel-mar 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;
81 daniel-mar 135
  szSid: array[0..MAX_PATH] of Char;
68 daniel-mar 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.