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
10 WINE_DEFAULT_DEBUG_CHANNEL(advapi
);
13 /* FUNCTIONS ***************************************************************/
19 CreateProcessAsUserA(HANDLE hToken
,
20 LPCSTR lpApplicationName
,
22 LPSECURITY_ATTRIBUTES lpProcessAttributes
,
23 LPSECURITY_ATTRIBUTES lpThreadAttributes
,
25 DWORD dwCreationFlags
,
27 LPCSTR lpCurrentDirectory
,
28 LPSTARTUPINFOA lpStartupInfo
,
29 LPPROCESS_INFORMATION lpProcessInformation
)
31 PROCESS_ACCESS_TOKEN AccessToken
;
34 /* Create the process with a suspended main thread */
35 if (!CreateProcessA(lpApplicationName
,
40 dwCreationFlags
| CREATE_SUSPENDED
,
44 lpProcessInformation
))
49 AccessToken
.Token
= hToken
;
50 AccessToken
.Thread
= NULL
;
52 /* Set the new process token */
53 Status
= NtSetInformationProcess(lpProcessInformation
->hProcess
,
57 if (!NT_SUCCESS (Status
))
59 SetLastError(RtlNtStatusToDosError(Status
));
63 /* Resume the main thread */
64 if (!(dwCreationFlags
& CREATE_SUSPENDED
))
66 ResumeThread(lpProcessInformation
->hThread
);
77 CreateProcessAsUserW(HANDLE hToken
,
78 LPCWSTR lpApplicationName
,
80 LPSECURITY_ATTRIBUTES lpProcessAttributes
,
81 LPSECURITY_ATTRIBUTES lpThreadAttributes
,
83 DWORD dwCreationFlags
,
85 LPCWSTR lpCurrentDirectory
,
86 LPSTARTUPINFOW lpStartupInfo
,
87 LPPROCESS_INFORMATION lpProcessInformation
)
89 PROCESS_ACCESS_TOKEN AccessToken
;
92 /* Create the process with a suspended main thread */
93 if (!CreateProcessW(lpApplicationName
,
98 dwCreationFlags
| CREATE_SUSPENDED
,
102 lpProcessInformation
))
107 AccessToken
.Token
= hToken
;
108 AccessToken
.Thread
= NULL
;
110 /* Set the new process token */
111 Status
= NtSetInformationProcess(lpProcessInformation
->hProcess
,
114 sizeof(AccessToken
));
115 if (!NT_SUCCESS (Status
))
117 SetLastError(RtlNtStatusToDosError(Status
));
121 /* Resume the main thread */
122 if (!(dwCreationFlags
& CREATE_SUSPENDED
))
124 ResumeThread(lpProcessInformation
->hThread
);
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
)
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
);
149 LogonUserA(LPSTR lpszUsername
,
153 DWORD dwLogonProvider
,
156 UNICODE_STRING UserName
;
157 UNICODE_STRING Domain
;
158 UNICODE_STRING Password
;
161 UserName
.Buffer
= NULL
;
162 Domain
.Buffer
= NULL
;
163 Password
.Buffer
= NULL
;
165 if (!RtlCreateUnicodeStringFromAsciiz(&UserName
, lpszUsername
))
167 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
171 if (!RtlCreateUnicodeStringFromAsciiz(&Domain
, lpszDomain
))
173 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
177 if (!RtlCreateUnicodeStringFromAsciiz(&Password
, lpszPassword
))
179 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
183 ret
= LogonUserW(UserName
.Buffer
,
190 if (Password
.Buffer
!= NULL
)
191 RtlFreeUnicodeString(&Password
);
194 if (Domain
.Buffer
!= NULL
)
195 RtlFreeUnicodeString(&Domain
);
198 if (UserName
.Buffer
!= NULL
)
199 RtlFreeUnicodeString(&UserName
);
207 GetAccountDomainSid(PSID
*Sid
)
209 PPOLICY_ACCOUNT_DOMAIN_INFO Info
= NULL
;
210 LSA_OBJECT_ATTRIBUTES ObjectAttributes
;
211 LSA_HANDLE PolicyHandle
;
218 memset(&ObjectAttributes
, 0, sizeof(LSA_OBJECT_ATTRIBUTES
));
219 ObjectAttributes
.Length
= sizeof(LSA_OBJECT_ATTRIBUTES
);
221 Status
= LsaOpenPolicy(NULL
,
223 POLICY_VIEW_LOCAL_INFORMATION
,
225 if (!NT_SUCCESS(Status
))
227 ERR("LsaOpenPolicy failed (Status: 0x%08lx)\n", Status
);
231 Status
= LsaQueryInformationPolicy(PolicyHandle
,
232 PolicyAccountDomainInformation
,
234 if (!NT_SUCCESS(Status
))
236 ERR("LsaQueryInformationPolicy failed (Status: 0x%08lx)\n", Status
);
237 LsaClose(PolicyHandle
);
241 Length
= RtlLengthSid(Info
->DomainSid
);
243 lpSid
= RtlAllocateHeap(RtlGetProcessHeap(),
248 ERR("Failed to allocate SID buffer!\n");
250 LsaClose(PolicyHandle
);
254 memcpy(lpSid
, Info
->DomainSid
, Length
);
259 LsaClose(PolicyHandle
);
266 AppendRidToSid(PSID SrcSid
,
269 ULONG Rids
[8] = {0, 0, 0, 0, 0, 0, 0, 0};
274 RidCount
= *RtlSubAuthorityCountSid(SrcSid
);
278 for (i
= 0; i
< RidCount
; i
++)
279 Rids
[i
] = *RtlSubAuthoritySid(SrcSid
, i
);
281 Rids
[RidCount
] = Rid
;
284 RtlAllocateAndInitializeSid(RtlIdentifierAuthoritySid(SrcSid
),
301 GetUserSid(LPCWSTR UserName
,
313 /* Open the Users key */
314 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
315 L
"SAM\\SAM\\Domains\\Account\\Users",
320 ERR("Failed to open Users key! (Error %lu)\n", GetLastError());
324 /* Open the user key */
325 if (RegOpenKeyExW(hUsersKey
,
331 if (GetLastError() == ERROR_FILE_NOT_FOUND
)
333 ERR("Invalid user name!\n");
334 SetLastError(ERROR_NO_SUCH_USER
);
338 ERR("Failed to open user key! (Error %lu)\n", GetLastError());
341 RegCloseKey(hUsersKey
);
345 RegCloseKey (hUsersKey
);
349 if (RegQueryValueExW(hUserKey
,
356 ERR("Failed to read the SID size! (Error %lu)\n", GetLastError());
357 RegCloseKey(hUserKey
);
361 /* Allocate sid buffer */
362 TRACE("Required SID buffer size: %lu\n", dwLength
);
363 lpSid
= (PSID
)RtlAllocateHeap(RtlGetProcessHeap(),
368 ERR("Failed to allocate SID buffer!\n");
369 RegCloseKey(hUserKey
);
374 if (RegQueryValueExW(hUserKey
,
381 ERR("Failed to read the SID! (Error %lu)\n", GetLastError());
382 RtlFreeHeap(RtlGetProcessHeap(),
385 RegCloseKey(hUserKey
);
389 RegCloseKey(hUserKey
);
396 PSID AccountDomainSid
= NULL
;
399 HKEY hNamesKey
= NULL
;
402 if (!GetAccountDomainSid(&AccountDomainSid
))
407 /* Open the Users\Names key */
408 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
409 L
"SAM\\SAM\\Domains\\Account\\Users\\Names",
414 ERR("Failed to open Users\\Names key! (Error %lu)\n", GetLastError());
419 /* Read the user RID */
420 dwLength
= sizeof(ULONG
);
421 if (RegQueryValueExW(hNamesKey
,
428 ERR("Failed to read the SID! (Error %ld)\n", GetLastError());
433 *Sid
= AppendRidToSid(AccountDomainSid
, ulUserRid
);
436 if (hNamesKey
!= NULL
)
437 RegCloseKey(hNamesKey
);
439 if (AccountDomainSid
!= NULL
)
440 RtlFreeHeap(RtlGetProcessHeap(), 0, AccountDomainSid
);
447 AllocateGroupSids(OUT PSID
*PrimaryGroupSid
,
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
;
455 DWORD GroupCount
= 0;
461 Status
= NtAllocateLocallyUniqueId(&Luid
);
462 if (!NT_SUCCESS(Status
))
465 if (!GetAccountDomainSid(&DomainSid
))
468 TokenGroups
= RtlAllocateHeap(
470 sizeof(TOKEN_GROUPS
) +
471 MAX_GROUPS
* sizeof(SID_AND_ATTRIBUTES
));
472 if (TokenGroups
== NULL
)
474 RtlFreeHeap(RtlGetProcessHeap(), 0, DomainSid
);
478 Sid
= AppendRidToSid(DomainSid
, DOMAIN_GROUP_RID_USERS
);
479 RtlFreeHeap(RtlGetProcessHeap(), 0, DomainSid
);
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
;
488 /* Member of 'Everyone' */
489 RtlAllocateAndInitializeSid(&WorldAuthority
,
500 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
501 TokenGroups
->Groups
[GroupCount
].Attributes
=
502 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
506 /* Member of 'Administrators' */
507 RtlAllocateAndInitializeSid(&SystemAuthority
,
509 SECURITY_BUILTIN_DOMAIN_RID
,
510 DOMAIN_ALIAS_RID_ADMINS
,
518 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
519 TokenGroups
->Groups
[GroupCount
].Attributes
=
520 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
523 TRACE("Not adding user to Administrators group\n");
526 /* Member of 'Users' */
527 RtlAllocateAndInitializeSid(&SystemAuthority
,
529 SECURITY_BUILTIN_DOMAIN_RID
,
530 DOMAIN_ALIAS_RID_USERS
,
538 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
539 TokenGroups
->Groups
[GroupCount
].Attributes
=
540 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
544 RtlAllocateAndInitializeSid(&SystemAuthority
,
545 SECURITY_LOGON_IDS_RID_COUNT
,
546 SECURITY_LOGON_IDS_RID
,
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
;
561 /* Member of 'Local users */
562 RtlAllocateAndInitializeSid(&LocalAuthority
,
573 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
574 TokenGroups
->Groups
[GroupCount
].Attributes
=
575 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
578 /* Member of 'Interactive users' */
579 RtlAllocateAndInitializeSid(&SystemAuthority
,
581 SECURITY_INTERACTIVE_RID
,
590 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
591 TokenGroups
->Groups
[GroupCount
].Attributes
=
592 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
595 /* Member of 'Authenticated users' */
596 RtlAllocateAndInitializeSid(&SystemAuthority
,
598 SECURITY_AUTHENTICATED_USER_RID
,
607 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
608 TokenGroups
->Groups
[GroupCount
].Attributes
=
609 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
612 TokenGroups
->GroupCount
= GroupCount
;
613 ASSERT(TokenGroups
->GroupCount
<= MAX_GROUPS
);
620 FreeGroupSids(PTOKEN_GROUPS TokenGroups
)
624 for (i
= 0; i
< TokenGroups
->GroupCount
; i
++)
626 if (TokenGroups
->Groups
[i
].Sid
!= NULL
)
627 RtlFreeHeap(GetProcessHeap(), 0, TokenGroups
->Groups
[i
].Sid
);
630 RtlFreeHeap(GetProcessHeap(), 0, TokenGroups
);
638 LogonUserW(LPWSTR lpszUsername
,
642 DWORD dwLogonProvider
,
645 /* FIXME shouldn't use hard-coded list of privileges */
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
}
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
;
686 PSID PrimaryGroupSid
= NULL
;
687 PSID OwnerSid
= NULL
;
691 SID_IDENTIFIER_AUTHORITY SystemAuthority
= {SECURITY_NT_AUTHORITY
};
694 Qos
.Length
= sizeof(SECURITY_QUALITY_OF_SERVICE
);
695 Qos
.ImpersonationLevel
= SecurityAnonymous
;
696 Qos
.ContextTrackingMode
= SECURITY_STATIC_TRACKING
;
697 Qos
.EffectiveOnly
= FALSE
;
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
;
706 Status
= NtAllocateLocallyUniqueId(&AuthenticationId
);
707 if (!NT_SUCCESS(Status
))
712 ExpirationTime
.QuadPart
= -1;
714 /* Get the user SID from the registry */
715 if (!GetUserSid (lpszUsername
, &UserSid
))
717 ERR("SamGetUserSid() failed\n");
721 TokenUser
.User
.Sid
= UserSid
;
722 TokenUser
.User
.Attributes
= 0;
724 /* Allocate and initialize token groups */
725 TokenGroups
= AllocateGroupSids(&PrimaryGroupSid
,
727 if (NULL
== TokenGroups
)
730 SetLastError(ERROR_OUTOFMEMORY
);
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
)
741 FreeGroupSids(TokenGroups
);
743 SetLastError(ERROR_OUTOFMEMORY
);
747 TokenPrivileges
->PrivilegeCount
= 0;
748 for (i
= 0; i
< sizeof(DefaultPrivs
) / sizeof(DefaultPrivs
[0]); i
++)
750 if (! LookupPrivilegeValueW(NULL
,
751 DefaultPrivs
[i
].PrivName
,
752 &TokenPrivileges
->Privileges
[TokenPrivileges
->PrivilegeCount
].Luid
))
754 WARN("Can't set privilege %S\n", DefaultPrivs
[i
].PrivName
);
758 TokenPrivileges
->Privileges
[TokenPrivileges
->PrivilegeCount
].Attributes
= DefaultPrivs
[i
].Attributes
;
759 TokenPrivileges
->PrivilegeCount
++;
763 TokenOwner
.Owner
= OwnerSid
;
764 TokenPrimaryGroup
.PrimaryGroup
= PrimaryGroupSid
;
766 Dacl
= RtlAllocateHeap(GetProcessHeap(), 0, 1024);
769 FreeGroupSids(TokenGroups
);
771 SetLastError(ERROR_OUTOFMEMORY
);
775 Status
= RtlCreateAcl(Dacl
, 1024, ACL_REVISION
);
776 if (!NT_SUCCESS(Status
))
778 RtlFreeHeap(GetProcessHeap(), 0, Dacl
);
779 FreeGroupSids(TokenGroups
);
780 RtlFreeHeap(GetProcessHeap(), 0, TokenPrivileges
);
785 RtlAddAccessAllowedAce(Dacl
,
790 RtlAllocateAndInitializeSid(&SystemAuthority
,
792 SECURITY_LOCAL_SYSTEM_RID
,
803 RtlAddAccessAllowedAce(Dacl
,
808 RtlFreeSid(LocalSystemSid
);
810 TokenDefaultDacl
.DefaultDacl
= Dacl
;
812 memcpy(TokenSource
.SourceName
,
816 Status
= NtAllocateLocallyUniqueId(&TokenSource
.SourceIdentifier
);
817 if (!NT_SUCCESS(Status
))
819 RtlFreeHeap(GetProcessHeap(), 0, Dacl
);
820 FreeGroupSids(TokenGroups
);
821 RtlFreeHeap(GetProcessHeap(), 0, TokenPrivileges
);
826 Status
= NtCreateToken(phToken
,
840 RtlFreeHeap(GetProcessHeap(), 0, Dacl
);
841 FreeGroupSids(TokenGroups
);
842 RtlFreeHeap(GetProcessHeap(), 0, TokenPrivileges
);
845 return NT_SUCCESS(Status
);