[SECUR32][LSASRV][LSALIB]
[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 } 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;
135 PVOID ClientBaseAddress;
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 Status = NtAllocateVirtualMemory(ProcessHandle,
179 &ClientBaseAddress,
180 0,
181 &Length,
182 MEM_COMMIT,
183 PAGE_READWRITE);
184 if (!NT_SUCCESS(Status))
185 {
186 TRACE("NtAllocateVirtualMemory() failed (Status %lx)\n", Status);
187 goto done;
188 }
189
190 Status = NtWriteVirtualMemory(ProcessHandle,
191 ClientBaseAddress,
192 SessionList,
193 Length,
194 NULL);
195 if (!NT_SUCCESS(Status))
196 {
197 TRACE("NtWriteVirtualMemory() failed (Status %lx)\n", Status);
198 goto done;
199 }
200
201 RequestMsg->EnumLogonSessions.Reply.LogonSessionCount = SessionCount;
202 RequestMsg->EnumLogonSessions.Reply.LogonSessionBuffer = ClientBaseAddress;
203
204 done:
205 if (ProcessHandle != NULL)
206 NtClose(ProcessHandle);
207
208 if (SessionList != NULL)
209 RtlFreeHeap(RtlGetProcessHeap(), 0, SessionList);
210
211 return Status;
212 }
213
214 /* EOF */