windows-nt/Source/XPSP1/NT/admin/snapin/certmgr/storersop.cpp
2020-09-26 16:20:57 +08:00

461 lines
16 KiB
C++

//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1997-2001.
//
// File: StoreRSOP.cpp
//
// Contents: Implementation of CCertStoreRSOP
//
//----------------------------------------------------------------------------
#include "stdafx.h"
#include <gpedit.h>
#include "cookie.h"
#include "StoreRSOP.h"
#include "certifct.h"
USE_HANDLE_MACROS("CERTMGR(StoreRSOP.cpp)")
#ifdef _DEBUG
#ifndef ALPHA
#define new DEBUG_NEW
#endif
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
extern GUID g_guidExtension;
extern GUID g_guidRegExt;
extern GUID g_guidSnapin;
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
CCertStoreRSOP::CCertStoreRSOP (
DWORD dwFlags,
LPCWSTR lpcszMachineName,
LPCWSTR objectName,
const CString & pcszLogStoreName,
const CString & pcszPhysStoreName,
CRSOPObjectArray& rsopObjectArray,
const GUID& compDataGUID,
IConsole* pConsole)
: CCertStore (CERTMGR_LOG_STORE_RSOP,
CERT_STORE_PROV_SYSTEM, dwFlags, lpcszMachineName, objectName,
pcszLogStoreName, pcszPhysStoreName,
StoreNameToType (pcszLogStoreName),
0,
pConsole),
m_fIsComputerType (false),
m_fIsNullEFSPolicy (true) // assume NULL policy until proven otherwise
{
_TRACE (1, L"Entering CCertStoreRSOP::CCertStoreRSOP - %s\n",
(LPCWSTR) pcszLogStoreName);
ASSERT (CERTMGR_LOG_STORE_RSOP == m_objecttype);
if ( ::IsEqualGUID (compDataGUID, NODEID_User) )
{
m_fIsComputerType = false;
m_dwFlags |= CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY;
}
else if ( ::IsEqualGUID (compDataGUID, NODEID_Machine) )
{
m_fIsComputerType = true;
m_dwFlags |= CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY;
}
else
ASSERT (0);
int nIndex = 0;
INT_PTR nUpperBound = rsopObjectArray.GetUpperBound ();
bool bFound = false;
CString storePath = CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH;
storePath += L"\\";
storePath += m_pcszStoreName;
size_t nStoreLen = storePath.GetLength ();
while ( nUpperBound >= nIndex )
{
CRSOPObject* pObject = rsopObjectArray.GetAt (nIndex);
if ( pObject )
{
// Only add if
// 1. Precedence is 1
// 2. The object belongs to this store
// 3. The valueName is not empty
if ( 1 == pObject->GetPrecedence () )
{
// Consider only entries from this store
if ( !wcsncmp (storePath, pObject->GetRegistryKey (), nStoreLen) )
{
bFound = true;
if ( !pObject->GetValueName ().IsEmpty () )
{
CRSOPObject* pNewObject = new CRSOPObject (*pObject);
if ( pNewObject )
m_rsopObjectArray.Add (pNewObject);
}
}
else if ( bFound )
{
// Since the list is sorted, and we've already found the
// desired RSOP objects and no longer are finding them,
// there aren't any more. We can optimize and break here.
break;
}
}
}
else
break;
nIndex++;
}
_TRACE (-1, L"Leaving CCertStoreRSOP::CCertStoreRSOP - %s\n",
(LPCWSTR) pcszLogStoreName);
}
CCertStoreRSOP::~CCertStoreRSOP ()
{
_TRACE (1, L"Entering CCertStoreRSOP::~CCertStoreRSOP - %s\n",
(LPCWSTR) m_pcszStoreName);
ASSERT (CERTMGR_LOG_STORE_RSOP == m_objecttype);
INT_PTR nUpperBound = m_rsopObjectArray.GetUpperBound ();
int nIndex = 0;
while (nUpperBound >= nIndex)
{
CRSOPObject* pObject = m_rsopObjectArray.GetAt (nIndex);
if ( pObject )
{
delete pObject;
}
else
break;
nIndex++;
}
_TRACE (-1, L"Leaving CCertStoreRSOP::~CCertStoreRSOP - %s\n",
(LPCWSTR) m_pcszStoreName);
}
HCERTSTORE CCertStoreRSOP::GetStoreHandle (BOOL bSilent /*= FALSE*/, HRESULT* phr /* = 0*/)
{
_TRACE (1, L"Entering CCertStoreRSOP::GetStoreHandle - %s\n",
(LPCWSTR) m_pcszStoreName);
ASSERT (CERTMGR_LOG_STORE_RSOP == m_objecttype);
if ( !m_hCertStore )
{
DWORD dwErr = 0;
//open a generic memory store
m_hCertStore = ::CertOpenStore (CERT_STORE_PROV_MEMORY,
0, NULL,
CERT_STORE_SET_LOCALIZED_NAME_FLAG | CERT_STORE_MAXIMUM_ALLOWED_FLAG,
NULL);
if ( m_hCertStore )
{
// Certificates, CTLs and other objects are either stored integrally in a
// value called "Blob" or broken up into multiple parts. In this case, we'll
// first see "BlobCount", which tells us how many parts there are, then
// "BlobLength" which tells us the total byte length and finally
// "Blob0", "Blob1", etc. to "Blob<BlobCount-1>"
// Check for Certificates
GetBlobs ();
}
else
{
dwErr = GetLastError ();
if ( phr )
*phr = HRESULT_FROM_WIN32 (dwErr);
_TRACE (0, L"CertOpenStore (CERT_STORE_PROV_MEMORY) failed: 0x%x\n", dwErr);
}
if ( !m_hCertStore && !m_bUnableToOpenMsgDisplayed
&& !bSilent &&
(USERDS_STORE != GetStoreType ()) )
{
m_bUnableToOpenMsgDisplayed = true;
CString caption;
CString text;
int iRetVal = 0;
VERIFY (caption.LoadString (IDS_CERTIFICATE_MANAGER));
text.FormatMessage (IDS_UNABLE_TO_OPEN_STORE, GetStoreName (),
GetSystemMessage (dwErr));
if ( m_pConsole )
m_pConsole->MessageBox (text, caption, MB_OK, &iRetVal);
}
}
_TRACE (-1, L"Leaving CCertStoreRSOP::GetStoreHandle - %s\n",
(LPCWSTR) m_pcszStoreName);
return m_hCertStore;
}
HRESULT CCertStoreRSOP::GetBlobs ()
{
HRESULT hr = S_OK;
INT_PTR nUpperBound = m_rsopObjectArray.GetUpperBound ();
int nIndex = 0;
while (nUpperBound >= nIndex)
{
CRSOPObject* pObject = m_rsopObjectArray.GetAt (nIndex);
if ( pObject )
{
if ( STR_BLOB == pObject->GetValueName () )
{
// If this is a single, serialized cert, get it and
// add it to the store
BYTE* pByte = pObject->GetBlob ();
ASSERT (pByte);
if ( pByte )
{
if ( !CertAddSerializedElementToStore (
m_hCertStore,
pByte,
(DWORD) pObject->GetBlobLength (),
CERT_STORE_ADD_ALWAYS,
0,
CERT_STORE_ALL_CONTEXT_FLAG,
NULL,
NULL) )
{
_TRACE (0, L"CertAddSerializedElementToStore () failed: 0x%x\n",
GetLastError ());
}
}
}
else if ( STR_BLOBCOUNT == pObject->GetValueName () )
{
CString szBaseRegKey = pObject->GetRegistryKey ();
DWORD dwBlobCount = pObject->GetDWORDValue ();
if ( dwBlobCount > 0 )
{
nIndex++;
if (nUpperBound >= nIndex)
{
// Get the blob length
pObject = m_rsopObjectArray.GetAt (nIndex);
if ( pObject )
{
if ( STR_BLOBLENGTH == pObject->GetValueName () )
{
DWORD dwBlobLength = pObject->GetDWORDValue ();
if ( dwBlobLength )
{
BYTE* pbyLob = new BYTE[dwBlobLength];
if ( pbyLob )
{
size_t nTotalBlobLength = 0;
BYTE* pbyLobPtr = pbyLob;
for (DWORD dwBlob = 0; dwBlob < dwBlobCount; dwBlob++)
{
nIndex++;
if ( nUpperBound >= nIndex )
{
WCHAR szName[16];
wsprintf (szName, L"%s%d", STR_BLOB, dwBlob);
CString szRegKey = szBaseRegKey;
szRegKey += L"\\";
szRegKey += szName;
pObject = m_rsopObjectArray.GetAt (nIndex);
if ( pObject )
{
if ( szRegKey == pObject->GetRegistryKey () &&
STR_BLOB == pObject->GetValueName () )
{
BYTE* pByte = pObject->GetBlob ();
if ( pByte )
{
memcpy (pbyLobPtr, pByte, pObject->GetBlobLength ());
pbyLobPtr += pObject->GetBlobLength ();
nTotalBlobLength += pObject->GetBlobLength ();
}
else
{
ASSERT (0);
hr = E_UNEXPECTED;
break;
}
}
else
{
ASSERT (0);
hr = E_UNEXPECTED;
break;
}
}
else
{
ASSERT (0);
hr = E_UNEXPECTED;
break;
}
}
else
{
ASSERT (0);
hr = E_UNEXPECTED;
break;
}
}
if ( SUCCEEDED (hr) && nTotalBlobLength == (size_t) dwBlobLength )
{
if ( !CertAddSerializedElementToStore (
m_hCertStore,
pbyLob,
dwBlobLength,
CERT_STORE_ADD_ALWAYS,
0,
CERT_STORE_ALL_CONTEXT_FLAG,
NULL,
NULL) )
{
_TRACE (0, L"CertAddSerializedElementToStore () failed: 0x%x\n",
GetLastError ());
}
}
delete [] pbyLob;
}
else
{
hr = E_OUTOFMEMORY;
break;
}
}
else
{
ASSERT (0);
hr = E_UNEXPECTED;
break;
}
}
else
{
ASSERT (0);
hr = E_UNEXPECTED;
break;
}
}
else
{
ASSERT (0);
hr = E_UNEXPECTED;
break;
}
}
else
{
ASSERT (0);
hr = E_UNEXPECTED;
break;
}
}
}
}
else
break;
nIndex++;
}
return hr;
}
bool CCertStoreRSOP::CanContain(CertificateManagerObjectType nodeType)
{
_TRACE (1, L"Entering CCertStoreRSOP::CanContain - %s\n",
(LPCWSTR) m_pcszStoreName);
ASSERT (CERTMGR_LOG_STORE_RSOP == m_objecttype);
bool bCanContain = false;
switch (nodeType)
{
case CERTMGR_CERTIFICATE:
if ( ROOT_STORE == GetStoreType () ||
EFS_STORE == GetStoreType () )
{
bCanContain = true;
}
break;
case CERTMGR_CTL:
if ( TRUST_STORE == GetStoreType () )
{
bCanContain = true;
}
break;
default:
break;
}
_TRACE (-1, L"Leaving CCertStoreRSOP::CanContain - %s\n",
(LPCWSTR) m_pcszStoreName);
return bCanContain;
}
bool CCertStoreRSOP::IsMachineStore()
{
_TRACE (0, L"Entering and leaving CCertStoreRSOP::IsMachineStore - %s\n",
(LPCWSTR) m_pcszStoreName);
ASSERT (CERTMGR_LOG_STORE_RSOP == m_objecttype);
if (m_dwFlags & CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY)
return true;
else
return false;
}
void CCertStoreRSOP::FinalCommit()
{
_TRACE (1, L"Entering CCertStoreRSOP::FinalCommit - %s\n",
(LPCWSTR) m_pcszStoreName);
ASSERT (CERTMGR_LOG_STORE_RSOP == m_objecttype);
// Called only from destructor
// Cannot commit here for GPT: GPT has already freed all pertinent data
_TRACE (-1, L"Leaving CCertStoreRSOP::FinalCommit - %s\n",
(LPCWSTR) m_pcszStoreName);
}
bool CCertStoreRSOP::IsNullEFSPolicy()
{
_TRACE (1, L"Entering CCertStoreRSOP::IsNullEFSPolicy - %s\n",
(LPCWSTR) m_pcszStoreName);
GetStoreHandle (); // to initialize
Close ();
_TRACE (-1, L"Leaving CCertStoreRSOP::IsNullEFSPolicy - %s\n",
(LPCWSTR) m_pcszStoreName);
return m_fIsNullEFSPolicy;
}
void CCertStoreRSOP::AllowEmptyEFSPolicy()
{
_TRACE (1, L"Entering CCertStoreRSOP::AllowEmptyEFSPolicy - %s\n",
(LPCWSTR) m_pcszStoreName);
m_fIsNullEFSPolicy = false;
_TRACE (-1, L"Leaving CCertStoreRSOP::AllowEmptyEFSPolicy - %s\n",
(LPCWSTR) m_pcszStoreName);
}
PCCERT_CONTEXT CCertStoreRSOP::EnumCertificates (PCCERT_CONTEXT pPrevCertContext)
{
PCCERT_CONTEXT pCertContext = CCertStore::EnumCertificates (pPrevCertContext);
if ( pCertContext )
m_fIsNullEFSPolicy = false;
return pCertContext;
}