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.

517 lines
21 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997-2002.
  5. //
  6. // File: StoreRSOP.cpp
  7. //
  8. // Contents: Implementation of CCertStoreRSOP
  9. //
  10. //----------------------------------------------------------------------------
  11. #include "stdafx.h"
  12. #include <gpedit.h>
  13. #include "cookie.h"
  14. #include "StoreRSOP.h"
  15. #include "certifct.h"
  16. USE_HANDLE_MACROS("CERTMGR(StoreRSOP.cpp)")
  17. #ifdef _DEBUG
  18. #ifndef ALPHA
  19. #define new DEBUG_NEW
  20. #endif
  21. #undef THIS_FILE
  22. static char THIS_FILE[] = __FILE__;
  23. #endif
  24. extern GUID g_guidExtension;
  25. extern GUID g_guidRegExt;
  26. extern GUID g_guidSnapin;
  27. ///////////////////////////////////////////////////////////////////////////////
  28. ///////////////////////////////////////////////////////////////////////////////
  29. CCertStoreRSOP::CCertStoreRSOP (
  30. DWORD dwFlags,
  31. LPCWSTR lpcszMachineName,
  32. LPCWSTR objectName,
  33. const CString & pcszLogStoreName,
  34. const CString & pcszPhysStoreName,
  35. CRSOPObjectArray& rsopObjectArray,
  36. const GUID& compDataGUID,
  37. IConsole* pConsole)
  38. : CCertStore (CERTMGR_LOG_STORE_RSOP,
  39. CERT_STORE_PROV_SYSTEM, dwFlags, lpcszMachineName, objectName,
  40. pcszLogStoreName, pcszPhysStoreName,
  41. StoreNameToType (pcszLogStoreName),
  42. 0,
  43. pConsole),
  44. m_fIsNullEFSPolicy (true) // assume NULL policy until proven otherwise
  45. {
  46. _TRACE (1, L"Entering CCertStoreRSOP::CCertStoreRSOP - %s\n",
  47. (LPCWSTR) pcszLogStoreName);
  48. ASSERT (CERTMGR_LOG_STORE_RSOP == m_objecttype);
  49. if ( ::IsEqualGUID (compDataGUID, NODEID_User) )
  50. {
  51. m_fIsComputerType = false;
  52. m_dwFlags |= CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY;
  53. }
  54. else if ( ::IsEqualGUID (compDataGUID, NODEID_Machine) )
  55. {
  56. m_fIsComputerType = true;
  57. m_dwFlags |= CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY;
  58. }
  59. else
  60. ASSERT (0);
  61. int nIndex = 0;
  62. INT_PTR nUpperBound = rsopObjectArray.GetUpperBound ();
  63. bool bFound = false;
  64. CString storePath = CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH;
  65. storePath += L"\\";
  66. storePath += m_pcszStoreName;
  67. size_t nStoreLen = storePath.GetLength ();
  68. CString szWinningEFSPolicy;
  69. while ( nUpperBound >= nIndex )
  70. {
  71. CRSOPObject* pObject = rsopObjectArray.GetAt (nIndex);
  72. if ( pObject )
  73. {
  74. // Only add if
  75. // 1. Precedence is 1
  76. // 2. The object belongs to this store
  77. // 3. The valueName is not empty
  78. if ( 1 == pObject->GetPrecedence () )
  79. {
  80. // Consider only entries from this store
  81. // security review 2/25/2002 BryanWal ok
  82. if ( !wcsncmp (storePath, pObject->GetRegistryKey (), nStoreLen) )
  83. {
  84. bFound = true;
  85. if ( !pObject->GetValueName ().IsEmpty () )
  86. {
  87. // NTRAID# 477258 AddRSoP: EFS: Domain policy should
  88. // be disabled once OU policy has been established
  89. if ( EFS_STORE == GetStoreType () )
  90. {
  91. // Find "EFSBlob". Because the list is sorted,
  92. // this will be found before all the "Certificate"
  93. // keys that have the value of "Blob". There should
  94. // only be one "EFSBlob" that has a precedence of 1.
  95. // This winning EFSBlob will contain the winning
  96. // GPO OID, which we will cache. After this, we
  97. // will only keep certificates that have this same
  98. // policy OID.
  99. // Note that the EFSBlob is a special structure that
  100. // also contains all the EFS certificates, but each
  101. // EFSBlob have a unique precedence, while all the
  102. // "Blob"s have a precedence of 1, even if they
  103. // will not be applied.
  104. if ( CERT_EFSBLOB_VALUE_NAME == pObject->GetValueName () )
  105. {
  106. ASSERT (-1 == m_rsopObjectArray.GetUpperBound ());
  107. ASSERT (szWinningEFSPolicy.IsEmpty ());
  108. szWinningEFSPolicy = pObject->GetPolicyOID ();
  109. }
  110. else if ( szWinningEFSPolicy == pObject->GetPolicyOID () )
  111. {
  112. CRSOPObject* pNewObject = new CRSOPObject (*pObject);
  113. if ( pNewObject )
  114. m_rsopObjectArray.Add (pNewObject);
  115. }
  116. }
  117. else
  118. {
  119. CRSOPObject* pNewObject = new CRSOPObject (*pObject);
  120. if ( pNewObject )
  121. m_rsopObjectArray.Add (pNewObject);
  122. }
  123. }
  124. }
  125. else if ( bFound )
  126. {
  127. // Since the list is sorted, and we've already found the
  128. // desired RSOP objects and no longer are finding them,
  129. // there aren't any more. We can optimize and break here.
  130. break;
  131. }
  132. }
  133. }
  134. else
  135. break;
  136. nIndex++;
  137. }
  138. _TRACE (-1, L"Leaving CCertStoreRSOP::CCertStoreRSOP - %s\n",
  139. (LPCWSTR) pcszLogStoreName);
  140. }
  141. CCertStoreRSOP::~CCertStoreRSOP ()
  142. {
  143. _TRACE (1, L"Entering CCertStoreRSOP::~CCertStoreRSOP - %s\n",
  144. (LPCWSTR) m_pcszStoreName);
  145. ASSERT (CERTMGR_LOG_STORE_RSOP == m_objecttype);
  146. INT_PTR nUpperBound = m_rsopObjectArray.GetUpperBound ();
  147. int nIndex = 0;
  148. while (nUpperBound >= nIndex)
  149. {
  150. CRSOPObject* pObject = m_rsopObjectArray.GetAt (nIndex);
  151. if ( pObject )
  152. {
  153. delete pObject;
  154. }
  155. else
  156. break;
  157. nIndex++;
  158. }
  159. _TRACE (-1, L"Leaving CCertStoreRSOP::~CCertStoreRSOP - %s\n",
  160. (LPCWSTR) m_pcszStoreName);
  161. }
  162. HCERTSTORE CCertStoreRSOP::GetStoreHandle (BOOL bSilent /*= FALSE*/, HRESULT* phr /* = 0*/)
  163. {
  164. _TRACE (1, L"Entering CCertStoreRSOP::GetStoreHandle - %s\n",
  165. (LPCWSTR) m_pcszStoreName);
  166. ASSERT (CERTMGR_LOG_STORE_RSOP == m_objecttype);
  167. if ( !m_hCertStore )
  168. {
  169. DWORD dwErr = 0;
  170. //open a generic memory store
  171. m_hCertStore = ::CertOpenStore (CERT_STORE_PROV_MEMORY,
  172. 0, NULL,
  173. CERT_STORE_SET_LOCALIZED_NAME_FLAG | CERT_STORE_MAXIMUM_ALLOWED_FLAG,
  174. NULL);
  175. if ( m_hCertStore )
  176. {
  177. // Certificates, CTLs and other objects are either stored integrally in a
  178. // value called "Blob" or broken up into multiple parts. In this case, we'll
  179. // first see "BlobCount", which tells us how many parts there are, then
  180. // "BlobLength" which tells us the total byte length and finally
  181. // "Blob0", "Blob1", etc. to "Blob<BlobCount-1>"
  182. // Check for Certificates
  183. GetBlobs ();
  184. }
  185. else
  186. {
  187. dwErr = GetLastError ();
  188. if ( phr )
  189. *phr = HRESULT_FROM_WIN32 (dwErr);
  190. _TRACE (0, L"CertOpenStore (CERT_STORE_PROV_MEMORY) failed: 0x%x\n", dwErr);
  191. }
  192. if ( !m_hCertStore && !m_bUnableToOpenMsgDisplayed
  193. && !bSilent &&
  194. (USERDS_STORE != GetStoreType ()) )
  195. {
  196. m_bUnableToOpenMsgDisplayed = true;
  197. CString caption;
  198. CString text;
  199. int iRetVal = 0;
  200. VERIFY (caption.LoadString (IDS_CERTIFICATE_MANAGER));
  201. text.FormatMessage (IDS_UNABLE_TO_OPEN_STORE, GetStoreName (),
  202. GetSystemMessage (dwErr));
  203. if ( m_pConsole )
  204. m_pConsole->MessageBox (text, caption, MB_OK, &iRetVal);
  205. }
  206. }
  207. _TRACE (-1, L"Leaving CCertStoreRSOP::GetStoreHandle - %s\n",
  208. (LPCWSTR) m_pcszStoreName);
  209. return m_hCertStore;
  210. }
  211. HRESULT CCertStoreRSOP::GetBlobs ()
  212. {
  213. HRESULT hr = S_OK;
  214. INT_PTR nUpperBound = m_rsopObjectArray.GetUpperBound ();
  215. int nIndex = 0;
  216. while (nUpperBound >= nIndex)
  217. {
  218. CRSOPObject* pObject = m_rsopObjectArray.GetAt (nIndex);
  219. if ( pObject )
  220. {
  221. if ( STR_BLOB == pObject->GetValueName () )
  222. {
  223. // If this is a single, serialized cert, get it and
  224. // add it to the store
  225. BYTE* pByte = pObject->GetBlob ();
  226. ASSERT (pByte);
  227. if ( pByte )
  228. {
  229. if ( !CertAddSerializedElementToStore (
  230. m_hCertStore,
  231. pByte,
  232. (DWORD) pObject->GetBlobLength (),
  233. CERT_STORE_ADD_ALWAYS,
  234. 0,
  235. CERT_STORE_ALL_CONTEXT_FLAG,
  236. NULL,
  237. NULL) )
  238. {
  239. _TRACE (0, L"CertAddSerializedElementToStore () failed: 0x%x\n",
  240. GetLastError ());
  241. }
  242. }
  243. }
  244. else if ( STR_BLOBCOUNT == pObject->GetValueName () )
  245. {
  246. CString szBaseRegKey = pObject->GetRegistryKey ();
  247. DWORD dwBlobCount = pObject->GetDWORDValue ();
  248. if ( dwBlobCount > 0 )
  249. {
  250. nIndex++;
  251. if (nUpperBound >= nIndex)
  252. {
  253. // Get the blob length
  254. pObject = m_rsopObjectArray.GetAt (nIndex);
  255. if ( pObject )
  256. {
  257. if ( STR_BLOBLENGTH == pObject->GetValueName () )
  258. {
  259. DWORD dwBlobLength = pObject->GetDWORDValue ();
  260. if ( dwBlobLength )
  261. {
  262. BYTE* pbyLob = new BYTE[dwBlobLength];
  263. if ( pbyLob )
  264. {
  265. size_t nTotalBlobLength = 0;
  266. BYTE* pbyLobPtr = pbyLob;
  267. for (DWORD dwBlob = 0; dwBlob < dwBlobCount; dwBlob++)
  268. {
  269. nIndex++;
  270. if ( nUpperBound >= nIndex )
  271. {
  272. // security review 2/25/2002 BryanWal
  273. // NOTICE. Docs say that int64 requires 33 chars,
  274. // so DWORD would require half that many (17)
  275. // NOTICE: 4 == wcslen (STR_BLOB) ("Blob")
  276. ASSERT (4 == wcslen (STR_BLOB));
  277. const size_t BUF_LEN = 4 + 17 + 1;
  278. WCHAR szName[BUF_LEN];
  279. wsprintf (szName, L"%s%d", STR_BLOB, dwBlob);
  280. CString szRegKey = szBaseRegKey;
  281. szRegKey += L"\\";
  282. szRegKey += szName;
  283. pObject = m_rsopObjectArray.GetAt (nIndex);
  284. if ( pObject )
  285. {
  286. if ( nTotalBlobLength + pObject->GetBlobLength () <=
  287. dwBlobLength )
  288. {
  289. if ( szRegKey == pObject->GetRegistryKey () &&
  290. STR_BLOB == pObject->GetValueName () )
  291. {
  292. BYTE* pByte = pObject->GetBlob ();
  293. if ( pByte )
  294. {
  295. // security review 2/25/2002 BryanWal
  296. // NOTICE: Add length addition check above to
  297. // to prevent buffer overflow here if registry
  298. // data is bad
  299. memcpy (pbyLobPtr, pByte, pObject->GetBlobLength ());
  300. pbyLobPtr += pObject->GetBlobLength ();
  301. nTotalBlobLength += pObject->GetBlobLength ();
  302. }
  303. else
  304. {
  305. ASSERT (0);
  306. hr = E_UNEXPECTED;
  307. break;
  308. }
  309. }
  310. else
  311. {
  312. ASSERT (0);
  313. hr = E_UNEXPECTED;
  314. break;
  315. }
  316. }
  317. else
  318. {
  319. ASSERT (0);
  320. hr = E_UNEXPECTED;
  321. break;
  322. }
  323. }
  324. else
  325. {
  326. ASSERT (0);
  327. hr = E_UNEXPECTED;
  328. break;
  329. }
  330. }
  331. else
  332. {
  333. ASSERT (0);
  334. hr = E_UNEXPECTED;
  335. break;
  336. }
  337. }
  338. if ( SUCCEEDED (hr) && nTotalBlobLength == (size_t) dwBlobLength )
  339. {
  340. if ( !CertAddSerializedElementToStore (
  341. m_hCertStore,
  342. pbyLob,
  343. dwBlobLength,
  344. CERT_STORE_ADD_ALWAYS,
  345. 0,
  346. CERT_STORE_ALL_CONTEXT_FLAG,
  347. NULL,
  348. NULL) )
  349. {
  350. _TRACE (0, L"CertAddSerializedElementToStore () failed: 0x%x\n",
  351. GetLastError ());
  352. }
  353. }
  354. delete [] pbyLob;
  355. }
  356. else
  357. {
  358. hr = E_OUTOFMEMORY;
  359. break;
  360. }
  361. }
  362. else
  363. {
  364. ASSERT (0);
  365. hr = E_UNEXPECTED;
  366. break;
  367. }
  368. }
  369. else
  370. {
  371. ASSERT (0);
  372. hr = E_UNEXPECTED;
  373. break;
  374. }
  375. }
  376. else
  377. {
  378. ASSERT (0);
  379. hr = E_UNEXPECTED;
  380. break;
  381. }
  382. }
  383. else
  384. {
  385. ASSERT (0);
  386. hr = E_UNEXPECTED;
  387. break;
  388. }
  389. }
  390. }
  391. }
  392. else
  393. break;
  394. nIndex++;
  395. }
  396. return hr;
  397. }
  398. bool CCertStoreRSOP::CanContain(CertificateManagerObjectType nodeType)
  399. {
  400. _TRACE (1, L"Entering CCertStoreRSOP::CanContain - %s\n",
  401. (LPCWSTR) m_pcszStoreName);
  402. ASSERT (CERTMGR_LOG_STORE_RSOP == m_objecttype);
  403. bool bCanContain = false;
  404. switch (nodeType)
  405. {
  406. case CERTMGR_CERTIFICATE:
  407. if ( ROOT_STORE == GetStoreType () ||
  408. EFS_STORE == GetStoreType () )
  409. {
  410. bCanContain = true;
  411. }
  412. break;
  413. case CERTMGR_CTL:
  414. if ( TRUST_STORE == GetStoreType () )
  415. {
  416. bCanContain = true;
  417. }
  418. break;
  419. default:
  420. break;
  421. }
  422. _TRACE (-1, L"Leaving CCertStoreRSOP::CanContain - %s\n",
  423. (LPCWSTR) m_pcszStoreName);
  424. return bCanContain;
  425. }
  426. bool CCertStoreRSOP::IsMachineStore()
  427. {
  428. _TRACE (0, L"Entering and leaving CCertStoreRSOP::IsMachineStore - %s\n",
  429. (LPCWSTR) m_pcszStoreName);
  430. ASSERT (CERTMGR_LOG_STORE_RSOP == m_objecttype);
  431. if (m_dwFlags & CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY)
  432. return true;
  433. else
  434. return false;
  435. }
  436. void CCertStoreRSOP::FinalCommit()
  437. {
  438. _TRACE (1, L"Entering CCertStoreRSOP::FinalCommit - %s\n",
  439. (LPCWSTR) m_pcszStoreName);
  440. ASSERT (CERTMGR_LOG_STORE_RSOP == m_objecttype);
  441. // Called only from destructor
  442. // Cannot commit here for GPT: GPT has already freed all pertinent data
  443. _TRACE (-1, L"Leaving CCertStoreRSOP::FinalCommit - %s\n",
  444. (LPCWSTR) m_pcszStoreName);
  445. }
  446. bool CCertStoreRSOP::IsNullEFSPolicy()
  447. {
  448. _TRACE (1, L"Entering CCertStoreRSOP::IsNullEFSPolicy - %s\n",
  449. (LPCWSTR) m_pcszStoreName);
  450. GetStoreHandle (); // to initialize
  451. PCCERT_CONTEXT pCertContext = EnumCertificates (0); // sets m_fIsNullEFSPolicy
  452. if ( pCertContext )
  453. ::CertFreeCertificateContext (pCertContext);
  454. Close ();
  455. _TRACE (-1, L"Leaving CCertStoreRSOP::IsNullEFSPolicy - %s\n",
  456. (LPCWSTR) m_pcszStoreName);
  457. return m_fIsNullEFSPolicy;
  458. }
  459. void CCertStoreRSOP::AllowEmptyEFSPolicy()
  460. {
  461. _TRACE (1, L"Entering CCertStoreRSOP::AllowEmptyEFSPolicy - %s\n",
  462. (LPCWSTR) m_pcszStoreName);
  463. m_fIsNullEFSPolicy = false;
  464. _TRACE (-1, L"Leaving CCertStoreRSOP::AllowEmptyEFSPolicy - %s\n",
  465. (LPCWSTR) m_pcszStoreName);
  466. }
  467. PCCERT_CONTEXT CCertStoreRSOP::EnumCertificates (PCCERT_CONTEXT pPrevCertContext)
  468. {
  469. PCCERT_CONTEXT pCertContext = CCertStore::EnumCertificates (pPrevCertContext);
  470. if ( pCertContext )
  471. m_fIsNullEFSPolicy = false;
  472. return pCertContext;
  473. }