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.
215 lines
5.5 KiB
215 lines
5.5 KiB
#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
|
|
for (;;)
|
|
{
|
|
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;
|
|
goto ContinueBinding;
|
|
}
|
|
goto ldap_bind_s_error;
|
|
}
|
|
|
|
break;
|
|
ContinueBinding:
|
|
if (NULL != pld)
|
|
{
|
|
ldap_unbind(pld);
|
|
pld = NULL;
|
|
}
|
|
}
|
|
|
|
*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;
|
|
}
|
|
|
|
|