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.

850 lines
34 KiB

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