//+--------------------------------------------------------------------------- ///////////////////////////////////////////////////////////////////////////////// // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1997-2001. // // 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 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; }