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
;
180 LsapEnumLogonSessions(IN OUT PLSA_API_MSG RequestMsg
)
182 OBJECT_ATTRIBUTES ObjectAttributes
;
183 HANDLE ProcessHandle
= NULL
;
184 PLIST_ENTRY SessionEntry
;
185 PLSAP_LOGON_SESSION CurrentSession
;
187 ULONG i
, Length
, MemSize
;
188 PVOID ClientBaseAddress
= NULL
;
191 TRACE("LsapEnumLogonSessions(%p)\n", RequestMsg
);
193 Length
= SessionCount
* sizeof(LUID
);
194 SessionList
= RtlAllocateHeap(RtlGetProcessHeap(),
197 if (SessionList
== NULL
)
198 return STATUS_INSUFFICIENT_RESOURCES
;
201 SessionEntry
= SessionListHead
.Flink
;
202 while (SessionEntry
!= &SessionListHead
)
204 CurrentSession
= CONTAINING_RECORD(SessionEntry
,
208 RtlCopyLuid(&SessionList
[i
],
209 &CurrentSession
->LogonId
);
211 SessionEntry
= SessionEntry
->Flink
;
215 InitializeObjectAttributes(&ObjectAttributes
,
221 Status
= NtOpenProcess(&ProcessHandle
,
222 PROCESS_VM_READ
| PROCESS_VM_WRITE
| PROCESS_VM_OPERATION
,
224 &RequestMsg
->h
.ClientId
);
225 if (!NT_SUCCESS(Status
))
227 TRACE("NtOpenProcess() failed (Status %lx)\n", Status
);
231 TRACE("Length: %lu\n", Length
);
234 Status
= NtAllocateVirtualMemory(ProcessHandle
,
240 if (!NT_SUCCESS(Status
))
242 TRACE("NtAllocateVirtualMemory() failed (Status %lx)\n", Status
);
246 TRACE("MemSize: %lu\n", MemSize
);
247 TRACE("ClientBaseAddress: %p\n", ClientBaseAddress
);
249 Status
= NtWriteVirtualMemory(ProcessHandle
,
254 if (!NT_SUCCESS(Status
))
256 TRACE("NtWriteVirtualMemory() failed (Status %lx)\n", Status
);
260 RequestMsg
->EnumLogonSessions
.Reply
.LogonSessionCount
= SessionCount
;
261 RequestMsg
->EnumLogonSessions
.Reply
.LogonSessionBuffer
= ClientBaseAddress
;
264 if (ProcessHandle
!= NULL
)
265 NtClose(ProcessHandle
);
267 if (SessionList
!= NULL
)
268 RtlFreeHeap(RtlGetProcessHeap(), 0, SessionList
);
275 LsapGetLogonSessionData(IN OUT PLSA_API_MSG RequestMsg
)
277 OBJECT_ATTRIBUTES ObjectAttributes
;
278 HANDLE ProcessHandle
= NULL
;
279 PLSAP_LOGON_SESSION Session
;
280 PSECURITY_LOGON_SESSION_DATA LocalSessionData
;
281 PVOID ClientBaseAddress
= NULL
;
282 ULONG Length
, MemSize
;
286 TRACE("LsapGetLogonSessionData(%p)\n", RequestMsg
);
288 TRACE("LogonId: %lx\n", RequestMsg
->GetLogonSessionData
.Request
.LogonId
.LowPart
);
289 Session
= LsapGetLogonSession(&RequestMsg
->GetLogonSessionData
.Request
.LogonId
);
291 return STATUS_NO_SUCH_LOGON_SESSION
;
293 Length
= sizeof(SECURITY_LOGON_SESSION_DATA
);
295 Session->UserName.MaximumLength +
296 Session->LogonDomain.MaximumLength +
297 Session->AuthenticationPackage.MaximumLength +
298 Session->LogonServer.MaximumLength +
299 Session->DnsDomainName.MaximumLength +
300 Session->Upn.MaximumLength;
302 if (Session->Sid != NULL)
303 RtlLengthSid(Session->Sid);
306 TRACE("Length: %lu\n", Length
);
308 LocalSessionData
= RtlAllocateHeap(RtlGetProcessHeap(),
311 if (LocalSessionData
== NULL
)
312 return STATUS_INSUFFICIENT_RESOURCES
;
314 Ptr
= (LPWSTR
)((ULONG_PTR
)LocalSessionData
+ sizeof(SECURITY_LOGON_SESSION_DATA
));
315 TRACE("LocalSessionData: %p Ptr: %p\n", LocalSessionData
, Ptr
);
317 LocalSessionData
->Size
= sizeof(SECURITY_LOGON_SESSION_DATA
);
319 RtlCopyLuid(&LocalSessionData
->LogonId
,
320 &RequestMsg
->GetLogonSessionData
.Request
.LogonId
);
322 InitializeObjectAttributes(&ObjectAttributes
,
328 Status
= NtOpenProcess(&ProcessHandle
,
329 PROCESS_VM_READ
| PROCESS_VM_WRITE
| PROCESS_VM_OPERATION
,
331 &RequestMsg
->h
.ClientId
);
332 if (!NT_SUCCESS(Status
))
334 TRACE("NtOpenProcess() failed (Status %lx)\n", Status
);
339 Status
= NtAllocateVirtualMemory(ProcessHandle
,
345 if (!NT_SUCCESS(Status
))
347 TRACE("NtAllocateVirtualMemory() failed (Status %lx)\n", Status
);
351 TRACE("MemSize: %lu\n", MemSize
);
352 TRACE("ClientBaseAddress: %p\n", ClientBaseAddress
);
354 Status
= NtWriteVirtualMemory(ProcessHandle
,
359 if (!NT_SUCCESS(Status
))
361 TRACE("NtWriteVirtualMemory() failed (Status %lx)\n", Status
);
365 RequestMsg
->GetLogonSessionData
.Reply
.SessionDataBuffer
= ClientBaseAddress
;
368 if (ProcessHandle
!= NULL
)
369 NtClose(ProcessHandle
);
371 if (LocalSessionData
!= NULL
)
372 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalSessionData
);