WindowsXP-SP1/admin/snapin/certmgr/componentdatarsop.cpp
2020-09-30 16:53:49 +02:00

610 lines
21 KiB
C++

//+---------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////////
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1997-2001.
//
// File: ComponentDataRSOP.cpp
//
// Contents: Implementation of RSOP portions CCertMgrComponentData
//
//----------------------------------------------------------------------------
#include "stdafx.h"
#include <gpedit.h>
#include "compdata.h"
#include "dataobj.h"
#include "cookie.h"
#include "Certifct.h"
#pragma warning(push, 3)
#include <wintrust.h>
#include <cryptui.h>
#include <sceattch.h>
#pragma warning(pop)
#include "StoreRSOP.h"
#ifdef _DEBUG
#ifndef ALPHA
#define new DEBUG_NEW
#endif
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//
// CCertMgrComponentData
//
HRESULT CCertMgrComponentData::BuildWMIList (LPDATAOBJECT pDataObject, bool bIsComputer)
{
_TRACE (1, L"Entering CCertMgrComponentData::BuildWMIList (%s)\n", bIsComputer ? L"computer" : L"user");
HRESULT hr = S_OK;
#if DBG
if ( bIsComputer )
{
_TRACE (0, L"m_rsopObjectArrayComputer contains %d objects\n",
m_rsopObjectArrayComputer.GetUpperBound ());
}
else
{
_TRACE (0, L"m_rsopObjectArrayUser contains %d objects\n",
m_rsopObjectArrayUser.GetUpperBound ());
}
#endif
if ( bIsComputer )
m_rsopObjectArrayComputer.RemoveAll ();
else
m_rsopObjectArrayUser.RemoveAll ();
if ( ((bIsComputer && !m_pRSOPInformationComputer) ||
(!bIsComputer && !m_pRSOPInformationUser) )
&& pDataObject )
{
IUnknown* pIUnknown = 0;
hr = ExtractData (pDataObject,
CCertMgrDataObject::m_CFSCE_RSOPUnknown,
&pIUnknown, sizeof (IUnknown*));
ASSERT (SUCCEEDED (hr));
if ( SUCCEEDED (hr) )
{
if ( bIsComputer )
{
hr = pIUnknown->QueryInterface (
IID_PPV_ARG (IRSOPInformation, &m_pRSOPInformationComputer));
}
else
{
hr = pIUnknown->QueryInterface (
IID_PPV_ARG (IRSOPInformation, &m_pRSOPInformationUser));
}
ASSERT (SUCCEEDED (hr));
if ( SUCCEEDED (hr) )
{
if ( bIsComputer )
{
hr = m_pRSOPInformationComputer->GetFlags (&m_dwRSOPFlagsComputer);
}
else
{
hr = m_pRSOPInformationUser->GetFlags (&m_dwRSOPFlagsUser);
}
ASSERT (SUCCEEDED (hr));
int cchMaxLength = 512;
LPOLESTR pszNameSpace = (LPOLESTR) LocalAlloc (LPTR, cchMaxLength * sizeof (WCHAR));
if ( pszNameSpace )
{
DWORD dwSection = 0;
switch (m_dwSCEMode)
{
case SCE_MODE_LOCAL_USER:
case SCE_MODE_DOMAIN_USER:
case SCE_MODE_OU_USER:
case SCE_MODE_REMOTE_USER:
case SCE_MODE_RSOP_USER:
dwSection = GPO_SECTION_USER;
break;
case SCE_MODE_LOCAL_COMPUTER:
case SCE_MODE_DOMAIN_COMPUTER:
case SCE_MODE_OU_COMPUTER:
case SCE_MODE_RSOP_COMPUTER:
case SCE_MODE_REMOTE_COMPUTER:
dwSection = GPO_SECTION_MACHINE;
break;
default:
ASSERT (0);
return E_UNEXPECTED;
}
if ( bIsComputer )
{
hr = m_pRSOPInformationComputer->GetNamespace (
dwSection,
pszNameSpace,
cchMaxLength);
}
else
{
hr = m_pRSOPInformationUser->GetNamespace (
dwSection,
pszNameSpace,
cchMaxLength);
}
if ( SUCCEEDED (hr) )
{
IWbemLocator *pIWbemLocator = 0;
hr = CoCreateInstance (CLSID_WbemLocator,
NULL,
CLSCTX_INPROC_SERVER,
IID_PPV_ARG(IWbemLocator, &pIWbemLocator));
if ( SUCCEEDED (hr) )
{
BSTR bstrNameSpace = SysAllocString (pszNameSpace);
if ( bstrNameSpace )
{
if ( bIsComputer )
{
hr = pIWbemLocator->ConnectServer (bstrNameSpace,
NULL, NULL, 0, 0, NULL, NULL,
&m_pIWbemServicesComputer);
}
else
{
hr = pIWbemLocator->ConnectServer (bstrNameSpace,
NULL, NULL, 0, 0, NULL, NULL,
&m_pIWbemServicesUser);
}
if ( FAILED (hr) )
{
_TRACE (0, L"IWbemLocator::ConnectServer (%s) failed: 0x%x(%s)\n",
bstrNameSpace, hr, (PCWSTR) GetSystemMessage (hr));
}
SysFreeString (bstrNameSpace);
}
else
hr = E_OUTOFMEMORY;
pIWbemLocator->Release ();
}
}
LocalFree (pszNameSpace);
}
else
hr = E_OUTOFMEMORY;
}
}
}
if ( SUCCEEDED (hr) && ((bIsComputer && m_pIWbemServicesComputer) ||
(!bIsComputer && m_pIWbemServicesUser)) )
{
IEnumWbemClassObject * pEnum = 0;
IWbemClassObject *pObject = 0;
ULONG ulRet = 0;
//
// Execute the query
//
if ( bIsComputer )
{
hr = m_pIWbemServicesComputer->ExecQuery (m_pbstrLanguage, m_pbstrQuery,
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
NULL, &pEnum);
}
else
{
hr = m_pIWbemServicesUser->ExecQuery (m_pbstrLanguage, m_pbstrQuery,
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
NULL, &pEnum);
}
if ( SUCCEEDED (hr) )
{
//
// Loop through the results retrieving the registry key and value names
//
while ( (hr = pEnum->Next(WBEM_INFINITE, 1, &pObject, &ulRet)) == WBEM_S_NO_ERROR )
{
hr = GetValuesAndInsertInRSOPObjectList (pObject,
bIsComputer ? m_rsopObjectArrayComputer : m_rsopObjectArrayUser,
bIsComputer);
pObject->Release ();
if ( FAILED (hr) )
break;
}
pEnum->Release();
#if DBG
int nIndex = 0;
INT_PTR nUpperBound = 0;
if ( bIsComputer )
nUpperBound = m_rsopObjectArrayComputer.GetUpperBound ();
else
nUpperBound = m_rsopObjectArrayUser.GetUpperBound ();
while ( nUpperBound >= nIndex )
{
CRSOPObject* pCurrObject = 0;
if ( bIsComputer )
pCurrObject = m_rsopObjectArrayComputer.GetAt (nIndex);
else
pCurrObject = m_rsopObjectArrayUser.GetAt (nIndex);
if ( !pCurrObject )
break;
_TRACE (0, L"\t%d\t%s\t%s\n", pCurrObject->GetPrecedence (),
(PCWSTR) pCurrObject->GetRegistryKey (),
(PCWSTR) pCurrObject->GetValueName ());
nIndex++;
}
#endif
}
}
_TRACE (-1, L"Leaving CCertMgrComponentData::BuildWMIList (): 0x%x\n", hr);
return hr;
}
HRESULT CCertMgrComponentData::GetValuesAndInsertInRSOPObjectList (
IWbemClassObject* pObject,
CRSOPObjectArray& rRsopObjectArray,
bool bIsComputer)
{
HRESULT hr = S_OK;
if ( !pObject )
return E_POINTER;
//
// Check if the allocations succeeded
//
if ( m_pbstrLanguage && m_pbstrQuery && m_pbstrRegistryKey &&
m_pbstrValueName && m_pbstrValue &&
m_pbstrPrecedence && m_pbstrGPOid )
{
COleVariant varRegistryKey;
COleVariant varValueName;
COleVariant varValue;
COleVariant varPrecedence;
COleVariant varGPOid;
hr = pObject->Get (m_pbstrRegistryKey, 0, &varRegistryKey, NULL, NULL);
if (SUCCEEDED(hr))
{
hr = pObject->Get (m_pbstrValueName, 0, &varValueName, NULL, NULL);
if (SUCCEEDED(hr))
{
hr = pObject->Get (m_pbstrValue, 0, &varValue, NULL, NULL);
if (SUCCEEDED(hr))
{
//#ifndef DBG
// only include objects that have a value name
if ( varValueName.bstrVal[0] )
//#endif
{
//#ifndef DBG
// Only include those objects that are in the system store registry
// path or in the cryptography\autoenrollment path
if ( FoundInRSOPFilter (varRegistryKey.bstrVal) )
//#endif
{
hr = pObject->Get (m_pbstrPrecedence, 0, &varPrecedence, NULL, NULL);
if (SUCCEEDED(hr))
{
hr = pObject->Get (m_pbstrGPOid, 0, &varGPOid, NULL, NULL);
if (SUCCEEDED(hr))
{
PWSTR lpGPOName = 0;
hr = GetGPOFriendlyName (
varGPOid.bstrVal,
&lpGPOName,
bIsComputer);
if (SUCCEEDED(hr))
{
CRSOPObject* pRSOPObject = new CRSOPObject (
varRegistryKey.bstrVal,
varValueName.bstrVal,
lpGPOName,
varPrecedence.uintVal,
varValue);
if ( pRSOPObject )
{
CRSOPObject* pCurrObject = 0;
int nIndex = 0;
bool bInserted = false;
INT_PTR nUpperBound = rRsopObjectArray.GetUpperBound ();
while ( nUpperBound >= nIndex )
{
pCurrObject = rRsopObjectArray.GetAt (nIndex);
if ( !pCurrObject )
break;
// Sort first by registry key name,
// then by value name, then by
// precedence
int nCmpVal = wcscmp (pCurrObject->GetRegistryKey (),
pRSOPObject->GetRegistryKey ());
if ( nCmpVal > 0 )
{
rRsopObjectArray.InsertAt (nIndex, pRSOPObject);
bInserted = true;
break;
}
else if ( nCmpVal == 0 )
{
// Sort by value name
nCmpVal = wcscmp (pCurrObject->GetValueName (),
pRSOPObject->GetValueName ());
if ( nCmpVal > 0 )
{
rRsopObjectArray.InsertAt (nIndex, pRSOPObject);
bInserted = true;
break;
}
else if ( nCmpVal == 0 )
{
// Sort by precedence
if ( pCurrObject->GetPrecedence () >
pRSOPObject->GetPrecedence () )
{
rRsopObjectArray.InsertAt (nIndex, pRSOPObject);
bInserted = true;
break;
}
else if ( pCurrObject->GetPrecedence () ==
pRSOPObject->GetPrecedence () )
{
// The registry key, value name and precedence
// are the same - this is a duplicate. Pretend
// we've added it and move on.
bInserted = true;
break;
}
}
}
nIndex++;
}
if ( !bInserted )
rRsopObjectArray.Add (pRSOPObject);
}
LocalFree (lpGPOName);
}
varGPOid.Clear ();
}
varPrecedence.Clear ();
}
}
}
varValue.Clear ();
}
varValueName.Clear ();
}
varRegistryKey.Clear ();
}
}
else
hr = E_OUTOFMEMORY;
return hr;
}
HRESULT CCertMgrComponentData::GetGPOFriendlyName (PWSTR lpGPOID, PWSTR *pGPOName, bool bIsComputer)
{
BSTR pQuery = NULL, pName = NULL;
LPTSTR lpQuery = NULL;
IEnumWbemClassObject * pEnum = NULL;
IWbemClassObject *pObjects[2];
HRESULT hr;
ULONG ulRet;
VARIANT varGPOName;
//
// Set the default
//
*pGPOName = NULL;
//
// Build the query
//
lpQuery = (LPTSTR) LocalAlloc (LPTR, ((lstrlen(lpGPOID) + 50) * sizeof(TCHAR)));
if (!lpQuery)
{
_TRACE (0, L"CCertMgrComponentData::GetGPOFriendlyName: Failed to allocate memory for unicode query");
hr = HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY);
goto Exit;
}
wsprintf (lpQuery, TEXT("SELECT name, id FROM RSOP_GPO where id=\"%s\""), lpGPOID);
pQuery = SysAllocString (lpQuery);
if (!pQuery)
{
_TRACE (0, L"CCertMgrComponentData::GetGPOFriendlyName: Failed to allocate memory for query");
hr = HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY);
goto Exit;
}
//
// Allocate BSTRs for the property names we want to retreive
//
pName = SysAllocString (TEXT("name"));
if (!pName)
{
_TRACE (0, L"CCertMgrComponentData::GetGPOFriendlyName: Failed to allocate memory for name");
hr = HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY);
goto Exit;
}
//
// Execute the query
//
if ( bIsComputer )
{
hr = m_pIWbemServicesComputer->ExecQuery (m_pbstrLanguage, pQuery,
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
NULL, &pEnum);
}
else
{
hr = m_pIWbemServicesUser->ExecQuery (m_pbstrLanguage, pQuery,
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
NULL, &pEnum);
}
if (FAILED(hr))
{
_TRACE (0, L"CCertMgrComponentData::GetGPOFriendlyName: Failed to query for %s with 0x%x\n",
pQuery, hr);
goto Exit;
}
//
// Loop through the results
//
hr = pEnum->Next(WBEM_INFINITE, 1, pObjects, &ulRet);
if (FAILED(hr))
{
_TRACE (0, L"CCertMgrComponentData::GetGPOFriendlyName: Failed to get first item in query results for %s with 0x%x\n",
pQuery, hr);
goto Exit;
}
//
// Check for the "data not available case"
//
if (ulRet == 0)
{
hr = S_OK;
goto Exit;
}
//
// Get the name
//
hr = pObjects[0]->Get (pName, 0, &varGPOName, NULL, NULL);
if (FAILED(hr))
{
_TRACE (0, L"CCertMgrComponentData::GetGPOFriendlyName: Failed to get gponame in query results for %s with 0x%x\n",
pQuery, hr);
goto Exit;
}
//
// Save the name
//
*pGPOName = (LPTSTR) LocalAlloc (LPTR, (lstrlen(varGPOName.bstrVal) + 1) * sizeof(TCHAR));
if (!(*pGPOName))
{
_TRACE (0, L"CCertMgrComponentData::GetGPOFriendlyName: Failed to allocate memory for GPO Name");
hr = HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY);
goto Exit;
}
lstrcpy (*pGPOName, varGPOName.bstrVal);
VariantClear (&varGPOName);
hr = S_OK;
Exit:
if (pEnum)
{
pEnum->Release();
}
if (pQuery)
{
SysFreeString (pQuery);
}
if (lpQuery)
{
LocalFree (lpQuery);
}
if (pName)
{
SysFreeString (pName);
}
return hr;
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
bool CCertMgrPKPolExtension::FoundInRSOPFilter (BSTR bstrKey) const
{
static size_t nRegPathLen = wcslen (CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH);
static size_t nTrustedPublisherKeyLen =
wcslen (CERT_TRUST_PUB_SAFER_GROUP_POLICY_TRUSTED_PUBLISHER_STORE_REGPATH);
static size_t nDisallowedKeyLen =
wcslen (CERT_TRUST_PUB_SAFER_GROUP_POLICY_DISALLOWED_STORE_REGPATH);
static size_t nSaferKeyLen = wcslen (SAFER_HKLM_REGBASE);
static size_t nEFSKeyLen = wcslen (EFS_SETTINGS_REGPATH);
//Include group policy system stores but not trusted publisher or disallowed
if ( !_wcsnicmp (CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH, bstrKey, nRegPathLen) &&
(_wcsnicmp (CERT_TRUST_PUB_SAFER_GROUP_POLICY_TRUSTED_PUBLISHER_STORE_REGPATH,
bstrKey, nTrustedPublisherKeyLen) &&
_wcsnicmp (CERT_TRUST_PUB_SAFER_GROUP_POLICY_DISALLOWED_STORE_REGPATH,
bstrKey, nDisallowedKeyLen)) )
{
return true;
}
else if ( !_wcsnicmp (SAFER_HKLM_REGBASE, bstrKey, nSaferKeyLen) ||
!_wcsnicmp (EFS_SETTINGS_REGPATH, bstrKey, nEFSKeyLen) ||
!_wcsicmp (AUTO_ENROLLMENT_KEY, bstrKey) )
{
return true;
}
else
return false;
}