b6e9268974a5ea721b66e241e14db3dac4ce9eed
[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
17 /* GLOBALS *****************************************************************/
18
19 #define TICKS_PER_SECOND 10000000LL
20
21 SID_IDENTIFIER_AUTHORITY SecurityNtAuthority = {SECURITY_NT_AUTHORITY};
22
23
24 /* FUNCTIONS ***************************************************************/
25
26 static BOOL
27 SampSetupAddMemberToAlias(HKEY hDomainKey,
28 ULONG AliasId,
29 PSID MemberSid)
30 {
31 DWORD dwDisposition;
32 LPWSTR MemberSidString = NULL;
33 WCHAR szKeyName[256];
34 HKEY hMembersKey;
35
36 ConvertSidToStringSidW(MemberSid, &MemberSidString);
37
38 swprintf(szKeyName, L"Aliases\\%08lX\\Members", AliasId);
39
40 if (!RegCreateKeyExW(hDomainKey,
41 szKeyName,
42 0,
43 NULL,
44 REG_OPTION_NON_VOLATILE,
45 KEY_ALL_ACCESS,
46 NULL,
47 &hMembersKey,
48 &dwDisposition))
49 {
50 RegSetValueEx(hMembersKey,
51 MemberSidString,
52 0,
53 REG_BINARY,
54 (LPVOID)MemberSid,
55 RtlLengthSid(MemberSid));
56
57 RegCloseKey(hMembersKey);
58 }
59
60 swprintf(szKeyName, L"Aliases\\Members\\%s", MemberSidString);
61
62 if (!RegCreateKeyExW(hDomainKey,
63 szKeyName,
64 0,
65 NULL,
66 REG_OPTION_NON_VOLATILE,
67 KEY_ALL_ACCESS,
68 NULL,
69 &hMembersKey,
70 &dwDisposition))
71 {
72 swprintf(szKeyName, L"%08lX", AliasId);
73
74 RegSetValueEx(hMembersKey,
75 szKeyName,
76 0,
77 REG_BINARY,
78 (LPVOID)MemberSid,
79 RtlLengthSid(MemberSid));
80
81 RegCloseKey(hMembersKey);
82 }
83
84 if (MemberSidString != NULL)
85 LocalFree(MemberSidString);
86
87 return TRUE;
88 }
89
90
91 static
92 NTSTATUS
93 SampSetupCreateAliasAccount(HANDLE hDomainKey,
94 LPCWSTR lpAccountName,
95 LPCWSTR lpDescription,
96 ULONG ulRelativeId)
97 {
98 WCHAR szAccountKeyName[32];
99 HANDLE hAccountKey = NULL;
100 HANDLE hNamesKey = NULL;
101 NTSTATUS Status;
102
103 swprintf(szAccountKeyName, L"Aliases\\%08lX", ulRelativeId);
104
105 Status = SampRegCreateKey(hDomainKey,
106 szAccountKeyName,
107 KEY_ALL_ACCESS,
108 &hAccountKey);
109 if (!NT_SUCCESS(Status))
110 return Status;
111
112 Status = SampRegSetValue(hAccountKey,
113 L"Name",
114 REG_SZ,
115 (LPVOID)lpAccountName,
116 (wcslen(lpAccountName) + 1) * sizeof(WCHAR));
117 if (!NT_SUCCESS(Status))
118 goto done;
119
120 Status = SampRegSetValue(hAccountKey,
121 L"Description",
122 REG_SZ,
123 (LPVOID)lpDescription,
124 (wcslen(lpDescription) + 1) * sizeof(WCHAR));
125 if (!NT_SUCCESS(Status))
126 goto done;
127
128
129 Status = SampRegOpenKey(hDomainKey,
130 L"Aliases\\Names",
131 KEY_ALL_ACCESS,
132 &hNamesKey);
133 if (!NT_SUCCESS(Status))
134 goto done;
135
136 Status = SampRegSetValue(hNamesKey,
137 lpAccountName,
138 REG_DWORD,
139 (LPVOID)&ulRelativeId,
140 sizeof(ULONG));
141
142 done:
143 if (hNamesKey != NULL)
144 SampRegCloseKey(hNamesKey);
145
146 if (hAccountKey != NULL)
147 {
148 SampRegCloseKey(hAccountKey);
149
150 if (!NT_SUCCESS(Status))
151 SampRegDeleteKey(hDomainKey,
152 szAccountKeyName);
153 }
154
155 return Status;
156 }
157
158
159 static
160 NTSTATUS
161 SampSetupAddMemberToGroup(IN HANDLE hDomainKey,
162 IN ULONG GroupId,
163 IN ULONG MemberId)
164 {
165 WCHAR szKeyName[256];
166 HANDLE hGroupKey = NULL;
167 PULONG MembersBuffer = NULL;
168 ULONG MembersCount = 0;
169 ULONG Length = 0;
170 ULONG i;
171 NTSTATUS Status;
172
173 swprintf(szKeyName, L"Groups\\%08lX", GroupId);
174
175 Status = SampRegOpenKey(hDomainKey,
176 szKeyName,
177 KEY_ALL_ACCESS,
178 &hGroupKey);
179 if (!NT_SUCCESS(Status))
180 return Status;
181
182 Status = SampRegQueryValue(hGroupKey,
183 L"Members",
184 NULL,
185 NULL,
186 &Length);
187 if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_NOT_FOUND)
188 goto done;
189
190 MembersBuffer = midl_user_allocate(Length + sizeof(ULONG));
191 if (MembersBuffer == NULL)
192 {
193 Status = STATUS_INSUFFICIENT_RESOURCES;
194 goto done;
195 }
196
197 if (Status != STATUS_OBJECT_NAME_NOT_FOUND)
198 {
199 Status = SampRegQueryValue(hGroupKey,
200 L"Members",
201 NULL,
202 MembersBuffer,
203 &Length);
204 if (!NT_SUCCESS(Status))
205 goto done;
206
207 MembersCount = Length / sizeof(ULONG);
208 }
209
210 for (i = 0; i < MembersCount; i++)
211 {
212 if (MembersBuffer[i] == MemberId)
213 {
214 Status = STATUS_MEMBER_IN_GROUP;
215 goto done;
216 }
217 }
218
219 MembersBuffer[MembersCount] = MemberId;
220 Length += sizeof(ULONG);
221
222 Status = SampRegSetValue(hGroupKey,
223 L"Members",
224 REG_BINARY,
225 MembersBuffer,
226 Length);
227
228 done:
229 if (MembersBuffer != NULL)
230 midl_user_free(MembersBuffer);
231
232 if (hGroupKey != NULL)
233 SampRegCloseKey(hGroupKey);
234
235 return Status;
236 }
237
238
239 static
240 NTSTATUS
241 SampSetupCreateGroupAccount(HANDLE hDomainKey,
242 LPCWSTR lpAccountName,
243 LPCWSTR lpComment,
244 ULONG ulRelativeId)
245 {
246 SAM_GROUP_FIXED_DATA FixedGroupData;
247 WCHAR szAccountKeyName[32];
248 HANDLE hAccountKey = NULL;
249 HANDLE hNamesKey = NULL;
250 NTSTATUS Status;
251
252 /* Initialize fixed group data */
253 FixedGroupData.Version = 1;
254 FixedGroupData.Reserved = 0;
255 FixedGroupData.GroupId = ulRelativeId;
256 FixedGroupData.Attributes = 0;
257
258 swprintf(szAccountKeyName, L"Groups\\%08lX", ulRelativeId);
259
260 Status = SampRegCreateKey(hDomainKey,
261 szAccountKeyName,
262 KEY_ALL_ACCESS,
263 &hAccountKey);
264 if (!NT_SUCCESS(Status))
265 return Status;
266
267 Status = SampRegSetValue(hAccountKey,
268 L"F",
269 REG_BINARY,
270 (LPVOID)&FixedGroupData,
271 sizeof(SAM_GROUP_FIXED_DATA));
272 if (!NT_SUCCESS(Status))
273 goto done;
274
275 Status = SampRegSetValue(hAccountKey,
276 L"Name",
277 REG_SZ,
278 (LPVOID)lpAccountName,
279 (wcslen(lpAccountName) + 1) * sizeof(WCHAR));
280 if (!NT_SUCCESS(Status))
281 goto done;
282
283 Status = SampRegSetValue(hAccountKey,
284 L"AdminComment",
285 REG_SZ,
286 (LPVOID)lpComment,
287 (wcslen(lpComment) + 1) * sizeof(WCHAR));
288 if (!NT_SUCCESS(Status))
289 goto done;
290
291 Status = SampRegOpenKey(hDomainKey,
292 L"Groups\\Names",
293 KEY_ALL_ACCESS,
294 &hNamesKey);
295 if (!NT_SUCCESS(Status))
296 goto done;
297
298 Status = SampRegSetValue(hNamesKey,
299 lpAccountName,
300 REG_DWORD,
301 (LPVOID)&ulRelativeId,
302 sizeof(ULONG));
303
304 done:
305 if (hNamesKey != NULL)
306 SampRegCloseKey(hNamesKey);
307
308 if (hAccountKey != NULL)
309 {
310 SampRegCloseKey(hAccountKey);
311
312 if (!NT_SUCCESS(Status))
313 SampRegDeleteKey(hDomainKey,
314 szAccountKeyName);
315 }
316
317 return Status;
318 }
319
320
321 static
322 NTSTATUS
323 SampSetupCreateUserAccount(HANDLE hDomainKey,
324 LPCWSTR lpAccountName,
325 LPCWSTR lpComment,
326 ULONG ulRelativeId,
327 ULONG UserAccountControl)
328 {
329 SAM_USER_FIXED_DATA FixedUserData;
330 GROUP_MEMBERSHIP GroupMembership;
331 UCHAR LogonHours[23];
332 LPWSTR lpEmptyString = L"";
333 WCHAR szAccountKeyName[32];
334 HANDLE hAccountKey = NULL;
335 HANDLE hNamesKey = NULL;
336 NTSTATUS Status;
337
338 /* Initialize fixed user data */
339 FixedUserData.Version = 1;
340 FixedUserData.Reserved = 0;
341 FixedUserData.LastLogon.QuadPart = 0;
342 FixedUserData.LastLogoff.QuadPart = 0;
343 FixedUserData.PasswordLastSet.QuadPart = 0;
344 FixedUserData.AccountExpires.LowPart = MAXULONG;
345 FixedUserData.AccountExpires.HighPart = MAXLONG;
346 FixedUserData.LastBadPasswordTime.QuadPart = 0;
347 FixedUserData.UserId = ulRelativeId;
348 FixedUserData.PrimaryGroupId = DOMAIN_GROUP_RID_USERS;
349 FixedUserData.UserAccountControl = UserAccountControl;
350 FixedUserData.CountryCode = 0;
351 FixedUserData.CodePage = 0;
352 FixedUserData.BadPasswordCount = 0;
353 FixedUserData.LogonCount = 0;
354 FixedUserData.AdminCount = 0;
355 FixedUserData.OperatorCount = 0;
356
357 swprintf(szAccountKeyName, L"Users\\%08lX", ulRelativeId);
358
359 Status = SampRegCreateKey(hDomainKey,
360 szAccountKeyName,
361 KEY_ALL_ACCESS,
362 &hAccountKey);
363 if (!NT_SUCCESS(Status))
364 return Status;
365
366 Status = SampRegSetValue(hAccountKey,
367 L"F",
368 REG_BINARY,
369 (LPVOID)&FixedUserData,
370 sizeof(SAM_USER_FIXED_DATA));
371 if (!NT_SUCCESS(Status))
372 goto done;
373
374 Status = SampRegSetValue(hAccountKey,
375 L"Name",
376 REG_SZ,
377 (LPVOID)lpAccountName,
378 (wcslen(lpAccountName) + 1) * sizeof(WCHAR));
379 if (!NT_SUCCESS(Status))
380 goto done;
381
382 Status = SampRegSetValue(hAccountKey,
383 L"FullName",
384 REG_SZ,
385 (LPVOID)lpEmptyString,
386 sizeof(WCHAR));
387 if (!NT_SUCCESS(Status))
388 goto done;
389
390 Status = SampRegSetValue(hAccountKey,
391 L"HomeDirectory",
392 REG_SZ,
393 (LPVOID)lpEmptyString,
394 sizeof(WCHAR));
395 if (!NT_SUCCESS(Status))
396 goto done;
397
398 Status = SampRegSetValue(hAccountKey,
399 L"HomeDirectoryDrive",
400 REG_SZ,
401 (LPVOID)lpEmptyString,
402 sizeof(WCHAR));
403 if (!NT_SUCCESS(Status))
404 goto done;
405
406 Status = SampRegSetValue(hAccountKey,
407 L"ScriptPath",
408 REG_SZ,
409 (LPVOID)lpEmptyString,
410 sizeof(WCHAR));
411 if (!NT_SUCCESS(Status))
412 goto done;
413
414 Status = SampRegSetValue(hAccountKey,
415 L"ProfilePath",
416 REG_SZ,
417 (LPVOID)lpEmptyString,
418 sizeof(WCHAR));
419 if (!NT_SUCCESS(Status))
420 goto done;
421
422 Status = SampRegSetValue(hAccountKey,
423 L"AdminComment",
424 REG_SZ,
425 (LPVOID)lpComment,
426 (wcslen(lpComment) + 1) * sizeof(WCHAR));
427 if (!NT_SUCCESS(Status))
428 goto done;
429
430 Status = SampRegSetValue(hAccountKey,
431 L"UserComment",
432 REG_SZ,
433 (LPVOID)lpEmptyString,
434 sizeof(WCHAR));
435 if (!NT_SUCCESS(Status))
436 goto done;
437
438 Status = SampRegSetValue(hAccountKey,
439 L"WorkStations",
440 REG_SZ,
441 (LPVOID)lpEmptyString,
442 sizeof(WCHAR));
443 if (!NT_SUCCESS(Status))
444 goto done;
445
446 Status = SampRegSetValue(hAccountKey,
447 L"Parameters",
448 REG_SZ,
449 (LPVOID)lpEmptyString,
450 sizeof(WCHAR));
451 if (!NT_SUCCESS(Status))
452 goto done;
453
454 /* Set LogonHours attribute*/
455 *((PUSHORT)LogonHours) = 168;
456 memset(&(LogonHours[2]), 0xff, 21);
457
458 Status = SampRegSetValue(hAccountKey,
459 L"LogonHours",
460 REG_BINARY,
461 (LPVOID)LogonHours,
462 sizeof(LogonHours));
463 if (!NT_SUCCESS(Status))
464 goto done;
465
466 /* Set Groups attribute*/
467 GroupMembership.RelativeId = DOMAIN_GROUP_RID_USERS;
468 GroupMembership.Attributes = SE_GROUP_MANDATORY |
469 SE_GROUP_ENABLED |
470 SE_GROUP_ENABLED_BY_DEFAULT;
471
472 Status = SampRegSetValue(hAccountKey,
473 L"Groups",
474 REG_BINARY,
475 (LPVOID)&GroupMembership,
476 sizeof(GROUP_MEMBERSHIP));
477 if (!NT_SUCCESS(Status))
478 goto done;
479
480 /* Set LMPwd attribute*/
481 Status = SampRegSetValue(hAccountKey,
482 L"LMPwd",
483 REG_BINARY,
484 (LPVOID)&EmptyLmHash,
485 sizeof(ENCRYPTED_LM_OWF_PASSWORD));
486 if (!NT_SUCCESS(Status))
487 goto done;
488
489 /* Set NTPwd attribute*/
490 Status = SampRegSetValue(hAccountKey,
491 L"NTPwd",
492 REG_BINARY,
493 (LPVOID)&EmptyNtHash,
494 sizeof(ENCRYPTED_NT_OWF_PASSWORD));
495 if (!NT_SUCCESS(Status))
496 goto done;
497
498 /* Set LMPwdHistory attribute*/
499 Status = SampRegSetValue(hAccountKey,
500 L"LMPwdHistory",
501 REG_BINARY,
502 NULL,
503 0);
504 if (!NT_SUCCESS(Status))
505 goto done;
506
507 /* Set NTPwdHistory attribute*/
508 Status = SampRegSetValue(hAccountKey,
509 L"NTPwdHistory",
510 REG_BINARY,
511 NULL,
512 0);
513 if (!NT_SUCCESS(Status))
514 goto done;
515
516 /* FIXME: Set SecDesc attribute*/
517
518
519 Status = SampRegOpenKey(hDomainKey,
520 L"Users\\Names",
521 KEY_ALL_ACCESS,
522 &hNamesKey);
523 if (!NT_SUCCESS(Status))
524 goto done;
525
526 Status = SampRegSetValue(hNamesKey,
527 lpAccountName,
528 REG_DWORD,
529 (LPVOID)&ulRelativeId,
530 sizeof(ULONG));
531
532 done:
533 if (hNamesKey != NULL)
534 SampRegCloseKey(hNamesKey);
535
536 if (hAccountKey != NULL)
537 {
538 SampRegCloseKey(hAccountKey);
539
540 if (!NT_SUCCESS(Status))
541 SampRegDeleteKey(hDomainKey,
542 szAccountKeyName);
543 }
544
545 return Status;
546 }
547
548
549 static
550 NTSTATUS
551 SampSetupCreateDomain(IN HANDLE hServerKey,
552 IN LPCWSTR lpKeyName,
553 IN LPCWSTR lpDomainName,
554 IN PSID lpDomainSid,
555 OUT HANDLE *lpDomainKey)
556 {
557 SAM_DOMAIN_FIXED_DATA FixedData;
558 WCHAR szDomainKeyName[32];
559 LPWSTR lpEmptyString = L"";
560 HANDLE hDomainKey = NULL;
561 HANDLE hAliasesKey = NULL;
562 HANDLE hGroupsKey = NULL;
563 HANDLE hUsersKey = NULL;
564 HANDLE hNamesKey = NULL;
565 NTSTATUS Status;
566
567 if (lpDomainKey != NULL)
568 *lpDomainKey = NULL;
569
570 /* Initialize the fixed domain data */
571 memset(&FixedData, 0, sizeof(SAM_DOMAIN_FIXED_DATA));
572 FixedData.Version = 1;
573 NtQuerySystemTime(&FixedData.CreationTime);
574 FixedData.DomainModifiedCount.QuadPart = 0;
575 FixedData.MaxPasswordAge.QuadPart = -(6LL * 7LL * 24LL * 60LL * 60LL * TICKS_PER_SECOND); /* 6 weeks */
576 FixedData.MinPasswordAge.QuadPart = 0; /* right now */
577 // FixedData.ForceLogoff.QuadPart = // very far in the future aka never
578 FixedData.LockoutDuration.QuadPart = -(30LL * 60LL * TICKS_PER_SECOND); /* 30 minutes */
579 FixedData.LockoutObservationWindow.QuadPart = -(30LL * 60LL * TICKS_PER_SECOND); /* 30 minutes */
580 FixedData.ModifiedCountAtLastPromotion.QuadPart = 0;
581 FixedData.NextRid = 1000;
582 FixedData.PasswordProperties = 0;
583 FixedData.MinPasswordLength = 0;
584 FixedData.PasswordHistoryLength = 0;
585 FixedData.LockoutThreshold = 0;
586 FixedData.DomainServerState = DomainServerEnabled;
587 FixedData.DomainServerRole = DomainServerRolePrimary;
588 FixedData.UasCompatibilityRequired = TRUE;
589
590 wcscpy(szDomainKeyName, L"Domains\\");
591 wcscat(szDomainKeyName, lpKeyName);
592
593 Status = SampRegCreateKey(hServerKey,
594 szDomainKeyName,
595 KEY_ALL_ACCESS,
596 &hDomainKey);
597 if (!NT_SUCCESS(Status))
598 return Status;
599
600 /* Set the fixed data value */
601 Status = SampRegSetValue(hDomainKey,
602 L"F",
603 REG_BINARY,
604 (LPVOID)&FixedData,
605 sizeof(SAM_DOMAIN_FIXED_DATA));
606 if (!NT_SUCCESS(Status))
607 goto done;
608
609 if (lpDomainSid != NULL)
610 {
611 Status = SampRegSetValue(hDomainKey,
612 L"Name",
613 REG_SZ,
614 (LPVOID)lpDomainName,
615 (wcslen(lpDomainName) + 1) * sizeof(WCHAR));
616 if (!NT_SUCCESS(Status))
617 goto done;
618
619 Status = SampRegSetValue(hDomainKey,
620 L"SID",
621 REG_BINARY,
622 (LPVOID)lpDomainSid,
623 RtlLengthSid(lpDomainSid));
624 if (!NT_SUCCESS(Status))
625 goto done;
626 }
627
628 Status = SampRegSetValue(hDomainKey,
629 L"OemInformation",
630 REG_SZ,
631 (LPVOID)lpEmptyString,
632 sizeof(WCHAR));
633 if (!NT_SUCCESS(Status))
634 goto done;
635
636 Status = SampRegSetValue(hDomainKey,
637 L"ReplicaSourceNodeName",
638 REG_SZ,
639 (LPVOID)lpEmptyString,
640 sizeof(WCHAR));
641 if (!NT_SUCCESS(Status))
642 goto done;
643
644 /* Create the Alias container */
645 Status = SampRegCreateKey(hDomainKey,
646 L"Aliases",
647 KEY_ALL_ACCESS,
648 &hAliasesKey);
649 if (!NT_SUCCESS(Status))
650 goto done;
651
652 Status = SampRegCreateKey(hAliasesKey,
653 L"Names",
654 KEY_ALL_ACCESS,
655 &hNamesKey);
656 if (!NT_SUCCESS(Status))
657 goto done;
658
659 SampRegCloseKey(hNamesKey);
660
661 /* Create the Groups container */
662 Status = SampRegCreateKey(hDomainKey,
663 L"Groups",
664 KEY_ALL_ACCESS,
665 &hGroupsKey);
666 if (!NT_SUCCESS(Status))
667 goto done;
668
669 Status = SampRegCreateKey(hGroupsKey,
670 L"Names",
671 KEY_ALL_ACCESS,
672 &hNamesKey);
673 if (!NT_SUCCESS(Status))
674 goto done;
675
676 SampRegCloseKey(hNamesKey);
677
678 /* Create the Users container */
679 Status = SampRegCreateKey(hDomainKey,
680 L"Users",
681 KEY_ALL_ACCESS,
682 &hUsersKey);
683 if (!NT_SUCCESS(Status))
684 goto done;
685
686 Status = SampRegCreateKey(hUsersKey,
687 L"Names",
688 KEY_ALL_ACCESS,
689 &hNamesKey);
690 if (!NT_SUCCESS(Status))
691 goto done;
692
693 SampRegCloseKey(hNamesKey);
694
695 if (lpDomainKey != NULL)
696 *lpDomainKey = hDomainKey;
697
698 done:
699 if (hAliasesKey != NULL)
700 SampRegCloseKey(hAliasesKey);
701
702 if (hGroupsKey != NULL)
703 SampRegCloseKey(hGroupsKey);
704
705 if (hUsersKey != NULL)
706 SampRegCloseKey(hUsersKey);
707
708 if (!NT_SUCCESS(Status))
709 {
710 if (hDomainKey != NULL)
711 SampRegCloseKey(hDomainKey);
712 }
713
714 return Status;
715 }
716
717
718 static
719 NTSTATUS
720 SampSetupCreateServer(IN HANDLE hSamKey,
721 OUT HANDLE *lpServerKey)
722 {
723 HANDLE hServerKey = NULL;
724 HANDLE hDomainsKey = NULL;
725 NTSTATUS Status;
726
727 Status = SampRegCreateKey(hSamKey,
728 L"SAM",
729 KEY_ALL_ACCESS,
730 &hServerKey);
731 if (!NT_SUCCESS(Status))
732 return Status;
733
734 Status = SampRegCreateKey(hServerKey,
735 L"Domains",
736 KEY_ALL_ACCESS,
737 &hDomainsKey);
738 if (!NT_SUCCESS(Status))
739 goto done;
740
741 SampRegCloseKey(hDomainsKey);
742
743 *lpServerKey = hServerKey;
744
745 done:
746
747 return Status;
748 }
749
750
751 NTSTATUS
752 SampGetAccountDomainInfo(PPOLICY_ACCOUNT_DOMAIN_INFO *AccountDomainInfo)
753 {
754 LSA_OBJECT_ATTRIBUTES ObjectAttributes;
755 LSA_HANDLE PolicyHandle;
756 NTSTATUS Status;
757
758 TRACE("SampGetAccountDomainInfo\n");
759
760 memset(&ObjectAttributes, 0, sizeof(LSA_OBJECT_ATTRIBUTES));
761 ObjectAttributes.Length = sizeof(LSA_OBJECT_ATTRIBUTES);
762
763 Status = LsaOpenPolicy(NULL,
764 &ObjectAttributes,
765 POLICY_VIEW_LOCAL_INFORMATION,
766 &PolicyHandle);
767 if (Status != STATUS_SUCCESS)
768 {
769 ERR("LsaOpenPolicy failed (Status: 0x%08lx)\n", Status);
770 return Status;
771 }
772
773 Status = LsaQueryInformationPolicy(PolicyHandle,
774 PolicyAccountDomainInformation,
775 (PVOID *)AccountDomainInfo);
776
777 LsaClose(PolicyHandle);
778
779 return Status;
780 }
781
782
783 BOOL
784 SampInitializeSAM(VOID)
785 {
786 PPOLICY_ACCOUNT_DOMAIN_INFO AccountDomainInfo = NULL;
787 HANDLE hSamKey = NULL;
788 HANDLE hServerKey = NULL;
789 HANDLE hBuiltinDomainKey = NULL;
790 HANDLE hAccountDomainKey = NULL;
791 PSID pBuiltinSid = NULL;
792 BOOL bResult = TRUE;
793 PSID pSid;
794 HINSTANCE hInstance;
795 WCHAR szComment[256];
796 WCHAR szName[80];
797 NTSTATUS Status;
798
799 TRACE("SampInitializeSAM() called\n");
800
801 hInstance = GetModuleHandleW(L"samsrv.dll");
802
803 /* Open the SAM key */
804 Status = SampRegOpenKey(NULL,
805 L"\\Registry\\Machine\\SAM",
806 KEY_READ | KEY_CREATE_SUB_KEY | KEY_ENUMERATE_SUB_KEYS,
807 &hSamKey);
808 if (!NT_SUCCESS(Status))
809 {
810 ERR("Failed to open the SAM key (Status: 0x%08lx)\n", Status);
811 return FALSE;
812 }
813
814 /* Create the SAM Server object */
815 Status = SampSetupCreateServer(hSamKey,
816 &hServerKey);
817 if (!NT_SUCCESS(Status))
818 {
819 bResult = FALSE;
820 goto done;
821 }
822
823 /* Create and initialize the Builtin Domain SID */
824 pBuiltinSid = RtlAllocateHeap(RtlGetProcessHeap(), 0, RtlLengthRequiredSid(1));
825 if (pBuiltinSid == NULL)
826 {
827 ERR("Failed to alloacte the Builtin Domain SID\n");
828 bResult = FALSE;
829 goto done;
830 }
831
832 RtlInitializeSid(pBuiltinSid, &SecurityNtAuthority, 1);
833 *(RtlSubAuthoritySid(pBuiltinSid, 0)) = SECURITY_BUILTIN_DOMAIN_RID;
834
835 /* Get account domain information */
836 Status = SampGetAccountDomainInfo(&AccountDomainInfo);
837 if (!NT_SUCCESS(Status))
838 {
839 ERR("SampGetAccountDomainInfo failed (Status %08lx)\n", Status);
840 bResult = FALSE;
841 goto done;
842 }
843
844 SampLoadString(hInstance, IDS_DOMAIN_BUILTIN_NAME, szName, 80);
845
846 /* Create the Builtin domain */
847 Status = SampSetupCreateDomain(hServerKey,
848 L"Builtin",
849 szName,
850 pBuiltinSid,
851 &hBuiltinDomainKey);
852 if (!NT_SUCCESS(Status))
853 {
854 bResult = FALSE;
855 goto done;
856 }
857
858 SampLoadString(hInstance, IDS_ALIAS_ADMINISTRATORS_NAME, szName, 80);
859 SampLoadString(hInstance, IDS_ALIAS_ADMINISTRATORS_COMMENT, szComment, 256);
860
861 SampSetupCreateAliasAccount(hBuiltinDomainKey,
862 szName,
863 szComment,
864 DOMAIN_ALIAS_RID_ADMINS);
865
866 SampLoadString(hInstance, IDS_ALIAS_USERS_NAME, szName, 80);
867 SampLoadString(hInstance, IDS_ALIAS_USERS_COMMENT, szComment, 256);
868
869 SampSetupCreateAliasAccount(hBuiltinDomainKey,
870 szName,
871 szComment,
872 DOMAIN_ALIAS_RID_USERS);
873
874 SampLoadString(hInstance, IDS_ALIAS_GUESTS_NAME, szName, 80);
875 SampLoadString(hInstance, IDS_ALIAS_GUESTS_COMMENT, szComment, 256);
876
877 SampSetupCreateAliasAccount(hBuiltinDomainKey,
878 szName,
879 szComment,
880 DOMAIN_ALIAS_RID_GUESTS);
881
882 SampLoadString(hInstance, IDS_ALIAS_POWER_USERS_NAME, szName, 80);
883 SampLoadString(hInstance, IDS_ALIAS_POWER_USERS_COMMENT, szComment, 256);
884
885 SampSetupCreateAliasAccount(hBuiltinDomainKey,
886 szName,
887 szComment,
888 DOMAIN_ALIAS_RID_POWER_USERS);
889
890 /* Add the Administrator user to the Administrators alias */
891 pSid = AppendRidToSid(AccountDomainInfo->DomainSid,
892 DOMAIN_USER_RID_ADMIN);
893 if (pSid != NULL)
894 {
895 SampSetupAddMemberToAlias(hBuiltinDomainKey,
896 DOMAIN_ALIAS_RID_ADMINS,
897 pSid);
898
899 RtlFreeHeap(RtlGetProcessHeap(), 0, pSid);
900 }
901
902 /* Add the Guest user to the Guests alias */
903 pSid = AppendRidToSid(AccountDomainInfo->DomainSid,
904 DOMAIN_USER_RID_GUEST);
905 if (pSid != NULL)
906 {
907 SampSetupAddMemberToAlias(hBuiltinDomainKey,
908 DOMAIN_ALIAS_RID_GUESTS,
909 pSid);
910
911 RtlFreeHeap(RtlGetProcessHeap(), 0, pSid);
912 }
913
914
915 /* Create the Account domain */
916 Status = SampSetupCreateDomain(hServerKey,
917 L"Account",
918 L"",
919 AccountDomainInfo->DomainSid,
920 &hAccountDomainKey);
921 if (!NT_SUCCESS(Status))
922 {
923 bResult = FALSE;
924 goto done;
925 }
926
927 SampLoadString(hInstance, IDS_GROUP_NONE_NAME, szName, 80);
928 SampLoadString(hInstance, IDS_GROUP_NONE_COMMENT, szComment, 256);
929
930 SampSetupCreateGroupAccount(hAccountDomainKey,
931 szName,
932 szComment,
933 DOMAIN_GROUP_RID_USERS);
934
935 SampLoadString(hInstance, IDS_USER_ADMINISTRATOR_NAME, szName, 80);
936 SampLoadString(hInstance, IDS_USER_ADMINISTRATOR_COMMENT, szComment, 256);
937
938 SampSetupCreateUserAccount(hAccountDomainKey,
939 szName,
940 szComment,
941 DOMAIN_USER_RID_ADMIN,
942 USER_DONT_EXPIRE_PASSWORD | USER_NORMAL_ACCOUNT);
943
944 SampSetupAddMemberToGroup(hAccountDomainKey,
945 DOMAIN_GROUP_RID_USERS,
946 DOMAIN_USER_RID_ADMIN);
947
948 SampLoadString(hInstance, IDS_USER_GUEST_NAME, szName, 80);
949 SampLoadString(hInstance, IDS_USER_GUEST_COMMENT, szComment, 256);
950
951 SampSetupCreateUserAccount(hAccountDomainKey,
952 szName,
953 szComment,
954 DOMAIN_USER_RID_GUEST,
955 USER_ACCOUNT_DISABLED | USER_DONT_EXPIRE_PASSWORD | USER_NORMAL_ACCOUNT);
956
957 SampSetupAddMemberToGroup(hAccountDomainKey,
958 DOMAIN_GROUP_RID_USERS,
959 DOMAIN_USER_RID_GUEST);
960
961 done:
962 if (AccountDomainInfo)
963 LsaFreeMemory(AccountDomainInfo);
964
965 if (pBuiltinSid)
966 RtlFreeHeap(RtlGetProcessHeap(), 0, pBuiltinSid);
967
968 if (hAccountDomainKey != NULL)
969 SampRegCloseKey(hAccountDomainKey);
970
971 if (hBuiltinDomainKey != NULL)
972 SampRegCloseKey(hBuiltinDomainKey);
973
974 if (hServerKey != NULL)
975 SampRegCloseKey(hServerKey);
976
977 if (hSamKey != NULL)
978 SampRegCloseKey(hSamKey);
979
980 TRACE("SampInitializeSAM() done\n");
981
982 return bResult;
983 }