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.

440 lines
11 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. // parameter validation
  47. if(!pdwNumAttributesModified || !dwNumAttributes)
  48. {
  49. hr = E_ADS_BAD_PARAMETER;
  50. return hr;
  51. }
  52. hr = ADsSetObjectAttributes( _pLdapHandle,
  53. _pszLDAPServer,
  54. _pszLDAPDn,
  55. _Credentials,
  56. _dwPort,
  57. _seInfo,
  58. pAttributeEntries,
  59. dwNumAttributes,
  60. pdwNumAttributesModified );
  61. RRETURN(hr);
  62. }
  63. HRESULT
  64. CLDAPGenObject::GetObjectAttributes(
  65. LPWSTR *pAttributeNames,
  66. DWORD dwNumberAttributes,
  67. PADS_ATTR_INFO *ppAttributeEntries,
  68. DWORD * pdwNumAttributesReturned
  69. )
  70. {
  71. HRESULT hr = S_OK;
  72. //
  73. // Make sure that the last error is reset
  74. //
  75. Macro_ClearADsLastError(L"LDAP Provider");
  76. // parameter validation
  77. // -1 means that return all the attributes.
  78. if(!ppAttributeEntries || !pdwNumAttributesReturned)
  79. {
  80. hr = E_ADS_BAD_PARAMETER;
  81. return hr;
  82. }
  83. hr = ADsGetObjectAttributes( _pLdapHandle,
  84. _pszLDAPServer,
  85. _pszLDAPDn,
  86. _Credentials,
  87. _dwPort,
  88. _seInfo,
  89. pAttributeNames,
  90. dwNumberAttributes,
  91. ppAttributeEntries,
  92. pdwNumAttributesReturned );
  93. RRETURN(hr);
  94. }
  95. HRESULT
  96. CLDAPGenObject::CreateDSObject(
  97. LPWSTR pszRDNName,
  98. PADS_ATTR_INFO pAttributeEntries,
  99. DWORD dwNumAttributes,
  100. IDispatch * FAR* ppObject
  101. )
  102. {
  103. HRESULT hr = S_OK;
  104. IADs *pADs = NULL;
  105. TCHAR* pszLDAPClassName = NULL;
  106. DWORD i;
  107. PADS_ATTR_INFO pThisAttribute = NULL;
  108. LDAP_SCHEMA_HANDLE hSchema = NULL;
  109. BOOL fSecDesc = FALSE;
  110. DWORD dwSecDescType = ADSI_LDAPC_SECDESC_NONE;
  111. //
  112. // Make sure that the last error is reset
  113. //
  114. Macro_ClearADsLastError(L"LDAP Provider");
  115. // parameter validation
  116. if(!pszRDNName || !ppObject || !dwNumAttributes)
  117. {
  118. hr = E_ADS_BAD_PARAMETER;
  119. return hr;
  120. }
  121. //
  122. // Check and see if security descriptor is one of the attributes.
  123. //
  124. for (i=0; (i < dwNumAttributes) && (fSecDesc == FALSE); i++) {
  125. pThisAttribute = pAttributeEntries + i;
  126. if(!pThisAttribute)
  127. {
  128. hr = E_ADS_BAD_PARAMETER;
  129. return hr;
  130. }
  131. if (_tcsicmp(
  132. pThisAttribute->pszAttrName,
  133. L"ntSecurityDescriptor")
  134. == 0)
  135. {
  136. fSecDesc = TRUE;
  137. }
  138. }
  139. if (fSecDesc) {
  140. //
  141. // Use the create extended method only if the control
  142. // is supported by the server
  143. //
  144. hr = ReadSecurityDescriptorControlType(
  145. _pszLDAPServer,
  146. &dwSecDescType,
  147. _Credentials,
  148. _dwPort
  149. );
  150. if (FAILED(hr) || (dwSecDescType != ADSI_LDAPC_SECDESC_NT)) {
  151. //
  152. // Do not use the control
  153. //
  154. fSecDesc = FALSE;
  155. }
  156. }
  157. //
  158. // Get the LDAP path of the object to create
  159. //
  160. hr = ADsCreateDSObjectExt(
  161. _pLdapHandle,
  162. _ADsPath,
  163. pszRDNName,
  164. pAttributeEntries,
  165. dwNumAttributes,
  166. _seInfo,
  167. fSecDesc
  168. );
  169. BAIL_ON_FAILURE(hr);
  170. if (ppObject) {
  171. for (i = 0; i < dwNumAttributes; i++) {
  172. pThisAttribute = pAttributeEntries + i;
  173. if ( _tcsicmp( pThisAttribute->pszAttrName,
  174. TEXT("objectClass")) == 0 ) {
  175. pszLDAPClassName = new TCHAR[_tcslen(pThisAttribute->pADsValues->CaseIgnoreString) + 1];
  176. if(!pszLDAPClassName)
  177. {
  178. hr = E_OUTOFMEMORY;
  179. BAIL_ON_FAILURE(hr);
  180. }
  181. _tcscpy( pszLDAPClassName,
  182. (LPTSTR)pThisAttribute->pADsValues->CaseIgnoreString);
  183. break;
  184. }
  185. }
  186. hr = CreateGenericObject(
  187. _ADsPath,
  188. pszRDNName,
  189. pszLDAPClassName,
  190. _Credentials,
  191. ADS_OBJECT_BOUND,
  192. IID_IADs,
  193. (void **) &pADs
  194. );
  195. BAIL_ON_FAILURE(hr);
  196. hr = pADs->QueryInterface(
  197. IID_IDispatch,
  198. (void **)ppObject
  199. );
  200. BAIL_ON_FAILURE(hr);
  201. }
  202. error:
  203. if ( pADs ) {
  204. pADs->Release();
  205. }
  206. if ( hSchema ) {
  207. SchemaClose( &hSchema );
  208. }
  209. if(pszLDAPClassName)
  210. {
  211. delete [] pszLDAPClassName;
  212. pszLDAPClassName = NULL;
  213. }
  214. RRETURN(hr);
  215. }
  216. HRESULT
  217. CLDAPGenObject::DeleteDSObject(
  218. LPWSTR pszRDNName
  219. )
  220. {
  221. HRESULT hr = S_OK;
  222. //
  223. // Make sure that the last error is reset
  224. //
  225. Macro_ClearADsLastError(L"LDAP Provider");
  226. // parameter validation
  227. if(!pszRDNName)
  228. {
  229. hr = E_ADS_BAD_PARAMETER;
  230. return hr;
  231. }
  232. //
  233. // Get the LDAP path of the object to create
  234. //
  235. hr = ADsDeleteDSObject(
  236. _pLdapHandle,
  237. _ADsPath,
  238. pszRDNName
  239. );
  240. RRETURN(hr);
  241. }
  242. HRESULT
  243. CLDAPGenObject::GetObjectInformation(
  244. THIS_ PADS_OBJECT_INFO *ppObjInfo
  245. )
  246. {
  247. HRESULT hr = S_OK;
  248. ADS_OBJECT_INFO ObjectInfo;
  249. PADS_OBJECT_INFO pObjectInfo = &ObjectInfo;
  250. LPBYTE pBuffer = NULL;
  251. DWORD dwSize = 0;
  252. BSTR bstrSchema = NULL;
  253. BSTR bstrClass = NULL;
  254. //
  255. // Make sure that the last error is reset
  256. //
  257. Macro_ClearADsLastError(L"LDAP Provider");
  258. // parameter validation
  259. if(!ppObjInfo)
  260. {
  261. hr = E_ADS_BAD_PARAMETER;
  262. return hr;
  263. }
  264. hr = get_Schema( &bstrSchema );
  265. BAIL_ON_FAILURE(hr);
  266. hr = get_Class( &bstrClass );
  267. BAIL_ON_FAILURE(hr);
  268. pObjectInfo->pszRDN = _Name;
  269. pObjectInfo->pszObjectDN = _ADsPath;
  270. pObjectInfo->pszParentDN = _Parent;
  271. pObjectInfo->pszSchemaDN = bstrSchema;
  272. pObjectInfo->pszClassName = bstrClass;
  273. dwSize = ComputeObjectInfoSize(pObjectInfo);
  274. pBuffer = (LPBYTE)AllocADsMem(dwSize);
  275. if (!pBuffer) {
  276. hr = E_OUTOFMEMORY;
  277. BAIL_ON_FAILURE(hr);
  278. }
  279. hr = MarshallObjectInfo(
  280. pObjectInfo,
  281. pBuffer,
  282. pBuffer + dwSize
  283. );
  284. BAIL_ON_FAILURE(hr);
  285. *ppObjInfo = (PADS_OBJECT_INFO) pBuffer;
  286. error:
  287. if ( bstrSchema )
  288. SysFreeString( bstrSchema );
  289. if ( bstrClass )
  290. SysFreeString( bstrClass );
  291. RRETURN(hr);
  292. }
  293. DWORD
  294. ComputeObjectInfoSize(
  295. PADS_OBJECT_INFO pObjectInfo
  296. )
  297. {
  298. DWORD dwLen = 0;
  299. dwLen += (wcslen(pObjectInfo->pszRDN) + 1) * sizeof(WCHAR);
  300. dwLen += (wcslen(pObjectInfo->pszObjectDN) + 1) * sizeof(WCHAR);
  301. dwLen += (wcslen(pObjectInfo->pszParentDN) + 1) * sizeof(WCHAR);
  302. dwLen += (wcslen(pObjectInfo->pszSchemaDN) + 1) * sizeof(WCHAR);
  303. dwLen += (wcslen(pObjectInfo->pszClassName) + 1) * sizeof(WCHAR);
  304. dwLen += sizeof(ADS_OBJECT_INFO);
  305. return(dwLen);
  306. }
  307. //
  308. // This assumes that addr is an LPBYTE type.
  309. //
  310. #define WORD_ALIGN_DOWN(addr) \
  311. addr = ((LPBYTE)((DWORD_PTR)addr & ~1))
  312. DWORD ObjectInfoStrings[] = {
  313. FIELD_OFFSET(ADS_OBJECT_INFO, pszRDN),
  314. FIELD_OFFSET(ADS_OBJECT_INFO, pszObjectDN),
  315. FIELD_OFFSET(ADS_OBJECT_INFO, pszParentDN),
  316. FIELD_OFFSET(ADS_OBJECT_INFO, pszSchemaDN),
  317. FIELD_OFFSET(ADS_OBJECT_INFO, pszClassName),
  318. 0xFFFFFFFF
  319. };
  320. HRESULT
  321. MarshallObjectInfo(
  322. PADS_OBJECT_INFO pSrcObjectInfo,
  323. LPBYTE pDestObjectInfo,
  324. LPBYTE pEnd
  325. )
  326. {
  327. LPWSTR SourceStrings[sizeof(ADS_OBJECT_INFO)/sizeof(LPWSTR)];
  328. LPWSTR *pSourceStrings=SourceStrings;
  329. memset(SourceStrings, 0, sizeof(ADS_OBJECT_INFO));
  330. *pSourceStrings++ = pSrcObjectInfo->pszRDN;
  331. *pSourceStrings++ = pSrcObjectInfo->pszObjectDN;
  332. *pSourceStrings++ = pSrcObjectInfo->pszParentDN;
  333. *pSourceStrings++ = pSrcObjectInfo->pszSchemaDN;
  334. *pSourceStrings++ = pSrcObjectInfo->pszClassName;
  335. pEnd = PackStrings(
  336. SourceStrings,
  337. pDestObjectInfo,
  338. ObjectInfoStrings,
  339. pEnd
  340. );
  341. RRETURN(S_OK);
  342. }
  343. LPBYTE
  344. PackStrings(
  345. LPWSTR *pSource,
  346. LPBYTE pDest,
  347. DWORD *DestOffsets,
  348. LPBYTE pEnd
  349. )
  350. {
  351. DWORD cbStr;
  352. WORD_ALIGN_DOWN(pEnd);
  353. while (*DestOffsets != -1) {
  354. if (*pSource) {
  355. cbStr = wcslen(*pSource)*sizeof(WCHAR) + sizeof(WCHAR);
  356. pEnd -= cbStr;
  357. CopyMemory( pEnd, *pSource, cbStr);
  358. *(LPWSTR *)(pDest+*DestOffsets) = (LPWSTR)pEnd;
  359. } else {
  360. *(LPWSTR *)(pDest+*DestOffsets)=0;
  361. }
  362. pSource++;
  363. DestOffsets++;
  364. }
  365. return pEnd;
  366. }