Synchronize up to trunk's revision r57784.
[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 SidBuffer = NULL;
314 PWSTR DomainBuffer = NULL;
315 DWORD cbSidSize = 0;
316 DWORD cchDomSize = 0;
317 SID_NAME_USE Use;
318 BOOL res = TRUE;
319
320 *Sid = NULL;
321
322 LookupAccountNameW(NULL,
323 UserName,
324 NULL,
325 &cbSidSize,
326 NULL,
327 &cchDomSize,
328 &Use);
329
330 if (cbSidSize == 0 || cchDomSize == 0)
331 return FALSE;
332
333 SidBuffer = RtlAllocateHeap(RtlGetProcessHeap(),
334 HEAP_ZERO_MEMORY,
335 cbSidSize);
336 if (SidBuffer == NULL)
337 return FALSE;
338
339 DomainBuffer = RtlAllocateHeap(RtlGetProcessHeap(),
340 HEAP_ZERO_MEMORY,
341 cchDomSize * sizeof(WCHAR));
342 if (DomainBuffer == NULL)
343 {
344 res = FALSE;
345 goto done;
346 }
347
348 if (!LookupAccountNameW(NULL,
349 UserName,
350 SidBuffer,
351 &cbSidSize,
352 DomainBuffer,
353 &cchDomSize,
354 &Use))
355 {
356 res = FALSE;
357 goto done;
358 }
359
360 if (Use != SidTypeUser)
361 {
362 res = FALSE;
363 goto done;
364 }
365
366 *Sid = SidBuffer;
367
368 done:
369 if (DomainBuffer != NULL)
370 RtlFreeHeap(RtlGetProcessHeap(), 0, DomainBuffer);
371
372 if (res == FALSE)
373 {
374 if (SidBuffer != NULL)
375 RtlFreeHeap(RtlGetProcessHeap(), 0, SidBuffer);
376 }
377
378 return res;
379 }
380
381
382 static PTOKEN_GROUPS
383 AllocateGroupSids(OUT PSID *PrimaryGroupSid,
384 OUT PSID *OwnerSid)
385 {
386 SID_IDENTIFIER_AUTHORITY WorldAuthority = {SECURITY_WORLD_SID_AUTHORITY};
387 SID_IDENTIFIER_AUTHORITY LocalAuthority = {SECURITY_LOCAL_SID_AUTHORITY};
388 SID_IDENTIFIER_AUTHORITY SystemAuthority = {SECURITY_NT_AUTHORITY};
389 PTOKEN_GROUPS TokenGroups;
390 #define MAX_GROUPS 8
391 DWORD GroupCount = 0;
392 PSID DomainSid;
393 PSID Sid;
394 LUID Luid;
395 NTSTATUS Status;
396
397 Status = NtAllocateLocallyUniqueId(&Luid);
398 if (!NT_SUCCESS(Status))
399 return NULL;
400
401 if (!GetAccountDomainSid(&DomainSid))
402 return NULL;
403
404 TokenGroups = RtlAllocateHeap(
405 GetProcessHeap(), 0,
406 sizeof(TOKEN_GROUPS) +
407 MAX_GROUPS * sizeof(SID_AND_ATTRIBUTES));
408 if (TokenGroups == NULL)
409 {
410 RtlFreeHeap(RtlGetProcessHeap(), 0, DomainSid);
411 return NULL;
412 }
413
414 Sid = AppendRidToSid(DomainSid, DOMAIN_GROUP_RID_USERS);
415 RtlFreeHeap(RtlGetProcessHeap(), 0, DomainSid);
416
417 /* Member of the domain */
418 TokenGroups->Groups[GroupCount].Sid = Sid;
419 TokenGroups->Groups[GroupCount].Attributes =
420 SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY;
421 *PrimaryGroupSid = Sid;
422 GroupCount++;
423
424 /* Member of 'Everyone' */
425 RtlAllocateAndInitializeSid(&WorldAuthority,
426 1,
427 SECURITY_WORLD_RID,
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 SECURITY_NULL_RID,
435 &Sid);
436 TokenGroups->Groups[GroupCount].Sid = Sid;
437 TokenGroups->Groups[GroupCount].Attributes =
438 SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY;
439 GroupCount++;
440
441 #if 1
442 /* Member of 'Administrators' */
443 RtlAllocateAndInitializeSid(&SystemAuthority,
444 2,
445 SECURITY_BUILTIN_DOMAIN_RID,
446 DOMAIN_ALIAS_RID_ADMINS,
447 SECURITY_NULL_RID,
448 SECURITY_NULL_RID,
449 SECURITY_NULL_RID,
450 SECURITY_NULL_RID,
451 SECURITY_NULL_RID,
452 SECURITY_NULL_RID,
453 &Sid);
454 TokenGroups->Groups[GroupCount].Sid = Sid;
455 TokenGroups->Groups[GroupCount].Attributes =
456 SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY;
457 GroupCount++;
458 #else
459 TRACE("Not adding user to Administrators group\n");
460 #endif
461
462 /* Member of 'Users' */
463 RtlAllocateAndInitializeSid(&SystemAuthority,
464 2,
465 SECURITY_BUILTIN_DOMAIN_RID,
466 DOMAIN_ALIAS_RID_USERS,
467 SECURITY_NULL_RID,
468 SECURITY_NULL_RID,
469 SECURITY_NULL_RID,
470 SECURITY_NULL_RID,
471 SECURITY_NULL_RID,
472 SECURITY_NULL_RID,
473 &Sid);
474 TokenGroups->Groups[GroupCount].Sid = Sid;
475 TokenGroups->Groups[GroupCount].Attributes =
476 SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY;
477 GroupCount++;
478
479 /* Logon SID */
480 RtlAllocateAndInitializeSid(&SystemAuthority,
481 SECURITY_LOGON_IDS_RID_COUNT,
482 SECURITY_LOGON_IDS_RID,
483 Luid.HighPart,
484 Luid.LowPart,
485 SECURITY_NULL_RID,
486 SECURITY_NULL_RID,
487 SECURITY_NULL_RID,
488 SECURITY_NULL_RID,
489 SECURITY_NULL_RID,
490 &Sid);
491 TokenGroups->Groups[GroupCount].Sid = Sid;
492 TokenGroups->Groups[GroupCount].Attributes =
493 SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY | SE_GROUP_LOGON_ID;
494 GroupCount++;
495 *OwnerSid = Sid;
496
497 /* Member of 'Local users */
498 RtlAllocateAndInitializeSid(&LocalAuthority,
499 1,
500 SECURITY_LOCAL_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 SECURITY_NULL_RID,
508 &Sid);
509 TokenGroups->Groups[GroupCount].Sid = Sid;
510 TokenGroups->Groups[GroupCount].Attributes =
511 SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY;
512 GroupCount++;
513
514 /* Member of 'Interactive users' */
515 RtlAllocateAndInitializeSid(&SystemAuthority,
516 1,
517 SECURITY_INTERACTIVE_RID,
518 SECURITY_NULL_RID,
519 SECURITY_NULL_RID,
520 SECURITY_NULL_RID,
521 SECURITY_NULL_RID,
522 SECURITY_NULL_RID,
523 SECURITY_NULL_RID,
524 SECURITY_NULL_RID,
525 &Sid);
526 TokenGroups->Groups[GroupCount].Sid = Sid;
527 TokenGroups->Groups[GroupCount].Attributes =
528 SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY;
529 GroupCount++;
530
531 /* Member of 'Authenticated users' */
532 RtlAllocateAndInitializeSid(&SystemAuthority,
533 1,
534 SECURITY_AUTHENTICATED_USER_RID,
535 SECURITY_NULL_RID,
536 SECURITY_NULL_RID,
537 SECURITY_NULL_RID,
538 SECURITY_NULL_RID,
539 SECURITY_NULL_RID,
540 SECURITY_NULL_RID,
541 SECURITY_NULL_RID,
542 &Sid);
543 TokenGroups->Groups[GroupCount].Sid = Sid;
544 TokenGroups->Groups[GroupCount].Attributes =
545 SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY;
546 GroupCount++;
547
548 TokenGroups->GroupCount = GroupCount;
549 ASSERT(TokenGroups->GroupCount <= MAX_GROUPS);
550
551 return TokenGroups;
552 }
553
554
555 static VOID
556 FreeGroupSids(PTOKEN_GROUPS TokenGroups)
557 {
558 ULONG i;
559
560 for (i = 0; i < TokenGroups->GroupCount; i++)
561 {
562 if (TokenGroups->Groups[i].Sid != NULL)
563 RtlFreeHeap(GetProcessHeap(), 0, TokenGroups->Groups[i].Sid);
564 }
565
566 RtlFreeHeap(GetProcessHeap(), 0, TokenGroups);
567 }
568
569
570 /*
571 * @unimplemented
572 */
573 BOOL WINAPI
574 LogonUserW(LPWSTR lpszUsername,
575 LPWSTR lpszDomain,
576 LPWSTR lpszPassword,
577 DWORD dwLogonType,
578 DWORD dwLogonProvider,
579 PHANDLE phToken)
580 {
581 /* FIXME shouldn't use hard-coded list of privileges */
582 static struct
583 {
584 LPCWSTR PrivName;
585 DWORD Attributes;
586 }
587 DefaultPrivs[] =
588 {
589 { L"SeMachineAccountPrivilege", 0 },
590 { L"SeSecurityPrivilege", 0 },
591 { L"SeTakeOwnershipPrivilege", 0 },
592 { L"SeLoadDriverPrivilege", 0 },
593 { L"SeSystemProfilePrivilege", 0 },
594 { L"SeSystemtimePrivilege", 0 },
595 { L"SeProfileSingleProcessPrivilege", 0 },
596 { L"SeIncreaseBasePriorityPrivilege", 0 },
597 { L"SeCreatePagefilePrivilege", 0 },
598 { L"SeBackupPrivilege", 0 },
599 { L"SeRestorePrivilege", 0 },
600 { L"SeShutdownPrivilege", 0 },
601 { L"SeDebugPrivilege", 0 },
602 { L"SeSystemEnvironmentPrivilege", 0 },
603 { L"SeChangeNotifyPrivilege", SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT },
604 { L"SeRemoteShutdownPrivilege", 0 },
605 { L"SeUndockPrivilege", 0 },
606 { L"SeEnableDelegationPrivilege", 0 },
607 { L"SeImpersonatePrivilege", SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT },
608 { L"SeCreateGlobalPrivilege", SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT }
609 };
610 OBJECT_ATTRIBUTES ObjectAttributes;
611 SECURITY_QUALITY_OF_SERVICE Qos;
612 TOKEN_USER TokenUser;
613 TOKEN_OWNER TokenOwner;
614 TOKEN_PRIMARY_GROUP TokenPrimaryGroup;
615 PTOKEN_GROUPS TokenGroups = NULL;
616 PTOKEN_PRIVILEGES TokenPrivileges = NULL;
617 TOKEN_DEFAULT_DACL TokenDefaultDacl;
618 LARGE_INTEGER ExpirationTime;
619 LUID AuthenticationId;
620 TOKEN_SOURCE TokenSource;
621 PSID UserSid = NULL;
622 PSID PrimaryGroupSid = NULL;
623 PSID OwnerSid = NULL;
624 PSID LocalSystemSid;
625 PACL Dacl = NULL;
626 SID_IDENTIFIER_AUTHORITY SystemAuthority = {SECURITY_NT_AUTHORITY};
627 unsigned i;
628 NTSTATUS Status = STATUS_SUCCESS;
629
630 Qos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
631 Qos.ImpersonationLevel = SecurityAnonymous;
632 Qos.ContextTrackingMode = SECURITY_STATIC_TRACKING;
633 Qos.EffectiveOnly = FALSE;
634
635 ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
636 ObjectAttributes.RootDirectory = NULL;
637 ObjectAttributes.ObjectName = NULL;
638 ObjectAttributes.Attributes = 0;
639 ObjectAttributes.SecurityDescriptor = NULL;
640 ObjectAttributes.SecurityQualityOfService = &Qos;
641
642 Status = NtAllocateLocallyUniqueId(&AuthenticationId);
643 if (!NT_SUCCESS(Status))
644 {
645 return FALSE;
646 }
647
648 ExpirationTime.QuadPart = -1;
649
650 /* Get the user SID from the registry */
651 if (!GetUserSid (lpszUsername, &UserSid))
652 {
653 ERR("SamGetUserSid() failed\n");
654 return FALSE;
655 }
656
657 TokenUser.User.Sid = UserSid;
658 TokenUser.User.Attributes = 0;
659
660 /* Allocate and initialize token groups */
661 TokenGroups = AllocateGroupSids(&PrimaryGroupSid,
662 &OwnerSid);
663 if (TokenGroups == NULL)
664 {
665 Status = STATUS_INSUFFICIENT_RESOURCES;
666 goto done;
667 }
668
669 /* Allocate and initialize token privileges */
670 TokenPrivileges = RtlAllocateHeap(GetProcessHeap(), 0,
671 sizeof(TOKEN_PRIVILEGES)
672 + sizeof(DefaultPrivs) / sizeof(DefaultPrivs[0])
673 * sizeof(LUID_AND_ATTRIBUTES));
674 if (TokenPrivileges == NULL)
675 {
676 Status = STATUS_INSUFFICIENT_RESOURCES;
677 goto done;
678 }
679
680 TokenPrivileges->PrivilegeCount = 0;
681 for (i = 0; i < sizeof(DefaultPrivs) / sizeof(DefaultPrivs[0]); i++)
682 {
683 if (! LookupPrivilegeValueW(NULL,
684 DefaultPrivs[i].PrivName,
685 &TokenPrivileges->Privileges[TokenPrivileges->PrivilegeCount].Luid))
686 {
687 WARN("Can't set privilege %S\n", DefaultPrivs[i].PrivName);
688 }
689 else
690 {
691 TokenPrivileges->Privileges[TokenPrivileges->PrivilegeCount].Attributes = DefaultPrivs[i].Attributes;
692 TokenPrivileges->PrivilegeCount++;
693 }
694 }
695
696 TokenOwner.Owner = OwnerSid;
697 TokenPrimaryGroup.PrimaryGroup = PrimaryGroupSid;
698
699 Dacl = RtlAllocateHeap(GetProcessHeap(), 0, 1024);
700 if (Dacl == NULL)
701 {
702 Status = STATUS_INSUFFICIENT_RESOURCES;
703 goto done;
704 }
705
706 Status = RtlCreateAcl(Dacl, 1024, ACL_REVISION);
707 if (!NT_SUCCESS(Status))
708 goto done;
709
710 RtlAddAccessAllowedAce(Dacl,
711 ACL_REVISION,
712 GENERIC_ALL,
713 OwnerSid);
714
715 RtlAllocateAndInitializeSid(&SystemAuthority,
716 1,
717 SECURITY_LOCAL_SYSTEM_RID,
718 SECURITY_NULL_RID,
719 SECURITY_NULL_RID,
720 SECURITY_NULL_RID,
721 SECURITY_NULL_RID,
722 SECURITY_NULL_RID,
723 SECURITY_NULL_RID,
724 SECURITY_NULL_RID,
725 &LocalSystemSid);
726
727 /* SID: S-1-5-18 */
728 RtlAddAccessAllowedAce(Dacl,
729 ACL_REVISION,
730 GENERIC_ALL,
731 LocalSystemSid);
732
733 RtlFreeSid(LocalSystemSid);
734
735 TokenDefaultDacl.DefaultDacl = Dacl;
736
737 memcpy(TokenSource.SourceName,
738 "User32 ",
739 8);
740
741 Status = NtAllocateLocallyUniqueId(&TokenSource.SourceIdentifier);
742 if (!NT_SUCCESS(Status))
743 {
744 RtlFreeHeap(GetProcessHeap(), 0, Dacl);
745 FreeGroupSids(TokenGroups);
746 RtlFreeHeap(GetProcessHeap(), 0, TokenPrivileges);
747 RtlFreeSid(UserSid);
748 return FALSE;
749 }
750
751 Status = NtCreateToken(phToken,
752 TOKEN_ALL_ACCESS,
753 &ObjectAttributes,
754 TokenPrimary,
755 &AuthenticationId,
756 &ExpirationTime,
757 &TokenUser,
758 TokenGroups,
759 TokenPrivileges,
760 &TokenOwner,
761 &TokenPrimaryGroup,
762 &TokenDefaultDacl,
763 &TokenSource);
764
765 done:
766 if (Dacl != NULL)
767 RtlFreeHeap(GetProcessHeap(), 0, Dacl);
768
769 if (TokenGroups != NULL)
770 FreeGroupSids(TokenGroups);
771
772 if (TokenPrivileges != NULL)
773 RtlFreeHeap(GetProcessHeap(), 0, TokenPrivileges);
774
775 if (UserSid != NULL)
776 RtlFreeHeap(GetProcessHeap(), 0, UserSid);
777
778 return NT_SUCCESS(Status);
779 }
780
781 /* EOF */