eb95f8c710215b0f6e1cf22e223e7ee364a3d17f
[reactos.git] / reactos / lib / advapi32 / misc / logon.c
1 /* $Id$
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS system libraries
5 * FILE: lib/advapi32/misc/logon.c
6 * PURPOSE: Logon functions
7 * PROGRAMMER: Eric Kohl
8 */
9
10 #include <advapi32.h>
11 #define NDEBUG
12 #include <debug.h>
13
14
15 /* FUNCTIONS ***************************************************************/
16
17 /*
18 * @implemented
19 */
20 BOOL STDCALL
21 CreateProcessAsUserA (HANDLE hToken,
22 LPCSTR lpApplicationName,
23 LPSTR lpCommandLine,
24 LPSECURITY_ATTRIBUTES lpProcessAttributes,
25 LPSECURITY_ATTRIBUTES lpThreadAttributes,
26 BOOL bInheritHandles,
27 DWORD dwCreationFlags,
28 LPVOID lpEnvironment,
29 LPCSTR lpCurrentDirectory,
30 LPSTARTUPINFOA lpStartupInfo,
31 LPPROCESS_INFORMATION lpProcessInformation)
32 {
33 PROCESS_ACCESS_TOKEN AccessToken;
34 NTSTATUS Status;
35
36 /* Create the process with a suspended main thread */
37 if (!CreateProcessA (lpApplicationName,
38 lpCommandLine,
39 lpProcessAttributes,
40 lpThreadAttributes,
41 bInheritHandles,
42 dwCreationFlags | CREATE_SUSPENDED,
43 lpEnvironment,
44 lpCurrentDirectory,
45 lpStartupInfo,
46 lpProcessInformation))
47 {
48 return FALSE;
49 }
50
51 AccessToken.Token = hToken;
52 AccessToken.Thread = NULL;
53
54 /* Set the new process token */
55 Status = NtSetInformationProcess (lpProcessInformation->hProcess,
56 ProcessAccessToken,
57 (PVOID)&AccessToken,
58 sizeof (AccessToken));
59 if (!NT_SUCCESS (Status))
60 {
61 SetLastError (RtlNtStatusToDosError (Status));
62 return FALSE;
63 }
64
65 /* Resume the main thread */
66 if (!(dwCreationFlags & CREATE_SUSPENDED))
67 {
68 ResumeThread (lpProcessInformation->hThread);
69 }
70
71 return TRUE;
72 }
73
74
75 /*
76 * @implemented
77 */
78 BOOL STDCALL
79 CreateProcessAsUserW (HANDLE hToken,
80 LPCWSTR lpApplicationName,
81 LPWSTR lpCommandLine,
82 LPSECURITY_ATTRIBUTES lpProcessAttributes,
83 LPSECURITY_ATTRIBUTES lpThreadAttributes,
84 BOOL bInheritHandles,
85 DWORD dwCreationFlags,
86 LPVOID lpEnvironment,
87 LPCWSTR lpCurrentDirectory,
88 LPSTARTUPINFOW lpStartupInfo,
89 LPPROCESS_INFORMATION lpProcessInformation)
90 {
91 PROCESS_ACCESS_TOKEN AccessToken;
92 NTSTATUS Status;
93
94 /* Create the process with a suspended main thread */
95 if (!CreateProcessW (lpApplicationName,
96 lpCommandLine,
97 lpProcessAttributes,
98 lpThreadAttributes,
99 bInheritHandles,
100 dwCreationFlags | CREATE_SUSPENDED,
101 lpEnvironment,
102 lpCurrentDirectory,
103 lpStartupInfo,
104 lpProcessInformation))
105 {
106 return FALSE;
107 }
108
109 AccessToken.Token = hToken;
110 AccessToken.Thread = NULL;
111
112 /* Set the new process token */
113 Status = NtSetInformationProcess (lpProcessInformation->hProcess,
114 ProcessAccessToken,
115 (PVOID)&AccessToken,
116 sizeof (AccessToken));
117 if (!NT_SUCCESS (Status))
118 {
119 SetLastError (RtlNtStatusToDosError (Status));
120 return FALSE;
121 }
122
123 /* Resume the main thread */
124 if (!(dwCreationFlags & CREATE_SUSPENDED))
125 {
126 ResumeThread (lpProcessInformation->hThread);
127 }
128
129 return TRUE;
130 }
131
132
133 /*
134 * @unimplemented
135 */
136 BOOL STDCALL
137 LogonUserA (LPSTR lpszUsername,
138 LPSTR lpszDomain,
139 LPSTR lpszPassword,
140 DWORD dwLogonType,
141 DWORD dwLogonProvider,
142 PHANDLE phToken)
143 {
144 return FALSE;
145 }
146
147
148 static BOOL STDCALL
149 SamGetUserSid (LPCWSTR UserName,
150 PSID *Sid)
151 {
152 PSID lpSid;
153 DWORD dwLength;
154 HKEY hUsersKey;
155 HKEY hUserKey;
156
157 if (Sid != NULL)
158 *Sid = NULL;
159
160 /* Open the Users key */
161 if (RegOpenKeyExW (HKEY_LOCAL_MACHINE,
162 L"SAM\\SAM\\Domains\\Account\\Users",
163 0,
164 KEY_READ,
165 &hUsersKey))
166 {
167 DPRINT1 ("Failed to open Users key! (Error %lu)\n", GetLastError());
168 return FALSE;
169 }
170
171 /* Open the user key */
172 if (RegOpenKeyExW (hUsersKey,
173 UserName,
174 0,
175 KEY_READ,
176 &hUserKey))
177 {
178 if (GetLastError () == ERROR_FILE_NOT_FOUND)
179 {
180 DPRINT1 ("Invalid user name!\n");
181 SetLastError (ERROR_NO_SUCH_USER);
182 }
183 else
184 {
185 DPRINT1 ("Failed to open user key! (Error %lu)\n", GetLastError());
186 }
187
188 RegCloseKey (hUsersKey);
189 return FALSE;
190 }
191
192 RegCloseKey (hUsersKey);
193
194 /* Get SID size */
195 dwLength = 0;
196 if (RegQueryValueExW (hUserKey,
197 L"Sid",
198 NULL,
199 NULL,
200 NULL,
201 &dwLength))
202 {
203 DPRINT1 ("Failed to read the SID size! (Error %lu)\n", GetLastError());
204 RegCloseKey (hUserKey);
205 return FALSE;
206 }
207
208 /* Allocate sid buffer */
209 DPRINT ("Required SID buffer size: %lu\n", dwLength);
210 lpSid = (PSID)RtlAllocateHeap (RtlGetProcessHeap (),
211 0,
212 dwLength);
213 if (lpSid == NULL)
214 {
215 DPRINT1 ("Failed to allocate SID buffer!\n");
216 RegCloseKey (hUserKey);
217 return FALSE;
218 }
219
220 /* Read sid */
221 if (RegQueryValueExW (hUserKey,
222 L"Sid",
223 NULL,
224 NULL,
225 (LPBYTE)lpSid,
226 &dwLength))
227 {
228 DPRINT1 ("Failed to read the SID! (Error %lu)\n", GetLastError());
229 RtlFreeHeap (RtlGetProcessHeap (),
230 0,
231 lpSid);
232 RegCloseKey (hUserKey);
233 return FALSE;
234 }
235
236 RegCloseKey (hUserKey);
237
238 *Sid = lpSid;
239
240 return TRUE;
241 }
242
243
244 static BOOL STDCALL
245 SamGetDomainSid(PSID *Sid)
246 {
247 PSID lpSid;
248 DWORD dwLength;
249 HKEY hDomainKey;
250
251 DPRINT("SamGetDomainSid() called\n");
252
253 if (Sid != NULL)
254 *Sid = NULL;
255
256 /* Open the account domain key */
257 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
258 L"SAM\\SAM\\Domains\\Account",
259 0,
260 KEY_READ,
261 &hDomainKey))
262 {
263 DPRINT1("Failed to open the account domain key! (Error %lu)\n", GetLastError());
264 return FALSE;
265 }
266
267 /* Get SID size */
268 dwLength = 0;
269 if (RegQueryValueExW(hDomainKey,
270 L"Sid",
271 NULL,
272 NULL,
273 NULL,
274 &dwLength))
275 {
276 DPRINT1("Failed to read the SID size! (Error %lu)\n", GetLastError());
277 RegCloseKey(hDomainKey);
278 return FALSE;
279 }
280
281 /* Allocate sid buffer */
282 DPRINT("Required SID buffer size: %lu\n", dwLength);
283 lpSid = (PSID)RtlAllocateHeap(RtlGetProcessHeap(),
284 0,
285 dwLength);
286 if (lpSid == NULL)
287 {
288 DPRINT1("Failed to allocate SID buffer!\n");
289 RegCloseKey(hDomainKey);
290 return FALSE;
291 }
292
293 /* Read sid */
294 if (RegQueryValueExW(hDomainKey,
295 L"Sid",
296 NULL,
297 NULL,
298 (LPBYTE)lpSid,
299 &dwLength))
300 {
301 DPRINT1("Failed to read the SID! (Error %lu)\n", GetLastError());
302 RtlFreeHeap(RtlGetProcessHeap(),
303 0,
304 lpSid);
305 RegCloseKey(hDomainKey);
306 return FALSE;
307 }
308
309 RegCloseKey(hDomainKey);
310
311 *Sid = lpSid;
312
313 DPRINT("SamGetDomainSid() done\n");
314
315 return TRUE;
316 }
317
318
319 static PSID
320 AppendRidToSid(PSID SrcSid,
321 ULONG Rid)
322 {
323 ULONG Rids[8] = {0, 0, 0, 0, 0, 0, 0, 0};
324 UCHAR RidCount;
325 PSID DstSid;
326 ULONG i;
327
328 RidCount = *RtlSubAuthorityCountSid(SrcSid);
329 if (RidCount >= 8)
330 return NULL;
331
332 for (i = 0; i < RidCount; i++)
333 Rids[i] = *RtlSubAuthoritySid(SrcSid, i);
334
335 Rids[RidCount] = Rid;
336 RidCount++;
337
338 RtlAllocateAndInitializeSid(RtlIdentifierAuthoritySid(SrcSid),
339 RidCount,
340 Rids[0],
341 Rids[1],
342 Rids[2],
343 Rids[3],
344 Rids[4],
345 Rids[5],
346 Rids[6],
347 Rids[7],
348 &DstSid);
349
350 return DstSid;
351 }
352
353
354 static PTOKEN_GROUPS
355 AllocateGroupSids(PSID *PrimaryGroupSid,
356 PSID *OwnerSid)
357 {
358 SID_IDENTIFIER_AUTHORITY WorldAuthority = {SECURITY_WORLD_SID_AUTHORITY};
359 SID_IDENTIFIER_AUTHORITY LocalAuthority = {SECURITY_LOCAL_SID_AUTHORITY};
360 SID_IDENTIFIER_AUTHORITY SystemAuthority = {SECURITY_NT_AUTHORITY};
361 PTOKEN_GROUPS TokenGroups;
362 PSID DomainSid;
363 PSID Sid;
364 LUID Luid;
365 NTSTATUS Status;
366
367 Status = NtAllocateLocallyUniqueId(&Luid);
368 if (!NT_SUCCESS(Status))
369 {
370 return NULL;
371 }
372
373 if (!SamGetDomainSid(&DomainSid))
374 {
375 return NULL;
376 }
377
378 TokenGroups = RtlAllocateHeap(GetProcessHeap(), 0,
379 sizeof(TOKEN_GROUPS) +
380 8 * sizeof(SID_AND_ATTRIBUTES));
381 if (TokenGroups == NULL)
382 {
383 RtlFreeHeap (RtlGetProcessHeap (),
384 0,
385 DomainSid);
386 return NULL;
387 }
388
389 TokenGroups->GroupCount = 8;
390
391 Sid = AppendRidToSid(DomainSid,
392 DOMAIN_GROUP_RID_USERS);
393
394 RtlFreeHeap(RtlGetProcessHeap(),
395 0,
396 DomainSid);
397
398 TokenGroups->Groups[0].Sid = Sid;
399 TokenGroups->Groups[0].Attributes = SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY;
400 *PrimaryGroupSid = Sid;
401
402
403 RtlAllocateAndInitializeSid(&WorldAuthority,
404 1,
405 SECURITY_WORLD_RID,
406 SECURITY_NULL_RID,
407 SECURITY_NULL_RID,
408 SECURITY_NULL_RID,
409 SECURITY_NULL_RID,
410 SECURITY_NULL_RID,
411 SECURITY_NULL_RID,
412 SECURITY_NULL_RID,
413 &Sid);
414
415 TokenGroups->Groups[1].Sid = Sid;
416 TokenGroups->Groups[1].Attributes = SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY;
417
418
419 RtlAllocateAndInitializeSid(&SystemAuthority,
420 2,
421 SECURITY_BUILTIN_DOMAIN_RID,
422 DOMAIN_ALIAS_RID_ADMINS,
423 SECURITY_NULL_RID,
424 SECURITY_NULL_RID,
425 SECURITY_NULL_RID,
426 SECURITY_NULL_RID,
427 SECURITY_NULL_RID,
428 SECURITY_NULL_RID,
429 &Sid);
430
431 TokenGroups->Groups[2].Sid = Sid;
432 TokenGroups->Groups[2].Attributes = SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY;
433
434 *OwnerSid = Sid;
435
436 RtlAllocateAndInitializeSid(&SystemAuthority,
437 2,
438 SECURITY_BUILTIN_DOMAIN_RID,
439 DOMAIN_ALIAS_RID_USERS,
440 SECURITY_NULL_RID,
441 SECURITY_NULL_RID,
442 SECURITY_NULL_RID,
443 SECURITY_NULL_RID,
444 SECURITY_NULL_RID,
445 SECURITY_NULL_RID,
446 &Sid);
447
448 TokenGroups->Groups[3].Sid = Sid;
449 TokenGroups->Groups[3].Attributes = SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY;
450
451 /* Logon SID */
452 RtlAllocateAndInitializeSid(&SystemAuthority,
453 SECURITY_LOGON_IDS_RID_COUNT,
454 SECURITY_LOGON_IDS_RID,
455 Luid.HighPart,
456 Luid.LowPart,
457 SECURITY_NULL_RID,
458 SECURITY_NULL_RID,
459 SECURITY_NULL_RID,
460 SECURITY_NULL_RID,
461 SECURITY_NULL_RID,
462 &Sid);
463
464 TokenGroups->Groups[4].Sid = Sid;
465 TokenGroups->Groups[4].Attributes = SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY | SE_GROUP_LOGON_ID;
466
467 RtlAllocateAndInitializeSid(&LocalAuthority,
468 1,
469 SECURITY_LOCAL_RID,
470 SECURITY_NULL_RID,
471 SECURITY_NULL_RID,
472 SECURITY_NULL_RID,
473 SECURITY_NULL_RID,
474 SECURITY_NULL_RID,
475 SECURITY_NULL_RID,
476 SECURITY_NULL_RID,
477 &Sid);
478
479 TokenGroups->Groups[5].Sid = Sid;
480 TokenGroups->Groups[5].Attributes = SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY;
481
482 RtlAllocateAndInitializeSid(&SystemAuthority,
483 1,
484 SECURITY_INTERACTIVE_RID,
485 SECURITY_NULL_RID,
486 SECURITY_NULL_RID,
487 SECURITY_NULL_RID,
488 SECURITY_NULL_RID,
489 SECURITY_NULL_RID,
490 SECURITY_NULL_RID,
491 SECURITY_NULL_RID,
492 &Sid);
493
494 TokenGroups->Groups[6].Sid = Sid;
495 TokenGroups->Groups[6].Attributes = SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY;
496
497 RtlAllocateAndInitializeSid(&SystemAuthority,
498 1,
499 SECURITY_AUTHENTICATED_USER_RID,
500 SECURITY_NULL_RID,
501 SECURITY_NULL_RID,
502 SECURITY_NULL_RID,
503 SECURITY_NULL_RID,
504 SECURITY_NULL_RID,
505 SECURITY_NULL_RID,
506 SECURITY_NULL_RID,
507 &Sid);
508
509 TokenGroups->Groups[7].Sid = Sid;
510 TokenGroups->Groups[7].Attributes = SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY;
511
512 return TokenGroups;
513 }
514
515
516 static VOID
517 FreeGroupSids(PTOKEN_GROUPS TokenGroups)
518 {
519 ULONG i;
520
521 for (i = 0; i < TokenGroups->GroupCount; i++)
522 {
523 if (TokenGroups->Groups[i].Sid != NULL)
524 RtlFreeHeap(GetProcessHeap(), 0, TokenGroups->Groups[i].Sid);
525 }
526
527 RtlFreeHeap(GetProcessHeap(), 0, TokenGroups);
528 }
529
530
531 /*
532 * @unimplemented
533 */
534 BOOL STDCALL
535 LogonUserW (LPWSTR lpszUsername,
536 LPWSTR lpszDomain,
537 LPWSTR lpszPassword,
538 DWORD dwLogonType,
539 DWORD dwLogonProvider,
540 PHANDLE phToken)
541 {
542 /* FIXME shouldn't use hard-coded list of privileges */
543 static struct
544 {
545 LPCWSTR PrivName;
546 DWORD Attributes;
547 }
548 DefaultPrivs[] =
549 {
550 { L"SeUnsolicitedInputPrivilege", 0 },
551 { L"SeMachineAccountPrivilege", 0 },
552 { L"SeSecurityPrivilege", 0 },
553 { L"SeTakeOwnershipPrivilege", 0 },
554 { L"SeLoadDriverPrivilege", 0 },
555 { L"SeSystemProfilePrivilege", 0 },
556 { L"SeSystemtimePrivilege", 0 },
557 { L"SeProfileSingleProcessPrivilege", 0 },
558 { L"SeIncreaseBasePriorityPrivilege", 0 },
559 { L"SeCreatePagefilePrivilege", 0 },
560 { L"SeBackupPrivilege", 0 },
561 { L"SeRestorePrivilege", 0 },
562 { L"SeShutdownPrivilege", 0 },
563 { L"SeDebugPrivilege", 0 },
564 { L"SeSystemEnvironmentPrivilege", 0 },
565 { L"SeChangeNotifyPrivilege", SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT },
566 { L"SeRemoteShutdownPrivilege", 0 },
567 { L"SeUndockPrivilege", 0 },
568 { L"SeEnableDelegationPrivilege", 0 },
569 { L"SeImpersonatePrivilege", SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT },
570 { L"SeCreateGlobalPrivilege", SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT }
571 };
572 OBJECT_ATTRIBUTES ObjectAttributes;
573 SECURITY_QUALITY_OF_SERVICE Qos;
574 TOKEN_USER TokenUser;
575 TOKEN_OWNER TokenOwner;
576 TOKEN_PRIMARY_GROUP TokenPrimaryGroup;
577 PTOKEN_GROUPS TokenGroups;
578 PTOKEN_PRIVILEGES TokenPrivileges;
579 TOKEN_DEFAULT_DACL TokenDefaultDacl;
580 LARGE_INTEGER ExpirationTime;
581 LUID AuthenticationId;
582 TOKEN_SOURCE TokenSource;
583 PSID UserSid = NULL;
584 PSID PrimaryGroupSid = NULL;
585 PSID OwnerSid = NULL;
586 PSID LocalSystemSid;
587 PACL Dacl;
588 NTSTATUS Status;
589 SID_IDENTIFIER_AUTHORITY SystemAuthority = {SECURITY_NT_AUTHORITY};
590 unsigned i;
591
592 Qos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
593 Qos.ImpersonationLevel = SecurityAnonymous;
594 Qos.ContextTrackingMode = SECURITY_STATIC_TRACKING;
595 Qos.EffectiveOnly = FALSE;
596
597 ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
598 ObjectAttributes.RootDirectory = NULL;
599 ObjectAttributes.ObjectName = NULL;
600 ObjectAttributes.Attributes = 0;
601 ObjectAttributes.SecurityDescriptor = NULL;
602 ObjectAttributes.SecurityQualityOfService = &Qos;
603
604 Status = NtAllocateLocallyUniqueId(&AuthenticationId);
605 if (!NT_SUCCESS(Status))
606 {
607 return FALSE;
608 }
609 ExpirationTime.QuadPart = -1;
610
611 /* Get the user SID from the registry */
612 if (!SamGetUserSid (lpszUsername, &UserSid))
613 {
614 DPRINT ("SamGetUserSid() failed\n");
615 RtlAllocateAndInitializeSid (&SystemAuthority,
616 5,
617 SECURITY_NT_NON_UNIQUE_RID,
618 0x12345678,
619 0x12345678,
620 0x12345678,
621 DOMAIN_USER_RID_ADMIN,
622 SECURITY_NULL_RID,
623 SECURITY_NULL_RID,
624 SECURITY_NULL_RID,
625 &UserSid);
626 }
627
628 TokenUser.User.Sid = UserSid;
629 TokenUser.User.Attributes = 0;
630
631 /* Allocate and initialize token groups */
632 TokenGroups = AllocateGroupSids(&PrimaryGroupSid,
633 &OwnerSid);
634 if (NULL == TokenGroups)
635 {
636 RtlFreeSid(UserSid);
637 SetLastError(ERROR_OUTOFMEMORY);
638 return FALSE;
639 }
640
641 /* Allocate and initialize token privileges */
642 TokenPrivileges = RtlAllocateHeap(GetProcessHeap(), 0,
643 sizeof(TOKEN_PRIVILEGES)
644 + sizeof(DefaultPrivs) / sizeof(DefaultPrivs[0])
645 * sizeof(LUID_AND_ATTRIBUTES));
646 if (NULL == TokenPrivileges)
647 {
648 FreeGroupSids(TokenGroups);
649 RtlFreeSid(UserSid);
650 SetLastError(ERROR_OUTOFMEMORY);
651 return FALSE;
652 }
653
654 TokenPrivileges->PrivilegeCount = 0;
655 for (i = 0; i < sizeof(DefaultPrivs) / sizeof(DefaultPrivs[0]); i++)
656 {
657 if (! LookupPrivilegeValueW(NULL, DefaultPrivs[i].PrivName,
658 &TokenPrivileges->Privileges[TokenPrivileges->PrivilegeCount].Luid))
659 {
660 DPRINT1("Can't set privilege %S\n", DefaultPrivs[i].PrivName);
661 }
662 else
663 {
664 TokenPrivileges->Privileges[TokenPrivileges->PrivilegeCount].Attributes = DefaultPrivs[i].Attributes;
665 TokenPrivileges->PrivilegeCount++;
666 }
667 }
668
669 TokenOwner.Owner = OwnerSid;
670 TokenPrimaryGroup.PrimaryGroup = PrimaryGroupSid;
671
672
673 Dacl = RtlAllocateHeap(GetProcessHeap(), 0, 1024);
674 if (Dacl == NULL)
675 {
676 FreeGroupSids(TokenGroups);
677 RtlFreeSid(UserSid);
678 SetLastError(ERROR_OUTOFMEMORY);
679 return FALSE;
680 }
681
682 Status = RtlCreateAcl(Dacl, 1024, ACL_REVISION);
683 if (!NT_SUCCESS(Status))
684 {
685 RtlFreeHeap(GetProcessHeap(), 0, Dacl);
686 FreeGroupSids(TokenGroups);
687 RtlFreeHeap(GetProcessHeap(), 0, TokenPrivileges);
688 RtlFreeSid(UserSid);
689 return FALSE;
690 }
691
692 RtlAddAccessAllowedAce(Dacl,
693 ACL_REVISION,
694 GENERIC_ALL,
695 OwnerSid);
696
697 RtlAllocateAndInitializeSid(&SystemAuthority,
698 1,
699 SECURITY_LOCAL_SYSTEM_RID,
700 SECURITY_NULL_RID,
701 SECURITY_NULL_RID,
702 SECURITY_NULL_RID,
703 SECURITY_NULL_RID,
704 SECURITY_NULL_RID,
705 SECURITY_NULL_RID,
706 SECURITY_NULL_RID,
707 &LocalSystemSid);
708
709 /* SID: S-1-5-18 */
710 RtlAddAccessAllowedAce(Dacl,
711 ACL_REVISION,
712 GENERIC_ALL,
713 LocalSystemSid);
714
715 RtlFreeSid(LocalSystemSid);
716
717 TokenDefaultDacl.DefaultDacl = Dacl;
718
719 memcpy(TokenSource.SourceName,
720 "User32 ",
721 8);
722 Status = NtAllocateLocallyUniqueId(&TokenSource.SourceIdentifier);
723 if (!NT_SUCCESS(Status))
724 {
725 RtlFreeHeap(GetProcessHeap(), 0, Dacl);
726 FreeGroupSids(TokenGroups);
727 RtlFreeHeap(GetProcessHeap(), 0, TokenPrivileges);
728 RtlFreeSid(UserSid);
729 return FALSE;
730 }
731
732 Status = NtCreateToken(phToken,
733 TOKEN_ALL_ACCESS,
734 &ObjectAttributes,
735 TokenPrimary,
736 &AuthenticationId,
737 &ExpirationTime,
738 &TokenUser,
739 TokenGroups,
740 TokenPrivileges,
741 &TokenOwner,
742 &TokenPrimaryGroup,
743 &TokenDefaultDacl,
744 &TokenSource);
745
746 RtlFreeHeap(GetProcessHeap(), 0, Dacl);
747 FreeGroupSids(TokenGroups);
748 RtlFreeHeap(GetProcessHeap(), 0, TokenPrivileges);
749 RtlFreeSid(UserSid);
750
751 return NT_SUCCESS(Status);
752 }
753
754 /* EOF */