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