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()\n");
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
;
90 /* Fail, if a session already exists */
91 if (LsapGetLogonSession(LogonId
) != NULL
)
92 return STATUS_LOGON_SESSION_COLLISION
;
94 /* Allocate a new session entry */
95 Session
= RtlAllocateHeap(RtlGetProcessHeap(),
97 sizeof(LSAP_LOGON_SESSION
));
99 return STATUS_INSUFFICIENT_RESOURCES
;
101 /* Initialize the session entry */
102 RtlCopyLuid(&Session
->LogonId
, LogonId
);
104 /* Insert the new session into the session list */
105 InsertHeadList(&SessionListHead
, &Session
->Entry
);
108 return STATUS_SUCCESS
;
114 LsapDeleteLogonSession(IN PLUID LogonId
)
116 PLSAP_LOGON_SESSION Session
;
120 /* Fail, if the session does not exist */
121 Session
= LsapGetLogonSession(LogonId
);
123 return STATUS_NO_SUCH_LOGON_SESSION
;
125 /* Remove the session entry from the list */
126 RemoveEntryList(&Session
->Entry
);
129 /* Free the session data */
130 if (Session
->Sid
!= NULL
)
131 RtlFreeHeap(RtlGetProcessHeap(), 0, Session
->Sid
);
133 if (Session
->UserName
.Buffer
!= NULL
)
134 RtlFreeHeap(RtlGetProcessHeap(), 0, Session
->UserName
.Buffer
);
136 if (Session
->LogonDomain
.Buffer
!= NULL
)
137 RtlFreeHeap(RtlGetProcessHeap(), 0, Session
->LogonDomain
.Buffer
);
139 if (Session
->AuthenticationPackage
.Buffer
!= NULL
)
140 RtlFreeHeap(RtlGetProcessHeap(), 0, Session
->AuthenticationPackage
.Buffer
);
142 if (Session
->LogonServer
.Buffer
!= NULL
)
143 RtlFreeHeap(RtlGetProcessHeap(), 0, Session
->LogonServer
.Buffer
);
145 if (Session
->DnsDomainName
.Buffer
!= NULL
)
146 RtlFreeHeap(RtlGetProcessHeap(), 0, Session
->DnsDomainName
.Buffer
);
148 if (Session
->Upn
.Buffer
!= NULL
)
149 RtlFreeHeap(RtlGetProcessHeap(), 0, Session
->Upn
.Buffer
);
151 /* Free the session entry */
152 RtlFreeHeap(RtlGetProcessHeap(), 0, Session
);
154 return STATUS_SUCCESS
;
159 LsapEnumLogonSessions(IN OUT PLSA_API_MSG RequestMsg
)
161 OBJECT_ATTRIBUTES ObjectAttributes
;
162 HANDLE ProcessHandle
= NULL
;
163 PLIST_ENTRY SessionEntry
;
164 PLSAP_LOGON_SESSION CurrentSession
;
166 ULONG i
, Length
, MemSize
;
167 PVOID ClientBaseAddress
= NULL
;
170 TRACE("LsapEnumLogonSessions(%p)\n", RequestMsg
);
172 Length
= SessionCount
* sizeof(LUID
);
173 SessionList
= RtlAllocateHeap(RtlGetProcessHeap(),
176 if (SessionList
== NULL
)
177 return STATUS_INSUFFICIENT_RESOURCES
;
180 SessionEntry
= SessionListHead
.Flink
;
181 while (SessionEntry
!= &SessionListHead
)
183 CurrentSession
= CONTAINING_RECORD(SessionEntry
,
187 RtlCopyLuid(&SessionList
[i
],
188 &CurrentSession
->LogonId
);
190 SessionEntry
= SessionEntry
->Flink
;
194 InitializeObjectAttributes(&ObjectAttributes
,
200 Status
= NtOpenProcess(&ProcessHandle
,
201 PROCESS_VM_READ
| PROCESS_VM_WRITE
| PROCESS_VM_OPERATION
,
203 &RequestMsg
->h
.ClientId
);
204 if (!NT_SUCCESS(Status
))
206 TRACE("NtOpenProcess() failed (Status %lx)\n", Status
);
210 TRACE("Length: %lu\n", Length
);
213 Status
= NtAllocateVirtualMemory(ProcessHandle
,
219 if (!NT_SUCCESS(Status
))
221 TRACE("NtAllocateVirtualMemory() failed (Status %lx)\n", Status
);
225 TRACE("MemSize: %lu\n", MemSize
);
226 TRACE("ClientBaseAddress: %p\n", ClientBaseAddress
);
228 Status
= NtWriteVirtualMemory(ProcessHandle
,
233 if (!NT_SUCCESS(Status
))
235 TRACE("NtWriteVirtualMemory() failed (Status %lx)\n", Status
);
239 RequestMsg
->EnumLogonSessions
.Reply
.LogonSessionCount
= SessionCount
;
240 RequestMsg
->EnumLogonSessions
.Reply
.LogonSessionBuffer
= ClientBaseAddress
;
243 if (ProcessHandle
!= NULL
)
244 NtClose(ProcessHandle
);
246 if (SessionList
!= NULL
)
247 RtlFreeHeap(RtlGetProcessHeap(), 0, SessionList
);
254 LsapGetLogonSessionData(IN OUT PLSA_API_MSG RequestMsg
)
256 OBJECT_ATTRIBUTES ObjectAttributes
;
257 HANDLE ProcessHandle
= NULL
;
258 PLSAP_LOGON_SESSION Session
;
259 PSECURITY_LOGON_SESSION_DATA LocalSessionData
;
260 PVOID ClientBaseAddress
= NULL
;
261 ULONG Length
, MemSize
;
265 TRACE("LsapGetLogonSessionData(%p)\n", RequestMsg
);
267 TRACE("LogonId: %lx\n", RequestMsg
->GetLogonSessionData
.Request
.LogonId
.LowPart
);
268 Session
= LsapGetLogonSession(&RequestMsg
->GetLogonSessionData
.Request
.LogonId
);
270 return STATUS_NO_SUCH_LOGON_SESSION
;
272 Length
= sizeof(SECURITY_LOGON_SESSION_DATA
);
274 Session->UserName.MaximumLength +
275 Session->LogonDomain.MaximumLength +
276 Session->AuthenticationPackage.MaximumLength +
277 Session->LogonServer.MaximumLength +
278 Session->DnsDomainName.MaximumLength +
279 Session->Upn.MaximumLength;
281 if (Session->Sid != NULL)
282 RtlLengthSid(Session->Sid);
285 TRACE("Length: %lu\n", Length
);
287 LocalSessionData
= RtlAllocateHeap(RtlGetProcessHeap(),
290 if (LocalSessionData
== NULL
)
291 return STATUS_INSUFFICIENT_RESOURCES
;
293 Ptr
= (LPWSTR
)((ULONG_PTR
)LocalSessionData
+ sizeof(SECURITY_LOGON_SESSION_DATA
));
294 TRACE("LocalSessionData: %p Ptr: %p\n", LocalSessionData
, Ptr
);
296 LocalSessionData
->Size
= sizeof(SECURITY_LOGON_SESSION_DATA
);
298 RtlCopyLuid(&LocalSessionData
->LogonId
,
299 &RequestMsg
->GetLogonSessionData
.Request
.LogonId
);
301 InitializeObjectAttributes(&ObjectAttributes
,
307 Status
= NtOpenProcess(&ProcessHandle
,
308 PROCESS_VM_READ
| PROCESS_VM_WRITE
| PROCESS_VM_OPERATION
,
310 &RequestMsg
->h
.ClientId
);
311 if (!NT_SUCCESS(Status
))
313 TRACE("NtOpenProcess() failed (Status %lx)\n", Status
);
317 TRACE("MemSize: %lu\n", MemSize
);
320 Status
= NtAllocateVirtualMemory(ProcessHandle
,
326 if (!NT_SUCCESS(Status
))
328 TRACE("NtAllocateVirtualMemory() failed (Status %lx)\n", Status
);
332 TRACE("MemSize: %lu\n", MemSize
);
333 TRACE("ClientBaseAddress: %p\n", ClientBaseAddress
);
335 Status
= NtWriteVirtualMemory(ProcessHandle
,
340 if (!NT_SUCCESS(Status
))
342 TRACE("NtWriteVirtualMemory() failed (Status %lx)\n", Status
);
346 RequestMsg
->GetLogonSessionData
.Reply
.SessionDataBuffer
= ClientBaseAddress
;
349 if (ProcessHandle
!= NULL
)
350 NtClose(ProcessHandle
);
352 if (LocalSessionData
!= NULL
)
353 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalSessionData
);