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