3ce57d519b3376c3881cf1d255b367b6a734b554
[reactos.git] / reactos / dll / win32 / lsasrv / authport.c
1 /*
2 * PROJECT: Local Security Authority Server DLL
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: dll/win32/lsasrv/authport.c
5 * PURPOSE: LsaAuthenticationPort server routines
6 * COPYRIGHT: Copyright 2009 Eric Kohl
7 */
8
9 #include "lsasrv.h"
10
11 #include <ndk/lpcfuncs.h>
12
13 static LIST_ENTRY LsapLogonContextList;
14
15 static HANDLE PortThreadHandle = NULL;
16 static HANDLE AuthPortHandle = NULL;
17
18
19 /* FUNCTIONS ***************************************************************/
20
21 static NTSTATUS
22 LsapDeregisterLogonProcess(PLSA_API_MSG RequestMsg,
23 PLSAP_LOGON_CONTEXT LogonContext)
24 {
25 TRACE("LsapDeregisterLogonProcess(%p %p)\n", RequestMsg, LogonContext);
26
27 RemoveHeadList(&LogonContext->Entry);
28
29 NtClose(LogonContext->ClientProcessHandle);
30 NtClose(LogonContext->ConnectionHandle);
31
32 RtlFreeHeap(RtlGetProcessHeap(), 0, LogonContext);
33
34 return STATUS_SUCCESS;
35 }
36
37
38 static NTSTATUS
39 LsapCheckLogonProcess(PLSA_API_MSG RequestMsg,
40 PLSAP_LOGON_CONTEXT *LogonContext)
41 {
42 OBJECT_ATTRIBUTES ObjectAttributes;
43 HANDLE ProcessHandle = NULL;
44 PLSAP_LOGON_CONTEXT Context = NULL;
45 NTSTATUS Status;
46
47 TRACE("LsapCheckLogonProcess(%p)\n", RequestMsg);
48
49 TRACE("Client ID: %p %p\n", RequestMsg->h.ClientId.UniqueProcess, RequestMsg->h.ClientId.UniqueThread);
50
51 InitializeObjectAttributes(&ObjectAttributes,
52 NULL,
53 0,
54 NULL,
55 NULL);
56
57 Status = NtOpenProcess(&ProcessHandle,
58 PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION | PROCESS_DUP_HANDLE,
59 &ObjectAttributes,
60 &RequestMsg->h.ClientId);
61 if (!NT_SUCCESS(Status))
62 {
63 TRACE("NtOpenProcess() failed (Status %lx)\n", Status);
64 return Status;
65 }
66
67 /* Allocate the logon context */
68 Context = RtlAllocateHeap(RtlGetProcessHeap(),
69 HEAP_ZERO_MEMORY,
70 sizeof(LSAP_LOGON_CONTEXT));
71 if (Context == NULL)
72 {
73 NtClose(ProcessHandle);
74 return STATUS_INSUFFICIENT_RESOURCES;
75 }
76
77 TRACE("New LogonContext: %p\n", Context);
78
79 Context->ClientProcessHandle = ProcessHandle;
80
81 *LogonContext = Context;
82
83 return STATUS_SUCCESS;
84 }
85
86
87 static NTSTATUS
88 LsapHandlePortConnection(PLSA_API_MSG RequestMsg)
89 {
90 PLSAP_LOGON_CONTEXT LogonContext = NULL;
91 HANDLE ConnectionHandle = NULL;
92 BOOLEAN Accept;
93 REMOTE_PORT_VIEW RemotePortView;
94 NTSTATUS Status = STATUS_SUCCESS;
95
96 TRACE("LsapHandlePortConnection(%p)\n", RequestMsg);
97
98 TRACE("Logon Process Name: %s\n", RequestMsg->ConnectInfo.LogonProcessNameBuffer);
99
100 if (RequestMsg->ConnectInfo.CreateContext == TRUE)
101 {
102 Status = LsapCheckLogonProcess(RequestMsg,
103 &LogonContext);
104
105 RequestMsg->ConnectInfo.OperationalMode = 0x43218765;
106
107 RequestMsg->ConnectInfo.Status = Status;
108 }
109
110 if (NT_SUCCESS(Status))
111 {
112 Accept = TRUE;
113 }
114 else
115 {
116 Accept = FALSE;
117 }
118
119 RemotePortView.Length = sizeof(REMOTE_PORT_VIEW);
120 Status = NtAcceptConnectPort(&ConnectionHandle,
121 (PVOID*)LogonContext,
122 &RequestMsg->h,
123 Accept,
124 NULL,
125 &RemotePortView);
126 if (!NT_SUCCESS(Status))
127 {
128 ERR("NtAcceptConnectPort failed (Status 0x%lx)\n", Status);
129 return Status;
130 }
131
132 if (Accept == TRUE)
133 {
134 if (LogonContext != NULL)
135 {
136 LogonContext->ConnectionHandle = ConnectionHandle;
137
138 InsertHeadList(&LsapLogonContextList,
139 &LogonContext->Entry);
140 }
141
142 Status = NtCompleteConnectPort(ConnectionHandle);
143 if (!NT_SUCCESS(Status))
144 {
145 ERR("NtCompleteConnectPort failed (Status 0x%lx)\n", Status);
146 return Status;
147 }
148 }
149
150 return Status;
151 }
152
153
154 NTSTATUS WINAPI
155 AuthPortThreadRoutine(PVOID Param)
156 {
157 PLSAP_LOGON_CONTEXT LogonContext;
158 PLSA_API_MSG ReplyMsg = NULL;
159 LSA_API_MSG RequestMsg;
160 NTSTATUS Status;
161
162 TRACE("AuthPortThreadRoutine() called\n");
163
164 Status = STATUS_SUCCESS;
165
166 for (;;)
167 {
168 TRACE("Reply: %p\n", ReplyMsg);
169 Status = NtReplyWaitReceivePort(AuthPortHandle,
170 (PVOID*)&LogonContext,
171 (PPORT_MESSAGE)ReplyMsg,
172 (PPORT_MESSAGE)&RequestMsg);
173 if (!NT_SUCCESS(Status))
174 {
175 TRACE("NtReplyWaitReceivePort() failed (Status %lx)\n", Status);
176 break;
177 }
178
179 TRACE("Received message\n");
180
181 switch (RequestMsg.h.u2.s2.Type)
182 {
183 case LPC_CONNECTION_REQUEST:
184 TRACE("Port connection request\n");
185 Status = LsapHandlePortConnection(&RequestMsg);
186 ReplyMsg = NULL;
187 break;
188
189 case LPC_PORT_CLOSED:
190 TRACE("Port closed\n");
191 ReplyMsg = NULL;
192 break;
193
194 case LPC_CLIENT_DIED:
195 TRACE("Client died\n");
196 ReplyMsg = NULL;
197 break;
198
199 default:
200 TRACE("Received request (ApiNumber: %lu)\n", RequestMsg.ApiNumber);
201
202 switch (RequestMsg.ApiNumber)
203 {
204 case LSASS_REQUEST_CALL_AUTHENTICATION_PACKAGE:
205 RequestMsg.Status = LsapCallAuthenticationPackage(&RequestMsg,
206 LogonContext);
207 ReplyMsg = &RequestMsg;
208 break;
209
210 case LSASS_REQUEST_DEREGISTER_LOGON_PROCESS:
211
212 ReplyMsg = &RequestMsg;
213 RequestMsg.Status = STATUS_SUCCESS;
214 NtReplyPort(AuthPortHandle,
215 &ReplyMsg->h);
216
217 LsapDeregisterLogonProcess(&RequestMsg,
218 LogonContext);
219
220 ReplyMsg = NULL;
221 break;
222
223 case LSASS_REQUEST_LOGON_USER:
224 RequestMsg.Status = LsapLogonUser(&RequestMsg,
225 LogonContext);
226 ReplyMsg = &RequestMsg;
227 break;
228
229 case LSASS_REQUEST_LOOKUP_AUTHENTICATION_PACKAGE:
230 RequestMsg.Status = LsapLookupAuthenticationPackage(&RequestMsg,
231 LogonContext);
232 ReplyMsg = &RequestMsg;
233 break;
234
235 case LSASS_REQUEST_ENUM_LOGON_SESSIONS:
236 RequestMsg.Status = LsapEnumLogonSessions(&RequestMsg);
237 ReplyMsg = &RequestMsg;
238 break;
239
240 case LSASS_REQUEST_GET_LOGON_SESSION_DATA:
241 RequestMsg.Status = LsapGetLogonSessionData(&RequestMsg);
242 ReplyMsg = &RequestMsg;
243 break;
244
245 default:
246 RequestMsg.Status = STATUS_INVALID_SYSTEM_SERVICE;
247 ReplyMsg = &RequestMsg;
248 break;
249 }
250
251 break;
252 }
253 }
254
255 return STATUS_SUCCESS;
256 }
257
258
259 NTSTATUS
260 StartAuthenticationPort(VOID)
261 {
262 OBJECT_ATTRIBUTES ObjectAttributes;
263 UNICODE_STRING PortName;
264 DWORD ThreadId;
265 UNICODE_STRING EventName;
266 HANDLE EventHandle;
267 NTSTATUS Status;
268
269 TRACE("StartAuthenticationPort()\n");
270
271 /* Initialize the logon context list */
272 InitializeListHead(&LsapLogonContextList);
273
274 RtlInitUnicodeString(&PortName,
275 L"\\LsaAuthenticationPort");
276
277 InitializeObjectAttributes(&ObjectAttributes,
278 &PortName,
279 0,
280 NULL,
281 NULL);
282
283 Status = NtCreatePort(&AuthPortHandle,
284 &ObjectAttributes,
285 sizeof(LSA_CONNECTION_INFO),
286 sizeof(LSA_API_MSG),
287 sizeof(LSA_API_MSG) * 32);
288 if (!NT_SUCCESS(Status))
289 {
290 WARN("NtCreatePort() failed (Status %lx)\n", Status);
291 return Status;
292 }
293
294 RtlInitUnicodeString(&EventName,
295 L"\\SECURITY\\LSA_AUTHENTICATION_INITIALIZED");
296 InitializeObjectAttributes(&ObjectAttributes,
297 &EventName,
298 OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,
299 NULL,
300 NULL);
301 Status = NtOpenEvent(&EventHandle,
302 EVENT_MODIFY_STATE,
303 &ObjectAttributes);
304 if (!NT_SUCCESS(Status))
305 {
306 TRACE("NtOpenEvent failed (Status 0x%08lx)\n", Status);
307
308 Status = NtCreateEvent(&EventHandle,
309 EVENT_MODIFY_STATE,
310 &ObjectAttributes,
311 NotificationEvent,
312 FALSE);
313 if (!NT_SUCCESS(Status))
314 {
315 WARN("NtCreateEvent failed (Status 0x%08lx)\n", Status);
316 return Status;
317 }
318 }
319
320 Status = NtSetEvent(EventHandle, NULL);
321 NtClose(EventHandle);
322 if (!NT_SUCCESS(Status))
323 {
324 WARN("NtSetEvent failed (Status 0x%08lx)\n", Status);
325 return Status;
326 }
327
328 PortThreadHandle = CreateThread(NULL,
329 0x1000,
330 (LPTHREAD_START_ROUTINE)AuthPortThreadRoutine,
331 NULL,
332 0,
333 &ThreadId);
334
335
336 return STATUS_SUCCESS;
337 }
338
339 /* EOF */