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