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