Source code of Windows XP (NT5)
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.

211 lines
5.2 KiB

  1. #include "wzrdpvk.h"
  2. #include "CertDSManager.h"
  3. HRESULT CertDSManager::MakeDSManager(OUT CertDSManager **ppDSManager)
  4. {
  5. if (NULL == ppDSManager)
  6. return E_INVALIDARG;
  7. if (NULL == (*ppDSManager = new CachingDSManager))
  8. return E_OUTOFMEMORY;
  9. return (*ppDSManager)->Initialize();
  10. }
  11. //--------------------------------------------------------------------------------
  12. //
  13. // Utility LDAP routines
  14. //
  15. //--------------------------------------------------------------------------------
  16. HRESULT myRobustLdapBind(OUT LDAP **ppldap)
  17. {
  18. BOOL fRediscover = FALSE;
  19. DWORD dwGetDcFlags = DS_RETURN_DNS_NAME;
  20. HRESULT hr;
  21. LDAP *pld = NULL;
  22. ULONG ldaperr;
  23. ULONG uVersion = LDAP_VERSION2;
  24. // bind to ds
  25. while (TRUE)
  26. {
  27. pld = ldap_init(NULL, LDAP_PORT);
  28. if (NULL == pld)
  29. {
  30. hr = HRESULT_FROM_WIN32(LdapGetLastError());
  31. if (!fRediscover)
  32. {
  33. fRediscover = TRUE;
  34. continue;
  35. }
  36. goto ldap_init_error;
  37. }
  38. if (fRediscover)
  39. {
  40. dwGetDcFlags |= DS_FORCE_REDISCOVERY;
  41. }
  42. struct LdapOptions {
  43. int nOption;
  44. void *pvInValue;
  45. } rgOptions[] = {
  46. { LDAP_OPT_GETDSNAME_FLAGS, &dwGetDcFlags },
  47. { LDAP_OPT_SIGN, LDAP_OPT_ON },
  48. { LDAP_OPT_VERSION, &uVersion }
  49. };
  50. for (DWORD dwIndex = 0; dwIndex < (sizeof(rgOptions) / sizeof(rgOptions[0])); dwIndex++)
  51. {
  52. ldaperr = ldap_set_option(pld, rgOptions[dwIndex].nOption, rgOptions[dwIndex].pvInValue);
  53. if (LDAP_SUCCESS != ldaperr)
  54. {
  55. hr = HRESULT_FROM_WIN32(LdapMapErrorToWin32(ldaperr));
  56. if (!fRediscover)
  57. {
  58. fRediscover = TRUE;
  59. goto ContinueBinding;
  60. }
  61. goto ldap_set_option_error;
  62. }
  63. }
  64. ldaperr = ldap_bind_s(pld, NULL, NULL, LDAP_AUTH_NEGOTIATE);
  65. if (LDAP_SUCCESS != ldaperr)
  66. {
  67. hr = HRESULT_FROM_WIN32(LdapMapErrorToWin32(ldaperr));
  68. if (!fRediscover)
  69. {
  70. fRediscover = TRUE;
  71. continue;
  72. }
  73. goto ldap_bind_s_error;
  74. }
  75. break;
  76. ContinueBinding:
  77. ;
  78. }
  79. *ppldap = pld;
  80. pld = NULL;
  81. hr = S_OK;
  82. ErrorReturn:
  83. if (NULL != pld)
  84. {
  85. ldap_unbind(pld);
  86. }
  87. return(hr);
  88. TRACE_ERROR(ldap_bind_s_error);
  89. TRACE_ERROR(ldap_init_error);
  90. TRACE_ERROR(ldap_set_option_error);
  91. }
  92. //--------------------------------------------------------------------------------
  93. //
  94. // CachingDSManager implementation.
  95. //
  96. //--------------------------------------------------------------------------------
  97. HRESULT CachingDSManager::Initialize()
  98. {
  99. HRESULT hr;
  100. hr = myRobustLdapBind(&m_ldBindingHandle);
  101. _JumpCondition(FAILED(hr), myRobustLdapBindError);
  102. hr = DefaultDSManager::Initialize();
  103. _JumpCondition(FAILED(hr), DefaultDSManager__InitializeError);
  104. hr = S_OK;
  105. ErrorReturn:
  106. return hr;
  107. TRACE_ERROR(DefaultDSManager__InitializeError);
  108. TRACE_ERROR(myRobustLdapBindError);
  109. }
  110. CachingDSManager::~CachingDSManager()
  111. {
  112. if (NULL != m_ldBindingHandle) {
  113. ldap_unbind(m_ldBindingHandle);
  114. }
  115. }
  116. HRESULT CachingDSManager::EnumCertTypesForCA(IN HCAINFO hCAInfo, IN DWORD dwFlags, OUT HCERTTYPE *phCertType)
  117. {
  118. return ::CAEnumCertTypesForCAEx
  119. (hCAInfo,
  120. (LPCWSTR)m_ldBindingHandle,
  121. dwFlags | CT_FLAG_SCOPE_IS_LDAP_HANDLE,
  122. phCertType);
  123. }
  124. HRESULT CachingDSManager::EnumFirstCA(IN LPCWSTR wszScope, IN DWORD dwFlags, OUT HCAINFO *phCAInfo)
  125. {
  126. HRESULT hr;
  127. if (NULL != wszScope) {
  128. // We can't muck with the scope parameter. Just do the default thing.
  129. hr = DefaultDSManager::EnumFirstCA
  130. (wszScope,
  131. dwFlags,
  132. phCAInfo);
  133. } else {
  134. hr = ::CAEnumFirstCA
  135. ((LPCWSTR)m_ldBindingHandle,
  136. dwFlags | CA_FLAG_SCOPE_IS_LDAP_HANDLE,
  137. phCAInfo);
  138. }
  139. return hr;
  140. }
  141. HRESULT CachingDSManager::FindCAByName(IN LPCWSTR wszCAName, IN LPCWSTR wszScope, IN DWORD dwFlags,OUT HCAINFO *phCAInfo)
  142. {
  143. HRESULT hr;
  144. if (NULL != wszScope) {
  145. // We can't muck with the scope parameter. Just do the default thing.
  146. hr = DefaultDSManager::FindCAByName
  147. (wszCAName,
  148. wszScope,
  149. dwFlags,
  150. phCAInfo);
  151. } else {
  152. hr = ::CAFindByName
  153. (wszCAName,
  154. (LPCWSTR)m_ldBindingHandle,
  155. dwFlags | CA_FLAG_SCOPE_IS_LDAP_HANDLE,
  156. phCAInfo);
  157. }
  158. return hr;
  159. }
  160. HRESULT CachingDSManager::FindCertTypeByName(IN LPCWSTR pwszCertType, IN HCAINFO hCAInfo, IN DWORD dwFlags, OUT HCERTTYPE *phCertType)
  161. {
  162. HRESULT hr;
  163. if (NULL != hCAInfo) {
  164. // We can't muck with the scope parameter. Just do the default thing.
  165. hr = DefaultDSManager::FindCertTypeByName
  166. (pwszCertType,
  167. hCAInfo,
  168. dwFlags,
  169. phCertType);
  170. } else {
  171. hr = ::CAFindCertTypeByName
  172. (pwszCertType,
  173. m_ldBindingHandle,
  174. dwFlags | CT_FLAG_SCOPE_IS_LDAP_HANDLE,
  175. phCertType);
  176. }
  177. return hr;
  178. }