xref: /reactos/dll/win32/samsrv/setup.c (revision 84344399)
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     /* Create the Administrators alias */
990     SampLoadString(hInstance, IDS_ALIAS_ADMINISTRATORS_NAME, szName, 80);
991     SampLoadString(hInstance, IDS_ALIAS_ADMINISTRATORS_COMMENT, szComment, 256);
992 
993     SampSetupCreateAliasAccount(hBuiltinDomainKey,
994                                 szName,
995                                 szComment,
996                                 DOMAIN_ALIAS_RID_ADMINS);
997 
998     /* Create the Users alias */
999     SampLoadString(hInstance, IDS_ALIAS_USERS_NAME, szName, 80);
1000     SampLoadString(hInstance, IDS_ALIAS_USERS_COMMENT, szComment, 256);
1001 
1002     SampSetupCreateAliasAccount(hBuiltinDomainKey,
1003                                 szName,
1004                                 szComment,
1005                                 DOMAIN_ALIAS_RID_USERS);
1006 
1007     /* Create the Guests alias */
1008     SampLoadString(hInstance, IDS_ALIAS_GUESTS_NAME, szName, 80);
1009     SampLoadString(hInstance, IDS_ALIAS_GUESTS_COMMENT, szComment, 256);
1010 
1011     SampSetupCreateAliasAccount(hBuiltinDomainKey,
1012                                 szName,
1013                                 szComment,
1014                                 DOMAIN_ALIAS_RID_GUESTS);
1015 
1016     /* Create the Power Users alias */
1017     SampLoadString(hInstance, IDS_ALIAS_POWER_USERS_NAME, szName, 80);
1018     SampLoadString(hInstance, IDS_ALIAS_POWER_USERS_COMMENT, szComment, 256);
1019 
1020     SampSetupCreateAliasAccount(hBuiltinDomainKey,
1021                                 szName,
1022                                 szComment,
1023                                 DOMAIN_ALIAS_RID_POWER_USERS);
1024 
1025     if (SampProductType != NtProductWinNt)
1026     {
1027         /* Create the Print Operators alias (Server only) */
1028         SampLoadString(hInstance, IDS_ALIAS_PRINT_OPS_NAME, szName, 80);
1029         SampLoadString(hInstance, IDS_ALIAS_PRINT_OPS_COMMENT, szComment, 256);
1030 
1031         SampSetupCreateAliasAccount(hBuiltinDomainKey,
1032                                     szName,
1033                                     szComment,
1034                                     DOMAIN_ALIAS_RID_PRINT_OPS);
1035     }
1036 
1037     /* Create the Backup Operators alias */
1038     SampLoadString(hInstance, IDS_ALIAS_BACKUP_OPS_NAME, szName, 80);
1039     SampLoadString(hInstance, IDS_ALIAS_BACKUP_OPS_COMMENT, szComment, 256);
1040 
1041     SampSetupCreateAliasAccount(hBuiltinDomainKey,
1042                                 szName,
1043                                 szComment,
1044                                 DOMAIN_ALIAS_RID_BACKUP_OPS);
1045 
1046     /* Create the Replicator alias */
1047     SampLoadString(hInstance, IDS_ALIAS_REPLICATOR_NAME, szName, 80);
1048     SampLoadString(hInstance, IDS_ALIAS_REPLICATOR_COMMENT, szComment, 256);
1049 
1050     SampSetupCreateAliasAccount(hBuiltinDomainKey,
1051                                 szName,
1052                                 szComment,
1053                                 DOMAIN_ALIAS_RID_REPLICATOR);
1054 
1055     /* Create the Remote Desktop Users alias */
1056     SampLoadString(hInstance, IDS_ALIAS_REMOTE_DESKTOP_USERS_NAME, szName, 80);
1057     SampLoadString(hInstance, IDS_ALIAS_REMOTE_DESKTOP_USERS_COMMENT, szComment, 256);
1058 
1059     SampSetupCreateAliasAccount(hBuiltinDomainKey,
1060                                 szName,
1061                                 szComment,
1062                                 DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS);
1063 
1064     /* Create the Network Configuration Operators alias */
1065     SampLoadString(hInstance, IDS_ALIAS_NETWORK_CONFIGURATION_OPS_NAME, szName, 80);
1066     SampLoadString(hInstance, IDS_ALIAS_NETWORK_CONFIGURATION_OPS_COMMENT, szComment, 256);
1067 
1068     SampSetupCreateAliasAccount(hBuiltinDomainKey,
1069                                 szName,
1070                                 szComment,
1071                                 DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS);
1072 
1073     if (SampProductType != NtProductWinNt)
1074     {
1075         /* Create the Performance Monitor Users alias (Server only) */
1076         SampLoadString(hInstance, IDS_ALIAS_MONITORING_USERS_NAME, szName, 80);
1077         SampLoadString(hInstance, IDS_ALIAS_MONITORING_USERS_COMMENT, szComment, 256);
1078 
1079         SampSetupCreateAliasAccount(hBuiltinDomainKey,
1080                                     szName,
1081                                     szComment,
1082                                     DOMAIN_ALIAS_RID_MONITORING_USERS);
1083 
1084         /* Create the Performance Log Users alias (Server only) */
1085         SampLoadString(hInstance, IDS_ALIAS_LOGGING_USERS_NAME, szName, 80);
1086         SampLoadString(hInstance, IDS_ALIAS_LOGGING_USERS_COMMENT, szComment, 256);
1087 
1088         SampSetupCreateAliasAccount(hBuiltinDomainKey,
1089                                     szName,
1090                                     szComment,
1091                                     DOMAIN_ALIAS_RID_LOGGING_USERS);
1092     }
1093 
1094     /* Add the Administrator user to the Administrators alias */
1095     pSid = AppendRidToSid(AccountDomainInfo->DomainSid,
1096                           DOMAIN_USER_RID_ADMIN);
1097     if (pSid != NULL)
1098     {
1099         SampSetupAddMemberToAlias(hBuiltinDomainKey,
1100                                   DOMAIN_ALIAS_RID_ADMINS,
1101                                   pSid);
1102 
1103         RtlFreeHeap(RtlGetProcessHeap(), 0, pSid);
1104     }
1105 
1106     /* Add the Guest user to the Guests alias */
1107     pSid = AppendRidToSid(AccountDomainInfo->DomainSid,
1108                           DOMAIN_USER_RID_GUEST);
1109     if (pSid != NULL)
1110     {
1111         SampSetupAddMemberToAlias(hBuiltinDomainKey,
1112                                   DOMAIN_ALIAS_RID_GUESTS,
1113                                   pSid);
1114 
1115         RtlFreeHeap(RtlGetProcessHeap(), 0, pSid);
1116     }
1117 
1118     /* Add the Interactive SID to the Users alias */
1119     SampSetupAddMemberToAlias(hBuiltinDomainKey,
1120                               DOMAIN_ALIAS_RID_USERS,
1121                               pInteractiveSid);
1122 
1123     /* Add the Authenticated User SID to the Users alias */
1124     SampSetupAddMemberToAlias(hBuiltinDomainKey,
1125                               DOMAIN_ALIAS_RID_USERS,
1126                               pAuthenticatedUserSid);
1127 
1128     /* Create the Account domain */
1129     Status = SampSetupCreateDomain(hServerKey,
1130                                    L"Account",
1131                                    L"",
1132                                    AccountDomainInfo->DomainSid,
1133                                    FALSE,
1134                                    &hAccountDomainKey);
1135     if (!NT_SUCCESS(Status))
1136     {
1137         bResult = FALSE;
1138         goto done;
1139     }
1140 
1141     /* Create the None group */
1142     SampLoadString(hInstance, IDS_GROUP_NONE_NAME, szName, 80);
1143     SampLoadString(hInstance, IDS_GROUP_NONE_COMMENT, szComment, 256);
1144 
1145     SampSetupCreateGroupAccount(hAccountDomainKey,
1146                                 szName,
1147                                 szComment,
1148                                 DOMAIN_GROUP_RID_USERS);
1149 
1150     /* Create the Administrator user */
1151     SampLoadString(hInstance, IDS_USER_ADMINISTRATOR_NAME, szName, 80);
1152     SampLoadString(hInstance, IDS_USER_ADMINISTRATOR_COMMENT, szComment, 256);
1153 
1154     SampSetupCreateUserAccount(hAccountDomainKey,
1155                                szName,
1156                                szComment,
1157                                AccountDomainInfo->DomainSid,
1158                                DOMAIN_USER_RID_ADMIN,
1159                                USER_DONT_EXPIRE_PASSWORD | USER_NORMAL_ACCOUNT);
1160 
1161     /* Add the Adminitrator user to the Administrators alias */
1162     SampSetupAddMemberToGroup(hAccountDomainKey,
1163                               DOMAIN_GROUP_RID_USERS,
1164                               DOMAIN_USER_RID_ADMIN);
1165 
1166     /* Create the Guest user */
1167     SampLoadString(hInstance, IDS_USER_GUEST_NAME, szName, 80);
1168     SampLoadString(hInstance, IDS_USER_GUEST_COMMENT, szComment, 256);
1169 
1170     SampSetupCreateUserAccount(hAccountDomainKey,
1171                                szName,
1172                                szComment,
1173                                AccountDomainInfo->DomainSid,
1174                                DOMAIN_USER_RID_GUEST,
1175                                USER_ACCOUNT_DISABLED | USER_DONT_EXPIRE_PASSWORD | USER_NORMAL_ACCOUNT);
1176 
1177     /* Add the Guest user to the Guests alias */
1178     SampSetupAddMemberToGroup(hAccountDomainKey,
1179                               DOMAIN_GROUP_RID_USERS,
1180                               DOMAIN_USER_RID_GUEST);
1181 
1182 done:
1183     if (AccountDomainInfo)
1184         LsaFreeMemory(AccountDomainInfo);
1185 
1186     if (pAuthenticatedUserSid)
1187         RtlFreeHeap(RtlGetProcessHeap(), 0, pAuthenticatedUserSid);
1188 
1189     if (pInteractiveSid)
1190         RtlFreeHeap(RtlGetProcessHeap(), 0, pInteractiveSid);
1191 
1192     if (pBuiltinSid)
1193         RtlFreeHeap(RtlGetProcessHeap(), 0, pBuiltinSid);
1194 
1195     SampRegCloseKey(&hAccountDomainKey);
1196     SampRegCloseKey(&hBuiltinDomainKey);
1197     SampRegCloseKey(&hServerKey);
1198     SampRegCloseKey(&hSamKey);
1199 
1200     TRACE("SampInitializeSAM() done\n");
1201 
1202     return bResult;
1203 }
1204