[LSASRV]
[reactos.git] / reactos / dll / win32 / lsasrv / session.c
1 /*
2 * PROJECT: Local Security Authority Server DLL
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: dll/win32/lsasrv/session.c
5 * PURPOSE: Logon session management routines
6 * COPYRIGHT: Copyright 2013 Eric Kohl
7 */
8
9 #include "lsasrv.h"
10
11 typedef struct _LSAP_LOGON_SESSION
12 {
13 LIST_ENTRY Entry;
14 LUID LogonId;
15 ULONG LogonType;
16 ULONG Session;
17 LARGE_INTEGER LogonTime;
18 PSID Sid;
19 UNICODE_STRING UserName;
20 UNICODE_STRING LogonDomain;
21 UNICODE_STRING AuthenticationPackage;
22 UNICODE_STRING LogonServer;
23 UNICODE_STRING DnsDomainName;
24 UNICODE_STRING Upn;
25 } LSAP_LOGON_SESSION, *PLSAP_LOGON_SESSION;
26
27
28 /* GLOBALS *****************************************************************/
29
30 LIST_ENTRY SessionListHead;
31 ULONG SessionCount;
32
33 /* FUNCTIONS ***************************************************************/
34
35 VOID
36 LsapInitLogonSessions(VOID)
37 {
38 InitializeListHead(&SessionListHead);
39 SessionCount = 0;
40 }
41
42
43 static
44 PLSAP_LOGON_SESSION
45 LsapGetLogonSession(IN PLUID LogonId)
46 {
47 PLIST_ENTRY SessionEntry;
48 PLSAP_LOGON_SESSION CurrentSession;
49
50 SessionEntry = SessionListHead.Flink;
51 while (SessionEntry != &SessionListHead)
52 {
53 CurrentSession = CONTAINING_RECORD(SessionEntry,
54 LSAP_LOGON_SESSION,
55 Entry);
56 if (RtlEqualLuid(&CurrentSession->LogonId, LogonId))
57 return CurrentSession;
58
59 SessionEntry = SessionEntry->Flink;
60 }
61
62 return NULL;
63 }
64
65
66 NTSTATUS
67 LsapSetLogonSessionData(IN PLUID LogonId)
68 {
69 PLSAP_LOGON_SESSION Session;
70
71 TRACE("LsapSetLogonSessionData(%p)\n", LogonId);
72
73 Session = LsapGetLogonSession(LogonId);
74 if (Session == NULL)
75 return STATUS_NO_SUCH_LOGON_SESSION;
76
77
78 return STATUS_SUCCESS;
79 }
80
81
82 NTSTATUS
83 NTAPI
84 LsapCreateLogonSession(IN PLUID LogonId)
85 {
86 PLSAP_LOGON_SESSION Session;
87 NTSTATUS Status;
88
89 TRACE("LsapCreateLogonSession(%p)\n", LogonId);
90
91 /* Fail, if a session already exists */
92 if (LsapGetLogonSession(LogonId) != NULL)
93 return STATUS_LOGON_SESSION_COLLISION;
94
95 /* Allocate a new session entry */
96 Session = RtlAllocateHeap(RtlGetProcessHeap(),
97 HEAP_ZERO_MEMORY,
98 sizeof(LSAP_LOGON_SESSION));
99 if (Session == NULL)
100 return STATUS_INSUFFICIENT_RESOURCES;
101
102 /* Initialize the session entry */
103 RtlCopyLuid(&Session->LogonId, LogonId);
104
105 TRACE("LsapCreateLogonSession(<0x%lx,0x%lx>)\n",
106 LogonId->HighPart, LogonId->LowPart);
107
108 /* Tell ntoskrnl to create a new logon session */
109 Status = LsapRmCreateLogonSession(LogonId);
110 if (!NT_SUCCESS(Status))
111 {
112 RtlFreeHeap(RtlGetProcessHeap(), 0, Session);
113 return Status;
114 }
115
116 /* Insert the new session into the session list */
117 InsertHeadList(&SessionListHead, &Session->Entry);
118 SessionCount++;
119
120 return STATUS_SUCCESS;
121 }
122
123
124 NTSTATUS
125 NTAPI
126 LsapDeleteLogonSession(IN PLUID LogonId)
127 {
128 PLSAP_LOGON_SESSION Session;
129 NTSTATUS Status;
130
131 TRACE("LsapDeleteLogonSession(%p)\n", LogonId);
132
133 /* Fail, if the session does not exist */
134 Session = LsapGetLogonSession(LogonId);
135 if (Session == NULL)
136 return STATUS_NO_SUCH_LOGON_SESSION;
137
138 TRACE("LsapDeleteLogonSession(<0x%lx,0x%lx>)\n",
139 LogonId->HighPart, LogonId->LowPart);
140
141 /* Tell ntoskrnl to delete the logon session */
142 Status = LsapRmDeleteLogonSession(LogonId);
143 if (!NT_SUCCESS(Status))
144 return Status;
145
146 /* Remove the session entry from the list */
147 RemoveEntryList(&Session->Entry);
148 SessionCount--;
149
150 /* Free the session data */
151 if (Session->Sid != NULL)
152 RtlFreeHeap(RtlGetProcessHeap(), 0, Session->Sid);
153
154 if (Session->UserName.Buffer != NULL)
155 RtlFreeHeap(RtlGetProcessHeap(), 0, Session->UserName.Buffer);
156
157 if (Session->LogonDomain.Buffer != NULL)
158 RtlFreeHeap(RtlGetProcessHeap(), 0, Session->LogonDomain.Buffer);
159
160 if (Session->AuthenticationPackage.Buffer != NULL)
161 RtlFreeHeap(RtlGetProcessHeap(), 0, Session->AuthenticationPackage.Buffer);
162
163 if (Session->LogonServer.Buffer != NULL)
164 RtlFreeHeap(RtlGetProcessHeap(), 0, Session->LogonServer.Buffer);
165
166 if (Session->DnsDomainName.Buffer != NULL)
167 RtlFreeHeap(RtlGetProcessHeap(), 0, Session->DnsDomainName.Buffer);
168
169 if (Session->Upn.Buffer != NULL)
170 RtlFreeHeap(RtlGetProcessHeap(), 0, Session->Upn.Buffer);
171
172 /* Free the session entry */
173 RtlFreeHeap(RtlGetProcessHeap(), 0, Session);
174
175 return STATUS_SUCCESS;
176 }
177
178
179 NTSTATUS
180 NTAPI
181 LsapAddCredential(
182 _In_ PLUID LogonId,
183 _In_ ULONG AuthenticationPackage,
184 _In_ PLSA_STRING PrimaryKeyValue,
185 _In_ PLSA_STRING Credential)
186 {
187
188 return STATUS_SUCCESS;
189 }
190
191
192 NTSTATUS
193 NTAPI
194 LsapGetCredentials(
195 _In_ PLUID LogonId,
196 _In_ ULONG AuthenticationPackage,
197 _Inout_ PULONG QueryContext,
198 _In_ BOOLEAN RetrieveAllCredentials,
199 _Inout_ PLSA_STRING PrimaryKeyValue,
200 _Out_ PULONG PrimaryKeyLength,
201 _Out_ PLSA_STRING Credentials)
202 {
203
204 return STATUS_SUCCESS;
205 }
206
207
208 NTSTATUS
209 NTAPI
210 LsapDeleteCredential(
211 _In_ PLUID LogonId,
212 _In_ ULONG AuthenticationPackage,
213 _In_ PLSA_STRING PrimaryKeyValue)
214 {
215
216 return STATUS_SUCCESS;
217 }
218
219
220 NTSTATUS
221 LsapEnumLogonSessions(IN OUT PLSA_API_MSG RequestMsg)
222 {
223 OBJECT_ATTRIBUTES ObjectAttributes;
224 HANDLE ProcessHandle = NULL;
225 PLIST_ENTRY SessionEntry;
226 PLSAP_LOGON_SESSION CurrentSession;
227 PLUID SessionList;
228 ULONG i, Length, MemSize;
229 PVOID ClientBaseAddress = NULL;
230 NTSTATUS Status;
231
232 TRACE("LsapEnumLogonSessions(%p)\n", RequestMsg);
233
234 Length = SessionCount * sizeof(LUID);
235 SessionList = RtlAllocateHeap(RtlGetProcessHeap(),
236 HEAP_ZERO_MEMORY,
237 Length);
238 if (SessionList == NULL)
239 return STATUS_INSUFFICIENT_RESOURCES;
240
241 i = 0;
242 SessionEntry = SessionListHead.Flink;
243 while (SessionEntry != &SessionListHead)
244 {
245 CurrentSession = CONTAINING_RECORD(SessionEntry,
246 LSAP_LOGON_SESSION,
247 Entry);
248
249 RtlCopyLuid(&SessionList[i],
250 &CurrentSession->LogonId);
251
252 SessionEntry = SessionEntry->Flink;
253 i++;
254 }
255
256 InitializeObjectAttributes(&ObjectAttributes,
257 NULL,
258 0,
259 NULL,
260 NULL);
261
262 Status = NtOpenProcess(&ProcessHandle,
263 PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION,
264 &ObjectAttributes,
265 &RequestMsg->h.ClientId);
266 if (!NT_SUCCESS(Status))
267 {
268 TRACE("NtOpenProcess() failed (Status %lx)\n", Status);
269 goto done;
270 }
271
272 TRACE("Length: %lu\n", Length);
273
274 MemSize = Length;
275 Status = NtAllocateVirtualMemory(ProcessHandle,
276 &ClientBaseAddress,
277 0,
278 &MemSize,
279 MEM_COMMIT,
280 PAGE_READWRITE);
281 if (!NT_SUCCESS(Status))
282 {
283 TRACE("NtAllocateVirtualMemory() failed (Status %lx)\n", Status);
284 goto done;
285 }
286
287 TRACE("MemSize: %lu\n", MemSize);
288 TRACE("ClientBaseAddress: %p\n", ClientBaseAddress);
289
290 Status = NtWriteVirtualMemory(ProcessHandle,
291 ClientBaseAddress,
292 SessionList,
293 Length,
294 NULL);
295 if (!NT_SUCCESS(Status))
296 {
297 TRACE("NtWriteVirtualMemory() failed (Status %lx)\n", Status);
298 goto done;
299 }
300
301 RequestMsg->EnumLogonSessions.Reply.LogonSessionCount = SessionCount;
302 RequestMsg->EnumLogonSessions.Reply.LogonSessionBuffer = ClientBaseAddress;
303
304 done:
305 if (ProcessHandle != NULL)
306 NtClose(ProcessHandle);
307
308 if (SessionList != NULL)
309 RtlFreeHeap(RtlGetProcessHeap(), 0, SessionList);
310
311 return Status;
312 }
313
314
315 NTSTATUS
316 LsapGetLogonSessionData(IN OUT PLSA_API_MSG RequestMsg)
317 {
318 OBJECT_ATTRIBUTES ObjectAttributes;
319 HANDLE ProcessHandle = NULL;
320 PLSAP_LOGON_SESSION Session;
321 PSECURITY_LOGON_SESSION_DATA LocalSessionData;
322 PVOID ClientBaseAddress = NULL;
323 ULONG Length, MemSize;
324 LPWSTR Ptr;
325 NTSTATUS Status;
326
327 TRACE("LsapGetLogonSessionData(%p)\n", RequestMsg);
328
329 TRACE("LogonId: %lx\n", RequestMsg->GetLogonSessionData.Request.LogonId.LowPart);
330 Session = LsapGetLogonSession(&RequestMsg->GetLogonSessionData.Request.LogonId);
331 if (Session == NULL)
332 return STATUS_NO_SUCH_LOGON_SESSION;
333
334 /* Calculate the required buffer size */
335 Length = sizeof(SECURITY_LOGON_SESSION_DATA) +
336 Session->UserName.MaximumLength;
337 /*
338 Session->LogonDomain.MaximumLength +
339 Session->AuthenticationPackage.MaximumLength +
340 Session->LogonServer.MaximumLength +
341 Session->DnsDomainName.MaximumLength +
342 Session->Upn.MaximumLength;
343
344 if (Session->Sid != NULL)
345 RtlLengthSid(Session->Sid);
346 */
347
348 TRACE("Length: %lu\n", Length);
349
350 /* Allocate the buffer */
351 LocalSessionData = RtlAllocateHeap(RtlGetProcessHeap(),
352 HEAP_ZERO_MEMORY,
353 Length);
354 if (LocalSessionData == NULL)
355 return STATUS_INSUFFICIENT_RESOURCES;
356
357 Ptr = (LPWSTR)((ULONG_PTR)LocalSessionData + sizeof(SECURITY_LOGON_SESSION_DATA));
358 TRACE("LocalSessionData: %p Ptr: %p\n", LocalSessionData, Ptr);
359
360 LocalSessionData->Size = sizeof(SECURITY_LOGON_SESSION_DATA);
361
362 RtlCopyLuid(&LocalSessionData->LogonId,
363 &RequestMsg->GetLogonSessionData.Request.LogonId);
364
365 LocalSessionData->UserName.Length = Session->UserName.Length;
366 LocalSessionData->UserName.MaximumLength = Session->UserName.MaximumLength;
367 LocalSessionData->UserName.Buffer = Ptr;
368
369 // RtlCopyMemory(Ptr)
370
371
372 LocalSessionData->LogonType = Session->LogonType;
373 LocalSessionData->Session = 0;
374
375
376
377
378 InitializeObjectAttributes(&ObjectAttributes,
379 NULL,
380 0,
381 NULL,
382 NULL);
383
384 Status = NtOpenProcess(&ProcessHandle,
385 PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION,
386 &ObjectAttributes,
387 &RequestMsg->h.ClientId);
388 if (!NT_SUCCESS(Status))
389 {
390 TRACE("NtOpenProcess() failed (Status %lx)\n", Status);
391 goto done;
392 }
393
394 MemSize = Length;
395 Status = NtAllocateVirtualMemory(ProcessHandle,
396 &ClientBaseAddress,
397 0,
398 &MemSize,
399 MEM_COMMIT,
400 PAGE_READWRITE);
401 if (!NT_SUCCESS(Status))
402 {
403 TRACE("NtAllocateVirtualMemory() failed (Status %lx)\n", Status);
404 goto done;
405 }
406
407 TRACE("MemSize: %lu\n", MemSize);
408 TRACE("ClientBaseAddress: %p\n", ClientBaseAddress);
409
410 Status = NtWriteVirtualMemory(ProcessHandle,
411 ClientBaseAddress,
412 LocalSessionData,
413 Length,
414 NULL);
415 if (!NT_SUCCESS(Status))
416 {
417 TRACE("NtWriteVirtualMemory() failed (Status %lx)\n", Status);
418 goto done;
419 }
420
421 RequestMsg->GetLogonSessionData.Reply.SessionDataBuffer = ClientBaseAddress;
422
423 done:
424 if (ProcessHandle != NULL)
425 NtClose(ProcessHandle);
426
427 if (LocalSessionData != NULL)
428 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalSessionData);
429
430 return Status;
431 }
432
433 /* EOF */