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 Length
, MemSize
;
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 Length
= sizeof(SECURITY_LOGON_SESSION_DATA
) +
336 Session
->UserName
.MaximumLength
;
338 Session->LogonDomain.MaximumLength +
339 Session->AuthenticationPackage.MaximumLength +
340 Session->LogonServer.MaximumLength +
341 Session->DnsDomainName.MaximumLength +
342 Session->Upn.MaximumLength;
344 if (Session->Sid != NULL)
345 RtlLengthSid(Session->Sid);
348 TRACE("Length: %lu\n", Length
);
350 /* Allocate the buffer */
351 LocalSessionData
= RtlAllocateHeap(RtlGetProcessHeap(),
354 if (LocalSessionData
== NULL
)
355 return STATUS_INSUFFICIENT_RESOURCES
;
357 Ptr
= (LPWSTR
)((ULONG_PTR
)LocalSessionData
+ sizeof(SECURITY_LOGON_SESSION_DATA
));
358 TRACE("LocalSessionData: %p Ptr: %p\n", LocalSessionData
, Ptr
);
360 LocalSessionData
->Size
= sizeof(SECURITY_LOGON_SESSION_DATA
);
362 RtlCopyLuid(&LocalSessionData
->LogonId
,
363 &RequestMsg
->GetLogonSessionData
.Request
.LogonId
);
365 LocalSessionData
->UserName
.Length
= Session
->UserName
.Length
;
366 LocalSessionData
->UserName
.MaximumLength
= Session
->UserName
.MaximumLength
;
367 LocalSessionData
->UserName
.Buffer
= Ptr
;
369 // RtlCopyMemory(Ptr)
372 LocalSessionData
->LogonType
= Session
->LogonType
;
373 LocalSessionData
->Session
= 0;
378 InitializeObjectAttributes(&ObjectAttributes
,
384 Status
= NtOpenProcess(&ProcessHandle
,
385 PROCESS_VM_READ
| PROCESS_VM_WRITE
| PROCESS_VM_OPERATION
,
387 &RequestMsg
->h
.ClientId
);
388 if (!NT_SUCCESS(Status
))
390 TRACE("NtOpenProcess() failed (Status %lx)\n", Status
);
395 Status
= NtAllocateVirtualMemory(ProcessHandle
,
401 if (!NT_SUCCESS(Status
))
403 TRACE("NtAllocateVirtualMemory() failed (Status %lx)\n", Status
);
407 TRACE("MemSize: %lu\n", MemSize
);
408 TRACE("ClientBaseAddress: %p\n", ClientBaseAddress
);
410 Status
= NtWriteVirtualMemory(ProcessHandle
,
415 if (!NT_SUCCESS(Status
))
417 TRACE("NtWriteVirtualMemory() failed (Status %lx)\n", Status
);
421 RequestMsg
->GetLogonSessionData
.Reply
.SessionDataBuffer
= ClientBaseAddress
;
424 if (ProcessHandle
!= NULL
)
425 NtClose(ProcessHandle
);
427 if (LocalSessionData
!= NULL
)
428 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalSessionData
);