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