//+--------------------------------------------------------------------------- ///////////////////////////////////////////////////////////////////////////////// // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1997-2002. // // File: ComponentDataRSOP.cpp // // Contents: Implementation of RSOP portions CCertMgrComponentData // //---------------------------------------------------------------------------- #include "stdafx.h" #include #include "compdata.h" #include "dataobj.h" #include "cookie.h" #include "Certifct.h" #pragma warning(push, 3) #include #include #include #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 int nIndex = 0; if ( bIsComputer ) { INT_PTR nUpperBound = m_rsopObjectArrayComputer.GetUpperBound (); while ( nUpperBound >= nIndex ) { CRSOPObject* pCurrObject = m_rsopObjectArrayComputer.GetAt (nIndex); if ( pCurrObject ) { delete pCurrObject; } nIndex++; } m_rsopObjectArrayComputer.RemoveAll (); } else { INT_PTR nUpperBound = m_rsopObjectArrayUser.GetUpperBound (); while ( nUpperBound >= nIndex ) { CRSOPObject* pCurrObject = m_rsopObjectArrayUser.GetAt (nIndex); if ( pCurrObject ) { delete pCurrObject; } nIndex++; } 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; // ISSUE // NTRAID 544154 TRACKING: PKP GrpPol: Verify that WMI communication with the store can be secured 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 nSpewIndex = 0; INT_PTR nUpperBound = 0; if ( bIsComputer ) nUpperBound = m_rsopObjectArrayComputer.GetUpperBound (); else nUpperBound = m_rsopObjectArrayUser.GetUpperBound (); while ( nUpperBound >= nSpewIndex ) { CRSOPObject* pCurrObject = 0; if ( bIsComputer ) pCurrObject = m_rsopObjectArrayComputer.GetAt (nSpewIndex); else pCurrObject = m_rsopObjectArrayUser.GetAt (nSpewIndex); if ( !pCurrObject ) break; _TRACE (0, L"\t%d\t%s\t%s\t%s\n", pCurrObject->GetPrecedence (), (PCWSTR) pCurrObject->GetRegistryKey (), (PCWSTR) pCurrObject->GetValueName (), (PCWSTR) pCurrObject->GetPolicyName ()); nSpewIndex++; } #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, varGPOid.bstrVal); 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 // security review 2/22/2002 BryanWal ok 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 // security review 2/22/2002 BryanWal ok 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 (PCWSTR pwszOID, PWSTR *ppwszGPOName, bool bIsComputer) { ASSERT (pwszOID); if ( !pwszOID ) return E_POINTER; ASSERT (ppwszGPOName); if ( !ppwszGPOName ) return E_POINTER; HRESULT hr = S_OK; // // Set the default // *ppwszGPOName = NULL; // // Build the query // PCWSTR pwszQueryFormat = L"SELECT name, id FROM RSOP_GPO where id=\"%s\""; // security review 2/22/2002 BryanWal ok PWSTR pwszQuery = (PWSTR) ::LocalAlloc (LPTR, ((wcslen(pwszOID) + wcslen (pwszQueryFormat) + 1) * sizeof(WCHAR))); if ( pwszQuery ) { // security review 2/22/2002 BryanWal ok wsprintf (pwszQuery, pwszQueryFormat, pwszOID); BSTR bstrQuery = SysAllocString (pwszQuery); if (bstrQuery) { // // Allocate BSTRs for the property names we want to retreive // BSTR bstrName = SysAllocString (TEXT("name")); if (bstrName) { // // Execute the query // IEnumWbemClassObject* pEnum = 0; if ( bIsComputer ) { hr = m_pIWbemServicesComputer->ExecQuery (m_pbstrLanguage, bstrQuery, WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnum); } else { hr = m_pIWbemServicesUser->ExecQuery (m_pbstrLanguage, bstrQuery, WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnum); } if ( SUCCEEDED (hr) ) { // // Loop through the results // IWbemClassObject* pObjects[2] = {0, 0}; ULONG ulRet = 0; hr = pEnum->Next(WBEM_INFINITE, 1, pObjects, &ulRet); if ( SUCCEEDED (hr) ) { // // Check for the "data not available case" // if (ulRet != 0) { // // Get the name // VARIANT varGPOName; hr = pObjects[0]->Get (bstrName, 0, &varGPOName, NULL, NULL); if ( SUCCEEDED (hr) ) { // // Save the name // // security review 2/22/2002 BryanWal ok *ppwszGPOName = (PWSTR) ::LocalAlloc (LPTR, (wcslen (varGPOName.bstrVal) + 1) * sizeof(WCHAR)); if ( *ppwszGPOName ) { // security review 2/22/2002 BryanWal ok wcscpy (*ppwszGPOName, varGPOName.bstrVal); VariantClear (&varGPOName); hr = S_OK; } else { _TRACE (0, L"CCertMgrComponentData::GetGPOFriendlyName: Failed to allocate memory for GPO Name"); hr = E_OUTOFMEMORY; } } else { _TRACE (0, L"CCertMgrComponentData::GetGPOFriendlyName: Failed to get gponame in query results for %s with 0x%x\n", bstrQuery, hr); } } } else { _TRACE (0, L"CCertMgrComponentData::GetGPOFriendlyName: Failed to get first item in query results for %s with 0x%x\n", bstrQuery, hr); } pEnum->Release (); } else { _TRACE (0, L"CCertMgrComponentData::GetGPOFriendlyName: Failed to query for %s with 0x%x\n", bstrQuery, hr); } SysFreeString (bstrName); } else { _TRACE (0, L"CCertMgrComponentData::GetGPOFriendlyName: Failed to allocate memory for name"); hr = HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY); } SysFreeString (bstrQuery); } else { _TRACE (0, L"CCertMgrComponentData::GetGPOFriendlyName: Failed to allocate memory for query"); hr = E_OUTOFMEMORY; } ::LocalFree (pwszQuery); } else { _TRACE (0, L"CCertMgrComponentData::GetGPOFriendlyName: Failed to allocate memory for unicode query"); hr = E_OUTOFMEMORY; } return hr; } /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// bool CCertMgrPKPolExtension::FoundInRSOPFilter (BSTR bstrKey) const { ASSERT (bstrKey); if ( !bstrKey ) return false; // security review 2/22/2002 BryanWal ok for all 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 // security review 2/22/2002 BryanWal ok for all 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; }