Author: Stewart Moss
Some useful Windows NT functions
Answer:
1
2 {-----------------------------------------------------------------------------
3 Unit Name: unitNTFunctions
4 Author: StewartM
5
6 Documentation Date: 22 February, 2002 (11:04)
7
8 Version 1.0
9 -----------------------------------------------------------------------------
10
11 Purpose:
12 To provide a few handy Windows NT API functions.
13
14 Description:
15
16 Unit written by Stewart Moss (except where indicated)
17 Some of the functions are incomplete or not tested.
18
19 Copyright 2001 by Stewart Moss. All rights reserved.
20 -----------------------------------------------------------------------------}
21
22 unit unitNTFunctions;
23 // Unit written by Stewart Moss (except where indicated)
24
25 interface
26 uses
27 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
28 StdCtrls;
29
30 const
31 BSECURITY_NULL_SID_AUTHORITY = 0;
32 BSECURITY_WORLD_SID_AUTHORITY = 1;
33 BSECURITY_LOCAL_SID_AUTHORITY = 2;
34 BSECURITY_CREATOR_SID_AUTHORITY = 3;
35 BSECURITY_NT_AUTHORITY = 5;
36
37 SECURITY_INTERACTIVE_RID = $00000004;
38 SECURITY_BUILTIN_DOMAIN_RID = $00000020;
39 DOMAIN_ALIAS_RID_ADMINS = $00000220;
40
41 ACL_REVISION = 2;
42 SECURITY_DESCRIPTOR_REVISION = 1;
43
44 type
45 PACE_Header = ^TACE_Header;
46 TACE_Header = record
47 AceType: BYTE;
48 AceFlags: BYTE;
49 AceSize: WORD;
50 end;
51
52 PAccess_Allowed_ACE = ^TAccess_Allowed_ACE;
53 TAccess_Allowed_ACE = record
54 Header: TACE_Header;
55 Mask: ACCESS_MASK;
56 SidStart: DWORD;
57 end;
58 const
59 SECURITY_NT_AUTHORITY: TSIDIdentifierAuthority =
60 (Value: (0, 0, 0, 0, 0, 5));
61
62 function ISHandleAdministrator(UserToken: THandle): Boolean;
63 function IsAdmin: Boolean;
64 function ReturnUserHandle(Username: string): THandle;
65 function IsWinNT: boolean;
66
67 function TryToLoginAsUser(Username, Domain, Password: string): THandle;
68
69 implementation
70
71 function ISHandleAdministrator(UserToken: THandle): Boolean;
72 // this function written by Stewart Moss
73 var
74 tmpBuffer: array[0..1024] of char;
75 BufferPtr: Pointer;
76 ptgGroups: PTokenGroups;
77 dwInfoBufferSize: DWord;
78 PSIDAdministrators: PSID;
79 siaNTAuthority: SID_IDENTIFIER_AUTHORITY;
80 X: DWord;
81 bSuccess: Boolean;
82
83 begin
84 GetMem(PtgGroups, 1024);
85
86 bSuccess := GetTokenInformation(UserToken, TokenGroups, ptgGroups,
87 1024, dwInfoBufferSize);
88 result := false;
89 if not bsuccess then
90 exit;
91
92 if not AllocateAndInitializeSid(siaNtAuthority, 2,
93 SECURITY_BUILTIN_DOMAIN_RID,
94 DOMAIN_ALIAS_RID_ADMINS,
95 0, 0, 0, 0, 0, 0,
96 psidAdministrators) then
97 exit;
98
99 for x := 0 to ptgGroups.GroupCount do
100 begin
101 if EqualSID(psidAdministrators, ptgGroups.Groups[x].SID) then
102 begin
103 result := true;
104 break;
105 end;
106 end;
107 freemem(PtgGroups);
108 Freemem(PsidAdministrators);
109 result := true;
110 end;
111
112 function IsAdmin: Boolean;
113 // This function written by somebody else
114 var
115 hAccessToken: THandle;
116 ptgGroups: PTokenGroups;
117 dwInfoBufferSize: DWORD;
118 psidAdministrators: PSID;
119 x: Integer;
120 bSuccess: BOOL;
121 begin
122 Result := False;
123 bSuccess := OpenThreadToken(GetCurrentThread, TOKEN_QUERY, True,
124 hAccessToken);
125 if not bSuccess then
126 begin
127 if GetLastError = ERROR_NO_TOKEN then
128 bSuccess := OpenProcessToken(GetCurrentProcess, TOKEN_QUERY,
129 hAccessToken);
130 end;
131 if bSuccess then
132 begin
133 GetMem(ptgGroups, 1024);
134 bSuccess := GetTokenInformation(hAccessToken, TokenGroups,
135 ptgGroups, 1024, dwInfoBufferSize);
136 CloseHandle(hAccessToken);
137 if bSuccess then
138 begin
139 AllocateAndInitializeSid(SECURITY_NT_AUTHORITY, 2,
140 SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS,
141 0, 0, 0, 0, 0, 0, psidAdministrators);
142 {$R-}
143 for x := 0 to ptgGroups.GroupCount - 1 do
144 if EqualSid(psidAdministrators, ptgGroups.Groups[x].Sid) then
145 begin
146 Result := True;
147 Break;
148 end;
149 {$R+}
150 FreeSid(psidAdministrators);
151 end;
152 FreeMem(ptgGroups);
153 end;
154 end;
155
156 function ReturnUserHandle(Username: string): THandle;
157 // Function written by Stewart Moss
158 begin
159
160 end;
161
162 function IsWinNT: boolean;
163 // Function Written by Stewart Moss
164 var
165 osv: TOSVERSIONINFO;
166 begin
167 result := false;
168 osv.dwOSVersionInfoSize := sizeOf(OSVERSIONINFO);
169 GetVersionEx(osv);
170 if (osv.dwPlatformId = VER_PLATFORM_WIN32_NT) then
171 result := true;
172 end;
173
174 function TryToLoginAsUser(Username, Domain, Password: string): THandle;
175 // Function written by Stewart Moss
176 // returns 0 if failed else User Handle
177 var
178 tmpstr: string;
179 hToken: THandle;
180 begin
181 result := 0;
182
183 if (UserName = '') or (Domain = '') then
184 exit;
185
186 if not LogonUser(PChar(Username), Pchar(Domain), PChar(Password),
187 LOGON32_LOGON_INTERACTIVE,
188 LOGON32_PROVIDER_DEFAULT, hToken) then
189 exit;
190 result := hToken;
191 end;
192
193 (*function ApplySecurityDescriptorToRegistryKey(Key : Hkey): Boolean;
194 var lRv : longint;
195 siaNtAuthority : SID_IDENTIFIER_AUTHORITY;
196 psidSystem, psidAdministrators: PSID;
197 tmpACL : ACL;
198 pNewDACL : PACL;
199 dwACL : DWord;
200 ACLRevision : ACL_REVISION_INFORMATION;
201 begin
202 siaNtAuthority := SECURITY_NT_AUTHORITY;
203 result := false;
204 InitializeSid(psidAdministrators, siaNtAuthority,2);
205 InitializeSid(psidSystem, siaNtAuthority,1);
206
207 //*(GetSidSubAuthority(psidAdministrators,0)) = SECURITY_BUILTIN_DOMAIN_RID;
208 //*(GetSidSubAuthority(psidAdministrators,1)) = DOMAIN_ALIAS_RID_ADMINS;
209 //*(GetSidSubAuthority(psidSystem,0)) = SECURITY_LOCAL_SYSTEM_RID;
210
211 // getmem(pNewDACL, sizeof(PACL));
212 // pNewDACL := tmpAcl;
213
214 dwAcl := sizeof(PACL);
215
216 if not GETAclInformation(pnewAcl,
217
218 if (not InitializeAcl(pnewDACL,
219 dwACL,
220 ACL_REVISION)) then exit;
221
222 if (!AddAccessAllowedAce(pNewDACL,
223 ACL_REVISION,
224 KEY_ALL_ACCESS,
225 psidAdministrators)) return FALSE;
226
227 if (!AddAccessAllowedAce(pNewDACL,
228 ACL_REVISION,
229 KEY_ALL_ACCESS,
230 psidSystem)) return FALSE;
231
232 if (!InitializeSecurityDescriptor(psdAbsoluteSD,
233 SECURITY_DESCRIPTOR_REVISION)) return FALSE;
234
235 if (!SetSecurityDescriptorDacl(psdAbsoluteSD,
236 TRUE, // fDaclPresent flag
237 pNewDACL,
238 FALSE)) // not a default DACL
239 return FALSE;
240
241 if (!IsValidSecurityDescriptor(psdAbsoluteSD)) return FALSE;
242
243 lRv=RegSetKeySecurity(hKey,
244 (SECURITY_INFORMATION)(DACL_SECURITY_INFORMATION),
245 psdAbsoluteSD);
246 if (lRv!=ERROR_SUCCESS) return FALSE;
247
248 return TRUE;
249 }
250
251 *)
252
253 function do_SetRegACL: boolean;
254 var
255 sia: TSIDIdentifierAuthority;
256 pInteractiveSid, pAdministratorsSid: PSID;
257 sd: Windows.TSecurityDescriptor;
258 pDacl: PACL;
259 dwAclSize: DWORD;
260 aHKey: HKEY;
261 lRetCode: longint;
262 bSuccess: boolean;
263 begin
264
265 sia.Value[0] := 0;
266 sia.Value[1] := 0;
267 sia.Value[2] := 0;
268 sia.Value[3] := 0;
269 sia.Value[4] := 0;
270 sia.Value[5] := BSECURITY_NT_AUTHORITY;
271 pInteractiveSid := nil;
272 pAdministratorsSid := nil;
273 pDacl := nil;
274
275 bSuccess := false; // assume this function fails
276
277 //
278 // open the key for WRITE_DAC access
279 //
280 lRetCode := RegOpenKeyEx(
281 HKEY_CURRENT_USER,
282 'SOFTWARE\Test',
283 0,
284 WRITE_DAC,
285 aHKey
286 );
287
288 if (lRetCode <> ERROR_SUCCESS) then
289 begin
290 ShowMessage('Error in RegOpenKeyEx');
291 result := false;
292 end;
293
294 //
295 // prepare a Sid representing any Interactively logged-on user
296 //
297 if (not AllocateAndInitializeSid(
298 sia,
299 1,
300 SECURITY_INTERACTIVE_RID,
301 0, 0, 0, 0, 0, 0, 0,
302 pInteractiveSid
303 )) then
304 begin
305 ShowMessage('Error in: AllocateAndInitializeSid');
306 //goto cleanup;
307 end;
308
309 //
310 // prepare a Sid representing the well-known admin group
311 //
312 if (not AllocateAndInitializeSid(
313 sia,
314 2,
315 SECURITY_BUILTIN_DOMAIN_RID,
316 DOMAIN_ALIAS_RID_ADMINS,
317 0, 0, 0, 0, 0, 0,
318 pAdministratorsSid
319 )) then
320 begin
321 ShowMessage('Error in: AllocateAndInitializeSid');
322 // goto cleanup;
323 end;
324
325 //
326 // compute size of new acl
327 //
328 dwAclSize := sizeof(TACL) +
329 2 * (sizeof(TAccess_Allowed_ACE) - sizeof(DWORD)) +
330 GetLengthSid(pInteractiveSid) +
331 GetLengthSid(pAdministratorsSid);
332
333 //
334 // allocate storage for Acl
335 //
336 pDacl := PACL(HeapAlloc(GetProcessHeap(), 0, dwAclSize));
337 //if(pDacl == nil) goto cleanup;
338
339 if (not InitializeAcl(pDacl^, dwAclSize, ACL_REVISION)) then
340 begin
341 ShowMessage('Error in: InitializeAcl');
342 //goto cleanup;
343 end;
344
345 //
346 // grant the Interactive Sid KEY_READ access to the perf key
347 //
348 if (not AddAccessAllowedAce(
349 pDacl^,
350 ACL_REVISION,
351 KEY_READ,
352 pInteractiveSid
353 )) then
354 begin
355 ShowMessage('Error in: AddAccessAllowedAce');
356 //goto cleanup;
357 end;
358
359 //
360 // grant the Administrators Sid KEY_ALL_ACCESS access to the perf key
361 //
362 if (not AddAccessAllowedAce(
363 pDacl^,
364 ACL_REVISION,
365 KEY_ALL_ACCESS,
366 pAdministratorsSid
367 )) then
368 begin
369 ShowMessage('Error in: AddAccessAllowedAce');
370 //goto cleanup;
371 end;
372
373 if (not InitializeSecurityDescriptor(@sd, SECURITY_DESCRIPTOR_REVISION)) then
374 begin
375 ShowMessage('Error in: InitializeSecurityDescriptor');
376 //goto cleanup;
377 end;
378
379 if (not SetSecurityDescriptorDacl(@sd, TRUE, pDacl, FALSE)) then
380 begin
381 ShowMessage('Error in: SetSecurityDescriptorDacl');
382 //goto cleanup;
383 end;
384
385 //
386 // apply the security descriptor to the registry key
387 //
388 lRetCode := RegSetKeySecurity(
389 aHKey,
390 SECURITY_INFORMATION(DACL_SECURITY_INFORMATION),
391 @sd
392 );
393
394 if (lRetCode <> ERROR_SUCCESS) then
395 begin
396 ShowMessage('Error in: RegSetKeySecurity');
397 //goto cleanup;
398 end;
399
400 bSuccess := TRUE; // indicate success
401
402 end;
403
404 end.
|