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