1 /*
2 * PROJECT: Local Security Authority Server DLL
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: dll/win32/samsrv/alias.c
5 * PURPOSE: Alias specific helper functions
6 * COPYRIGHT: Copyright 2013 Eric Kohl
7 */
8
9 #include "samsrv.h"
10
11 /* FUNCTIONS ***************************************************************/
12
13 NTSTATUS
SampOpenAliasObject(IN PSAM_DB_OBJECT DomainObject,IN ULONG AliasId,IN ACCESS_MASK DesiredAccess,OUT PSAM_DB_OBJECT * AliasObject)14 SampOpenAliasObject(IN PSAM_DB_OBJECT DomainObject,
15 IN ULONG AliasId,
16 IN ACCESS_MASK DesiredAccess,
17 OUT PSAM_DB_OBJECT *AliasObject)
18 {
19 WCHAR szRid[9];
20
21 TRACE("(%p %lu %lx %p)\n",
22 DomainObject, AliasId, DesiredAccess, AliasObject);
23
24 /* Convert the RID into a string (hex) */
25 swprintf(szRid, L"%08lX", AliasId);
26
27 /* Create the user object */
28 return SampOpenDbObject(DomainObject,
29 L"Aliases",
30 szRid,
31 AliasId,
32 SamDbAliasObject,
33 DesiredAccess,
34 AliasObject);
35 }
36
37
38 NTSTATUS
SampAddMemberToAlias(IN PSAM_DB_OBJECT AliasObject,IN PRPC_SID MemberId)39 SampAddMemberToAlias(IN PSAM_DB_OBJECT AliasObject,
40 IN PRPC_SID MemberId)
41 {
42 LPWSTR MemberIdString = NULL;
43 HANDLE MembersKeyHandle = NULL;
44 HANDLE MemberKeyHandle = NULL;
45 ULONG MemberIdLength;
46 NTSTATUS Status;
47
48 TRACE("(%p %p)\n",
49 AliasObject, MemberId);
50
51 ConvertSidToStringSidW(MemberId, &MemberIdString);
52 TRACE("Member SID: %S\n", MemberIdString);
53
54 MemberIdLength = RtlLengthSid(MemberId);
55
56 Status = SampRegCreateKey(AliasObject->KeyHandle,
57 L"Members",
58 KEY_WRITE,
59 &MembersKeyHandle);
60 if (!NT_SUCCESS(Status))
61 {
62 TRACE("SampRegCreateKey failed with status 0x%08lx\n", Status);
63 goto done;
64 }
65
66 Status = SampRegSetValue(MembersKeyHandle,
67 MemberIdString,
68 REG_BINARY,
69 MemberId,
70 MemberIdLength);
71 if (!NT_SUCCESS(Status))
72 {
73 TRACE("SampRegSetValue failed with status 0x%08lx\n", Status);
74 goto done;
75 }
76
77 Status = SampRegCreateKey(AliasObject->MembersKeyHandle,
78 MemberIdString,
79 KEY_WRITE,
80 &MemberKeyHandle);
81 if (!NT_SUCCESS(Status))
82 {
83 TRACE("SampRegCreateKey failed with status 0x%08lx\n", Status);
84 goto done;
85 }
86
87 Status = SampRegSetValue(MemberKeyHandle,
88 AliasObject->Name,
89 REG_BINARY,
90 MemberId,
91 MemberIdLength);
92 if (!NT_SUCCESS(Status))
93 {
94 TRACE("SampRegSetValue failed with status 0x%08lx\n", Status);
95 goto done;
96 }
97
98 done:
99 SampRegCloseKey(&MemberKeyHandle);
100 SampRegCloseKey(&MembersKeyHandle);
101
102 if (MemberIdString != NULL)
103 LocalFree(MemberIdString);
104
105 return Status;
106 }
107
108
109 NTSTATUS
110 NTAPI
SampRemoveMemberFromAlias(IN PSAM_DB_OBJECT AliasObject,IN PRPC_SID MemberId)111 SampRemoveMemberFromAlias(IN PSAM_DB_OBJECT AliasObject,
112 IN PRPC_SID MemberId)
113 {
114 LPWSTR MemberIdString = NULL;
115 HANDLE MembersKeyHandle = NULL;
116 HANDLE MemberKeyHandle = NULL;
117 ULONG ulValueCount;
118 NTSTATUS Status;
119
120 TRACE("(%p %p)\n",
121 AliasObject, MemberId);
122
123 ConvertSidToStringSidW(MemberId, &MemberIdString);
124 TRACE("Member SID: %S\n", MemberIdString);
125
126 Status = SampRegOpenKey(AliasObject->MembersKeyHandle,
127 MemberIdString,
128 KEY_WRITE | KEY_QUERY_VALUE,
129 &MemberKeyHandle);
130 if (!NT_SUCCESS(Status))
131 {
132 TRACE("SampRegOpenKey failed with status 0x%08lx\n", Status);
133 goto done;
134 }
135
136 Status = SampRegDeleteValue(MemberKeyHandle,
137 AliasObject->Name);
138 if (!NT_SUCCESS(Status))
139 {
140 TRACE("SampRegDeleteValue failed with status 0x%08lx\n", Status);
141 goto done;
142 }
143
144 Status = SampRegQueryKeyInfo(MemberKeyHandle,
145 NULL,
146 &ulValueCount);
147 if (!NT_SUCCESS(Status))
148 {
149 TRACE("SampRegQueryKeyInfo failed with status 0x%08lx\n", Status);
150 goto done;
151 }
152
153 if (ulValueCount == 0)
154 {
155 SampRegCloseKey(&MemberKeyHandle);
156
157 Status = SampRegDeleteKey(AliasObject->MembersKeyHandle,
158 MemberIdString);
159 if (!NT_SUCCESS(Status))
160 {
161 TRACE("SampRegDeleteKey failed with status 0x%08lx\n", Status);
162 goto done;
163 }
164 }
165
166 Status = SampRegOpenKey(AliasObject->KeyHandle,
167 L"Members",
168 KEY_WRITE | KEY_QUERY_VALUE,
169 &MembersKeyHandle);
170 if (!NT_SUCCESS(Status))
171 {
172 TRACE("SampRegOpenKey failed with status 0x%08lx\n", Status);
173 goto done;
174 }
175
176 Status = SampRegDeleteValue(MembersKeyHandle,
177 MemberIdString);
178 if (!NT_SUCCESS(Status))
179 {
180 TRACE("SampRegDeleteValue failed with status 0x%08lx\n", Status);
181 goto done;
182 }
183
184 Status = SampRegQueryKeyInfo(MembersKeyHandle,
185 NULL,
186 &ulValueCount);
187 if (!NT_SUCCESS(Status))
188 {
189 TRACE("SampRegQueryKeyInfo failed with status 0x%08lx\n", Status);
190 goto done;
191 }
192
193 if (ulValueCount == 0)
194 {
195 SampRegCloseKey(&MembersKeyHandle);
196
197 Status = SampRegDeleteKey(AliasObject->KeyHandle,
198 L"Members");
199 if (!NT_SUCCESS(Status))
200 {
201 TRACE("SampRegDeleteKey failed with status 0x%08lx\n", Status);
202 goto done;
203 }
204 }
205
206 done:
207 SampRegCloseKey(&MemberKeyHandle);
208 SampRegCloseKey(&MembersKeyHandle);
209
210 if (MemberIdString != NULL)
211 LocalFree(MemberIdString);
212
213 return Status;
214 }
215
216
217 NTSTATUS
SampGetMembersInAlias(IN PSAM_DB_OBJECT AliasObject,OUT PULONG MemberCount,OUT PSAMPR_SID_INFORMATION * MemberArray)218 SampGetMembersInAlias(IN PSAM_DB_OBJECT AliasObject,
219 OUT PULONG MemberCount,
220 OUT PSAMPR_SID_INFORMATION *MemberArray)
221 {
222 HANDLE MembersKeyHandle = NULL;
223 PSAMPR_SID_INFORMATION Members = NULL;
224 ULONG Count = 0;
225 ULONG DataLength;
226 ULONG Index;
227 NTSTATUS Status;
228
229 /* Open the members key of the alias object */
230 Status = SampRegOpenKey(AliasObject->KeyHandle,
231 L"Members",
232 KEY_READ,
233 &MembersKeyHandle);
234 if (!NT_SUCCESS(Status))
235 {
236 ERR("SampRegOpenKey failed with status 0x%08lx\n", Status);
237 goto done;
238 }
239
240 /* Get the number of members */
241 Status = SampRegQueryKeyInfo(MembersKeyHandle,
242 NULL,
243 &Count);
244 if (!NT_SUCCESS(Status))
245 {
246 ERR("SampRegQueryKeyInfo failed with status 0x%08lx\n", Status);
247 goto done;
248 }
249
250 /* Allocate the member array */
251 Members = midl_user_allocate(Count * sizeof(SAMPR_SID_INFORMATION));
252 if (Members == NULL)
253 {
254 Status = STATUS_INSUFFICIENT_RESOURCES;
255 goto done;
256 }
257
258 /* Enumerate the members */
259 Index = 0;
260 while (TRUE)
261 {
262 /* Get the size of the next SID */
263 DataLength = 0;
264 Status = SampRegEnumerateValue(MembersKeyHandle,
265 Index,
266 NULL,
267 NULL,
268 NULL,
269 NULL,
270 &DataLength);
271 if (!NT_SUCCESS(Status))
272 {
273 if (Status == STATUS_NO_MORE_ENTRIES)
274 Status = STATUS_SUCCESS;
275 break;
276 }
277
278 /* Allocate a buffer for the SID */
279 Members[Index].SidPointer = midl_user_allocate(DataLength);
280 if (Members[Index].SidPointer == NULL)
281 {
282 Status = STATUS_INSUFFICIENT_RESOURCES;
283 goto done;
284 }
285
286 /* Read the SID into the buffer */
287 Status = SampRegEnumerateValue(MembersKeyHandle,
288 Index,
289 NULL,
290 NULL,
291 NULL,
292 (PVOID)Members[Index].SidPointer,
293 &DataLength);
294 if (!NT_SUCCESS(Status))
295 {
296 goto done;
297 }
298
299 Index++;
300 }
301
302 if (NT_SUCCESS(Status))
303 {
304 *MemberCount = Count;
305 *MemberArray = Members;
306 }
307
308 done:
309 return Status;
310 }
311
312
313 NTSTATUS
SampRemoveAllMembersFromAlias(IN PSAM_DB_OBJECT AliasObject)314 SampRemoveAllMembersFromAlias(IN PSAM_DB_OBJECT AliasObject)
315 {
316 HANDLE MembersKeyHandle = NULL;
317 PSAMPR_SID_INFORMATION MemberArray = NULL;
318 ULONG MemberCount = 0;
319 ULONG Index;
320 NTSTATUS Status;
321
322 TRACE("(%p)\n", AliasObject);
323
324 /* Open the members key of the alias object */
325 Status = SampRegOpenKey(AliasObject->KeyHandle,
326 L"Members",
327 KEY_READ,
328 &MembersKeyHandle);
329 if (!NT_SUCCESS(Status))
330 {
331 ERR("SampRegOpenKey failed (Status 0x%08lx)\n", Status);
332 goto done;
333 }
334
335 /* Get a list of all members of the alias */
336 Status = SampGetMembersInAlias(AliasObject,
337 &MemberCount,
338 &MemberArray);
339 if (!NT_SUCCESS(Status))
340 {
341 ERR("SampGetMembersInAlias failed (Status 0x%08lx)\n", Status);
342 goto done;
343 }
344
345 /* Remove all members from the alias */
346 for (Index = 0; Index < MemberCount; Index++)
347 {
348 Status = SampRemoveMemberFromAlias(AliasObject,
349 MemberArray[Index].SidPointer);
350 if (!NT_SUCCESS(Status))
351 goto done;
352 }
353
354 done:
355 if (MemberArray != NULL)
356 {
357 for (Index = 0; Index < MemberCount; Index++)
358 {
359 if (MemberArray[Index].SidPointer != NULL)
360 midl_user_free(MemberArray[Index].SidPointer);
361 }
362
363 midl_user_free(MemberArray);
364 }
365
366 SampRegCloseKey(&MembersKeyHandle);
367
368 return Status;
369 }
370
371 /* EOF */
372