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.

340 lines
7.7 KiB

  1. //---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1996
  5. //
  6. // File: cenumUserCollection.cxx
  7. //
  8. // Contents: Windows NT 3.5 UserCollection Enumeration Code
  9. //
  10. // CLDAPUserCollectionEnum::CLDAPUserCollectionEnum()
  11. // CLDAPUserCollectionEnum::CLDAPUserCollectionEnum
  12. // CLDAPUserCollectionEnum::EnumObjects
  13. // CLDAPUserCollectionEnum::EnumObjects
  14. //
  15. // History:
  16. //----------------------------------------------------------------------------
  17. #include "ldap.hxx"
  18. #pragma hdrstop
  19. HRESULT
  20. BuildADsPathFromLDAPPath(
  21. LPWSTR szNamespace,
  22. LPWSTR szLdapDN,
  23. LPWSTR * ppszADsPathName
  24. );
  25. //+---------------------------------------------------------------------------
  26. //
  27. // Function: CLDAPEnumVariant::Create
  28. //
  29. // Synopsis:
  30. //
  31. // Arguments: [pCollection]
  32. // [ppEnumVariant]
  33. //
  34. // Returns: HRESULT
  35. //
  36. // Modifies:
  37. //
  38. // History: 01-30-95 krishnag Created.
  39. //
  40. //----------------------------------------------------------------------------
  41. HRESULT
  42. CLDAPUserCollectionEnum::Create(
  43. BSTR bstrUserName,
  44. CLDAPUserCollectionEnum FAR* FAR* ppenumvariant,
  45. VARIANT var,
  46. CCredentials& Credentials
  47. )
  48. {
  49. HRESULT hr = NOERROR;
  50. CLDAPUserCollectionEnum FAR* penumvariant = NULL;
  51. DWORD dwSLBound = 0;
  52. DWORD dwSUBound = 0;
  53. if ( V_VT(&var) == VT_BSTR )
  54. {
  55. dwSLBound = 0;
  56. dwSUBound = 0;
  57. }
  58. else
  59. {
  60. if(!(V_VT(&var) == (VT_VARIANT|VT_ARRAY))) {
  61. return(E_FAIL);
  62. }
  63. //
  64. // Check that there is only one dimension in this array
  65. //
  66. if ((V_ARRAY(&var))->cDims != 1) {
  67. hr = E_FAIL;
  68. BAIL_ON_FAILURE(hr);
  69. }
  70. //
  71. // We know that this is a valid single dimension array
  72. //
  73. hr = SafeArrayGetLBound(
  74. V_ARRAY(&var),
  75. 1,
  76. (long FAR *)&dwSLBound
  77. );
  78. BAIL_ON_FAILURE(hr);
  79. hr = SafeArrayGetUBound(
  80. V_ARRAY(&var),
  81. 1,
  82. (long FAR *)&dwSUBound
  83. );
  84. BAIL_ON_FAILURE(hr);
  85. }
  86. *ppenumvariant = NULL;
  87. penumvariant = new CLDAPUserCollectionEnum();
  88. if (!penumvariant) {
  89. hr = E_OUTOFMEMORY;
  90. BAIL_ON_FAILURE(hr);
  91. }
  92. hr = ADsAllocString(bstrUserName, &(penumvariant->_bstrUserName));
  93. BAIL_ON_FAILURE(hr);
  94. hr = VariantCopy(&(penumvariant->_vMembers), &var);
  95. BAIL_ON_FAILURE(hr);
  96. penumvariant->_dwSUBound = dwSUBound;
  97. penumvariant->_dwSLBound = dwSLBound;
  98. penumvariant->_dwIndex = dwSLBound;
  99. penumvariant->_Credentials = Credentials;
  100. *ppenumvariant = penumvariant;
  101. RRETURN(hr);
  102. error:
  103. delete penumvariant;
  104. RRETURN_EXP_IF_ERR(hr);
  105. }
  106. CLDAPUserCollectionEnum::CLDAPUserCollectionEnum():
  107. _dwSLBound(0),
  108. _dwSUBound(0),
  109. _dwIndex(0),
  110. _bstrUserName(NULL)
  111. {
  112. VariantInit(&_vMembers);
  113. }
  114. CLDAPUserCollectionEnum::~CLDAPUserCollectionEnum()
  115. {
  116. VariantClear(&_vMembers);
  117. if ( _bstrUserName )
  118. ADsFreeString( _bstrUserName );
  119. }
  120. HRESULT
  121. CLDAPUserCollectionEnum::EnumUserMembers(
  122. ULONG cElements,
  123. VARIANT FAR* pvar,
  124. ULONG FAR* pcElementFetched
  125. )
  126. {
  127. HRESULT hr = S_OK;
  128. IDispatch *pDispatch = NULL;
  129. DWORD i = 0;
  130. while (i < cElements) {
  131. hr = GetUserMemberObject(&pDispatch);
  132. if (FAILED(hr)) {
  133. //
  134. // Enumerators support code can only handle S_FALSE and S_OK,
  135. // so we cannot return other failure hr's for now.
  136. //
  137. hr = S_FALSE;
  138. }
  139. if (hr == S_FALSE) {
  140. break;
  141. }
  142. VariantInit(&pvar[i]);
  143. pvar[i].vt = VT_DISPATCH;
  144. pvar[i].pdispVal = pDispatch;
  145. (*pcElementFetched)++;
  146. i++;
  147. }
  148. RRETURN_EXP_IF_ERR(hr);
  149. }
  150. HRESULT
  151. CLDAPUserCollectionEnum::GetUserMemberObject(
  152. IDispatch ** ppDispatch
  153. )
  154. {
  155. VARIANT v;
  156. HRESULT hr = S_OK;
  157. TCHAR *pszADsPathName = NULL;
  158. IUnknown *pObject = NULL;
  159. LPWSTR pszUserName = NULL;
  160. LPWSTR pszPassword = NULL;
  161. DWORD dwAuthFlags = 0;
  162. *ppDispatch = NULL;
  163. VariantInit(&v);
  164. hr = _Credentials.GetUserName(&pszUserName);
  165. BAIL_ON_FAILURE(hr);
  166. hr = _Credentials.GetPassword(&pszPassword);
  167. BAIL_ON_FAILURE(hr);
  168. dwAuthFlags = _Credentials.GetAuthFlags();
  169. if (_dwIndex > _dwSUBound) {
  170. hr = S_FALSE;
  171. goto error;
  172. }
  173. while ( TRUE )
  174. {
  175. VariantInit(&v);
  176. if ( _vMembers.vt == VT_BSTR )
  177. {
  178. hr = VariantCopy( &v, &_vMembers );
  179. }
  180. else
  181. {
  182. hr = SafeArrayGetElement(
  183. V_ARRAY(&_vMembers),
  184. (long FAR *)&_dwIndex,
  185. &v
  186. );
  187. }
  188. BAIL_ON_FAILURE(hr);
  189. _dwIndex++;
  190. hr = BuildADsPathFromLDAPPath( _bstrUserName,
  191. V_BSTR(&v),
  192. &pszADsPathName);
  193. BAIL_ON_FAILURE(hr);
  194. hr = ADsOpenObject(
  195. pszADsPathName,
  196. pszUserName,
  197. pszPassword,
  198. dwAuthFlags,
  199. IID_IUnknown,
  200. (LPVOID *)&pObject
  201. );
  202. if ( pszADsPathName )
  203. {
  204. FreeADsStr( pszADsPathName );
  205. pszADsPathName = NULL;
  206. }
  207. VariantClear(&v);
  208. //
  209. // If we failed to get the current object, continue with the next one
  210. //
  211. if ( FAILED(hr))
  212. continue;
  213. hr = pObject->QueryInterface( IID_IDispatch, (LPVOID *) ppDispatch );
  214. BAIL_ON_FAILURE(hr);
  215. hr = S_OK;
  216. goto error;
  217. }
  218. error:
  219. if ( pObject )
  220. pObject->Release();
  221. if ( pszADsPathName )
  222. FreeADsStr( pszADsPathName );
  223. if (pszPassword) {
  224. SecureZeroMemory(pszPassword, wcslen(pszPassword)*sizeof(WCHAR));
  225. FreeADsStr(pszPassword);
  226. }
  227. if (pszUserName) {
  228. FreeADsStr(pszUserName);
  229. }
  230. VariantClear(&v);
  231. RRETURN(hr);
  232. }
  233. //+---------------------------------------------------------------------------
  234. //
  235. // Function: CLDAPUserCollectionEnum::Next
  236. //
  237. // Synopsis: Returns cElements number of requested NetOle objects in the
  238. // array supplied in pvar.
  239. //
  240. // Arguments: [cElements] -- The number of elements requested by client
  241. // [pvar] -- ptr to array of VARIANTs to for return objects
  242. // [pcElementFetched] -- if non-NULL, then number of elements
  243. // -- actually returned is placed here
  244. //
  245. // Returns: HRESULT -- S_OK if number of elements requested are returned
  246. // -- S_FALSE if number of elements is < requested
  247. //
  248. // Modifies:
  249. //
  250. // History: 11-3-95 krishnag Created.
  251. //
  252. //----------------------------------------------------------------------------
  253. STDMETHODIMP
  254. CLDAPUserCollectionEnum::Next(
  255. ULONG cElements,
  256. VARIANT FAR* pvar,
  257. ULONG FAR* pcElementFetched
  258. )
  259. {
  260. ULONG cElementFetched = 0;
  261. HRESULT hr = S_OK;
  262. hr = EnumUserMembers(
  263. cElements,
  264. pvar,
  265. &cElementFetched
  266. );
  267. if (pcElementFetched) {
  268. *pcElementFetched = cElementFetched;
  269. }
  270. RRETURN_EXP_IF_ERR(hr);
  271. }
  272.