95080af777e4f2de70cca18a410607ef380d4c8b
[reactos.git] / dll / win32 / samsrv / domain.c
1 /*
2 * PROJECT: Local Security Authority Server DLL
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: dll/win32/samsrv/domain.c
5 * PURPOSE: Domain specific helper functions
6 * COPYRIGHT: Copyright 2013 Eric Kohl
7 */
8
9 #include "samsrv.h"
10
11 /* FUNCTIONS ***************************************************************/
12
13 NTSTATUS
14 SampSetAccountNameInDomain(IN PSAM_DB_OBJECT DomainObject,
15 IN LPCWSTR lpContainerName,
16 IN LPCWSTR lpAccountName,
17 IN ULONG ulRelativeId)
18 {
19 HANDLE ContainerKeyHandle = NULL;
20 HANDLE NamesKeyHandle = NULL;
21 NTSTATUS Status;
22
23 TRACE("SampSetAccountNameInDomain()\n");
24
25 /* Open the container key */
26 Status = SampRegOpenKey(DomainObject->KeyHandle,
27 lpContainerName,
28 KEY_ALL_ACCESS,
29 &ContainerKeyHandle);
30 if (!NT_SUCCESS(Status))
31 return Status;
32
33 /* Open the 'Names' key */
34 Status = SampRegOpenKey(ContainerKeyHandle,
35 L"Names",
36 KEY_ALL_ACCESS,
37 &NamesKeyHandle);
38 if (!NT_SUCCESS(Status))
39 goto done;
40
41 /* Set the alias value */
42 Status = SampRegSetValue(NamesKeyHandle,
43 lpAccountName,
44 REG_DWORD,
45 (LPVOID)&ulRelativeId,
46 sizeof(ULONG));
47
48 done:
49 SampRegCloseKey(&NamesKeyHandle);
50 SampRegCloseKey(&ContainerKeyHandle);
51
52 return Status;
53 }
54
55
56 NTSTATUS
57 SampRemoveAccountNameFromDomain(IN PSAM_DB_OBJECT DomainObject,
58 IN LPCWSTR lpContainerName,
59 IN LPCWSTR lpAccountName)
60 {
61 HANDLE ContainerKeyHandle = NULL;
62 HANDLE NamesKeyHandle = NULL;
63 NTSTATUS Status;
64
65 TRACE("(%S %S)\n", lpContainerName, lpAccountName);
66
67 /* Open the container key */
68 Status = SampRegOpenKey(DomainObject->KeyHandle,
69 lpContainerName,
70 KEY_ALL_ACCESS,
71 &ContainerKeyHandle);
72 if (!NT_SUCCESS(Status))
73 return Status;
74
75 /* Open the 'Names' key */
76 Status = SampRegOpenKey(ContainerKeyHandle,
77 L"Names",
78 KEY_SET_VALUE,
79 &NamesKeyHandle);
80 if (!NT_SUCCESS(Status))
81 goto done;
82
83 /* Delete the account name value */
84 Status = SampRegDeleteValue(NamesKeyHandle,
85 lpAccountName);
86
87 done:
88 SampRegCloseKey(&NamesKeyHandle);
89 SampRegCloseKey(&ContainerKeyHandle);
90
91 return Status;
92 }
93
94
95 NTSTATUS
96 SampCheckAccountNameInDomain(IN PSAM_DB_OBJECT DomainObject,
97 IN LPCWSTR lpAccountName)
98 {
99 HANDLE AccountKey = NULL;
100 HANDLE NamesKey = NULL;
101 NTSTATUS Status;
102
103 TRACE("SampCheckAccountNameInDomain()\n");
104
105 Status = SampRegOpenKey(DomainObject->KeyHandle,
106 L"Aliases",
107 KEY_READ,
108 &AccountKey);
109 if (NT_SUCCESS(Status))
110 {
111 Status = SampRegOpenKey(AccountKey,
112 L"Names",
113 KEY_READ,
114 &NamesKey);
115 if (NT_SUCCESS(Status))
116 {
117 Status = SampRegQueryValue(NamesKey,
118 lpAccountName,
119 NULL,
120 NULL,
121 NULL);
122 if (Status == STATUS_SUCCESS)
123 {
124 SampRegCloseKey(&NamesKey);
125 Status = STATUS_ALIAS_EXISTS;
126 }
127 else if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
128 Status = STATUS_SUCCESS;
129 }
130
131 SampRegCloseKey(&AccountKey);
132 }
133
134 if (!NT_SUCCESS(Status))
135 {
136 TRACE("Checking for alias account failed (Status 0x%08lx)\n", Status);
137 return Status;
138 }
139
140 Status = SampRegOpenKey(DomainObject->KeyHandle,
141 L"Groups",
142 KEY_READ,
143 &AccountKey);
144 if (NT_SUCCESS(Status))
145 {
146 Status = SampRegOpenKey(AccountKey,
147 L"Names",
148 KEY_READ,
149 &NamesKey);
150 if (NT_SUCCESS(Status))
151 {
152 Status = SampRegQueryValue(NamesKey,
153 lpAccountName,
154 NULL,
155 NULL,
156 NULL);
157 if (Status == STATUS_SUCCESS)
158 {
159 SampRegCloseKey(&NamesKey);
160 Status = STATUS_ALIAS_EXISTS;
161 }
162 else if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
163 Status = STATUS_SUCCESS;
164 }
165
166 SampRegCloseKey(&AccountKey);
167 }
168
169 if (!NT_SUCCESS(Status))
170 {
171 TRACE("Checking for group account failed (Status 0x%08lx)\n", Status);
172 return Status;
173 }
174
175 Status = SampRegOpenKey(DomainObject->KeyHandle,
176 L"Users",
177 KEY_READ,
178 &AccountKey);
179 if (NT_SUCCESS(Status))
180 {
181 Status = SampRegOpenKey(AccountKey,
182 L"Names",
183 KEY_READ,
184 &NamesKey);
185 if (NT_SUCCESS(Status))
186 {
187 Status = SampRegQueryValue(NamesKey,
188 lpAccountName,
189 NULL,
190 NULL,
191 NULL);
192 if (Status == STATUS_SUCCESS)
193 {
194 SampRegCloseKey(&NamesKey);
195 Status = STATUS_ALIAS_EXISTS;
196 }
197 else if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
198 Status = STATUS_SUCCESS;
199 }
200
201 SampRegCloseKey(&AccountKey);
202 }
203
204 if (!NT_SUCCESS(Status))
205 {
206 TRACE("Checking for user account failed (Status 0x%08lx)\n", Status);
207 }
208
209 return Status;
210 }
211
212
213 NTSTATUS
214 SampRemoveMemberFromAllAliases(IN PSAM_DB_OBJECT DomainObject,
215 IN PRPC_SID MemberSid)
216 {
217 WCHAR AliasKeyName[64];
218 LPWSTR MemberSidString = NULL;
219 HANDLE AliasesKey = NULL;
220 HANDLE MembersKey = NULL;
221 HANDLE AliasKey = NULL;
222 ULONG Index;
223 NTSTATUS Status;
224
225 TRACE("(%p %p)\n", DomainObject, MemberSid);
226
227 ConvertSidToStringSidW(MemberSid, &MemberSidString);
228 TRACE("Member SID: %S\n", MemberSidString);
229
230 Status = SampRegOpenKey(DomainObject->KeyHandle,
231 L"Aliases",
232 KEY_READ,
233 &AliasesKey);
234 if (NT_SUCCESS(Status))
235 {
236 Index = 0;
237 while (TRUE)
238 {
239 Status = SampRegEnumerateSubKey(AliasesKey,
240 Index,
241 64,
242 AliasKeyName);
243 if (!NT_SUCCESS(Status))
244 {
245 if (Status == STATUS_NO_MORE_ENTRIES)
246 Status = STATUS_SUCCESS;
247 break;
248 }
249
250 TRACE("Alias key name: %S\n", AliasKeyName);
251
252 Status = SampRegOpenKey(AliasesKey,
253 AliasKeyName,
254 KEY_READ,
255 &AliasKey);
256 if (NT_SUCCESS(Status))
257 {
258 Status = SampRegOpenKey(AliasKey,
259 L"Members",
260 KEY_WRITE,
261 &MembersKey);
262 if (NT_SUCCESS(Status))
263 {
264 Status = SampRegDeleteValue(AliasKey,
265 MemberSidString);
266
267 SampRegCloseKey(&MembersKey);
268 }
269 else if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
270 Status = STATUS_SUCCESS;
271
272 SampRegCloseKey(&AliasKey);
273 }
274
275 Index++;
276 }
277
278 Status = SampRegOpenKey(AliasesKey,
279 L"Members",
280 KEY_WRITE,
281 &MembersKey);
282 if (NT_SUCCESS(Status))
283 {
284 Status = SampRegDeleteKey(MembersKey,
285 MemberSidString);
286 if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
287 Status = STATUS_SUCCESS;
288
289 SampRegCloseKey(&MembersKey);
290 }
291
292 SampRegCloseKey(&AliasesKey);
293 }
294
295 if (MemberSidString != NULL)
296 LocalFree(MemberSidString);
297
298 return Status;
299 }
300
301
302 NTSTATUS
303 SampCreateAccountSid(IN PSAM_DB_OBJECT DomainObject,
304 IN ULONG ulRelativeId,
305 IN OUT PSID *AccountSid)
306 {
307 PSID DomainSid = NULL;
308 ULONG Length = 0;
309 NTSTATUS Status;
310
311 Status = SampGetObjectAttribute(DomainObject,
312 L"SID",
313 NULL,
314 NULL,
315 &Length);
316 if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_OVERFLOW)
317 {
318 TRACE("Status 0x%08lx\n", Status);
319 goto done;
320 }
321
322 TRACE("Length: %lu\n", Length);
323
324 DomainSid = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length);
325 if (DomainSid == NULL)
326 {
327 Status = STATUS_INSUFFICIENT_RESOURCES;
328 goto done;
329 }
330
331 Status = SampGetObjectAttribute(DomainObject,
332 L"SID",
333 NULL,
334 DomainSid,
335 &Length);
336 if (!NT_SUCCESS(Status))
337 {
338 TRACE("Status 0x%08lx\n", Status);
339 goto done;
340 }
341
342 *AccountSid = AppendRidToSid(DomainSid,
343 ulRelativeId);
344
345 done:
346 if (DomainSid != NULL)
347 RtlFreeHeap(RtlGetProcessHeap(), 0, DomainSid);
348
349 return Status;
350 }
351
352 /* EOF */