55f56d294d69c92a1e9584ecff9114ab78a1ef10
[reactos.git] / reactos / dll / win32 / lsasrv / session.c
1 /*
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
7 */
8
9 #include "lsasrv.h"
10
11 typedef struct _LSAP_LOGON_SESSION
12 {
13 LIST_ENTRY Entry;
14 LUID LogonId;
15 ULONG LogonType;
16 ULONG Session;
17 LARGE_INTEGER LogonTime;
18 PSID Sid;
19 UNICODE_STRING UserName;
20 UNICODE_STRING LogonDomain;
21 UNICODE_STRING AuthenticationPackage;
22 UNICODE_STRING LogonServer;
23 UNICODE_STRING DnsDomainName;
24 UNICODE_STRING Upn;
25 } LSAP_LOGON_SESSION, *PLSAP_LOGON_SESSION;
26
27
28 /* GLOBALS *****************************************************************/
29
30 LIST_ENTRY SessionListHead;
31 ULONG SessionCount;
32
33 /* FUNCTIONS ***************************************************************/
34
35 VOID
36 LsapInitLogonSessions(VOID)
37 {
38 InitializeListHead(&SessionListHead);
39 SessionCount = 0;
40 }
41
42
43 static
44 PLSAP_LOGON_SESSION
45 LsapGetLogonSession(IN PLUID LogonId)
46 {
47 PLIST_ENTRY SessionEntry;
48 PLSAP_LOGON_SESSION CurrentSession;
49
50 SessionEntry = SessionListHead.Flink;
51 while (SessionEntry != &SessionListHead)
52 {
53 CurrentSession = CONTAINING_RECORD(SessionEntry,
54 LSAP_LOGON_SESSION,
55 Entry);
56 if (RtlEqualLuid(&CurrentSession->LogonId, LogonId))
57 return CurrentSession;
58
59 SessionEntry = SessionEntry->Flink;
60 }
61
62 return NULL;
63 }
64
65
66 NTSTATUS
67 LsapSetLogonSessionData(IN PLUID LogonId)
68 {
69 PLSAP_LOGON_SESSION Session;
70
71 TRACE("LsapSetLogonSessionData()\n");
72
73 Session = LsapGetLogonSession(LogonId);
74 if (Session == NULL)
75 return STATUS_NO_SUCH_LOGON_SESSION;
76
77
78 return STATUS_SUCCESS;
79 }
80
81
82 NTSTATUS
83 NTAPI
84 LsapCreateLogonSession(IN PLUID LogonId)
85 {
86 PLSAP_LOGON_SESSION Session;
87
88 TRACE("()\n");
89
90 /* Fail, if a session already exists */
91 if (LsapGetLogonSession(LogonId) != NULL)
92 return STATUS_LOGON_SESSION_COLLISION;
93
94 /* Allocate a new session entry */
95 Session = RtlAllocateHeap(RtlGetProcessHeap(),
96 HEAP_ZERO_MEMORY,
97 sizeof(LSAP_LOGON_SESSION));
98 if (Session == NULL)
99 return STATUS_INSUFFICIENT_RESOURCES;
100
101 /* Initialize the session entry */
102 RtlCopyLuid(&Session->LogonId, LogonId);
103
104 /* Insert the new session into the session list */
105 InsertHeadList(&SessionListHead, &Session->Entry);
106 SessionCount++;
107
108 return STATUS_SUCCESS;
109 }
110
111
112 NTSTATUS
113 NTAPI
114 LsapDeleteLogonSession(IN PLUID LogonId)
115 {
116 PLSAP_LOGON_SESSION Session;
117
118 TRACE("()\n");
119
120 /* Fail, if the session does not exist */
121 Session = LsapGetLogonSession(LogonId);
122 if (Session == NULL)
123 return STATUS_NO_SUCH_LOGON_SESSION;
124
125 /* Remove the session entry from the list */
126 RemoveEntryList(&Session->Entry);
127 SessionCount--;
128
129 /* Free the session data */
130 if (Session->Sid != NULL)
131 RtlFreeHeap(RtlGetProcessHeap(), 0, Session->Sid);
132
133 if (Session->UserName.Buffer != NULL)
134 RtlFreeHeap(RtlGetProcessHeap(), 0, Session->UserName.Buffer);
135
136 if (Session->LogonDomain.Buffer != NULL)
137 RtlFreeHeap(RtlGetProcessHeap(), 0, Session->LogonDomain.Buffer);
138
139 if (Session->AuthenticationPackage.Buffer != NULL)
140 RtlFreeHeap(RtlGetProcessHeap(), 0, Session->AuthenticationPackage.Buffer);
141
142 if (Session->LogonServer.Buffer != NULL)
143 RtlFreeHeap(RtlGetProcessHeap(), 0, Session->LogonServer.Buffer);
144
145 if (Session->DnsDomainName.Buffer != NULL)
146 RtlFreeHeap(RtlGetProcessHeap(), 0, Session->DnsDomainName.Buffer);
147
148 if (Session->Upn.Buffer != NULL)
149 RtlFreeHeap(RtlGetProcessHeap(), 0, Session->Upn.Buffer);
150
151 /* Free the session entry */
152 RtlFreeHeap(RtlGetProcessHeap(), 0, Session);
153
154 return STATUS_SUCCESS;
155 }
156
157
158 NTSTATUS
159 LsapEnumLogonSessions(IN OUT PLSA_API_MSG RequestMsg)
160 {
161 OBJECT_ATTRIBUTES ObjectAttributes;
162 HANDLE ProcessHandle = NULL;
163 PLIST_ENTRY SessionEntry;
164 PLSAP_LOGON_SESSION CurrentSession;
165 PLUID SessionList;
166 ULONG i, Length, MemSize;
167 PVOID ClientBaseAddress = NULL;
168 NTSTATUS Status;
169
170 TRACE("LsapEnumLogonSessions(%p)\n", RequestMsg);
171
172 Length = SessionCount * sizeof(LUID);
173 SessionList = RtlAllocateHeap(RtlGetProcessHeap(),
174 HEAP_ZERO_MEMORY,
175 Length);
176 if (SessionList == NULL)
177 return STATUS_INSUFFICIENT_RESOURCES;
178
179 i = 0;
180 SessionEntry = SessionListHead.Flink;
181 while (SessionEntry != &SessionListHead)
182 {
183 CurrentSession = CONTAINING_RECORD(SessionEntry,
184 LSAP_LOGON_SESSION,
185 Entry);
186
187 RtlCopyLuid(&SessionList[i],
188 &CurrentSession->LogonId);
189
190 SessionEntry = SessionEntry->Flink;
191 i++;
192 }
193
194 InitializeObjectAttributes(&ObjectAttributes,
195 NULL,
196 0,
197 NULL,
198 NULL);
199
200 Status = NtOpenProcess(&ProcessHandle,
201 PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION,
202 &ObjectAttributes,
203 &RequestMsg->h.ClientId);
204 if (!NT_SUCCESS(Status))
205 {
206 TRACE("NtOpenProcess() failed (Status %lx)\n", Status);
207 goto done;
208 }
209
210 TRACE("Length: %lu\n", Length);
211
212 MemSize = Length;
213 Status = NtAllocateVirtualMemory(ProcessHandle,
214 &ClientBaseAddress,
215 0,
216 &MemSize,
217 MEM_COMMIT,
218 PAGE_READWRITE);
219 if (!NT_SUCCESS(Status))
220 {
221 TRACE("NtAllocateVirtualMemory() failed (Status %lx)\n", Status);
222 goto done;
223 }
224
225 TRACE("MemSize: %lu\n", MemSize);
226 TRACE("ClientBaseAddress: %p\n", ClientBaseAddress);
227
228 Status = NtWriteVirtualMemory(ProcessHandle,
229 ClientBaseAddress,
230 SessionList,
231 Length,
232 NULL);
233 if (!NT_SUCCESS(Status))
234 {
235 TRACE("NtWriteVirtualMemory() failed (Status %lx)\n", Status);
236 goto done;
237 }
238
239 RequestMsg->EnumLogonSessions.Reply.LogonSessionCount = SessionCount;
240 RequestMsg->EnumLogonSessions.Reply.LogonSessionBuffer = ClientBaseAddress;
241
242 done:
243 if (ProcessHandle != NULL)
244 NtClose(ProcessHandle);
245
246 if (SessionList != NULL)
247 RtlFreeHeap(RtlGetProcessHeap(), 0, SessionList);
248
249 return Status;
250 }
251
252
253 NTSTATUS
254 LsapGetLogonSessionData(IN OUT PLSA_API_MSG RequestMsg)
255 {
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;
262 LPWSTR Ptr;
263 NTSTATUS Status;
264
265 TRACE("LsapGetLogonSessionData(%p)\n", RequestMsg);
266
267 TRACE("LogonId: %lx\n", RequestMsg->GetLogonSessionData.Request.LogonId.LowPart);
268 Session = LsapGetLogonSession(&RequestMsg->GetLogonSessionData.Request.LogonId);
269 if (Session == NULL)
270 return STATUS_NO_SUCH_LOGON_SESSION;
271
272 Length = sizeof(SECURITY_LOGON_SESSION_DATA);
273 /*
274 Session->UserName.MaximumLength +
275 Session->LogonDomain.MaximumLength +
276 Session->AuthenticationPackage.MaximumLength +
277 Session->LogonServer.MaximumLength +
278 Session->DnsDomainName.MaximumLength +
279 Session->Upn.MaximumLength;
280
281 if (Session->Sid != NULL)
282 RtlLengthSid(Session->Sid);
283 */
284
285 TRACE("Length: %lu\n", Length);
286
287 LocalSessionData = RtlAllocateHeap(RtlGetProcessHeap(),
288 HEAP_ZERO_MEMORY,
289 Length);
290 if (LocalSessionData == NULL)
291 return STATUS_INSUFFICIENT_RESOURCES;
292
293 Ptr = (LPWSTR)((ULONG_PTR)LocalSessionData + sizeof(SECURITY_LOGON_SESSION_DATA));
294 TRACE("LocalSessionData: %p Ptr: %p\n", LocalSessionData, Ptr);
295
296 LocalSessionData->Size = sizeof(SECURITY_LOGON_SESSION_DATA);
297
298 RtlCopyLuid(&LocalSessionData->LogonId,
299 &RequestMsg->GetLogonSessionData.Request.LogonId);
300
301 InitializeObjectAttributes(&ObjectAttributes,
302 NULL,
303 0,
304 NULL,
305 NULL);
306
307 Status = NtOpenProcess(&ProcessHandle,
308 PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION,
309 &ObjectAttributes,
310 &RequestMsg->h.ClientId);
311 if (!NT_SUCCESS(Status))
312 {
313 TRACE("NtOpenProcess() failed (Status %lx)\n", Status);
314 goto done;
315 }
316
317 TRACE("MemSize: %lu\n", MemSize);
318
319 MemSize = Length;
320 Status = NtAllocateVirtualMemory(ProcessHandle,
321 &ClientBaseAddress,
322 0,
323 &MemSize,
324 MEM_COMMIT,
325 PAGE_READWRITE);
326 if (!NT_SUCCESS(Status))
327 {
328 TRACE("NtAllocateVirtualMemory() failed (Status %lx)\n", Status);
329 goto done;
330 }
331
332 TRACE("MemSize: %lu\n", MemSize);
333 TRACE("ClientBaseAddress: %p\n", ClientBaseAddress);
334
335 Status = NtWriteVirtualMemory(ProcessHandle,
336 ClientBaseAddress,
337 LocalSessionData,
338 Length,
339 NULL);
340 if (!NT_SUCCESS(Status))
341 {
342 TRACE("NtWriteVirtualMemory() failed (Status %lx)\n", Status);
343 goto done;
344 }
345
346 RequestMsg->GetLogonSessionData.Reply.SessionDataBuffer = ClientBaseAddress;
347
348 done:
349 if (ProcessHandle != NULL)
350 NtClose(ProcessHandle);
351
352 if (LocalSessionData != NULL)
353 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalSessionData);
354
355 return Status;
356 }
357
358 /* EOF */