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