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.

381 lines
9.0 KiB

  1. //---------------------------------------------------------------------------
  2. //
  3. //
  4. // Microsoft Windows
  5. // Copyright (C) Microsoft Corporation, 1992 - 1997
  6. //
  7. // File: cdsobj.cxx
  8. //
  9. // Contents: Microsoft ADs LDAP Provider DSObject
  10. //
  11. //
  12. // History: 02-20-97 yihsins Created.
  13. //
  14. //----------------------------------------------------------------------------
  15. #include "ldap.hxx"
  16. #pragma hdrstop
  17. DWORD
  18. ComputeObjectInfoSize(
  19. PADS_OBJECT_INFO pObjectInfo
  20. );
  21. HRESULT
  22. MarshallObjectInfo(
  23. PADS_OBJECT_INFO pSrcObjectInfo,
  24. LPBYTE pDestObjectInfo,
  25. LPBYTE pEnd
  26. );
  27. LPBYTE
  28. PackStrings(
  29. LPWSTR *pSource,
  30. LPBYTE pDest,
  31. DWORD *DestOffsets,
  32. LPBYTE pEnd
  33. );
  34. HRESULT
  35. CLDAPGenObject::SetObjectAttributes(
  36. PADS_ATTR_INFO pAttributeEntries,
  37. DWORD dwNumAttributes,
  38. DWORD *pdwNumAttributesModified
  39. )
  40. {
  41. HRESULT hr = S_OK;
  42. //
  43. // Make sure that the last error is reset
  44. //
  45. Macro_ClearADsLastError(L"LDAP Provider");
  46. hr = ADsSetObjectAttributes( _pLdapHandle,
  47. _pszLDAPServer,
  48. _pszLDAPDn,
  49. _Credentials,
  50. _dwPort,
  51. _seInfo,
  52. pAttributeEntries,
  53. dwNumAttributes,
  54. pdwNumAttributesModified );
  55. RRETURN(hr);
  56. }
  57. HRESULT
  58. CLDAPGenObject::GetObjectAttributes(
  59. LPWSTR *pAttributeNames,
  60. DWORD dwNumberAttributes,
  61. PADS_ATTR_INFO *ppAttributeEntries,
  62. DWORD * pdwNumAttributesReturned
  63. )
  64. {
  65. HRESULT hr = S_OK;
  66. //
  67. // Make sure that the last error is reset
  68. //
  69. Macro_ClearADsLastError(L"LDAP Provider");
  70. hr = ADsGetObjectAttributes( _pLdapHandle,
  71. _pszLDAPServer,
  72. _pszLDAPDn,
  73. _Credentials,
  74. _dwPort,
  75. _seInfo,
  76. pAttributeNames,
  77. dwNumberAttributes,
  78. ppAttributeEntries,
  79. pdwNumAttributesReturned );
  80. RRETURN(hr);
  81. }
  82. HRESULT
  83. CLDAPGenObject::CreateDSObject(
  84. LPWSTR pszRDNName,
  85. PADS_ATTR_INFO pAttributeEntries,
  86. DWORD dwNumAttributes,
  87. IDispatch * FAR* ppObject
  88. )
  89. {
  90. HRESULT hr = S_OK;
  91. IADs *pADs = NULL;
  92. TCHAR szADsClassName[64];
  93. TCHAR szLDAPClassName[64];
  94. DWORD i;
  95. PADS_ATTR_INFO pThisAttribute;
  96. LDAP_SCHEMA_HANDLE hSchema = NULL;
  97. BOOL fSecDesc = FALSE;
  98. DWORD dwSecDescType = ADSI_LDAPC_SECDESC_NONE;
  99. //
  100. // Make sure that the last error is reset
  101. //
  102. Macro_ClearADsLastError(L"LDAP Provider");
  103. //
  104. // Check and see if security descriptor is one of the attributes.
  105. //
  106. for (i=0; (i < dwNumAttributes) && (fSecDesc == FALSE); i++) {
  107. pThisAttribute = pAttributeEntries + i;
  108. if (_tcsicmp(
  109. pThisAttribute->pszAttrName,
  110. L"ntSecurityDescriptor")
  111. == 0)
  112. {
  113. fSecDesc = TRUE;
  114. }
  115. }
  116. if (fSecDesc) {
  117. //
  118. // Use the create extended method only if the control
  119. // is supported by the server
  120. //
  121. hr = ReadSecurityDescriptorControlType(
  122. _pszLDAPServer,
  123. &dwSecDescType,
  124. _Credentials,
  125. _dwPort
  126. );
  127. if (FAILED(hr) || (dwSecDescType != ADSI_LDAPC_SECDESC_NT)) {
  128. //
  129. // Do not use the control
  130. //
  131. fSecDesc = FALSE;
  132. }
  133. }
  134. //
  135. // Get the LDAP path of the object to create
  136. //
  137. hr = ADsCreateDSObjectExt(
  138. _pLdapHandle,
  139. _ADsPath,
  140. pszRDNName,
  141. pAttributeEntries,
  142. dwNumAttributes,
  143. _seInfo,
  144. fSecDesc
  145. );
  146. BAIL_ON_FAILURE(hr);
  147. if (ppObject) {
  148. for (i = 0; i < dwNumAttributes; i++) {
  149. pThisAttribute = pAttributeEntries + i;
  150. if ( _tcsicmp( pThisAttribute->pszAttrName,
  151. TEXT("objectClass")) == 0 ) {
  152. _tcscpy( szLDAPClassName,
  153. (LPTSTR)pThisAttribute->pADsValues->CaseIgnoreString);
  154. break;
  155. }
  156. }
  157. hr = CreateGenericObject(
  158. _ADsPath,
  159. pszRDNName,
  160. szLDAPClassName,
  161. _Credentials,
  162. ADS_OBJECT_BOUND,
  163. IID_IADs,
  164. (void **) &pADs
  165. );
  166. BAIL_ON_FAILURE(hr);
  167. hr = pADs->QueryInterface(
  168. IID_IDispatch,
  169. (void **)ppObject
  170. );
  171. BAIL_ON_FAILURE(hr);
  172. }
  173. error:
  174. if ( pADs ) {
  175. pADs->Release();
  176. }
  177. if ( hSchema ) {
  178. SchemaClose( &hSchema );
  179. }
  180. RRETURN(hr);
  181. }
  182. HRESULT
  183. CLDAPGenObject::DeleteDSObject(
  184. LPWSTR pszRDNName
  185. )
  186. {
  187. HRESULT hr = S_OK;
  188. //
  189. // Make sure that the last error is reset
  190. //
  191. Macro_ClearADsLastError(L"LDAP Provider");
  192. //
  193. // Get the LDAP path of the object to create
  194. //
  195. hr = ADsDeleteDSObject(
  196. _pLdapHandle,
  197. _ADsPath,
  198. pszRDNName
  199. );
  200. RRETURN(hr);
  201. }
  202. HRESULT
  203. CLDAPGenObject::GetObjectInformation(
  204. THIS_ PADS_OBJECT_INFO *ppObjInfo
  205. )
  206. {
  207. HRESULT hr = S_OK;
  208. ADS_OBJECT_INFO ObjectInfo;
  209. PADS_OBJECT_INFO pObjectInfo = &ObjectInfo;
  210. LPBYTE pBuffer = NULL;
  211. DWORD dwSize = 0;
  212. BSTR bstrSchema = NULL;
  213. BSTR bstrClass = NULL;
  214. //
  215. // Make sure that the last error is reset
  216. //
  217. Macro_ClearADsLastError(L"LDAP Provider");
  218. hr = get_Schema( &bstrSchema );
  219. BAIL_ON_FAILURE(hr);
  220. hr = get_Class( &bstrClass );
  221. BAIL_ON_FAILURE(hr);
  222. pObjectInfo->pszRDN = _Name;
  223. pObjectInfo->pszObjectDN = _ADsPath;
  224. pObjectInfo->pszParentDN = _Parent;
  225. pObjectInfo->pszSchemaDN = bstrSchema;
  226. pObjectInfo->pszClassName = bstrClass;
  227. dwSize = ComputeObjectInfoSize(pObjectInfo);
  228. pBuffer = (LPBYTE)AllocADsMem(dwSize);
  229. if (!pBuffer) {
  230. hr = E_OUTOFMEMORY;
  231. BAIL_ON_FAILURE(hr);
  232. }
  233. hr = MarshallObjectInfo(
  234. pObjectInfo,
  235. pBuffer,
  236. pBuffer + dwSize
  237. );
  238. BAIL_ON_FAILURE(hr);
  239. *ppObjInfo = (PADS_OBJECT_INFO) pBuffer;
  240. error:
  241. if ( bstrSchema )
  242. SysFreeString( bstrSchema );
  243. if ( bstrClass )
  244. SysFreeString( bstrClass );
  245. RRETURN(hr);
  246. }
  247. DWORD
  248. ComputeObjectInfoSize(
  249. PADS_OBJECT_INFO pObjectInfo
  250. )
  251. {
  252. DWORD dwLen = 0;
  253. dwLen += (wcslen(pObjectInfo->pszRDN) + 1) * sizeof(WCHAR);
  254. dwLen += (wcslen(pObjectInfo->pszObjectDN) + 1) * sizeof(WCHAR);
  255. dwLen += (wcslen(pObjectInfo->pszParentDN) + 1) * sizeof(WCHAR);
  256. dwLen += (wcslen(pObjectInfo->pszSchemaDN) + 1) * sizeof(WCHAR);
  257. dwLen += (wcslen(pObjectInfo->pszClassName) + 1) * sizeof(WCHAR);
  258. dwLen += sizeof(ADS_OBJECT_INFO);
  259. return(dwLen);
  260. }
  261. //
  262. // This assumes that addr is an LPBYTE type.
  263. //
  264. #define WORD_ALIGN_DOWN(addr) \
  265. addr = ((LPBYTE)((DWORD_PTR)addr & ~1))
  266. DWORD ObjectInfoStrings[] = {
  267. FIELD_OFFSET(ADS_OBJECT_INFO, pszRDN),
  268. FIELD_OFFSET(ADS_OBJECT_INFO, pszObjectDN),
  269. FIELD_OFFSET(ADS_OBJECT_INFO, pszParentDN),
  270. FIELD_OFFSET(ADS_OBJECT_INFO, pszSchemaDN),
  271. FIELD_OFFSET(ADS_OBJECT_INFO, pszClassName),
  272. 0xFFFFFFFF
  273. };
  274. HRESULT
  275. MarshallObjectInfo(
  276. PADS_OBJECT_INFO pSrcObjectInfo,
  277. LPBYTE pDestObjectInfo,
  278. LPBYTE pEnd
  279. )
  280. {
  281. LPWSTR SourceStrings[sizeof(ADS_OBJECT_INFO)/sizeof(LPWSTR)];
  282. LPWSTR *pSourceStrings=SourceStrings;
  283. memset(SourceStrings, 0, sizeof(ADS_OBJECT_INFO));
  284. *pSourceStrings++ = pSrcObjectInfo->pszRDN;
  285. *pSourceStrings++ = pSrcObjectInfo->pszObjectDN;
  286. *pSourceStrings++ = pSrcObjectInfo->pszParentDN;
  287. *pSourceStrings++ = pSrcObjectInfo->pszSchemaDN;
  288. *pSourceStrings++ = pSrcObjectInfo->pszClassName;
  289. pEnd = PackStrings(
  290. SourceStrings,
  291. pDestObjectInfo,
  292. ObjectInfoStrings,
  293. pEnd
  294. );
  295. RRETURN(S_OK);
  296. }
  297. LPBYTE
  298. PackStrings(
  299. LPWSTR *pSource,
  300. LPBYTE pDest,
  301. DWORD *DestOffsets,
  302. LPBYTE pEnd
  303. )
  304. {
  305. DWORD cbStr;
  306. WORD_ALIGN_DOWN(pEnd);
  307. while (*DestOffsets != -1) {
  308. if (*pSource) {
  309. cbStr = wcslen(*pSource)*sizeof(WCHAR) + sizeof(WCHAR);
  310. pEnd -= cbStr;
  311. CopyMemory( pEnd, *pSource, cbStr);
  312. *(LPWSTR *)(pDest+*DestOffsets) = (LPWSTR)pEnd;
  313. } else {
  314. *(LPWSTR *)(pDest+*DestOffsets)=0;
  315. }
  316. pSource++;
  317. DestOffsets++;
  318. }
  319. return pEnd;
  320. }