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 ZeroMemory(&StartupInfo, sizeof(StartupInfo)); 130 StartupInfo.cb = sizeof(StartupInfo); 131 132 /* FIXME: Get startup info from the caller */ 133 134 ZeroMemory(&ProcessInfo, sizeof(ProcessInfo)); 135 136 /* Create Process */ 137 rc = CreateProcessAsUserW(hToken, 138 pRequest->ApplicationName, 139 pRequest->CommandLine, 140 NULL, // lpProcessAttributes, 141 NULL, // lpThreadAttributes, 142 FALSE, // bInheritHandles, 143 pRequest->dwCreationFlags, 144 NULL, // lpEnvironment, 145 pRequest->CurrentDirectory, 146 &StartupInfo, 147 &ProcessInfo); 148 if (rc == FALSE) 149 { 150 dwError = GetLastError(); 151 WARN("CreateProcessAsUser() failed with Error %lu\n", dwError); 152 goto done; 153 } 154 155 /* Return process info to the caller */ 156 if (pResponse != NULL) 157 { 158 DuplicateHandle(GetCurrentProcess(), 159 ProcessInfo.hProcess, 160 hTargetProcessHandle, 161 (PHANDLE)&pResponse->hProcess, 162 0, 163 FALSE, 164 DUPLICATE_SAME_ACCESS); 165 166 DuplicateHandle(GetCurrentProcess(), 167 ProcessInfo.hThread, 168 hTargetProcessHandle, 169 (PHANDLE)&pResponse->hThread, 170 0, 171 FALSE, 172 DUPLICATE_SAME_ACCESS); 173 174 pResponse->dwProcessId = ProcessInfo.dwProcessId; 175 pResponse->dwThreadId = ProcessInfo.dwThreadId; 176 } 177 178 done: 179 if (hTargetProcessHandle) 180 CloseHandle(hTargetProcessHandle); 181 182 if (ProcessInfo.hThread) 183 CloseHandle(ProcessInfo.hThread); 184 185 if (ProcessInfo.hProcess) 186 CloseHandle(ProcessInfo.hProcess); 187 188 if (ProfileInfo.hProfile != NULL) 189 UnloadUserProfile(hToken, ProfileInfo.hProfile); 190 191 if (hToken != NULL) 192 CloseHandle(hToken); 193 194 if (pResponse != NULL) 195 pResponse->dwError = dwError; 196 } 197