* Sync up to trunk head (r64377).
[reactos.git] / 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 default:
241 RequestMsg.Status = STATUS_INVALID_SYSTEM_SERVICE;
242 ReplyMsg = &RequestMsg;
243 break;
244 }
245
246 break;
247 }
248 }
249
250 return STATUS_SUCCESS;
251 }
252
253
254 NTSTATUS
255 StartAuthenticationPort(VOID)
256 {
257 OBJECT_ATTRIBUTES ObjectAttributes;
258 UNICODE_STRING PortName;
259 DWORD ThreadId;
260 NTSTATUS Status;
261
262 /* Initialize the logon context list */
263 InitializeListHead(&LsapLogonContextList);
264
265 RtlInitUnicodeString(&PortName,
266 L"\\LsaAuthenticationPort");
267
268 InitializeObjectAttributes(&ObjectAttributes,
269 &PortName,
270 0,
271 NULL,
272 NULL);
273
274 Status = NtCreatePort(&AuthPortHandle,
275 &ObjectAttributes,
276 sizeof(LSA_CONNECTION_INFO),
277 sizeof(LSA_API_MSG),
278 sizeof(LSA_API_MSG) * 32);
279 if (!NT_SUCCESS(Status))
280 {
281 TRACE("NtCreatePort() failed (Status %lx)\n", Status);
282 return Status;
283 }
284
285 PortThreadHandle = CreateThread(NULL,
286 0x1000,
287 (LPTHREAD_START_ROUTINE)AuthPortThreadRoutine,
288 NULL,
289 0,
290 &ThreadId);
291
292
293 return STATUS_SUCCESS;
294 }
295
296 /* EOF */