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
11 typedef struct _LSAP_LOGON_SESSION
17 LARGE_INTEGER LogonTime
;
19 UNICODE_STRING UserName
;
20 UNICODE_STRING LogonDomain
;
21 UNICODE_STRING AuthenticationPackage
;
22 UNICODE_STRING LogonServer
;
23 UNICODE_STRING DnsDomainName
;
25 } LSAP_LOGON_SESSION
, *PLSAP_LOGON_SESSION
;
28 /* GLOBALS *****************************************************************/
30 LIST_ENTRY SessionListHead
;
33 /* FUNCTIONS ***************************************************************/
36 LsapInitLogonSessions(VOID
)
38 InitializeListHead(&SessionListHead
);
45 LsapGetLogonSession(IN PLUID LogonId
)
47 PLIST_ENTRY SessionEntry
;
48 PLSAP_LOGON_SESSION CurrentSession
;
50 SessionEntry
= SessionListHead
.Flink
;
51 while (SessionEntry
!= &SessionListHead
)
53 CurrentSession
= CONTAINING_RECORD(SessionEntry
,
56 if (RtlEqualLuid(&CurrentSession
->LogonId
, LogonId
))
57 return CurrentSession
;
59 SessionEntry
= SessionEntry
->Flink
;
67 LsapSetLogonSessionData(IN PLUID LogonId
)
69 PLSAP_LOGON_SESSION Session
;
71 TRACE("LsapSetLogonSessionData(%p)\n", LogonId
);
73 Session
= LsapGetLogonSession(LogonId
);
75 return STATUS_NO_SUCH_LOGON_SESSION
;
78 return STATUS_SUCCESS
;
84 LsapCreateLogonSession(IN PLUID LogonId
)
86 PLSAP_LOGON_SESSION Session
;
89 TRACE("LsapCreateLogonSession(%p)\n", LogonId
);
91 /* Fail, if a session already exists */
92 if (LsapGetLogonSession(LogonId
) != NULL
)
93 return STATUS_LOGON_SESSION_COLLISION
;
95 /* Allocate a new session entry */
96 Session
= RtlAllocateHeap(RtlGetProcessHeap(),
98 sizeof(LSAP_LOGON_SESSION
));
100 return STATUS_INSUFFICIENT_RESOURCES
;
102 /* Initialize the session entry */
103 RtlCopyLuid(&Session
->LogonId
, LogonId
);
105 TRACE("LsapCreateLogonSession(<0x%lx,0x%lx>)\n",
106 LogonId
->HighPart
, LogonId
->LowPart
);
108 /* Tell ntoskrnl to create a new logon session */
109 Status
= LsapRmCreateLogonSession(LogonId
);
110 if (!NT_SUCCESS(Status
))
112 RtlFreeHeap(RtlGetProcessHeap(), 0, Session
);
116 /* Insert the new session into the session list */
117 InsertHeadList(&SessionListHead
, &Session
->Entry
);
120 return STATUS_SUCCESS
;
126 LsapDeleteLogonSession(IN PLUID LogonId
)
128 PLSAP_LOGON_SESSION Session
;
131 TRACE("LsapDeleteLogonSession(%p)\n", LogonId
);
133 /* Fail, if the session does not exist */
134 Session
= LsapGetLogonSession(LogonId
);
136 return STATUS_NO_SUCH_LOGON_SESSION
;
138 TRACE("LsapDeleteLogonSession(<0x%lx,0x%lx>)\n",
139 LogonId
->HighPart
, LogonId
->LowPart
);
141 /* Tell ntoskrnl to delete the logon session */
142 Status
= LsapRmDeleteLogonSession(LogonId
);
143 if (!NT_SUCCESS(Status
))
146 /* Remove the session entry from the list */
147 RemoveEntryList(&Session
->Entry
);
150 /* Free the session data */
151 if (Session
->Sid
!= NULL
)
152 RtlFreeHeap(RtlGetProcessHeap(), 0, Session
->Sid
);
154 if (Session
->UserName
.Buffer
!= NULL
)
155 RtlFreeHeap(RtlGetProcessHeap(), 0, Session
->UserName
.Buffer
);
157 if (Session
->LogonDomain
.Buffer
!= NULL
)
158 RtlFreeHeap(RtlGetProcessHeap(), 0, Session
->LogonDomain
.Buffer
);
160 if (Session
->AuthenticationPackage
.Buffer
!= NULL
)
161 RtlFreeHeap(RtlGetProcessHeap(), 0, Session
->AuthenticationPackage
.Buffer
);
163 if (Session
->LogonServer
.Buffer
!= NULL
)
164 RtlFreeHeap(RtlGetProcessHeap(), 0, Session
->LogonServer
.Buffer
);
166 if (Session
->DnsDomainName
.Buffer
!= NULL
)
167 RtlFreeHeap(RtlGetProcessHeap(), 0, Session
->DnsDomainName
.Buffer
);
169 if (Session
->Upn
.Buffer
!= NULL
)
170 RtlFreeHeap(RtlGetProcessHeap(), 0, Session
->Upn
.Buffer
);
172 /* Free the session entry */
173 RtlFreeHeap(RtlGetProcessHeap(), 0, Session
);
175 return STATUS_SUCCESS
;
183 _In_ ULONG AuthenticationPackage
,
184 _In_ PLSA_STRING PrimaryKeyValue
,
185 _In_ PLSA_STRING Credential
)
188 return STATUS_SUCCESS
;
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
)
204 return STATUS_SUCCESS
;
210 LsapDeleteCredential(
212 _In_ ULONG AuthenticationPackage
,
213 _In_ PLSA_STRING PrimaryKeyValue
)
216 return STATUS_SUCCESS
;
221 LsapEnumLogonSessions(IN OUT PLSA_API_MSG RequestMsg
)
223 OBJECT_ATTRIBUTES ObjectAttributes
;
224 HANDLE ProcessHandle
= NULL
;
225 PLIST_ENTRY SessionEntry
;
226 PLSAP_LOGON_SESSION CurrentSession
;
228 ULONG i
, Length
, MemSize
;
229 PVOID ClientBaseAddress
= NULL
;
232 TRACE("LsapEnumLogonSessions(%p)\n", RequestMsg
);
234 Length
= SessionCount
* sizeof(LUID
);
235 SessionList
= RtlAllocateHeap(RtlGetProcessHeap(),
238 if (SessionList
== NULL
)
239 return STATUS_INSUFFICIENT_RESOURCES
;
242 SessionEntry
= SessionListHead
.Flink
;
243 while (SessionEntry
!= &SessionListHead
)
245 CurrentSession
= CONTAINING_RECORD(SessionEntry
,
249 RtlCopyLuid(&SessionList
[i
],
250 &CurrentSession
->LogonId
);
252 SessionEntry
= SessionEntry
->Flink
;
256 InitializeObjectAttributes(&ObjectAttributes
,
262 Status
= NtOpenProcess(&ProcessHandle
,
263 PROCESS_VM_READ
| PROCESS_VM_WRITE
| PROCESS_VM_OPERATION
,
265 &RequestMsg
->h
.ClientId
);
266 if (!NT_SUCCESS(Status
))
268 TRACE("NtOpenProcess() failed (Status %lx)\n", Status
);
272 TRACE("Length: %lu\n", Length
);
275 Status
= NtAllocateVirtualMemory(ProcessHandle
,
281 if (!NT_SUCCESS(Status
))
283 TRACE("NtAllocateVirtualMemory() failed (Status %lx)\n", Status
);
287 TRACE("MemSize: %lu\n", MemSize
);
288 TRACE("ClientBaseAddress: %p\n", ClientBaseAddress
);
290 Status
= NtWriteVirtualMemory(ProcessHandle
,
295 if (!NT_SUCCESS(Status
))
297 TRACE("NtWriteVirtualMemory() failed (Status %lx)\n", Status
);
301 RequestMsg
->EnumLogonSessions
.Reply
.LogonSessionCount
= SessionCount
;
302 RequestMsg
->EnumLogonSessions
.Reply
.LogonSessionBuffer
= ClientBaseAddress
;
305 if (ProcessHandle
!= NULL
)
306 NtClose(ProcessHandle
);
308 if (SessionList
!= NULL
)
309 RtlFreeHeap(RtlGetProcessHeap(), 0, SessionList
);
316 LsapGetLogonSessionData(IN OUT PLSA_API_MSG RequestMsg
)
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 TotalLength
, MemSize
, SidLength
= 0;
327 TRACE("LsapGetLogonSessionData(%p)\n", RequestMsg
);
329 TRACE("LogonId: %lx\n", RequestMsg
->GetLogonSessionData
.Request
.LogonId
.LowPart
);
330 Session
= LsapGetLogonSession(&RequestMsg
->GetLogonSessionData
.Request
.LogonId
);
332 return STATUS_NO_SUCH_LOGON_SESSION
;
334 /* Calculate the required buffer size */
335 TotalLength
= sizeof(SECURITY_LOGON_SESSION_DATA
) +
336 Session
->UserName
.MaximumLength
+
337 Session
->LogonDomain
.MaximumLength
+
338 Session
->AuthenticationPackage
.MaximumLength
+
339 Session
->LogonServer
.MaximumLength
+
340 Session
->DnsDomainName
.MaximumLength
+
341 Session
->Upn
.MaximumLength
;
342 if (Session
->Sid
!= NULL
)
344 SidLength
= RtlLengthSid(Session
->Sid
);
345 TotalLength
+= SidLength
;
347 TRACE("TotalLength: %lu\n", TotalLength
);
349 /* Allocate the buffer */
350 LocalSessionData
= RtlAllocateHeap(RtlGetProcessHeap(),
353 if (LocalSessionData
== NULL
)
354 return STATUS_INSUFFICIENT_RESOURCES
;
356 Ptr
= (PUCHAR
)((ULONG_PTR
)LocalSessionData
+ sizeof(SECURITY_LOGON_SESSION_DATA
));
357 TRACE("LocalSessionData: %p Ptr: %p\n", LocalSessionData
, Ptr
);
359 LocalSessionData
->Size
= sizeof(SECURITY_LOGON_SESSION_DATA
);
361 /* Copy the LogonId */
362 RtlCopyLuid(&LocalSessionData
->LogonId
,
363 &RequestMsg
->GetLogonSessionData
.Request
.LogonId
);
365 /* Copy the UserName string*/
366 LocalSessionData
->UserName
.Length
= Session
->UserName
.Length
;
367 LocalSessionData
->UserName
.MaximumLength
= Session
->UserName
.MaximumLength
;
369 if (Session
->UserName
.MaximumLength
!= 0)
371 RtlCopyMemory(Ptr
, Session
->UserName
.Buffer
, Session
->UserName
.MaximumLength
);
372 Ptr
= (PUCHAR
)((ULONG_PTR
)Ptr
+ Session
->UserName
.MaximumLength
);
374 LocalSessionData
->UserName
.Buffer
= (PWSTR
)((ULONG_PTR
)Ptr
- (ULONG_PTR
)LocalSessionData
);
377 /* Copy the LogonDomain string */
378 LocalSessionData
->LogonDomain
.Length
= Session
->LogonDomain
.Length
;
379 LocalSessionData
->LogonDomain
.MaximumLength
= Session
->LogonDomain
.MaximumLength
;
380 if (Session
->LogonDomain
.MaximumLength
!= 0)
382 RtlCopyMemory(Ptr
, Session
->LogonDomain
.Buffer
, Session
->LogonDomain
.MaximumLength
);
383 Ptr
= (PUCHAR
)((ULONG_PTR
)Ptr
+ Session
->LogonDomain
.MaximumLength
);
385 LocalSessionData
->LogonDomain
.Buffer
= (PWSTR
)((ULONG_PTR
)Ptr
- (ULONG_PTR
)LocalSessionData
);
388 /* Copy the AuthenticationPackage string */
389 LocalSessionData
->AuthenticationPackage
.Length
= Session
->AuthenticationPackage
.Length
;
390 LocalSessionData
->AuthenticationPackage
.MaximumLength
= Session
->AuthenticationPackage
.MaximumLength
;
391 if (Session
->AuthenticationPackage
.MaximumLength
!= 0)
393 RtlCopyMemory(Ptr
, Session
->AuthenticationPackage
.Buffer
, Session
->AuthenticationPackage
.MaximumLength
);
394 Ptr
= (PUCHAR
)((ULONG_PTR
)Ptr
+ Session
->AuthenticationPackage
.MaximumLength
);
396 LocalSessionData
->AuthenticationPackage
.Buffer
= (PWSTR
)((ULONG_PTR
)Ptr
- (ULONG_PTR
)LocalSessionData
);
399 LocalSessionData
->LogonType
= Session
->LogonType
;
400 LocalSessionData
->Session
= 0;
403 if (Session
->Sid
!= NULL
)
405 RtlCopyMemory(Ptr
, Session
->Sid
, SidLength
);
406 Ptr
= (PUCHAR
)((ULONG_PTR
)Ptr
+ SidLength
);
408 LocalSessionData
->Sid
= (PSID
)((ULONG_PTR
)Ptr
- (ULONG_PTR
)LocalSessionData
);
412 LocalSessionData
->LogonTime
.QuadPart
= Session
->LogonTime
.QuadPart
;
414 /* Copy the LogonServer string */
415 LocalSessionData
->LogonServer
.Length
= Session
->LogonServer
.Length
;
416 LocalSessionData
->LogonServer
.MaximumLength
= Session
->LogonServer
.MaximumLength
;
417 if (Session
->LogonServer
.MaximumLength
!= 0)
419 RtlCopyMemory(Ptr
, Session
->LogonServer
.Buffer
, Session
->LogonServer
.MaximumLength
);
420 Ptr
= (PUCHAR
)((ULONG_PTR
)Ptr
+ Session
->LogonServer
.MaximumLength
);
422 LocalSessionData
->LogonServer
.Buffer
= (PWSTR
)((ULONG_PTR
)Ptr
- (ULONG_PTR
)LocalSessionData
);
425 /* Copy the DnsDomainName string */
426 LocalSessionData
->DnsDomainName
.Length
= Session
->DnsDomainName
.Length
;
427 LocalSessionData
->DnsDomainName
.MaximumLength
= Session
->DnsDomainName
.MaximumLength
;
428 if (Session
->DnsDomainName
.MaximumLength
!= 0)
430 RtlCopyMemory(Ptr
, Session
->DnsDomainName
.Buffer
, Session
->DnsDomainName
.MaximumLength
);
431 Ptr
= (PUCHAR
)((ULONG_PTR
)Ptr
+ Session
->DnsDomainName
.MaximumLength
);
433 LocalSessionData
->DnsDomainName
.Buffer
= (PWSTR
)((ULONG_PTR
)Ptr
- (ULONG_PTR
)LocalSessionData
);
436 /* Copy the Upn string */
437 LocalSessionData
->Upn
.Length
= Session
->Upn
.Length
;
438 LocalSessionData
->Upn
.MaximumLength
= Session
->Upn
.MaximumLength
;
439 if (Session
->Upn
.MaximumLength
!= 0)
441 RtlCopyMemory(Ptr
, Session
->Upn
.Buffer
, Session
->Upn
.MaximumLength
);
442 Ptr
= (PUCHAR
)((ULONG_PTR
)Ptr
+ Session
->Upn
.MaximumLength
);
444 LocalSessionData
->Upn
.Buffer
= (PWSTR
)((ULONG_PTR
)Ptr
- (ULONG_PTR
)LocalSessionData
);
448 InitializeObjectAttributes(&ObjectAttributes
,
454 Status
= NtOpenProcess(&ProcessHandle
,
455 PROCESS_VM_READ
| PROCESS_VM_WRITE
| PROCESS_VM_OPERATION
,
457 &RequestMsg
->h
.ClientId
);
458 if (!NT_SUCCESS(Status
))
460 TRACE("NtOpenProcess() failed (Status %lx)\n", Status
);
464 MemSize
= TotalLength
;
465 Status
= NtAllocateVirtualMemory(ProcessHandle
,
471 if (!NT_SUCCESS(Status
))
473 TRACE("NtAllocateVirtualMemory() failed (Status %lx)\n", Status
);
477 TRACE("MemSize: %lu\n", MemSize
);
478 TRACE("ClientBaseAddress: %p\n", ClientBaseAddress
);
480 Status
= NtWriteVirtualMemory(ProcessHandle
,
485 if (!NT_SUCCESS(Status
))
487 TRACE("NtWriteVirtualMemory() failed (Status %lx)\n", Status
);
491 RequestMsg
->GetLogonSessionData
.Reply
.SessionDataBuffer
= ClientBaseAddress
;
494 if (ProcessHandle
!= NULL
)
495 NtClose(ProcessHandle
);
497 if (LocalSessionData
!= NULL
)
498 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalSessionData
);