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 HANDLE hTargetProcessHandle = NULL; 68 69 ULONG dwError = ERROR_SUCCESS; 70 BOOL rc; 71 72 TRACE("SeclCreateProcessWithLogonW(%p %p %p)\n", hBinding, pRequest, pResponse); 73 74 if (pRequest != NULL) 75 { 76 TRACE("Username: '%S'\n", pRequest->Username); 77 TRACE("Domain: '%S'\n", pRequest->Domain); 78 TRACE("Password: '%S'\n", pRequest->Password); 79 TRACE("ApplicationName: '%S'\n", pRequest->ApplicationName); 80 TRACE("CommandLine: '%S'\n", pRequest->CommandLine); 81 TRACE("CurrentDirectory: '%S'\n", pRequest->CurrentDirectory); 82 TRACE("LogonFlags: 0x%lx\n", pRequest->dwLogonFlags); 83 TRACE("CreationFlags: 0x%lx\n", pRequest->dwCreationFlags); 84 TRACE("ProcessId: %lu\n", pRequest->dwProcessId); 85 } 86 87 hTargetProcessHandle = OpenProcess(PROCESS_DUP_HANDLE, 88 FALSE, 89 pRequest->dwProcessId); 90 if (hTargetProcessHandle == NULL) 91 { 92 dwError = GetLastError(); 93 WARN("OpenProcess() failed with Error %lu\n", dwError); 94 goto done; 95 } 96 97 ZeroMemory(&ProfileInfo, sizeof(ProfileInfo)); 98 99 /* Logon */ 100 rc = LogonUser(pRequest->Username, 101 pRequest->Domain, 102 pRequest->Password, 103 LOGON32_LOGON_INTERACTIVE, 104 LOGON32_PROVIDER_DEFAULT, 105 &hToken); 106 if (rc == FALSE) 107 { 108 dwError = GetLastError(); 109 WARN("LogonUser() failed with Error %lu\n", dwError); 110 goto done; 111 } 112 113 /* Load the user profile */ 114 if (pRequest->dwLogonFlags & LOGON_WITH_PROFILE) 115 { 116 ProfileInfo.dwSize = sizeof(ProfileInfo); 117 ProfileInfo.lpUserName = pRequest->Username; 118 119 rc = LoadUserProfileW(hToken, 120 &ProfileInfo); 121 if (rc == FALSE) 122 { 123 dwError = GetLastError(); 124 WARN("LoadUserProfile() failed with Error %lu\n", dwError); 125 goto done; 126 } 127 } 128 129 /* Initialize the startup information */ 130 ZeroMemory(&StartupInfo, sizeof(StartupInfo)); 131 StartupInfo.cb = sizeof(StartupInfo); 132 133 /* FIXME: Get startup info from the caller */ 134 135 /* Initialize the process information */ 136 ZeroMemory(&ProcessInfo, sizeof(ProcessInfo)); 137 138 /* Create Process */ 139 rc = CreateProcessAsUserW(hToken, 140 pRequest->ApplicationName, 141 pRequest->CommandLine, 142 NULL, // lpProcessAttributes, 143 NULL, // lpThreadAttributes, 144 FALSE, // bInheritHandles, 145 pRequest->dwCreationFlags, 146 pRequest->Environment, // lpEnvironment, 147 pRequest->CurrentDirectory, 148 &StartupInfo, 149 &ProcessInfo); 150 if (rc == FALSE) 151 { 152 dwError = GetLastError(); 153 WARN("CreateProcessAsUser() failed with Error %lu\n", dwError); 154 goto done; 155 } 156 157 /* Return process info to the caller */ 158 if (pResponse != NULL) 159 { 160 DuplicateHandle(GetCurrentProcess(), 161 ProcessInfo.hProcess, 162 hTargetProcessHandle, 163 (PHANDLE)&pResponse->hProcess, 164 0, 165 FALSE, 166 DUPLICATE_SAME_ACCESS); 167 168 DuplicateHandle(GetCurrentProcess(), 169 ProcessInfo.hThread, 170 hTargetProcessHandle, 171 (PHANDLE)&pResponse->hThread, 172 0, 173 FALSE, 174 DUPLICATE_SAME_ACCESS); 175 176 pResponse->dwProcessId = ProcessInfo.dwProcessId; 177 pResponse->dwThreadId = ProcessInfo.dwThreadId; 178 } 179 180 done: 181 if (hTargetProcessHandle) 182 CloseHandle(hTargetProcessHandle); 183 184 if (ProcessInfo.hThread) 185 CloseHandle(ProcessInfo.hThread); 186 187 if (ProcessInfo.hProcess) 188 CloseHandle(ProcessInfo.hProcess); 189 190 if (ProfileInfo.hProfile != NULL) 191 UnloadUserProfile(hToken, ProfileInfo.hProfile); 192 193 if (hToken != NULL) 194 CloseHandle(hToken); 195 196 if (pResponse != NULL) 197 pResponse->dwError = dwError; 198 } 199