WINE_DEFAULT_DEBUG_CHANNEL(samsrv);
+/* GLOBALS *****************************************************************/
+
+SID_IDENTIFIER_AUTHORITY SecurityNtAuthority = {SECURITY_NT_AUTHORITY};
/* FUNCTIONS ***************************************************************/
}
-static BOOL
-CreateBuiltinAliases(HKEY hAliasesKey)
+static PSID
+AppendRidToSid(PSID SrcSid,
+ ULONG Rid)
{
- return TRUE;
+ ULONG Rids[8] = {0, 0, 0, 0, 0, 0, 0, 0};
+ UCHAR RidCount;
+ PSID DstSid;
+ ULONG i;
+
+ RidCount = *RtlSubAuthorityCountSid(SrcSid);
+ if (RidCount >= 8)
+ return NULL;
+
+ for (i = 0; i < RidCount; i++)
+ Rids[i] = *RtlSubAuthoritySid(SrcSid, i);
+
+ Rids[RidCount] = Rid;
+ RidCount++;
+
+ RtlAllocateAndInitializeSid(RtlIdentifierAuthoritySid(SrcSid),
+ RidCount,
+ Rids[0],
+ Rids[1],
+ Rids[2],
+ Rids[3],
+ Rids[4],
+ Rids[5],
+ Rids[6],
+ Rids[7],
+ &DstSid);
+
+ return DstSid;
}
static BOOL
-CreateBuiltinGroups(HKEY hGroupsKey)
+SampAddMemberToAlias(HKEY hDomainKey,
+ ULONG AliasId,
+ PSID MemberSid)
{
+ DWORD dwDisposition;
+ LPWSTR MemberSidString = NULL;
+ WCHAR szKeyName[256];
+ HKEY hMembersKey;
+
+ ConvertSidToStringSidW(MemberSid, &MemberSidString);
+
+ swprintf(szKeyName, L"Aliases\\%08lX\\Members", AliasId);
+
+ if (!RegCreateKeyExW(hDomainKey,
+ szKeyName,
+ 0,
+ NULL,
+ REG_OPTION_NON_VOLATILE,
+ KEY_ALL_ACCESS,
+ NULL,
+ &hMembersKey,
+ &dwDisposition))
+ {
+ RegSetValueEx(hMembersKey,
+ MemberSidString,
+ 0,
+ REG_BINARY,
+ (LPVOID)MemberSid,
+ RtlLengthSid(MemberSid));
+
+ RegCloseKey(hMembersKey);
+ }
+
+ swprintf(szKeyName, L"Aliases\\Members\\%s", MemberSidString);
+
+ if (!RegCreateKeyExW(hDomainKey,
+ szKeyName,
+ 0,
+ NULL,
+ REG_OPTION_NON_VOLATILE,
+ KEY_ALL_ACCESS,
+ NULL,
+ &hMembersKey,
+ &dwDisposition))
+ {
+ swprintf(szKeyName, L"%08lX", AliasId);
+
+ RegSetValueEx(hMembersKey,
+ szKeyName,
+ 0,
+ REG_BINARY,
+ (LPVOID)MemberSid,
+ RtlLengthSid(MemberSid));
+
+ RegCloseKey(hMembersKey);
+ }
+
+ if (MemberSidString != NULL)
+ LocalFree(MemberSidString);
+
return TRUE;
}
static BOOL
-CreateBuiltinUsers(HKEY hUsersKey)
+SampCreateAliasAccount(HKEY hDomainKey,
+ LPCWSTR lpAccountName,
+ LPCWSTR lpDescription,
+ ULONG ulRelativeId)
{
+ DWORD dwDisposition;
+ WCHAR szAccountKeyName[32];
+ HKEY hAccountKey = NULL;
+ HKEY hNamesKey = NULL;
+
+ swprintf(szAccountKeyName, L"Aliases\\%08lX", ulRelativeId);
+
+ if (!RegCreateKeyExW(hDomainKey,
+ szAccountKeyName,
+ 0,
+ NULL,
+ REG_OPTION_NON_VOLATILE,
+ KEY_ALL_ACCESS,
+ NULL,
+ &hAccountKey,
+ &dwDisposition))
+ {
+ RegSetValueEx(hAccountKey,
+ L"Name",
+ 0,
+ REG_SZ,
+ (LPVOID)lpAccountName,
+ (wcslen(lpAccountName) + 1) * sizeof(WCHAR));
+
+ RegSetValueEx(hAccountKey,
+ L"Description",
+ 0,
+ REG_SZ,
+ (LPVOID)lpDescription,
+ (wcslen(lpDescription) + 1) * sizeof(WCHAR));
+
+ RegCloseKey(hAccountKey);
+ }
+
+ if (!RegOpenKeyExW(hDomainKey,
+ L"Aliases\\Names",
+ 0,
+ KEY_ALL_ACCESS,
+ &hNamesKey))
+ {
+ RegSetValueEx(hNamesKey,
+ lpAccountName,
+ 0,
+ REG_DWORD,
+ (LPVOID)&ulRelativeId,
+ sizeof(ULONG));
+
+ RegCloseKey(hNamesKey);
+ }
+
return TRUE;
}
-BOOL
-SampInitializeSAM(VOID)
+static BOOL
+SampCreateUserAccount(HKEY hDomainKey,
+ LPCWSTR lpAccountName,
+ ULONG ulRelativeId)
{
+ SAM_USER_FIXED_DATA FixedUserData;
DWORD dwDisposition;
- HKEY hSamKey;
- HKEY hDomainsKey;
- HKEY hAccountKey;
- HKEY hBuiltinKey;
- HKEY hAliasesKey;
- HKEY hGroupsKey;
- HKEY hUsersKey;
-
- TRACE("SampInitializeSAM() called\n");
-
- if (RegCreateKeyExW(HKEY_LOCAL_MACHINE,
- L"SAM\\SAM",
- 0,
- NULL,
- REG_OPTION_NON_VOLATILE,
- KEY_ALL_ACCESS,
- NULL,
- &hSamKey,
- &dwDisposition))
+ WCHAR szAccountKeyName[32];
+ HKEY hAccountKey = NULL;
+ HKEY hNamesKey = NULL;
+
+ /* Initialize fixed user data */
+ memset(&FixedUserData, 0, sizeof(SAM_USER_FIXED_DATA));
+ FixedUserData.Version = 1;
+
+ FixedUserData.UserId = ulRelativeId;
+
+ swprintf(szAccountKeyName, L"Users\\%08lX", ulRelativeId);
+
+ if (!RegCreateKeyExW(hDomainKey,
+ szAccountKeyName,
+ 0,
+ NULL,
+ REG_OPTION_NON_VOLATILE,
+ KEY_ALL_ACCESS,
+ NULL,
+ &hAccountKey,
+ &dwDisposition))
{
- ERR("Failed to create 'Sam' key! (Error %lu)\n", GetLastError());
- return FALSE;
+ RegSetValueEx(hAccountKey,
+ L"F",
+ 0,
+ REG_BINARY,
+ (LPVOID)&FixedUserData,
+ sizeof(SAM_USER_FIXED_DATA));
+
+ RegSetValueEx(hAccountKey,
+ L"Name",
+ 0,
+ REG_SZ,
+ (LPVOID)lpAccountName,
+ (wcslen(lpAccountName) + 1) * sizeof(WCHAR));
+
+ RegCloseKey(hAccountKey);
}
- if (RegCreateKeyExW(hSamKey,
- L"Domains",
- 0,
- NULL,
- REG_OPTION_NON_VOLATILE,
- KEY_ALL_ACCESS,
- NULL,
- &hDomainsKey,
- &dwDisposition))
+ if (!RegOpenKeyExW(hDomainKey,
+ L"Users\\Names",
+ 0,
+ KEY_ALL_ACCESS,
+ &hNamesKey))
{
- ERR("Failed to create 'Domains' key! (Error %lu)\n", GetLastError());
- RegCloseKey(hSamKey);
- return FALSE;
+ RegSetValueEx(hNamesKey,
+ lpAccountName,
+ 0,
+ REG_DWORD,
+ (LPVOID)&ulRelativeId,
+ sizeof(ULONG));
+
+ RegCloseKey(hNamesKey);
}
- RegCloseKey (hSamKey);
+ return TRUE;
+}
+
+
+static BOOL
+SampCreateDomain(IN HKEY hDomainsKey,
+ IN LPCWSTR lpKeyName,
+ IN LPCWSTR lpDomainName,
+ IN PSID lpDomainSid,
+ OUT PHKEY lpDomainKey)
+{
+ SAM_DOMAIN_FIXED_DATA FixedData;
+ LPWSTR lpEmptyString = L"";
+ DWORD dwDisposition;
+ HKEY hDomainKey = NULL;
+ HKEY hAliasesKey = NULL;
+ HKEY hGroupsKey = NULL;
+ HKEY hUsersKey = NULL;
+ HKEY hNamesKey = NULL;
+
+ if (lpDomainKey != NULL)
+ *lpDomainKey = NULL;
+
+ /* Initialize the fixed domain data */
+ memset(&FixedData, 0, sizeof(SAM_DOMAIN_FIXED_DATA));
+ FixedData.Version = 1;
+ NtQuerySystemTime(&FixedData.CreationTime);
+ FixedData.DomainModifiedCount.QuadPart = 0;
+// FixedData.MaxPasswordAge // 6 Weeks
+ FixedData.MinPasswordAge.QuadPart = 0; // Now
+// FixedData.ForceLogoff
+// FixedData.LockoutDuration // 30 minutes
+// FixedData.LockoutObservationWindow // 30 minutes
+ FixedData.ModifiedCountAtLastPromotion.QuadPart = 0;
+ FixedData.NextRid = 1000;
+ FixedData.PasswordProperties = 0;
+ FixedData.MinPasswordLength = 0;
+ FixedData.PasswordHistoryLength = 0;
+ FixedData.LockoutThreshold = 0;
+ FixedData.DomainServerState = DomainServerEnabled;
+ FixedData.DomainServerRole = DomainServerRolePrimary;
+ FixedData.UasCompatibilityRequired = TRUE;
- /* Create the 'Domains\\Account' key */
if (RegCreateKeyExW(hDomainsKey,
- L"Account",
+ lpKeyName,
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
NULL,
- &hAccountKey,
+ &hDomainKey,
&dwDisposition))
- {
- ERR("Failed to create 'Domains\\Account' key! (Error %lu)\n", GetLastError());
- RegCloseKey(hDomainsKey);
return FALSE;
- }
+ /* Set the fixed data value */
+ if (RegSetValueEx(hDomainKey,
+ L"F",
+ 0,
+ REG_BINARY,
+ (LPVOID)&FixedData,
+ sizeof(SAM_DOMAIN_FIXED_DATA)))
+ return FALSE;
- /* Create the 'Account\Aliases' key */
- if (RegCreateKeyExW(hAccountKey,
- L"Aliases",
- 0,
- NULL,
- REG_OPTION_NON_VOLATILE,
- KEY_ALL_ACCESS,
- NULL,
- &hAliasesKey,
- &dwDisposition))
+ if (lpDomainSid != NULL)
{
- ERR("Failed to create 'Account\\Aliases' key! (Error %lu)\n", GetLastError());
- RegCloseKey(hAccountKey);
- RegCloseKey(hDomainsKey);
- return FALSE;
+ RegSetValueEx(hDomainKey,
+ L"Name",
+ 0,
+ REG_SZ,
+ (LPVOID)lpDomainName,
+ (wcslen(lpDomainName) + 1) * sizeof(WCHAR));
+
+ RegSetValueEx(hDomainKey,
+ L"SID",
+ 0,
+ REG_BINARY,
+ (LPVOID)lpDomainSid,
+ RtlLengthSid(lpDomainSid));
}
- RegCloseKey (hAliasesKey);
+ RegSetValueEx(hDomainKey,
+ L"OemInformation",
+ 0,
+ REG_SZ,
+ (LPVOID)lpEmptyString,
+ sizeof(WCHAR));
+
+ RegSetValueEx(hDomainKey,
+ L"ReplicaSourceNodeName",
+ 0,
+ REG_SZ,
+ (LPVOID)lpEmptyString,
+ sizeof(WCHAR));
+
+ /* Create the Alias container */
+ if (!RegCreateKeyExW(hDomainKey,
+ L"Aliases",
+ 0,
+ NULL,
+ REG_OPTION_NON_VOLATILE,
+ KEY_ALL_ACCESS,
+ NULL,
+ &hAliasesKey,
+ &dwDisposition))
+ {
+ if (!RegCreateKeyExW(hAliasesKey,
+ L"Names",
+ 0,
+ NULL,
+ REG_OPTION_NON_VOLATILE,
+ KEY_ALL_ACCESS,
+ NULL,
+ &hNamesKey,
+ &dwDisposition))
+ RegCloseKey(hNamesKey);
+ RegCloseKey(hAliasesKey);
+ }
- /* Create the 'Account\Groups' key */
- if (RegCreateKeyExW(hAccountKey,
- L"Groups",
- 0,
- NULL,
- REG_OPTION_NON_VOLATILE,
- KEY_ALL_ACCESS,
- NULL,
- &hGroupsKey,
- &dwDisposition))
+ /* Create the Groups container */
+ if (!RegCreateKeyExW(hDomainKey,
+ L"Groups",
+ 0,
+ NULL,
+ REG_OPTION_NON_VOLATILE,
+ KEY_ALL_ACCESS,
+ NULL,
+ &hGroupsKey,
+ &dwDisposition))
{
- ERR("Failed to create 'Account\\Groups' key! (Error %lu)\n", GetLastError());
- RegCloseKey(hAccountKey);
- RegCloseKey(hDomainsKey);
- return FALSE;
+ if (!RegCreateKeyExW(hGroupsKey,
+ L"Names",
+ 0,
+ NULL,
+ REG_OPTION_NON_VOLATILE,
+ KEY_ALL_ACCESS,
+ NULL,
+ &hNamesKey,
+ &dwDisposition))
+ RegCloseKey(hNamesKey);
+
+ RegCloseKey(hGroupsKey);
}
- RegCloseKey(hGroupsKey);
+ /* Create the Users container */
+ if (!RegCreateKeyExW(hDomainKey,
+ L"Users",
+ 0,
+ NULL,
+ REG_OPTION_NON_VOLATILE,
+ KEY_ALL_ACCESS,
+ NULL,
+ &hUsersKey,
+ &dwDisposition))
+ {
+ if (!RegCreateKeyExW(hUsersKey,
+ L"Names",
+ 0,
+ NULL,
+ REG_OPTION_NON_VOLATILE,
+ KEY_ALL_ACCESS,
+ NULL,
+ &hNamesKey,
+ &dwDisposition))
+ RegCloseKey(hNamesKey);
- /* Create the 'Account\Users' key */
- if (RegCreateKeyExW(hAccountKey,
- L"Users",
- 0,
- NULL,
- REG_OPTION_NON_VOLATILE,
- KEY_ALL_ACCESS,
- NULL,
- &hUsersKey,
- &dwDisposition))
+ RegCloseKey(hUsersKey);
+ }
+
+ if (lpDomainKey != NULL)
+ *lpDomainKey = hDomainKey;
+
+ return TRUE;
+}
+
+
+NTSTATUS
+SampGetAccountDomainInfo(PPOLICY_ACCOUNT_DOMAIN_INFO *AccountDomainInfo)
+{
+ LSA_OBJECT_ATTRIBUTES ObjectAttributes;
+ LSA_HANDLE PolicyHandle;
+ NTSTATUS Status;
+
+ TRACE("SampGetAccountDomainInfo\n");
+
+ memset(&ObjectAttributes, 0, sizeof(LSA_OBJECT_ATTRIBUTES));
+ ObjectAttributes.Length = sizeof(LSA_OBJECT_ATTRIBUTES);
+
+ Status = LsaOpenPolicy(NULL,
+ &ObjectAttributes,
+ POLICY_VIEW_LOCAL_INFORMATION,
+ &PolicyHandle);
+ if (Status != STATUS_SUCCESS)
{
- ERR("Failed to create 'Account\\Users' key! (Error %lu)\n", GetLastError());
- RegCloseKey(hAccountKey);
- RegCloseKey(hDomainsKey);
- return FALSE;
+ ERR("LsaOpenPolicy failed (Status: 0x%08lx)\n", Status);
+ return Status;
}
- RegCloseKey(hUsersKey);
+ Status = LsaQueryInformationPolicy(PolicyHandle,
+ PolicyAccountDomainInformation,
+ (PVOID *)AccountDomainInfo);
- RegCloseKey(hAccountKey);
+ LsaClose(PolicyHandle);
+ return Status;
+}
- /* Create the 'Domains\\Builtin' */
- if (RegCreateKeyExW(hDomainsKey,
- L"Builtin",
+
+BOOL
+SampInitializeSAM(VOID)
+{
+ PPOLICY_ACCOUNT_DOMAIN_INFO AccountDomainInfo = NULL;
+ DWORD dwDisposition;
+ HKEY hSamKey = NULL;
+ HKEY hDomainsKey = NULL;
+ HKEY hDomainKey = NULL;
+ PSID pBuiltinSid = NULL;
+ BOOL bResult = TRUE;
+ PSID pSid;
+ NTSTATUS Status;
+
+ TRACE("SampInitializeSAM() called\n");
+
+ if (RegCreateKeyExW(HKEY_LOCAL_MACHINE,
+ L"SAM\\SAM",
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
NULL,
- &hBuiltinKey,
+ &hSamKey,
&dwDisposition))
{
- ERR("Failed to create Builtin key! (Error %lu)\n", GetLastError());
- RegCloseKey(hDomainsKey);
+ ERR("Failed to create 'Sam' key! (Error %lu)\n", GetLastError());
return FALSE;
}
-
- /* Create the 'Builtin\Aliases' key */
- if (RegCreateKeyExW(hBuiltinKey,
- L"Aliases",
+ if (RegCreateKeyExW(hSamKey,
+ L"Domains",
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
NULL,
- &hAliasesKey,
+ &hDomainsKey,
&dwDisposition))
{
- ERR("Failed to create 'Builtin\\Aliases' key! (Error %lu)\n", GetLastError());
- RegCloseKey(hBuiltinKey);
- RegCloseKey(hDomainsKey);
- return FALSE;
+ ERR("Failed to create 'Domains' key! (Error %lu)\n", GetLastError());
+ bResult = FALSE;
+ goto done;
}
- /* Create builtin aliases */
- if (!CreateBuiltinAliases(hAliasesKey))
+ RegCloseKey(hSamKey);
+ hSamKey = NULL;
+
+ /* Create and initialize the Builtin Domain SID */
+ pBuiltinSid = RtlAllocateHeap(RtlGetProcessHeap(), 0, RtlLengthRequiredSid(1));
+ if (pBuiltinSid == NULL)
{
- ERR("Failed to create builtin aliases!\n");
- RegCloseKey(hAliasesKey);
- RegCloseKey(hBuiltinKey);
- RegCloseKey(hDomainsKey);
- return FALSE;
+ ERR("Failed to alloacte the Builtin Domain SID\n");
+ bResult = FALSE;
+ goto done;
}
- RegCloseKey(hAliasesKey);
+ RtlInitializeSid(pBuiltinSid, &SecurityNtAuthority, 1);
+ *(RtlSubAuthoritySid(pBuiltinSid, 0)) = SECURITY_BUILTIN_DOMAIN_RID;
-
- /* Create the 'Builtin\Groups' key */
- if (RegCreateKeyExW(hBuiltinKey,
- L"Groups",
- 0,
- NULL,
- REG_OPTION_NON_VOLATILE,
- KEY_ALL_ACCESS,
- NULL,
- &hGroupsKey,
- &dwDisposition))
+ /* Get account domain information */
+ Status = SampGetAccountDomainInfo(&AccountDomainInfo);
+ if (!NT_SUCCESS(Status))
{
- ERR("Failed to create 'Builtin\\Groups' key! (Error %lu)\n", GetLastError());
- RegCloseKey(hBuiltinKey);
- RegCloseKey(hDomainsKey);
- return FALSE;
+ ERR("SampGetAccountDomainInfo failed (Status %08lx)\n", Status);
+ bResult = FALSE;
+ goto done;
}
- /* Create builtin groups */
- if (!CreateBuiltinGroups(hGroupsKey))
+ /* Create the Builtin domain */
+ if (SampCreateDomain(hDomainsKey,
+ L"Builtin",
+ L"Builtin",
+ pBuiltinSid,
+ &hDomainKey))
{
- ERR("Failed to create builtin groups!\n");
- RegCloseKey(hGroupsKey);
- RegCloseKey(hBuiltinKey);
- RegCloseKey(hDomainsKey);
- return FALSE;
- }
+ SampCreateAliasAccount(hDomainKey,
+ L"Administrators",
+ L"Testabc1234567890",
+ DOMAIN_ALIAS_RID_ADMINS);
- RegCloseKey(hGroupsKey);
+ SampCreateAliasAccount(hDomainKey,
+ L"Users",
+ L"Users Group",
+ DOMAIN_ALIAS_RID_USERS);
+ SampCreateAliasAccount(hDomainKey,
+ L"Guests",
+ L"Guests Group",
+ DOMAIN_ALIAS_RID_GUESTS);
- /* Create the 'Builtin\Users' key */
- if (RegCreateKeyExW(hBuiltinKey,
- L"Users",
- 0,
- NULL,
- REG_OPTION_NON_VOLATILE,
- KEY_ALL_ACCESS,
- NULL,
- &hUsersKey,
- &dwDisposition))
- {
- ERR("Failed to create 'Builtin\\Users' key! (Error %lu)\n", GetLastError());
- RegCloseKey(hBuiltinKey);
- RegCloseKey(hDomainsKey);
- return FALSE;
+ SampCreateAliasAccount(hDomainKey,
+ L"Power Users",
+ L"Power Users Group",
+ DOMAIN_ALIAS_RID_POWER_USERS);
+
+
+ pSid = AppendRidToSid(AccountDomainInfo->DomainSid,
+ DOMAIN_USER_RID_ADMIN);
+ if (pSid != NULL)
+ {
+ SampAddMemberToAlias(hDomainKey,
+ DOMAIN_ALIAS_RID_ADMINS,
+ pSid);
+
+ RtlFreeHeap(RtlGetProcessHeap(), 0, pSid);
+ }
+
+
+ RegCloseKey(hDomainKey);
}
- /* Create builtin users */
- if (!CreateBuiltinUsers(hUsersKey))
+ /* Create the Account domain */
+ if (SampCreateDomain(hDomainsKey,
+ L"Account",
+ L"",
+ AccountDomainInfo->DomainSid,
+ &hDomainKey))
{
- ERR("Failed to create builtin users!\n");
- RegCloseKey(hUsersKey);
- RegCloseKey(hBuiltinKey);
- RegCloseKey(hDomainsKey);
- return FALSE;
+ SampCreateUserAccount(hDomainKey,
+ L"Administrator",
+ DOMAIN_USER_RID_ADMIN);
+
+ SampCreateUserAccount(hDomainKey,
+ L"Guest",
+ DOMAIN_USER_RID_GUEST);
+
+ RegCloseKey(hDomainKey);
}
- RegCloseKey(hUsersKey);
+done:
+ if (AccountDomainInfo)
+ LsaFreeMemory(AccountDomainInfo);
- RegCloseKey(hBuiltinKey);
+ if (pBuiltinSid)
+ RtlFreeHeap(RtlGetProcessHeap(), 0, pBuiltinSid);
- RegCloseKey(hDomainsKey);
+ if (hDomainsKey)
+ RegCloseKey(hDomainsKey);
+
+ if (hSamKey)
+ RegCloseKey(hSamKey);
TRACE("SampInitializeSAM() done\n");
- return TRUE;
+ return bResult;
}