Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

631 lines
24 KiB

  1. //+---------------------------------------------------------------------------
  2. /////////////////////////////////////////////////////////////////////////////////
  3. //
  4. // Microsoft Windows
  5. // Copyright (C) Microsoft Corporation, 1997-2002.
  6. //
  7. // File: ComponentDataRSOP.cpp
  8. //
  9. // Contents: Implementation of RSOP portions CCertMgrComponentData
  10. //
  11. //----------------------------------------------------------------------------
  12. #include "stdafx.h"
  13. #include <gpedit.h>
  14. #include "compdata.h"
  15. #include "dataobj.h"
  16. #include "cookie.h"
  17. #include "Certifct.h"
  18. #pragma warning(push, 3)
  19. #include <wintrust.h>
  20. #include <cryptui.h>
  21. #include <sceattch.h>
  22. #pragma warning(pop)
  23. #include "StoreRSOP.h"
  24. #ifdef _DEBUG
  25. #ifndef ALPHA
  26. #define new DEBUG_NEW
  27. #endif
  28. #undef THIS_FILE
  29. static char THIS_FILE[] = __FILE__;
  30. #endif
  31. //
  32. // CCertMgrComponentData
  33. //
  34. HRESULT CCertMgrComponentData::BuildWMIList (LPDATAOBJECT pDataObject, bool bIsComputer)
  35. {
  36. _TRACE (1, L"Entering CCertMgrComponentData::BuildWMIList (%s)\n", bIsComputer ? L"computer" : L"user");
  37. HRESULT hr = S_OK;
  38. #if DBG
  39. if ( bIsComputer )
  40. {
  41. _TRACE (0, L"m_rsopObjectArrayComputer contains %d objects\n",
  42. m_rsopObjectArrayComputer.GetUpperBound ());
  43. }
  44. else
  45. {
  46. _TRACE (0, L"m_rsopObjectArrayUser contains %d objects\n",
  47. m_rsopObjectArrayUser.GetUpperBound ());
  48. }
  49. #endif
  50. int nIndex = 0;
  51. if ( bIsComputer )
  52. {
  53. INT_PTR nUpperBound = m_rsopObjectArrayComputer.GetUpperBound ();
  54. while ( nUpperBound >= nIndex )
  55. {
  56. CRSOPObject* pCurrObject = m_rsopObjectArrayComputer.GetAt (nIndex);
  57. if ( pCurrObject )
  58. {
  59. delete pCurrObject;
  60. }
  61. nIndex++;
  62. }
  63. m_rsopObjectArrayComputer.RemoveAll ();
  64. }
  65. else
  66. {
  67. INT_PTR nUpperBound = m_rsopObjectArrayUser.GetUpperBound ();
  68. while ( nUpperBound >= nIndex )
  69. {
  70. CRSOPObject* pCurrObject = m_rsopObjectArrayUser.GetAt (nIndex);
  71. if ( pCurrObject )
  72. {
  73. delete pCurrObject;
  74. }
  75. nIndex++;
  76. }
  77. m_rsopObjectArrayUser.RemoveAll ();
  78. }
  79. if ( ((bIsComputer && !m_pRSOPInformationComputer) ||
  80. (!bIsComputer && !m_pRSOPInformationUser) )
  81. && pDataObject )
  82. {
  83. IUnknown* pIUnknown = 0;
  84. hr = ExtractData (pDataObject,
  85. CCertMgrDataObject::m_CFSCE_RSOPUnknown,
  86. &pIUnknown, sizeof (IUnknown*));
  87. ASSERT (SUCCEEDED (hr));
  88. if ( SUCCEEDED (hr) )
  89. {
  90. if ( bIsComputer )
  91. {
  92. hr = pIUnknown->QueryInterface (
  93. IID_PPV_ARG (IRSOPInformation, &m_pRSOPInformationComputer));
  94. }
  95. else
  96. {
  97. hr = pIUnknown->QueryInterface (
  98. IID_PPV_ARG (IRSOPInformation, &m_pRSOPInformationUser));
  99. }
  100. ASSERT (SUCCEEDED (hr));
  101. if ( SUCCEEDED (hr) )
  102. {
  103. if ( bIsComputer )
  104. {
  105. hr = m_pRSOPInformationComputer->GetFlags (&m_dwRSOPFlagsComputer);
  106. }
  107. else
  108. {
  109. hr = m_pRSOPInformationUser->GetFlags (&m_dwRSOPFlagsUser);
  110. }
  111. ASSERT (SUCCEEDED (hr));
  112. int cchMaxLength = 512;
  113. LPOLESTR pszNameSpace = (LPOLESTR) LocalAlloc (LPTR, cchMaxLength * sizeof (WCHAR));
  114. if ( pszNameSpace )
  115. {
  116. DWORD dwSection = 0;
  117. switch (m_dwSCEMode)
  118. {
  119. case SCE_MODE_LOCAL_USER:
  120. case SCE_MODE_DOMAIN_USER:
  121. case SCE_MODE_OU_USER:
  122. case SCE_MODE_REMOTE_USER:
  123. case SCE_MODE_RSOP_USER:
  124. dwSection = GPO_SECTION_USER;
  125. break;
  126. case SCE_MODE_LOCAL_COMPUTER:
  127. case SCE_MODE_DOMAIN_COMPUTER:
  128. case SCE_MODE_OU_COMPUTER:
  129. case SCE_MODE_RSOP_COMPUTER:
  130. case SCE_MODE_REMOTE_COMPUTER:
  131. dwSection = GPO_SECTION_MACHINE;
  132. break;
  133. default:
  134. ASSERT (0);
  135. return E_UNEXPECTED;
  136. }
  137. if ( bIsComputer )
  138. {
  139. hr = m_pRSOPInformationComputer->GetNamespace (
  140. dwSection,
  141. pszNameSpace,
  142. cchMaxLength);
  143. }
  144. else
  145. {
  146. hr = m_pRSOPInformationUser->GetNamespace (
  147. dwSection,
  148. pszNameSpace,
  149. cchMaxLength);
  150. }
  151. if ( SUCCEEDED (hr) )
  152. {
  153. IWbemLocator *pIWbemLocator = 0;
  154. // ISSUE
  155. // NTRAID 544154 TRACKING: PKP GrpPol: Verify that WMI communication with the store can be secured
  156. hr = ::CoCreateInstance (CLSID_WbemLocator,
  157. NULL,
  158. CLSCTX_INPROC_SERVER,
  159. IID_PPV_ARG(IWbemLocator, &pIWbemLocator));
  160. if ( SUCCEEDED (hr) )
  161. {
  162. BSTR bstrNameSpace = SysAllocString (pszNameSpace);
  163. if ( bstrNameSpace )
  164. {
  165. if ( bIsComputer )
  166. {
  167. hr = pIWbemLocator->ConnectServer (bstrNameSpace,
  168. NULL, NULL, 0, 0, NULL, NULL,
  169. &m_pIWbemServicesComputer);
  170. }
  171. else
  172. {
  173. hr = pIWbemLocator->ConnectServer (bstrNameSpace,
  174. NULL, NULL, 0, 0, NULL, NULL,
  175. &m_pIWbemServicesUser);
  176. }
  177. if ( FAILED (hr) )
  178. {
  179. _TRACE (0, L"IWbemLocator::ConnectServer (%s) failed: 0x%x(%s)\n",
  180. bstrNameSpace, hr, (PCWSTR) GetSystemMessage (hr));
  181. }
  182. SysFreeString (bstrNameSpace);
  183. }
  184. else
  185. hr = E_OUTOFMEMORY;
  186. pIWbemLocator->Release ();
  187. }
  188. }
  189. LocalFree (pszNameSpace);
  190. }
  191. else
  192. hr = E_OUTOFMEMORY;
  193. }
  194. }
  195. }
  196. if ( SUCCEEDED (hr) && ((bIsComputer && m_pIWbemServicesComputer) ||
  197. (!bIsComputer && m_pIWbemServicesUser)) )
  198. {
  199. IEnumWbemClassObject * pEnum = 0;
  200. IWbemClassObject *pObject = 0;
  201. ULONG ulRet = 0;
  202. //
  203. // Execute the query
  204. //
  205. if ( bIsComputer )
  206. {
  207. hr = m_pIWbemServicesComputer->ExecQuery (m_pbstrLanguage, m_pbstrQuery,
  208. WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
  209. NULL, &pEnum);
  210. }
  211. else
  212. {
  213. hr = m_pIWbemServicesUser->ExecQuery (m_pbstrLanguage, m_pbstrQuery,
  214. WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
  215. NULL, &pEnum);
  216. }
  217. if ( SUCCEEDED (hr) )
  218. {
  219. //
  220. // Loop through the results retrieving the registry key and value names
  221. //
  222. while ( (hr = pEnum->Next(WBEM_INFINITE, 1, &pObject, &ulRet)) == WBEM_S_NO_ERROR )
  223. {
  224. hr = GetValuesAndInsertInRSOPObjectList (pObject,
  225. bIsComputer ? m_rsopObjectArrayComputer : m_rsopObjectArrayUser,
  226. bIsComputer);
  227. pObject->Release ();
  228. if ( FAILED (hr) )
  229. break;
  230. }
  231. pEnum->Release();
  232. #if DBG
  233. int nSpewIndex = 0;
  234. INT_PTR nUpperBound = 0;
  235. if ( bIsComputer )
  236. nUpperBound = m_rsopObjectArrayComputer.GetUpperBound ();
  237. else
  238. nUpperBound = m_rsopObjectArrayUser.GetUpperBound ();
  239. while ( nUpperBound >= nSpewIndex )
  240. {
  241. CRSOPObject* pCurrObject = 0;
  242. if ( bIsComputer )
  243. pCurrObject = m_rsopObjectArrayComputer.GetAt (nSpewIndex);
  244. else
  245. pCurrObject = m_rsopObjectArrayUser.GetAt (nSpewIndex);
  246. if ( !pCurrObject )
  247. break;
  248. _TRACE (0, L"\t%d\t%s\t%s\t%s\n", pCurrObject->GetPrecedence (),
  249. (PCWSTR) pCurrObject->GetRegistryKey (),
  250. (PCWSTR) pCurrObject->GetValueName (),
  251. (PCWSTR) pCurrObject->GetPolicyName ());
  252. nSpewIndex++;
  253. }
  254. #endif
  255. }
  256. }
  257. _TRACE (-1, L"Leaving CCertMgrComponentData::BuildWMIList (): 0x%x\n", hr);
  258. return hr;
  259. }
  260. HRESULT CCertMgrComponentData::GetValuesAndInsertInRSOPObjectList (
  261. IWbemClassObject* pObject,
  262. CRSOPObjectArray& rRsopObjectArray,
  263. bool bIsComputer)
  264. {
  265. HRESULT hr = S_OK;
  266. if ( !pObject )
  267. return E_POINTER;
  268. //
  269. // Check if the allocations succeeded
  270. //
  271. if ( m_pbstrLanguage && m_pbstrQuery && m_pbstrRegistryKey &&
  272. m_pbstrValueName && m_pbstrValue &&
  273. m_pbstrPrecedence && m_pbstrGPOid )
  274. {
  275. COleVariant varRegistryKey;
  276. COleVariant varValueName;
  277. COleVariant varValue;
  278. COleVariant varPrecedence;
  279. COleVariant varGPOid;
  280. hr = pObject->Get (m_pbstrRegistryKey, 0, &varRegistryKey, NULL, NULL);
  281. if (SUCCEEDED(hr))
  282. {
  283. hr = pObject->Get (m_pbstrValueName, 0, &varValueName, NULL, NULL);
  284. if (SUCCEEDED(hr))
  285. {
  286. hr = pObject->Get (m_pbstrValue, 0, &varValue, NULL, NULL);
  287. if (SUCCEEDED(hr))
  288. {
  289. //#ifndef DBG
  290. // only include objects that have a value name
  291. if ( varValueName.bstrVal[0] )
  292. //#endif
  293. {
  294. //#ifndef DBG
  295. // Only include those objects that are in the system store registry
  296. // path or in the cryptography\autoenrollment path
  297. if ( FoundInRSOPFilter (varRegistryKey.bstrVal) )
  298. //#endif
  299. {
  300. hr = pObject->Get (m_pbstrPrecedence, 0, &varPrecedence, NULL, NULL);
  301. if (SUCCEEDED(hr))
  302. {
  303. hr = pObject->Get (m_pbstrGPOid, 0, &varGPOid, NULL, NULL);
  304. if (SUCCEEDED(hr))
  305. {
  306. PWSTR lpGPOName = 0;
  307. hr = GetGPOFriendlyName (
  308. varGPOid.bstrVal,
  309. &lpGPOName,
  310. bIsComputer);
  311. if (SUCCEEDED(hr))
  312. {
  313. CRSOPObject* pRSOPObject = new CRSOPObject (
  314. varRegistryKey.bstrVal,
  315. varValueName.bstrVal,
  316. lpGPOName,
  317. varPrecedence.uintVal,
  318. varValue,
  319. varGPOid.bstrVal);
  320. if ( pRSOPObject )
  321. {
  322. CRSOPObject* pCurrObject = 0;
  323. int nIndex = 0;
  324. bool bInserted = false;
  325. INT_PTR nUpperBound = rRsopObjectArray.GetUpperBound ();
  326. while ( nUpperBound >= nIndex )
  327. {
  328. pCurrObject = rRsopObjectArray.GetAt (nIndex);
  329. if ( !pCurrObject )
  330. break;
  331. // Sort first by registry key name,
  332. // then by value name, then by
  333. // precedence
  334. // security review 2/22/2002 BryanWal ok
  335. int nCmpVal = wcscmp (pCurrObject->GetRegistryKey (),
  336. pRSOPObject->GetRegistryKey ());
  337. if ( nCmpVal > 0 )
  338. {
  339. rRsopObjectArray.InsertAt (nIndex, pRSOPObject);
  340. bInserted = true;
  341. break;
  342. }
  343. else if ( nCmpVal == 0 )
  344. {
  345. // Sort by value name
  346. // security review 2/22/2002 BryanWal ok
  347. nCmpVal = wcscmp (pCurrObject->GetValueName (),
  348. pRSOPObject->GetValueName ());
  349. if ( nCmpVal > 0 )
  350. {
  351. rRsopObjectArray.InsertAt (nIndex, pRSOPObject);
  352. bInserted = true;
  353. break;
  354. }
  355. else if ( nCmpVal == 0 )
  356. {
  357. // Sort by precedence
  358. if ( pCurrObject->GetPrecedence () >
  359. pRSOPObject->GetPrecedence () )
  360. {
  361. rRsopObjectArray.InsertAt (nIndex, pRSOPObject);
  362. bInserted = true;
  363. break;
  364. }
  365. else if ( pCurrObject->GetPrecedence () ==
  366. pRSOPObject->GetPrecedence () )
  367. {
  368. // The registry key, value name and precedence
  369. // are the same - this is a duplicate. Pretend
  370. // we've added it and move on.
  371. bInserted = true;
  372. break;
  373. }
  374. }
  375. }
  376. nIndex++;
  377. }
  378. if ( !bInserted )
  379. rRsopObjectArray.Add (pRSOPObject);
  380. }
  381. LocalFree (lpGPOName);
  382. }
  383. varGPOid.Clear ();
  384. }
  385. varPrecedence.Clear ();
  386. }
  387. }
  388. }
  389. varValue.Clear ();
  390. }
  391. varValueName.Clear ();
  392. }
  393. varRegistryKey.Clear ();
  394. }
  395. }
  396. else
  397. hr = E_OUTOFMEMORY;
  398. return hr;
  399. }
  400. HRESULT CCertMgrComponentData::GetGPOFriendlyName (PCWSTR pwszOID, PWSTR *ppwszGPOName, bool bIsComputer)
  401. {
  402. ASSERT (pwszOID);
  403. if ( !pwszOID )
  404. return E_POINTER;
  405. ASSERT (ppwszGPOName);
  406. if ( !ppwszGPOName )
  407. return E_POINTER;
  408. HRESULT hr = S_OK;
  409. //
  410. // Set the default
  411. //
  412. *ppwszGPOName = NULL;
  413. //
  414. // Build the query
  415. //
  416. PCWSTR pwszQueryFormat = L"SELECT name, id FROM RSOP_GPO where id=\"%s\"";
  417. // security review 2/22/2002 BryanWal ok
  418. PWSTR pwszQuery = (PWSTR) ::LocalAlloc (LPTR, ((wcslen(pwszOID) + wcslen (pwszQueryFormat) + 1) * sizeof(WCHAR)));
  419. if ( pwszQuery )
  420. {
  421. // security review 2/22/2002 BryanWal ok
  422. wsprintf (pwszQuery, pwszQueryFormat, pwszOID);
  423. BSTR bstrQuery = SysAllocString (pwszQuery);
  424. if (bstrQuery)
  425. {
  426. //
  427. // Allocate BSTRs for the property names we want to retreive
  428. //
  429. BSTR bstrName = SysAllocString (TEXT("name"));
  430. if (bstrName)
  431. {
  432. //
  433. // Execute the query
  434. //
  435. IEnumWbemClassObject* pEnum = 0;
  436. if ( bIsComputer )
  437. {
  438. hr = m_pIWbemServicesComputer->ExecQuery (m_pbstrLanguage, bstrQuery,
  439. WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
  440. NULL, &pEnum);
  441. }
  442. else
  443. {
  444. hr = m_pIWbemServicesUser->ExecQuery (m_pbstrLanguage, bstrQuery,
  445. WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
  446. NULL, &pEnum);
  447. }
  448. if ( SUCCEEDED (hr) )
  449. {
  450. //
  451. // Loop through the results
  452. //
  453. IWbemClassObject* pObjects[2] = {0, 0};
  454. ULONG ulRet = 0;
  455. hr = pEnum->Next(WBEM_INFINITE, 1, pObjects, &ulRet);
  456. if ( SUCCEEDED (hr) )
  457. {
  458. //
  459. // Check for the "data not available case"
  460. //
  461. if (ulRet != 0)
  462. {
  463. //
  464. // Get the name
  465. //
  466. VARIANT varGPOName;
  467. hr = pObjects[0]->Get (bstrName, 0, &varGPOName, NULL, NULL);
  468. if ( SUCCEEDED (hr) )
  469. {
  470. //
  471. // Save the name
  472. //
  473. // security review 2/22/2002 BryanWal ok
  474. *ppwszGPOName = (PWSTR) ::LocalAlloc (LPTR, (wcslen (varGPOName.bstrVal) + 1) * sizeof(WCHAR));
  475. if ( *ppwszGPOName )
  476. {
  477. // security review 2/22/2002 BryanWal ok
  478. wcscpy (*ppwszGPOName, varGPOName.bstrVal);
  479. VariantClear (&varGPOName);
  480. hr = S_OK;
  481. }
  482. else
  483. {
  484. _TRACE (0, L"CCertMgrComponentData::GetGPOFriendlyName: Failed to allocate memory for GPO Name");
  485. hr = E_OUTOFMEMORY;
  486. }
  487. }
  488. else
  489. {
  490. _TRACE (0, L"CCertMgrComponentData::GetGPOFriendlyName: Failed to get gponame in query results for %s with 0x%x\n",
  491. bstrQuery, hr);
  492. }
  493. }
  494. }
  495. else
  496. {
  497. _TRACE (0, L"CCertMgrComponentData::GetGPOFriendlyName: Failed to get first item in query results for %s with 0x%x\n",
  498. bstrQuery, hr);
  499. }
  500. pEnum->Release ();
  501. }
  502. else
  503. {
  504. _TRACE (0, L"CCertMgrComponentData::GetGPOFriendlyName: Failed to query for %s with 0x%x\n",
  505. bstrQuery, hr);
  506. }
  507. SysFreeString (bstrName);
  508. }
  509. else
  510. {
  511. _TRACE (0, L"CCertMgrComponentData::GetGPOFriendlyName: Failed to allocate memory for name");
  512. hr = HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY);
  513. }
  514. SysFreeString (bstrQuery);
  515. }
  516. else
  517. {
  518. _TRACE (0, L"CCertMgrComponentData::GetGPOFriendlyName: Failed to allocate memory for query");
  519. hr = E_OUTOFMEMORY;
  520. }
  521. ::LocalFree (pwszQuery);
  522. }
  523. else
  524. {
  525. _TRACE (0, L"CCertMgrComponentData::GetGPOFriendlyName: Failed to allocate memory for unicode query");
  526. hr = E_OUTOFMEMORY;
  527. }
  528. return hr;
  529. }
  530. ///////////////////////////////////////////////////////////////////////////////
  531. ///////////////////////////////////////////////////////////////////////////////
  532. bool CCertMgrPKPolExtension::FoundInRSOPFilter (BSTR bstrKey) const
  533. {
  534. ASSERT (bstrKey);
  535. if ( !bstrKey )
  536. return false;
  537. // security review 2/22/2002 BryanWal ok for all
  538. static size_t nRegPathLen = wcslen (CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH);
  539. static size_t nTrustedPublisherKeyLen =
  540. wcslen (CERT_TRUST_PUB_SAFER_GROUP_POLICY_TRUSTED_PUBLISHER_STORE_REGPATH);
  541. static size_t nDisallowedKeyLen =
  542. wcslen (CERT_TRUST_PUB_SAFER_GROUP_POLICY_DISALLOWED_STORE_REGPATH);
  543. static size_t nSaferKeyLen = wcslen (SAFER_HKLM_REGBASE);
  544. static size_t nEFSKeyLen = wcslen (EFS_SETTINGS_REGPATH);
  545. //Include group policy system stores but not trusted publisher or disallowed
  546. // security review 2/22/2002 BryanWal ok for all
  547. if ( !_wcsnicmp (CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH, bstrKey, nRegPathLen) &&
  548. (_wcsnicmp (CERT_TRUST_PUB_SAFER_GROUP_POLICY_TRUSTED_PUBLISHER_STORE_REGPATH,
  549. bstrKey, nTrustedPublisherKeyLen) &&
  550. _wcsnicmp (CERT_TRUST_PUB_SAFER_GROUP_POLICY_DISALLOWED_STORE_REGPATH,
  551. bstrKey, nDisallowedKeyLen)) )
  552. {
  553. return true;
  554. }
  555. else if ( !_wcsnicmp (SAFER_HKLM_REGBASE, bstrKey, nSaferKeyLen) ||
  556. !_wcsnicmp (EFS_SETTINGS_REGPATH, bstrKey, nEFSKeyLen) ||
  557. !_wcsicmp (AUTO_ENROLLMENT_KEY, bstrKey) )
  558. {
  559. return true;
  560. }
  561. else
  562. return false;
  563. }