[SAMLIB]
[reactos.git] / reactos / dll / win32 / samsrv / setup.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: Security Account Manager (SAM) Server
4 * FILE: reactos/dll/win32/samsrv/setup.c
5 * PURPOSE: Registry setup routines
6 *
7 * PROGRAMMERS: Eric Kohl
8 */
9
10 /* INCLUDES ****************************************************************/
11
12 #include "samsrv.h"
13
14 WINE_DEFAULT_DEBUG_CHANNEL(samsrv);
15
16 /* GLOBALS *****************************************************************/
17
18 SID_IDENTIFIER_AUTHORITY SecurityNtAuthority = {SECURITY_NT_AUTHORITY};
19
20 /* FUNCTIONS ***************************************************************/
21
22 BOOL
23 SampIsSetupRunning(VOID)
24 {
25 DWORD dwError;
26 HKEY hKey;
27 DWORD dwType;
28 DWORD dwSize;
29 DWORD dwSetupType;
30
31 TRACE("SampIsSetupRunning()\n");
32
33 /* Open key */
34 dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
35 L"SYSTEM\\Setup",
36 0,
37 KEY_QUERY_VALUE,
38 &hKey);
39 if (dwError != ERROR_SUCCESS)
40 return FALSE;
41
42 /* Read key */
43 dwSize = sizeof(DWORD);
44 dwError = RegQueryValueExW(hKey,
45 L"SetupType",
46 NULL,
47 &dwType,
48 (LPBYTE)&dwSetupType,
49 &dwSize);
50
51 /* Close key, and check if returned values are correct */
52 RegCloseKey(hKey);
53 if (dwError != ERROR_SUCCESS || dwType != REG_DWORD || dwSize != sizeof(DWORD))
54 return FALSE;
55
56 TRACE("SampIsSetupRunning() returns %s\n", (dwSetupType != 0) ? "TRUE" : "FALSE");
57 return (dwSetupType != 0);
58 }
59
60
61 static PSID
62 AppendRidToSid(PSID SrcSid,
63 ULONG Rid)
64 {
65 ULONG Rids[8] = {0, 0, 0, 0, 0, 0, 0, 0};
66 UCHAR RidCount;
67 PSID DstSid;
68 ULONG i;
69
70 RidCount = *RtlSubAuthorityCountSid(SrcSid);
71 if (RidCount >= 8)
72 return NULL;
73
74 for (i = 0; i < RidCount; i++)
75 Rids[i] = *RtlSubAuthoritySid(SrcSid, i);
76
77 Rids[RidCount] = Rid;
78 RidCount++;
79
80 RtlAllocateAndInitializeSid(RtlIdentifierAuthoritySid(SrcSid),
81 RidCount,
82 Rids[0],
83 Rids[1],
84 Rids[2],
85 Rids[3],
86 Rids[4],
87 Rids[5],
88 Rids[6],
89 Rids[7],
90 &DstSid);
91
92 return DstSid;
93 }
94
95
96 static BOOL
97 SampAddMemberToAlias(HKEY hDomainKey,
98 ULONG AliasId,
99 PSID MemberSid)
100 {
101 DWORD dwDisposition;
102 LPWSTR MemberSidString = NULL;
103 WCHAR szKeyName[256];
104 HKEY hMembersKey;
105
106 ConvertSidToStringSidW(MemberSid, &MemberSidString);
107
108 swprintf(szKeyName, L"Aliases\\%08lX\\Members", AliasId);
109
110 if (!RegCreateKeyExW(hDomainKey,
111 szKeyName,
112 0,
113 NULL,
114 REG_OPTION_NON_VOLATILE,
115 KEY_ALL_ACCESS,
116 NULL,
117 &hMembersKey,
118 &dwDisposition))
119 {
120 RegSetValueEx(hMembersKey,
121 MemberSidString,
122 0,
123 REG_BINARY,
124 (LPVOID)MemberSid,
125 RtlLengthSid(MemberSid));
126
127 RegCloseKey(hMembersKey);
128 }
129
130 swprintf(szKeyName, L"Aliases\\Members\\%s", MemberSidString);
131
132 if (!RegCreateKeyExW(hDomainKey,
133 szKeyName,
134 0,
135 NULL,
136 REG_OPTION_NON_VOLATILE,
137 KEY_ALL_ACCESS,
138 NULL,
139 &hMembersKey,
140 &dwDisposition))
141 {
142 swprintf(szKeyName, L"%08lX", AliasId);
143
144 RegSetValueEx(hMembersKey,
145 szKeyName,
146 0,
147 REG_BINARY,
148 (LPVOID)MemberSid,
149 RtlLengthSid(MemberSid));
150
151 RegCloseKey(hMembersKey);
152 }
153
154 if (MemberSidString != NULL)
155 LocalFree(MemberSidString);
156
157 return TRUE;
158 }
159
160
161 static BOOL
162 SampCreateAliasAccount(HKEY hDomainKey,
163 LPCWSTR lpAccountName,
164 LPCWSTR lpDescription,
165 ULONG ulRelativeId)
166 {
167 DWORD dwDisposition;
168 WCHAR szAccountKeyName[32];
169 HKEY hAccountKey = NULL;
170 HKEY hNamesKey = NULL;
171
172 swprintf(szAccountKeyName, L"Aliases\\%08lX", ulRelativeId);
173
174 if (!RegCreateKeyExW(hDomainKey,
175 szAccountKeyName,
176 0,
177 NULL,
178 REG_OPTION_NON_VOLATILE,
179 KEY_ALL_ACCESS,
180 NULL,
181 &hAccountKey,
182 &dwDisposition))
183 {
184 RegSetValueEx(hAccountKey,
185 L"Name",
186 0,
187 REG_SZ,
188 (LPVOID)lpAccountName,
189 (wcslen(lpAccountName) + 1) * sizeof(WCHAR));
190
191 RegSetValueEx(hAccountKey,
192 L"Description",
193 0,
194 REG_SZ,
195 (LPVOID)lpDescription,
196 (wcslen(lpDescription) + 1) * sizeof(WCHAR));
197
198 RegCloseKey(hAccountKey);
199 }
200
201 if (!RegOpenKeyExW(hDomainKey,
202 L"Aliases\\Names",
203 0,
204 KEY_ALL_ACCESS,
205 &hNamesKey))
206 {
207 RegSetValueEx(hNamesKey,
208 lpAccountName,
209 0,
210 REG_DWORD,
211 (LPVOID)&ulRelativeId,
212 sizeof(ULONG));
213
214 RegCloseKey(hNamesKey);
215 }
216
217 return TRUE;
218 }
219
220
221 static BOOL
222 SampCreateUserAccount(HKEY hDomainKey,
223 LPCWSTR lpAccountName,
224 ULONG ulRelativeId)
225 {
226 DWORD dwDisposition;
227 WCHAR szAccountKeyName[32];
228 HKEY hAccountKey = NULL;
229 HKEY hNamesKey = NULL;
230
231 swprintf(szAccountKeyName, L"Users\\%08lX", ulRelativeId);
232
233 if (!RegCreateKeyExW(hDomainKey,
234 szAccountKeyName,
235 0,
236 NULL,
237 REG_OPTION_NON_VOLATILE,
238 KEY_ALL_ACCESS,
239 NULL,
240 &hAccountKey,
241 &dwDisposition))
242 {
243 RegSetValueEx(hAccountKey,
244 L"Name",
245 0,
246 REG_SZ,
247 (LPVOID)lpAccountName,
248 (wcslen(lpAccountName) + 1) * sizeof(WCHAR));
249
250 RegCloseKey(hAccountKey);
251 }
252
253 if (!RegOpenKeyExW(hDomainKey,
254 L"Users\\Names",
255 0,
256 KEY_ALL_ACCESS,
257 &hNamesKey))
258 {
259 RegSetValueEx(hNamesKey,
260 lpAccountName,
261 0,
262 REG_DWORD,
263 (LPVOID)&ulRelativeId,
264 sizeof(ULONG));
265
266 RegCloseKey(hNamesKey);
267 }
268
269 return TRUE;
270 }
271
272
273 static BOOL
274 SampCreateDomain(IN HKEY hDomainsKey,
275 IN LPCWSTR lpKeyName,
276 IN LPCWSTR lpDomainName,
277 IN PSID lpDomainSid,
278 OUT PHKEY lpDomainKey)
279 {
280 DWORD dwDisposition;
281 HKEY hDomainKey = NULL;
282 HKEY hAliasesKey = NULL;
283 HKEY hGroupsKey = NULL;
284 HKEY hUsersKey = NULL;
285 HKEY hNamesKey = NULL;
286
287 if (lpDomainKey != NULL)
288 *lpDomainKey = NULL;
289
290 if (RegCreateKeyExW(hDomainsKey,
291 lpKeyName,
292 0,
293 NULL,
294 REG_OPTION_NON_VOLATILE,
295 KEY_ALL_ACCESS,
296 NULL,
297 &hDomainKey,
298 &dwDisposition))
299 return FALSE;
300
301 if (lpDomainSid != NULL)
302 {
303 RegSetValueEx(hDomainKey,
304 L"Name",
305 0,
306 REG_SZ,
307 (LPVOID)lpDomainName,
308 (wcslen(lpDomainName) + 1) * sizeof(WCHAR));
309
310 RegSetValueEx(hDomainKey,
311 L"SID",
312 0,
313 REG_BINARY,
314 (LPVOID)lpDomainSid,
315 RtlLengthSid(lpDomainSid));
316 }
317
318 /* Create the Alias container */
319 if (!RegCreateKeyExW(hDomainKey,
320 L"Aliases",
321 0,
322 NULL,
323 REG_OPTION_NON_VOLATILE,
324 KEY_ALL_ACCESS,
325 NULL,
326 &hAliasesKey,
327 &dwDisposition))
328 {
329 if (!RegCreateKeyExW(hAliasesKey,
330 L"Names",
331 0,
332 NULL,
333 REG_OPTION_NON_VOLATILE,
334 KEY_ALL_ACCESS,
335 NULL,
336 &hNamesKey,
337 &dwDisposition))
338 RegCloseKey(hNamesKey);
339
340 RegCloseKey(hAliasesKey);
341 }
342
343 /* Create the Groups container */
344 if (!RegCreateKeyExW(hDomainKey,
345 L"Groups",
346 0,
347 NULL,
348 REG_OPTION_NON_VOLATILE,
349 KEY_ALL_ACCESS,
350 NULL,
351 &hGroupsKey,
352 &dwDisposition))
353 {
354 if (!RegCreateKeyExW(hGroupsKey,
355 L"Names",
356 0,
357 NULL,
358 REG_OPTION_NON_VOLATILE,
359 KEY_ALL_ACCESS,
360 NULL,
361 &hNamesKey,
362 &dwDisposition))
363 RegCloseKey(hNamesKey);
364
365 RegCloseKey(hGroupsKey);
366 }
367
368
369 /* Create the Users container */
370 if (!RegCreateKeyExW(hDomainKey,
371 L"Users",
372 0,
373 NULL,
374 REG_OPTION_NON_VOLATILE,
375 KEY_ALL_ACCESS,
376 NULL,
377 &hUsersKey,
378 &dwDisposition))
379 {
380 if (!RegCreateKeyExW(hUsersKey,
381 L"Names",
382 0,
383 NULL,
384 REG_OPTION_NON_VOLATILE,
385 KEY_ALL_ACCESS,
386 NULL,
387 &hNamesKey,
388 &dwDisposition))
389 RegCloseKey(hNamesKey);
390
391 RegCloseKey(hUsersKey);
392 }
393
394 if (lpDomainKey != NULL)
395 *lpDomainKey = hDomainKey;
396
397 return TRUE;
398 }
399
400
401 NTSTATUS
402 SampGetAccountDomainInfo(PPOLICY_ACCOUNT_DOMAIN_INFO *AccountDomainInfo)
403 {
404 LSA_OBJECT_ATTRIBUTES ObjectAttributes;
405 LSA_HANDLE PolicyHandle;
406 NTSTATUS Status;
407
408 TRACE("SampGetAccountDomainInfo\n");
409
410 memset(&ObjectAttributes, 0, sizeof(LSA_OBJECT_ATTRIBUTES));
411 ObjectAttributes.Length = sizeof(LSA_OBJECT_ATTRIBUTES);
412
413 Status = LsaOpenPolicy(NULL,
414 &ObjectAttributes,
415 POLICY_TRUST_ADMIN,
416 &PolicyHandle);
417 if (Status != STATUS_SUCCESS)
418 {
419 ERR("LsaOpenPolicy failed (Status: 0x%08lx)\n", Status);
420 return Status;
421 }
422
423 Status = LsaQueryInformationPolicy(PolicyHandle,
424 PolicyAccountDomainInformation,
425 (PVOID *)AccountDomainInfo);
426
427 LsaClose(PolicyHandle);
428
429 return Status;
430 }
431
432
433 BOOL
434 SampInitializeSAM(VOID)
435 {
436 PPOLICY_ACCOUNT_DOMAIN_INFO AccountDomainInfo = NULL;
437 DWORD dwDisposition;
438 HKEY hSamKey = NULL;
439 HKEY hDomainsKey = NULL;
440 HKEY hDomainKey = NULL;
441 PSID pBuiltinSid = NULL;
442 BOOL bResult = TRUE;
443 PSID pSid;
444 NTSTATUS Status;
445
446 TRACE("SampInitializeSAM() called\n");
447
448 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE,
449 L"SAM\\SAM",
450 0,
451 NULL,
452 REG_OPTION_NON_VOLATILE,
453 KEY_ALL_ACCESS,
454 NULL,
455 &hSamKey,
456 &dwDisposition))
457 {
458 ERR("Failed to create 'Sam' key! (Error %lu)\n", GetLastError());
459 return FALSE;
460 }
461
462 if (RegCreateKeyExW(hSamKey,
463 L"Domains",
464 0,
465 NULL,
466 REG_OPTION_NON_VOLATILE,
467 KEY_ALL_ACCESS,
468 NULL,
469 &hDomainsKey,
470 &dwDisposition))
471 {
472 ERR("Failed to create 'Domains' key! (Error %lu)\n", GetLastError());
473 bResult = FALSE;
474 goto done;
475 }
476
477 RegCloseKey(hSamKey);
478 hSamKey = NULL;
479
480 /* Create and initialize the Builtin Domain SID */
481 pBuiltinSid = RtlAllocateHeap(RtlGetProcessHeap(), 0, RtlLengthRequiredSid(1));
482 if (pBuiltinSid == NULL)
483 {
484 ERR("Failed to alloacte the Builtin Domain SID\n");
485 bResult = FALSE;
486 goto done;
487 }
488
489 RtlInitializeSid(pBuiltinSid, &SecurityNtAuthority, 1);
490 *(RtlSubAuthoritySid(pBuiltinSid, 0)) = SECURITY_BUILTIN_DOMAIN_RID;
491
492 /* Get account domain information */
493 Status = SampGetAccountDomainInfo(&AccountDomainInfo);
494 if (!NT_SUCCESS(Status))
495 {
496 ERR("SampGetAccountDomainInfo failed (Status %08lx)\n", Status);
497 bResult = FALSE;
498 goto done;
499 }
500
501 /* Create the Builtin domain */
502 if (SampCreateDomain(hDomainsKey,
503 L"Builtin",
504 L"Builtin",
505 pBuiltinSid,
506 &hDomainKey))
507 {
508 SampCreateAliasAccount(hDomainKey,
509 L"Administrators",
510 L"",
511 DOMAIN_ALIAS_RID_ADMINS);
512
513 SampCreateAliasAccount(hDomainKey,
514 L"Users",
515 L"",
516 DOMAIN_ALIAS_RID_USERS);
517
518 SampCreateAliasAccount(hDomainKey,
519 L"Guests",
520 L"",
521 DOMAIN_ALIAS_RID_GUESTS);
522
523 SampCreateAliasAccount(hDomainKey,
524 L"Power Users",
525 L"",
526 DOMAIN_ALIAS_RID_POWER_USERS);
527
528
529 pSid = AppendRidToSid(AccountDomainInfo->DomainSid,
530 DOMAIN_USER_RID_ADMIN);
531 if (pSid != NULL)
532 {
533 SampAddMemberToAlias(hDomainKey,
534 DOMAIN_ALIAS_RID_ADMINS,
535 pSid);
536
537 RtlFreeHeap(RtlGetProcessHeap(), 0, pSid);
538 }
539
540
541 RegCloseKey(hDomainKey);
542 }
543
544 /* Create the Account domain */
545 if (SampCreateDomain(hDomainsKey,
546 L"Account",
547 L"",
548 AccountDomainInfo->DomainSid,
549 &hDomainKey))
550 {
551 SampCreateUserAccount(hDomainKey,
552 L"Administrator",
553 DOMAIN_USER_RID_ADMIN);
554
555 SampCreateUserAccount(hDomainKey,
556 L"Guest",
557 DOMAIN_USER_RID_GUEST);
558
559 RegCloseKey(hDomainKey);
560 }
561
562 done:
563 if (AccountDomainInfo)
564 LsaFreeMemory(AccountDomainInfo);
565
566 if (pBuiltinSid)
567 RtlFreeHeap(RtlGetProcessHeap(), 0, pBuiltinSid);
568
569 if (hDomainsKey)
570 RegCloseKey(hDomainsKey);
571
572 if (hSamKey)
573 RegCloseKey(hSamKey);
574
575 TRACE("SampInitializeSAM() done\n");
576
577 return bResult;
578 }