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