491e7205e339547f23bbb0e46d77abfd6c4e176a
[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 /* INCLUDES ****************************************************************/
10
11
12 #include "lsasrv.h"
13
14 WINE_DEFAULT_DEBUG_CHANNEL(lsasrv);
15
16
17 static LIST_ENTRY LsapLogonContextList;
18
19 static HANDLE PortThreadHandle = NULL;
20 static HANDLE AuthPortHandle = NULL;
21
22
23 /* FUNCTIONS ***************************************************************/
24
25 static NTSTATUS
26 LsapDeregisterLogonProcess(PLSA_API_MSG RequestMsg,
27 PLSAP_LOGON_CONTEXT LogonContext)
28 {
29 TRACE("(%p %p)\n", RequestMsg, LogonContext);
30
31 RemoveHeadList(&LogonContext->Entry);
32
33 NtClose(LogonContext->ClientProcessHandle);
34 NtClose(LogonContext->ConnectionHandle);
35
36 RtlFreeHeap(RtlGetProcessHeap(), 0, LogonContext);
37
38 return STATUS_SUCCESS;
39 }
40
41
42 static NTSTATUS
43 LsapCheckLogonProcess(PLSA_API_MSG RequestMsg,
44 PLSAP_LOGON_CONTEXT *LogonContext)
45 {
46 OBJECT_ATTRIBUTES ObjectAttributes;
47 HANDLE ProcessHandle = NULL;
48 PLSAP_LOGON_CONTEXT Context = NULL;
49 NTSTATUS Status;
50
51 TRACE("(%p)\n", RequestMsg);
52
53 TRACE("Client ID: %p %p\n", RequestMsg->h.ClientId.UniqueProcess, RequestMsg->h.ClientId.UniqueThread);
54
55 InitializeObjectAttributes(&ObjectAttributes,
56 NULL,
57 0,
58 NULL,
59 NULL);
60
61 Status = NtOpenProcess(&ProcessHandle,
62 PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION | PROCESS_DUP_HANDLE,
63 &ObjectAttributes,
64 &RequestMsg->h.ClientId);
65 if (!NT_SUCCESS(Status))
66 {
67 TRACE("NtOpenProcess() failed (Status %lx)\n", Status);
68 return Status;
69 }
70
71 /* Allocate the logon context */
72 Context = RtlAllocateHeap(RtlGetProcessHeap(),
73 HEAP_ZERO_MEMORY,
74 sizeof(LSAP_LOGON_CONTEXT));
75 if (Context == NULL)
76 {
77 NtClose(ProcessHandle);
78 return STATUS_INSUFFICIENT_RESOURCES;
79 }
80
81 TRACE("New LogonContext: %p\n", Context);
82
83 Context->ClientProcessHandle = ProcessHandle;
84
85 *LogonContext = Context;
86
87 return STATUS_SUCCESS;
88 }
89
90
91 static NTSTATUS
92 LsapHandlePortConnection(PLSA_API_MSG RequestMsg)
93 {
94 PLSAP_LOGON_CONTEXT LogonContext = NULL;
95 HANDLE ConnectionHandle = NULL;
96 BOOLEAN Accept;
97 REMOTE_PORT_VIEW RemotePortView;
98 NTSTATUS Status;
99
100 TRACE("(%p)\n", RequestMsg);
101
102 TRACE("Logon Process Name: %s\n", RequestMsg->ConnectInfo.LogonProcessNameBuffer);
103
104 Status = LsapCheckLogonProcess(RequestMsg,
105 &LogonContext);
106
107 RequestMsg->ConnectInfo.OperationalMode = 0x43218765;
108
109 RequestMsg->ConnectInfo.Status = Status;
110
111 if (NT_SUCCESS(Status))
112 {
113 Accept = TRUE;
114 }
115 else
116 {
117 Accept = FALSE;
118 }
119
120 RemotePortView.Length = sizeof(REMOTE_PORT_VIEW);
121 Status = NtAcceptConnectPort(&ConnectionHandle,
122 (PVOID*)LogonContext,
123 &RequestMsg->h,
124 Accept,
125 NULL,
126 &RemotePortView);
127 if (!NT_SUCCESS(Status))
128 {
129 ERR("NtAcceptConnectPort failed (Status 0x%lx)\n", Status);
130 return Status;
131 }
132
133 if (Accept == TRUE)
134 {
135 LogonContext->ConnectionHandle = ConnectionHandle;
136
137 InsertHeadList(&LsapLogonContextList,
138 &LogonContext->Entry);
139
140 Status = NtCompleteConnectPort(ConnectionHandle);
141 if (!NT_SUCCESS(Status))
142 {
143 ERR("NtCompleteConnectPort failed (Status 0x%lx)\n", Status);
144 return Status;
145 }
146 }
147
148 return Status;
149 }
150
151
152 NTSTATUS WINAPI
153 AuthPortThreadRoutine(PVOID Param)
154 {
155 PLSAP_LOGON_CONTEXT LogonContext;
156 PLSA_API_MSG ReplyMsg = NULL;
157 LSA_API_MSG RequestMsg;
158 NTSTATUS Status;
159
160 TRACE("AuthPortThreadRoutine() called\n");
161
162 Status = STATUS_SUCCESS;
163
164 for (;;)
165 {
166 TRACE("Reply: %p\n", ReplyMsg);
167 Status = NtReplyWaitReceivePort(AuthPortHandle,
168 (PVOID*)&LogonContext,
169 (PPORT_MESSAGE)ReplyMsg,
170 (PPORT_MESSAGE)&RequestMsg);
171 if (!NT_SUCCESS(Status))
172 {
173 TRACE("NtReplyWaitReceivePort() failed (Status %lx)\n", Status);
174 break;
175 }
176
177 TRACE("Received message\n");
178
179 switch (RequestMsg.h.u2.s2.Type)
180 {
181 case LPC_CONNECTION_REQUEST:
182 TRACE("Port connection request\n");
183 Status = LsapHandlePortConnection(&RequestMsg);
184 ReplyMsg = NULL;
185 break;
186
187 case LPC_PORT_CLOSED:
188 TRACE("Port closed\n");
189 ReplyMsg = NULL;
190 break;
191
192 case LPC_CLIENT_DIED:
193 TRACE("Client died\n");
194 ReplyMsg = NULL;
195 break;
196
197 default:
198 TRACE("Received request (ApiNumber: %lu)\n", RequestMsg.ApiNumber);
199
200 switch (RequestMsg.ApiNumber)
201 {
202 case LSASS_REQUEST_CALL_AUTHENTICATION_PACKAGE:
203 RequestMsg.Status = LsapCallAuthenticationPackage(&RequestMsg,
204 LogonContext);
205 ReplyMsg = &RequestMsg;
206 break;
207
208 case LSASS_REQUEST_DEREGISTER_LOGON_PROCESS:
209
210 ReplyMsg = &RequestMsg;
211 RequestMsg.Status = STATUS_SUCCESS;
212 NtReplyPort(AuthPortHandle,
213 &ReplyMsg->h);
214
215 LsapDeregisterLogonProcess(&RequestMsg,
216 LogonContext);
217
218 ReplyMsg = NULL;
219 break;
220
221 case LSASS_REQUEST_LOGON_USER:
222 RequestMsg.Status = LsapLogonUser(&RequestMsg,
223 LogonContext);
224 ReplyMsg = &RequestMsg;
225 break;
226
227 case LSASS_REQUEST_LOOKUP_AUTHENTICATION_PACKAGE:
228 RequestMsg.Status = LsapLookupAuthenticationPackage(&RequestMsg,
229 LogonContext);
230 ReplyMsg = &RequestMsg;
231 break;
232
233 default:
234 RequestMsg.Status = STATUS_INVALID_SYSTEM_SERVICE;
235 ReplyMsg = &RequestMsg;
236 break;
237 }
238
239 break;
240 }
241 }
242
243 return STATUS_SUCCESS;
244 }
245
246
247 NTSTATUS
248 StartAuthenticationPort(VOID)
249 {
250 OBJECT_ATTRIBUTES ObjectAttributes;
251 UNICODE_STRING PortName;
252 DWORD ThreadId;
253 NTSTATUS Status;
254
255 /* Initialize the logon context list */
256 InitializeListHead(&LsapLogonContextList);
257
258 RtlInitUnicodeString(&PortName,
259 L"\\LsaAuthenticationPort");
260
261 InitializeObjectAttributes(&ObjectAttributes,
262 &PortName,
263 0,
264 NULL,
265 NULL);
266
267 Status = NtCreatePort(&AuthPortHandle,
268 &ObjectAttributes,
269 sizeof(LSA_CONNECTION_INFO),
270 sizeof(LSA_API_MSG),
271 sizeof(LSA_API_MSG) * 32);
272 if (!NT_SUCCESS(Status))
273 {
274 TRACE("NtCreatePort() failed (Status %lx)\n", Status);
275 return Status;
276 }
277
278 PortThreadHandle = CreateThread(NULL,
279 0x1000,
280 (LPTHREAD_START_ROUTINE)AuthPortThreadRoutine,
281 NULL,
282 0,
283 &ThreadId);
284
285
286 return STATUS_SUCCESS;
287 }
288
289 /* EOF */