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