xref: /reactos/base/services/seclogon/rpcserver.c (revision 3c5a56ed)
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