xref: /reactos/dll/win32/samsrv/setup.c (revision 321bcc05)
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.LowPart = MAXULONG;
393     FixedUserData.AccountExpires.HighPart = MAXLONG;
394     FixedUserData.LastBadPasswordTime.QuadPart = 0;
395     FixedUserData.UserId = ulRelativeId;
396     FixedUserData.PrimaryGroupId = DOMAIN_GROUP_RID_USERS;
397     FixedUserData.UserAccountControl = UserAccountControl;
398     FixedUserData.CountryCode = 0;
399     FixedUserData.CodePage = 0;
400     FixedUserData.BadPasswordCount = 0;
401     FixedUserData.LogonCount = 0;
402     FixedUserData.AdminCount = 0;
403     FixedUserData.OperatorCount = 0;
404 
405     swprintf(szAccountKeyName, L"Users\\%08lX", ulRelativeId);
406 
407     Status = SampRegCreateKey(hDomainKey,
408                               szAccountKeyName,
409                               KEY_ALL_ACCESS,
410                               &hAccountKey);
411     if (!NT_SUCCESS(Status))
412         return Status;
413 
414     Status = SampRegSetValue(hAccountKey,
415                              L"F",
416                              REG_BINARY,
417                              (LPVOID)&FixedUserData,
418                              sizeof(SAM_USER_FIXED_DATA));
419     if (!NT_SUCCESS(Status))
420         goto done;
421 
422     Status = SampRegSetValue(hAccountKey,
423                              L"Name",
424                              REG_SZ,
425                              (LPVOID)lpAccountName,
426                              (wcslen(lpAccountName) + 1) * sizeof(WCHAR));
427     if (!NT_SUCCESS(Status))
428         goto done;
429 
430     Status = SampRegSetValue(hAccountKey,
431                              L"FullName",
432                              REG_SZ,
433                              (LPVOID)lpEmptyString,
434                              sizeof(WCHAR));
435     if (!NT_SUCCESS(Status))
436         goto done;
437 
438     Status = SampRegSetValue(hAccountKey,
439                              L"HomeDirectory",
440                              REG_SZ,
441                              (LPVOID)lpEmptyString,
442                              sizeof(WCHAR));
443     if (!NT_SUCCESS(Status))
444         goto done;
445 
446     Status = SampRegSetValue(hAccountKey,
447                              L"HomeDirectoryDrive",
448                              REG_SZ,
449                              (LPVOID)lpEmptyString,
450                              sizeof(WCHAR));
451     if (!NT_SUCCESS(Status))
452         goto done;
453 
454     Status = SampRegSetValue(hAccountKey,
455                              L"ScriptPath",
456                              REG_SZ,
457                              (LPVOID)lpEmptyString,
458                              sizeof(WCHAR));
459     if (!NT_SUCCESS(Status))
460         goto done;
461 
462     Status = SampRegSetValue(hAccountKey,
463                              L"ProfilePath",
464                              REG_SZ,
465                              (LPVOID)lpEmptyString,
466                              sizeof(WCHAR));
467     if (!NT_SUCCESS(Status))
468         goto done;
469 
470     Status = SampRegSetValue(hAccountKey,
471                              L"AdminComment",
472                              REG_SZ,
473                              (LPVOID)lpComment,
474                              (wcslen(lpComment) + 1) * sizeof(WCHAR));
475     if (!NT_SUCCESS(Status))
476         goto done;
477 
478     Status = SampRegSetValue(hAccountKey,
479                              L"UserComment",
480                              REG_SZ,
481                              (LPVOID)lpEmptyString,
482                              sizeof(WCHAR));
483     if (!NT_SUCCESS(Status))
484         goto done;
485 
486     Status = SampRegSetValue(hAccountKey,
487                              L"WorkStations",
488                              REG_SZ,
489                              (LPVOID)lpEmptyString,
490                              sizeof(WCHAR));
491     if (!NT_SUCCESS(Status))
492         goto done;
493 
494     Status = SampRegSetValue(hAccountKey,
495                              L"Parameters",
496                              REG_SZ,
497                              (LPVOID)lpEmptyString,
498                              sizeof(WCHAR));
499     if (!NT_SUCCESS(Status))
500         goto done;
501 
502     /* Set LogonHours attribute*/
503     *((PUSHORT)LogonHours) = 168;
504     memset(&(LogonHours[2]), 0xff, 21);
505 
506     Status = SampRegSetValue(hAccountKey,
507                              L"LogonHours",
508                              REG_BINARY,
509                              (LPVOID)LogonHours,
510                              sizeof(LogonHours));
511     if (!NT_SUCCESS(Status))
512         goto done;
513 
514     /* Set Groups attribute*/
515     GroupMembership.RelativeId = DOMAIN_GROUP_RID_USERS;
516     GroupMembership.Attributes = SE_GROUP_MANDATORY |
517                                  SE_GROUP_ENABLED |
518                                  SE_GROUP_ENABLED_BY_DEFAULT;
519 
520     Status = SampRegSetValue(hAccountKey,
521                              L"Groups",
522                              REG_BINARY,
523                              (LPVOID)&GroupMembership,
524                              sizeof(GROUP_MEMBERSHIP));
525     if (!NT_SUCCESS(Status))
526         goto done;
527 
528     /* Set LMPwd attribute*/
529     Status = SampRegSetValue(hAccountKey,
530                              L"LMPwd",
531                              REG_BINARY,
532                              (LPVOID)&EmptyLmHash,
533                              sizeof(ENCRYPTED_LM_OWF_PASSWORD));
534     if (!NT_SUCCESS(Status))
535         goto done;
536 
537     /* Set NTPwd attribute*/
538     Status = SampRegSetValue(hAccountKey,
539                              L"NTPwd",
540                              REG_BINARY,
541                              (LPVOID)&EmptyNtHash,
542                              sizeof(ENCRYPTED_NT_OWF_PASSWORD));
543     if (!NT_SUCCESS(Status))
544         goto done;
545 
546     /* Set LMPwdHistory attribute*/
547     Status = SampRegSetValue(hAccountKey,
548                              L"LMPwdHistory",
549                              REG_BINARY,
550                              NULL,
551                              0);
552     if (!NT_SUCCESS(Status))
553         goto done;
554 
555     /* Set NTPwdHistory attribute*/
556     Status = SampRegSetValue(hAccountKey,
557                              L"NTPwdHistory",
558                              REG_BINARY,
559                              NULL,
560                              0);
561     if (!NT_SUCCESS(Status))
562         goto done;
563 
564     /* Set PrivateData attribute*/
565     Status = SampRegSetValue(hAccountKey,
566                              L"PrivateData",
567                              REG_SZ,
568                              (LPVOID)lpEmptyString,
569                              sizeof(WCHAR));
570     if (!NT_SUCCESS(Status))
571         goto done;
572 
573     /* Set the SecDesc attribute*/
574     Status = SampRegSetValue(hAccountKey,
575                              L"SecDesc",
576                              REG_BINARY,
577                              Sd,
578                              SdSize);
579     if (!NT_SUCCESS(Status))
580         goto done;
581 
582     Status = SampRegOpenKey(hDomainKey,
583                             L"Users\\Names",
584                             KEY_ALL_ACCESS,
585                             &hNamesKey);
586     if (!NT_SUCCESS(Status))
587         goto done;
588 
589     Status = SampRegSetValue(hNamesKey,
590                             lpAccountName,
591                             REG_DWORD,
592                             (LPVOID)&ulRelativeId,
593                             sizeof(ULONG));
594 
595 done:
596     SampRegCloseKey(&hNamesKey);
597 
598     if (Sd != NULL)
599         RtlFreeHeap(RtlGetProcessHeap(), 0, Sd);
600 
601     if (UserSid != NULL)
602         RtlFreeHeap(RtlGetProcessHeap(), 0, UserSid);
603 
604     if (hAccountKey != NULL)
605     {
606         SampRegCloseKey(&hAccountKey);
607 
608         if (!NT_SUCCESS(Status))
609             SampRegDeleteKey(hDomainKey,
610                              szAccountKeyName);
611     }
612 
613     return Status;
614 }
615 
616 
617 static
618 NTSTATUS
619 SampSetupCreateDomain(IN HANDLE hServerKey,
620                       IN LPCWSTR lpKeyName,
621                       IN LPCWSTR lpDomainName,
622                       IN PSID lpDomainSid,
623                       IN BOOLEAN bBuiltinDomain,
624                       OUT HANDLE *lpDomainKey)
625 {
626     SAM_DOMAIN_FIXED_DATA FixedData;
627     WCHAR szDomainKeyName[32];
628     LPWSTR lpEmptyString = L"";
629     HANDLE hDomainKey = NULL;
630     HANDLE hAliasesKey = NULL;
631     HANDLE hGroupsKey = NULL;
632     HANDLE hUsersKey = NULL;
633     HANDLE hNamesKey = NULL;
634     PSECURITY_DESCRIPTOR Sd = NULL;
635     ULONG SdSize = 0;
636     NTSTATUS Status;
637 
638     if (lpDomainKey != NULL)
639         *lpDomainKey = NULL;
640 
641     /* Initialize the fixed domain data */
642     memset(&FixedData, 0, sizeof(SAM_DOMAIN_FIXED_DATA));
643     FixedData.Version = 1;
644     NtQuerySystemTime(&FixedData.CreationTime);
645     FixedData.DomainModifiedCount.QuadPart = 0;
646     FixedData.MaxPasswordAge.QuadPart = -(6LL * 7LL * 24LL * 60LL * 60LL * TICKS_PER_SECOND); /* 6 weeks */
647     FixedData.MinPasswordAge.QuadPart = 0;                                                    /* right now */
648     FixedData.ForceLogoff.QuadPart = LLONG_MAX;                                               /* very far in the future aka never */
649     FixedData.LockoutDuration.QuadPart = -(30LL * 60LL * TICKS_PER_SECOND);                   /* 30 minutes */
650     FixedData.LockoutObservationWindow.QuadPart = -(30LL * 60LL * TICKS_PER_SECOND);          /* 30 minutes */
651     FixedData.ModifiedCountAtLastPromotion.QuadPart = 0;
652     FixedData.NextRid = 1000;
653     FixedData.PasswordProperties = 0;
654     FixedData.MinPasswordLength = 0;
655     FixedData.PasswordHistoryLength = 0;
656     FixedData.LockoutThreshold = 0;
657     FixedData.DomainServerState = DomainServerEnabled;
658     FixedData.DomainServerRole = DomainServerRolePrimary;
659     FixedData.UasCompatibilityRequired = TRUE;
660 
661     wcscpy(szDomainKeyName, L"Domains\\");
662     wcscat(szDomainKeyName, lpKeyName);
663 
664     Status = SampRegCreateKey(hServerKey,
665                               szDomainKeyName,
666                               KEY_ALL_ACCESS,
667                               &hDomainKey);
668     if (!NT_SUCCESS(Status))
669         return Status;
670 
671     /* Set the fixed data value */
672     Status = SampRegSetValue(hDomainKey,
673                              L"F",
674                              REG_BINARY,
675                              (LPVOID)&FixedData,
676                              sizeof(SAM_DOMAIN_FIXED_DATA));
677     if (!NT_SUCCESS(Status))
678         goto done;
679 
680     if (lpDomainSid != NULL)
681     {
682         Status = SampRegSetValue(hDomainKey,
683                                  L"Name",
684                                  REG_SZ,
685                                  (LPVOID)lpDomainName,
686                                  (wcslen(lpDomainName) + 1) * sizeof(WCHAR));
687         if (!NT_SUCCESS(Status))
688             goto done;
689 
690         Status = SampRegSetValue(hDomainKey,
691                                  L"SID",
692                                  REG_BINARY,
693                                  (LPVOID)lpDomainSid,
694                                  RtlLengthSid(lpDomainSid));
695         if (!NT_SUCCESS(Status))
696             goto done;
697     }
698 
699     Status = SampRegSetValue(hDomainKey,
700                              L"OemInformation",
701                              REG_SZ,
702                              (LPVOID)lpEmptyString,
703                              sizeof(WCHAR));
704     if (!NT_SUCCESS(Status))
705         goto done;
706 
707     Status = SampRegSetValue(hDomainKey,
708                              L"ReplicaSourceNodeName",
709                              REG_SZ,
710                              (LPVOID)lpEmptyString,
711                              sizeof(WCHAR));
712     if (!NT_SUCCESS(Status))
713         goto done;
714 
715     /* Create the Alias container */
716     Status = SampRegCreateKey(hDomainKey,
717                               L"Aliases",
718                               KEY_ALL_ACCESS,
719                               &hAliasesKey);
720     if (!NT_SUCCESS(Status))
721         goto done;
722 
723     Status = SampRegCreateKey(hAliasesKey,
724                               L"Names",
725                               KEY_ALL_ACCESS,
726                               &hNamesKey);
727     if (!NT_SUCCESS(Status))
728         goto done;
729 
730     SampRegCloseKey(&hNamesKey);
731 
732     /* Create the Groups container */
733     Status = SampRegCreateKey(hDomainKey,
734                               L"Groups",
735                               KEY_ALL_ACCESS,
736                               &hGroupsKey);
737     if (!NT_SUCCESS(Status))
738         goto done;
739 
740     Status = SampRegCreateKey(hGroupsKey,
741                               L"Names",
742                               KEY_ALL_ACCESS,
743                               &hNamesKey);
744     if (!NT_SUCCESS(Status))
745         goto done;
746 
747     SampRegCloseKey(&hNamesKey);
748 
749     /* Create the Users container */
750     Status = SampRegCreateKey(hDomainKey,
751                               L"Users",
752                               KEY_ALL_ACCESS,
753                               &hUsersKey);
754     if (!NT_SUCCESS(Status))
755         goto done;
756 
757     Status = SampRegCreateKey(hUsersKey,
758                               L"Names",
759                               KEY_ALL_ACCESS,
760                               &hNamesKey);
761     if (!NT_SUCCESS(Status))
762         goto done;
763 
764     /* Create the server SD */
765     if (bBuiltinDomain == TRUE)
766         Status = SampCreateBuiltinDomainSD(&Sd,
767                                            &SdSize);
768     else
769         Status = SampCreateAccountDomainSD(&Sd,
770                                            &SdSize);
771 
772     if (!NT_SUCCESS(Status))
773         goto done;
774 
775     /* Set SecDesc attribute*/
776     Status = SampRegSetValue(hServerKey,
777                              L"SecDesc",
778                              REG_BINARY,
779                              Sd,
780                              SdSize);
781     if (!NT_SUCCESS(Status))
782         goto done;
783 
784     SampRegCloseKey(&hNamesKey);
785 
786     if (lpDomainKey != NULL)
787         *lpDomainKey = hDomainKey;
788 
789 done:
790     if (Sd != NULL)
791         RtlFreeHeap(RtlGetProcessHeap(), 0, Sd);
792 
793     SampRegCloseKey(&hAliasesKey);
794     SampRegCloseKey(&hGroupsKey);
795     SampRegCloseKey(&hUsersKey);
796 
797     if (!NT_SUCCESS(Status))
798         SampRegCloseKey(&hDomainKey);
799 
800     return Status;
801 }
802 
803 
804 static
805 NTSTATUS
806 SampSetupCreateServer(IN HANDLE hSamKey,
807                       OUT HANDLE *lpServerKey)
808 {
809     HANDLE hServerKey = NULL;
810     HANDLE hDomainsKey = NULL;
811     PSECURITY_DESCRIPTOR Sd = NULL;
812     ULONG SdSize = 0;
813     NTSTATUS Status;
814 
815     Status = SampRegCreateKey(hSamKey,
816                               L"SAM",
817                               KEY_ALL_ACCESS,
818                               &hServerKey);
819     if (!NT_SUCCESS(Status))
820         return Status;
821 
822     Status = SampRegCreateKey(hServerKey,
823                               L"Domains",
824                               KEY_ALL_ACCESS,
825                               &hDomainsKey);
826     if (!NT_SUCCESS(Status))
827         goto done;
828 
829     /* Create the server SD */
830     Status = SampCreateServerSD(&Sd,
831                                 &SdSize);
832     if (!NT_SUCCESS(Status))
833         goto done;
834 
835     /* Set SecDesc attribute*/
836     Status = SampRegSetValue(hServerKey,
837                              L"SecDesc",
838                              REG_BINARY,
839                              Sd,
840                              SdSize);
841     if (!NT_SUCCESS(Status))
842         goto done;
843 
844     SampRegCloseKey(&hDomainsKey);
845 
846     *lpServerKey = hServerKey;
847 
848 done:
849     if (Sd != NULL)
850         RtlFreeHeap(RtlGetProcessHeap(), 0, Sd);
851 
852     return Status;
853 }
854 
855 
856 NTSTATUS
857 SampGetAccountDomainInfo(PPOLICY_ACCOUNT_DOMAIN_INFO *AccountDomainInfo)
858 {
859     LSA_OBJECT_ATTRIBUTES ObjectAttributes;
860     LSA_HANDLE PolicyHandle;
861     NTSTATUS Status;
862 
863     TRACE("SampGetAccountDomainInfo\n");
864 
865     memset(&ObjectAttributes, 0, sizeof(LSA_OBJECT_ATTRIBUTES));
866     ObjectAttributes.Length = sizeof(LSA_OBJECT_ATTRIBUTES);
867 
868     Status = LsaOpenPolicy(NULL,
869                            &ObjectAttributes,
870                            POLICY_VIEW_LOCAL_INFORMATION,
871                            &PolicyHandle);
872     if (Status != STATUS_SUCCESS)
873     {
874         ERR("LsaOpenPolicy failed (Status: 0x%08lx)\n", Status);
875         return Status;
876     }
877 
878     Status = LsaQueryInformationPolicy(PolicyHandle,
879                                        PolicyAccountDomainInformation,
880                                        (PVOID *)AccountDomainInfo);
881 
882     LsaClose(PolicyHandle);
883 
884     return Status;
885 }
886 
887 
888 BOOL
889 SampInitializeSAM(VOID)
890 {
891     PPOLICY_ACCOUNT_DOMAIN_INFO AccountDomainInfo = NULL;
892     HANDLE hSamKey = NULL;
893     HANDLE hServerKey = NULL;
894     HANDLE hBuiltinDomainKey = NULL;
895     HANDLE hAccountDomainKey = NULL;
896     PSID pBuiltinSid = NULL;
897     PSID pInteractiveSid = NULL;
898     PSID pAuthenticatedUserSid = NULL;
899     BOOL bResult = TRUE;
900     PSID pSid;
901     HINSTANCE hInstance;
902     WCHAR szComment[256];
903     WCHAR szName[80];
904     NTSTATUS Status;
905 
906     TRACE("SampInitializeSAM() called\n");
907 
908     hInstance = GetModuleHandleW(L"samsrv.dll");
909 
910     /* Open the SAM key */
911     Status = SampRegOpenKey(NULL,
912                             L"\\Registry\\Machine\\SAM",
913                             KEY_READ | KEY_CREATE_SUB_KEY | KEY_ENUMERATE_SUB_KEYS,
914                             &hSamKey);
915     if (!NT_SUCCESS(Status))
916     {
917         ERR("Failed to open the SAM key (Status: 0x%08lx)\n", Status);
918         return FALSE;
919     }
920 
921     /* Create the SAM Server object */
922     Status = SampSetupCreateServer(hSamKey,
923                                    &hServerKey);
924     if (!NT_SUCCESS(Status))
925     {
926         bResult = FALSE;
927         goto done;
928     }
929 
930     /* Create and initialize the Builtin Domain SID */
931     pBuiltinSid = RtlAllocateHeap(RtlGetProcessHeap(), 0, RtlLengthRequiredSid(1));
932     if (pBuiltinSid == NULL)
933     {
934         ERR("Failed to alloacte the Builtin Domain SID\n");
935         bResult = FALSE;
936         goto done;
937     }
938 
939     RtlInitializeSid(pBuiltinSid, &SecurityNtAuthority, 1);
940     *(RtlSubAuthoritySid(pBuiltinSid, 0)) = SECURITY_BUILTIN_DOMAIN_RID;
941 
942     /* Create and initialize the Interactive SID */
943     pInteractiveSid = RtlAllocateHeap(RtlGetProcessHeap(), 0, RtlLengthRequiredSid(1));
944     if (pInteractiveSid == NULL)
945     {
946         ERR("Failed to alloacte the Interactive SID\n");
947         bResult = FALSE;
948         goto done;
949     }
950 
951     RtlInitializeSid(pInteractiveSid, &SecurityNtAuthority, 1);
952     *(RtlSubAuthoritySid(pInteractiveSid, 0)) = SECURITY_INTERACTIVE_RID;
953 
954     /* Create and initialize the Authenticated User SID */
955     pAuthenticatedUserSid = RtlAllocateHeap(RtlGetProcessHeap(), 0, RtlLengthRequiredSid(1));
956     if (pAuthenticatedUserSid == NULL)
957     {
958         ERR("Failed to alloacte the Authenticated User SID\n");
959         bResult = FALSE;
960         goto done;
961     }
962 
963     RtlInitializeSid(pAuthenticatedUserSid, &SecurityNtAuthority, 1);
964     *(RtlSubAuthoritySid(pAuthenticatedUserSid, 0)) = SECURITY_AUTHENTICATED_USER_RID;
965 
966     /* Get account domain information */
967     Status = SampGetAccountDomainInfo(&AccountDomainInfo);
968     if (!NT_SUCCESS(Status))
969     {
970         ERR("SampGetAccountDomainInfo failed (Status %08lx)\n", Status);
971         bResult = FALSE;
972         goto done;
973     }
974 
975     SampLoadString(hInstance, IDS_DOMAIN_BUILTIN_NAME, szName, 80);
976 
977     /* Create the Builtin domain */
978     Status = SampSetupCreateDomain(hServerKey,
979                                    L"Builtin",
980                                    szName,
981                                    pBuiltinSid,
982                                    TRUE,
983                                    &hBuiltinDomainKey);
984     if (!NT_SUCCESS(Status))
985     {
986         bResult = FALSE;
987         goto done;
988     }
989 
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         SampLoadString(hInstance, IDS_ALIAS_USERS_NAME, szName, 80);
999         SampLoadString(hInstance, IDS_ALIAS_USERS_COMMENT, szComment, 256);
1000 
1001         SampSetupCreateAliasAccount(hBuiltinDomainKey,
1002                                     szName,
1003                                     szComment,
1004                                     DOMAIN_ALIAS_RID_USERS);
1005 
1006         SampLoadString(hInstance, IDS_ALIAS_GUESTS_NAME, szName, 80);
1007         SampLoadString(hInstance, IDS_ALIAS_GUESTS_COMMENT, szComment, 256);
1008 
1009         SampSetupCreateAliasAccount(hBuiltinDomainKey,
1010                                     szName,
1011                                     szComment,
1012                                     DOMAIN_ALIAS_RID_GUESTS);
1013 
1014         SampLoadString(hInstance, IDS_ALIAS_POWER_USERS_NAME, szName, 80);
1015         SampLoadString(hInstance, IDS_ALIAS_POWER_USERS_COMMENT, szComment, 256);
1016 
1017         SampSetupCreateAliasAccount(hBuiltinDomainKey,
1018                                     szName,
1019                                     szComment,
1020                                     DOMAIN_ALIAS_RID_POWER_USERS);
1021 
1022         /* Add the Administrator user to the Administrators alias */
1023         pSid = AppendRidToSid(AccountDomainInfo->DomainSid,
1024                               DOMAIN_USER_RID_ADMIN);
1025         if (pSid != NULL)
1026         {
1027             SampSetupAddMemberToAlias(hBuiltinDomainKey,
1028                                       DOMAIN_ALIAS_RID_ADMINS,
1029                                       pSid);
1030 
1031             RtlFreeHeap(RtlGetProcessHeap(), 0, pSid);
1032         }
1033 
1034         /* Add the Guest user to the Guests alias */
1035         pSid = AppendRidToSid(AccountDomainInfo->DomainSid,
1036                               DOMAIN_USER_RID_GUEST);
1037         if (pSid != NULL)
1038         {
1039             SampSetupAddMemberToAlias(hBuiltinDomainKey,
1040                                       DOMAIN_ALIAS_RID_GUESTS,
1041                                       pSid);
1042 
1043             RtlFreeHeap(RtlGetProcessHeap(), 0, pSid);
1044         }
1045 
1046     /* Add the Interactive SID to the Users alias */
1047     SampSetupAddMemberToAlias(hBuiltinDomainKey,
1048                               DOMAIN_ALIAS_RID_USERS,
1049                               pInteractiveSid);
1050 
1051     /* Add the Authenticated User SID to the Users alias */
1052     SampSetupAddMemberToAlias(hBuiltinDomainKey,
1053                               DOMAIN_ALIAS_RID_USERS,
1054                               pAuthenticatedUserSid);
1055 
1056     /* Create the Account domain */
1057     Status = SampSetupCreateDomain(hServerKey,
1058                                    L"Account",
1059                                    L"",
1060                                    AccountDomainInfo->DomainSid,
1061                                    FALSE,
1062                                    &hAccountDomainKey);
1063     if (!NT_SUCCESS(Status))
1064     {
1065         bResult = FALSE;
1066         goto done;
1067     }
1068 
1069         SampLoadString(hInstance, IDS_GROUP_NONE_NAME, szName, 80);
1070         SampLoadString(hInstance, IDS_GROUP_NONE_COMMENT, szComment, 256);
1071 
1072         SampSetupCreateGroupAccount(hAccountDomainKey,
1073                                     szName,
1074                                     szComment,
1075                                     DOMAIN_GROUP_RID_USERS);
1076 
1077         SampLoadString(hInstance, IDS_USER_ADMINISTRATOR_NAME, szName, 80);
1078         SampLoadString(hInstance, IDS_USER_ADMINISTRATOR_COMMENT, szComment, 256);
1079 
1080         SampSetupCreateUserAccount(hAccountDomainKey,
1081                                    szName,
1082                                    szComment,
1083                                    AccountDomainInfo->DomainSid,
1084                                    DOMAIN_USER_RID_ADMIN,
1085                                    USER_DONT_EXPIRE_PASSWORD | USER_NORMAL_ACCOUNT);
1086 
1087         SampSetupAddMemberToGroup(hAccountDomainKey,
1088                                   DOMAIN_GROUP_RID_USERS,
1089                                   DOMAIN_USER_RID_ADMIN);
1090 
1091         SampLoadString(hInstance, IDS_USER_GUEST_NAME, szName, 80);
1092         SampLoadString(hInstance, IDS_USER_GUEST_COMMENT, szComment, 256);
1093 
1094         SampSetupCreateUserAccount(hAccountDomainKey,
1095                                    szName,
1096                                    szComment,
1097                                    AccountDomainInfo->DomainSid,
1098                                    DOMAIN_USER_RID_GUEST,
1099                                    USER_ACCOUNT_DISABLED | USER_DONT_EXPIRE_PASSWORD | USER_NORMAL_ACCOUNT);
1100 
1101         SampSetupAddMemberToGroup(hAccountDomainKey,
1102                                   DOMAIN_GROUP_RID_USERS,
1103                                   DOMAIN_USER_RID_GUEST);
1104 
1105 done:
1106     if (AccountDomainInfo)
1107         LsaFreeMemory(AccountDomainInfo);
1108 
1109     if (pAuthenticatedUserSid)
1110         RtlFreeHeap(RtlGetProcessHeap(), 0, pAuthenticatedUserSid);
1111 
1112     if (pInteractiveSid)
1113         RtlFreeHeap(RtlGetProcessHeap(), 0, pInteractiveSid);
1114 
1115     if (pBuiltinSid)
1116         RtlFreeHeap(RtlGetProcessHeap(), 0, pBuiltinSid);
1117 
1118     SampRegCloseKey(&hAccountDomainKey);
1119     SampRegCloseKey(&hBuiltinDomainKey);
1120     SampRegCloseKey(&hServerKey);
1121     SampRegCloseKey(&hSamKey);
1122 
1123     TRACE("SampInitializeSAM() done\n");
1124 
1125     return bResult;
1126 }
1127