- Implement ProtocolResetComplete
[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
11 #include <wine/debug.h>
12 WINE_DEFAULT_DEBUG_CHANNEL(advapi);
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 * @implemented
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 UNICODE_STRING UserName;
145 UNICODE_STRING Domain;
146 UNICODE_STRING Password;
147 NTSTATUS Status;
148 BOOL ret = FALSE;
149
150 UserName.Buffer = NULL;
151 Domain.Buffer = NULL;
152 Password.Buffer = NULL;
153
154 Status = RtlCreateUnicodeStringFromAsciiz(&UserName,
155 lpszUsername);
156 if (!NT_SUCCESS(Status))
157 {
158 SetLastError(RtlNtStatusToDosError(Status));
159 goto UsernameDone;
160 }
161
162 Status = RtlCreateUnicodeStringFromAsciiz(&Domain,
163 lpszDomain);
164 if (!NT_SUCCESS(Status))
165 {
166 SetLastError(RtlNtStatusToDosError(Status));
167 goto DomainDone;
168 }
169
170 Status = RtlCreateUnicodeStringFromAsciiz(&Password,
171 lpszPassword);
172 if (!NT_SUCCESS(Status))
173 {
174 SetLastError(RtlNtStatusToDosError(Status));
175 goto PasswordDone;
176 }
177
178 ret = LogonUserW(UserName.Buffer,
179 Domain.Buffer,
180 Password.Buffer,
181 dwLogonType,
182 dwLogonProvider,
183 phToken);
184
185 if (Password.Buffer != NULL)
186 RtlFreeUnicodeString(&Password);
187
188 PasswordDone:
189 if (Domain.Buffer != NULL)
190 RtlFreeUnicodeString(&Domain);
191
192 DomainDone:
193 if (UserName.Buffer != NULL)
194 RtlFreeUnicodeString(&UserName);
195
196 UsernameDone:
197 return ret;
198 }
199
200
201 static BOOL STDCALL
202 SamGetUserSid (LPCWSTR UserName,
203 PSID *Sid)
204 {
205 PSID lpSid;
206 DWORD dwLength;
207 HKEY hUsersKey;
208 HKEY hUserKey;
209
210 if (Sid != NULL)
211 *Sid = NULL;
212
213 /* Open the Users key */
214 if (RegOpenKeyExW (HKEY_LOCAL_MACHINE,
215 L"SAM\\SAM\\Domains\\Account\\Users",
216 0,
217 KEY_READ,
218 &hUsersKey))
219 {
220 ERR("Failed to open Users key! (Error %lu)\n", GetLastError());
221 return FALSE;
222 }
223
224 /* Open the user key */
225 if (RegOpenKeyExW (hUsersKey,
226 UserName,
227 0,
228 KEY_READ,
229 &hUserKey))
230 {
231 if (GetLastError () == ERROR_FILE_NOT_FOUND)
232 {
233 ERR("Invalid user name!\n");
234 SetLastError (ERROR_NO_SUCH_USER);
235 }
236 else
237 {
238 ERR("Failed to open user key! (Error %lu)\n", GetLastError());
239 }
240
241 RegCloseKey (hUsersKey);
242 return FALSE;
243 }
244
245 RegCloseKey (hUsersKey);
246
247 /* Get SID size */
248 dwLength = 0;
249 if (RegQueryValueExW (hUserKey,
250 L"Sid",
251 NULL,
252 NULL,
253 NULL,
254 &dwLength))
255 {
256 ERR("Failed to read the SID size! (Error %lu)\n", GetLastError());
257 RegCloseKey (hUserKey);
258 return FALSE;
259 }
260
261 /* Allocate sid buffer */
262 TRACE("Required SID buffer size: %lu\n", dwLength);
263 lpSid = (PSID)RtlAllocateHeap (RtlGetProcessHeap (),
264 0,
265 dwLength);
266 if (lpSid == NULL)
267 {
268 ERR("Failed to allocate SID buffer!\n");
269 RegCloseKey (hUserKey);
270 return FALSE;
271 }
272
273 /* Read sid */
274 if (RegQueryValueExW (hUserKey,
275 L"Sid",
276 NULL,
277 NULL,
278 (LPBYTE)lpSid,
279 &dwLength))
280 {
281 ERR("Failed to read the SID! (Error %lu)\n", GetLastError());
282 RtlFreeHeap (RtlGetProcessHeap (),
283 0,
284 lpSid);
285 RegCloseKey (hUserKey);
286 return FALSE;
287 }
288
289 RegCloseKey (hUserKey);
290
291 *Sid = lpSid;
292
293 return TRUE;
294 }
295
296
297 static BOOL STDCALL
298 SamGetDomainSid(PSID *Sid)
299 {
300 PSID lpSid;
301 DWORD dwLength;
302 HKEY hDomainKey;
303
304 TRACE("SamGetDomainSid() called\n");
305
306 if (Sid != NULL)
307 *Sid = NULL;
308
309 /* Open the account domain key */
310 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
311 L"SAM\\SAM\\Domains\\Account",
312 0,
313 KEY_READ,
314 &hDomainKey))
315 {
316 ERR("Failed to open the account domain key! (Error %lu)\n", GetLastError());
317 return FALSE;
318 }
319
320 /* Get SID size */
321 dwLength = 0;
322 if (RegQueryValueExW(hDomainKey,
323 L"Sid",
324 NULL,
325 NULL,
326 NULL,
327 &dwLength))
328 {
329 ERR("Failed to read the SID size! (Error %lu)\n", GetLastError());
330 RegCloseKey(hDomainKey);
331 return FALSE;
332 }
333
334 /* Allocate sid buffer */
335 TRACE("Required SID buffer size: %lu\n", dwLength);
336 lpSid = (PSID)RtlAllocateHeap(RtlGetProcessHeap(),
337 0,
338 dwLength);
339 if (lpSid == NULL)
340 {
341 ERR("Failed to allocate SID buffer!\n");
342 RegCloseKey(hDomainKey);
343 return FALSE;
344 }
345
346 /* Read sid */
347 if (RegQueryValueExW(hDomainKey,
348 L"Sid",
349 NULL,
350 NULL,
351 (LPBYTE)lpSid,
352 &dwLength))
353 {
354 ERR("Failed to read the SID! (Error %lu)\n", GetLastError());
355 RtlFreeHeap(RtlGetProcessHeap(),
356 0,
357 lpSid);
358 RegCloseKey(hDomainKey);
359 return FALSE;
360 }
361
362 RegCloseKey(hDomainKey);
363
364 *Sid = lpSid;
365
366 TRACE("SamGetDomainSid() done\n");
367
368 return TRUE;
369 }
370
371
372 static PSID
373 AppendRidToSid(PSID SrcSid,
374 ULONG Rid)
375 {
376 ULONG Rids[8] = {0, 0, 0, 0, 0, 0, 0, 0};
377 UCHAR RidCount;
378 PSID DstSid;
379 ULONG i;
380
381 RidCount = *RtlSubAuthorityCountSid(SrcSid);
382 if (RidCount >= 8)
383 return NULL;
384
385 for (i = 0; i < RidCount; i++)
386 Rids[i] = *RtlSubAuthoritySid(SrcSid, i);
387
388 Rids[RidCount] = Rid;
389 RidCount++;
390
391 RtlAllocateAndInitializeSid(RtlIdentifierAuthoritySid(SrcSid),
392 RidCount,
393 Rids[0],
394 Rids[1],
395 Rids[2],
396 Rids[3],
397 Rids[4],
398 Rids[5],
399 Rids[6],
400 Rids[7],
401 &DstSid);
402
403 return DstSid;
404 }
405
406
407 static PTOKEN_GROUPS
408 AllocateGroupSids(
409 OUT PSID *PrimaryGroupSid,
410 OUT PSID *OwnerSid)
411 {
412 SID_IDENTIFIER_AUTHORITY WorldAuthority = {SECURITY_WORLD_SID_AUTHORITY};
413 SID_IDENTIFIER_AUTHORITY LocalAuthority = {SECURITY_LOCAL_SID_AUTHORITY};
414 SID_IDENTIFIER_AUTHORITY SystemAuthority = {SECURITY_NT_AUTHORITY};
415 PTOKEN_GROUPS TokenGroups;
416 #define MAX_GROUPS 8
417 DWORD GroupCount = 0;
418 PSID DomainSid;
419 PSID Sid;
420 LUID Luid;
421 NTSTATUS Status;
422
423 Status = NtAllocateLocallyUniqueId(&Luid);
424 if (!NT_SUCCESS(Status))
425 return NULL;
426
427 if (!SamGetDomainSid(&DomainSid))
428 return NULL;
429
430 TokenGroups = RtlAllocateHeap(
431 GetProcessHeap(), 0,
432 sizeof(TOKEN_GROUPS) +
433 MAX_GROUPS * sizeof(SID_AND_ATTRIBUTES));
434 if (TokenGroups == NULL)
435 {
436 RtlFreeHeap(RtlGetProcessHeap(), 0, DomainSid);
437 return NULL;
438 }
439
440 Sid = AppendRidToSid(DomainSid, DOMAIN_GROUP_RID_USERS);
441 RtlFreeHeap(RtlGetProcessHeap(), 0, DomainSid);
442
443 /* Member of the domain */
444 TokenGroups->Groups[GroupCount].Sid = Sid;
445 TokenGroups->Groups[GroupCount].Attributes = SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY;
446 *PrimaryGroupSid = Sid;
447 GroupCount++;
448
449 /* Member of 'Everyone' */
450 RtlAllocateAndInitializeSid(
451 &WorldAuthority,
452 1,
453 SECURITY_WORLD_RID,
454 SECURITY_NULL_RID,
455 SECURITY_NULL_RID,
456 SECURITY_NULL_RID,
457 SECURITY_NULL_RID,
458 SECURITY_NULL_RID,
459 SECURITY_NULL_RID,
460 SECURITY_NULL_RID,
461 &Sid);
462 TokenGroups->Groups[GroupCount].Sid = Sid;
463 TokenGroups->Groups[GroupCount].Attributes = SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY;
464 GroupCount++;
465
466 #if 1
467 /* Member of 'Administrators' */
468 RtlAllocateAndInitializeSid(
469 &SystemAuthority,
470 2,
471 SECURITY_BUILTIN_DOMAIN_RID,
472 DOMAIN_ALIAS_RID_ADMINS,
473 SECURITY_NULL_RID,
474 SECURITY_NULL_RID,
475 SECURITY_NULL_RID,
476 SECURITY_NULL_RID,
477 SECURITY_NULL_RID,
478 SECURITY_NULL_RID,
479 &Sid);
480 TokenGroups->Groups[GroupCount].Sid = Sid;
481 TokenGroups->Groups[GroupCount].Attributes = SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY;
482 GroupCount++;
483 #else
484 TRACE("Not adding user to Administrators group\n");
485 #endif
486
487 /* Member of 'Users' */
488 RtlAllocateAndInitializeSid(
489 &SystemAuthority,
490 2,
491 SECURITY_BUILTIN_DOMAIN_RID,
492 DOMAIN_ALIAS_RID_USERS,
493 SECURITY_NULL_RID,
494 SECURITY_NULL_RID,
495 SECURITY_NULL_RID,
496 SECURITY_NULL_RID,
497 SECURITY_NULL_RID,
498 SECURITY_NULL_RID,
499 &Sid);
500 TokenGroups->Groups[GroupCount].Sid = Sid;
501 TokenGroups->Groups[GroupCount].Attributes = SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY;
502 GroupCount++;
503
504 /* Logon SID */
505 RtlAllocateAndInitializeSid(
506 &SystemAuthority,
507 SECURITY_LOGON_IDS_RID_COUNT,
508 SECURITY_LOGON_IDS_RID,
509 Luid.HighPart,
510 Luid.LowPart,
511 SECURITY_NULL_RID,
512 SECURITY_NULL_RID,
513 SECURITY_NULL_RID,
514 SECURITY_NULL_RID,
515 SECURITY_NULL_RID,
516 &Sid);
517 TokenGroups->Groups[GroupCount].Sid = Sid;
518 TokenGroups->Groups[GroupCount].Attributes = SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY | SE_GROUP_LOGON_ID;
519 GroupCount++;
520 *OwnerSid = Sid;
521
522 /* Member of 'Local users */
523 RtlAllocateAndInitializeSid(
524 &LocalAuthority,
525 1,
526 SECURITY_LOCAL_RID,
527 SECURITY_NULL_RID,
528 SECURITY_NULL_RID,
529 SECURITY_NULL_RID,
530 SECURITY_NULL_RID,
531 SECURITY_NULL_RID,
532 SECURITY_NULL_RID,
533 SECURITY_NULL_RID,
534 &Sid);
535 TokenGroups->Groups[GroupCount].Sid = Sid;
536 TokenGroups->Groups[GroupCount].Attributes = SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY;
537 GroupCount++;
538
539 /* Member of 'Interactive users' */
540 RtlAllocateAndInitializeSid(
541 &SystemAuthority,
542 1,
543 SECURITY_INTERACTIVE_RID,
544 SECURITY_NULL_RID,
545 SECURITY_NULL_RID,
546 SECURITY_NULL_RID,
547 SECURITY_NULL_RID,
548 SECURITY_NULL_RID,
549 SECURITY_NULL_RID,
550 SECURITY_NULL_RID,
551 &Sid);
552 TokenGroups->Groups[GroupCount].Sid = Sid;
553 TokenGroups->Groups[GroupCount].Attributes = SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY;
554 GroupCount++;
555
556 /* Member of 'Authenticated users' */
557 RtlAllocateAndInitializeSid(
558 &SystemAuthority,
559 1,
560 SECURITY_AUTHENTICATED_USER_RID,
561 SECURITY_NULL_RID,
562 SECURITY_NULL_RID,
563 SECURITY_NULL_RID,
564 SECURITY_NULL_RID,
565 SECURITY_NULL_RID,
566 SECURITY_NULL_RID,
567 SECURITY_NULL_RID,
568 &Sid);
569 TokenGroups->Groups[GroupCount].Sid = Sid;
570 TokenGroups->Groups[GroupCount].Attributes = SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY;
571 GroupCount++;
572
573 TokenGroups->GroupCount = GroupCount;
574 ASSERT(TokenGroups->GroupCount <= MAX_GROUPS);
575
576 return TokenGroups;
577 }
578
579
580 static VOID
581 FreeGroupSids(PTOKEN_GROUPS TokenGroups)
582 {
583 ULONG i;
584
585 for (i = 0; i < TokenGroups->GroupCount; i++)
586 {
587 if (TokenGroups->Groups[i].Sid != NULL)
588 RtlFreeHeap(GetProcessHeap(), 0, TokenGroups->Groups[i].Sid);
589 }
590
591 RtlFreeHeap(GetProcessHeap(), 0, TokenGroups);
592 }
593
594
595 /*
596 * @unimplemented
597 */
598 BOOL STDCALL
599 LogonUserW (LPWSTR lpszUsername,
600 LPWSTR lpszDomain,
601 LPWSTR lpszPassword,
602 DWORD dwLogonType,
603 DWORD dwLogonProvider,
604 PHANDLE phToken)
605 {
606 /* FIXME shouldn't use hard-coded list of privileges */
607 static struct
608 {
609 LPCWSTR PrivName;
610 DWORD Attributes;
611 }
612 DefaultPrivs[] =
613 {
614 { L"SeUnsolicitedInputPrivilege", 0 },
615 { L"SeMachineAccountPrivilege", 0 },
616 { L"SeSecurityPrivilege", 0 },
617 { L"SeTakeOwnershipPrivilege", 0 },
618 { L"SeLoadDriverPrivilege", 0 },
619 { L"SeSystemProfilePrivilege", 0 },
620 { L"SeSystemtimePrivilege", 0 },
621 { L"SeProfileSingleProcessPrivilege", 0 },
622 { L"SeIncreaseBasePriorityPrivilege", 0 },
623 { L"SeCreatePagefilePrivilege", 0 },
624 { L"SeBackupPrivilege", 0 },
625 { L"SeRestorePrivilege", 0 },
626 { L"SeShutdownPrivilege", 0 },
627 { L"SeDebugPrivilege", 0 },
628 { L"SeSystemEnvironmentPrivilege", 0 },
629 { L"SeChangeNotifyPrivilege", SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT },
630 { L"SeRemoteShutdownPrivilege", 0 },
631 { L"SeUndockPrivilege", 0 },
632 { L"SeEnableDelegationPrivilege", 0 },
633 { L"SeImpersonatePrivilege", SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT },
634 { L"SeCreateGlobalPrivilege", SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT }
635 };
636 OBJECT_ATTRIBUTES ObjectAttributes;
637 SECURITY_QUALITY_OF_SERVICE Qos;
638 TOKEN_USER TokenUser;
639 TOKEN_OWNER TokenOwner;
640 TOKEN_PRIMARY_GROUP TokenPrimaryGroup;
641 PTOKEN_GROUPS TokenGroups;
642 PTOKEN_PRIVILEGES TokenPrivileges;
643 TOKEN_DEFAULT_DACL TokenDefaultDacl;
644 LARGE_INTEGER ExpirationTime;
645 LUID AuthenticationId;
646 TOKEN_SOURCE TokenSource;
647 PSID UserSid = NULL;
648 PSID PrimaryGroupSid = NULL;
649 PSID OwnerSid = NULL;
650 PSID LocalSystemSid;
651 PACL Dacl;
652 NTSTATUS Status;
653 SID_IDENTIFIER_AUTHORITY SystemAuthority = {SECURITY_NT_AUTHORITY};
654 unsigned i;
655
656 Qos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
657 Qos.ImpersonationLevel = SecurityAnonymous;
658 Qos.ContextTrackingMode = SECURITY_STATIC_TRACKING;
659 Qos.EffectiveOnly = FALSE;
660
661 ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
662 ObjectAttributes.RootDirectory = NULL;
663 ObjectAttributes.ObjectName = NULL;
664 ObjectAttributes.Attributes = 0;
665 ObjectAttributes.SecurityDescriptor = NULL;
666 ObjectAttributes.SecurityQualityOfService = &Qos;
667
668 Status = NtAllocateLocallyUniqueId(&AuthenticationId);
669 if (!NT_SUCCESS(Status))
670 {
671 return FALSE;
672 }
673 ExpirationTime.QuadPart = -1;
674
675 /* Get the user SID from the registry */
676 if (!SamGetUserSid (lpszUsername, &UserSid))
677 {
678 ERR("SamGetUserSid() failed\n");
679 return FALSE;
680 }
681
682 TokenUser.User.Sid = UserSid;
683 TokenUser.User.Attributes = 0;
684
685 /* Allocate and initialize token groups */
686 TokenGroups = AllocateGroupSids(&PrimaryGroupSid,
687 &OwnerSid);
688 if (NULL == TokenGroups)
689 {
690 RtlFreeSid(UserSid);
691 SetLastError(ERROR_OUTOFMEMORY);
692 return FALSE;
693 }
694
695 /* Allocate and initialize token privileges */
696 TokenPrivileges = RtlAllocateHeap(GetProcessHeap(), 0,
697 sizeof(TOKEN_PRIVILEGES)
698 + sizeof(DefaultPrivs) / sizeof(DefaultPrivs[0])
699 * sizeof(LUID_AND_ATTRIBUTES));
700 if (NULL == TokenPrivileges)
701 {
702 FreeGroupSids(TokenGroups);
703 RtlFreeSid(UserSid);
704 SetLastError(ERROR_OUTOFMEMORY);
705 return FALSE;
706 }
707
708 TokenPrivileges->PrivilegeCount = 0;
709 for (i = 0; i < sizeof(DefaultPrivs) / sizeof(DefaultPrivs[0]); i++)
710 {
711 if (! LookupPrivilegeValueW(NULL, DefaultPrivs[i].PrivName,
712 &TokenPrivileges->Privileges[TokenPrivileges->PrivilegeCount].Luid))
713 {
714 WARN("Can't set privilege %S\n", DefaultPrivs[i].PrivName);
715 }
716 else
717 {
718 TokenPrivileges->Privileges[TokenPrivileges->PrivilegeCount].Attributes = DefaultPrivs[i].Attributes;
719 TokenPrivileges->PrivilegeCount++;
720 }
721 }
722
723 TokenOwner.Owner = OwnerSid;
724 TokenPrimaryGroup.PrimaryGroup = PrimaryGroupSid;
725
726
727 Dacl = RtlAllocateHeap(GetProcessHeap(), 0, 1024);
728 if (Dacl == NULL)
729 {
730 FreeGroupSids(TokenGroups);
731 RtlFreeSid(UserSid);
732 SetLastError(ERROR_OUTOFMEMORY);
733 return FALSE;
734 }
735
736 Status = RtlCreateAcl(Dacl, 1024, ACL_REVISION);
737 if (!NT_SUCCESS(Status))
738 {
739 RtlFreeHeap(GetProcessHeap(), 0, Dacl);
740 FreeGroupSids(TokenGroups);
741 RtlFreeHeap(GetProcessHeap(), 0, TokenPrivileges);
742 RtlFreeSid(UserSid);
743 return FALSE;
744 }
745
746 RtlAddAccessAllowedAce(Dacl,
747 ACL_REVISION,
748 GENERIC_ALL,
749 OwnerSid);
750
751 RtlAllocateAndInitializeSid(&SystemAuthority,
752 1,
753 SECURITY_LOCAL_SYSTEM_RID,
754 SECURITY_NULL_RID,
755 SECURITY_NULL_RID,
756 SECURITY_NULL_RID,
757 SECURITY_NULL_RID,
758 SECURITY_NULL_RID,
759 SECURITY_NULL_RID,
760 SECURITY_NULL_RID,
761 &LocalSystemSid);
762
763 /* SID: S-1-5-18 */
764 RtlAddAccessAllowedAce(Dacl,
765 ACL_REVISION,
766 GENERIC_ALL,
767 LocalSystemSid);
768
769 RtlFreeSid(LocalSystemSid);
770
771 TokenDefaultDacl.DefaultDacl = Dacl;
772
773 memcpy(TokenSource.SourceName,
774 "User32 ",
775 8);
776 Status = NtAllocateLocallyUniqueId(&TokenSource.SourceIdentifier);
777 if (!NT_SUCCESS(Status))
778 {
779 RtlFreeHeap(GetProcessHeap(), 0, Dacl);
780 FreeGroupSids(TokenGroups);
781 RtlFreeHeap(GetProcessHeap(), 0, TokenPrivileges);
782 RtlFreeSid(UserSid);
783 return FALSE;
784 }
785
786 Status = NtCreateToken(phToken,
787 TOKEN_ALL_ACCESS,
788 &ObjectAttributes,
789 TokenPrimary,
790 &AuthenticationId,
791 &ExpirationTime,
792 &TokenUser,
793 TokenGroups,
794 TokenPrivileges,
795 &TokenOwner,
796 &TokenPrimaryGroup,
797 &TokenDefaultDacl,
798 &TokenSource);
799
800 RtlFreeHeap(GetProcessHeap(), 0, Dacl);
801 FreeGroupSids(TokenGroups);
802 RtlFreeHeap(GetProcessHeap(), 0, TokenPrivileges);
803 RtlFreeSid(UserSid);
804
805 return NT_SUCCESS(Status);
806 }
807
808 /* EOF */