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