1 /* 2 * PROJECT: ReactOS Secondary Logon Service 3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) 4 * PURPOSE: Secondary Logon service RPC server 5 * COPYRIGHT: Eric Kohl 2022 <eric.kohl@reactos.org> 6 */ 7 8 /* INCLUDES *****************************************************************/ 9 10 #include "precomp.h" 11 12 #include <seclogon_s.h> 13 14 WINE_DEFAULT_DEBUG_CHANNEL(seclogon); 15 16 /* FUNCTIONS *****************************************************************/ 17 18 19 void __RPC_FAR * __RPC_USER midl_user_allocate(SIZE_T len) 20 { 21 return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len); 22 } 23 24 25 void __RPC_USER midl_user_free(void __RPC_FAR * ptr) 26 { 27 HeapFree(GetProcessHeap(), 0, ptr); 28 } 29 30 31 DWORD 32 StartRpcServer(VOID) 33 { 34 NTSTATUS Status; 35 36 Status = lpServiceGlobals->StartRpcServer(L"seclogon", ISeclogon_v1_0_s_ifspec); 37 TRACE("StartRpcServer returned 0x%08lx\n", Status); 38 39 return RtlNtStatusToDosError(Status); 40 } 41 42 43 DWORD 44 StopRpcServer(VOID) 45 { 46 NTSTATUS Status; 47 48 Status = lpServiceGlobals->StopRpcServer(ISeclogon_v1_0_s_ifspec); 49 TRACE("StopRpcServer returned 0x%08lx\n", Status); 50 51 return RtlNtStatusToDosError(Status); 52 } 53 54 55 VOID 56 __stdcall 57 SeclCreateProcessWithLogonW( 58 _In_ handle_t hBinding, 59 _In_ SECL_REQUEST *pRequest, 60 _Out_ SECL_RESPONSE *pResponse) 61 { 62 STARTUPINFOW StartupInfo; 63 PROCESS_INFORMATION ProcessInfo; 64 65 PROFILEINFOW ProfileInfo; 66 HANDLE hToken = NULL; 67 68 ULONG dwError = ERROR_SUCCESS; 69 BOOL rc; 70 71 TRACE("SeclCreateProcessWithLogonW(%p %p %p)\n", hBinding, pRequest, pResponse); 72 73 if (pRequest != NULL) 74 { 75 TRACE("Username: '%S'\n", pRequest->Username); 76 TRACE("Domain: '%S'\n", pRequest->Domain); 77 TRACE("Password: '%S'\n", pRequest->Password); 78 TRACE("ApplicationName: '%S'\n", pRequest->ApplicationName); 79 TRACE("CommandLine: '%S'\n", pRequest->CommandLine); 80 TRACE("CurrentDirectory: '%S'\n", pRequest->CurrentDirectory); 81 TRACE("LogonFlags: 0x%lx\n", pRequest->dwLogonFlags); 82 TRACE("CreationFlags: 0x%lx\n", pRequest->dwCreationFlags); 83 } 84 85 ZeroMemory(&ProfileInfo, sizeof(ProfileInfo)); 86 87 /* Logon */ 88 rc = LogonUser(pRequest->Username, 89 pRequest->Domain, 90 pRequest->Password, 91 LOGON32_LOGON_INTERACTIVE, 92 LOGON32_PROVIDER_DEFAULT, 93 &hToken); 94 if (rc == FALSE) 95 { 96 dwError = GetLastError(); 97 WARN("LogonUser() failed with Error %lu\n", dwError); 98 goto done; 99 } 100 101 /* Load the user profile */ 102 if (pRequest->dwLogonFlags & LOGON_WITH_PROFILE) 103 { 104 ProfileInfo.dwSize = sizeof(ProfileInfo); 105 ProfileInfo.lpUserName = pRequest->Username; 106 107 rc = LoadUserProfileW(hToken, 108 &ProfileInfo); 109 if (rc == FALSE) 110 { 111 dwError = GetLastError(); 112 WARN("LoadUserProfile() failed with Error %lu\n", dwError); 113 goto done; 114 } 115 } 116 117 ZeroMemory(&StartupInfo, sizeof(StartupInfo)); 118 StartupInfo.cb = sizeof(StartupInfo); 119 120 /* FIXME: Get startup info from the caller */ 121 122 ZeroMemory(&ProcessInfo, sizeof(ProcessInfo)); 123 124 /* Create Process */ 125 rc = CreateProcessAsUserW(hToken, 126 pRequest->ApplicationName, 127 pRequest->CommandLine, 128 NULL, // lpProcessAttributes, 129 NULL, // lpThreadAttributes, 130 FALSE, // bInheritHandles, 131 pRequest->dwCreationFlags, 132 NULL, // lpEnvironment, 133 pRequest->CurrentDirectory, 134 &StartupInfo, 135 &ProcessInfo); 136 if (rc == FALSE) 137 { 138 dwError = GetLastError(); 139 WARN("CreateProcessAsUser() failed with Error %lu\n", dwError); 140 goto done; 141 } 142 143 /* FIXME: Pass process info to the caller */ 144 145 done: 146 if (ProcessInfo.hThread) 147 CloseHandle(ProcessInfo.hThread); 148 149 if (ProcessInfo.hProcess) 150 CloseHandle(ProcessInfo.hProcess); 151 152 if (ProfileInfo.hProfile != NULL) 153 UnloadUserProfile(hToken, ProfileInfo.hProfile); 154 155 if (hToken != NULL) 156 CloseHandle(hToken); 157 158 if (pResponse != NULL) 159 pResponse->ulError = dwError; 160 } 161