X-Git-Url: https://git.reactos.org/?p=reactos.git;a=blobdiff_plain;f=dll%2Fwin32%2Fadvapi32%2Fmisc%2Flogon.c;h=1262f1b652d1dba4f2332f5c7b28ac22d1386097;hp=950b425824c4742c6e0f3ab00d06b29c7a555e13;hb=f3a9b524f102eb4c9f8759d0c51990e354f488a2;hpb=25445ea35f5286c9367faa6bcac147ff4d371d2e diff --git a/dll/win32/advapi32/misc/logon.c b/dll/win32/advapi32/misc/logon.c index 950b425824c..1262f1b652d 100644 --- a/dll/win32/advapi32/misc/logon.c +++ b/dll/win32/advapi32/misc/logon.c @@ -9,61 +9,217 @@ #include WINE_DEFAULT_DEBUG_CHANNEL(advapi); +/* GLOBALS *****************************************************************/ + +static const CHAR AdvapiTokenSourceName[] = "Advapi "; +C_ASSERT(sizeof(AdvapiTokenSourceName) == RTL_FIELD_SIZE(TOKEN_SOURCE, SourceName) + 1); + +HANDLE LsaHandle = NULL; +ULONG AuthenticationPackage = 0; /* FUNCTIONS ***************************************************************/ -/* - * @implemented - */ -BOOL WINAPI -CreateProcessAsUserA(HANDLE hToken, - LPCSTR lpApplicationName, - LPSTR lpCommandLine, - LPSECURITY_ATTRIBUTES lpProcessAttributes, - LPSECURITY_ATTRIBUTES lpThreadAttributes, - BOOL bInheritHandles, - DWORD dwCreationFlags, - LPVOID lpEnvironment, - LPCSTR lpCurrentDirectory, - LPSTARTUPINFOA lpStartupInfo, - LPPROCESS_INFORMATION lpProcessInformation) +static +NTSTATUS +OpenLogonLsaHandle(VOID) { - PROCESS_ACCESS_TOKEN AccessToken; + LSA_STRING LogonProcessName; + LSA_STRING PackageName; + LSA_OPERATIONAL_MODE SecurityMode = 0; NTSTATUS Status; - /* Create the process with a suspended main thread */ - if (!CreateProcessA(lpApplicationName, - lpCommandLine, - lpProcessAttributes, - lpThreadAttributes, - bInheritHandles, - dwCreationFlags | CREATE_SUSPENDED, - lpEnvironment, - lpCurrentDirectory, - lpStartupInfo, - lpProcessInformation)) + RtlInitAnsiString((PANSI_STRING)&LogonProcessName, + "User32LogonProcess"); + + Status = LsaRegisterLogonProcess(&LogonProcessName, + &LsaHandle, + &SecurityMode); + if (!NT_SUCCESS(Status)) { - return FALSE; + TRACE("LsaRegisterLogonProcess failed (Status 0x%08lx)\n", Status); + goto done; } - AccessToken.Token = hToken; - AccessToken.Thread = NULL; + RtlInitAnsiString((PANSI_STRING)&PackageName, + MSV1_0_PACKAGE_NAME); - /* Set the new process token */ - Status = NtSetInformationProcess(lpProcessInformation->hProcess, - ProcessAccessToken, - (PVOID)&AccessToken, - sizeof(AccessToken)); - if (!NT_SUCCESS (Status)) + Status = LsaLookupAuthenticationPackage(LsaHandle, + &PackageName, + &AuthenticationPackage); + if (!NT_SUCCESS(Status)) { - SetLastError(RtlNtStatusToDosError(Status)); - return FALSE; + TRACE("LsaLookupAuthenticationPackage failed (Status 0x%08lx)\n", Status); + goto done; + } + + TRACE("AuthenticationPackage: 0x%08lx\n", AuthenticationPackage); + +done: + if (!NT_SUCCESS(Status)) + { + if (LsaHandle != NULL) + { + Status = LsaDeregisterLogonProcess(LsaHandle); + if (!NT_SUCCESS(Status)) + { + TRACE("LsaDeregisterLogonProcess failed (Status 0x%08lx)\n", Status); + } + } + } + + return Status; +} + + +NTSTATUS +CloseLogonLsaHandle(VOID) +{ + NTSTATUS Status = STATUS_SUCCESS; + + if (LsaHandle != NULL) + { + Status = LsaDeregisterLogonProcess(LsaHandle); + if (!NT_SUCCESS(Status)) + { + TRACE("LsaDeregisterLogonProcess failed (Status 0x%08lx)\n", Status); + } + } + + return Status; +} + + +static +BOOL +CreateProcessAsUserCommon( + _In_opt_ HANDLE hToken, + _In_ DWORD dwCreationFlags, + _Out_ LPPROCESS_INFORMATION lpProcessInformation) +{ + NTSTATUS Status; + PROCESS_ACCESS_TOKEN AccessToken; + + if (hToken != NULL) + { + TOKEN_TYPE Type; + ULONG ReturnLength; + OBJECT_ATTRIBUTES ObjectAttributes; + HANDLE hTokenDup; + BOOLEAN PrivilegeSet = FALSE, HavePrivilege; + + /* Check whether the user-provided token is a primary token */ + // GetTokenInformation(); + Status = NtQueryInformationToken(hToken, + TokenType, + &Type, + sizeof(Type), + &ReturnLength); + if (!NT_SUCCESS(Status)) + { + ERR("NtQueryInformationToken() failed, Status 0x%08x\n", Status); + goto Quit; + } + if (Type != TokenPrimary) + { + ERR("Wrong token type for token 0x%p, expected TokenPrimary, got %ld\n", hToken, Type); + Status = STATUS_BAD_TOKEN_TYPE; + goto Quit; + } + + /* Duplicate the token for this new process */ + InitializeObjectAttributes(&ObjectAttributes, + NULL, + 0, + NULL, + NULL); // FIXME: Use a valid SecurityDescriptor! + Status = NtDuplicateToken(hToken, + 0, + &ObjectAttributes, + FALSE, + TokenPrimary, + &hTokenDup); + if (!NT_SUCCESS(Status)) + { + ERR("NtDuplicateToken() failed, Status 0x%08x\n", Status); + goto Quit; + } + + // FIXME: Do we always need SecurityImpersonation? + Status = RtlImpersonateSelf(SecurityImpersonation); + if (!NT_SUCCESS(Status)) + { + ERR("RtlImpersonateSelf(SecurityImpersonation) failed, Status 0x%08x\n", Status); + NtClose(hTokenDup); + goto Quit; + } + + /* + * Attempt to acquire the process primary token assignment privilege + * in case we actually need it. + * The call will either succeed or fail when the caller has (or has not) + * enough rights. + * The last situation may not be dramatic for us. Indeed it may happen + * that the user-provided token is a restricted version of the caller's + * primary token (aka. a "child" token), or both tokens inherit (i.e. are + * children, and are together "siblings") from a common parent token. + * In this case the NT kernel allows us to assign the token to the child + * process without the need for the assignment privilege, which is fine. + * On the contrary, if the user-provided token is completely arbitrary, + * then the NT kernel will enforce the presence of the assignment privilege: + * because we failed (by assumption) to assign the privilege, the process + * token assignment will fail as required. It is then the job of the + * caller to manually acquire the necessary privileges. + */ + Status = RtlAdjustPrivilege(SE_ASSIGNPRIMARYTOKEN_PRIVILEGE, + TRUE, TRUE, &PrivilegeSet); + HavePrivilege = NT_SUCCESS(Status); + if (!HavePrivilege) + { + ERR("RtlAdjustPrivilege(SE_ASSIGNPRIMARYTOKEN_PRIVILEGE) failed, Status 0x%08lx, " + "attempting to continue without it...\n", Status); + } + + AccessToken.Token = hTokenDup; + AccessToken.Thread = lpProcessInformation->hThread; + + /* Set the new process token */ + Status = NtSetInformationProcess(lpProcessInformation->hProcess, + ProcessAccessToken, + (PVOID)&AccessToken, + sizeof(AccessToken)); + + /* Restore the privilege */ + if (HavePrivilege) + { + RtlAdjustPrivilege(SE_ASSIGNPRIMARYTOKEN_PRIVILEGE, + PrivilegeSet, TRUE, &PrivilegeSet); + } + + RevertToSelf(); + + /* Close the duplicated token */ + NtClose(hTokenDup); + + /* Check whether NtSetInformationProcess() failed */ + if (!NT_SUCCESS(Status)) + { + ERR("NtSetInformationProcess() failed, Status 0x%08x\n", Status); + goto Quit; + } + + if (!NT_SUCCESS(Status)) + { +Quit: + TerminateProcess(lpProcessInformation->hProcess, Status); + SetLastError(RtlNtStatusToDosError(Status)); + return FALSE; + } } /* Resume the main thread */ if (!(dwCreationFlags & CREATE_SUSPENDED)) { - ResumeThread(lpProcessInformation->hThread); + ResumeThread(lpProcessInformation->hThread); } return TRUE; @@ -73,24 +229,28 @@ CreateProcessAsUserA(HANDLE hToken, /* * @implemented */ -BOOL WINAPI -CreateProcessAsUserW(HANDLE hToken, - LPCWSTR lpApplicationName, - LPWSTR lpCommandLine, - LPSECURITY_ATTRIBUTES lpProcessAttributes, - LPSECURITY_ATTRIBUTES lpThreadAttributes, - BOOL bInheritHandles, - DWORD dwCreationFlags, - LPVOID lpEnvironment, - LPCWSTR lpCurrentDirectory, - LPSTARTUPINFOW lpStartupInfo, - LPPROCESS_INFORMATION lpProcessInformation) +BOOL +WINAPI +DECLSPEC_HOTPATCH +CreateProcessAsUserA( + _In_opt_ HANDLE hToken, + _In_opt_ LPCSTR lpApplicationName, + _Inout_opt_ LPSTR lpCommandLine, + _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, + _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, + _In_ BOOL bInheritHandles, + _In_ DWORD dwCreationFlags, + _In_opt_ LPVOID lpEnvironment, + _In_opt_ LPCSTR lpCurrentDirectory, + _In_ LPSTARTUPINFOA lpStartupInfo, + _Out_ LPPROCESS_INFORMATION lpProcessInformation) { - PROCESS_ACCESS_TOKEN AccessToken; - NTSTATUS Status; + TRACE("%p %s %s %p %p %d 0x%08x %p %s %p %p\n", hToken, debugstr_a(lpApplicationName), + debugstr_a(lpCommandLine), lpProcessAttributes, lpThreadAttributes, bInheritHandles, + dwCreationFlags, lpEnvironment, debugstr_a(lpCurrentDirectory), lpStartupInfo, lpProcessInformation); /* Create the process with a suspended main thread */ - if (!CreateProcessW(lpApplicationName, + if (!CreateProcessA(lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, @@ -101,66 +261,105 @@ CreateProcessAsUserW(HANDLE hToken, lpStartupInfo, lpProcessInformation)) { + ERR("CreateProcessA failed, last error: %d\n", GetLastError()); return FALSE; } - AccessToken.Token = hToken; - AccessToken.Thread = NULL; + /* Call the helper function */ + return CreateProcessAsUserCommon(hToken, + dwCreationFlags, + lpProcessInformation); +} - /* Set the new process token */ - Status = NtSetInformationProcess(lpProcessInformation->hProcess, - ProcessAccessToken, - (PVOID)&AccessToken, - sizeof(AccessToken)); - if (!NT_SUCCESS (Status)) - { - SetLastError(RtlNtStatusToDosError(Status)); - return FALSE; - } - /* Resume the main thread */ - if (!(dwCreationFlags & CREATE_SUSPENDED)) +/* + * @implemented + */ +BOOL +WINAPI +DECLSPEC_HOTPATCH +CreateProcessAsUserW( + _In_opt_ HANDLE hToken, + _In_opt_ LPCWSTR lpApplicationName, + _Inout_opt_ LPWSTR lpCommandLine, + _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, + _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, + _In_ BOOL bInheritHandles, + _In_ DWORD dwCreationFlags, + _In_opt_ LPVOID lpEnvironment, + _In_opt_ LPCWSTR lpCurrentDirectory, + _In_ LPSTARTUPINFOW lpStartupInfo, + _Out_ LPPROCESS_INFORMATION lpProcessInformation) +{ + TRACE("%p %s %s %p %p %d 0x%08x %p %s %p %p\n", hToken, debugstr_w(lpApplicationName), + debugstr_w(lpCommandLine), lpProcessAttributes, lpThreadAttributes, bInheritHandles, + dwCreationFlags, lpEnvironment, debugstr_w(lpCurrentDirectory), lpStartupInfo, lpProcessInformation); + + /* Create the process with a suspended main thread */ + if (!CreateProcessW(lpApplicationName, + lpCommandLine, + lpProcessAttributes, + lpThreadAttributes, + bInheritHandles, + dwCreationFlags | CREATE_SUSPENDED, + lpEnvironment, + lpCurrentDirectory, + lpStartupInfo, + lpProcessInformation)) { - ResumeThread(lpProcessInformation->hThread); + ERR("CreateProcessW failed, last error: %d\n", GetLastError()); + return FALSE; } - return TRUE; + /* Call the helper function */ + return CreateProcessAsUserCommon(hToken, + dwCreationFlags, + lpProcessInformation); } + /* - * @unimplemented + * @implemented */ -BOOL WINAPI -CreateProcessWithLogonW(LPCWSTR lpUsername, - LPCWSTR lpDomain, - LPCWSTR lpPassword, - DWORD dwLogonFlags, - LPCWSTR lpApplicationName, - LPWSTR lpCommandLine, - DWORD dwCreationFlags, - LPVOID lpEnvironment, - LPCWSTR lpCurrentDirectory, - LPSTARTUPINFOW lpStartupInfo, - LPPROCESS_INFORMATION lpProcessInformation) +BOOL +WINAPI +LogonUserA( + _In_ LPSTR lpszUsername, + _In_opt_ LPSTR lpszDomain, + _In_opt_ LPSTR lpszPassword, + _In_ DWORD dwLogonType, + _In_ DWORD dwLogonProvider, + _Out_opt_ PHANDLE phToken) { - FIXME("%s %s %s 0x%08x %s %s 0x%08x %p %s %p %p stub\n", debugstr_w(lpUsername), debugstr_w(lpDomain), - debugstr_w(lpPassword), dwLogonFlags, debugstr_w(lpApplicationName), - debugstr_w(lpCommandLine), dwCreationFlags, lpEnvironment, debugstr_w(lpCurrentDirectory), - lpStartupInfo, lpProcessInformation); - - return FALSE; + return LogonUserExA(lpszUsername, + lpszDomain, + lpszPassword, + dwLogonType, + dwLogonProvider, + phToken, + NULL, + NULL, + NULL, + NULL); } + /* * @implemented */ -BOOL WINAPI -LogonUserA(LPSTR lpszUsername, - LPSTR lpszDomain, - LPSTR lpszPassword, - DWORD dwLogonType, - DWORD dwLogonProvider, - PHANDLE phToken) +BOOL +WINAPI +LogonUserExA( + _In_ LPSTR lpszUsername, + _In_opt_ LPSTR lpszDomain, + _In_opt_ LPSTR lpszPassword, + _In_ DWORD dwLogonType, + _In_ DWORD dwLogonProvider, + _Out_opt_ PHANDLE phToken, + _Out_opt_ PSID *ppLogonSid, + _Out_opt_ PVOID *ppProfileBuffer, + _Out_opt_ LPDWORD pdwProfileLength, + _Out_opt_ PQUOTA_LIMITS pQuotaLimits) { UNICODE_STRING UserName; UNICODE_STRING Domain; @@ -189,12 +388,16 @@ LogonUserA(LPSTR lpszUsername, goto PasswordDone; } - ret = LogonUserW(UserName.Buffer, - Domain.Buffer, - Password.Buffer, - dwLogonType, - dwLogonProvider, - phToken); + ret = LogonUserExW(UserName.Buffer, + Domain.Buffer, + Password.Buffer, + dwLogonType, + dwLogonProvider, + phToken, + ppLogonSid, + ppProfileBuffer, + pdwProfileLength, + pQuotaLimits); if (Password.Buffer != NULL) RtlFreeUnicodeString(&Password); @@ -212,570 +415,307 @@ UsernameDone: } -static BOOL WINAPI -GetAccountDomainSid(PSID *Sid) -{ - PPOLICY_ACCOUNT_DOMAIN_INFO Info = NULL; - LSA_OBJECT_ATTRIBUTES ObjectAttributes; - LSA_HANDLE PolicyHandle; - PSID lpSid; - ULONG Length; - NTSTATUS Status; - - *Sid = NULL; - - memset(&ObjectAttributes, 0, sizeof(LSA_OBJECT_ATTRIBUTES)); - ObjectAttributes.Length = sizeof(LSA_OBJECT_ATTRIBUTES); - - Status = LsaOpenPolicy(NULL, - &ObjectAttributes, - POLICY_VIEW_LOCAL_INFORMATION, - &PolicyHandle); - if (!NT_SUCCESS(Status)) - { - ERR("LsaOpenPolicy failed (Status: 0x%08lx)\n", Status); - return FALSE; - } - - Status = LsaQueryInformationPolicy(PolicyHandle, - PolicyAccountDomainInformation, - (PVOID *)&Info); - if (!NT_SUCCESS(Status)) - { - ERR("LsaQueryInformationPolicy failed (Status: 0x%08lx)\n", Status); - LsaClose(PolicyHandle); - return FALSE; - } - - Length = RtlLengthSid(Info->DomainSid); - - lpSid = RtlAllocateHeap(RtlGetProcessHeap(), - 0, - Length); - if (lpSid == NULL) - { - ERR("Failed to allocate SID buffer!\n"); - LsaFreeMemory(Info); - LsaClose(PolicyHandle); - return FALSE; - } - - memcpy(lpSid, Info->DomainSid, Length); - - *Sid = lpSid; - - LsaFreeMemory(Info); - LsaClose(PolicyHandle); - - return TRUE; -} - - -static PSID -AppendRidToSid(PSID SrcSid, - ULONG Rid) +/* + * @implemented + */ +BOOL +WINAPI +LogonUserW( + _In_ LPWSTR lpszUsername, + _In_opt_ LPWSTR lpszDomain, + _In_opt_ LPWSTR lpszPassword, + _In_ DWORD dwLogonType, + _In_ DWORD dwLogonProvider, + _Out_opt_ PHANDLE phToken) { - ULONG Rids[8] = {0, 0, 0, 0, 0, 0, 0, 0}; - UCHAR RidCount; - PSID DstSid; - ULONG i; - - RidCount = *RtlSubAuthorityCountSid(SrcSid); - if (RidCount >= 8) - return NULL; - - for (i = 0; i < RidCount; i++) - Rids[i] = *RtlSubAuthoritySid(SrcSid, i); - - Rids[RidCount] = Rid; - RidCount++; - - RtlAllocateAndInitializeSid(RtlIdentifierAuthoritySid(SrcSid), - RidCount, - Rids[0], - Rids[1], - Rids[2], - Rids[3], - Rids[4], - Rids[5], - Rids[6], - Rids[7], - &DstSid); - - return DstSid; + return LogonUserExW(lpszUsername, + lpszDomain, + lpszPassword, + dwLogonType, + dwLogonProvider, + phToken, + NULL, + NULL, + NULL, + NULL); } -static BOOL WINAPI -GetUserSid(LPCWSTR UserName, - PSID *Sid) +/* + * @implemented + */ +BOOL +WINAPI +LogonUserExW( + _In_ LPWSTR lpszUsername, + _In_opt_ LPWSTR lpszDomain, + _In_opt_ LPWSTR lpszPassword, + _In_ DWORD dwLogonType, + _In_ DWORD dwLogonProvider, + _Out_opt_ PHANDLE phToken, + _Out_opt_ PSID *ppLogonSid, + _Out_opt_ PVOID *ppProfileBuffer, + _Out_opt_ LPDWORD pdwProfileLength, + _Out_opt_ PQUOTA_LIMITS pQuotaLimits) { - PSID SidBuffer = NULL; - PWSTR DomainBuffer = NULL; - DWORD cbSidSize = 0; - DWORD cchDomSize = 0; - SID_NAME_USE Use; - BOOL res = TRUE; - - *Sid = NULL; - - LookupAccountNameW(NULL, - UserName, - NULL, - &cbSidSize, - NULL, - &cchDomSize, - &Use); - - if (cbSidSize == 0 || cchDomSize == 0) - return FALSE; - - SidBuffer = RtlAllocateHeap(RtlGetProcessHeap(), - HEAP_ZERO_MEMORY, - cbSidSize); - if (SidBuffer == NULL) - return FALSE; + SID_IDENTIFIER_AUTHORITY LocalAuthority = {SECURITY_LOCAL_SID_AUTHORITY}; + SID_IDENTIFIER_AUTHORITY SystemAuthority = {SECURITY_NT_AUTHORITY}; + PSID LogonSid = NULL; + PSID LocalSid = NULL; + LSA_STRING OriginName; + UNICODE_STRING DomainName; + UNICODE_STRING UserName; + UNICODE_STRING Password; + PMSV1_0_INTERACTIVE_LOGON AuthInfo = NULL; + ULONG AuthInfoLength; + ULONG_PTR Ptr; + TOKEN_SOURCE TokenSource; + PTOKEN_GROUPS TokenGroups = NULL; + PMSV1_0_INTERACTIVE_PROFILE ProfileBuffer = NULL; + ULONG ProfileBufferLength = 0; + LUID Luid = {0, 0}; + LUID LogonId = {0, 0}; + HANDLE TokenHandle = NULL; + QUOTA_LIMITS QuotaLimits; + SECURITY_LOGON_TYPE LogonType; + NTSTATUS SubStatus = STATUS_SUCCESS; + NTSTATUS Status; - DomainBuffer = RtlAllocateHeap(RtlGetProcessHeap(), - HEAP_ZERO_MEMORY, - cchDomSize * sizeof(WCHAR)); - if (DomainBuffer == NULL) + if ((ppProfileBuffer != NULL && pdwProfileLength == NULL) || + (ppProfileBuffer == NULL && pdwProfileLength != NULL)) { - res = FALSE; - goto done; + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; } - if (!LookupAccountNameW(NULL, - UserName, - SidBuffer, - &cbSidSize, - DomainBuffer, - &cchDomSize, - &Use)) + if (ppProfileBuffer != NULL && pdwProfileLength != NULL) { - res = FALSE; - goto done; + *ppProfileBuffer = NULL; + *pdwProfileLength = 0; } - if (Use != SidTypeUser) + if (phToken != NULL) + *phToken = NULL; + + switch (dwLogonType) { - res = FALSE; - goto done; + case LOGON32_LOGON_INTERACTIVE: + LogonType = Interactive; + break; + + case LOGON32_LOGON_NETWORK: + LogonType = Network; + break; + + case LOGON32_LOGON_BATCH: + LogonType = Batch; + break; + + case LOGON32_LOGON_SERVICE: + LogonType = Service; + break; + + default: + ERR("Invalid logon type: %ul\n", dwLogonType); + Status = STATUS_INVALID_PARAMETER; + goto done; } - *Sid = SidBuffer; - -done: - if (DomainBuffer != NULL) - RtlFreeHeap(RtlGetProcessHeap(), 0, DomainBuffer); - - if (res == FALSE) + if (LsaHandle == NULL) { - if (SidBuffer != NULL) - RtlFreeHeap(RtlGetProcessHeap(), 0, SidBuffer); + Status = OpenLogonLsaHandle(); + if (!NT_SUCCESS(Status)) + goto done; } - return res; -} + RtlInitAnsiString((PANSI_STRING)&OriginName, + "Advapi32 Logon"); + RtlInitUnicodeString(&DomainName, + lpszDomain); -static PTOKEN_GROUPS -AllocateGroupSids(OUT PSID *PrimaryGroupSid, - OUT PSID *OwnerSid) -{ - SID_IDENTIFIER_AUTHORITY WorldAuthority = {SECURITY_WORLD_SID_AUTHORITY}; - SID_IDENTIFIER_AUTHORITY LocalAuthority = {SECURITY_LOCAL_SID_AUTHORITY}; - SID_IDENTIFIER_AUTHORITY SystemAuthority = {SECURITY_NT_AUTHORITY}; - PTOKEN_GROUPS TokenGroups; -#define MAX_GROUPS 8 - DWORD GroupCount = 0; - PSID DomainSid; - PSID Sid; - LUID Luid; - NTSTATUS Status; + RtlInitUnicodeString(&UserName, + lpszUsername); - Status = NtAllocateLocallyUniqueId(&Luid); - if (!NT_SUCCESS(Status)) - return NULL; + RtlInitUnicodeString(&Password, + lpszPassword); - if (!GetAccountDomainSid(&DomainSid)) - return NULL; + AuthInfoLength = sizeof(MSV1_0_INTERACTIVE_LOGON)+ + DomainName.MaximumLength + + UserName.MaximumLength + + Password.MaximumLength; - TokenGroups = RtlAllocateHeap( - GetProcessHeap(), 0, - sizeof(TOKEN_GROUPS) + - MAX_GROUPS * sizeof(SID_AND_ATTRIBUTES)); - if (TokenGroups == NULL) + AuthInfo = RtlAllocateHeap(RtlGetProcessHeap(), + HEAP_ZERO_MEMORY, + AuthInfoLength); + if (AuthInfo == NULL) { - RtlFreeHeap(RtlGetProcessHeap(), 0, DomainSid); - return NULL; + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; } - Sid = AppendRidToSid(DomainSid, DOMAIN_GROUP_RID_USERS); - RtlFreeHeap(RtlGetProcessHeap(), 0, DomainSid); - - /* Member of the domain */ - TokenGroups->Groups[GroupCount].Sid = Sid; - TokenGroups->Groups[GroupCount].Attributes = - SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY; - *PrimaryGroupSid = Sid; - GroupCount++; - - /* Member of 'Everyone' */ - RtlAllocateAndInitializeSid(&WorldAuthority, - 1, - SECURITY_WORLD_RID, - SECURITY_NULL_RID, - SECURITY_NULL_RID, - SECURITY_NULL_RID, - SECURITY_NULL_RID, - SECURITY_NULL_RID, - SECURITY_NULL_RID, - SECURITY_NULL_RID, - &Sid); - TokenGroups->Groups[GroupCount].Sid = Sid; - TokenGroups->Groups[GroupCount].Attributes = - SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY; - GroupCount++; - -#if 1 - /* Member of 'Administrators' */ - RtlAllocateAndInitializeSid(&SystemAuthority, - 2, - SECURITY_BUILTIN_DOMAIN_RID, - DOMAIN_ALIAS_RID_ADMINS, - SECURITY_NULL_RID, - SECURITY_NULL_RID, - SECURITY_NULL_RID, - SECURITY_NULL_RID, - SECURITY_NULL_RID, - SECURITY_NULL_RID, - &Sid); - TokenGroups->Groups[GroupCount].Sid = Sid; - TokenGroups->Groups[GroupCount].Attributes = - SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY; - GroupCount++; -#else - TRACE("Not adding user to Administrators group\n"); -#endif - - /* Member of 'Users' */ - RtlAllocateAndInitializeSid(&SystemAuthority, - 2, - SECURITY_BUILTIN_DOMAIN_RID, - DOMAIN_ALIAS_RID_USERS, - SECURITY_NULL_RID, - SECURITY_NULL_RID, - SECURITY_NULL_RID, - SECURITY_NULL_RID, - SECURITY_NULL_RID, - SECURITY_NULL_RID, - &Sid); - TokenGroups->Groups[GroupCount].Sid = Sid; - TokenGroups->Groups[GroupCount].Attributes = - SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY; - GroupCount++; - - /* Logon SID */ - RtlAllocateAndInitializeSid(&SystemAuthority, - SECURITY_LOGON_IDS_RID_COUNT, - SECURITY_LOGON_IDS_RID, - Luid.HighPart, - Luid.LowPart, - SECURITY_NULL_RID, - SECURITY_NULL_RID, - SECURITY_NULL_RID, - SECURITY_NULL_RID, - SECURITY_NULL_RID, - &Sid); - TokenGroups->Groups[GroupCount].Sid = Sid; - TokenGroups->Groups[GroupCount].Attributes = - SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY | SE_GROUP_LOGON_ID; - GroupCount++; - *OwnerSid = Sid; - - /* Member of 'Local users */ - RtlAllocateAndInitializeSid(&LocalAuthority, - 1, - SECURITY_LOCAL_RID, - SECURITY_NULL_RID, - SECURITY_NULL_RID, - SECURITY_NULL_RID, - SECURITY_NULL_RID, - SECURITY_NULL_RID, - SECURITY_NULL_RID, - SECURITY_NULL_RID, - &Sid); - TokenGroups->Groups[GroupCount].Sid = Sid; - TokenGroups->Groups[GroupCount].Attributes = - SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY; - GroupCount++; - - /* Member of 'Interactive users' */ - RtlAllocateAndInitializeSid(&SystemAuthority, - 1, - SECURITY_INTERACTIVE_RID, - SECURITY_NULL_RID, - SECURITY_NULL_RID, - SECURITY_NULL_RID, - SECURITY_NULL_RID, - SECURITY_NULL_RID, - SECURITY_NULL_RID, - SECURITY_NULL_RID, - &Sid); - TokenGroups->Groups[GroupCount].Sid = Sid; - TokenGroups->Groups[GroupCount].Attributes = - SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY; - GroupCount++; - - /* Member of 'Authenticated users' */ - RtlAllocateAndInitializeSid(&SystemAuthority, - 1, - SECURITY_AUTHENTICATED_USER_RID, - SECURITY_NULL_RID, - SECURITY_NULL_RID, - SECURITY_NULL_RID, - SECURITY_NULL_RID, - SECURITY_NULL_RID, - SECURITY_NULL_RID, - SECURITY_NULL_RID, - &Sid); - TokenGroups->Groups[GroupCount].Sid = Sid; - TokenGroups->Groups[GroupCount].Attributes = - SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY; - GroupCount++; - - TokenGroups->GroupCount = GroupCount; - ASSERT(TokenGroups->GroupCount <= MAX_GROUPS); - - return TokenGroups; -} - + AuthInfo->MessageType = MsV1_0InteractiveLogon; -static VOID -FreeGroupSids(PTOKEN_GROUPS TokenGroups) -{ - ULONG i; + Ptr = (ULONG_PTR)AuthInfo + sizeof(MSV1_0_INTERACTIVE_LOGON); - for (i = 0; i < TokenGroups->GroupCount; i++) + AuthInfo->LogonDomainName.Length = DomainName.Length; + AuthInfo->LogonDomainName.MaximumLength = DomainName.MaximumLength; + AuthInfo->LogonDomainName.Buffer = (DomainName.Buffer == NULL) ? NULL : (PWCHAR)Ptr; + if (DomainName.MaximumLength > 0) { - if (TokenGroups->Groups[i].Sid != NULL) - RtlFreeHeap(GetProcessHeap(), 0, TokenGroups->Groups[i].Sid); - } + RtlCopyMemory(AuthInfo->LogonDomainName.Buffer, + DomainName.Buffer, + DomainName.MaximumLength); - RtlFreeHeap(GetProcessHeap(), 0, TokenGroups); -} - - -/* - * @unimplemented - */ -BOOL WINAPI -LogonUserW(LPWSTR lpszUsername, - LPWSTR lpszDomain, - LPWSTR lpszPassword, - DWORD dwLogonType, - DWORD dwLogonProvider, - PHANDLE phToken) -{ - /* FIXME shouldn't use hard-coded list of privileges */ - static struct - { - LPCWSTR PrivName; - DWORD Attributes; + Ptr += DomainName.MaximumLength; } - DefaultPrivs[] = - { - { L"SeMachineAccountPrivilege", 0 }, - { L"SeSecurityPrivilege", 0 }, - { L"SeTakeOwnershipPrivilege", 0 }, - { L"SeLoadDriverPrivilege", 0 }, - { L"SeSystemProfilePrivilege", 0 }, - { L"SeSystemtimePrivilege", 0 }, - { L"SeProfileSingleProcessPrivilege", 0 }, - { L"SeIncreaseBasePriorityPrivilege", 0 }, - { L"SeCreatePagefilePrivilege", 0 }, - { L"SeBackupPrivilege", 0 }, - { L"SeRestorePrivilege", 0 }, - { L"SeShutdownPrivilege", 0 }, - { L"SeDebugPrivilege", 0 }, - { L"SeSystemEnvironmentPrivilege", 0 }, - { L"SeChangeNotifyPrivilege", SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT }, - { L"SeRemoteShutdownPrivilege", 0 }, - { L"SeUndockPrivilege", 0 }, - { L"SeEnableDelegationPrivilege", 0 }, - { L"SeImpersonatePrivilege", SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT }, - { L"SeCreateGlobalPrivilege", SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT } - }; - OBJECT_ATTRIBUTES ObjectAttributes; - SECURITY_QUALITY_OF_SERVICE Qos; - TOKEN_USER TokenUser; - TOKEN_OWNER TokenOwner; - TOKEN_PRIMARY_GROUP TokenPrimaryGroup; - PTOKEN_GROUPS TokenGroups = NULL; - PTOKEN_PRIVILEGES TokenPrivileges = NULL; - TOKEN_DEFAULT_DACL TokenDefaultDacl; - LARGE_INTEGER ExpirationTime; - LUID AuthenticationId; - TOKEN_SOURCE TokenSource; - PSID UserSid = NULL; - PSID PrimaryGroupSid = NULL; - PSID OwnerSid = NULL; - PSID LocalSystemSid; - PACL Dacl = NULL; - SID_IDENTIFIER_AUTHORITY SystemAuthority = {SECURITY_NT_AUTHORITY}; - unsigned i; - NTSTATUS Status = STATUS_SUCCESS; - - Qos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE); - Qos.ImpersonationLevel = SecurityAnonymous; - Qos.ContextTrackingMode = SECURITY_STATIC_TRACKING; - Qos.EffectiveOnly = FALSE; - - ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES); - ObjectAttributes.RootDirectory = NULL; - ObjectAttributes.ObjectName = NULL; - ObjectAttributes.Attributes = 0; - ObjectAttributes.SecurityDescriptor = NULL; - ObjectAttributes.SecurityQualityOfService = &Qos; - Status = NtAllocateLocallyUniqueId(&AuthenticationId); + AuthInfo->UserName.Length = UserName.Length; + AuthInfo->UserName.MaximumLength = UserName.MaximumLength; + AuthInfo->UserName.Buffer = (PWCHAR)Ptr; + if (UserName.MaximumLength > 0) + RtlCopyMemory(AuthInfo->UserName.Buffer, + UserName.Buffer, + UserName.MaximumLength); + + Ptr += UserName.MaximumLength; + + AuthInfo->Password.Length = Password.Length; + AuthInfo->Password.MaximumLength = Password.MaximumLength; + AuthInfo->Password.Buffer = (PWCHAR)Ptr; + if (Password.MaximumLength > 0) + RtlCopyMemory(AuthInfo->Password.Buffer, + Password.Buffer, + Password.MaximumLength); + + /* Create the Logon SID */ + AllocateLocallyUniqueId(&LogonId); + Status = RtlAllocateAndInitializeSid(&SystemAuthority, + SECURITY_LOGON_IDS_RID_COUNT, + SECURITY_LOGON_IDS_RID, + LogonId.HighPart, + LogonId.LowPart, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + &LogonSid); if (!NT_SUCCESS(Status)) - { - return FALSE; - } - - ExpirationTime.QuadPart = -1; - - /* Get the user SID from the registry */ - if (!GetUserSid (lpszUsername, &UserSid)) - { - ERR("GetUserSid() failed\n"); - return FALSE; - } + goto done; - TokenUser.User.Sid = UserSid; - TokenUser.User.Attributes = 0; + /* Create the Local SID */ + Status = RtlAllocateAndInitializeSid(&LocalAuthority, + 1, + SECURITY_LOCAL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + &LocalSid); + if (!NT_SUCCESS(Status)) + goto done; - /* Allocate and initialize token groups */ - TokenGroups = AllocateGroupSids(&PrimaryGroupSid, - &OwnerSid); + /* Allocate and set the token groups */ + TokenGroups = RtlAllocateHeap(RtlGetProcessHeap(), + HEAP_ZERO_MEMORY, + sizeof(TOKEN_GROUPS) + ((2 - ANYSIZE_ARRAY) * sizeof(SID_AND_ATTRIBUTES))); if (TokenGroups == NULL) { Status = STATUS_INSUFFICIENT_RESOURCES; goto done; } - /* Allocate and initialize token privileges */ - TokenPrivileges = RtlAllocateHeap(GetProcessHeap(), 0, - sizeof(TOKEN_PRIVILEGES) - + sizeof(DefaultPrivs) / sizeof(DefaultPrivs[0]) - * sizeof(LUID_AND_ATTRIBUTES)); - if (TokenPrivileges == NULL) + TokenGroups->GroupCount = 2; + TokenGroups->Groups[0].Sid = LogonSid; + TokenGroups->Groups[0].Attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED | + SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_LOGON_ID; + TokenGroups->Groups[1].Sid = LocalSid; + TokenGroups->Groups[1].Attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED | + SE_GROUP_ENABLED_BY_DEFAULT; + + /* Set the token source */ + RtlCopyMemory(TokenSource.SourceName, + AdvapiTokenSourceName, + sizeof(TokenSource.SourceName)); + AllocateLocallyUniqueId(&TokenSource.SourceIdentifier); + + Status = LsaLogonUser(LsaHandle, + &OriginName, + LogonType, + AuthenticationPackage, + (PVOID)AuthInfo, + AuthInfoLength, + TokenGroups, + &TokenSource, + (PVOID*)&ProfileBuffer, + &ProfileBufferLength, + &Luid, + &TokenHandle, + &QuotaLimits, + &SubStatus); + if (!NT_SUCCESS(Status)) { - Status = STATUS_INSUFFICIENT_RESOURCES; + ERR("LsaLogonUser failed (Status 0x%08lx)\n", Status); goto done; } - TokenPrivileges->PrivilegeCount = 0; - for (i = 0; i < sizeof(DefaultPrivs) / sizeof(DefaultPrivs[0]); i++) + if (ProfileBuffer != NULL) { - if (! LookupPrivilegeValueW(NULL, - DefaultPrivs[i].PrivName, - &TokenPrivileges->Privileges[TokenPrivileges->PrivilegeCount].Luid)) - { - WARN("Can't set privilege %S\n", DefaultPrivs[i].PrivName); - } - else - { - TokenPrivileges->Privileges[TokenPrivileges->PrivilegeCount].Attributes = DefaultPrivs[i].Attributes; - TokenPrivileges->PrivilegeCount++; - } + TRACE("ProfileBuffer: %p\n", ProfileBuffer); + TRACE("MessageType: %u\n", ProfileBuffer->MessageType); + + TRACE("FullName: %p\n", ProfileBuffer->FullName.Buffer); + TRACE("FullName: %S\n", ProfileBuffer->FullName.Buffer); + + TRACE("LogonServer: %p\n", ProfileBuffer->LogonServer.Buffer); + TRACE("LogonServer: %S\n", ProfileBuffer->LogonServer.Buffer); } - TokenOwner.Owner = OwnerSid; - TokenPrimaryGroup.PrimaryGroup = PrimaryGroupSid; + TRACE("Luid: 0x%08lx%08lx\n", Luid.HighPart, Luid.LowPart); - Dacl = RtlAllocateHeap(GetProcessHeap(), 0, 1024); - if (Dacl == NULL) + if (TokenHandle != NULL) { - Status = STATUS_INSUFFICIENT_RESOURCES; - goto done; + TRACE("TokenHandle: %p\n", TokenHandle); } - Status = RtlCreateAcl(Dacl, 1024, ACL_REVISION); - if (!NT_SUCCESS(Status)) - goto done; + if (phToken != NULL) + *phToken = TokenHandle; + + /* FIXME: return ppLogonSid and pQuotaLimits */ + +done: + if (ProfileBuffer != NULL) + LsaFreeReturnBuffer(ProfileBuffer); - RtlAddAccessAllowedAce(Dacl, - ACL_REVISION, - GENERIC_ALL, - OwnerSid); - - RtlAllocateAndInitializeSid(&SystemAuthority, - 1, - SECURITY_LOCAL_SYSTEM_RID, - SECURITY_NULL_RID, - SECURITY_NULL_RID, - SECURITY_NULL_RID, - SECURITY_NULL_RID, - SECURITY_NULL_RID, - SECURITY_NULL_RID, - SECURITY_NULL_RID, - &LocalSystemSid); - - /* SID: S-1-5-18 */ - RtlAddAccessAllowedAce(Dacl, - ACL_REVISION, - GENERIC_ALL, - LocalSystemSid); - - RtlFreeSid(LocalSystemSid); - - TokenDefaultDacl.DefaultDacl = Dacl; - - memcpy(TokenSource.SourceName, - "User32 ", - 8); - - Status = NtAllocateLocallyUniqueId(&TokenSource.SourceIdentifier); if (!NT_SUCCESS(Status)) { - RtlFreeHeap(GetProcessHeap(), 0, Dacl); - FreeGroupSids(TokenGroups); - RtlFreeHeap(GetProcessHeap(), 0, TokenPrivileges); - RtlFreeSid(UserSid); - return FALSE; + if (TokenHandle != NULL) + CloseHandle(TokenHandle); } - Status = NtCreateToken(phToken, - TOKEN_ALL_ACCESS, - &ObjectAttributes, - TokenPrimary, - &AuthenticationId, - &ExpirationTime, - &TokenUser, - TokenGroups, - TokenPrivileges, - &TokenOwner, - &TokenPrimaryGroup, - &TokenDefaultDacl, - &TokenSource); + if (TokenGroups != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, TokenGroups); -done: - if (Dacl != NULL) - RtlFreeHeap(GetProcessHeap(), 0, Dacl); + if (LocalSid != NULL) + RtlFreeSid(LocalSid); - if (TokenGroups != NULL) - FreeGroupSids(TokenGroups); + if (LogonSid != NULL) + RtlFreeSid(LogonSid); - if (TokenPrivileges != NULL) - RtlFreeHeap(GetProcessHeap(), 0, TokenPrivileges); + if (AuthInfo != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, AuthInfo); - if (UserSid != NULL) - RtlFreeHeap(GetProcessHeap(), 0, UserSid); + if (!NT_SUCCESS(Status)) + { + SetLastError(RtlNtStatusToDosError(Status)); + return FALSE; + } - return NT_SUCCESS(Status); + return TRUE; } /* EOF */