* Sync up to trunk head (r64377).
[reactos.git] / 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 } LSAP_LOGON_SESSION, *PLSAP_LOGON_SESSION;
16
17
18 /* GLOBALS *****************************************************************/
19
20 LIST_ENTRY SessionListHead;
21 ULONG SessionCount;
22
23 /* FUNCTIONS ***************************************************************/
24
25 VOID
26 LsapInitLogonSessions(VOID)
27 {
28 InitializeListHead(&SessionListHead);
29 SessionCount = 0;
30 }
31
32
33 static
34 PLSAP_LOGON_SESSION
35 LsapGetLogonSession(IN PLUID LogonId)
36 {
37 PLIST_ENTRY SessionEntry;
38 PLSAP_LOGON_SESSION CurrentSession;
39
40 SessionEntry = SessionListHead.Flink;
41 while (SessionEntry != &SessionListHead)
42 {
43 CurrentSession = CONTAINING_RECORD(SessionEntry,
44 LSAP_LOGON_SESSION,
45 Entry);
46 if (RtlEqualLuid(&CurrentSession->LogonId, LogonId))
47 return CurrentSession;
48
49 SessionEntry = SessionEntry->Flink;
50 }
51
52 return NULL;
53 }
54
55
56 NTSTATUS
57 LsapSetLogonSessionData(IN PLUID LogonId)
58 {
59 PLSAP_LOGON_SESSION Session;
60
61 TRACE("()\n");
62
63 Session = LsapGetLogonSession(LogonId);
64 if (Session == NULL)
65 return STATUS_NO_SUCH_LOGON_SESSION;
66
67
68 return STATUS_SUCCESS;
69 }
70
71
72 NTSTATUS
73 NTAPI
74 LsapCreateLogonSession(IN PLUID LogonId)
75 {
76 PLSAP_LOGON_SESSION Session;
77
78 TRACE("()\n");
79
80 /* Fail, if a session already exists */
81 if (LsapGetLogonSession(LogonId) != NULL)
82 return STATUS_LOGON_SESSION_COLLISION;
83
84 /* Allocate a new session entry */
85 Session = RtlAllocateHeap(RtlGetProcessHeap(),
86 HEAP_ZERO_MEMORY,
87 sizeof(LSAP_LOGON_SESSION));
88 if (Session == NULL)
89 return STATUS_INSUFFICIENT_RESOURCES;
90
91 /* Initialize the session entry */
92 RtlCopyLuid(&Session->LogonId, LogonId);
93
94 /* Insert the new session into the session list */
95 InsertTailList(&SessionListHead, &Session->Entry);
96 SessionCount++;
97
98 return STATUS_SUCCESS;
99 }
100
101
102 NTSTATUS
103 NTAPI
104 LsapDeleteLogonSession(IN PLUID LogonId)
105 {
106 PLSAP_LOGON_SESSION Session;
107
108 TRACE("()\n");
109
110 /* Fail, if the session does not exist */
111 Session = LsapGetLogonSession(LogonId);
112 if (Session == NULL)
113 return STATUS_NO_SUCH_LOGON_SESSION;
114
115 /* Remove the session entry from the list */
116 RemoveEntryList(&Session->Entry);
117 SessionCount--;
118
119 /* Free the session entry */
120 RtlFreeHeap(RtlGetProcessHeap(), 0, Session);
121
122 return STATUS_SUCCESS;
123 }
124
125
126 NTSTATUS
127 LsapEnumLogonSessions(IN OUT PLSA_API_MSG RequestMsg)
128 {
129 OBJECT_ATTRIBUTES ObjectAttributes;
130 HANDLE ProcessHandle = NULL;
131 PLIST_ENTRY SessionEntry;
132 PLSAP_LOGON_SESSION CurrentSession;
133 PLUID SessionList;
134 ULONG i, Length, MemSize;
135 PVOID ClientBaseAddress = NULL;
136 NTSTATUS Status;
137
138 TRACE("LsapEnumLogonSessions()\n");
139
140 Length = SessionCount * sizeof(LUID);
141 SessionList = RtlAllocateHeap(RtlGetProcessHeap(),
142 HEAP_ZERO_MEMORY,
143 Length);
144 if (SessionList == NULL)
145 return STATUS_INSUFFICIENT_RESOURCES;
146
147 i = 0;
148 SessionEntry = SessionListHead.Flink;
149 while (SessionEntry != &SessionListHead)
150 {
151 CurrentSession = CONTAINING_RECORD(SessionEntry,
152 LSAP_LOGON_SESSION,
153 Entry);
154
155 RtlCopyLuid(&SessionList[i],
156 &CurrentSession->LogonId);
157
158 SessionEntry = SessionEntry->Flink;
159 i++;
160 }
161
162 InitializeObjectAttributes(&ObjectAttributes,
163 NULL,
164 0,
165 NULL,
166 NULL);
167
168 Status = NtOpenProcess(&ProcessHandle,
169 PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION | PROCESS_DUP_HANDLE,
170 &ObjectAttributes,
171 &RequestMsg->h.ClientId);
172 if (!NT_SUCCESS(Status))
173 {
174 TRACE("NtOpenProcess() failed (Status %lx)\n", Status);
175 goto done;
176 }
177
178 MemSize = Length;
179 Status = NtAllocateVirtualMemory(ProcessHandle,
180 &ClientBaseAddress,
181 0,
182 &MemSize,
183 MEM_COMMIT,
184 PAGE_READWRITE);
185 if (!NT_SUCCESS(Status))
186 {
187 TRACE("NtAllocateVirtualMemory() failed (Status %lx)\n", Status);
188 goto done;
189 }
190
191 Status = NtWriteVirtualMemory(ProcessHandle,
192 ClientBaseAddress,
193 SessionList,
194 Length,
195 NULL);
196 if (!NT_SUCCESS(Status))
197 {
198 TRACE("NtWriteVirtualMemory() failed (Status %lx)\n", Status);
199 goto done;
200 }
201
202 RequestMsg->EnumLogonSessions.Reply.LogonSessionCount = SessionCount;
203 RequestMsg->EnumLogonSessions.Reply.LogonSessionBuffer = ClientBaseAddress;
204
205 done:
206 if (ProcessHandle != NULL)
207 NtClose(ProcessHandle);
208
209 if (SessionList != NULL)
210 RtlFreeHeap(RtlGetProcessHeap(), 0, SessionList);
211
212 return Status;
213 }
214
215 /* EOF */