xref: /reactos/dll/win32/samsrv/domain.c (revision 527f2f90)
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 */
353