mirror of
https://github.com/reactos/reactos.git
synced 2024-12-29 10:35:28 +00:00
1805 lines
53 KiB
C
1805 lines
53 KiB
C
/*
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
* PROJECT: ReactOS system libraries
|
|
* PURPOSE: System setup
|
|
* FILE: dll/win32/syssetup/security.c
|
|
* PROGRAMER: Eric Kohl
|
|
*/
|
|
|
|
/* INCLUDES *****************************************************************/
|
|
|
|
#include "precomp.h"
|
|
|
|
#include <ntlsa.h>
|
|
#include <ntsecapi.h>
|
|
#include <ntsam.h>
|
|
#include <sddl.h>
|
|
|
|
#define NDEBUG
|
|
#include <debug.h>
|
|
|
|
#define TICKS_PER_DAY -864000000000LL
|
|
#define TICKS_PER_MINUTE -600000000LL
|
|
|
|
/* FUNCTIONS ****************************************************************/
|
|
|
|
NTSTATUS
|
|
WINAPI
|
|
SetAccountsDomainSid(
|
|
PSID DomainSid,
|
|
LPCWSTR DomainName)
|
|
{
|
|
PPOLICY_ACCOUNT_DOMAIN_INFO OrigInfo = NULL;
|
|
POLICY_ACCOUNT_DOMAIN_INFO Info;
|
|
LSA_OBJECT_ATTRIBUTES ObjectAttributes;
|
|
LSA_HANDLE PolicyHandle;
|
|
|
|
SAM_HANDLE ServerHandle = NULL;
|
|
SAM_HANDLE DomainHandle = NULL;
|
|
DOMAIN_NAME_INFORMATION DomainNameInfo;
|
|
|
|
SIZE_T DomainNameLength = 0;
|
|
NTSTATUS Status;
|
|
|
|
DPRINT("SYSSETUP: SetAccountsDomainSid\n");
|
|
|
|
if (DomainName != NULL)
|
|
{
|
|
DomainNameLength = wcslen(DomainName);
|
|
if (DomainNameLength > UNICODE_STRING_MAX_CHARS)
|
|
{
|
|
return STATUS_INVALID_PARAMETER;
|
|
}
|
|
}
|
|
|
|
memset(&ObjectAttributes, 0, sizeof(LSA_OBJECT_ATTRIBUTES));
|
|
ObjectAttributes.Length = sizeof(LSA_OBJECT_ATTRIBUTES);
|
|
|
|
Status = LsaOpenPolicy(NULL,
|
|
&ObjectAttributes,
|
|
POLICY_VIEW_LOCAL_INFORMATION | POLICY_TRUST_ADMIN,
|
|
&PolicyHandle);
|
|
if (Status != STATUS_SUCCESS)
|
|
{
|
|
DPRINT("LsaOpenPolicy failed (Status: 0x%08lx)\n", Status);
|
|
return Status;
|
|
}
|
|
|
|
Status = LsaQueryInformationPolicy(PolicyHandle,
|
|
PolicyAccountDomainInformation,
|
|
(PVOID *)&OrigInfo);
|
|
if (Status == STATUS_SUCCESS && OrigInfo != NULL)
|
|
{
|
|
if (DomainName == NULL)
|
|
{
|
|
Info.DomainName.Buffer = OrigInfo->DomainName.Buffer;
|
|
Info.DomainName.Length = OrigInfo->DomainName.Length;
|
|
Info.DomainName.MaximumLength = OrigInfo->DomainName.MaximumLength;
|
|
}
|
|
else
|
|
{
|
|
Info.DomainName.Buffer = (LPWSTR)DomainName;
|
|
Info.DomainName.Length = DomainNameLength * sizeof(WCHAR);
|
|
Info.DomainName.MaximumLength = Info.DomainName.Length + sizeof(WCHAR);
|
|
}
|
|
|
|
if (DomainSid == NULL)
|
|
Info.DomainSid = OrigInfo->DomainSid;
|
|
else
|
|
Info.DomainSid = DomainSid;
|
|
}
|
|
else
|
|
{
|
|
Info.DomainName.Buffer = (LPWSTR)DomainName;
|
|
Info.DomainName.Length = DomainNameLength * sizeof(WCHAR);
|
|
Info.DomainName.MaximumLength = Info.DomainName.Length + sizeof(WCHAR);
|
|
Info.DomainSid = DomainSid;
|
|
}
|
|
|
|
Status = LsaSetInformationPolicy(PolicyHandle,
|
|
PolicyAccountDomainInformation,
|
|
(PVOID)&Info);
|
|
if (Status != STATUS_SUCCESS)
|
|
{
|
|
DPRINT("LsaSetInformationPolicy failed (Status: 0x%08lx)\n", Status);
|
|
}
|
|
|
|
if (OrigInfo != NULL)
|
|
LsaFreeMemory(OrigInfo);
|
|
|
|
LsaClose(PolicyHandle);
|
|
|
|
DomainNameInfo.DomainName.Length = DomainNameLength * sizeof(WCHAR);
|
|
DomainNameInfo.DomainName.MaximumLength = DomainNameInfo.DomainName.Length + sizeof(WCHAR);
|
|
DomainNameInfo.DomainName.Buffer = (LPWSTR)DomainName;
|
|
|
|
Status = SamConnect(NULL,
|
|
&ServerHandle,
|
|
SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN,
|
|
NULL);
|
|
if (NT_SUCCESS(Status))
|
|
{
|
|
Status = SamOpenDomain(ServerHandle,
|
|
DOMAIN_WRITE_OTHER_PARAMETERS,
|
|
Info.DomainSid,
|
|
&DomainHandle);
|
|
if (NT_SUCCESS(Status))
|
|
{
|
|
Status = SamSetInformationDomain(DomainHandle,
|
|
DomainNameInformation,
|
|
&DomainNameInfo);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
DPRINT1("SamSetInformationDomain failed (Status: 0x%08lx)\n", Status);
|
|
}
|
|
|
|
SamCloseHandle(DomainHandle);
|
|
}
|
|
else
|
|
{
|
|
DPRINT1("SamOpenDomain failed (Status: 0x%08lx)\n", Status);
|
|
}
|
|
|
|
SamCloseHandle(ServerHandle);
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
|
|
/* Hack */
|
|
static
|
|
NTSTATUS
|
|
SetPrimaryDomain(LPCWSTR DomainName,
|
|
PSID DomainSid)
|
|
{
|
|
PPOLICY_PRIMARY_DOMAIN_INFO OrigInfo = NULL;
|
|
POLICY_PRIMARY_DOMAIN_INFO Info;
|
|
LSA_OBJECT_ATTRIBUTES ObjectAttributes;
|
|
LSA_HANDLE PolicyHandle;
|
|
SIZE_T DomainNameLength = 0;
|
|
NTSTATUS Status;
|
|
|
|
DPRINT1("SYSSETUP: SetPrimaryDomain()\n");
|
|
|
|
if (DomainName != NULL)
|
|
{
|
|
DomainNameLength = wcslen(DomainName);
|
|
if (DomainNameLength > UNICODE_STRING_MAX_CHARS)
|
|
{
|
|
return STATUS_INVALID_PARAMETER;
|
|
}
|
|
}
|
|
|
|
memset(&ObjectAttributes, 0, sizeof(LSA_OBJECT_ATTRIBUTES));
|
|
ObjectAttributes.Length = sizeof(LSA_OBJECT_ATTRIBUTES);
|
|
|
|
Status = LsaOpenPolicy(NULL,
|
|
&ObjectAttributes,
|
|
POLICY_VIEW_LOCAL_INFORMATION | POLICY_TRUST_ADMIN,
|
|
&PolicyHandle);
|
|
if (Status != STATUS_SUCCESS)
|
|
{
|
|
DPRINT("LsaOpenPolicy failed (Status: 0x%08lx)\n", Status);
|
|
return Status;
|
|
}
|
|
|
|
Status = LsaQueryInformationPolicy(PolicyHandle,
|
|
PolicyPrimaryDomainInformation,
|
|
(PVOID *)&OrigInfo);
|
|
if (Status == STATUS_SUCCESS && OrigInfo != NULL)
|
|
{
|
|
if (DomainName == NULL)
|
|
{
|
|
Info.Name.Buffer = OrigInfo->Name.Buffer;
|
|
Info.Name.Length = OrigInfo->Name.Length;
|
|
Info.Name.MaximumLength = OrigInfo->Name.MaximumLength;
|
|
}
|
|
else
|
|
{
|
|
Info.Name.Buffer = (LPWSTR)DomainName;
|
|
Info.Name.Length = DomainNameLength * sizeof(WCHAR);
|
|
Info.Name.MaximumLength = Info.Name.Length + sizeof(WCHAR);
|
|
}
|
|
|
|
if (DomainSid == NULL)
|
|
Info.Sid = OrigInfo->Sid;
|
|
else
|
|
Info.Sid = DomainSid;
|
|
}
|
|
else
|
|
{
|
|
Info.Name.Buffer = (LPWSTR)DomainName;
|
|
Info.Name.Length = DomainNameLength * sizeof(WCHAR);
|
|
Info.Name.MaximumLength = Info.Name.Length + sizeof(WCHAR);
|
|
Info.Sid = DomainSid;
|
|
}
|
|
|
|
Status = LsaSetInformationPolicy(PolicyHandle,
|
|
PolicyPrimaryDomainInformation,
|
|
(PVOID)&Info);
|
|
if (Status != STATUS_SUCCESS)
|
|
{
|
|
DPRINT("LsaSetInformationPolicy failed (Status: 0x%08lx)\n", Status);
|
|
}
|
|
|
|
if (OrigInfo != NULL)
|
|
LsaFreeMemory(OrigInfo);
|
|
|
|
LsaClose(PolicyHandle);
|
|
|
|
return Status;
|
|
}
|
|
|
|
|
|
static
|
|
VOID
|
|
InstallBuiltinAccounts(VOID)
|
|
{
|
|
LPWSTR BuiltinAccounts[] = {
|
|
L"S-1-1-0", /* Everyone */
|
|
L"S-1-5-4", /* Interactive */
|
|
L"S-1-5-6", /* Service */
|
|
L"S-1-5-19", /* Local Service */
|
|
L"S-1-5-20", /* Network Service */
|
|
L"S-1-5-32-544", /* Administrators */
|
|
L"S-1-5-32-545", /* Users */
|
|
L"S-1-5-32-547", /* Power Users */
|
|
L"S-1-5-32-551", /* Backup Operators */
|
|
L"S-1-5-32-555"}; /* Remote Desktop Users */
|
|
LSA_OBJECT_ATTRIBUTES ObjectAttributes;
|
|
NTSTATUS Status;
|
|
LSA_HANDLE PolicyHandle = NULL;
|
|
LSA_HANDLE AccountHandle = NULL;
|
|
PSID AccountSid;
|
|
ULONG i;
|
|
|
|
DPRINT("InstallBuiltinAccounts()\n");
|
|
|
|
memset(&ObjectAttributes, 0, sizeof(LSA_OBJECT_ATTRIBUTES));
|
|
|
|
Status = LsaOpenPolicy(NULL,
|
|
&ObjectAttributes,
|
|
POLICY_CREATE_ACCOUNT,
|
|
&PolicyHandle);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
DPRINT1("LsaOpenPolicy failed (Status %08lx)\n", Status);
|
|
return;
|
|
}
|
|
|
|
for (i = 0; i < ARRAYSIZE(BuiltinAccounts); i++)
|
|
{
|
|
if (!ConvertStringSidToSid(BuiltinAccounts[i], &AccountSid))
|
|
{
|
|
DPRINT1("ConvertStringSidToSid(%S) failed: %lu\n", BuiltinAccounts[i], GetLastError());
|
|
continue;
|
|
}
|
|
|
|
Status = LsaCreateAccount(PolicyHandle,
|
|
AccountSid,
|
|
0,
|
|
&AccountHandle);
|
|
if (NT_SUCCESS(Status))
|
|
{
|
|
LsaClose(AccountHandle);
|
|
}
|
|
|
|
LocalFree(AccountSid);
|
|
}
|
|
|
|
LsaClose(PolicyHandle);
|
|
}
|
|
|
|
|
|
static
|
|
VOID
|
|
InstallPrivileges(
|
|
HINF hSecurityInf)
|
|
{
|
|
LSA_OBJECT_ATTRIBUTES ObjectAttributes;
|
|
WCHAR szPrivilegeString[256];
|
|
WCHAR szSidString[256];
|
|
INFCONTEXT InfContext;
|
|
DWORD i;
|
|
PSID AccountSid = NULL;
|
|
NTSTATUS Status;
|
|
LSA_HANDLE PolicyHandle = NULL;
|
|
LSA_UNICODE_STRING RightString, AccountName;
|
|
PLSA_REFERENCED_DOMAIN_LIST ReferencedDomains = NULL;
|
|
PLSA_TRANSLATED_SID2 Sids = NULL;
|
|
|
|
DPRINT("InstallPrivileges()\n");
|
|
|
|
memset(&ObjectAttributes, 0, sizeof(LSA_OBJECT_ATTRIBUTES));
|
|
|
|
Status = LsaOpenPolicy(NULL,
|
|
&ObjectAttributes,
|
|
POLICY_CREATE_ACCOUNT | POLICY_LOOKUP_NAMES,
|
|
&PolicyHandle);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
DPRINT1("LsaOpenPolicy failed (Status %08lx)\n", Status);
|
|
goto done;
|
|
}
|
|
|
|
if (!SetupFindFirstLineW(hSecurityInf,
|
|
L"Privilege Rights",
|
|
NULL,
|
|
&InfContext))
|
|
{
|
|
DPRINT1("SetupFindFirstLineW failed\n");
|
|
goto done;
|
|
}
|
|
|
|
do
|
|
{
|
|
/* Retrieve the privilege name */
|
|
if (!SetupGetStringFieldW(&InfContext,
|
|
0,
|
|
szPrivilegeString,
|
|
ARRAYSIZE(szPrivilegeString),
|
|
NULL))
|
|
{
|
|
DPRINT1("SetupGetStringFieldW() failed\n");
|
|
goto done;
|
|
}
|
|
DPRINT("Privilege: %S\n", szPrivilegeString);
|
|
|
|
for (i = 0; i < SetupGetFieldCount(&InfContext); i++)
|
|
{
|
|
if (!SetupGetStringFieldW(&InfContext,
|
|
i + 1,
|
|
szSidString,
|
|
ARRAYSIZE(szSidString),
|
|
NULL))
|
|
{
|
|
DPRINT1("SetupGetStringFieldW() failed\n");
|
|
goto done;
|
|
}
|
|
DPRINT("SID: %S\n", szSidString);
|
|
|
|
if (szSidString[0] == UNICODE_NULL)
|
|
continue;
|
|
|
|
if (szSidString[0] == L'*')
|
|
{
|
|
DPRINT("Account Sid: %S\n", &szSidString[1]);
|
|
|
|
if (!ConvertStringSidToSid(&szSidString[1], &AccountSid))
|
|
{
|
|
DPRINT1("ConvertStringSidToSid(%S) failed: %lu\n", szSidString, GetLastError());
|
|
continue;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DPRINT("Account name: %S\n", szSidString);
|
|
|
|
ReferencedDomains = NULL;
|
|
Sids = NULL;
|
|
RtlInitUnicodeString(&AccountName, szSidString);
|
|
Status = LsaLookupNames2(PolicyHandle,
|
|
0,
|
|
1,
|
|
&AccountName,
|
|
&ReferencedDomains,
|
|
&Sids);
|
|
if (ReferencedDomains != NULL)
|
|
{
|
|
LsaFreeMemory(ReferencedDomains);
|
|
}
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
DPRINT1("LsaLookupNames2() failed (Status 0x%08lx)\n", Status);
|
|
|
|
if (Sids != NULL)
|
|
{
|
|
LsaFreeMemory(Sids);
|
|
Sids = NULL;
|
|
}
|
|
|
|
continue;
|
|
}
|
|
}
|
|
|
|
RtlInitUnicodeString(&RightString, szPrivilegeString);
|
|
Status = LsaAddAccountRights(PolicyHandle,
|
|
(AccountSid != NULL) ? AccountSid : Sids[0].Sid,
|
|
&RightString,
|
|
1);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
DPRINT1("LsaAddAccountRights() failed (Status %08lx)\n", Status);
|
|
}
|
|
|
|
if (Sids != NULL)
|
|
{
|
|
LsaFreeMemory(Sids);
|
|
Sids = NULL;
|
|
}
|
|
|
|
if (AccountSid != NULL)
|
|
{
|
|
LocalFree(AccountSid);
|
|
AccountSid = NULL;
|
|
}
|
|
}
|
|
|
|
}
|
|
while (SetupFindNextLine(&InfContext, &InfContext));
|
|
|
|
done:
|
|
if (PolicyHandle != NULL)
|
|
LsaClose(PolicyHandle);
|
|
}
|
|
|
|
|
|
static
|
|
VOID
|
|
ApplyRegistryValues(
|
|
HINF hSecurityInf)
|
|
{
|
|
WCHAR szRegistryPath[MAX_PATH];
|
|
WCHAR szRootName[MAX_PATH];
|
|
WCHAR szKeyName[MAX_PATH];
|
|
WCHAR szValueName[MAX_PATH];
|
|
INFCONTEXT InfContext;
|
|
DWORD dwLength, dwType;
|
|
HKEY hRootKey, hKey;
|
|
PWSTR Ptr1, Ptr2;
|
|
DWORD dwError;
|
|
PVOID pBuffer;
|
|
|
|
DPRINT("ApplyRegistryValues()\n");
|
|
|
|
if (!SetupFindFirstLineW(hSecurityInf,
|
|
L"Registry Values",
|
|
NULL,
|
|
&InfContext))
|
|
{
|
|
DPRINT1("SetupFindFirstLineW failed\n");
|
|
return;
|
|
}
|
|
|
|
do
|
|
{
|
|
/* Retrieve the privilege name */
|
|
if (!SetupGetStringFieldW(&InfContext,
|
|
0,
|
|
szRegistryPath,
|
|
ARRAYSIZE(szRegistryPath),
|
|
NULL))
|
|
{
|
|
DPRINT1("SetupGetStringFieldW() failed\n");
|
|
return;
|
|
}
|
|
|
|
DPRINT("RegistryPath: %S\n", szRegistryPath);
|
|
|
|
Ptr1 = wcschr(szRegistryPath, L'\\');
|
|
Ptr2 = wcsrchr(szRegistryPath, L'\\');
|
|
if (Ptr1 != NULL && Ptr2 != NULL && Ptr1 != Ptr2)
|
|
{
|
|
dwLength = (DWORD)(((ULONG_PTR)Ptr1 - (ULONG_PTR)szRegistryPath) / sizeof(WCHAR));
|
|
wcsncpy(szRootName, szRegistryPath, dwLength);
|
|
szRootName[dwLength] = UNICODE_NULL;
|
|
|
|
Ptr1++;
|
|
dwLength = (DWORD)(((ULONG_PTR)Ptr2 - (ULONG_PTR)Ptr1) / sizeof(WCHAR));
|
|
wcsncpy(szKeyName, Ptr1, dwLength);
|
|
szKeyName[dwLength] = UNICODE_NULL;
|
|
|
|
Ptr2++;
|
|
wcscpy(szValueName, Ptr2);
|
|
|
|
DPRINT("RootName: %S\n", szRootName);
|
|
DPRINT("KeyName: %S\n", szKeyName);
|
|
DPRINT("ValueName: %S\n", szValueName);
|
|
|
|
if (_wcsicmp(szRootName, L"Machine") == 0)
|
|
{
|
|
hRootKey = HKEY_LOCAL_MACHINE;
|
|
}
|
|
else
|
|
{
|
|
DPRINT1("Unsupported root key %S\n", szRootName);
|
|
break;
|
|
}
|
|
|
|
if (!SetupGetIntField(&InfContext,
|
|
1,
|
|
(PINT)&dwType))
|
|
{
|
|
DPRINT1("Failed to get key type (Error %lu)\n", GetLastError());
|
|
break;
|
|
}
|
|
|
|
if (dwType != REG_SZ && dwType != REG_EXPAND_SZ && dwType != REG_BINARY &&
|
|
dwType != REG_DWORD && dwType != REG_MULTI_SZ)
|
|
{
|
|
DPRINT1("Invalid value type %lu\n", dwType);
|
|
break;
|
|
}
|
|
|
|
dwLength = 0;
|
|
switch (dwType)
|
|
{
|
|
case REG_SZ:
|
|
case REG_EXPAND_SZ:
|
|
SetupGetStringField(&InfContext,
|
|
2,
|
|
NULL,
|
|
0,
|
|
&dwLength);
|
|
dwLength *= sizeof(WCHAR);
|
|
break;
|
|
|
|
case REG_BINARY:
|
|
SetupGetBinaryField(&InfContext,
|
|
2,
|
|
NULL,
|
|
0,
|
|
&dwLength);
|
|
break;
|
|
|
|
case REG_DWORD:
|
|
dwLength = sizeof(INT);
|
|
break;
|
|
|
|
case REG_MULTI_SZ:
|
|
SetupGetMultiSzField(&InfContext,
|
|
2,
|
|
NULL,
|
|
0,
|
|
&dwLength);
|
|
dwLength *= sizeof(WCHAR);
|
|
break;
|
|
}
|
|
|
|
if (dwLength == 0)
|
|
{
|
|
DPRINT1("Failed to determine the required buffer size!\n");
|
|
break;
|
|
}
|
|
|
|
dwError = RegCreateKeyExW(hRootKey,
|
|
szKeyName,
|
|
0,
|
|
NULL,
|
|
REG_OPTION_NON_VOLATILE,
|
|
KEY_WRITE,
|
|
NULL,
|
|
&hKey,
|
|
NULL);
|
|
if (dwError != ERROR_SUCCESS)
|
|
{
|
|
DPRINT1("Failed to create the key %S (Error %lu)\n", szKeyName, dwError);
|
|
break;
|
|
}
|
|
|
|
pBuffer = HeapAlloc(GetProcessHeap(), 0, dwLength);
|
|
if (pBuffer)
|
|
{
|
|
switch (dwType)
|
|
{
|
|
case REG_SZ:
|
|
case REG_EXPAND_SZ:
|
|
SetupGetStringField(&InfContext,
|
|
2,
|
|
pBuffer,
|
|
dwLength / sizeof(WCHAR),
|
|
&dwLength);
|
|
dwLength *= sizeof(WCHAR);
|
|
break;
|
|
|
|
case REG_BINARY:
|
|
SetupGetBinaryField(&InfContext,
|
|
2,
|
|
pBuffer,
|
|
dwLength,
|
|
&dwLength);
|
|
break;
|
|
|
|
case REG_DWORD:
|
|
SetupGetIntField(&InfContext,
|
|
2,
|
|
pBuffer);
|
|
break;
|
|
|
|
case REG_MULTI_SZ:
|
|
SetupGetMultiSzField(&InfContext,
|
|
2,
|
|
pBuffer,
|
|
dwLength / sizeof(WCHAR),
|
|
&dwLength);
|
|
dwLength *= sizeof(WCHAR);
|
|
break;
|
|
}
|
|
|
|
RegSetValueEx(hKey,
|
|
szValueName,
|
|
0,
|
|
dwType,
|
|
pBuffer,
|
|
dwLength);
|
|
|
|
HeapFree(GetProcessHeap(), 0, pBuffer);
|
|
}
|
|
|
|
RegCloseKey(hKey);
|
|
}
|
|
}
|
|
while (SetupFindNextLine(&InfContext, &InfContext));
|
|
}
|
|
|
|
|
|
static
|
|
VOID
|
|
ApplyEventlogSettings(
|
|
_In_ HINF hSecurityInf,
|
|
_In_ PWSTR pszSectionName,
|
|
_In_ PWSTR pszLogName)
|
|
{
|
|
INFCONTEXT InfContext;
|
|
HKEY hServiceKey = NULL, hLogKey = NULL;
|
|
DWORD dwValue, dwError;
|
|
BOOL bValueSet;
|
|
|
|
DPRINT("ApplyEventlogSettings(%p %S %S)\n",
|
|
hSecurityInf, pszSectionName, pszLogName);
|
|
|
|
dwError = RegCreateKeyExW(HKEY_LOCAL_MACHINE,
|
|
L"System\\CurrentControlSet\\Services\\Eventlog",
|
|
0,
|
|
NULL,
|
|
REG_OPTION_NON_VOLATILE,
|
|
KEY_WRITE,
|
|
NULL,
|
|
&hServiceKey,
|
|
NULL);
|
|
if (dwError != ERROR_SUCCESS)
|
|
{
|
|
DPRINT1("Failed to create the Eventlog Service key (Error %lu)\n", dwError);
|
|
return;
|
|
}
|
|
|
|
dwError = RegCreateKeyExW(hServiceKey,
|
|
pszLogName,
|
|
0,
|
|
NULL,
|
|
REG_OPTION_NON_VOLATILE,
|
|
KEY_WRITE,
|
|
NULL,
|
|
&hLogKey,
|
|
NULL);
|
|
if (dwError != ERROR_SUCCESS)
|
|
{
|
|
DPRINT1("Failed to create the key %S (Error %lu)\n", pszLogName, dwError);
|
|
RegCloseKey(hServiceKey);
|
|
return;
|
|
}
|
|
|
|
if (SetupFindFirstLineW(hSecurityInf,
|
|
pszSectionName,
|
|
L"MaximumLogSize",
|
|
&InfContext))
|
|
{
|
|
DPRINT("MaximumLogSize\n");
|
|
dwValue = 0;
|
|
SetupGetIntField(&InfContext,
|
|
1,
|
|
(PINT)&dwValue);
|
|
|
|
DPRINT("MaximumLogSize: %lu (kByte)\n", dwValue);
|
|
if (dwValue >= 64 && dwValue <= 4194240)
|
|
{
|
|
dwValue *= 1024;
|
|
|
|
DPRINT("MaxSize: %lu\n", dwValue);
|
|
RegSetValueEx(hLogKey,
|
|
L"MaxSize",
|
|
0,
|
|
REG_DWORD,
|
|
(LPBYTE)&dwValue,
|
|
sizeof(dwValue));
|
|
}
|
|
}
|
|
|
|
if (SetupFindFirstLineW(hSecurityInf,
|
|
pszSectionName,
|
|
L"AuditLogRetentionPeriod",
|
|
&InfContext))
|
|
{
|
|
bValueSet = FALSE;
|
|
dwValue = 0;
|
|
SetupGetIntField(&InfContext,
|
|
1,
|
|
(PINT)&dwValue);
|
|
if (dwValue == 0)
|
|
{
|
|
bValueSet = TRUE;
|
|
}
|
|
else if (dwValue == 1)
|
|
{
|
|
if (SetupFindFirstLineW(hSecurityInf,
|
|
pszSectionName,
|
|
L"RetentionDays",
|
|
&InfContext))
|
|
{
|
|
SetupGetIntField(&InfContext,
|
|
1,
|
|
(PINT)&dwValue);
|
|
dwValue *= 86400;
|
|
bValueSet = TRUE;
|
|
}
|
|
}
|
|
else if (dwValue == 2)
|
|
{
|
|
dwValue = (DWORD)-1;
|
|
bValueSet = TRUE;
|
|
}
|
|
|
|
if (bValueSet)
|
|
{
|
|
DPRINT("Retention: %lu\n", dwValue);
|
|
RegSetValueEx(hLogKey,
|
|
L"Retention",
|
|
0,
|
|
REG_DWORD,
|
|
(LPBYTE)&dwValue,
|
|
sizeof(dwValue));
|
|
}
|
|
}
|
|
|
|
if (SetupFindFirstLineW(hSecurityInf,
|
|
pszSectionName,
|
|
L"RestrictGuestAccess",
|
|
&InfContext))
|
|
{
|
|
dwValue = 0;
|
|
SetupGetIntField(&InfContext,
|
|
1,
|
|
(PINT)&dwValue);
|
|
if (dwValue == 0 || dwValue == 1)
|
|
{
|
|
DPRINT("RestrictGuestAccess: %lu\n", dwValue);
|
|
RegSetValueEx(hLogKey,
|
|
L"RestrictGuestAccess",
|
|
0,
|
|
REG_DWORD,
|
|
(LPBYTE)&dwValue,
|
|
sizeof(dwValue));
|
|
}
|
|
}
|
|
|
|
RegCloseKey(hLogKey);
|
|
RegCloseKey(hServiceKey);
|
|
}
|
|
|
|
|
|
static
|
|
VOID
|
|
ApplyPasswordSettings(
|
|
_In_ HINF hSecurityInf,
|
|
_In_ PWSTR pszSectionName)
|
|
{
|
|
INFCONTEXT InfContext;
|
|
PDOMAIN_PASSWORD_INFORMATION PasswordInfo = NULL;
|
|
PPOLICY_ACCOUNT_DOMAIN_INFO OrigInfo = NULL;
|
|
LSA_OBJECT_ATTRIBUTES ObjectAttributes;
|
|
LSA_HANDLE PolicyHandle = NULL;
|
|
SAM_HANDLE ServerHandle = NULL;
|
|
SAM_HANDLE DomainHandle = NULL;
|
|
INT nValue;
|
|
NTSTATUS Status;
|
|
|
|
DPRINT("ApplyPasswordSettings()\n");
|
|
|
|
memset(&ObjectAttributes, 0, sizeof(LSA_OBJECT_ATTRIBUTES));
|
|
ObjectAttributes.Length = sizeof(LSA_OBJECT_ATTRIBUTES);
|
|
|
|
Status = LsaOpenPolicy(NULL,
|
|
&ObjectAttributes,
|
|
POLICY_VIEW_LOCAL_INFORMATION | POLICY_TRUST_ADMIN,
|
|
&PolicyHandle);
|
|
if (Status != STATUS_SUCCESS)
|
|
{
|
|
DPRINT1("LsaOpenPolicy() failed (Status: 0x%08lx)\n", Status);
|
|
return;
|
|
}
|
|
|
|
Status = LsaQueryInformationPolicy(PolicyHandle,
|
|
PolicyAccountDomainInformation,
|
|
(PVOID *)&OrigInfo);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
DPRINT1("LsaQueryInformationPolicy() failed (Status: 0x%08lx)\n", Status);
|
|
goto done;
|
|
}
|
|
|
|
Status = SamConnect(NULL,
|
|
&ServerHandle,
|
|
SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN,
|
|
NULL);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
DPRINT1("SamConnect() failed (Status: 0x%08lx)\n", Status);
|
|
goto done;
|
|
}
|
|
|
|
Status = SamOpenDomain(ServerHandle,
|
|
DOMAIN_READ_PASSWORD_PARAMETERS | DOMAIN_WRITE_PASSWORD_PARAMS,
|
|
OrigInfo->DomainSid,
|
|
&DomainHandle);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
DPRINT1("SamOpenDomain() failed (Status: 0x%08lx)\n", Status);
|
|
goto done;
|
|
}
|
|
|
|
Status = SamQueryInformationDomain(DomainHandle,
|
|
DomainPasswordInformation,
|
|
(PVOID*)&PasswordInfo);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
DPRINT1("SamQueryInformationDomain() failed (Status %08lx)\n", Status);
|
|
goto done;
|
|
}
|
|
|
|
DPRINT("MaximumPasswordAge (OldValue) : 0x%I64x\n", PasswordInfo->MaxPasswordAge.QuadPart);
|
|
if (SetupFindFirstLineW(hSecurityInf,
|
|
pszSectionName,
|
|
L"MaximumPasswordAge",
|
|
&InfContext))
|
|
{
|
|
if (SetupGetIntField(&InfContext, 1, &nValue))
|
|
{
|
|
DPRINT("Value: %ld\n", nValue);
|
|
if (nValue == -1)
|
|
{
|
|
PasswordInfo->MaxPasswordAge.QuadPart = 0x8000000000000000;
|
|
}
|
|
else if ((nValue >= 1) && (nValue < 1000))
|
|
{
|
|
PasswordInfo->MaxPasswordAge.QuadPart = (LONGLONG)nValue * TICKS_PER_DAY;
|
|
}
|
|
DPRINT("MaximumPasswordAge (NewValue) : 0x%I64x\n", PasswordInfo->MaxPasswordAge.QuadPart);
|
|
}
|
|
}
|
|
|
|
DPRINT("MinimumPasswordAge (OldValue) : 0x%I64x\n", PasswordInfo->MinPasswordAge.QuadPart);
|
|
if (SetupFindFirstLineW(hSecurityInf,
|
|
pszSectionName,
|
|
L"MinimumPasswordAge",
|
|
&InfContext))
|
|
{
|
|
if (SetupGetIntField(&InfContext, 1, &nValue))
|
|
{
|
|
DPRINT("Wert: %ld\n", nValue);
|
|
if ((nValue >= 0) && (nValue < 1000))
|
|
{
|
|
if (PasswordInfo->MaxPasswordAge.QuadPart < (LONGLONG)nValue * TICKS_PER_DAY)
|
|
PasswordInfo->MinPasswordAge.QuadPart = (LONGLONG)nValue * TICKS_PER_DAY;
|
|
}
|
|
DPRINT("MinimumPasswordAge (NewValue) : 0x%I64x\n", PasswordInfo->MinPasswordAge.QuadPart);
|
|
}
|
|
}
|
|
|
|
DPRINT("MinimumPasswordLength (OldValue) : %lu\n", PasswordInfo->MinPasswordLength);
|
|
if (SetupFindFirstLineW(hSecurityInf,
|
|
pszSectionName,
|
|
L"MinimumPasswordLength",
|
|
&InfContext))
|
|
{
|
|
if (SetupGetIntField(&InfContext, 1, &nValue))
|
|
{
|
|
DPRINT("Value: %ld\n", nValue);
|
|
if ((nValue >= 0) && (nValue <= 65535))
|
|
{
|
|
PasswordInfo->MinPasswordLength = nValue;
|
|
}
|
|
DPRINT("MinimumPasswordLength (NewValue) : %lu\n", PasswordInfo->MinPasswordLength);
|
|
}
|
|
}
|
|
|
|
DPRINT("PasswordHistoryLength (OldValue) : %lu\n", PasswordInfo->PasswordHistoryLength);
|
|
if (SetupFindFirstLineW(hSecurityInf,
|
|
pszSectionName,
|
|
L"PasswordHistorySize",
|
|
&InfContext))
|
|
{
|
|
if (SetupGetIntField(&InfContext, 1, &nValue))
|
|
{
|
|
DPRINT("Value: %ld\n", nValue);
|
|
if ((nValue >= 0) && (nValue <= 65535))
|
|
{
|
|
PasswordInfo->PasswordHistoryLength = nValue;
|
|
}
|
|
DPRINT("PasswordHistoryLength (NewValue) : %lu\n", PasswordInfo->PasswordHistoryLength);
|
|
}
|
|
}
|
|
|
|
if (SetupFindFirstLineW(hSecurityInf,
|
|
pszSectionName,
|
|
L"PasswordComplexity",
|
|
&InfContext))
|
|
{
|
|
if (SetupGetIntField(&InfContext, 1, &nValue))
|
|
{
|
|
if (nValue == 0)
|
|
{
|
|
PasswordInfo->PasswordProperties &= ~DOMAIN_PASSWORD_COMPLEX;
|
|
}
|
|
else
|
|
{
|
|
PasswordInfo->PasswordProperties |= DOMAIN_PASSWORD_COMPLEX;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (SetupFindFirstLineW(hSecurityInf,
|
|
pszSectionName,
|
|
L"ClearTextPassword",
|
|
&InfContext))
|
|
{
|
|
if (SetupGetIntField(&InfContext, 1, &nValue))
|
|
{
|
|
if (nValue == 0)
|
|
{
|
|
PasswordInfo->PasswordProperties &= ~DOMAIN_PASSWORD_STORE_CLEARTEXT;
|
|
}
|
|
else
|
|
{
|
|
PasswordInfo->PasswordProperties |= DOMAIN_PASSWORD_STORE_CLEARTEXT;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Windows ignores the RequireLogonToChangePassword option */
|
|
|
|
Status = SamSetInformationDomain(DomainHandle,
|
|
DomainPasswordInformation,
|
|
PasswordInfo);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
DPRINT1("SamSetInformationDomain() failed (Status %08lx)\n", Status);
|
|
goto done;
|
|
}
|
|
|
|
done:
|
|
if (PasswordInfo != NULL)
|
|
SamFreeMemory(PasswordInfo);
|
|
|
|
if (DomainHandle != NULL)
|
|
SamCloseHandle(DomainHandle);
|
|
|
|
if (ServerHandle != NULL)
|
|
SamCloseHandle(ServerHandle);
|
|
|
|
if (OrigInfo != NULL)
|
|
LsaFreeMemory(OrigInfo);
|
|
|
|
if (PolicyHandle != NULL)
|
|
LsaClose(PolicyHandle);
|
|
}
|
|
|
|
|
|
static
|
|
VOID
|
|
ApplyLockoutSettings(
|
|
_In_ HINF hSecurityInf,
|
|
_In_ PWSTR pszSectionName)
|
|
{
|
|
INFCONTEXT InfContext;
|
|
PDOMAIN_LOCKOUT_INFORMATION LockoutInfo = NULL;
|
|
PPOLICY_ACCOUNT_DOMAIN_INFO OrigInfo = NULL;
|
|
LSA_OBJECT_ATTRIBUTES ObjectAttributes;
|
|
LSA_HANDLE PolicyHandle = NULL;
|
|
SAM_HANDLE ServerHandle = NULL;
|
|
SAM_HANDLE DomainHandle = NULL;
|
|
INT nValue;
|
|
NTSTATUS Status;
|
|
|
|
DPRINT("ApplyLockoutSettings()\n");
|
|
|
|
memset(&ObjectAttributes, 0, sizeof(LSA_OBJECT_ATTRIBUTES));
|
|
ObjectAttributes.Length = sizeof(LSA_OBJECT_ATTRIBUTES);
|
|
|
|
Status = LsaOpenPolicy(NULL,
|
|
&ObjectAttributes,
|
|
POLICY_VIEW_LOCAL_INFORMATION | POLICY_TRUST_ADMIN,
|
|
&PolicyHandle);
|
|
if (Status != STATUS_SUCCESS)
|
|
{
|
|
DPRINT1("LsaOpenPolicy() failed (Status: 0x%08lx)\n", Status);
|
|
return;
|
|
}
|
|
|
|
Status = LsaQueryInformationPolicy(PolicyHandle,
|
|
PolicyAccountDomainInformation,
|
|
(PVOID *)&OrigInfo);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
DPRINT1("LsaQueryInformationPolicy() failed (Status: 0x%08lx)\n", Status);
|
|
goto done;
|
|
}
|
|
|
|
Status = SamConnect(NULL,
|
|
&ServerHandle,
|
|
SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN,
|
|
NULL);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
DPRINT1("SamConnect() failed (Status: 0x%08lx)\n", Status);
|
|
goto done;
|
|
}
|
|
|
|
Status = SamOpenDomain(ServerHandle,
|
|
DOMAIN_READ_PASSWORD_PARAMETERS | DOMAIN_WRITE_PASSWORD_PARAMS,
|
|
OrigInfo->DomainSid,
|
|
&DomainHandle);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
DPRINT1("SamOpenDomain() failed (Status: 0x%08lx)\n", Status);
|
|
goto done;
|
|
}
|
|
|
|
Status = SamQueryInformationDomain(DomainHandle,
|
|
DomainLockoutInformation,
|
|
(PVOID*)&LockoutInfo);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
DPRINT1("SamQueryInformationDomain() failed (Status %08lx)\n", Status);
|
|
goto done;
|
|
}
|
|
|
|
if (SetupFindFirstLineW(hSecurityInf,
|
|
pszSectionName,
|
|
L"LockoutBadCount",
|
|
&InfContext))
|
|
{
|
|
if (SetupGetIntField(&InfContext, 1, &nValue))
|
|
{
|
|
if (nValue >= 0)
|
|
{
|
|
LockoutInfo->LockoutThreshold = nValue;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (SetupFindFirstLineW(hSecurityInf,
|
|
pszSectionName,
|
|
L"ResetLockoutCount",
|
|
&InfContext))
|
|
{
|
|
if (SetupGetIntField(&InfContext, 1, &nValue))
|
|
{
|
|
if (nValue >= 0)
|
|
{
|
|
LockoutInfo->LockoutObservationWindow.QuadPart = (LONGLONG)nValue * TICKS_PER_MINUTE;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (SetupFindFirstLineW(hSecurityInf,
|
|
pszSectionName,
|
|
L"LockoutDuration",
|
|
&InfContext))
|
|
{
|
|
if (SetupGetIntField(&InfContext, 1, &nValue))
|
|
{
|
|
if (nValue == -1)
|
|
{
|
|
LockoutInfo->LockoutDuration.QuadPart = 0x8000000000000000LL;
|
|
}
|
|
else if ((nValue >= 0) && (nValue < 100000))
|
|
{
|
|
LockoutInfo->LockoutDuration.QuadPart = (LONGLONG)nValue * TICKS_PER_MINUTE;
|
|
}
|
|
}
|
|
}
|
|
|
|
Status = SamSetInformationDomain(DomainHandle,
|
|
DomainLockoutInformation,
|
|
LockoutInfo);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
DPRINT1("SamSetInformationDomain() failed (Status %08lx)\n", Status);
|
|
goto done;
|
|
}
|
|
|
|
done:
|
|
if (LockoutInfo != NULL)
|
|
SamFreeMemory(LockoutInfo);
|
|
|
|
if (DomainHandle != NULL)
|
|
SamCloseHandle(DomainHandle);
|
|
|
|
if (ServerHandle != NULL)
|
|
SamCloseHandle(ServerHandle);
|
|
|
|
if (OrigInfo != NULL)
|
|
LsaFreeMemory(OrigInfo);
|
|
|
|
if (PolicyHandle != NULL)
|
|
LsaClose(PolicyHandle);
|
|
}
|
|
|
|
|
|
static
|
|
VOID
|
|
SetLsaAnonymousNameLookup(
|
|
_In_ HINF hSecurityInf,
|
|
_In_ PWSTR pszSectionName)
|
|
{
|
|
#if 0
|
|
INFCONTEXT InfContext;
|
|
INT nValue = 0;
|
|
|
|
DPRINT1("SetLsaAnonymousNameLookup()\n");
|
|
|
|
if (!SetupFindFirstLineW(hSecurityInf,
|
|
pszSectionName,
|
|
L"LSAAnonymousNameLookup",
|
|
&InfContext))
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (!SetupGetIntField(&InfContext, 1, &nValue))
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (nValue == 0)
|
|
{
|
|
}
|
|
else
|
|
{
|
|
}
|
|
#endif
|
|
}
|
|
|
|
|
|
static
|
|
VOID
|
|
EnableAccount(
|
|
_In_ HINF hSecurityInf,
|
|
_In_ PWSTR pszSectionName,
|
|
_In_ PWSTR pszValueName,
|
|
_In_ SAM_HANDLE DomainHandle,
|
|
_In_ DWORD dwAccountRid)
|
|
{
|
|
INFCONTEXT InfContext;
|
|
SAM_HANDLE UserHandle = NULL;
|
|
PUSER_CONTROL_INFORMATION ControlInfo = NULL;
|
|
INT nValue = 0;
|
|
NTSTATUS Status;
|
|
|
|
DPRINT("EnableAccount()\n");
|
|
|
|
if (!SetupFindFirstLineW(hSecurityInf,
|
|
pszSectionName,
|
|
pszValueName,
|
|
&InfContext))
|
|
return;
|
|
|
|
if (!SetupGetIntField(&InfContext, 1, &nValue))
|
|
{
|
|
DPRINT1("No valid integer value\n");
|
|
goto done;
|
|
}
|
|
|
|
DPRINT("Value: %d\n", nValue);
|
|
|
|
Status = SamOpenUser(DomainHandle,
|
|
USER_READ_ACCOUNT | USER_WRITE_ACCOUNT,
|
|
dwAccountRid,
|
|
&UserHandle);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
DPRINT1("SamOpenUser() failed (Status: 0x%08lx)\n", Status);
|
|
goto done;
|
|
}
|
|
|
|
Status = SamQueryInformationUser(UserHandle,
|
|
UserControlInformation,
|
|
(PVOID*)&ControlInfo);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
DPRINT1("SamQueryInformationUser() failed (Status: 0x%08lx)\n", Status);
|
|
goto done;
|
|
}
|
|
|
|
if (nValue == 0)
|
|
{
|
|
ControlInfo->UserAccountControl |= USER_ACCOUNT_DISABLED;
|
|
}
|
|
else
|
|
{
|
|
ControlInfo->UserAccountControl &= ~USER_ACCOUNT_DISABLED;
|
|
}
|
|
|
|
Status = SamSetInformationUser(UserHandle,
|
|
UserControlInformation,
|
|
ControlInfo);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
DPRINT1("SamSetInformationUser() failed (Status: 0x%08lx)\n", Status);
|
|
}
|
|
|
|
done:
|
|
if (ControlInfo != NULL)
|
|
SamFreeMemory(ControlInfo);
|
|
|
|
if (UserHandle != NULL)
|
|
SamCloseHandle(UserHandle);
|
|
}
|
|
|
|
|
|
static
|
|
VOID
|
|
SetNewAccountName(
|
|
_In_ HINF hSecurityInf,
|
|
_In_ PWSTR pszSectionName,
|
|
_In_ PWSTR pszValueName,
|
|
_In_ SAM_HANDLE DomainHandle,
|
|
_In_ DWORD dwAccountRid)
|
|
{
|
|
INFCONTEXT InfContext;
|
|
DWORD dwLength = 0;
|
|
PWSTR pszName = NULL;
|
|
SAM_HANDLE UserHandle = NULL;
|
|
USER_NAME_INFORMATION NameInfo;
|
|
NTSTATUS Status;
|
|
|
|
DPRINT("SetNewAccountName()\n");
|
|
|
|
if (!SetupFindFirstLineW(hSecurityInf,
|
|
pszSectionName,
|
|
pszValueName,
|
|
&InfContext))
|
|
return;
|
|
|
|
SetupGetStringFieldW(&InfContext,
|
|
1,
|
|
NULL,
|
|
0,
|
|
&dwLength);
|
|
if (dwLength == 0)
|
|
return;
|
|
|
|
ASSERT(dwLength <= UNICODE_STRING_MAX_CHARS);
|
|
|
|
pszName = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwLength * sizeof(WCHAR));
|
|
if (pszName == NULL)
|
|
{
|
|
DPRINT1("HeapAlloc() failed\n");
|
|
return;
|
|
}
|
|
|
|
if (!SetupGetStringFieldW(&InfContext,
|
|
1,
|
|
pszName,
|
|
dwLength,
|
|
&dwLength))
|
|
{
|
|
DPRINT1("No valid string value\n");
|
|
goto done;
|
|
}
|
|
|
|
DPRINT("NewAccountName: '%S'\n", pszName);
|
|
|
|
Status = SamOpenUser(DomainHandle,
|
|
USER_WRITE_ACCOUNT,
|
|
dwAccountRid,
|
|
&UserHandle);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
DPRINT1("SamOpenUser() failed (Status: 0x%08lx)\n", Status);
|
|
goto done;
|
|
}
|
|
|
|
NameInfo.UserName.Length = (USHORT)wcslen(pszName) * sizeof(WCHAR);
|
|
NameInfo.UserName.MaximumLength = NameInfo.UserName.Length + sizeof(WCHAR);
|
|
NameInfo.UserName.Buffer = pszName;
|
|
NameInfo.FullName.Length = 0;
|
|
NameInfo.FullName.MaximumLength = 0;
|
|
NameInfo.FullName.Buffer = NULL;
|
|
|
|
Status = SamSetInformationUser(UserHandle,
|
|
UserNameInformation,
|
|
&NameInfo);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
DPRINT1("SamSetInformationUser() failed (Status: 0x%08lx)\n", Status);
|
|
}
|
|
|
|
done:
|
|
if (UserHandle != NULL)
|
|
SamCloseHandle(UserHandle);
|
|
|
|
if (pszName != NULL)
|
|
HeapFree(GetProcessHeap(), 0, pszName);
|
|
}
|
|
|
|
|
|
static
|
|
VOID
|
|
ApplyAccountSettings(
|
|
_In_ HINF hSecurityInf,
|
|
_In_ PWSTR pszSectionName)
|
|
{
|
|
PPOLICY_ACCOUNT_DOMAIN_INFO OrigInfo = NULL;
|
|
LSA_OBJECT_ATTRIBUTES ObjectAttributes;
|
|
LSA_HANDLE PolicyHandle = NULL;
|
|
SAM_HANDLE ServerHandle = NULL;
|
|
SAM_HANDLE DomainHandle = NULL;
|
|
NTSTATUS Status;
|
|
|
|
DPRINT("ApplyAccountSettings()\n");
|
|
|
|
memset(&ObjectAttributes, 0, sizeof(LSA_OBJECT_ATTRIBUTES));
|
|
ObjectAttributes.Length = sizeof(LSA_OBJECT_ATTRIBUTES);
|
|
|
|
Status = LsaOpenPolicy(NULL,
|
|
&ObjectAttributes,
|
|
POLICY_VIEW_LOCAL_INFORMATION | POLICY_TRUST_ADMIN,
|
|
&PolicyHandle);
|
|
if (Status != STATUS_SUCCESS)
|
|
{
|
|
DPRINT1("LsaOpenPolicy() failed (Status: 0x%08lx)\n", Status);
|
|
return;
|
|
}
|
|
|
|
Status = LsaQueryInformationPolicy(PolicyHandle,
|
|
PolicyAccountDomainInformation,
|
|
(PVOID *)&OrigInfo);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
DPRINT1("LsaQueryInformationPolicy() failed (Status: 0x%08lx)\n", Status);
|
|
goto done;
|
|
}
|
|
|
|
Status = SamConnect(NULL,
|
|
&ServerHandle,
|
|
SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN,
|
|
NULL);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
DPRINT1("SamConnect() failed (Status: 0x%08lx)\n", Status);
|
|
goto done;
|
|
}
|
|
|
|
Status = SamOpenDomain(ServerHandle,
|
|
DOMAIN_LOOKUP,
|
|
OrigInfo->DomainSid,
|
|
&DomainHandle);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
DPRINT1("SamOpenDomain() failed (Status: 0x%08lx)\n", Status);
|
|
goto done;
|
|
}
|
|
|
|
SetLsaAnonymousNameLookup(hSecurityInf,
|
|
pszSectionName);
|
|
|
|
EnableAccount(hSecurityInf,
|
|
pszSectionName,
|
|
L"EnableAdminAccount",
|
|
DomainHandle,
|
|
DOMAIN_USER_RID_ADMIN);
|
|
|
|
EnableAccount(hSecurityInf,
|
|
pszSectionName,
|
|
L"EnableGuestAccount",
|
|
DomainHandle,
|
|
DOMAIN_USER_RID_GUEST);
|
|
|
|
SetNewAccountName(hSecurityInf,
|
|
pszSectionName,
|
|
L"NewAdministratorName",
|
|
DomainHandle,
|
|
DOMAIN_USER_RID_ADMIN);
|
|
|
|
SetNewAccountName(hSecurityInf,
|
|
pszSectionName,
|
|
L"NewGuestName",
|
|
DomainHandle,
|
|
DOMAIN_USER_RID_GUEST);
|
|
|
|
done:
|
|
if (DomainHandle != NULL)
|
|
SamCloseHandle(DomainHandle);
|
|
|
|
if (ServerHandle != NULL)
|
|
SamCloseHandle(ServerHandle);
|
|
|
|
if (OrigInfo != NULL)
|
|
LsaFreeMemory(OrigInfo);
|
|
|
|
if (PolicyHandle != NULL)
|
|
LsaClose(PolicyHandle);
|
|
}
|
|
|
|
|
|
static
|
|
VOID
|
|
ApplyAuditEvents(
|
|
_In_ HINF hSecurityInf)
|
|
{
|
|
LSA_OBJECT_ATTRIBUTES ObjectAttributes;
|
|
INFCONTEXT InfContext;
|
|
WCHAR szOptionName[256];
|
|
INT nValue;
|
|
LSA_HANDLE PolicyHandle = NULL;
|
|
POLICY_AUDIT_EVENTS_INFO AuditInfo;
|
|
PULONG AuditOptions = NULL;
|
|
NTSTATUS Status;
|
|
|
|
DPRINT("ApplyAuditEvents(%p)\n", hSecurityInf);
|
|
|
|
if (!SetupFindFirstLineW(hSecurityInf,
|
|
L"Event Audit",
|
|
NULL,
|
|
&InfContext))
|
|
{
|
|
DPRINT1("SetupFindFirstLineW failed\n");
|
|
return;
|
|
}
|
|
|
|
ZeroMemory(&ObjectAttributes, sizeof(LSA_OBJECT_ATTRIBUTES));
|
|
|
|
Status = LsaOpenPolicy(NULL,
|
|
&ObjectAttributes,
|
|
POLICY_SET_AUDIT_REQUIREMENTS,
|
|
&PolicyHandle);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
DPRINT1("LsaOpenPolicy failed (Status %08lx)\n", Status);
|
|
return;
|
|
}
|
|
|
|
AuditOptions = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
|
|
(AuditCategoryAccountLogon + 1) * sizeof(ULONG));
|
|
if (AuditOptions == NULL)
|
|
{
|
|
DPRINT1("Failed to allocate the auditiing options array!\n");
|
|
goto done;
|
|
}
|
|
|
|
AuditInfo.AuditingMode = TRUE;
|
|
AuditInfo.EventAuditingOptions = AuditOptions;
|
|
AuditInfo.MaximumAuditEventCount = AuditCategoryAccountLogon + 1;
|
|
|
|
do
|
|
{
|
|
/* Retrieve the group name */
|
|
if (!SetupGetStringFieldW(&InfContext,
|
|
0,
|
|
szOptionName,
|
|
ARRAYSIZE(szOptionName),
|
|
NULL))
|
|
{
|
|
DPRINT1("SetupGetStringFieldW() failed\n");
|
|
continue;
|
|
}
|
|
|
|
DPRINT("Option: '%S'\n", szOptionName);
|
|
|
|
if (!SetupGetIntField(&InfContext,
|
|
1,
|
|
&nValue))
|
|
{
|
|
DPRINT1("SetupGetStringFieldW() failed\n");
|
|
continue;
|
|
}
|
|
|
|
DPRINT("Value: %d\n", nValue);
|
|
|
|
if ((nValue < POLICY_AUDIT_EVENT_UNCHANGED) || (nValue > POLICY_AUDIT_EVENT_NONE))
|
|
{
|
|
DPRINT1("Invalid audit option!\n");
|
|
continue;
|
|
}
|
|
|
|
if (_wcsicmp(szOptionName, L"AuditSystemEvents") == 0)
|
|
{
|
|
AuditOptions[AuditCategorySystem] = (ULONG)nValue;
|
|
}
|
|
else if (_wcsicmp(szOptionName, L"AuditLogonEvents") == 0)
|
|
{
|
|
AuditOptions[AuditCategoryLogon] = (ULONG)nValue;
|
|
}
|
|
else if (_wcsicmp(szOptionName, L"AuditObjectAccess") == 0)
|
|
{
|
|
AuditOptions[AuditCategoryObjectAccess] = (ULONG)nValue;
|
|
}
|
|
else if (_wcsicmp(szOptionName, L"AuditPrivilegeUse") == 0)
|
|
{
|
|
AuditOptions[AuditCategoryPrivilegeUse] = (ULONG)nValue;
|
|
}
|
|
else if (_wcsicmp(szOptionName, L"AuditProcessTracking") == 0)
|
|
{
|
|
AuditOptions[AuditCategoryDetailedTracking] = (ULONG)nValue;
|
|
}
|
|
else if (_wcsicmp(szOptionName, L"AuditPolicyChange") == 0)
|
|
{
|
|
AuditOptions[AuditCategoryPolicyChange] = (ULONG)nValue;
|
|
}
|
|
else if (_wcsicmp(szOptionName, L"AuditAccountManage") == 0)
|
|
{
|
|
AuditOptions[AuditCategoryAccountManagement] = (ULONG)nValue;
|
|
}
|
|
else if (_wcsicmp(szOptionName, L"AuditDSAccess") == 0)
|
|
{
|
|
AuditOptions[AuditCategoryDirectoryServiceAccess] = (ULONG)nValue;
|
|
}
|
|
else if (_wcsicmp(szOptionName, L"AuditAccountLogon") == 0)
|
|
{
|
|
AuditOptions[AuditCategoryAccountLogon] = (ULONG)nValue;
|
|
}
|
|
else
|
|
{
|
|
DPRINT1("Invalid auditing option '%S'\n", szOptionName);
|
|
}
|
|
}
|
|
while (SetupFindNextLine(&InfContext, &InfContext));
|
|
|
|
Status = LsaSetInformationPolicy(PolicyHandle,
|
|
PolicyAuditEventsInformation,
|
|
(PVOID)&AuditInfo);
|
|
if (Status != STATUS_SUCCESS)
|
|
{
|
|
DPRINT1("LsaSetInformationPolicy() failed (Status 0x%08lx)\n", Status);
|
|
}
|
|
|
|
done:
|
|
if (AuditOptions != NULL)
|
|
HeapFree(GetProcessHeap(), 0, AuditOptions);
|
|
|
|
if (PolicyHandle != NULL)
|
|
LsaClose(PolicyHandle);
|
|
}
|
|
|
|
|
|
VOID
|
|
InstallSecurity(VOID)
|
|
{
|
|
HINF hSecurityInf;
|
|
PWSTR pszSecurityInf;
|
|
|
|
// if (IsServer())
|
|
// pszSecurityInf = L"defltsv.inf";
|
|
// else
|
|
pszSecurityInf = L"defltwk.inf";
|
|
|
|
InstallBuiltinAccounts();
|
|
|
|
hSecurityInf = SetupOpenInfFileW(pszSecurityInf,
|
|
NULL,
|
|
INF_STYLE_WIN4,
|
|
NULL);
|
|
if (hSecurityInf != INVALID_HANDLE_VALUE)
|
|
{
|
|
InstallPrivileges(hSecurityInf);
|
|
ApplyRegistryValues(hSecurityInf);
|
|
|
|
ApplyEventlogSettings(hSecurityInf, L"Application Log", L"Application");
|
|
ApplyEventlogSettings(hSecurityInf, L"Security Log", L"Security");
|
|
ApplyEventlogSettings(hSecurityInf, L"System Log", L"System");
|
|
|
|
ApplyPasswordSettings(hSecurityInf, L"System Access");
|
|
ApplyLockoutSettings(hSecurityInf, L"System Access");
|
|
ApplyAccountSettings(hSecurityInf, L"System Access");
|
|
|
|
ApplyAuditEvents(hSecurityInf);
|
|
|
|
SetupCloseInfFile(hSecurityInf);
|
|
}
|
|
|
|
/* Hack */
|
|
SetPrimaryDomain(L"WORKGROUP", NULL);
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
SetAdministratorPassword(LPCWSTR Password)
|
|
{
|
|
PPOLICY_ACCOUNT_DOMAIN_INFO OrigInfo = NULL;
|
|
PUSER_ACCOUNT_NAME_INFORMATION AccountNameInfo = NULL;
|
|
USER_SET_PASSWORD_INFORMATION PasswordInfo;
|
|
LSA_OBJECT_ATTRIBUTES ObjectAttributes;
|
|
LSA_HANDLE PolicyHandle = NULL;
|
|
SAM_HANDLE ServerHandle = NULL;
|
|
SAM_HANDLE DomainHandle = NULL;
|
|
SAM_HANDLE UserHandle = NULL;
|
|
NTSTATUS Status;
|
|
|
|
DPRINT("SYSSETUP: SetAdministratorPassword(%p)\n", Password);
|
|
|
|
memset(&ObjectAttributes, 0, sizeof(LSA_OBJECT_ATTRIBUTES));
|
|
ObjectAttributes.Length = sizeof(LSA_OBJECT_ATTRIBUTES);
|
|
|
|
Status = LsaOpenPolicy(NULL,
|
|
&ObjectAttributes,
|
|
POLICY_VIEW_LOCAL_INFORMATION | POLICY_TRUST_ADMIN,
|
|
&PolicyHandle);
|
|
if (Status != STATUS_SUCCESS)
|
|
{
|
|
DPRINT1("LsaOpenPolicy() failed (Status: 0x%08lx)\n", Status);
|
|
return Status;
|
|
}
|
|
|
|
Status = LsaQueryInformationPolicy(PolicyHandle,
|
|
PolicyAccountDomainInformation,
|
|
(PVOID *)&OrigInfo);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
DPRINT1("LsaQueryInformationPolicy() failed (Status: 0x%08lx)\n", Status);
|
|
goto done;
|
|
}
|
|
|
|
Status = SamConnect(NULL,
|
|
&ServerHandle,
|
|
SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN,
|
|
NULL);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
DPRINT1("SamConnect() failed (Status: 0x%08lx)\n", Status);
|
|
goto done;
|
|
}
|
|
|
|
Status = SamOpenDomain(ServerHandle,
|
|
DOMAIN_LOOKUP,
|
|
OrigInfo->DomainSid,
|
|
&DomainHandle);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
DPRINT1("SamOpenDomain() failed (Status: 0x%08lx)\n", Status);
|
|
goto done;
|
|
}
|
|
|
|
Status = SamOpenUser(DomainHandle,
|
|
USER_FORCE_PASSWORD_CHANGE | USER_READ_GENERAL,
|
|
DOMAIN_USER_RID_ADMIN,
|
|
&UserHandle);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
DPRINT1("SamOpenUser() failed (Status %08lx)\n", Status);
|
|
goto done;
|
|
}
|
|
|
|
RtlInitUnicodeString(&PasswordInfo.Password, Password);
|
|
PasswordInfo.PasswordExpired = FALSE;
|
|
|
|
Status = SamSetInformationUser(UserHandle,
|
|
UserSetPasswordInformation,
|
|
&PasswordInfo);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
DPRINT1("SamSetInformationUser() failed (Status %08lx)\n", Status);
|
|
goto done;
|
|
}
|
|
|
|
Status = SamQueryInformationUser(UserHandle,
|
|
UserAccountNameInformation,
|
|
(PVOID*)&AccountNameInfo);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
DPRINT1("SamQueryInformationUser() failed (Status 0x%08lx)\n", Status);
|
|
goto done;
|
|
}
|
|
|
|
AdminInfo.Name = RtlAllocateHeap(RtlGetProcessHeap(),
|
|
HEAP_ZERO_MEMORY,
|
|
AccountNameInfo->UserName.Length + sizeof(WCHAR));
|
|
if (AdminInfo.Name != NULL)
|
|
RtlCopyMemory(AdminInfo.Name,
|
|
AccountNameInfo->UserName.Buffer,
|
|
AccountNameInfo->UserName.Length);
|
|
|
|
AdminInfo.Domain = RtlAllocateHeap(RtlGetProcessHeap(),
|
|
HEAP_ZERO_MEMORY,
|
|
OrigInfo->DomainName.Length + sizeof(WCHAR));
|
|
if (AdminInfo.Domain != NULL)
|
|
RtlCopyMemory(AdminInfo.Domain,
|
|
OrigInfo->DomainName.Buffer,
|
|
OrigInfo->DomainName.Length);
|
|
|
|
AdminInfo.Password = RtlAllocateHeap(RtlGetProcessHeap(),
|
|
0,
|
|
(wcslen(Password) + 1) * sizeof(WCHAR));
|
|
if (AdminInfo.Password != NULL)
|
|
wcscpy(AdminInfo.Password, Password);
|
|
|
|
DPRINT("Administrator Name: %S\n", AdminInfo.Name);
|
|
DPRINT("Administrator Domain: %S\n", AdminInfo.Domain);
|
|
DPRINT("Administrator Password: %S\n", AdminInfo.Password);
|
|
|
|
done:
|
|
if (AccountNameInfo != NULL)
|
|
SamFreeMemory(AccountNameInfo);
|
|
|
|
if (OrigInfo != NULL)
|
|
LsaFreeMemory(OrigInfo);
|
|
|
|
if (PolicyHandle != NULL)
|
|
LsaClose(PolicyHandle);
|
|
|
|
if (UserHandle != NULL)
|
|
SamCloseHandle(UserHandle);
|
|
|
|
if (DomainHandle != NULL)
|
|
SamCloseHandle(DomainHandle);
|
|
|
|
if (ServerHandle != NULL)
|
|
SamCloseHandle(ServerHandle);
|
|
|
|
DPRINT1("SYSSETUP: SetAdministratorPassword() done (Status %08lx)\n", Status);
|
|
|
|
return Status;
|
|
}
|
|
|
|
|
|
VOID
|
|
SetAutoAdminLogon(VOID)
|
|
{
|
|
WCHAR szAutoAdminLogon[2];
|
|
HKEY hKey = NULL;
|
|
DWORD dwType;
|
|
DWORD dwSize;
|
|
LONG lError;
|
|
|
|
lError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
|
|
L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
|
|
0,
|
|
KEY_READ | KEY_WRITE,
|
|
&hKey);
|
|
if (lError != ERROR_SUCCESS)
|
|
return;
|
|
|
|
dwSize = 2 * sizeof(WCHAR);
|
|
lError = RegQueryValueExW(hKey,
|
|
L"AutoAdminLogon",
|
|
NULL,
|
|
&dwType,
|
|
(LPBYTE)szAutoAdminLogon,
|
|
&dwSize);
|
|
if (lError != ERROR_SUCCESS)
|
|
goto done;
|
|
|
|
if (wcscmp(szAutoAdminLogon, L"1") == 0)
|
|
{
|
|
RegSetValueExW(hKey,
|
|
L"DefaultDomainName",
|
|
0,
|
|
REG_SZ,
|
|
(LPBYTE)AdminInfo.Domain,
|
|
(wcslen(AdminInfo.Domain) + 1) * sizeof(WCHAR));
|
|
|
|
RegSetValueExW(hKey,
|
|
L"DefaultUserName",
|
|
0,
|
|
REG_SZ,
|
|
(LPBYTE)AdminInfo.Name,
|
|
(wcslen(AdminInfo.Name) + 1) * sizeof(WCHAR));
|
|
|
|
RegSetValueExW(hKey,
|
|
L"DefaultPassword",
|
|
0,
|
|
REG_SZ,
|
|
(LPBYTE)AdminInfo.Password,
|
|
(wcslen(AdminInfo.Password) + 1) * sizeof(WCHAR));
|
|
}
|
|
|
|
done:
|
|
if (hKey != NULL)
|
|
RegCloseKey(hKey);
|
|
}
|
|
|
|
|
|
/* EOF */
|
|
|