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.

261 lines
7.0 KiB

  1. // Class to enumerate Naming contexts
  2. // Copyright (c) 2001 Microsoft Corporation
  3. // Nov 2001 lucios
  4. // This class is an informal gathering of all
  5. // that is necessary to enummerate naming contexts
  6. // in order to fix the bug 472876
  7. // NTRAID#NTBUG9-472876-2001/11/30-lucios
  8. #include "pch.h"
  9. #include <ntdsadef.h>
  10. #include "enumncs.hpp"
  11. #define BREAK_ON_FAILED_HRESULT(hr) if(FAILED(hr)) break;
  12. // connects to "LDAP://RootDSE"
  13. HRESULT enumNCsAux::connectToRootDse(IADs** pDSO)
  14. {
  15. HRESULT hr= AdminToolsOpenObject
  16. (
  17. L"LDAP://RootDSE",
  18. 0,
  19. 0,
  20. ADS_SECURE_AUTHENTICATION,
  21. IID_IADs,
  22. reinterpret_cast<void**>(pDSO)
  23. );
  24. return hr;
  25. }
  26. // gets any property as a variant
  27. HRESULT enumNCsAux::getProperty
  28. (
  29. const wstring &name,
  30. CComVariant &property,
  31. IADs *pADObj
  32. )
  33. {
  34. return
  35. (
  36. pADObj->Get
  37. (
  38. CComBSTR(name.c_str()),
  39. &property
  40. )
  41. );
  42. }
  43. // Gets a string property
  44. HRESULT enumNCsAux::getStringProperty
  45. (
  46. const wstring &name,
  47. wstring &property,
  48. IADs *pADObj
  49. )
  50. {
  51. CComVariant propertyVar;
  52. HRESULT hr = getProperty(name,propertyVar,pADObj);
  53. if(FAILED(hr)) return(hr);
  54. if(propertyVar.vt!=VT_BSTR) return E_FAIL;
  55. property= V_BSTR(&propertyVar);
  56. return S_OK;
  57. }
  58. // Gets a long property
  59. HRESULT enumNCsAux::getLongProperty
  60. (
  61. const wstring &name,
  62. long &property,
  63. IADs *pADObj
  64. )
  65. {
  66. CComVariant propertyVar;
  67. HRESULT hr = getProperty(name,propertyVar,pADObj);
  68. if(FAILED(hr)) return(hr);
  69. if(propertyVar.vt!=VT_I4) return E_FAIL;
  70. property= V_I4(&propertyVar);
  71. return S_OK;
  72. }
  73. // Gets CN=Configuration from a connected rootDse IADs
  74. HRESULT enumNCsAux::getConfigurationDn(wstring &confDn,IADs *pDSO)
  75. {
  76. return
  77. (
  78. getStringProperty
  79. (
  80. LDAP_OPATT_CONFIG_NAMING_CONTEXT_W,
  81. confDn,
  82. pDSO
  83. )
  84. );
  85. }
  86. // gets the IADsContainer from a distinguished name path
  87. HRESULT enumNCsAux::getContainer(const wstring &path,IADsContainer **pCont)
  88. {
  89. return
  90. (
  91. ADsGetObject
  92. (
  93. path.c_str(),
  94. IID_IADsContainer,
  95. reinterpret_cast<void**>(pCont)
  96. )
  97. );
  98. }
  99. // Gets the IEnumVARIANT from a container
  100. HRESULT enumNCsAux::getContainerEnumerator
  101. (
  102. IADsContainer* pPart,
  103. IEnumVARIANT** ppiEnum
  104. )
  105. {
  106. HRESULT hr=S_OK;
  107. CComPtr<IUnknown> spUnkEnum;
  108. do
  109. {
  110. hr=pPart->get__NewEnum(&spUnkEnum);
  111. BREAK_ON_FAILED_HRESULT(hr);
  112. CComQIPtr<IEnumVARIANT,&IID_IEnumVARIANT> spRet(spUnkEnum);
  113. if(!spRet) return E_FAIL;
  114. *ppiEnum = spRet.Detach();
  115. } while(0);
  116. return hr;
  117. }
  118. // calls IADsObj->get_Class and returns a wstring from it
  119. HRESULT enumNCsAux::getObjectClass
  120. (
  121. wstring &className,
  122. IADs *IADsObj
  123. )
  124. {
  125. BSTR classBstr;
  126. HRESULT hr=IADsObj->get_Class(&classBstr);
  127. if(FAILED(hr)) return hr;
  128. className=(const wchar_t*)classBstr;
  129. return S_OK;
  130. }
  131. // Gets the IDispatch from the variant and queries
  132. // for a IADs(returned in IADsObj)
  133. HRESULT enumNCsAux::getIADsFromDispatch
  134. (
  135. const CComVariant &dispatchVar,
  136. IADs **ppiIADsObj
  137. )
  138. {
  139. if(dispatchVar.vt!=VT_DISPATCH) return E_INVALIDARG;
  140. IDispatch *pDisp=V_DISPATCH(&dispatchVar);
  141. if(pDisp==NULL) return E_FAIL;
  142. CComQIPtr<IADs,&IID_IADs> spRet(pDisp);
  143. if(!spRet) return E_FAIL;
  144. *ppiIADsObj=spRet.Detach();
  145. return S_OK;
  146. }
  147. // Enumerate the names of the naming contexts.
  148. // The names are from the crossRef objects in CN=configuration,CN=Partitions
  149. // that have FLAG_CR_NTDS_DOMAIN set. The property used to extract the names
  150. // is NCName.
  151. HRESULT enumNCsAux::enumerateNCs(set<wstring> &ncs)
  152. {
  153. HRESULT hr=S_OK;
  154. try
  155. {
  156. ncs.clear();
  157. do
  158. {
  159. // first of all: connect.
  160. CComPtr <IADs> spDSO; //for rootDse
  161. hr=connectToRootDse(&spDSO);
  162. BREAK_ON_FAILED_HRESULT(hr);
  163. wstring partPath;
  164. // then get the path to CN=Configuration,...
  165. hr=getConfigurationDn(partPath,spDSO);
  166. BREAK_ON_FAILED_HRESULT(hr);
  167. // .. and complete it with CN=Partitions
  168. partPath=L"LDAP://CN=Partitions,"+partPath;
  169. // then get the container for the partition..
  170. CComPtr <IADsContainer> spPart; // or the partitions container
  171. hr=getContainer(partPath,&spPart);
  172. BREAK_ON_FAILED_HRESULT(hr);
  173. // and enumerate the partition container
  174. CComPtr <IEnumVARIANT> spPartEnum;//for the enumeration of partition objects
  175. hr=getContainerEnumerator(spPart,&spPartEnum);
  176. BREAK_ON_FAILED_HRESULT(hr);
  177. CComVariant partitionVar;
  178. ULONG lFetch=0;
  179. while ( S_OK == (hr=spPartEnum->Next(1,&partitionVar,&lFetch)) )
  180. {
  181. if (lFetch != 1) continue;
  182. CComPtr<IADs> spPartitionObj;
  183. hr=getIADsFromDispatch(partitionVar,&spPartitionObj);
  184. BREAK_ON_FAILED_HRESULT(hr);
  185. do
  186. {
  187. wstring className;
  188. HRESULT hrAux;
  189. // Not getting a property/class is not a fatal error
  190. // so we use an auxilliary HRESULT hrAux
  191. hrAux=getObjectClass(className,spPartitionObj);
  192. BREAK_ON_FAILED_HRESULT(hrAux);
  193. if(_wcsicmp(className.c_str(),L"crossref")==0)
  194. {
  195. long systemFlags;
  196. hrAux=getLongProperty
  197. (
  198. L"systemFlags",
  199. systemFlags,
  200. spPartitionObj
  201. );
  202. BREAK_ON_FAILED_HRESULT(hrAux);
  203. if
  204. (
  205. (systemFlags & FLAG_CR_NTDS_DOMAIN) ==
  206. FLAG_CR_NTDS_DOMAIN
  207. )
  208. {
  209. wstring NCName;
  210. hrAux=getStringProperty
  211. (
  212. L"NCName",
  213. NCName,
  214. spPartitionObj
  215. );
  216. BREAK_ON_FAILED_HRESULT(hrAux);
  217. ncs.insert(NCName);
  218. }
  219. }
  220. } while(0);
  221. BREAK_ON_FAILED_HRESULT(hr);
  222. }
  223. if(SUCCEEDED(hr)) hr=S_OK;
  224. BREAK_ON_FAILED_HRESULT(hr);
  225. } while(0);
  226. }
  227. catch( const std::bad_alloc& )
  228. {
  229. hr=E_FAIL;
  230. }
  231. return hr;
  232. }