1406 lines
40 KiB
C++
1406 lines
40 KiB
C++
|
#include "stdafx.h"
|
||
|
#include "hydraoc.h"
|
||
|
#include "subcomp.h"
|
||
|
#include "secupgrd.h"
|
||
|
#include "lscsp.h"
|
||
|
#include <SHlWapi.h>
|
||
|
#include "reglic.h"
|
||
|
#include "cryptkey.h"
|
||
|
|
||
|
#define MSLICENSING_REG_KEY _T("SOFTWARE\\Microsoft\\MSLicensing")
|
||
|
|
||
|
typedef DWORD (*PSETENTRIESINACL)(
|
||
|
ULONG cCountOfExplicitEntries, // number of entries
|
||
|
PEXPLICIT_ACCESS pListOfExplicitEntries, // buffer
|
||
|
PACL OldAcl, // original ACL
|
||
|
PACL *NewAcl // new ACL
|
||
|
);
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
AddACLToObjectSecurityDescriptor(
|
||
|
HANDLE hObject,
|
||
|
SE_OBJECT_TYPE ObjectType
|
||
|
)
|
||
|
{
|
||
|
SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
|
||
|
SID_IDENTIFIER_AUTHORITY CreatorAuthority = SECURITY_CREATOR_SID_AUTHORITY;
|
||
|
PSID pAdminSid = NULL;
|
||
|
PSID pSystemSid = NULL;
|
||
|
PSID pPowerUsersSid = NULL;
|
||
|
PSID pCreatorSid = NULL;
|
||
|
PSID pUsersSid = NULL;
|
||
|
PACL pNewDACL;
|
||
|
|
||
|
DWORD dwError;
|
||
|
BOOL bSuccess;
|
||
|
|
||
|
DWORD i;
|
||
|
|
||
|
PALLOCATEANDINITIALIZESID_FN pAllocateAndInitializeSid = NULL;
|
||
|
PSETENTRIESINACL pSetEntriesInAcl = NULL;
|
||
|
HMODULE pAdvApi32 = NULL;
|
||
|
PFREESID_FN pFreeSid = NULL;
|
||
|
|
||
|
PSETSECURITYINFO_FN pSetSecurityInfo;
|
||
|
|
||
|
pAdvApi32 = LoadLibrary(ADVAPI_32_DLL);
|
||
|
if (!pAdvApi32) {
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
pAllocateAndInitializeSid = (PALLOCATEANDINITIALIZESID_FN)
|
||
|
GetProcAddress(pAdvApi32,
|
||
|
ALLOCATE_AND_INITITIALIZE_SID);
|
||
|
if (pAllocateAndInitializeSid == NULL)
|
||
|
{
|
||
|
goto ErrorCleanup;
|
||
|
}
|
||
|
|
||
|
#ifdef UNICODE
|
||
|
pSetEntriesInAcl = reinterpret_cast<PSETENTRIESINACL>(GetProcAddress( pAdvApi32, "SetEntriesInAclW" ));
|
||
|
#else
|
||
|
pSetEntriesInAcl = reinterpret_cast<PSETENTRIESINACL>(GetProcAddress( pAdvApi32, "SetEntriesInAclA" ));
|
||
|
#endif
|
||
|
|
||
|
if (!pSetEntriesInAcl) {
|
||
|
FreeLibrary( pAdvApi32 );
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
EXPLICIT_ACCESS ExplicitAccess[5];
|
||
|
//
|
||
|
// Create SIDs - Admins and System
|
||
|
//
|
||
|
|
||
|
bSuccess = pAllocateAndInitializeSid( &NtAuthority,
|
||
|
2,
|
||
|
SECURITY_BUILTIN_DOMAIN_RID,
|
||
|
DOMAIN_ALIAS_RID_ADMINS,
|
||
|
0, 0, 0, 0, 0, 0,
|
||
|
&pAdminSid);
|
||
|
|
||
|
bSuccess = bSuccess && pAllocateAndInitializeSid( &NtAuthority,
|
||
|
1,
|
||
|
SECURITY_LOCAL_SYSTEM_RID,
|
||
|
0, 0, 0, 0, 0, 0, 0,
|
||
|
&pSystemSid);
|
||
|
|
||
|
bSuccess = bSuccess && pAllocateAndInitializeSid( &NtAuthority,
|
||
|
2,
|
||
|
SECURITY_BUILTIN_DOMAIN_RID,
|
||
|
DOMAIN_ALIAS_RID_POWER_USERS,
|
||
|
0, 0, 0, 0, 0, 0,
|
||
|
&pPowerUsersSid);
|
||
|
|
||
|
bSuccess = bSuccess && pAllocateAndInitializeSid( &CreatorAuthority,
|
||
|
1,
|
||
|
SECURITY_CREATOR_OWNER_RID,
|
||
|
0, 0, 0, 0, 0, 0, 0,
|
||
|
&pCreatorSid);
|
||
|
|
||
|
bSuccess = bSuccess && pAllocateAndInitializeSid(&NtAuthority,
|
||
|
2,
|
||
|
SECURITY_BUILTIN_DOMAIN_RID,
|
||
|
DOMAIN_ALIAS_RID_USERS,
|
||
|
0, 0, 0, 0, 0, 0,
|
||
|
&pUsersSid);
|
||
|
|
||
|
if (bSuccess) {
|
||
|
|
||
|
//
|
||
|
// Initialize Access structures describing the ACEs we want:
|
||
|
// System Full Control
|
||
|
// Admins Full Control
|
||
|
//
|
||
|
// We'll take advantage of the fact that the unlocked private keys is
|
||
|
// the same as the device parameters key and they are a superset of the
|
||
|
// locked private keys.
|
||
|
//
|
||
|
// When we create the DACL for the private key we'll specify a subset of
|
||
|
// the ExplicitAccess array.
|
||
|
//
|
||
|
for (i = 0; i < 5; i++) {
|
||
|
ExplicitAccess[i].grfAccessMode = SET_ACCESS;
|
||
|
ExplicitAccess[i].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
|
||
|
ExplicitAccess[i].Trustee.pMultipleTrustee = NULL;
|
||
|
ExplicitAccess[i].Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
|
||
|
ExplicitAccess[i].Trustee.TrusteeForm = TRUSTEE_IS_SID;
|
||
|
ExplicitAccess[i].Trustee.TrusteeType = TRUSTEE_IS_GROUP;
|
||
|
}
|
||
|
ExplicitAccess[0].grfAccessPermissions = KEY_ALL_ACCESS;
|
||
|
ExplicitAccess[0].Trustee.ptstrName = (LPTSTR)pAdminSid;
|
||
|
|
||
|
ExplicitAccess[1].grfAccessPermissions = KEY_ALL_ACCESS;
|
||
|
ExplicitAccess[1].Trustee.ptstrName = (LPTSTR)pSystemSid;
|
||
|
|
||
|
ExplicitAccess[2].grfAccessPermissions = KEY_ALL_ACCESS;
|
||
|
ExplicitAccess[2].Trustee.ptstrName = (LPTSTR)pCreatorSid;
|
||
|
|
||
|
ExplicitAccess[3].grfAccessPermissions = GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | DELETE;
|
||
|
ExplicitAccess[3].Trustee.ptstrName = (LPTSTR)pPowerUsersSid;
|
||
|
|
||
|
ExplicitAccess[4].grfAccessPermissions = GENERIC_READ;
|
||
|
ExplicitAccess[4].Trustee.ptstrName = (LPTSTR)pUsersSid;
|
||
|
|
||
|
dwError = (DWORD)pSetEntriesInAcl( 5,
|
||
|
ExplicitAccess,
|
||
|
NULL,
|
||
|
&pNewDACL );
|
||
|
|
||
|
pSetSecurityInfo = (PSETSECURITYINFO_FN)GetProcAddress(pAdvApi32,SET_SECURITY_INFO);
|
||
|
|
||
|
if (pSetSecurityInfo == NULL)
|
||
|
{
|
||
|
OutputDebugString(_T("AddSidToObjectsSecurityDescriptor: Can't get proc SetSecurityInfo"));
|
||
|
goto ErrorCleanup;
|
||
|
}
|
||
|
|
||
|
dwError = pSetSecurityInfo(
|
||
|
hObject,
|
||
|
ObjectType,
|
||
|
DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
pNewDACL,
|
||
|
NULL
|
||
|
);
|
||
|
|
||
|
}
|
||
|
ErrorCleanup:
|
||
|
|
||
|
pFreeSid = (PFREESID_FN)
|
||
|
GetProcAddress(pAdvApi32,
|
||
|
FREE_SID);
|
||
|
|
||
|
if(pAdminSid)
|
||
|
pFreeSid(pAdminSid);
|
||
|
if(pSystemSid)
|
||
|
pFreeSid(pSystemSid);
|
||
|
if(pPowerUsersSid)
|
||
|
pFreeSid(pPowerUsersSid);
|
||
|
if(pCreatorSid)
|
||
|
pFreeSid(pCreatorSid);
|
||
|
if(pUsersSid)
|
||
|
pFreeSid(pUsersSid);
|
||
|
if(pNewDACL)
|
||
|
LocalFree(pNewDACL);
|
||
|
|
||
|
|
||
|
if(pAdvApi32)
|
||
|
FreeLibrary( pAdvApi32 );
|
||
|
|
||
|
return bSuccess;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
AddACLToStoreObjectSecurityDescriptor(
|
||
|
HANDLE hObject,
|
||
|
SE_OBJECT_TYPE ObjectType
|
||
|
)
|
||
|
{
|
||
|
SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
|
||
|
SID_IDENTIFIER_AUTHORITY CreatorAuthority = SECURITY_CREATOR_SID_AUTHORITY;
|
||
|
PSID pAdminSid = NULL;
|
||
|
PSID pSystemSid = NULL;
|
||
|
PSID pPowerUsersSid = NULL;
|
||
|
PSID pCreatorSid = NULL;
|
||
|
PSID pUsersSid = NULL;
|
||
|
PACL pNewDACL;
|
||
|
|
||
|
DWORD dwError;
|
||
|
BOOL bSuccess;
|
||
|
|
||
|
DWORD i;
|
||
|
|
||
|
PALLOCATEANDINITIALIZESID_FN pAllocateAndInitializeSid = NULL;
|
||
|
PSETENTRIESINACL pSetEntriesInAcl = NULL;
|
||
|
HMODULE pAdvApi32 = NULL;
|
||
|
PFREESID_FN pFreeSid = NULL;
|
||
|
PSETSECURITYINFO_FN pSetSecurityInfo;
|
||
|
EXPLICIT_ACCESS ExplicitAccess[6];
|
||
|
|
||
|
pAdvApi32 = LoadLibrary(ADVAPI_32_DLL);
|
||
|
if (!pAdvApi32) {
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
pAllocateAndInitializeSid = (PALLOCATEANDINITIALIZESID_FN)
|
||
|
GetProcAddress(pAdvApi32,
|
||
|
ALLOCATE_AND_INITITIALIZE_SID);
|
||
|
if (pAllocateAndInitializeSid == NULL)
|
||
|
{
|
||
|
goto ErrorCleanup;
|
||
|
}
|
||
|
|
||
|
#ifdef UNICODE
|
||
|
pSetEntriesInAcl = reinterpret_cast<PSETENTRIESINACL>(GetProcAddress( pAdvApi32, "SetEntriesInAclW" ));
|
||
|
#else
|
||
|
pSetEntriesInAcl = reinterpret_cast<PSETENTRIESINACL>(GetProcAddress( pAdvApi32, "SetEntriesInAclA" ));
|
||
|
#endif
|
||
|
|
||
|
if (!pSetEntriesInAcl) {
|
||
|
FreeLibrary( pAdvApi32 );
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Create SIDs - Admins and System
|
||
|
//
|
||
|
|
||
|
bSuccess = pAllocateAndInitializeSid( &NtAuthority,
|
||
|
2,
|
||
|
SECURITY_BUILTIN_DOMAIN_RID,
|
||
|
DOMAIN_ALIAS_RID_ADMINS,
|
||
|
0, 0, 0, 0, 0, 0,
|
||
|
&pAdminSid);
|
||
|
|
||
|
bSuccess = bSuccess && pAllocateAndInitializeSid( &NtAuthority,
|
||
|
1,
|
||
|
SECURITY_LOCAL_SYSTEM_RID,
|
||
|
0, 0, 0, 0, 0, 0, 0,
|
||
|
&pSystemSid);
|
||
|
|
||
|
bSuccess = bSuccess && pAllocateAndInitializeSid( &NtAuthority,
|
||
|
2,
|
||
|
SECURITY_BUILTIN_DOMAIN_RID,
|
||
|
DOMAIN_ALIAS_RID_POWER_USERS,
|
||
|
0, 0, 0, 0, 0, 0,
|
||
|
&pPowerUsersSid);
|
||
|
|
||
|
bSuccess = bSuccess && pAllocateAndInitializeSid( &CreatorAuthority,
|
||
|
1,
|
||
|
SECURITY_CREATOR_OWNER_RID,
|
||
|
0, 0, 0, 0, 0, 0, 0,
|
||
|
&pCreatorSid);
|
||
|
|
||
|
bSuccess = bSuccess && pAllocateAndInitializeSid(&NtAuthority,
|
||
|
2,
|
||
|
SECURITY_BUILTIN_DOMAIN_RID,
|
||
|
DOMAIN_ALIAS_RID_USERS,
|
||
|
0, 0, 0, 0, 0, 0,
|
||
|
&pUsersSid);
|
||
|
|
||
|
if (bSuccess) {
|
||
|
|
||
|
//
|
||
|
// Initialize Access structures describing the ACEs we want:
|
||
|
// System Full Control
|
||
|
// Admins Full Control
|
||
|
//
|
||
|
// We'll take advantage of the fact that the unlocked private keys is
|
||
|
// the same as the device parameters key and they are a superset of the
|
||
|
// locked private keys.
|
||
|
//
|
||
|
// When we create the DACL for the private key we'll specify a subset of
|
||
|
// the ExplicitAccess array.
|
||
|
//
|
||
|
for (i = 0; i < 6; i++) {
|
||
|
ExplicitAccess[i].grfAccessMode = SET_ACCESS;
|
||
|
ExplicitAccess[i].Trustee.pMultipleTrustee = NULL;
|
||
|
ExplicitAccess[i].Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
|
||
|
ExplicitAccess[i].Trustee.TrusteeForm = TRUSTEE_IS_SID;
|
||
|
ExplicitAccess[i].Trustee.TrusteeType = TRUSTEE_IS_GROUP;
|
||
|
}
|
||
|
ExplicitAccess[0].grfAccessPermissions = KEY_ALL_ACCESS;
|
||
|
ExplicitAccess[0].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
|
||
|
ExplicitAccess[0].Trustee.ptstrName = (LPTSTR)pAdminSid;
|
||
|
|
||
|
ExplicitAccess[1].grfAccessPermissions = KEY_ALL_ACCESS;
|
||
|
ExplicitAccess[1].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
|
||
|
ExplicitAccess[1].Trustee.ptstrName = (LPTSTR)pSystemSid;
|
||
|
|
||
|
ExplicitAccess[2].grfAccessPermissions = KEY_ALL_ACCESS;
|
||
|
ExplicitAccess[2].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
|
||
|
ExplicitAccess[2].Trustee.ptstrName = (LPTSTR)pCreatorSid;
|
||
|
|
||
|
ExplicitAccess[3].grfAccessPermissions = GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | DELETE;
|
||
|
ExplicitAccess[3].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
|
||
|
ExplicitAccess[3].Trustee.ptstrName = (LPTSTR)pPowerUsersSid;
|
||
|
|
||
|
ExplicitAccess[4].grfAccessPermissions = GENERIC_READ | GENERIC_WRITE| KEY_CREATE_SUB_KEY |KEY_SET_VALUE;
|
||
|
ExplicitAccess[4].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
|
||
|
ExplicitAccess[4].Trustee.ptstrName = (LPTSTR)pUsersSid;
|
||
|
|
||
|
ExplicitAccess[5].grfAccessPermissions = DELETE;
|
||
|
ExplicitAccess[5].grfInheritance = INHERIT_ONLY_ACE | SUB_CONTAINERS_AND_OBJECTS_INHERIT;
|
||
|
ExplicitAccess[5].Trustee.ptstrName = (LPTSTR)pUsersSid;
|
||
|
|
||
|
dwError = (DWORD)pSetEntriesInAcl( 6,
|
||
|
ExplicitAccess,
|
||
|
NULL,
|
||
|
&pNewDACL );
|
||
|
|
||
|
pSetSecurityInfo = (PSETSECURITYINFO_FN)GetProcAddress(pAdvApi32,SET_SECURITY_INFO);
|
||
|
|
||
|
if (pSetSecurityInfo == NULL)
|
||
|
{
|
||
|
OutputDebugString(_T("AddSidToObjectsSecurityDescriptor: Can't get proc SetSecurityInfo"));
|
||
|
goto ErrorCleanup;
|
||
|
}
|
||
|
|
||
|
dwError = pSetSecurityInfo(
|
||
|
hObject,
|
||
|
ObjectType,
|
||
|
DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
pNewDACL,
|
||
|
NULL
|
||
|
);
|
||
|
|
||
|
}
|
||
|
ErrorCleanup:
|
||
|
|
||
|
pFreeSid = (PFREESID_FN)
|
||
|
GetProcAddress(pAdvApi32,
|
||
|
FREE_SID);
|
||
|
|
||
|
if(pAdminSid)
|
||
|
pFreeSid(pAdminSid);
|
||
|
if(pSystemSid)
|
||
|
pFreeSid(pSystemSid);
|
||
|
if(pPowerUsersSid)
|
||
|
pFreeSid(pPowerUsersSid);
|
||
|
if(pCreatorSid)
|
||
|
pFreeSid(pCreatorSid);
|
||
|
if(pUsersSid)
|
||
|
pFreeSid(pUsersSid);
|
||
|
if(pNewDACL)
|
||
|
LocalFree(pNewDACL);
|
||
|
|
||
|
|
||
|
if(pAdvApi32)
|
||
|
FreeLibrary( pAdvApi32 );
|
||
|
|
||
|
return bSuccess;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL CreateRegAddAcl(VOID)
|
||
|
{
|
||
|
BOOL fRet = FALSE;
|
||
|
DWORD dwDisposition, dwError = NO_ERROR;
|
||
|
HKEY hKey = NULL, hKeyStore = NULL;
|
||
|
|
||
|
dwError = RegCreateKeyEx(
|
||
|
HKEY_LOCAL_MACHINE,
|
||
|
MSLICENSING_REG_KEY,
|
||
|
0,
|
||
|
NULL,
|
||
|
REG_OPTION_NON_VOLATILE,
|
||
|
KEY_ALL_ACCESS,
|
||
|
NULL,
|
||
|
&hKey,
|
||
|
&dwDisposition
|
||
|
);
|
||
|
|
||
|
if (dwError != ERROR_SUCCESS) {
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
fRet = AddACLToObjectSecurityDescriptor(
|
||
|
hKey,
|
||
|
SE_REGISTRY_KEY
|
||
|
);
|
||
|
|
||
|
if (!fRet) {
|
||
|
goto cleanup;
|
||
|
}
|
||
|
|
||
|
dwError = RegCreateKeyEx(
|
||
|
hKey,
|
||
|
MSLICENSING_STORE_SUBKEY,
|
||
|
0,
|
||
|
NULL,
|
||
|
REG_OPTION_NON_VOLATILE,
|
||
|
KEY_ALL_ACCESS,
|
||
|
NULL,
|
||
|
&hKeyStore,
|
||
|
&dwDisposition
|
||
|
);
|
||
|
|
||
|
if (dwError != ERROR_SUCCESS) {
|
||
|
fRet = FALSE;
|
||
|
goto cleanup;
|
||
|
}
|
||
|
|
||
|
fRet = AddACLToStoreObjectSecurityDescriptor(
|
||
|
hKeyStore,
|
||
|
SE_REGISTRY_KEY
|
||
|
);
|
||
|
|
||
|
cleanup:
|
||
|
if (NULL != hKey)
|
||
|
{
|
||
|
RegCloseKey( hKey );
|
||
|
}
|
||
|
|
||
|
if (NULL != hKeyStore)
|
||
|
{
|
||
|
RegCloseKey( hKeyStore );
|
||
|
}
|
||
|
|
||
|
return fRet;
|
||
|
}
|
||
|
|
||
|
BOOL
|
||
|
CreateAndWriteHWID(VOID)
|
||
|
{
|
||
|
BOOL fRet = FALSE;
|
||
|
DWORD dwDisposition, dwError = NO_ERROR;
|
||
|
HKEY hKey = NULL;
|
||
|
HWID hwid;
|
||
|
|
||
|
// Write HWID to registry
|
||
|
|
||
|
dwError = RegCreateKeyEx(
|
||
|
HKEY_LOCAL_MACHINE,
|
||
|
MSLICENSING_HWID_KEY,
|
||
|
0,
|
||
|
NULL,
|
||
|
REG_OPTION_NON_VOLATILE,
|
||
|
KEY_ALL_ACCESS,
|
||
|
NULL,
|
||
|
&hKey,
|
||
|
&dwDisposition
|
||
|
);
|
||
|
|
||
|
if (dwError != ERROR_SUCCESS) {
|
||
|
goto cleanup;
|
||
|
}
|
||
|
|
||
|
// generate HWID
|
||
|
|
||
|
if (LICENSE_STATUS_OK == GenerateClientHWID(&hwid))
|
||
|
{
|
||
|
|
||
|
dwError = RegSetValueEx(hKey,
|
||
|
MSLICENSING_HWID_VALUE,
|
||
|
0,
|
||
|
REG_BINARY,
|
||
|
(LPBYTE)&hwid,
|
||
|
sizeof(HWID));
|
||
|
|
||
|
if (dwError != ERROR_SUCCESS) {
|
||
|
goto cleanup;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
fRet = TRUE;
|
||
|
|
||
|
|
||
|
cleanup:
|
||
|
if (NULL != hKey)
|
||
|
{
|
||
|
RegCloseKey( hKey );
|
||
|
}
|
||
|
|
||
|
return fRet;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL SetupMSLicensingKey()
|
||
|
{
|
||
|
OSVERSIONINFOA OsVer;
|
||
|
memset(&OsVer, 0x0, sizeof(OSVERSIONINFOA));
|
||
|
OsVer.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
|
||
|
GetVersionExA(&OsVer);
|
||
|
|
||
|
if (VER_PLATFORM_WIN32_NT == OsVer.dwPlatformId) //It should be Windows NT
|
||
|
{
|
||
|
if(CreateRegAddAcl())
|
||
|
{
|
||
|
// generate and write the HWID
|
||
|
if (CreateAndWriteHWID())
|
||
|
{
|
||
|
return TRUE;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
LPCTSTR pszSysPrepBackupCmd[] = { _T("sessmgr.exe -unregserver") };
|
||
|
DWORD numSysPrepBackupCmd = sizeof(pszSysPrepBackupCmd) / sizeof(pszSysPrepBackupCmd[0]);
|
||
|
|
||
|
LPCTSTR pszSysPrepRestoreCmd[] = { _T("sessmgr.exe -service") };
|
||
|
DWORD numSysPrepRestoreCmd = sizeof(pszSysPrepRestoreCmd) / sizeof(pszSysPrepRestoreCmd[0]);
|
||
|
|
||
|
class CNameSIDList : public list<CNameSID>
|
||
|
{
|
||
|
public:
|
||
|
BOOL Save(HKEY hKey);
|
||
|
BOOL LoadAndDelete(HKEY hKey);
|
||
|
BOOL Find(PSID pSid, LPCWSTR *pwszName);
|
||
|
void AddIfNotExist(CNameSID &NameSID);
|
||
|
};
|
||
|
|
||
|
DWORD
|
||
|
BackupTSCustomSercurity();
|
||
|
|
||
|
DWORD
|
||
|
RestoreTSCustomSercurity();
|
||
|
|
||
|
DWORD
|
||
|
GetLocalSIDs(
|
||
|
IN PSECURITY_DESCRIPTOR pSD,
|
||
|
IN OUT CNameSIDList &NameSIDList);
|
||
|
|
||
|
DWORD
|
||
|
RenewLocalSIDs(
|
||
|
IN OUT PSECURITY_DESCRIPTOR &pSD,
|
||
|
IN OUT CNameSIDList &NameSIDList);
|
||
|
|
||
|
DWORD
|
||
|
ResetTSPublicPrivateKeys();
|
||
|
|
||
|
BOOL
|
||
|
CNameSIDList::Save(HKEY hKey)
|
||
|
{
|
||
|
BOOL bResult = FALSE;
|
||
|
CNameSIDList::iterator it;
|
||
|
//
|
||
|
//calc the size of the buffer we need
|
||
|
//
|
||
|
DWORD dwBufSize = 0;
|
||
|
LPCWSTR wszTmp1,wszTmp2;
|
||
|
for(it=begin();it!=end(); it++)
|
||
|
{
|
||
|
wszTmp1 = (*it).GetName();
|
||
|
wszTmp2 = (*it).GetTextSID();
|
||
|
if(wszTmp1 && wszTmp2)
|
||
|
{
|
||
|
dwBufSize += (wcslen(wszTmp1)+wcslen(wszTmp2)+2)*sizeof(WCHAR);
|
||
|
}
|
||
|
}
|
||
|
//
|
||
|
//for second terminating 0.
|
||
|
//
|
||
|
dwBufSize += sizeof(WCHAR);
|
||
|
//
|
||
|
//Allocate buffer (this will also zeroinit it).
|
||
|
//
|
||
|
LPWSTR wszBuf = (LPWSTR)LocalAlloc(LPTR,dwBufSize);
|
||
|
DWORD dwPos = 0;
|
||
|
if(wszBuf)
|
||
|
{
|
||
|
//
|
||
|
//Fill buffer with data
|
||
|
//
|
||
|
for(it=begin();it!=end(); it++)
|
||
|
{
|
||
|
wszTmp1 = (*it).GetName();
|
||
|
wszTmp2 = (*it).GetTextSID();
|
||
|
if(wszTmp1 && wszTmp2)
|
||
|
{
|
||
|
wcscpy(wszBuf+dwPos,wszTmp1);
|
||
|
dwPos += wcslen(wszTmp1)+1;
|
||
|
wcscpy(wszBuf+dwPos,wszTmp2);
|
||
|
dwPos += wcslen(wszTmp2)+1;
|
||
|
}
|
||
|
}
|
||
|
//
|
||
|
//Save data in the registry
|
||
|
//
|
||
|
if(dwPos && RegSetValueExW(hKey,L"BackupSids",0,REG_MULTI_SZ,
|
||
|
(CONST BYTE *)wszBuf,dwBufSize)==ERROR_SUCCESS)
|
||
|
{
|
||
|
bResult = TRUE;
|
||
|
}
|
||
|
|
||
|
LocalFree(wszBuf);
|
||
|
}
|
||
|
|
||
|
|
||
|
return bResult;
|
||
|
}
|
||
|
|
||
|
BOOL
|
||
|
CNameSIDList::LoadAndDelete(HKEY hKey)
|
||
|
{
|
||
|
BOOL bResult = FALSE;
|
||
|
DWORD err;
|
||
|
DWORD ValueSize = 0;
|
||
|
DWORD ValueType = 0;
|
||
|
|
||
|
err = RegQueryValueExW( hKey, L"BackupSids", NULL, &ValueType, NULL, &ValueSize );
|
||
|
|
||
|
if(err == ERROR_SUCCESS && ValueType == REG_MULTI_SZ && ValueSize)
|
||
|
{
|
||
|
|
||
|
LPWSTR wszBuf = (LPWSTR)LocalAlloc(LPTR,ValueSize);
|
||
|
|
||
|
if ( wszBuf )
|
||
|
{
|
||
|
|
||
|
err = RegQueryValueExW( hKey, L"BackupSids", NULL, &ValueType,
|
||
|
(BYTE *) wszBuf, &ValueSize );
|
||
|
|
||
|
RegDeleteValueW(hKey,L"BackupSids");
|
||
|
|
||
|
if(err == ERROR_SUCCESS )
|
||
|
{
|
||
|
LPCWSTR wszTmp1,wszTmp2;
|
||
|
DWORD dwPos = 0,dwMaxPos = ValueSize/sizeof(WCHAR);
|
||
|
while(dwPos < dwMaxPos)
|
||
|
{
|
||
|
wszTmp1 = wszBuf + dwPos;
|
||
|
dwPos += wcslen(wszTmp1) + 1;
|
||
|
wszTmp2 = wszBuf + dwPos;
|
||
|
dwPos += wcslen(wszTmp2) + 1;
|
||
|
|
||
|
PSID pSid;
|
||
|
if(ConvertStringSidToSidW(wszTmp2,&pSid))
|
||
|
{
|
||
|
CNameSID NameSID(wszTmp1,pSid);
|
||
|
push_back(NameSID);
|
||
|
LocalFree(pSid);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
bResult = TRUE;
|
||
|
}
|
||
|
|
||
|
LocalFree(wszBuf);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
return bResult;
|
||
|
}
|
||
|
|
||
|
BOOL
|
||
|
CNameSIDList::Find(PSID pSid, LPCWSTR *pwszName)
|
||
|
{
|
||
|
*pwszName = NULL;
|
||
|
|
||
|
CNameSIDList::iterator it;
|
||
|
|
||
|
for(it=begin();it!=end(); it++)
|
||
|
{
|
||
|
if(EqualSid(pSid,(*it).GetSID()))
|
||
|
{
|
||
|
*pwszName = (*it).GetName();
|
||
|
return TRUE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
CNameSIDList::AddIfNotExist(CNameSID &NameSID)
|
||
|
{
|
||
|
LPCWSTR wszName;
|
||
|
if(!Find(NameSID.GetSID(),&wszName))
|
||
|
{
|
||
|
push_back(NameSID);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
VOID
|
||
|
RunSysPrepCommands( LPCTSTR pszCmds )
|
||
|
{
|
||
|
STARTUPINFO startupinfo;
|
||
|
PROCESS_INFORMATION process_information;
|
||
|
BOOL bSuccess;
|
||
|
DWORD dwErr;
|
||
|
TCHAR pszCommand[ MAX_PATH * 2 + 1];
|
||
|
|
||
|
|
||
|
try {
|
||
|
//
|
||
|
// CreateProcessW() will fail if lpCommandLine is a const string
|
||
|
// AV if it is actually point to LPCTSTR.
|
||
|
//
|
||
|
lstrcpy( pszCommand, pszCmds );
|
||
|
|
||
|
ZeroMemory( &startupinfo, sizeof(startupinfo) );
|
||
|
startupinfo.cb = sizeof(startupinfo);
|
||
|
startupinfo.dwFlags = STARTF_USESHOWWINDOW;
|
||
|
startupinfo.wShowWindow = SW_HIDE | SW_SHOWMINNOACTIVE;
|
||
|
|
||
|
LOGMESSAGE1(_T("Running command %s."), pszCmds);
|
||
|
|
||
|
bSuccess = CreateProcess( NULL,
|
||
|
pszCommand,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
FALSE,
|
||
|
CREATE_DEFAULT_ERROR_MODE,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
&startupinfo,
|
||
|
&process_information );
|
||
|
if ( !bSuccess )
|
||
|
{
|
||
|
LOGMESSAGE1(_T("ERROR: failed to spawn %s process."), pszCommand);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
dwErr = WaitForSingleObject( process_information.hProcess, RUNONCE_DEFAULTWAIT );
|
||
|
if ( dwErr != NO_ERROR )
|
||
|
{
|
||
|
LOGMESSAGE1(_T("ERROR: process %s failed to complete in time."), pszCommand);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
LOGMESSAGE1(_T("INFO: process %s completed successfully."), pszCommand);
|
||
|
}
|
||
|
|
||
|
CloseHandle( process_information.hProcess );
|
||
|
CloseHandle( process_information.hThread );
|
||
|
}
|
||
|
}
|
||
|
catch(...) {
|
||
|
LOGMESSAGE0(_T("Command caused exception.") );
|
||
|
}
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
|
||
|
__declspec( dllexport )
|
||
|
VOID
|
||
|
SysPrepBackup( void )
|
||
|
{
|
||
|
DWORD dwIndex;
|
||
|
TCHAR szLogFile[MAX_PATH + 1];
|
||
|
|
||
|
ZeroMemory(szLogFile, sizeof(szLogFile));
|
||
|
|
||
|
ExpandEnvironmentStrings(LOGFILE, szLogFile, MAX_PATH);
|
||
|
LOGMESSAGEINIT(szLogFile, MODULENAME);
|
||
|
|
||
|
LOGMESSAGE0( _T("Entering SysPrepBackup") );
|
||
|
|
||
|
for(dwIndex = 0; dwIndex < numSysPrepBackupCmd; dwIndex++ )
|
||
|
{
|
||
|
RunSysPrepCommands( pszSysPrepBackupCmd[dwIndex] );
|
||
|
}
|
||
|
|
||
|
DWORD err = BackupTSCustomSercurity();
|
||
|
if(err != ERROR_SUCCESS)
|
||
|
{
|
||
|
LOGMESSAGE1(_T("ERROR: BackupTSCustomSercurity() FAILED: %d"),err );
|
||
|
}
|
||
|
|
||
|
LOGMESSAGE0( _T("SysPrepBackup completed") );
|
||
|
}
|
||
|
|
||
|
__declspec( dllexport )
|
||
|
VOID
|
||
|
SysPrepRestore( void )
|
||
|
{
|
||
|
DWORD dwIndex;
|
||
|
TCHAR szLogFile[MAX_PATH + 1];
|
||
|
|
||
|
ZeroMemory( szLogFile, sizeof(szLogFile) );
|
||
|
|
||
|
ExpandEnvironmentStrings(LOGFILE, szLogFile, MAX_PATH);
|
||
|
|
||
|
LOGMESSAGEINIT(szLogFile, MODULENAME);
|
||
|
|
||
|
LOGMESSAGE0( _T("Entering SysPrepRestore") );
|
||
|
|
||
|
for(dwIndex = 0; dwIndex < numSysPrepRestoreCmd; dwIndex++ )
|
||
|
{
|
||
|
RunSysPrepCommands( pszSysPrepRestoreCmd[dwIndex] );
|
||
|
}
|
||
|
|
||
|
DWORD err = RestoreTSCustomSercurity();
|
||
|
if(err != ERROR_SUCCESS)
|
||
|
{
|
||
|
LOGMESSAGE1(_T("ERROR: RestoreTSCustomSercurity() FAILED: %d"),err );
|
||
|
}
|
||
|
|
||
|
err = ResetTSPublicPrivateKeys();
|
||
|
if(err != ERROR_SUCCESS)
|
||
|
{
|
||
|
LOGMESSAGE1(_T("ERROR: ResetTSPublicPrivateKeys() FAILED: %d"),err );
|
||
|
}
|
||
|
//
|
||
|
// This can be done at SysPrep time instead of SysRestore time; however, sysprep
|
||
|
// might support back out sysprep so we delay deleting licensing key at restore time,
|
||
|
// also, to keep it consistent with ResetTSPublicPrivateKey().
|
||
|
//
|
||
|
err = SHDeleteKey( HKEY_LOCAL_MACHINE, MSLICENSING_REG_KEY );
|
||
|
|
||
|
if(err != ERROR_SUCCESS)
|
||
|
{
|
||
|
LOGMESSAGE1(_T("ERROR: Deleting MSLicensing key FAILED: %d"),err );
|
||
|
}
|
||
|
|
||
|
err = SetupMSLicensingKey();
|
||
|
|
||
|
if(err != ERROR_SUCCESS)
|
||
|
{
|
||
|
LOGMESSAGE1(_T("ERROR: SetupMSLicensingKey() FAILED: %d"),err );
|
||
|
}
|
||
|
LOGMESSAGE0( _T("SysPrepRestore completed") );
|
||
|
}
|
||
|
|
||
|
//*************************************************************
|
||
|
//
|
||
|
// BackupTSCustomSercurity()
|
||
|
//
|
||
|
// Purpose: Creates a list of all local SIDs and
|
||
|
// corresponding names included in WinStation's
|
||
|
// security descriptors, and saves it
|
||
|
// in the registry.
|
||
|
//
|
||
|
// Parameters: NONE
|
||
|
//
|
||
|
// Return: error code if fails, ERROR_SUCCESS otherwise
|
||
|
//
|
||
|
// Comments:
|
||
|
//
|
||
|
// History: Date Author Comment
|
||
|
// 03/13/01 skuzin Created
|
||
|
//
|
||
|
//*************************************************************
|
||
|
DWORD
|
||
|
BackupTSCustomSercurity()
|
||
|
{
|
||
|
HKEY hKey;
|
||
|
DWORD err;
|
||
|
//
|
||
|
//Open "SYSTEM\\CurrentControlSet\\Control\\Terminal Server\\WinStations" key
|
||
|
//
|
||
|
err = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
|
||
|
_T("SYSTEM\\CurrentControlSet\\Control\\Terminal Server\\WinStations"),
|
||
|
0,KEY_READ|KEY_WRITE, &hKey );
|
||
|
|
||
|
if(err != ERROR_SUCCESS)
|
||
|
{
|
||
|
LOGMESSAGE1(_T("ERROR: BackupTSCustomSercurity - RegOpenKeyEx FAILED: %d"),err );
|
||
|
return err;
|
||
|
}
|
||
|
|
||
|
|
||
|
CNameAndSDList NameSDList; //List of security descriptors
|
||
|
CNameSIDList NameSIDList; //List of local SIDs
|
||
|
|
||
|
err=EnumWinStationSecurityDescriptors( hKey, &NameSDList);
|
||
|
|
||
|
if(err == ERROR_SUCCESS)
|
||
|
{
|
||
|
CNameAndSDList::iterator it;
|
||
|
|
||
|
for(it=NameSDList.begin();it!=NameSDList.end(); it++)
|
||
|
{
|
||
|
//
|
||
|
//If SD was not customized in most cases it is NULL
|
||
|
//
|
||
|
if((*it).m_pSD)
|
||
|
{
|
||
|
err = GetLocalSIDs((*it).m_pSD, NameSIDList);
|
||
|
|
||
|
if(err != ERROR_SUCCESS)
|
||
|
{
|
||
|
LOGMESSAGE2(_T("ERROR: GetLocalSIDs for %s FAILED: %d"), (*it).m_pName, err );
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(err == ERROR_SUCCESS)
|
||
|
{
|
||
|
if(!NameSIDList.Save(hKey))
|
||
|
{
|
||
|
LOGMESSAGE0(_T("ERROR: BackupTSCustomSercurity - NameSIDList.Save FAILED"));
|
||
|
err = ERROR_FILE_NOT_FOUND;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
LOGMESSAGE1(_T("ERROR: RestoreTSCustomSercurity - ")
|
||
|
_T("EnumWinStationSecurityDescriptors FAILED: %d"),err );
|
||
|
}
|
||
|
|
||
|
RegCloseKey(hKey);
|
||
|
|
||
|
return err;
|
||
|
}
|
||
|
|
||
|
//*************************************************************
|
||
|
//
|
||
|
// RestoreTSCustomSercurity()
|
||
|
//
|
||
|
// Purpose: Gets a list of local SIDs and corresponding names
|
||
|
// (saved by BackupTSCustomSercurity)
|
||
|
// from the registry and updates all WinStation's
|
||
|
// security descriptors with new SID for each
|
||
|
// local account.
|
||
|
//
|
||
|
// Parameters: NONE
|
||
|
//
|
||
|
// Return: error code if fails, ERROR_SUCCESS otherwise
|
||
|
//
|
||
|
// Comments:
|
||
|
//
|
||
|
// History: Date Author Comment
|
||
|
// 03/13/01 skuzin Created
|
||
|
//
|
||
|
//*************************************************************
|
||
|
DWORD
|
||
|
RestoreTSCustomSercurity()
|
||
|
{
|
||
|
HKEY hKey;
|
||
|
DWORD err;
|
||
|
//
|
||
|
//Open "SYSTEM\\CurrentControlSet\\Control\\Terminal Server\\WinStations" key
|
||
|
//
|
||
|
err = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
|
||
|
_T("SYSTEM\\CurrentControlSet\\Control\\Terminal Server\\WinStations"),
|
||
|
0,KEY_READ|KEY_WRITE, &hKey );
|
||
|
|
||
|
if(err != ERROR_SUCCESS)
|
||
|
{
|
||
|
LOGMESSAGE1(_T("ERROR: RestoreTSCustomSercurity - RegOpenKeyEx FAILED: %d"),err );
|
||
|
return err;
|
||
|
}
|
||
|
|
||
|
|
||
|
CNameAndSDList NameSDList; //List of security descriptors
|
||
|
CNameSIDList NameSIDList; //List of local SIDs
|
||
|
|
||
|
//Now load
|
||
|
if(!NameSIDList.LoadAndDelete(hKey))
|
||
|
{
|
||
|
LOGMESSAGE0(_T("ERROR: RestoreTSCustomSercurity - NameSIDList.LoadAndDelete FAILED"));
|
||
|
RegCloseKey(hKey);
|
||
|
return ERROR_FILE_NOT_FOUND;
|
||
|
}
|
||
|
|
||
|
err=EnumWinStationSecurityDescriptors( hKey, &NameSDList);
|
||
|
|
||
|
if(err == ERROR_SUCCESS)
|
||
|
{
|
||
|
CNameAndSDList::iterator it;
|
||
|
|
||
|
for(it=NameSDList.begin();it!=NameSDList.end(); it++)
|
||
|
{
|
||
|
//
|
||
|
//If SD was not customized in most cases it is NULL
|
||
|
//
|
||
|
if((*it).m_pSD)
|
||
|
{
|
||
|
err = RenewLocalSIDs((*it).m_pSD, NameSIDList);
|
||
|
|
||
|
if(err == ERROR_SUCCESS)
|
||
|
{
|
||
|
err = SetWinStationSecurity( hKey, (*it).m_pName, (*it).m_pSD );
|
||
|
|
||
|
if(err !=ERROR_SUCCESS)
|
||
|
{
|
||
|
LOGMESSAGE2(_T("ERROR: SetWinStationSecurity for %s FAILED: %d"),
|
||
|
(*it).m_pName, err );
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
LOGMESSAGE2(_T("ERROR: RenewLocalSIDs for %s FAILED: %d"),
|
||
|
(*it).m_pName, err );
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
LOGMESSAGE1(_T("ERROR: RestoreTSCustomSercurity - ")
|
||
|
_T("EnumWinStationSecurityDescriptors FAILED: %d"),err );
|
||
|
}
|
||
|
|
||
|
RegCloseKey(hKey);
|
||
|
|
||
|
return err;
|
||
|
}
|
||
|
|
||
|
//*************************************************************
|
||
|
//
|
||
|
// GetLocalSIDs()
|
||
|
//
|
||
|
// Purpose: Gets local SIDs from a security descriptor
|
||
|
// and puts them in the list
|
||
|
//
|
||
|
// Parameters:
|
||
|
// IN PSECURITY_DESCRIPTOR pSD,
|
||
|
// IN OUT CNameSIDList &NameSIDList
|
||
|
//
|
||
|
// Return: error code if fails, ERROR_SUCCESS otherwise
|
||
|
//
|
||
|
// Comments:
|
||
|
//
|
||
|
// History: Date Author Comment
|
||
|
// 03/13/01 skuzin Created
|
||
|
//
|
||
|
//*************************************************************
|
||
|
DWORD
|
||
|
GetLocalSIDs(
|
||
|
IN PSECURITY_DESCRIPTOR pSD,
|
||
|
IN OUT CNameSIDList &NameSIDList)
|
||
|
{
|
||
|
PACL pDacl;
|
||
|
PACL pSacl;
|
||
|
DWORD dwResult;
|
||
|
|
||
|
DWORD cEntries = 0;
|
||
|
|
||
|
dwResult = GetDacl(pSD,&pDacl);
|
||
|
|
||
|
if(dwResult != ERROR_SUCCESS)
|
||
|
{
|
||
|
return dwResult;
|
||
|
}
|
||
|
|
||
|
dwResult = GetSacl(pSD,&pSacl);
|
||
|
|
||
|
if(dwResult != ERROR_SUCCESS)
|
||
|
{
|
||
|
return dwResult;
|
||
|
}
|
||
|
|
||
|
DWORD dwCompNameSize = MAX_COMPUTERNAME_LENGTH + 1;
|
||
|
WCHAR wszComputerName[MAX_COMPUTERNAME_LENGTH + 1];
|
||
|
|
||
|
if(!GetComputerNameW(wszComputerName, &dwCompNameSize))
|
||
|
{
|
||
|
return GetLastError();
|
||
|
}
|
||
|
|
||
|
|
||
|
ACL_SIZE_INFORMATION asiAclSize;
|
||
|
DWORD dwBufLength=sizeof(asiAclSize);
|
||
|
ACCESS_ALLOWED_ACE *pAllowedAce;
|
||
|
SYSTEM_AUDIT_ACE *pSystemAce;
|
||
|
DWORD dwAcl_i;
|
||
|
LPWSTR wszName;
|
||
|
SID_NAME_USE eUse;
|
||
|
|
||
|
if(pDacl)
|
||
|
{
|
||
|
if (GetAclInformation(pDacl,
|
||
|
(LPVOID)&asiAclSize,
|
||
|
(DWORD)dwBufLength,
|
||
|
(ACL_INFORMATION_CLASS)AclSizeInformation))
|
||
|
{
|
||
|
for (dwAcl_i = 0; dwAcl_i < asiAclSize.AceCount; dwAcl_i++)
|
||
|
{
|
||
|
|
||
|
if(GetAce( pDacl, dwAcl_i, (LPVOID *)&pAllowedAce))
|
||
|
{
|
||
|
if(LookupSid((PSID)&(pAllowedAce->SidStart),&wszName,&eUse))
|
||
|
{
|
||
|
if(IsLocal(wszComputerName, wszName))
|
||
|
{
|
||
|
NameSIDList.AddIfNotExist(CNameSID(wszName,
|
||
|
(PSID)&(pAllowedAce->SidStart)));
|
||
|
}
|
||
|
|
||
|
LocalFree(wszName);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(pSacl)
|
||
|
{
|
||
|
if (GetAclInformation(pSacl,
|
||
|
(LPVOID)&asiAclSize,
|
||
|
(DWORD)dwBufLength,
|
||
|
(ACL_INFORMATION_CLASS)AclSizeInformation))
|
||
|
{
|
||
|
for (dwAcl_i = 0; dwAcl_i < asiAclSize.AceCount; dwAcl_i++)
|
||
|
{
|
||
|
|
||
|
if(GetAce( pSacl, dwAcl_i, (LPVOID *)&pSystemAce))
|
||
|
{
|
||
|
if(LookupSid((PSID)&(pSystemAce->SidStart),&wszName,&eUse))
|
||
|
{
|
||
|
if(IsLocal(wszComputerName, wszName))
|
||
|
{
|
||
|
NameSIDList.AddIfNotExist(CNameSID(wszName,
|
||
|
(PSID)&(pSystemAce->SidStart)));
|
||
|
}
|
||
|
|
||
|
LocalFree(wszName);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return ERROR_SUCCESS;
|
||
|
}
|
||
|
|
||
|
|
||
|
//*************************************************************
|
||
|
//
|
||
|
// RenewLocalSIDs()
|
||
|
//
|
||
|
// Purpose: Replaces all the local SIDs in a security
|
||
|
// descriptor with the new ones.
|
||
|
//
|
||
|
// Parameters:
|
||
|
// IN OUT PSECURITY_DESCRIPTOR &pSD,
|
||
|
// IN OUT CNameSIDList &NameSIDList
|
||
|
//
|
||
|
// Return: error code if fails, ERROR_SUCCESS otherwise
|
||
|
//
|
||
|
// Comments:
|
||
|
//
|
||
|
// History: Date Author Comment
|
||
|
// 03/13/01 skuzin Created
|
||
|
//
|
||
|
//*************************************************************
|
||
|
|
||
|
DWORD
|
||
|
RenewLocalSIDs(
|
||
|
IN OUT PSECURITY_DESCRIPTOR &pSD,
|
||
|
IN OUT CNameSIDList &NameSIDList)
|
||
|
{
|
||
|
PSECURITY_DESCRIPTOR pAbsoluteSD = NULL;
|
||
|
PACL pDacl = NULL;
|
||
|
PACL pSacl = NULL;
|
||
|
PSID pOwner = NULL;
|
||
|
PSID pPrimaryGroup = NULL;
|
||
|
DWORD dwResult;
|
||
|
|
||
|
dwResult = GetAbsoluteSD(
|
||
|
pSD,
|
||
|
&pAbsoluteSD,
|
||
|
&pDacl,
|
||
|
&pSacl,
|
||
|
&pOwner,
|
||
|
&pPrimaryGroup);
|
||
|
|
||
|
if(dwResult != ERROR_SUCCESS)
|
||
|
{
|
||
|
return dwResult;
|
||
|
}
|
||
|
|
||
|
ULONG cEntries;
|
||
|
PEXPLICIT_ACCESS_W pListOfEntries;
|
||
|
LPCWSTR wszName;
|
||
|
PACL pNewDacl = NULL, pNewSacl = NULL;
|
||
|
|
||
|
__try
|
||
|
{
|
||
|
if(pDacl)
|
||
|
{
|
||
|
dwResult = GetExplicitEntriesFromAclW(pDacl, &cEntries, &pListOfEntries);
|
||
|
|
||
|
if(dwResult != ERROR_SUCCESS)
|
||
|
{
|
||
|
return dwResult;
|
||
|
}
|
||
|
|
||
|
for(ULONG i=0;i<cEntries;i++)
|
||
|
{
|
||
|
if(pListOfEntries[i].Trustee.TrusteeForm == TRUSTEE_IS_SID &&
|
||
|
NameSIDList.Find((PSID)pListOfEntries[i].Trustee.ptstrName, &wszName))
|
||
|
{
|
||
|
pListOfEntries[i].Trustee.TrusteeForm = TRUSTEE_IS_NAME;
|
||
|
pListOfEntries[i].Trustee.ptstrName = const_cast<LPWSTR>(wszName);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
dwResult = SetEntriesInAclW(cEntries,pListOfEntries,NULL,&pNewDacl);
|
||
|
|
||
|
LocalFree(pListOfEntries);
|
||
|
|
||
|
if(dwResult != ERROR_SUCCESS)
|
||
|
{
|
||
|
return dwResult;
|
||
|
}
|
||
|
|
||
|
if(!SetSecurityDescriptorDacl(pAbsoluteSD,TRUE,pNewDacl,FALSE))
|
||
|
{
|
||
|
return GetLastError();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(pSacl)
|
||
|
{
|
||
|
dwResult = GetExplicitEntriesFromAclW(pSacl, &cEntries, &pListOfEntries);
|
||
|
|
||
|
if(dwResult != ERROR_SUCCESS)
|
||
|
{
|
||
|
return dwResult;
|
||
|
}
|
||
|
|
||
|
for(ULONG i=0;i<cEntries;i++)
|
||
|
{
|
||
|
if(pListOfEntries[i].Trustee.TrusteeForm == TRUSTEE_IS_SID &&
|
||
|
NameSIDList.Find((PSID)pListOfEntries[i].Trustee.ptstrName, &wszName))
|
||
|
{
|
||
|
pListOfEntries[i].Trustee.TrusteeForm = TRUSTEE_IS_NAME;
|
||
|
pListOfEntries[i].Trustee.ptstrName = const_cast<LPWSTR>(wszName);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
dwResult = SetEntriesInAclW(cEntries,pListOfEntries,NULL,&pNewSacl);
|
||
|
|
||
|
LocalFree(pListOfEntries);
|
||
|
|
||
|
if(dwResult != ERROR_SUCCESS)
|
||
|
{
|
||
|
return dwResult;
|
||
|
}
|
||
|
|
||
|
if(!SetSecurityDescriptorSacl(pAbsoluteSD,TRUE,pNewSacl,FALSE))
|
||
|
{
|
||
|
return GetLastError();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
PSECURITY_DESCRIPTOR pTmpSD;
|
||
|
|
||
|
dwResult = GetSelfRelativeSD(pAbsoluteSD,&pTmpSD);
|
||
|
|
||
|
if(dwResult != ERROR_SUCCESS)
|
||
|
{
|
||
|
return dwResult;
|
||
|
}
|
||
|
|
||
|
LocalFree(pSD);
|
||
|
pSD = pTmpSD;
|
||
|
|
||
|
}
|
||
|
__finally
|
||
|
{
|
||
|
if(pAbsoluteSD)
|
||
|
{
|
||
|
LocalFree(pAbsoluteSD);
|
||
|
}
|
||
|
if(pDacl)
|
||
|
{
|
||
|
LocalFree(pDacl);
|
||
|
}
|
||
|
if(pSacl)
|
||
|
{
|
||
|
LocalFree(pSacl);
|
||
|
}
|
||
|
if(pOwner)
|
||
|
{
|
||
|
LocalFree(pOwner);
|
||
|
}
|
||
|
if(pPrimaryGroup)
|
||
|
{
|
||
|
LocalFree(pPrimaryGroup);
|
||
|
}
|
||
|
if(pNewDacl)
|
||
|
{
|
||
|
LocalFree(pNewDacl);
|
||
|
}
|
||
|
if(pNewSacl)
|
||
|
{
|
||
|
LocalFree(pNewSacl);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
return ERROR_SUCCESS;
|
||
|
}
|
||
|
|
||
|
|
||
|
//*************************************************************
|
||
|
//
|
||
|
// ResetTSPublicPrivateKeys()
|
||
|
//
|
||
|
// Purpose: Deletes keys from LSA secret, so that sysprep'd
|
||
|
// machines don't share the same keys
|
||
|
//
|
||
|
// Parameters: NONE
|
||
|
//
|
||
|
// Return: error code if fails, ERROR_SUCCESS otherwise
|
||
|
//
|
||
|
// Comments:
|
||
|
//
|
||
|
// History: Date Author Comment
|
||
|
// 06/12/01 robleit Created
|
||
|
//
|
||
|
//*************************************************************
|
||
|
DWORD
|
||
|
ResetTSPublicPrivateKeys()
|
||
|
{
|
||
|
LSA_HANDLE
|
||
|
PolicyHandle;
|
||
|
UNICODE_STRING
|
||
|
SecretKeyName;
|
||
|
DWORD
|
||
|
Status;
|
||
|
|
||
|
LOGMESSAGE0(_T("INFO: Starting ResetTSPublicPrivateKeys.") );
|
||
|
|
||
|
Status = OpenPolicy( NULL, POLICY_CREATE_SECRET, &PolicyHandle );
|
||
|
|
||
|
if( ERROR_SUCCESS != Status )
|
||
|
{
|
||
|
return LsaNtStatusToWinError(Status);
|
||
|
}
|
||
|
|
||
|
SecretKeyName.Buffer = PRIVATE_KEY_NAME;
|
||
|
SecretKeyName.Length = sizeof(PRIVATE_KEY_NAME) - sizeof(WCHAR);
|
||
|
SecretKeyName.MaximumLength = sizeof(PRIVATE_KEY_NAME) ;
|
||
|
|
||
|
Status = LsaStorePrivateData(
|
||
|
PolicyHandle,
|
||
|
&SecretKeyName,
|
||
|
NULL
|
||
|
);
|
||
|
|
||
|
if (Status != STATUS_SUCCESS)
|
||
|
{
|
||
|
LOGMESSAGE1(_T("ERROR: ResetTSPublicPrivateKeys() FAILED to delete private key: %d"),Status );
|
||
|
}
|
||
|
|
||
|
SecretKeyName.Buffer = X509_CERT_PRIVATE_KEY_NAME;
|
||
|
SecretKeyName.Length = sizeof(X509_CERT_PRIVATE_KEY_NAME) - sizeof(WCHAR);
|
||
|
SecretKeyName.MaximumLength = sizeof(X509_CERT_PRIVATE_KEY_NAME);
|
||
|
|
||
|
Status = LsaStorePrivateData(
|
||
|
PolicyHandle,
|
||
|
&SecretKeyName,
|
||
|
NULL
|
||
|
);
|
||
|
|
||
|
if (Status != STATUS_SUCCESS)
|
||
|
{
|
||
|
LOGMESSAGE1(_T("WARNING: ResetTSPublicPrivateKeys() FAILED to delete X509 private key: %d"),Status );
|
||
|
}
|
||
|
|
||
|
SecretKeyName.Buffer = X509_CERT_PUBLIC_KEY_NAME;
|
||
|
SecretKeyName.Length = sizeof(X509_CERT_PUBLIC_KEY_NAME) - sizeof(WCHAR);
|
||
|
SecretKeyName.MaximumLength = sizeof(X509_CERT_PUBLIC_KEY_NAME);
|
||
|
|
||
|
Status = LsaStorePrivateData(
|
||
|
PolicyHandle,
|
||
|
&SecretKeyName,
|
||
|
NULL
|
||
|
);
|
||
|
|
||
|
if (Status != STATUS_SUCCESS)
|
||
|
{
|
||
|
LOGMESSAGE1(_T("WARNING: ResetTSPublicPrivateKeys() FAILED to delete X509 public key: %d"),Status );
|
||
|
}
|
||
|
|
||
|
LsaClose( PolicyHandle );
|
||
|
|
||
|
Status = LsaNtStatusToWinError( Status );
|
||
|
|
||
|
return Status;
|
||
|
}
|