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(
70 _In_ PUNICODE_STRING UserName
)
72 PLSAP_LOGON_SESSION Session
;
74 TRACE("LsapSetLogonSessionData(%p)\n", LogonId
);
76 Session
= LsapGetLogonSession(LogonId
);
78 return STATUS_NO_SUCH_LOGON_SESSION
;
80 TRACE("LogonType %lu\n", LogonType
);
81 Session
->LogonType
= LogonType
;
83 TRACE("UserName %wZ\n", UserName
);
84 Session
->UserName
.Buffer
= RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY
, UserName
->MaximumLength
);
85 if (Session
->UserName
.Buffer
== NULL
)
86 return STATUS_INSUFFICIENT_RESOURCES
;
88 Session
->UserName
.Length
= UserName
->Length
;
89 Session
->UserName
.MaximumLength
= UserName
->MaximumLength
;
90 RtlCopyMemory(Session
->UserName
.Buffer
, UserName
->Buffer
, UserName
->MaximumLength
);
92 return STATUS_SUCCESS
;
98 LsapCreateLogonSession(IN PLUID LogonId
)
100 PLSAP_LOGON_SESSION Session
;
103 TRACE("LsapCreateLogonSession(%p)\n", LogonId
);
105 /* Fail, if a session already exists */
106 if (LsapGetLogonSession(LogonId
) != NULL
)
107 return STATUS_LOGON_SESSION_COLLISION
;
109 /* Allocate a new session entry */
110 Session
= RtlAllocateHeap(RtlGetProcessHeap(),
112 sizeof(LSAP_LOGON_SESSION
));
114 return STATUS_INSUFFICIENT_RESOURCES
;
116 /* Initialize the session entry */
117 RtlCopyLuid(&Session
->LogonId
, LogonId
);
119 TRACE("LsapCreateLogonSession(<0x%lx,0x%lx>)\n",
120 LogonId
->HighPart
, LogonId
->LowPart
);
122 /* Tell ntoskrnl to create a new logon session */
123 Status
= LsapRmCreateLogonSession(LogonId
);
124 if (!NT_SUCCESS(Status
))
126 RtlFreeHeap(RtlGetProcessHeap(), 0, Session
);
130 /* Insert the new session into the session list */
131 InsertHeadList(&SessionListHead
, &Session
->Entry
);
134 return STATUS_SUCCESS
;
140 LsapDeleteLogonSession(IN PLUID LogonId
)
142 PLSAP_LOGON_SESSION Session
;
145 TRACE("LsapDeleteLogonSession(%p)\n", LogonId
);
147 /* Fail, if the session does not exist */
148 Session
= LsapGetLogonSession(LogonId
);
150 return STATUS_NO_SUCH_LOGON_SESSION
;
152 TRACE("LsapDeleteLogonSession(<0x%lx,0x%lx>)\n",
153 LogonId
->HighPart
, LogonId
->LowPart
);
155 /* Tell ntoskrnl to delete the logon session */
156 Status
= LsapRmDeleteLogonSession(LogonId
);
157 if (!NT_SUCCESS(Status
))
160 /* Remove the session entry from the list */
161 RemoveEntryList(&Session
->Entry
);
164 /* Free the session data */
165 if (Session
->Sid
!= NULL
)
166 RtlFreeHeap(RtlGetProcessHeap(), 0, Session
->Sid
);
168 if (Session
->UserName
.Buffer
!= NULL
)
169 RtlFreeHeap(RtlGetProcessHeap(), 0, Session
->UserName
.Buffer
);
171 if (Session
->LogonDomain
.Buffer
!= NULL
)
172 RtlFreeHeap(RtlGetProcessHeap(), 0, Session
->LogonDomain
.Buffer
);
174 if (Session
->AuthenticationPackage
.Buffer
!= NULL
)
175 RtlFreeHeap(RtlGetProcessHeap(), 0, Session
->AuthenticationPackage
.Buffer
);
177 if (Session
->LogonServer
.Buffer
!= NULL
)
178 RtlFreeHeap(RtlGetProcessHeap(), 0, Session
->LogonServer
.Buffer
);
180 if (Session
->DnsDomainName
.Buffer
!= NULL
)
181 RtlFreeHeap(RtlGetProcessHeap(), 0, Session
->DnsDomainName
.Buffer
);
183 if (Session
->Upn
.Buffer
!= NULL
)
184 RtlFreeHeap(RtlGetProcessHeap(), 0, Session
->Upn
.Buffer
);
186 /* Free the session entry */
187 RtlFreeHeap(RtlGetProcessHeap(), 0, Session
);
189 return STATUS_SUCCESS
;
197 _In_ ULONG AuthenticationPackage
,
198 _In_ PLSA_STRING PrimaryKeyValue
,
199 _In_ PLSA_STRING Credential
)
202 return STATUS_SUCCESS
;
210 _In_ ULONG AuthenticationPackage
,
211 _Inout_ PULONG QueryContext
,
212 _In_ BOOLEAN RetrieveAllCredentials
,
213 _Inout_ PLSA_STRING PrimaryKeyValue
,
214 _Out_ PULONG PrimaryKeyLength
,
215 _Out_ PLSA_STRING Credentials
)
218 return STATUS_SUCCESS
;
224 LsapDeleteCredential(
226 _In_ ULONG AuthenticationPackage
,
227 _In_ PLSA_STRING PrimaryKeyValue
)
230 return STATUS_SUCCESS
;
235 LsapEnumLogonSessions(IN OUT PLSA_API_MSG RequestMsg
)
237 OBJECT_ATTRIBUTES ObjectAttributes
;
238 HANDLE ProcessHandle
= NULL
;
239 PLIST_ENTRY SessionEntry
;
240 PLSAP_LOGON_SESSION CurrentSession
;
242 ULONG i
, Length
, MemSize
;
243 PVOID ClientBaseAddress
= NULL
;
246 TRACE("LsapEnumLogonSessions(%p)\n", RequestMsg
);
248 Length
= SessionCount
* sizeof(LUID
);
249 SessionList
= RtlAllocateHeap(RtlGetProcessHeap(),
252 if (SessionList
== NULL
)
253 return STATUS_INSUFFICIENT_RESOURCES
;
256 SessionEntry
= SessionListHead
.Flink
;
257 while (SessionEntry
!= &SessionListHead
)
259 CurrentSession
= CONTAINING_RECORD(SessionEntry
,
263 RtlCopyLuid(&SessionList
[i
],
264 &CurrentSession
->LogonId
);
266 SessionEntry
= SessionEntry
->Flink
;
270 InitializeObjectAttributes(&ObjectAttributes
,
276 Status
= NtOpenProcess(&ProcessHandle
,
277 PROCESS_VM_READ
| PROCESS_VM_WRITE
| PROCESS_VM_OPERATION
,
279 &RequestMsg
->h
.ClientId
);
280 if (!NT_SUCCESS(Status
))
282 TRACE("NtOpenProcess() failed (Status %lx)\n", Status
);
286 TRACE("Length: %lu\n", Length
);
289 Status
= NtAllocateVirtualMemory(ProcessHandle
,
295 if (!NT_SUCCESS(Status
))
297 TRACE("NtAllocateVirtualMemory() failed (Status %lx)\n", Status
);
301 TRACE("MemSize: %lu\n", MemSize
);
302 TRACE("ClientBaseAddress: %p\n", ClientBaseAddress
);
304 Status
= NtWriteVirtualMemory(ProcessHandle
,
309 if (!NT_SUCCESS(Status
))
311 TRACE("NtWriteVirtualMemory() failed (Status %lx)\n", Status
);
315 RequestMsg
->EnumLogonSessions
.Reply
.LogonSessionCount
= SessionCount
;
316 RequestMsg
->EnumLogonSessions
.Reply
.LogonSessionBuffer
= ClientBaseAddress
;
319 if (ProcessHandle
!= NULL
)
320 NtClose(ProcessHandle
);
322 if (SessionList
!= NULL
)
323 RtlFreeHeap(RtlGetProcessHeap(), 0, SessionList
);
330 LsapGetLogonSessionData(IN OUT PLSA_API_MSG RequestMsg
)
332 OBJECT_ATTRIBUTES ObjectAttributes
;
333 HANDLE ProcessHandle
= NULL
;
334 PLSAP_LOGON_SESSION Session
;
335 PSECURITY_LOGON_SESSION_DATA LocalSessionData
;
336 PVOID ClientBaseAddress
= NULL
;
337 ULONG TotalLength
, MemSize
, SidLength
= 0;
341 TRACE("LsapGetLogonSessionData(%p)\n", RequestMsg
);
343 TRACE("LogonId: %lx\n", RequestMsg
->GetLogonSessionData
.Request
.LogonId
.LowPart
);
344 Session
= LsapGetLogonSession(&RequestMsg
->GetLogonSessionData
.Request
.LogonId
);
346 return STATUS_NO_SUCH_LOGON_SESSION
;
348 /* Calculate the required buffer size */
349 TotalLength
= sizeof(SECURITY_LOGON_SESSION_DATA
) +
350 Session
->UserName
.MaximumLength
+
351 Session
->LogonDomain
.MaximumLength
+
352 Session
->AuthenticationPackage
.MaximumLength
+
353 Session
->LogonServer
.MaximumLength
+
354 Session
->DnsDomainName
.MaximumLength
+
355 Session
->Upn
.MaximumLength
;
356 if (Session
->Sid
!= NULL
)
358 SidLength
= RtlLengthSid(Session
->Sid
);
359 TotalLength
+= SidLength
;
361 TRACE("TotalLength: %lu\n", TotalLength
);
363 /* Allocate the buffer */
364 LocalSessionData
= RtlAllocateHeap(RtlGetProcessHeap(),
367 if (LocalSessionData
== NULL
)
368 return STATUS_INSUFFICIENT_RESOURCES
;
370 Ptr
= (PUCHAR
)((ULONG_PTR
)LocalSessionData
+ sizeof(SECURITY_LOGON_SESSION_DATA
));
371 TRACE("LocalSessionData: %p Ptr: %p\n", LocalSessionData
, Ptr
);
373 LocalSessionData
->Size
= sizeof(SECURITY_LOGON_SESSION_DATA
);
375 /* Copy the LogonId */
376 RtlCopyLuid(&LocalSessionData
->LogonId
,
377 &RequestMsg
->GetLogonSessionData
.Request
.LogonId
);
379 /* Copy the UserName string*/
380 LocalSessionData
->UserName
.Length
= Session
->UserName
.Length
;
381 LocalSessionData
->UserName
.MaximumLength
= Session
->UserName
.MaximumLength
;
383 if (Session
->UserName
.MaximumLength
!= 0)
385 RtlCopyMemory(Ptr
, Session
->UserName
.Buffer
, Session
->UserName
.MaximumLength
);
386 LocalSessionData
->UserName
.Buffer
= (PWSTR
)((ULONG_PTR
)Ptr
- (ULONG_PTR
)LocalSessionData
);
388 Ptr
= (PUCHAR
)((ULONG_PTR
)Ptr
+ Session
->UserName
.MaximumLength
);
391 /* Copy the LogonDomain string */
392 LocalSessionData
->LogonDomain
.Length
= Session
->LogonDomain
.Length
;
393 LocalSessionData
->LogonDomain
.MaximumLength
= Session
->LogonDomain
.MaximumLength
;
394 if (Session
->LogonDomain
.MaximumLength
!= 0)
396 RtlCopyMemory(Ptr
, Session
->LogonDomain
.Buffer
, Session
->LogonDomain
.MaximumLength
);
397 LocalSessionData
->LogonDomain
.Buffer
= (PWSTR
)((ULONG_PTR
)Ptr
- (ULONG_PTR
)LocalSessionData
);
399 Ptr
= (PUCHAR
)((ULONG_PTR
)Ptr
+ Session
->LogonDomain
.MaximumLength
);
402 /* Copy the AuthenticationPackage string */
403 LocalSessionData
->AuthenticationPackage
.Length
= Session
->AuthenticationPackage
.Length
;
404 LocalSessionData
->AuthenticationPackage
.MaximumLength
= Session
->AuthenticationPackage
.MaximumLength
;
405 if (Session
->AuthenticationPackage
.MaximumLength
!= 0)
407 RtlCopyMemory(Ptr
, Session
->AuthenticationPackage
.Buffer
, Session
->AuthenticationPackage
.MaximumLength
);
408 LocalSessionData
->AuthenticationPackage
.Buffer
= (PWSTR
)((ULONG_PTR
)Ptr
- (ULONG_PTR
)LocalSessionData
);
410 Ptr
= (PUCHAR
)((ULONG_PTR
)Ptr
+ Session
->AuthenticationPackage
.MaximumLength
);
413 LocalSessionData
->LogonType
= Session
->LogonType
;
414 LocalSessionData
->Session
= 0;
417 if (Session
->Sid
!= NULL
)
419 RtlCopyMemory(Ptr
, Session
->Sid
, SidLength
);
420 LocalSessionData
->Sid
= (PSID
)((ULONG_PTR
)Ptr
- (ULONG_PTR
)LocalSessionData
);
422 Ptr
= (PUCHAR
)((ULONG_PTR
)Ptr
+ SidLength
);
426 LocalSessionData
->LogonTime
.QuadPart
= Session
->LogonTime
.QuadPart
;
428 /* Copy the LogonServer string */
429 LocalSessionData
->LogonServer
.Length
= Session
->LogonServer
.Length
;
430 LocalSessionData
->LogonServer
.MaximumLength
= Session
->LogonServer
.MaximumLength
;
431 if (Session
->LogonServer
.MaximumLength
!= 0)
433 RtlCopyMemory(Ptr
, Session
->LogonServer
.Buffer
, Session
->LogonServer
.MaximumLength
);
434 LocalSessionData
->LogonServer
.Buffer
= (PWSTR
)((ULONG_PTR
)Ptr
- (ULONG_PTR
)LocalSessionData
);
436 Ptr
= (PUCHAR
)((ULONG_PTR
)Ptr
+ Session
->LogonServer
.MaximumLength
);
439 /* Copy the DnsDomainName string */
440 LocalSessionData
->DnsDomainName
.Length
= Session
->DnsDomainName
.Length
;
441 LocalSessionData
->DnsDomainName
.MaximumLength
= Session
->DnsDomainName
.MaximumLength
;
442 if (Session
->DnsDomainName
.MaximumLength
!= 0)
444 RtlCopyMemory(Ptr
, Session
->DnsDomainName
.Buffer
, Session
->DnsDomainName
.MaximumLength
);
445 LocalSessionData
->DnsDomainName
.Buffer
= (PWSTR
)((ULONG_PTR
)Ptr
- (ULONG_PTR
)LocalSessionData
);
447 Ptr
= (PUCHAR
)((ULONG_PTR
)Ptr
+ Session
->DnsDomainName
.MaximumLength
);
450 /* Copy the Upn string */
451 LocalSessionData
->Upn
.Length
= Session
->Upn
.Length
;
452 LocalSessionData
->Upn
.MaximumLength
= Session
->Upn
.MaximumLength
;
453 if (Session
->Upn
.MaximumLength
!= 0)
455 RtlCopyMemory(Ptr
, Session
->Upn
.Buffer
, Session
->Upn
.MaximumLength
);
456 LocalSessionData
->Upn
.Buffer
= (PWSTR
)((ULONG_PTR
)Ptr
- (ULONG_PTR
)LocalSessionData
);
458 Ptr
= (PUCHAR
)((ULONG_PTR
)Ptr
+ Session
->Upn
.MaximumLength
);
462 InitializeObjectAttributes(&ObjectAttributes
,
468 Status
= NtOpenProcess(&ProcessHandle
,
469 PROCESS_VM_READ
| PROCESS_VM_WRITE
| PROCESS_VM_OPERATION
,
471 &RequestMsg
->h
.ClientId
);
472 if (!NT_SUCCESS(Status
))
474 TRACE("NtOpenProcess() failed (Status %lx)\n", Status
);
478 MemSize
= TotalLength
;
479 Status
= NtAllocateVirtualMemory(ProcessHandle
,
485 if (!NT_SUCCESS(Status
))
487 TRACE("NtAllocateVirtualMemory() failed (Status %lx)\n", Status
);
491 TRACE("MemSize: %lu\n", MemSize
);
492 TRACE("ClientBaseAddress: %p\n", ClientBaseAddress
);
494 Status
= NtWriteVirtualMemory(ProcessHandle
,
499 if (!NT_SUCCESS(Status
))
501 TRACE("NtWriteVirtualMemory() failed (Status %lx)\n", Status
);
505 RequestMsg
->GetLogonSessionData
.Reply
.SessionDataBuffer
= ClientBaseAddress
;
508 if (ProcessHandle
!= NULL
)
509 NtClose(ProcessHandle
);
511 if (LocalSessionData
!= NULL
)
512 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalSessionData
);