windows-nt/Source/XPSP1/NT/ds/security/cryptoapi/ui/wizards/certdsmanager.cpp
2020-09-26 16:20:57 +08:00

212 lines
5.2 KiB
C++

#include "wzrdpvk.h"
#include "CertDSManager.h"
HRESULT CertDSManager::MakeDSManager(OUT CertDSManager **ppDSManager)
{
if (NULL == ppDSManager)
return E_INVALIDARG;
if (NULL == (*ppDSManager = new CachingDSManager))
return E_OUTOFMEMORY;
return (*ppDSManager)->Initialize();
}
//--------------------------------------------------------------------------------
//
// Utility LDAP routines
//
//--------------------------------------------------------------------------------
HRESULT myRobustLdapBind(OUT LDAP **ppldap)
{
BOOL fRediscover = FALSE;
DWORD dwGetDcFlags = DS_RETURN_DNS_NAME;
HRESULT hr;
LDAP *pld = NULL;
ULONG ldaperr;
ULONG uVersion = LDAP_VERSION2;
// bind to ds
while (TRUE)
{
pld = ldap_init(NULL, LDAP_PORT);
if (NULL == pld)
{
hr = HRESULT_FROM_WIN32(LdapGetLastError());
if (!fRediscover)
{
fRediscover = TRUE;
continue;
}
goto ldap_init_error;
}
if (fRediscover)
{
dwGetDcFlags |= DS_FORCE_REDISCOVERY;
}
struct LdapOptions {
int nOption;
void *pvInValue;
} rgOptions[] = {
{ LDAP_OPT_GETDSNAME_FLAGS, &dwGetDcFlags },
{ LDAP_OPT_SIGN, LDAP_OPT_ON },
{ LDAP_OPT_VERSION, &uVersion }
};
for (DWORD dwIndex = 0; dwIndex < (sizeof(rgOptions) / sizeof(rgOptions[0])); dwIndex++)
{
ldaperr = ldap_set_option(pld, rgOptions[dwIndex].nOption, rgOptions[dwIndex].pvInValue);
if (LDAP_SUCCESS != ldaperr)
{
hr = HRESULT_FROM_WIN32(LdapMapErrorToWin32(ldaperr));
if (!fRediscover)
{
fRediscover = TRUE;
goto ContinueBinding;
}
goto ldap_set_option_error;
}
}
ldaperr = ldap_bind_s(pld, NULL, NULL, LDAP_AUTH_NEGOTIATE);
if (LDAP_SUCCESS != ldaperr)
{
hr = HRESULT_FROM_WIN32(LdapMapErrorToWin32(ldaperr));
if (!fRediscover)
{
fRediscover = TRUE;
continue;
}
goto ldap_bind_s_error;
}
break;
ContinueBinding:
;
}
*ppldap = pld;
pld = NULL;
hr = S_OK;
ErrorReturn:
if (NULL != pld)
{
ldap_unbind(pld);
}
return(hr);
TRACE_ERROR(ldap_bind_s_error);
TRACE_ERROR(ldap_init_error);
TRACE_ERROR(ldap_set_option_error);
}
//--------------------------------------------------------------------------------
//
// CachingDSManager implementation.
//
//--------------------------------------------------------------------------------
HRESULT CachingDSManager::Initialize()
{
HRESULT hr;
hr = myRobustLdapBind(&m_ldBindingHandle);
_JumpCondition(FAILED(hr), myRobustLdapBindError);
hr = DefaultDSManager::Initialize();
_JumpCondition(FAILED(hr), DefaultDSManager__InitializeError);
hr = S_OK;
ErrorReturn:
return hr;
TRACE_ERROR(DefaultDSManager__InitializeError);
TRACE_ERROR(myRobustLdapBindError);
}
CachingDSManager::~CachingDSManager()
{
if (NULL != m_ldBindingHandle) {
ldap_unbind(m_ldBindingHandle);
}
}
HRESULT CachingDSManager::EnumCertTypesForCA(IN HCAINFO hCAInfo, IN DWORD dwFlags, OUT HCERTTYPE *phCertType)
{
return ::CAEnumCertTypesForCAEx
(hCAInfo,
(LPCWSTR)m_ldBindingHandle,
dwFlags | CT_FLAG_SCOPE_IS_LDAP_HANDLE,
phCertType);
}
HRESULT CachingDSManager::EnumFirstCA(IN LPCWSTR wszScope, IN DWORD dwFlags, OUT HCAINFO *phCAInfo)
{
HRESULT hr;
if (NULL != wszScope) {
// We can't muck with the scope parameter. Just do the default thing.
hr = DefaultDSManager::EnumFirstCA
(wszScope,
dwFlags,
phCAInfo);
} else {
hr = ::CAEnumFirstCA
((LPCWSTR)m_ldBindingHandle,
dwFlags | CA_FLAG_SCOPE_IS_LDAP_HANDLE,
phCAInfo);
}
return hr;
}
HRESULT CachingDSManager::FindCAByName(IN LPCWSTR wszCAName, IN LPCWSTR wszScope, IN DWORD dwFlags,OUT HCAINFO *phCAInfo)
{
HRESULT hr;
if (NULL != wszScope) {
// We can't muck with the scope parameter. Just do the default thing.
hr = DefaultDSManager::FindCAByName
(wszCAName,
wszScope,
dwFlags,
phCAInfo);
} else {
hr = ::CAFindByName
(wszCAName,
(LPCWSTR)m_ldBindingHandle,
dwFlags | CA_FLAG_SCOPE_IS_LDAP_HANDLE,
phCAInfo);
}
return hr;
}
HRESULT CachingDSManager::FindCertTypeByName(IN LPCWSTR pwszCertType, IN HCAINFO hCAInfo, IN DWORD dwFlags, OUT HCERTTYPE *phCertType)
{
HRESULT hr;
if (NULL != hCAInfo) {
// We can't muck with the scope parameter. Just do the default thing.
hr = DefaultDSManager::FindCertTypeByName
(pwszCertType,
hCAInfo,
dwFlags,
phCertType);
} else {
hr = ::CAFindCertTypeByName
(pwszCertType,
m_ldBindingHandle,
dwFlags | CT_FLAG_SCOPE_IS_LDAP_HANDLE,
phCertType);
}
return hr;
}