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
7 * PROGRAMMERS: Eric Kohl
10 /* INCLUDES ****************************************************************/
14 WINE_DEFAULT_DEBUG_CHANNEL(samsrv
);
17 /* GLOBALS *****************************************************************/
19 #define TICKS_PER_SECOND 10000000LL
21 SID_IDENTIFIER_AUTHORITY SecurityNtAuthority
= {SECURITY_NT_AUTHORITY
};
24 /* FUNCTIONS ***************************************************************/
27 SampIsSetupRunning(VOID
)
35 TRACE("SampIsSetupRunning()\n");
38 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
43 if (dwError
!= ERROR_SUCCESS
)
47 dwSize
= sizeof(DWORD
);
48 dwError
= RegQueryValueExW(hKey
,
55 /* Close key, and check if returned values are correct */
57 if (dwError
!= ERROR_SUCCESS
|| dwType
!= REG_DWORD
|| dwSize
!= sizeof(DWORD
))
60 TRACE("SampIsSetupRunning() returns %s\n", (dwSetupType
!= 0) ? "TRUE" : "FALSE");
61 return (dwSetupType
!= 0);
66 AppendRidToSid(PSID SrcSid
,
69 ULONG Rids
[8] = {0, 0, 0, 0, 0, 0, 0, 0};
74 RidCount
= *RtlSubAuthorityCountSid(SrcSid
);
78 for (i
= 0; i
< RidCount
; i
++)
79 Rids
[i
] = *RtlSubAuthoritySid(SrcSid
, i
);
84 RtlAllocateAndInitializeSid(RtlIdentifierAuthoritySid(SrcSid
),
101 SampAddMemberToAlias(HKEY hDomainKey
,
106 LPWSTR MemberSidString
= NULL
;
107 WCHAR szKeyName
[256];
110 ConvertSidToStringSidW(MemberSid
, &MemberSidString
);
112 swprintf(szKeyName
, L
"Aliases\\%08lX\\Members", AliasId
);
114 if (!RegCreateKeyExW(hDomainKey
,
118 REG_OPTION_NON_VOLATILE
,
124 RegSetValueEx(hMembersKey
,
129 RtlLengthSid(MemberSid
));
131 RegCloseKey(hMembersKey
);
134 swprintf(szKeyName
, L
"Aliases\\Members\\%s", MemberSidString
);
136 if (!RegCreateKeyExW(hDomainKey
,
140 REG_OPTION_NON_VOLATILE
,
146 swprintf(szKeyName
, L
"%08lX", AliasId
);
148 RegSetValueEx(hMembersKey
,
153 RtlLengthSid(MemberSid
));
155 RegCloseKey(hMembersKey
);
158 if (MemberSidString
!= NULL
)
159 LocalFree(MemberSidString
);
166 SampCreateAliasAccount(HKEY hDomainKey
,
167 LPCWSTR lpAccountName
,
168 LPCWSTR lpDescription
,
172 WCHAR szAccountKeyName
[32];
173 HKEY hAccountKey
= NULL
;
174 HKEY hNamesKey
= NULL
;
176 swprintf(szAccountKeyName
, L
"Aliases\\%08lX", ulRelativeId
);
178 if (!RegCreateKeyExW(hDomainKey
,
182 REG_OPTION_NON_VOLATILE
,
188 RegSetValueEx(hAccountKey
,
192 (LPVOID
)lpAccountName
,
193 (wcslen(lpAccountName
) + 1) * sizeof(WCHAR
));
195 RegSetValueEx(hAccountKey
,
199 (LPVOID
)lpDescription
,
200 (wcslen(lpDescription
) + 1) * sizeof(WCHAR
));
202 RegCloseKey(hAccountKey
);
205 if (!RegOpenKeyExW(hDomainKey
,
211 RegSetValueEx(hNamesKey
,
215 (LPVOID
)&ulRelativeId
,
218 RegCloseKey(hNamesKey
);
226 SampCreateUserAccount(HKEY hDomainKey
,
227 LPCWSTR lpAccountName
,
229 ULONG UserAccountControl
)
231 SAM_USER_FIXED_DATA FixedUserData
;
232 LPWSTR lpEmptyString
= L
"";
234 WCHAR szAccountKeyName
[32];
235 HKEY hAccountKey
= NULL
;
236 HKEY hNamesKey
= NULL
;
238 /* Initialize fixed user data */
239 FixedUserData
.Version
= 1;
240 FixedUserData
.Reserved
= 0;
241 FixedUserData
.LastLogon
.QuadPart
= 0;
242 FixedUserData
.LastLogoff
.QuadPart
= 0;
243 FixedUserData
.PasswordLastSet
.QuadPart
= 0;
244 FixedUserData
.AccountExpires
.LowPart
= MAXULONG
;
245 FixedUserData
.AccountExpires
.HighPart
= MAXLONG
;
246 FixedUserData
.LastBadPasswordTime
.QuadPart
= 0;
247 FixedUserData
.UserId
= ulRelativeId
;
248 FixedUserData
.PrimaryGroupId
= DOMAIN_GROUP_RID_USERS
;
249 FixedUserData
.UserAccountControl
= UserAccountControl
;
250 FixedUserData
.CountryCode
= 0;
251 FixedUserData
.CodePage
= 0;
252 FixedUserData
.BadPasswordCount
= 0;
253 FixedUserData
.LogonCount
= 0;
254 FixedUserData
.AdminCount
= 0;
255 FixedUserData
.OperatorCount
= 0;
257 swprintf(szAccountKeyName
, L
"Users\\%08lX", ulRelativeId
);
259 if (!RegCreateKeyExW(hDomainKey
,
263 REG_OPTION_NON_VOLATILE
,
269 RegSetValueEx(hAccountKey
,
273 (LPVOID
)&FixedUserData
,
274 sizeof(SAM_USER_FIXED_DATA
));
276 RegSetValueEx(hAccountKey
,
280 (LPVOID
)lpAccountName
,
281 (wcslen(lpAccountName
) + 1) * sizeof(WCHAR
));
283 RegSetValueEx(hAccountKey
,
287 (LPVOID
)lpEmptyString
,
290 RegSetValueEx(hAccountKey
,
294 (LPVOID
)lpEmptyString
,
297 RegSetValueEx(hAccountKey
,
298 L
"HomeDirectoryDrive",
301 (LPVOID
)lpEmptyString
,
304 RegSetValueEx(hAccountKey
,
308 (LPVOID
)lpEmptyString
,
311 RegSetValueEx(hAccountKey
,
315 (LPVOID
)lpEmptyString
,
318 RegSetValueEx(hAccountKey
,
322 (LPVOID
)lpEmptyString
,
325 RegSetValueEx(hAccountKey
,
329 (LPVOID
)lpEmptyString
,
332 RegSetValueEx(hAccountKey
,
336 (LPVOID
)lpEmptyString
,
339 RegSetValueEx(hAccountKey
,
343 (LPVOID
)lpEmptyString
,
346 /* FIXME: Set LogonHours attribute*/
347 /* FIXME: Set Groups attribute*/
349 /* Set LMPwd attribute*/
350 RegSetValueEx(hAccountKey
,
357 /* Set NTPwd attribute*/
358 RegSetValueEx(hAccountKey
,
365 /* Set LMPwdHistory attribute*/
366 RegSetValueEx(hAccountKey
,
373 /* Set NTPwdHistory attribute*/
374 RegSetValueEx(hAccountKey
,
381 /* FIXME: Set SecDesc attribute*/
383 RegCloseKey(hAccountKey
);
386 if (!RegOpenKeyExW(hDomainKey
,
392 RegSetValueEx(hNamesKey
,
396 (LPVOID
)&ulRelativeId
,
399 RegCloseKey(hNamesKey
);
407 SampCreateDomain(IN HKEY hDomainsKey
,
408 IN LPCWSTR lpKeyName
,
409 IN LPCWSTR lpDomainName
,
411 OUT PHKEY lpDomainKey
)
413 SAM_DOMAIN_FIXED_DATA FixedData
;
414 LPWSTR lpEmptyString
= L
"";
416 HKEY hDomainKey
= NULL
;
417 HKEY hAliasesKey
= NULL
;
418 HKEY hGroupsKey
= NULL
;
419 HKEY hUsersKey
= NULL
;
420 HKEY hNamesKey
= NULL
;
422 if (lpDomainKey
!= NULL
)
425 /* Initialize the fixed domain data */
426 memset(&FixedData
, 0, sizeof(SAM_DOMAIN_FIXED_DATA
));
427 FixedData
.Version
= 1;
428 NtQuerySystemTime(&FixedData
.CreationTime
);
429 FixedData
.DomainModifiedCount
.QuadPart
= 0;
430 FixedData
.MaxPasswordAge
.QuadPart
= -(6LL * 7LL * 24LL * 60LL * 60LL * TICKS_PER_SECOND
); /* 6 weeks */
431 FixedData
.MinPasswordAge
.QuadPart
= 0; /* right now */
432 // FixedData.ForceLogoff.QuadPart = // very far in the future aka never
433 FixedData
.LockoutDuration
.QuadPart
= -(30LL * 60LL * TICKS_PER_SECOND
); /* 30 minutes */
434 FixedData
.LockoutObservationWindow
.QuadPart
= -(30LL * 60LL * TICKS_PER_SECOND
); /* 30 minutes */
435 FixedData
.ModifiedCountAtLastPromotion
.QuadPart
= 0;
436 FixedData
.NextRid
= 1000;
437 FixedData
.PasswordProperties
= 0;
438 FixedData
.MinPasswordLength
= 0;
439 FixedData
.PasswordHistoryLength
= 0;
440 FixedData
.LockoutThreshold
= 0;
441 FixedData
.DomainServerState
= DomainServerEnabled
;
442 FixedData
.DomainServerRole
= DomainServerRolePrimary
;
443 FixedData
.UasCompatibilityRequired
= TRUE
;
445 if (RegCreateKeyExW(hDomainsKey
,
449 REG_OPTION_NON_VOLATILE
,
456 /* Set the fixed data value */
457 if (RegSetValueEx(hDomainKey
,
462 sizeof(SAM_DOMAIN_FIXED_DATA
)))
465 if (lpDomainSid
!= NULL
)
467 RegSetValueEx(hDomainKey
,
471 (LPVOID
)lpDomainName
,
472 (wcslen(lpDomainName
) + 1) * sizeof(WCHAR
));
474 RegSetValueEx(hDomainKey
,
479 RtlLengthSid(lpDomainSid
));
482 RegSetValueEx(hDomainKey
,
486 (LPVOID
)lpEmptyString
,
489 RegSetValueEx(hDomainKey
,
490 L
"ReplicaSourceNodeName",
493 (LPVOID
)lpEmptyString
,
496 /* Create the Alias container */
497 if (!RegCreateKeyExW(hDomainKey
,
501 REG_OPTION_NON_VOLATILE
,
507 if (!RegCreateKeyExW(hAliasesKey
,
511 REG_OPTION_NON_VOLATILE
,
516 RegCloseKey(hNamesKey
);
518 RegCloseKey(hAliasesKey
);
521 /* Create the Groups container */
522 if (!RegCreateKeyExW(hDomainKey
,
526 REG_OPTION_NON_VOLATILE
,
532 if (!RegCreateKeyExW(hGroupsKey
,
536 REG_OPTION_NON_VOLATILE
,
541 RegCloseKey(hNamesKey
);
543 RegCloseKey(hGroupsKey
);
547 /* Create the Users container */
548 if (!RegCreateKeyExW(hDomainKey
,
552 REG_OPTION_NON_VOLATILE
,
558 if (!RegCreateKeyExW(hUsersKey
,
562 REG_OPTION_NON_VOLATILE
,
567 RegCloseKey(hNamesKey
);
569 RegCloseKey(hUsersKey
);
572 if (lpDomainKey
!= NULL
)
573 *lpDomainKey
= hDomainKey
;
580 SampGetAccountDomainInfo(PPOLICY_ACCOUNT_DOMAIN_INFO
*AccountDomainInfo
)
582 LSA_OBJECT_ATTRIBUTES ObjectAttributes
;
583 LSA_HANDLE PolicyHandle
;
586 TRACE("SampGetAccountDomainInfo\n");
588 memset(&ObjectAttributes
, 0, sizeof(LSA_OBJECT_ATTRIBUTES
));
589 ObjectAttributes
.Length
= sizeof(LSA_OBJECT_ATTRIBUTES
);
591 Status
= LsaOpenPolicy(NULL
,
593 POLICY_VIEW_LOCAL_INFORMATION
,
595 if (Status
!= STATUS_SUCCESS
)
597 ERR("LsaOpenPolicy failed (Status: 0x%08lx)\n", Status
);
601 Status
= LsaQueryInformationPolicy(PolicyHandle
,
602 PolicyAccountDomainInformation
,
603 (PVOID
*)AccountDomainInfo
);
605 LsaClose(PolicyHandle
);
612 SampInitializeSAM(VOID
)
614 PPOLICY_ACCOUNT_DOMAIN_INFO AccountDomainInfo
= NULL
;
617 HKEY hDomainsKey
= NULL
;
618 HKEY hDomainKey
= NULL
;
619 PSID pBuiltinSid
= NULL
;
624 TRACE("SampInitializeSAM() called\n");
626 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE
,
630 REG_OPTION_NON_VOLATILE
,
636 ERR("Failed to create 'Sam' key! (Error %lu)\n", GetLastError());
640 if (RegCreateKeyExW(hSamKey
,
644 REG_OPTION_NON_VOLATILE
,
650 ERR("Failed to create 'Domains' key! (Error %lu)\n", GetLastError());
655 RegCloseKey(hSamKey
);
658 /* Create and initialize the Builtin Domain SID */
659 pBuiltinSid
= RtlAllocateHeap(RtlGetProcessHeap(), 0, RtlLengthRequiredSid(1));
660 if (pBuiltinSid
== NULL
)
662 ERR("Failed to alloacte the Builtin Domain SID\n");
667 RtlInitializeSid(pBuiltinSid
, &SecurityNtAuthority
, 1);
668 *(RtlSubAuthoritySid(pBuiltinSid
, 0)) = SECURITY_BUILTIN_DOMAIN_RID
;
670 /* Get account domain information */
671 Status
= SampGetAccountDomainInfo(&AccountDomainInfo
);
672 if (!NT_SUCCESS(Status
))
674 ERR("SampGetAccountDomainInfo failed (Status %08lx)\n", Status
);
679 /* Create the Builtin domain */
680 if (SampCreateDomain(hDomainsKey
,
686 SampCreateAliasAccount(hDomainKey
,
688 L
"Testabc1234567890",
689 DOMAIN_ALIAS_RID_ADMINS
);
691 SampCreateAliasAccount(hDomainKey
,
694 DOMAIN_ALIAS_RID_USERS
);
696 SampCreateAliasAccount(hDomainKey
,
699 DOMAIN_ALIAS_RID_GUESTS
);
701 SampCreateAliasAccount(hDomainKey
,
703 L
"Power Users Group",
704 DOMAIN_ALIAS_RID_POWER_USERS
);
707 pSid
= AppendRidToSid(AccountDomainInfo
->DomainSid
,
708 DOMAIN_USER_RID_ADMIN
);
711 SampAddMemberToAlias(hDomainKey
,
712 DOMAIN_ALIAS_RID_ADMINS
,
715 RtlFreeHeap(RtlGetProcessHeap(), 0, pSid
);
719 RegCloseKey(hDomainKey
);
722 /* Create the Account domain */
723 if (SampCreateDomain(hDomainsKey
,
726 AccountDomainInfo
->DomainSid
,
729 SampCreateUserAccount(hDomainKey
,
731 DOMAIN_USER_RID_ADMIN
,
732 USER_DONT_EXPIRE_PASSWORD
| USER_NORMAL_ACCOUNT
);
734 SampCreateUserAccount(hDomainKey
,
736 DOMAIN_USER_RID_GUEST
,
737 USER_ACCOUNT_DISABLED
| USER_DONT_EXPIRE_PASSWORD
| USER_NORMAL_ACCOUNT
);
739 RegCloseKey(hDomainKey
);
743 if (AccountDomainInfo
)
744 LsaFreeMemory(AccountDomainInfo
);
747 RtlFreeHeap(RtlGetProcessHeap(), 0, pBuiltinSid
);
750 RegCloseKey(hDomainsKey
);
753 RegCloseKey(hSamKey
);
755 TRACE("SampInitializeSAM() done\n");