d6b848283d16684797e4d71dd58ae565f1b17222
[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("(%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("(%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("(%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 NTSTATUS Status;
266
267 /* Initialize the logon context list */
268 InitializeListHead(&LsapLogonContextList);
269
270 RtlInitUnicodeString(&PortName,
271 L"\\LsaAuthenticationPort");
272
273 InitializeObjectAttributes(&ObjectAttributes,
274 &PortName,
275 0,
276 NULL,
277 NULL);
278
279 Status = NtCreatePort(&AuthPortHandle,
280 &ObjectAttributes,
281 sizeof(LSA_CONNECTION_INFO),
282 sizeof(LSA_API_MSG),
283 sizeof(LSA_API_MSG) * 32);
284 if (!NT_SUCCESS(Status))
285 {
286 TRACE("NtCreatePort() failed (Status %lx)\n", Status);
287 return Status;
288 }
289
290 PortThreadHandle = CreateThread(NULL,
291 0x1000,
292 (LPTHREAD_START_ROUTINE)AuthPortThreadRoutine,
293 NULL,
294 0,
295 &ThreadId);
296
297
298 return STATUS_SUCCESS;
299 }
300
301 /* EOF */