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.

215 lines
5.5 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. for (;;)
  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. goto ContinueBinding;
  72. }
  73. goto ldap_bind_s_error;
  74. }
  75. break;
  76. ContinueBinding:
  77. if (NULL != pld)
  78. {
  79. ldap_unbind(pld);
  80. pld = NULL;
  81. }
  82. }
  83. *ppldap = pld;
  84. pld = NULL;
  85. hr = S_OK;
  86. ErrorReturn:
  87. if (NULL != pld)
  88. {
  89. ldap_unbind(pld);
  90. }
  91. return(hr);
  92. TRACE_ERROR(ldap_bind_s_error);
  93. TRACE_ERROR(ldap_init_error);
  94. TRACE_ERROR(ldap_set_option_error);
  95. }
  96. //--------------------------------------------------------------------------------
  97. //
  98. // CachingDSManager implementation.
  99. //
  100. //--------------------------------------------------------------------------------
  101. HRESULT CachingDSManager::Initialize()
  102. {
  103. HRESULT hr;
  104. hr = myRobustLdapBind(&m_ldBindingHandle);
  105. _JumpCondition(FAILED(hr), myRobustLdapBindError);
  106. hr = DefaultDSManager::Initialize();
  107. _JumpCondition(FAILED(hr), DefaultDSManager__InitializeError);
  108. hr = S_OK;
  109. ErrorReturn:
  110. return hr;
  111. TRACE_ERROR(DefaultDSManager__InitializeError);
  112. TRACE_ERROR(myRobustLdapBindError);
  113. }
  114. CachingDSManager::~CachingDSManager()
  115. {
  116. if (NULL != m_ldBindingHandle) {
  117. ldap_unbind(m_ldBindingHandle);
  118. }
  119. }
  120. HRESULT CachingDSManager::EnumCertTypesForCA(IN HCAINFO hCAInfo, IN DWORD dwFlags, OUT HCERTTYPE *phCertType)
  121. {
  122. return ::CAEnumCertTypesForCAEx
  123. (hCAInfo,
  124. (LPCWSTR)m_ldBindingHandle,
  125. dwFlags | CT_FLAG_SCOPE_IS_LDAP_HANDLE,
  126. phCertType);
  127. }
  128. HRESULT CachingDSManager::EnumFirstCA(IN LPCWSTR wszScope, IN DWORD dwFlags, OUT HCAINFO *phCAInfo)
  129. {
  130. HRESULT hr;
  131. if (NULL != wszScope) {
  132. // We can't muck with the scope parameter. Just do the default thing.
  133. hr = DefaultDSManager::EnumFirstCA
  134. (wszScope,
  135. dwFlags,
  136. phCAInfo);
  137. } else {
  138. hr = ::CAEnumFirstCA
  139. ((LPCWSTR)m_ldBindingHandle,
  140. dwFlags | CA_FLAG_SCOPE_IS_LDAP_HANDLE,
  141. phCAInfo);
  142. }
  143. return hr;
  144. }
  145. HRESULT CachingDSManager::FindCAByName(IN LPCWSTR wszCAName, IN LPCWSTR wszScope, IN DWORD dwFlags,OUT HCAINFO *phCAInfo)
  146. {
  147. HRESULT hr;
  148. if (NULL != wszScope) {
  149. // We can't muck with the scope parameter. Just do the default thing.
  150. hr = DefaultDSManager::FindCAByName
  151. (wszCAName,
  152. wszScope,
  153. dwFlags,
  154. phCAInfo);
  155. } else {
  156. hr = ::CAFindByName
  157. (wszCAName,
  158. (LPCWSTR)m_ldBindingHandle,
  159. dwFlags | CA_FLAG_SCOPE_IS_LDAP_HANDLE,
  160. phCAInfo);
  161. }
  162. return hr;
  163. }
  164. HRESULT CachingDSManager::FindCertTypeByName(IN LPCWSTR pwszCertType, IN HCAINFO hCAInfo, IN DWORD dwFlags, OUT HCERTTYPE *phCertType)
  165. {
  166. HRESULT hr;
  167. if (NULL != hCAInfo) {
  168. // We can't muck with the scope parameter. Just do the default thing.
  169. hr = DefaultDSManager::FindCertTypeByName
  170. (pwszCertType,
  171. hCAInfo,
  172. dwFlags,
  173. phCertType);
  174. } else {
  175. hr = ::CAFindCertTypeByName
  176. (pwszCertType,
  177. m_ldBindingHandle,
  178. dwFlags | CT_FLAG_SCOPE_IS_LDAP_HANDLE,
  179. phCertType);
  180. }
  181. return hr;
  182. }