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.

862 lines
39 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1999-2002.
  5. //
  6. // File: ADSIObj.cpp
  7. //
  8. // Contents: ADSI Object
  9. //
  10. //
  11. //----------------------------------------------------------------------------
  12. #include "stdafx.h"
  13. #include "ADSIObj.h"
  14. #include "ADUtils.h"
  15. HRESULT CACLAdsiObject::AddAttrGUIDToList (
  16. const BSTR pszAttrName,
  17. list<POBJECT_TYPE_LIST>& guidList)
  18. {
  19. _TRACE (1, L"Entering CACLAdsiObject::AddAttrGUIDToList ()\n");
  20. HRESULT hr = S_OK;
  21. CComPtr<IADsPathname> spPathname;
  22. //
  23. // Constructing the directory paths
  24. //
  25. hr = CoCreateInstance(
  26. CLSID_Pathname,
  27. NULL,
  28. CLSCTX_ALL,
  29. IID_PPV_ARG (IADsPathname, &spPathname));
  30. if ( SUCCEEDED (hr) )
  31. {
  32. ASSERT (!!spPathname);
  33. hr = spPathname->Set (CComBSTR (ACLDIAG_LDAP), ADS_SETTYPE_PROVIDER);
  34. if ( SUCCEEDED (hr) )
  35. {
  36. hr = spPathname->Set (CComBSTR (GetPhysicalSchemaNamingContext()),
  37. ADS_SETTYPE_DN);
  38. if ( SUCCEEDED (hr) )
  39. {
  40. BSTR strAttrCommonName = 0;
  41. hr = ReadSchemaAttributeCommonName (pszAttrName, &strAttrCommonName);
  42. if ( SUCCEEDED (hr) )
  43. {
  44. wstring strLeaf;
  45. FormatMessage (strLeaf, L"CN=%1", strAttrCommonName);
  46. hr = spPathname->AddLeafElement(CComBSTR (strLeaf.c_str ()));
  47. if ( SUCCEEDED (hr) )
  48. {
  49. BSTR bstrFullPath = 0;
  50. hr = spPathname->Retrieve(ADS_FORMAT_X500, &bstrFullPath);
  51. if ( SUCCEEDED (hr) )
  52. {
  53. CComPtr<IDirectoryObject> spDirObj;
  54. hr = ADsOpenObjectHelper(bstrFullPath,
  55. IID_IDirectoryObject,
  56. 0,
  57. (void**)&spDirObj);
  58. if ( SUCCEEDED (hr) )
  59. {
  60. GUID* pGUID = 0;
  61. POBJECT_TYPE_LIST pOtl = 0;
  62. bool bPropertySetFound = false;
  63. // Property set GUIDs must be added before property GUIDs
  64. // See documentation for "AccessCheckByTypeResultList
  65. {
  66. // Get attribute security GUID (property set GUID)
  67. PADS_ATTR_INFO pAttrs = 0;
  68. DWORD cAttrs = 0;
  69. LPWSTR rgpwzAttrNames[] = {L"attributeSecurityGUID"};
  70. hr = spDirObj->GetObjectAttributes(rgpwzAttrNames, 1, &pAttrs, &cAttrs);
  71. if ( SUCCEEDED (hr) )
  72. {
  73. if ( 1 == cAttrs && pAttrs && pAttrs->pADsValues )
  74. {
  75. if ( pAttrs->pADsValues->OctetString.dwLength == sizeof (GUID) )
  76. {
  77. bPropertySetFound = true;
  78. pGUID = (GUID*) CoTaskMemAlloc (sizeof (GUID));
  79. if ( pGUID )
  80. {
  81. bool bFound = false;
  82. memcpy (pGUID,
  83. pAttrs->pADsValues->OctetString.lpValue,
  84. pAttrs->pADsValues->OctetString.dwLength);
  85. for (list<POBJECT_TYPE_LIST>::iterator itr = guidList.begin ();
  86. itr != guidList.end ();
  87. itr++)
  88. {
  89. if ( ::IsEqualGUID (*((*itr)->ObjectType), *pGUID) )
  90. {
  91. bFound = true;
  92. break;
  93. }
  94. }
  95. if ( !bFound )
  96. {
  97. pOtl = (POBJECT_TYPE_LIST) CoTaskMemAlloc (sizeof (OBJECT_TYPE_LIST));
  98. if ( pOtl )
  99. {
  100. ::ZeroMemory (pOtl, sizeof (OBJECT_TYPE_LIST));
  101. pOtl->Level = ACCESS_PROPERTY_SET_GUID;
  102. pOtl->ObjectType = pGUID;
  103. pOtl->Sbz = 0;
  104. guidList.push_back (pOtl);
  105. }
  106. else
  107. {
  108. CoTaskMemFree (pGUID);
  109. hr = E_OUTOFMEMORY;
  110. }
  111. }
  112. else
  113. CoTaskMemFree (pGUID);
  114. }
  115. else
  116. hr = E_OUTOFMEMORY;
  117. }
  118. else
  119. hr = E_UNEXPECTED;
  120. }
  121. if ( pAttrs )
  122. FreeADsMem (pAttrs);
  123. }
  124. else
  125. {
  126. _TRACE (0, L"IDirectoryObject->GetObjectAttributes (): 0x%x\n", hr);
  127. }
  128. }
  129. if ( SUCCEEDED (hr) )
  130. {
  131. // Get attribute GUID (schemaIDGUID)
  132. PADS_ATTR_INFO pAttrs = 0;
  133. DWORD cAttrs = 0;
  134. LPWSTR rgpwzAttrNames[] = {L"schemaIDGUID"};
  135. hr = spDirObj->GetObjectAttributes(rgpwzAttrNames, 1, &pAttrs, &cAttrs);
  136. if ( SUCCEEDED (hr) )
  137. {
  138. if ( 1 == cAttrs && pAttrs && pAttrs->pADsValues )
  139. {
  140. if ( pAttrs->pADsValues->OctetString.dwLength == sizeof (GUID) )
  141. {
  142. pGUID = (GUID*) CoTaskMemAlloc (sizeof (GUID));
  143. if ( pGUID )
  144. {
  145. memcpy (pGUID,
  146. pAttrs->pADsValues->OctetString.lpValue,
  147. pAttrs->pADsValues->OctetString.dwLength);
  148. pOtl = (POBJECT_TYPE_LIST) CoTaskMemAlloc (sizeof (OBJECT_TYPE_LIST));
  149. if ( pOtl )
  150. {
  151. ::ZeroMemory (pOtl, sizeof (OBJECT_TYPE_LIST));
  152. if ( bPropertySetFound )
  153. pOtl->Level = ACCESS_PROPERTY_GUID;
  154. else
  155. pOtl->Level = ACCESS_PROPERTY_SET_GUID;
  156. pOtl->ObjectType = pGUID;
  157. pOtl->Sbz = 0;
  158. guidList.push_back (pOtl);
  159. }
  160. else
  161. {
  162. CoTaskMemFree (pGUID);
  163. hr = E_OUTOFMEMORY;
  164. }
  165. }
  166. else
  167. hr = E_OUTOFMEMORY;
  168. }
  169. else
  170. hr = E_UNEXPECTED;
  171. }
  172. if ( pAttrs )
  173. FreeADsMem (pAttrs);
  174. }
  175. else
  176. {
  177. _TRACE (0, L"IDirectoryObject->GetObjectAttributes (): 0x%x\n", hr);
  178. }
  179. }
  180. }
  181. else
  182. {
  183. _TRACE (0, L"ADsOpenObjectHelper (%s) failed: 0x%x\n", bstrFullPath);
  184. }
  185. }
  186. else
  187. {
  188. _TRACE (0, L"IADsPathname->Retrieve () failed: 0x%x\n", hr);
  189. }
  190. }
  191. else
  192. {
  193. _TRACE (0, L"IADsPathname->AddLeafElement (%s) failed: 0x%x\n",
  194. strLeaf.c_str (), hr);
  195. }
  196. SysFreeString (strAttrCommonName);
  197. }
  198. }
  199. else
  200. {
  201. _TRACE (0, L"IADsPathname->Set (%s): 0x%x\n",
  202. GetPhysicalSchemaNamingContext(), hr);
  203. }
  204. }
  205. else
  206. {
  207. _TRACE (0, L"IADsPathname->Set (%s): 0x%x\n", ACLDIAG_LDAP, hr);
  208. }
  209. }
  210. else
  211. {
  212. _TRACE (0, L"CoCreateInstance(CLSID_Pathname) failed: 0x%x\n", hr);
  213. }
  214. _TRACE (-1, L"Leaving CACLAdsiObject::AddAttrGUIDToList (): 0x%x\n", hr);
  215. return hr;
  216. }
  217. HRESULT CACLAdsiObject::BuildObjectTypeList (POBJECT_TYPE_LIST* pObjectTypeList, size_t& objectTypeListLength)
  218. {
  219. _TRACE (1, L"Entering CACLAdsiObject::BuildObjectTypeList ()\n");
  220. if ( !pObjectTypeList )
  221. return E_POINTER;
  222. HRESULT hr = S_OK;
  223. CComPtr<IADsPathname> spPathname;
  224. list<POBJECT_TYPE_LIST> guidList;
  225. //
  226. // Constructing the directory paths
  227. //
  228. hr = CoCreateInstance(
  229. CLSID_Pathname,
  230. NULL,
  231. CLSCTX_ALL,
  232. IID_PPV_ARG (IADsPathname, &spPathname));
  233. if ( SUCCEEDED (hr) )
  234. {
  235. ASSERT (!!spPathname);
  236. hr = spPathname->Set (CComBSTR (ACLDIAG_LDAP), ADS_SETTYPE_PROVIDER);
  237. if ( SUCCEEDED (hr) )
  238. {
  239. hr = spPathname->Set (CComBSTR (GetPhysicalSchemaNamingContext()),
  240. ADS_SETTYPE_DN);
  241. if ( SUCCEEDED (hr) )
  242. {
  243. wstring strLeaf;
  244. FormatMessage (strLeaf, L"CN=%1", GetSchemaCommonName ());
  245. hr = spPathname->AddLeafElement(CComBSTR (strLeaf.c_str ()));
  246. if ( SUCCEEDED (hr) )
  247. {
  248. BSTR bstrFullPath = 0;
  249. hr = spPathname->Retrieve(ADS_FORMAT_X500, &bstrFullPath);
  250. if ( SUCCEEDED (hr) )
  251. {
  252. CComPtr<IDirectoryObject> spDirObj;
  253. hr = ADsOpenObjectHelper (bstrFullPath,
  254. IID_IDirectoryObject,
  255. 0,
  256. (void**)&spDirObj);
  257. if ( SUCCEEDED (hr) )
  258. {
  259. GUID* pGUID = 0;
  260. POBJECT_TYPE_LIST pOtl = 0;
  261. {
  262. // Get class GUID (schemaIDGUID)
  263. LPWSTR rgpwzAttrNames1[] = {L"schemaIDGUID"};
  264. PADS_ATTR_INFO pAttrs = 0;
  265. DWORD cAttrs = 0;
  266. hr = spDirObj->GetObjectAttributes(rgpwzAttrNames1, 1, &pAttrs, &cAttrs);
  267. if ( SUCCEEDED (hr) )
  268. {
  269. if ( 1 == cAttrs && pAttrs && pAttrs->pADsValues )
  270. {
  271. if ( pAttrs->pADsValues->OctetString.dwLength == sizeof (GUID) )
  272. {
  273. pGUID = (GUID*) CoTaskMemAlloc (sizeof (GUID));
  274. if ( pGUID )
  275. {
  276. memcpy (pGUID,
  277. pAttrs->pADsValues->OctetString.lpValue,
  278. pAttrs->pADsValues->OctetString.dwLength);
  279. pOtl = (POBJECT_TYPE_LIST) CoTaskMemAlloc (sizeof (OBJECT_TYPE_LIST));
  280. if ( pOtl )
  281. {
  282. ::ZeroMemory (pOtl, sizeof (OBJECT_TYPE_LIST));
  283. pOtl->Level = ACCESS_OBJECT_GUID;
  284. pOtl->ObjectType = pGUID;
  285. pOtl->Sbz = 0;
  286. guidList.push_back (pOtl);
  287. }
  288. else
  289. {
  290. CoTaskMemFree (pGUID);
  291. hr = E_OUTOFMEMORY;
  292. }
  293. }
  294. else
  295. hr = E_OUTOFMEMORY;
  296. }
  297. else
  298. hr = E_UNEXPECTED;
  299. }
  300. if ( pAttrs )
  301. FreeADsMem (pAttrs);
  302. }
  303. else
  304. {
  305. _TRACE (0, L"IDirectoryObject->GetObjectAttributes (): 0x%x\n", hr);
  306. }
  307. }
  308. if ( SUCCEEDED (hr) )
  309. {
  310. //
  311. // Get "allowedAttributes" attribute
  312. //
  313. PADS_ATTR_INFO pAttrs = 0;
  314. DWORD cAttrs = 0;
  315. LPWSTR rgpwzAttrNames2[] = {L"allowedAttributes"};
  316. hr = spDirObj->GetObjectAttributes(rgpwzAttrNames2, 1, &pAttrs, &cAttrs);
  317. if ( SUCCEEDED (hr) )
  318. {
  319. if ( 1 == cAttrs && pAttrs && pAttrs->pADsValues )
  320. {
  321. for (DWORD dwIdx = 0;
  322. dwIdx < pAttrs->dwNumValues && SUCCEEDED (hr);
  323. dwIdx++)
  324. {
  325. hr = AddAttrGUIDToList (
  326. CComBSTR (pAttrs->pADsValues[dwIdx].CaseIgnoreString),
  327. guidList);
  328. }
  329. }
  330. if ( pAttrs )
  331. FreeADsMem (pAttrs);
  332. }
  333. else
  334. {
  335. _TRACE (0, L"IDirectoryObject->GetObjectAttributes (): 0x%x\n", hr);
  336. }
  337. }
  338. if ( SUCCEEDED (hr) )
  339. {
  340. objectTypeListLength = guidList.size ();
  341. *pObjectTypeList = (POBJECT_TYPE_LIST) CoTaskMemAlloc (
  342. sizeof (OBJECT_TYPE_LIST) + (sizeof (GUID) * objectTypeListLength));
  343. if ( *pObjectTypeList )
  344. {
  345. DWORD idx = 0;
  346. list<POBJECT_TYPE_LIST>::iterator itr = guidList.begin ();
  347. for (; idx < objectTypeListLength && itr != guidList.end ();
  348. idx++, itr++)
  349. {
  350. pOtl = *itr;
  351. (*pObjectTypeList)[idx].Level = pOtl->Level;
  352. // Note just copy pointer here and don't free the pOtl->ObjectType later.
  353. (*pObjectTypeList)[idx].ObjectType = pOtl->ObjectType;
  354. pOtl->ObjectType = 0;
  355. (*pObjectTypeList)[idx].Sbz = 0;
  356. CoTaskMemFree (pOtl);
  357. }
  358. }
  359. else
  360. hr = E_OUTOFMEMORY;
  361. }
  362. }
  363. else
  364. {
  365. _TRACE (0, L"ADsOpenObjectHelper (%s) failed: 0x%x\n", bstrFullPath);
  366. }
  367. }
  368. else
  369. {
  370. _TRACE (0, L"IADsPathname->Retrieve () failed: 0x%x\n", hr);
  371. }
  372. }
  373. else
  374. {
  375. _TRACE (0, L"IADsPathname->AddLeafElement (%s) failed: 0x%x\n",
  376. strLeaf.c_str (), hr);
  377. }
  378. }
  379. else
  380. {
  381. _TRACE (0, L"IADsPathname->Set (%s): 0x%x\n",
  382. GetPhysicalSchemaNamingContext(), hr);
  383. }
  384. }
  385. else
  386. {
  387. _TRACE (0, L"IADsPathname->Set (%s): 0x%x\n", ACLDIAG_LDAP, hr);
  388. }
  389. }
  390. else
  391. {
  392. _TRACE (0, L"CoCreateInstance(CLSID_Pathname) failed: 0x%x\n", hr);
  393. }
  394. _TRACE (-1, L"Leaving CACLAdsiObject::BuildObjectTypeList (): 0x%x\n", hr);
  395. return hr;
  396. }
  397. HRESULT CACLAdsiObject::ReadSchemaCommonName ()
  398. {
  399. _TRACE (1, L"Entering CACLAdsiObject::ReadSchemaCommonName ()\n");
  400. HRESULT hr = S_OK;
  401. CComPtr<IADsPathname> spPathname;
  402. //
  403. // Constructing the directory paths
  404. //
  405. hr = CoCreateInstance(
  406. CLSID_Pathname,
  407. NULL,
  408. CLSCTX_ALL,
  409. IID_PPV_ARG (IADsPathname, &spPathname));
  410. if ( SUCCEEDED (hr) )
  411. {
  412. ASSERT (!!spPathname);
  413. hr = spPathname->Set (CComBSTR (ACLDIAG_LDAP), ADS_SETTYPE_PROVIDER);
  414. if ( SUCCEEDED (hr) )
  415. {
  416. hr = spPathname->Set (CComBSTR (GetPhysicalSchemaNamingContext()),
  417. ADS_SETTYPE_DN);
  418. if ( SUCCEEDED (hr) )
  419. {
  420. BSTR bstrFullPath = 0;
  421. hr = spPathname->Retrieve(ADS_FORMAT_X500, &bstrFullPath);
  422. if ( SUCCEEDED (hr) )
  423. {
  424. CComPtr<IDirectoryObject> spDirObj;
  425. hr = ADsOpenObjectHelper (bstrFullPath,
  426. IID_IDirectoryObject,
  427. 0,
  428. (void**)&spDirObj);
  429. if ( SUCCEEDED (hr) )
  430. {
  431. CComPtr<IDirectorySearch> spDsSearch;
  432. hr = spDirObj->QueryInterface (IID_PPV_ARG(IDirectorySearch, &spDsSearch));
  433. if ( SUCCEEDED (hr) )
  434. {
  435. ASSERT (!!spDsSearch);
  436. ADS_SEARCHPREF_INFO pSearchPref[2];
  437. DWORD dwNumPref = 2;
  438. pSearchPref[0].dwSearchPref = ADS_SEARCHPREF_SEARCH_SCOPE;
  439. pSearchPref[0].vValue.dwType = ADSTYPE_INTEGER;
  440. pSearchPref[0].vValue.Integer = ADS_SCOPE_ONELEVEL;
  441. pSearchPref[1].dwSearchPref = ADS_SEARCHPREF_CHASE_REFERRALS;
  442. pSearchPref[1].vValue.dwType = ADSTYPE_INTEGER;
  443. pSearchPref[1].vValue.Integer = ADS_CHASE_REFERRALS_NEVER;
  444. hr = spDsSearch->SetSearchPreference(
  445. pSearchPref,
  446. dwNumPref
  447. );
  448. if ( SUCCEEDED (hr) )
  449. {
  450. PWSTR rgszAttrList[] = {L"cn"};
  451. ADS_SEARCH_HANDLE hSearchHandle = 0;
  452. DWORD dwNumAttributes = 1;
  453. wstring strQuery;
  454. ADS_SEARCH_COLUMN Column;
  455. ::ZeroMemory (&Column, sizeof (ADS_SEARCH_COLUMN));
  456. FormatMessage (strQuery,
  457. L"lDAPDisplayName=%1",
  458. this->GetClass ());
  459. hr = spDsSearch->ExecuteSearch(
  460. const_cast <LPWSTR>(strQuery.c_str ()),
  461. rgszAttrList,
  462. dwNumAttributes,
  463. &hSearchHandle
  464. );
  465. if ( SUCCEEDED (hr) )
  466. {
  467. hr = spDsSearch->GetFirstRow (hSearchHandle);
  468. if ( SUCCEEDED (hr) )
  469. {
  470. while (hr != S_ADS_NOMORE_ROWS )
  471. {
  472. //
  473. // Getting current row's information
  474. //
  475. hr = spDsSearch->GetColumn(
  476. hSearchHandle,
  477. rgszAttrList[0],
  478. &Column
  479. );
  480. if ( SUCCEEDED (hr) )
  481. {
  482. m_strSchemaCommonName = Column.pADsValues->CaseIgnoreString;
  483. spDsSearch->FreeColumn (&Column);
  484. Column.pszAttrName = NULL;
  485. break;
  486. }
  487. else if ( hr != E_ADS_COLUMN_NOT_SET )
  488. {
  489. break;
  490. }
  491. else
  492. {
  493. _TRACE (0, L"IDirectorySearch::GetColumn (): 0x%x\n", hr);
  494. }
  495. }
  496. }
  497. else
  498. {
  499. _TRACE (0, L"IDirectorySearch::GetFirstRow (): 0x%x\n", hr);
  500. }
  501. if (Column.pszAttrName)
  502. {
  503. spDsSearch->FreeColumn(&Column);
  504. }
  505. spDsSearch->CloseSearchHandle(hSearchHandle);
  506. }
  507. else
  508. {
  509. _TRACE (0, L"IDirectorySearch::ExecuteSearch (): 0x%x\n", hr);
  510. hr = S_OK;
  511. }
  512. }
  513. else
  514. {
  515. _TRACE (0, L"IDirectorySearch::SetSearchPreference (): 0x%x\n", hr);
  516. }
  517. }
  518. else
  519. {
  520. _TRACE (0, L"IDirectoryObject::QueryInterface (IDirectorySearch): 0x%x\n", hr);
  521. }
  522. }
  523. else
  524. {
  525. _TRACE (0, L"ADsOpenObjectHelper (%s) failed: 0x%x\n", bstrFullPath);
  526. }
  527. }
  528. else
  529. {
  530. _TRACE (0, L"IADsPathname->Retrieve () failed: 0x%x\n", hr);
  531. }
  532. }
  533. else
  534. {
  535. _TRACE (0, L"IADsPathname->Set (%s): 0x%x\n",
  536. GetPhysicalSchemaNamingContext(), hr);
  537. }
  538. }
  539. else
  540. {
  541. _TRACE (0, L"IADsPathname->Set (%s): 0x%x\n", ACLDIAG_LDAP, hr);
  542. }
  543. }
  544. else
  545. {
  546. _TRACE (0, L"CoCreateInstance(CLSID_Pathname) failed: 0x%x\n", hr);
  547. }
  548. _TRACE (-1, L"Leaving CACLAdsiObject::ReadSchemaCommonName (): 0x%x\n", hr);
  549. return hr;
  550. }
  551. HRESULT CACLAdsiObject::Bind(LPCWSTR lpszLdapPath)
  552. {
  553. _TRACE (1, L"Entering CACLAdsiObject::Bind ()\n");
  554. HRESULT hr = CAdsiObject::Bind (lpszLdapPath);
  555. if ( SUCCEEDED (hr) )
  556. {
  557. hr = ReadSchemaCommonName ();
  558. }
  559. _TRACE (-1, L"Leaving CACLAdsiObject::Bind (): 0x%x\n", hr);
  560. return hr;
  561. }
  562. HRESULT CACLAdsiObject::ReadSchemaAttributeCommonName (const BSTR pszAttrName, BSTR* ppszAttrCommonName)
  563. {
  564. _TRACE (1, L"Entering CACLAdsiObject::ReadSchemaAttributeCommonName ()\n");
  565. if ( !pszAttrName || !ppszAttrCommonName )
  566. return E_POINTER;
  567. HRESULT hr = S_OK;
  568. CComPtr<IADsPathname> spPathname;
  569. //
  570. // Constructing the directory paths
  571. //
  572. hr = CoCreateInstance(
  573. CLSID_Pathname,
  574. NULL,
  575. CLSCTX_ALL,
  576. IID_PPV_ARG (IADsPathname, &spPathname));
  577. if ( SUCCEEDED (hr) )
  578. {
  579. ASSERT (!!spPathname);
  580. hr = spPathname->Set (CComBSTR (ACLDIAG_LDAP), ADS_SETTYPE_PROVIDER);
  581. if ( SUCCEEDED (hr) )
  582. {
  583. hr = spPathname->Set (CComBSTR (GetPhysicalSchemaNamingContext()),
  584. ADS_SETTYPE_DN);
  585. if ( SUCCEEDED (hr) )
  586. {
  587. BSTR bstrFullPath = 0;
  588. hr = spPathname->Retrieve(ADS_FORMAT_X500, &bstrFullPath);
  589. if ( SUCCEEDED (hr) )
  590. {
  591. CComPtr<IDirectoryObject> spDirObj;
  592. hr = ADsOpenObjectHelper (bstrFullPath,
  593. IID_IDirectoryObject,
  594. 0,
  595. (void**)&spDirObj);
  596. if ( SUCCEEDED (hr) )
  597. {
  598. CComPtr<IDirectorySearch> spDsSearch;
  599. hr = spDirObj->QueryInterface (IID_PPV_ARG(IDirectorySearch, &spDsSearch));
  600. if ( SUCCEEDED (hr) )
  601. {
  602. ASSERT (!!spDsSearch);
  603. ADS_SEARCHPREF_INFO pSearchPref[2];
  604. DWORD dwNumPref = 2;
  605. pSearchPref[0].dwSearchPref = ADS_SEARCHPREF_SEARCH_SCOPE;
  606. pSearchPref[0].vValue.dwType = ADSTYPE_INTEGER;
  607. pSearchPref[0].vValue.Integer = ADS_SCOPE_ONELEVEL;
  608. pSearchPref[1].dwSearchPref = ADS_SEARCHPREF_CHASE_REFERRALS;
  609. pSearchPref[1].vValue.dwType = ADSTYPE_INTEGER;
  610. pSearchPref[1].vValue.Integer = ADS_CHASE_REFERRALS_NEVER;
  611. hr = spDsSearch->SetSearchPreference(
  612. pSearchPref,
  613. dwNumPref
  614. );
  615. if ( SUCCEEDED (hr) )
  616. {
  617. PWSTR rgszAttrList[] = {L"cn"};
  618. ADS_SEARCH_HANDLE hSearchHandle = 0;
  619. DWORD dwNumAttributes = 1;
  620. wstring strQuery;
  621. ADS_SEARCH_COLUMN Column;
  622. ::ZeroMemory (&Column, sizeof (ADS_SEARCH_COLUMN));
  623. FormatMessage (strQuery,
  624. L"lDAPDisplayName=%1",
  625. pszAttrName);
  626. hr = spDsSearch->ExecuteSearch(
  627. const_cast <LPWSTR>(strQuery.c_str ()),
  628. rgszAttrList,
  629. dwNumAttributes,
  630. &hSearchHandle
  631. );
  632. if ( SUCCEEDED (hr) )
  633. {
  634. hr = spDsSearch->GetFirstRow (hSearchHandle);
  635. if ( SUCCEEDED (hr) )
  636. {
  637. while (hr != S_ADS_NOMORE_ROWS )
  638. {
  639. //
  640. // Getting current row's information
  641. //
  642. hr = spDsSearch->GetColumn(
  643. hSearchHandle,
  644. rgszAttrList[0],
  645. &Column
  646. );
  647. if ( SUCCEEDED (hr) )
  648. {
  649. *ppszAttrCommonName = SysAllocString (Column.pADsValues->CaseIgnoreString);
  650. if ( !(*ppszAttrCommonName) )
  651. hr = E_OUTOFMEMORY;
  652. spDsSearch->FreeColumn (&Column);
  653. Column.pszAttrName = NULL;
  654. break;
  655. }
  656. else if ( hr != E_ADS_COLUMN_NOT_SET )
  657. {
  658. break;
  659. }
  660. else
  661. {
  662. _TRACE (0, L"IDirectorySearch::GetColumn (): 0x%x\n", hr);
  663. }
  664. }
  665. }
  666. else
  667. {
  668. _TRACE (0, L"IDirectorySearch::GetFirstRow (): 0x%x\n", hr);
  669. }
  670. if (Column.pszAttrName)
  671. {
  672. spDsSearch->FreeColumn(&Column);
  673. }
  674. spDsSearch->CloseSearchHandle(hSearchHandle);
  675. }
  676. else
  677. {
  678. _TRACE (0, L"IDirectorySearch::ExecuteSearch (): 0x%x\n", hr);
  679. hr = S_OK;
  680. }
  681. }
  682. else
  683. {
  684. _TRACE (0, L"IDirectorySearch::SetSearchPreference (): 0x%x\n", hr);
  685. }
  686. }
  687. else
  688. {
  689. _TRACE (0, L"IDirectoryObject::QueryInterface (IDirectorySearch): 0x%x\n", hr);
  690. }
  691. }
  692. else
  693. {
  694. _TRACE (0, L"ADsOpenObjectHelper (%s) failed: 0x%x\n", bstrFullPath);
  695. }
  696. }
  697. else
  698. {
  699. _TRACE (0, L"IADsPathname->Retrieve () failed: 0x%x\n", hr);
  700. }
  701. }
  702. else
  703. {
  704. _TRACE (0, L"IADsPathname->Set (%s): 0x%x\n",
  705. GetPhysicalSchemaNamingContext(), hr);
  706. }
  707. }
  708. else
  709. {
  710. _TRACE (0, L"IADsPathname->Set (%s): 0x%x\n", ACLDIAG_LDAP, hr);
  711. }
  712. }
  713. else
  714. {
  715. _TRACE (0, L"CoCreateInstance(CLSID_Pathname) failed: 0x%x\n", hr);
  716. }
  717. _TRACE (-1, L"Leaving CACLAdsiObject::ReadSchemaAttributeCommonName (): 0x%x\n", hr);
  718. return hr;
  719. }
  720. HRESULT CACLAdsiObject::GetPrincipalSelfSid(PSID &principalSelfSid)
  721. {
  722. _TRACE (1, L"Entering CACLAdsiObject::GetPrincipalSelfSid ()\n");
  723. HRESULT hr = S_OK;
  724. ASSERT (!!m_spIADs);
  725. if ( !!m_spIADs )
  726. {
  727. CComPtr<IDirectoryObject> spDirObj;
  728. hr = m_spIADs->QueryInterface (IID_PPV_ARG(IDirectoryObject, &spDirObj));
  729. if ( SUCCEEDED (hr) )
  730. {
  731. ASSERT ( !!spDirObj);
  732. //
  733. // Get "objectSid" attribute
  734. //
  735. const PWSTR wzAllowedAttributes = L"objectSid";
  736. PADS_ATTR_INFO pAttrs = 0;
  737. DWORD cAttrs = 0;
  738. LPWSTR rgpwzAttrNames[] = {wzAllowedAttributes};
  739. hr = spDirObj->GetObjectAttributes(rgpwzAttrNames, 1, &pAttrs, &cAttrs);
  740. if ( SUCCEEDED (hr) )
  741. {
  742. if ( 1 == cAttrs && pAttrs && pAttrs->pADsValues && 1 == pAttrs->dwNumValues )
  743. {
  744. PSID pSid = pAttrs->pADsValues->OctetString.lpValue;
  745. DWORD dwSidLen = GetLengthSid (pSid);
  746. PSID pSidCopy = CoTaskMemAlloc (dwSidLen);
  747. if ( pSidCopy )
  748. {
  749. if ( CopySid (dwSidLen, pSidCopy, pSid) )
  750. {
  751. ASSERT (IsValidSid (pSidCopy));
  752. principalSelfSid = pSidCopy;
  753. }
  754. else
  755. {
  756. CoTaskMemFree (pSidCopy);
  757. hr = GetLastError ();
  758. _TRACE (0, L"CopySid () failed: 0x%x\n", hr);
  759. }
  760. }
  761. else
  762. {
  763. hr = E_OUTOFMEMORY;
  764. }
  765. }
  766. else
  767. principalSelfSid = 0;
  768. if ( pAttrs )
  769. FreeADsMem (pAttrs);
  770. }
  771. else
  772. {
  773. _TRACE (0, L"IDirectoryObject->GetObjectAttributes (): 0x%x\n", hr);
  774. }
  775. }
  776. else
  777. {
  778. _TRACE (0, L"IADs->QueryInterface (IDirectoryObject): 0x%x\n", hr);
  779. }
  780. }
  781. else
  782. hr = E_UNEXPECTED;
  783. _TRACE (-1, L"Leaving CACLAdsiObject::GetPrincipalSelfSid (): 0x%x\n", hr);
  784. return hr;
  785. }