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.

2128 lines
78 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1999-2002.
  5. //
  6. // File: SecDesc.cpp
  7. //
  8. // Contents: DoSecurityDescription and support methods
  9. //
  10. //
  11. //----------------------------------------------------------------------------
  12. #include "stdafx.h"
  13. #include "ADUtils.h"
  14. #include "SecDesc.h"
  15. ///////////////////////////////////////////////////////////////////////////////
  16. //
  17. // Method: DoSecurityDescription ()
  18. //
  19. // Purpose: Main routine for doing security description
  20. //
  21. //
  22. HRESULT DoSecurityDescription ()
  23. {
  24. _TRACE (1, L"Entering DoSecurityDescription\n");
  25. HRESULT hr = S_OK;
  26. wstring str;
  27. // Print header
  28. if ( _Module.DoTabDelimitedOutput () )
  29. {
  30. MyWprintf (_Module.GetObjectDN ().c_str ());
  31. MyWprintf (L"\n");
  32. }
  33. else
  34. {
  35. FormatMessage (str, IDS_SECURITY_DIAGNOSIS_FOR, _Module.GetObjectDN ().c_str ());
  36. MyWprintf (str.c_str ());
  37. if ( !_Module.SkipDescription () )
  38. {
  39. LoadFromResource (str, IDS_DESCRIPTION);
  40. str += L"\n";
  41. MyWprintf (str.c_str ());
  42. }
  43. }
  44. hr = GetSecurityDescriptor (_Module.GetObjectDN (), &_Module.m_pSecurityDescriptor);
  45. if ( SUCCEEDED (hr) )
  46. {
  47. if ( _Module.m_pSecurityDescriptor )
  48. {
  49. hr = DisplayOwner ();
  50. if ( SUCCEEDED (hr) )
  51. {
  52. SECURITY_DESCRIPTOR_CONTROL control;
  53. DWORD dwRevision = 0;
  54. if ( GetSecurityDescriptorControl (
  55. _Module.m_pSecurityDescriptor,
  56. &control,
  57. &dwRevision) )
  58. {
  59. if ( _Module.DoTabDelimitedOutput () )
  60. {
  61. MyWprintf (L"\n");
  62. if ( control & SE_DACL_PROTECTED )
  63. LoadFromResource (str, IDS_PERMISSIONS_PROTECTED);
  64. else
  65. LoadFromResource (str, IDS_PERMISSIONS_NOT_PROTECTED);
  66. MyWprintf (str.c_str ());
  67. if ( control & SE_SACL_PROTECTED )
  68. LoadFromResource (str, IDS_AUDITING_PROTECTED);
  69. else
  70. LoadFromResource (str, IDS_AUDITING_NOT_PROTECTED);
  71. MyWprintf (str.c_str ());
  72. }
  73. else
  74. {
  75. if ( control & SE_DACL_PROTECTED )
  76. {
  77. LoadFromResource (str, IDS_CONFIG_NO_INHERIT);
  78. MyWprintf (str.c_str ());
  79. }
  80. }
  81. }
  82. else
  83. {
  84. _TRACE (0, L"GetSecurityDescriptorControl () failed: 0x%x\n", GetLastError ());
  85. }
  86. hr = EnumerateDacl (_Module.m_pSecurityDescriptor, _Module.m_DACLList, true);
  87. if ( SUCCEEDED (hr) )
  88. {
  89. hr = EnumerateSacl (_Module.m_pSecurityDescriptor, _Module.m_SACLList);
  90. if ( SUCCEEDED (hr) && !_Module.SkipDescription () )
  91. {
  92. hr = PrintEffectivePermissions ();
  93. if ( SUCCEEDED (hr) )
  94. {
  95. hr = PrintInheritedPermissions ();
  96. if ( SUCCEEDED (hr) )
  97. {
  98. hr = PrintAuditingInformation ();
  99. }
  100. }
  101. }
  102. }
  103. }
  104. }
  105. else
  106. {
  107. hr = E_ACCESSDENIED;
  108. wstring str;
  109. FormatMessage (str, IDS_UNABLE_TO_READ_SECURITY_DESCRIPTOR, _Module.GetObjectDN ().c_str ());
  110. MyWprintf (str.c_str ());
  111. }
  112. }
  113. _TRACE (-1, L"Leaving DoSecurityDescription: 0x%x\n", hr);
  114. return hr;
  115. }
  116. ///////////////////////////////////////////////////////////////////////////////
  117. //
  118. // Method: GetSecurityDescriptor ()
  119. //
  120. // Purpose: Get ths security descriptor for the indicated object
  121. //
  122. // Inputs: strObjectDN - the object show security descriptor we wish to
  123. // retrieve
  124. //
  125. // Outputs: ppAttrs - returns the security descriptor raw data - this holds the data
  126. // persistent in memory
  127. //
  128. // ppSecurityDescriptor - returns the security descriptor
  129. //
  130. HRESULT GetSecurityDescriptor (
  131. wstring strObjectDN, // pass by value
  132. PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
  133. {
  134. _TRACE (1, L"Entering GetSecurityDescriptor\n");
  135. HRESULT hr = S_OK;
  136. if ( ppSecurityDescriptor )
  137. {
  138. CComPtr<IADsPathname> spPathname;
  139. //
  140. // Constructing the directory paths
  141. //
  142. hr = CoCreateInstance(
  143. CLSID_Pathname,
  144. NULL,
  145. CLSCTX_ALL,
  146. IID_PPV_ARG (IADsPathname, &spPathname));
  147. if ( SUCCEEDED (hr) )
  148. {
  149. ASSERT (!!spPathname);
  150. LPCWSTR pszLDAP = L"LDAP://";
  151. // If object name is preceded with LDAP, set the whole name at once.
  152. if ( !wcsncmp (strObjectDN.c_str (), pszLDAP, wcslen (pszLDAP)) )
  153. {
  154. hr = spPathname->Set (CComBSTR (strObjectDN.c_str ()),
  155. ADS_SETTYPE_FULL);
  156. if ( FAILED (hr) )
  157. {
  158. _TRACE (0, L"IADsPathname->Set (%s): 0x%x\n",
  159. strObjectDN.c_str (), hr);
  160. }
  161. }
  162. else
  163. {
  164. hr = spPathname->Set (CComBSTR (ACLDIAG_LDAP),
  165. ADS_SETTYPE_PROVIDER);
  166. if ( SUCCEEDED (hr) )
  167. {
  168. hr = spPathname->Set (CComBSTR (strObjectDN.c_str ()),
  169. ADS_SETTYPE_DN);
  170. if ( FAILED (hr) )
  171. {
  172. _TRACE (0, L"IADsPathname->Set (%s): 0x%x\n",
  173. strObjectDN.c_str (), hr);
  174. }
  175. }
  176. else
  177. {
  178. _TRACE (0, L"IADsPathname->Set (%s): 0x%x\n", ACLDIAG_LDAP, hr);
  179. }
  180. }
  181. if ( SUCCEEDED (hr) )
  182. {
  183. BSTR bstrFullPath = 0;
  184. hr = spPathname->Retrieve(ADS_FORMAT_X500, &bstrFullPath);
  185. if ( SUCCEEDED (hr) )
  186. {
  187. CComPtr<IDirectoryObject> spDirObj;
  188. hr = ADsOpenObjectHelper (bstrFullPath,
  189. IID_IDirectoryObject,
  190. 0,
  191. (void**)&spDirObj);
  192. if ( SUCCEEDED (hr) )
  193. {
  194. hr = SetSecurityInfoMask (spDirObj,
  195. OWNER_SECURITY_INFORMATION |
  196. GROUP_SECURITY_INFORMATION |
  197. DACL_SECURITY_INFORMATION |
  198. SACL_SECURITY_INFORMATION);
  199. //
  200. // Get this object's Security Descriptor.
  201. //
  202. const PWSTR wzSecDescriptor = L"nTSecurityDescriptor";
  203. PADS_ATTR_INFO pAttrs = 0;
  204. DWORD cAttrs = 0;
  205. LPWSTR rgpwzAttrNames[] = {wzSecDescriptor};
  206. hr = spDirObj->GetObjectAttributes(rgpwzAttrNames, 1, &pAttrs, &cAttrs);
  207. if ( SUCCEEDED (hr) )
  208. {
  209. if ( 0 == cAttrs )
  210. {
  211. // remove SACL_SECURITY_INFORMATION
  212. hr = SetSecurityInfoMask (spDirObj,
  213. OWNER_SECURITY_INFORMATION |
  214. GROUP_SECURITY_INFORMATION |
  215. DACL_SECURITY_INFORMATION);
  216. hr = spDirObj->GetObjectAttributes(rgpwzAttrNames, 1, &pAttrs, &cAttrs);
  217. }
  218. if ( SUCCEEDED (hr) && 1 == cAttrs && pAttrs && pAttrs->pADsValues )
  219. {
  220. if (!(pAttrs->pADsValues->SecurityDescriptor.lpValue) ||
  221. !(pAttrs->pADsValues->SecurityDescriptor.dwLength))
  222. {
  223. _TRACE (0, L"IADS return bogus SD!\n");
  224. hr = E_UNEXPECTED;
  225. }
  226. else if (!IsValidSecurityDescriptor(pAttrs->pADsValues->SecurityDescriptor.lpValue))
  227. {
  228. _TRACE (0, L"IsValidSecurityDescriptor failed!\n");
  229. hr = HRESULT_FROM_WIN32(GetLastError());
  230. }
  231. else
  232. {
  233. *ppSecurityDescriptor = (PSECURITY_DESCRIPTOR)
  234. ::LocalAlloc (LMEM_ZEROINIT, pAttrs->pADsValues->SecurityDescriptor.dwLength);
  235. if ( *ppSecurityDescriptor )
  236. {
  237. memcpy (*ppSecurityDescriptor,
  238. pAttrs->pADsValues->SecurityDescriptor.lpValue,
  239. pAttrs->pADsValues->SecurityDescriptor.dwLength);
  240. }
  241. else
  242. hr = E_OUTOFMEMORY;
  243. }
  244. FreeADsMem (pAttrs);
  245. }
  246. else
  247. {
  248. if ( !wcscmp (strObjectDN.c_str (), _Module.GetObjectDN ().c_str ()) )
  249. {
  250. wstring str;
  251. FormatMessage (str, IDS_NO_SECDESC_RETURNED, strObjectDN.c_str ());
  252. MyWprintf (str.c_str ());
  253. }
  254. }
  255. }
  256. else
  257. {
  258. if ( !wcscmp (strObjectDN.c_str (), _Module.GetObjectDN ().c_str ()) )
  259. {
  260. wstring str;
  261. FormatMessage (str, IDS_NO_SECDESC_RETURNED_WITH_CODE,
  262. strObjectDN.c_str (), GetSystemMessage (hr).c_str ());
  263. MyWprintf (str.c_str ());
  264. }
  265. _TRACE (0, L"IDirectoryObject->GetObjectAttributes (): 0x%x\n", hr);
  266. }
  267. }
  268. else
  269. {
  270. if ( ERROR_DS_REFERRAL == HRESULT_CODE (hr) )
  271. hr = S_FALSE;
  272. else
  273. {
  274. _TRACE (0, L"ADsOpenObjectHelper (%s): 0x%x\n", bstrFullPath, hr);
  275. wstring strErr;
  276. FormatMessage (strErr, IDS_INVALID_OBJECT,
  277. _Module.GetObjectDN ().c_str (),
  278. GetSystemMessage (hr).c_str ());
  279. MyWprintf (strErr.c_str ());
  280. }
  281. }
  282. }
  283. else
  284. {
  285. _TRACE (0, L"IADsPathname->Retrieve (): 0x%x\n", hr);
  286. }
  287. }
  288. }
  289. else
  290. {
  291. _TRACE (0, L"CoCreateInstance(CLSID_Pathname): 0x%x\n", hr);
  292. }
  293. }
  294. else
  295. hr = E_POINTER;
  296. _TRACE (-1, L"Leaving GetSecurityDescriptor: 0x%x\n", hr);
  297. return hr;
  298. }
  299. ///////////////////////////////////////////////////////////////////////////////
  300. //
  301. // Method: DisplayOwner ()
  302. //
  303. // Purpose: Display the owner of this object
  304. //
  305. HRESULT DisplayOwner ()
  306. {
  307. _TRACE (1, L"Entering DisplayOwner\n");
  308. HRESULT hr = S_OK;
  309. PSID pSidOwner = 0;
  310. BOOL bOwnerDefaulted = FALSE;
  311. if ( ::GetSecurityDescriptorOwner(
  312. _Module.m_pSecurityDescriptor,
  313. &pSidOwner,
  314. &bOwnerDefaulted) )
  315. {
  316. wstring strPrincipalName;
  317. wstring strFQDN;
  318. SID_NAME_USE sne = SidTypeUnknown;
  319. hr = GetNameFromSid (pSidOwner, strPrincipalName, &strFQDN, sne);
  320. if ( SUCCEEDED (hr) && !_Module.SkipDescription () )
  321. {
  322. wstring str;
  323. if ( _Module.DoTabDelimitedOutput () )
  324. FormatMessage (str, IDS_OWNER_CDO, strPrincipalName.c_str ());
  325. else
  326. FormatMessage (str, IDS_OWNER, strPrincipalName.c_str ());
  327. MyWprintf (str.c_str ());
  328. }
  329. PSID_FQDN* pItem = new PSID_FQDN (pSidOwner, strFQDN, strPrincipalName, sne);
  330. if ( pItem )
  331. _Module.m_PSIDList.push_back (pItem);
  332. else
  333. hr = E_OUTOFMEMORY;
  334. }
  335. else
  336. {
  337. DWORD dwErr = GetLastError ();
  338. _TRACE (0, L"GetSecurityDescriptorOwner () failed: 0x%x\n",
  339. dwErr);
  340. hr = HRESULT_FROM_WIN32 (dwErr);
  341. }
  342. _TRACE (-1, L"Leaving DisplayOwner: 0x%x\n", hr);
  343. return hr;
  344. }
  345. ///////////////////////////////////////////////////////////////////////////////
  346. //
  347. // Method: EnumerateDacl ()
  348. //
  349. // Purpose: Enumerate the DACL and store it in a list
  350. //
  351. // Inputs: pSecurityDescriptor - where to get the DACL
  352. //
  353. // Outputs: DACLList - return the ACEs in this list
  354. //
  355. HRESULT EnumerateDacl (PSECURITY_DESCRIPTOR pSecurityDescriptor, ACE_SAMNAME_LIST& DACLList, bool bListSids)
  356. {
  357. _TRACE (1, L"Entering EnumerateDacl\n");
  358. HRESULT hr = S_OK;
  359. ASSERT (pSecurityDescriptor);
  360. if ( !pSecurityDescriptor )
  361. return E_POINTER;
  362. PACL pDacl = 0;
  363. BOOL bDaclPresent = FALSE;
  364. BOOL bDaclDefaulted = FALSE;
  365. _TRACE (0, L"Calling GetSecurityDescriptorDacl ()\n");
  366. if ( GetSecurityDescriptorDacl (pSecurityDescriptor,
  367. &bDaclPresent, &pDacl, &bDaclDefaulted) )
  368. {
  369. _TRACE (0, L"Call to GetSecurityDescriptorDacl () succeeded.\n");
  370. if ( bDaclPresent )
  371. {
  372. PACCESS_ALLOWED_ACE pAllowedAce;
  373. PSID_FQDN_LIST::iterator itrPSID = _Module.m_PSIDList.begin ();
  374. ACE_SAMNAME* pAceSAMName = 0;
  375. PSID_FQDN* pPsidFQDN = 0;
  376. SID_NAME_USE sne = SidTypeUnknown;
  377. // copy the ACES
  378. for (int i = 0; i < pDacl->AceCount; i++)
  379. {
  380. if ( GetAce (pDacl, i, (void **)&pAllowedAce) )
  381. {
  382. PSID AceSid = 0;
  383. if ( IsObjectAceType ( pAllowedAce ) )
  384. {
  385. AceSid = RtlObjectAceSid( pAllowedAce );
  386. }
  387. else
  388. {
  389. AceSid = &( ( PKNOWN_ACE )pAllowedAce )->SidStart;
  390. }
  391. ASSERT (IsValidSid (AceSid));
  392. wstring strPrincipalName;
  393. wstring strFQDN;
  394. hr = GetNameFromSid (AceSid, strPrincipalName,
  395. bListSids ? &strFQDN : 0, sne);
  396. if ( SUCCEEDED (hr) )
  397. {
  398. if ( bListSids )
  399. {
  400. bool bFound = false;
  401. for (PSID_FQDN_LIST::iterator itrPSIDFind = _Module.m_PSIDList.begin ();
  402. itrPSIDFind != _Module.m_PSIDList.end ();
  403. itrPSIDFind++)
  404. {
  405. pPsidFQDN = *itrPSIDFind;
  406. if ( pPsidFQDN )
  407. {
  408. if ( !wcscmp (pPsidFQDN->m_strFQDN.c_str (), strFQDN.c_str ()) )
  409. {
  410. bFound = true;
  411. }
  412. }
  413. }
  414. if ( !bFound )
  415. {
  416. pPsidFQDN = new PSID_FQDN (AceSid, strFQDN, strPrincipalName, sne);
  417. if ( pPsidFQDN )
  418. {
  419. _Module.m_PSIDList.push_back (pPsidFQDN);
  420. }
  421. else
  422. {
  423. hr = E_OUTOFMEMORY;
  424. break;
  425. }
  426. }
  427. }
  428. pAceSAMName = new ACE_SAMNAME;
  429. if ( pAceSAMName )
  430. {
  431. pAceSAMName->m_AceType = pAllowedAce->Header.AceType;
  432. switch (pAceSAMName->m_AceType)
  433. {
  434. case ACCESS_ALLOWED_ACE_TYPE:
  435. pAceSAMName->m_pAllowedAce = pAllowedAce;
  436. break;
  437. case ACCESS_ALLOWED_OBJECT_ACE_TYPE:
  438. pAceSAMName->m_pAllowedObjectAce =
  439. reinterpret_cast <PACCESS_ALLOWED_OBJECT_ACE> (pAllowedAce);
  440. break;
  441. case ACCESS_DENIED_ACE_TYPE:
  442. pAceSAMName->m_pDeniedAce =
  443. reinterpret_cast <PACCESS_DENIED_ACE> (pAllowedAce);
  444. break;
  445. case ACCESS_DENIED_OBJECT_ACE_TYPE:
  446. pAceSAMName->m_pDeniedObjectAce =
  447. reinterpret_cast <PACCESS_DENIED_OBJECT_ACE> (pAllowedAce);
  448. break;
  449. default:
  450. break;
  451. }
  452. pAceSAMName->m_SAMAccountName = strPrincipalName;
  453. pAceSAMName->DebugOut ();
  454. DACLList.push_back (pAceSAMName);
  455. }
  456. else
  457. {
  458. hr = E_OUTOFMEMORY;
  459. break;
  460. }
  461. }
  462. }
  463. else
  464. {
  465. _TRACE (0, L"GetAce failed: 0x%x\n", GetLastError ());
  466. break;
  467. }
  468. }
  469. }
  470. }
  471. else
  472. {
  473. DWORD dwErr = GetLastError ();
  474. _TRACE (0, L"Call to GetSecurityDescriptorDacl () failed: 0x%x\n", dwErr);
  475. hr = HRESULT_FROM_WIN32 (dwErr);
  476. }
  477. _TRACE (-1, L"Leaving EnumerateDacl: 0x%x\n", hr);
  478. return hr;
  479. }
  480. ///////////////////////////////////////////////////////////////////////////////
  481. //
  482. // Method: EnumerateSacl ()
  483. //
  484. // Purpose: Enumerate the SACL and store it in a list
  485. //
  486. // Inputs: pSecurityDescriptor - where to get the DACL
  487. //
  488. // Outputs: The results are store in the _Module.m_SACLList
  489. //
  490. HRESULT EnumerateSacl (PSECURITY_DESCRIPTOR pSecurityDescriptor, ACE_SAMNAME_LIST& SACLList)
  491. {
  492. _TRACE (1, L"Entering EnumerateSacl\n");
  493. HRESULT hr = S_OK;
  494. ASSERT (pSecurityDescriptor);
  495. if ( !pSecurityDescriptor )
  496. return E_POINTER;
  497. PACL pSacl = 0;
  498. BOOL bSaclPresent = FALSE;
  499. BOOL bSaclDefaulted = FALSE;
  500. _TRACE (0, L"Calling GetSecurityDescriptorSacl ()\n");
  501. if ( GetSecurityDescriptorSacl (pSecurityDescriptor,
  502. &bSaclPresent, &pSacl, &bSaclDefaulted) )
  503. {
  504. _TRACE (0, L"Call to GetSecurityDescriptorSacl () succeeded.\n");
  505. if ( bSaclPresent && pSacl )
  506. {
  507. PACCESS_ALLOWED_ACE pAllowedAce;
  508. wstring strPrincipalName;
  509. wstring strFQDN;
  510. ACE_SAMNAME* pAceSAMName = 0;
  511. SID_NAME_USE sne = SidTypeUnknown;
  512. // copy the ACES
  513. for (int i = 0; i < pSacl->AceCount; i++)
  514. {
  515. if ( GetAce (pSacl, i, (void **)&pAllowedAce) )
  516. {
  517. PSID AceSid;
  518. if ( IsObjectAceType ( pAllowedAce ) )
  519. {
  520. AceSid = RtlObjectAceSid( pAllowedAce );
  521. }
  522. else
  523. {
  524. AceSid = &( ( PKNOWN_ACE )pAllowedAce )->SidStart;
  525. }
  526. hr = GetNameFromSid (AceSid, strPrincipalName, 0, sne);
  527. if ( SUCCEEDED (hr) )
  528. {
  529. pAceSAMName = new ACE_SAMNAME;
  530. if ( pAceSAMName )
  531. {
  532. pAceSAMName->m_AceType = pAllowedAce->Header.AceType;
  533. switch (pAceSAMName->m_AceType)
  534. {
  535. case SYSTEM_AUDIT_OBJECT_ACE_TYPE:
  536. pAceSAMName->m_pSystemAuditObjectAce =
  537. reinterpret_cast <PSYSTEM_AUDIT_OBJECT_ACE> (pAllowedAce);
  538. break;
  539. case SYSTEM_AUDIT_ACE_TYPE:
  540. pAceSAMName->m_pSystemAuditAce =
  541. reinterpret_cast <PSYSTEM_AUDIT_ACE> (pAllowedAce);
  542. break;
  543. default:
  544. break;
  545. }
  546. pAceSAMName->m_SAMAccountName = strPrincipalName;
  547. pAceSAMName->DebugOut ();
  548. SACLList.push_back (pAceSAMName);
  549. }
  550. else
  551. {
  552. hr = E_OUTOFMEMORY;
  553. break;
  554. }
  555. }
  556. }
  557. else
  558. {
  559. _TRACE (0, L"GetAce failed: 0x%x\n", GetLastError ());
  560. break;
  561. }
  562. }
  563. }
  564. }
  565. else
  566. {
  567. DWORD dwErr = GetLastError ();
  568. _TRACE (0, L"GetSecurityDescriptorSacl () failed: 0x%x\n", dwErr);
  569. hr = HRESULT_FROM_WIN32 (dwErr);
  570. }
  571. _TRACE (-1, L"Leaving EnumerateSacl: 0x%x\n", hr);
  572. return hr;
  573. }
  574. ///////////////////////////////////////////////////////////////////////////////
  575. //
  576. // Method: PrintEffectivePermissions ()
  577. //
  578. // Purpose: Print the permissions effective on the object
  579. //
  580. HRESULT PrintEffectivePermissions ()
  581. {
  582. HRESULT hr = S_OK;
  583. ACE_SAMNAME_LIST::iterator itr = _Module.m_DACLList.begin ();
  584. wstring str;
  585. ACE_SAMNAME* pAceSAMName = 0;
  586. if ( !_Module.DoTabDelimitedOutput () )
  587. {
  588. LoadFromResource (str, IDS_PERMISSIONS_EFFECTIVE);
  589. MyWprintf (str.c_str ());
  590. }
  591. for (itr = _Module.m_DACLList.begin(); itr != _Module.m_DACLList.end(); itr++)
  592. {
  593. pAceSAMName = *itr;
  594. if ( !(pAceSAMName->m_pAllowedAce->Header.AceFlags & INHERIT_ONLY_ACE) )
  595. {
  596. switch (pAceSAMName->m_AceType)
  597. {
  598. case ACCESS_ALLOWED_ACE_TYPE:
  599. case ACCESS_ALLOWED_OBJECT_ACE_TYPE:
  600. hr = EnumeratePermissions (pAceSAMName, P_ALLOW, P_THIS_OBJECT, L"");
  601. break;
  602. case ACCESS_DENIED_OBJECT_ACE_TYPE:
  603. case ACCESS_DENIED_ACE_TYPE:
  604. hr = EnumeratePermissions (pAceSAMName, P_DENY, P_THIS_OBJECT, L"");
  605. break;
  606. default:
  607. break;
  608. }
  609. }
  610. }
  611. return hr;
  612. }
  613. ///////////////////////////////////////////////////////////////////////////////
  614. //
  615. // Method: EnumeratePermissions ()
  616. //
  617. // Purpose: Print all the permissions contained on the passed in ACE
  618. //
  619. // Inputs: pAceSAMName - structure containing the ACE whose permissions we wish
  620. // to print
  621. //
  622. // ptype - allow, deny, succes, failure, success and failure
  623. //
  624. HRESULT EnumeratePermissions (ACE_SAMNAME* pAceSAMName, P_TYPE ptype, P_WHO pWho, PCWSTR pwszClassName)
  625. {
  626. HRESULT hr = S_OK;
  627. if ( pAceSAMName )
  628. {
  629. hr = PrintPermission (pAceSAMName,
  630. ACTRL_DS_CREATE_CHILD,
  631. ptype,
  632. IDS_CREATE_ALL_SUBOBJECTS,
  633. IDS_CREATE_CLASS_OBJECTS,
  634. pWho,
  635. pwszClassName);
  636. if ( SUCCEEDED (hr) )
  637. {
  638. hr = PrintPermission (pAceSAMName,
  639. ACTRL_DS_DELETE_CHILD,
  640. ptype,
  641. IDS_DELETE_ALL_SUBOBJECTS,
  642. IDS_DELETE_CLASS_OBJECTS,
  643. pWho,
  644. pwszClassName);
  645. }
  646. if ( SUCCEEDED (hr) )
  647. {
  648. hr = PrintPermission (pAceSAMName,
  649. ACTRL_DS_READ_PROP,
  650. ptype,
  651. IDS_READ_ALL_PROPERTIES,
  652. IDS_READ_PROPERTY_PROPERTY,
  653. pWho,
  654. pwszClassName);
  655. }
  656. if ( SUCCEEDED (hr) )
  657. {
  658. hr = PrintPermission (pAceSAMName,
  659. ACTRL_DS_WRITE_PROP,
  660. ptype,
  661. IDS_WRITE_ALL_PROPERTIES,
  662. IDS_WRITE_PROPERTY_PROPERTY,
  663. pWho,
  664. pwszClassName);
  665. }
  666. if ( SUCCEEDED (hr) )
  667. {
  668. hr = PrintPermission (pAceSAMName,
  669. ACTRL_DS_LIST,
  670. ptype,
  671. IDS_LIST_CONTENTS, false,
  672. pWho,
  673. pwszClassName);
  674. }
  675. if ( SUCCEEDED (hr) )
  676. {
  677. hr = PrintPermission (pAceSAMName,
  678. ACTRL_DS_LIST_OBJECT,
  679. ptype,
  680. IDS_LIST_OBJECT, false,
  681. pWho,
  682. pwszClassName);
  683. }
  684. if ( SUCCEEDED (hr) )
  685. {
  686. hr = PrintPermission (pAceSAMName,
  687. ACTRL_DS_CONTROL_ACCESS,
  688. ptype,
  689. IDS_ALL_CONTROL_ACCESSES,
  690. IDS_CONTROL_ACCESS_DISPLAY_NAME,
  691. pWho,
  692. pwszClassName);
  693. }
  694. if ( SUCCEEDED (hr) )
  695. {
  696. hr = PrintPermission (pAceSAMName,
  697. ACTRL_DELETE,
  698. ptype,
  699. IDS_DELETE_THIS_OBJECT, false,
  700. pWho,
  701. pwszClassName);
  702. }
  703. if ( SUCCEEDED (hr) )
  704. {
  705. hr = PrintPermission (pAceSAMName,
  706. ACTRL_READ_CONTROL,
  707. ptype,
  708. IDS_READ_PERMISSIONS, false,
  709. pWho,
  710. pwszClassName);
  711. }
  712. if ( SUCCEEDED (hr) )
  713. {
  714. hr = PrintPermission (pAceSAMName,
  715. ACTRL_CHANGE_ACCESS,
  716. ptype,
  717. IDS_MODIFY_PERMISSIONS, false,
  718. pWho,
  719. pwszClassName);
  720. }
  721. if ( SUCCEEDED (hr) )
  722. {
  723. hr = PrintPermission (pAceSAMName,
  724. ACTRL_CHANGE_OWNER,
  725. ptype,
  726. IDS_TAKE_CHANGE_OWNERSHIP, false,
  727. pWho,
  728. pwszClassName);
  729. }
  730. if ( SUCCEEDED (hr) )
  731. {
  732. hr = PrintPermission (pAceSAMName,
  733. ACTRL_DS_SELF,
  734. ptype,
  735. IDS_MODIFY_MEMBERSHIP, false,
  736. pWho,
  737. pwszClassName);
  738. }
  739. }
  740. else
  741. hr = E_POINTER;
  742. return hr;
  743. }
  744. ///////////////////////////////////////////////////////////////////////////////
  745. //
  746. // Method: PrintPermission ()
  747. //
  748. // Purpose: Print an OBJECT_ACE_TYPE permission
  749. //
  750. // Inputs: pAceSAMName - structure containing the ACE whose permission we wish
  751. // to print
  752. //
  753. // accessMask - the specific permission we're looking to print
  754. //
  755. // bAllow - whether the permission is allowed or denied
  756. //
  757. // strIDAll - string to print if permission applies to all object
  758. // classes
  759. //
  760. // strIDParam - string print if permission applies to a specific
  761. // object class
  762. //
  763. HRESULT PrintPermission (ACE_SAMNAME* pAceSAMName,
  764. ACCESS_MASK accessMask,
  765. P_TYPE ptype,
  766. int strIDAll,
  767. int strIDParam,
  768. P_WHO pWho,
  769. PCWSTR pwszClassName)
  770. {
  771. HRESULT hr = S_OK;
  772. if ( pAceSAMName )
  773. {
  774. wstring str;
  775. wstring strPermission;
  776. if ( pAceSAMName->m_pAllowedAce->Mask & accessMask )
  777. {
  778. bool bIsAudit = false;
  779. switch (pAceSAMName->m_AceType )
  780. {
  781. case ACCESS_ALLOWED_OBJECT_ACE_TYPE:
  782. if ( (pAceSAMName->m_pAllowedObjectAce->Flags & ACE_OBJECT_TYPE_PRESENT) &&
  783. !::IsEqualGUID (pAceSAMName->m_pAllowedObjectAce->ObjectType, NULLGUID) )
  784. {
  785. wstring strClass;
  786. if ( ACTRL_DS_CONTROL_ACCESS == accessMask )
  787. {
  788. hr = GetControlDisplayName (
  789. pAceSAMName->m_pAllowedObjectAce->ObjectType, strClass);
  790. }
  791. else
  792. {
  793. _Module.GetClassFromGUID (
  794. pAceSAMName->m_pAllowedObjectAce->ObjectType,
  795. strClass);
  796. }
  797. FormatMessage (strPermission, strIDParam,
  798. strClass.c_str ());
  799. }
  800. else
  801. {
  802. LoadFromResource (strPermission, strIDAll);
  803. }
  804. break;
  805. case ACCESS_DENIED_OBJECT_ACE_TYPE:
  806. if ( (pAceSAMName->m_pDeniedObjectAce->Flags & ACE_OBJECT_TYPE_PRESENT) &&
  807. !::IsEqualGUID (pAceSAMName->m_pDeniedObjectAce->ObjectType, NULLGUID) )
  808. {
  809. wstring strClass;
  810. if ( ACTRL_DS_CONTROL_ACCESS == accessMask )
  811. {
  812. hr = GetControlDisplayName (
  813. pAceSAMName->m_pDeniedObjectAce->ObjectType, strClass);
  814. }
  815. else
  816. {
  817. _Module.GetClassFromGUID (
  818. pAceSAMName->m_pDeniedObjectAce->ObjectType,
  819. strClass);
  820. }
  821. FormatMessage (strPermission,strIDParam,
  822. strClass.c_str ());
  823. }
  824. else
  825. {
  826. LoadFromResource (strPermission, strIDAll);
  827. }
  828. break;
  829. case SYSTEM_AUDIT_OBJECT_ACE_TYPE:
  830. if ( (pAceSAMName->m_pSystemAuditObjectAce->Flags & ACE_OBJECT_TYPE_PRESENT) &&
  831. !::IsEqualGUID (pAceSAMName->m_pSystemAuditObjectAce->ObjectType, NULLGUID) )
  832. {
  833. wstring strClass;
  834. if ( ACTRL_DS_CONTROL_ACCESS == accessMask )
  835. {
  836. hr = GetControlDisplayName (
  837. pAceSAMName->m_pSystemAuditObjectAce->ObjectType, strClass);
  838. }
  839. else
  840. {
  841. _Module.GetClassFromGUID (
  842. pAceSAMName->m_pSystemAuditObjectAce->ObjectType,
  843. strClass);
  844. }
  845. FormatMessage (strPermission,strIDParam,
  846. strClass.c_str ());
  847. }
  848. else
  849. {
  850. LoadFromResource (strPermission, strIDAll);
  851. }
  852. bIsAudit = true;
  853. break;
  854. case SYSTEM_AUDIT_ACE_TYPE:
  855. bIsAudit = true;
  856. // fall through
  857. case ACCESS_ALLOWED_ACE_TYPE:
  858. case ACCESS_DENIED_ACE_TYPE:
  859. default:
  860. LoadFromResource (strPermission, strIDAll);
  861. break;
  862. }
  863. int strid = 0;
  864. switch (ptype)
  865. {
  866. case P_ALLOW:
  867. if ( _Module.DoTabDelimitedOutput () )
  868. strid = IDS_ALLOW_CDO;
  869. else
  870. strid = IDS_ALLOW;
  871. break;
  872. case P_DENY:
  873. if ( _Module.DoTabDelimitedOutput () )
  874. strid = IDS_DENY_CDO;
  875. else
  876. strid = IDS_DENY;
  877. break;
  878. case P_SUCCESS:
  879. if ( _Module.DoTabDelimitedOutput () )
  880. strid = IDS_SUCCESS_CDO;
  881. else
  882. strid = IDS_SUCCESS;
  883. break;
  884. case P_FAILURE:
  885. if ( _Module.DoTabDelimitedOutput () )
  886. strid = IDS_FAILURE_CDO;
  887. else
  888. strid = IDS_FAILURE;
  889. break;
  890. case P_SUCCESS_AND_FAILURE:
  891. if ( _Module.DoTabDelimitedOutput () )
  892. strid = IDS_SUCCESS_AND_FAILURE_CDO;
  893. else
  894. strid = IDS_SUCCESS_AND_FAILURE;
  895. break;
  896. default:
  897. return E_UNEXPECTED;
  898. }
  899. if ( _Module.DoTabDelimitedOutput () )
  900. {
  901. wstring strObject;
  902. switch ( pWho )
  903. {
  904. case P_THIS_OBJECT:
  905. LoadFromResource (strObject, IDS_THIS_OBJECT);
  906. break;
  907. case P_ALL_OBJECTS:
  908. LoadFromResource (strObject, IDS_ALL_SUBOBJECTS);
  909. break;
  910. case P_CLASS_OBJECT:
  911. FormatMessage (strObject, IDS_CLASS_OBJECT, pwszClassName);
  912. break;
  913. }
  914. FormatMessage (str, strid,
  915. strObject.c_str (),
  916. pAceSAMName->m_SAMAccountName.c_str (),
  917. strPermission.c_str ());
  918. }
  919. else
  920. {
  921. FormatMessage (str, strid,
  922. pAceSAMName->m_SAMAccountName.c_str (),
  923. strPermission.c_str ());
  924. }
  925. MyWprintf (str.c_str ());
  926. if ( pAceSAMName->m_pAllowedAce->Header.AceFlags & INHERITED_ACE &&
  927. (P_ALLOW == ptype || P_DENY == ptype) )
  928. {
  929. hr = PrintInheritedPermissionFromDN (pAceSAMName, accessMask, bIsAudit);
  930. }
  931. if ( _Module.DoTabDelimitedOutput () )
  932. MyWprintf (L"\n");
  933. }
  934. }
  935. else
  936. hr = E_POINTER;
  937. return hr;
  938. }
  939. ///////////////////////////////////////////////////////////////////////////////
  940. //
  941. // Method: PrintPermission ()
  942. //
  943. // Purpose: Print a non-OBJECT_ACE_TYPE permission
  944. //
  945. // Inputs: pAceSAMName - structure containing the ACE whose permission we wish
  946. // to print
  947. //
  948. // accessMask - the specific permission we're looking to print
  949. //
  950. // bAllow - whether the permission is allowed or denied
  951. //
  952. // strID - string to print
  953. //
  954. HRESULT PrintPermission (ACE_SAMNAME* pAceSAMName,
  955. ACCESS_MASK accessMask,
  956. P_TYPE ptype,
  957. int strID,
  958. bool bIsAudit,
  959. P_WHO pWho,
  960. PCWSTR pwszClassName)
  961. {
  962. HRESULT hr = S_OK;
  963. if ( pAceSAMName )
  964. {
  965. wstring str;
  966. wstring strPermission;
  967. if ( pAceSAMName->m_pAllowedAce->Mask & accessMask )
  968. {
  969. LoadFromResource (strPermission, strID);
  970. int id = 0;
  971. switch (ptype)
  972. {
  973. case P_ALLOW:
  974. if ( _Module.DoTabDelimitedOutput () )
  975. id = IDS_ALLOW_CDO;
  976. else
  977. id = IDS_ALLOW;
  978. break;
  979. case P_DENY:
  980. if ( _Module.DoTabDelimitedOutput () )
  981. id = IDS_DENY_CDO;
  982. else
  983. id = IDS_DENY;
  984. break;
  985. case P_SUCCESS:
  986. if ( _Module.DoTabDelimitedOutput () )
  987. id = IDS_SUCCESS_CDO;
  988. else
  989. id = IDS_SUCCESS;
  990. break;
  991. case P_FAILURE:
  992. if ( _Module.DoTabDelimitedOutput () )
  993. id = IDS_FAILURE_CDO;
  994. else
  995. id = IDS_FAILURE;
  996. break;
  997. case P_SUCCESS_AND_FAILURE:
  998. if ( _Module.DoTabDelimitedOutput () )
  999. id = IDS_SUCCESS_AND_FAILURE_CDO;
  1000. else
  1001. id = IDS_SUCCESS_AND_FAILURE;
  1002. break;
  1003. default:
  1004. return E_UNEXPECTED;
  1005. }
  1006. if ( _Module.DoTabDelimitedOutput () )
  1007. {
  1008. wstring strObject;
  1009. switch ( pWho )
  1010. {
  1011. case P_THIS_OBJECT:
  1012. LoadFromResource (strObject, IDS_THIS_OBJECT);
  1013. break;
  1014. case P_ALL_OBJECTS:
  1015. LoadFromResource (strObject, IDS_ALL_SUBOBJECTS);
  1016. break;
  1017. case P_CLASS_OBJECT:
  1018. FormatMessage (strObject, IDS_CLASS_OBJECT, pwszClassName);
  1019. break;
  1020. }
  1021. FormatMessage (str, id,
  1022. strObject.c_str (),
  1023. pAceSAMName->m_SAMAccountName.c_str (),
  1024. strPermission.c_str ());
  1025. }
  1026. else
  1027. {
  1028. FormatMessage (str, id,
  1029. pAceSAMName->m_SAMAccountName.c_str (),
  1030. strPermission.c_str ());
  1031. }
  1032. MyWprintf (str.c_str ());
  1033. if ( pAceSAMName->m_pAllowedAce->Header.AceFlags & INHERITED_ACE )
  1034. {
  1035. hr = PrintInheritedPermissionFromDN (pAceSAMName, accessMask, bIsAudit);
  1036. }
  1037. if ( _Module.DoTabDelimitedOutput () )
  1038. MyWprintf (L"\n");
  1039. }
  1040. }
  1041. else
  1042. hr = E_POINTER;
  1043. return hr;
  1044. }
  1045. ///////////////////////////////////////////////////////////////////////////////
  1046. //
  1047. // GetParentObjectDNWithSameACE ()
  1048. //
  1049. // This function is called recursively to try to find an ACE that matches the ACE
  1050. // contained in pAceSAMName somewhere in the parent container of the object pointed to
  1051. // by pPathName. Each iteration strips a leaf element off pPathName, gets its
  1052. // security descriptor and searches the Dacl list for the ACE. If a match is
  1053. // found, taking into account the INHERITED_ACE flag, we look to see if the
  1054. // INHERITED_ACE flag is set. If so, we call GetParentObjectDNWithSameACE () again.
  1055. // If not, we get the return the object name at this level.
  1056. //
  1057. HRESULT GetParentObjectDNWithSameACE (
  1058. IN ACE_SAMNAME* pAceSAMName,
  1059. IN IADsPathname* pPathName,
  1060. IN ACCESS_MASK accessMask,
  1061. OUT wstring& strParentDN,
  1062. bool bIsAudit)
  1063. {
  1064. _TRACE (1, L"Entering GetParentObjectDNWithSameACE\n");
  1065. HRESULT hr = pPathName->RemoveLeafElement ();
  1066. if ( SUCCEEDED (hr) )
  1067. {
  1068. BSTR bstrFullPath = 0;
  1069. hr = pPathName->Retrieve(ADS_FORMAT_X500, &bstrFullPath);
  1070. if ( SUCCEEDED (hr) )
  1071. {
  1072. if ( !wcscmp (bstrFullPath, L"LDAP://") )
  1073. return S_FALSE;
  1074. PSECURITY_DESCRIPTOR pSecurityDescriptor = 0;
  1075. bool bFound = false;
  1076. // Check to see if we already have this object's Security Descriptor
  1077. list<SAMNAME_SD*>::iterator sdItr = _Module.m_listOfParentSDs.begin ();
  1078. SAMNAME_SD* pCurrSAMNameSD = 0;
  1079. for (; sdItr != _Module.m_listOfParentSDs.end (); sdItr++)
  1080. {
  1081. pCurrSAMNameSD = *sdItr;
  1082. if ( !pCurrSAMNameSD->m_upn.compare (bstrFullPath) )
  1083. {
  1084. pSecurityDescriptor = pCurrSAMNameSD->m_pSecurityDescriptor;
  1085. bFound = true; // Note - pSecurityDescriptor could be NULL
  1086. // this is expected.
  1087. break;
  1088. }
  1089. }
  1090. // If we don't already have the SD for this object, get it and cache it.
  1091. if ( !bFound )
  1092. {
  1093. wstring objectDN (bstrFullPath);
  1094. hr = GetSecurityDescriptor (objectDN, &pSecurityDescriptor);
  1095. if ( SUCCEEDED (hr) )
  1096. {
  1097. pCurrSAMNameSD = new SAMNAME_SD (bstrFullPath, pSecurityDescriptor);
  1098. if ( pCurrSAMNameSD )
  1099. {
  1100. if ( pSecurityDescriptor )
  1101. {
  1102. hr = EnumerateDacl (pSecurityDescriptor, pCurrSAMNameSD->m_DACLList, false);
  1103. if ( SUCCEEDED (hr) )
  1104. hr = EnumerateSacl (pSecurityDescriptor, pCurrSAMNameSD->m_SACLList);
  1105. }
  1106. _Module.m_listOfParentSDs.push_back (pCurrSAMNameSD);
  1107. }
  1108. else
  1109. hr = E_OUTOFMEMORY;
  1110. }
  1111. }
  1112. if ( SUCCEEDED (hr) && pCurrSAMNameSD )
  1113. {
  1114. ACE_SAMNAME_LIST* pList = 0;
  1115. if ( bIsAudit )
  1116. pList = &pCurrSAMNameSD->m_SACLList;
  1117. else
  1118. pList = &pCurrSAMNameSD->m_DACLList;
  1119. ACE_SAMNAME_LIST::iterator itr = pList->begin ();
  1120. ACE_SAMNAME* pCurrSAMName = 0;
  1121. for (; itr != pList->end(); itr++)
  1122. {
  1123. pCurrSAMName = *itr;
  1124. if ( pCurrSAMName->IsEquivalent (*pAceSAMName,
  1125. accessMask) )
  1126. {
  1127. if ( pCurrSAMName->m_pAllowedAce->Header.AceFlags & INHERITED_ACE )
  1128. {
  1129. hr = GetParentObjectDNWithSameACE (
  1130. pAceSAMName,
  1131. pPathName,
  1132. accessMask,
  1133. strParentDN,
  1134. bIsAudit);
  1135. }
  1136. else
  1137. {
  1138. BSTR bstrDN = 0;
  1139. hr = pPathName->Retrieve(ADS_FORMAT_X500_DN, &bstrDN);
  1140. if ( SUCCEEDED (hr) )
  1141. {
  1142. strParentDN = bstrDN;
  1143. }
  1144. else
  1145. {
  1146. _TRACE (0, L"IADsPathname->Retrieve (): 0x%x\n", hr);
  1147. }
  1148. }
  1149. break;
  1150. }
  1151. }
  1152. }
  1153. SysFreeString (bstrFullPath);
  1154. }
  1155. else
  1156. {
  1157. _TRACE (0, L"IADsPathname->Retrieve (): 0x%x\n", hr);
  1158. }
  1159. }
  1160. if ( SUCCEEDED (hr) && S_FALSE != hr && !strParentDN.length () )
  1161. {
  1162. hr = GetParentObjectDNWithSameACE (pAceSAMName, pPathName, accessMask,
  1163. strParentDN, bIsAudit);
  1164. }
  1165. _TRACE (-1, L"Leaving GetParentObjectDNWithSameACE: 0x%x\n", hr);
  1166. return hr;
  1167. }
  1168. ///////////////////////////////////////////////////////////////////////////////
  1169. //
  1170. // Method: PrintInheritedPermissionFromDN ()
  1171. //
  1172. // Purpose: Print a message indicating that a permission is inherited from
  1173. // another object plus that object's DN
  1174. //
  1175. // Inputs: pAceSAMName - structure containing the ACE whose permission we wish
  1176. // to print
  1177. //
  1178. // accessMask - the specific permission we're looking to print
  1179. //
  1180. HRESULT PrintInheritedPermissionFromDN (ACE_SAMNAME* pAceSAMName, ACCESS_MASK accessMask, bool bIsAudit)
  1181. {
  1182. _TRACE (1, L"Entering PrintInheritedPermissionFromDN\n");
  1183. HRESULT hr = S_OK;
  1184. if ( pAceSAMName )
  1185. {
  1186. CComPtr<IADsPathname> spPathname;
  1187. //
  1188. // Constructing the directory paths
  1189. //
  1190. hr = CoCreateInstance(
  1191. CLSID_Pathname,
  1192. NULL,
  1193. CLSCTX_ALL,
  1194. IID_IADsPathname,
  1195. (void**)&spPathname);
  1196. if ( SUCCEEDED (hr) )
  1197. {
  1198. ASSERT (!!spPathname);
  1199. hr = spPathname->Set (CComBSTR (ACLDIAG_LDAP), ADS_SETTYPE_PROVIDER);
  1200. if ( SUCCEEDED (hr) )
  1201. {
  1202. hr = spPathname->Set (CComBSTR (_Module.GetObjectDN ().c_str ()),
  1203. ADS_SETTYPE_DN);
  1204. if ( SUCCEEDED (hr) )
  1205. {
  1206. wstring str;
  1207. wstring strParentDN;
  1208. hr = GetParentObjectDNWithSameACE (pAceSAMName,
  1209. spPathname, accessMask, strParentDN, bIsAudit);
  1210. if ( SUCCEEDED (hr) )
  1211. {
  1212. if ( !strParentDN.length () )
  1213. {
  1214. if ( _Module.DoTabDelimitedOutput () )
  1215. {
  1216. LoadFromResource (str,
  1217. IDS_GENERATED_INHERITED_PERMISSION_CDO);
  1218. }
  1219. else
  1220. {
  1221. LoadFromResource (str,
  1222. IDS_GENERATED_INHERITED_PERMISSION);
  1223. }
  1224. }
  1225. else
  1226. {
  1227. if ( _Module.DoTabDelimitedOutput () )
  1228. {
  1229. FormatMessage (str, IDS_INHERITED_PERMISSION_CDO,
  1230. strParentDN.c_str ());
  1231. }
  1232. else
  1233. {
  1234. FormatMessage (str, IDS_INHERITED_PERMISSION,
  1235. strParentDN.c_str ());
  1236. }
  1237. }
  1238. MyWprintf (str.c_str ());
  1239. }
  1240. }
  1241. }
  1242. }
  1243. }
  1244. else
  1245. hr = E_POINTER;
  1246. _TRACE (-1, L"Leaving PrintInheritedPermissionFromDN: 0x%x\n", hr);
  1247. return hr;
  1248. }
  1249. ///////////////////////////////////////////////////////////////////////////////
  1250. //
  1251. // Method: PrintInheritedPermissions ()
  1252. //
  1253. // Purpose: Print permissions that are inherited by subobjects
  1254. //
  1255. HRESULT PrintInheritedPermissions ()
  1256. {
  1257. _TRACE (1, L"Entering PrintInheritedPermissions\n");
  1258. HRESULT hr = S_OK;
  1259. ACE_SAMNAME_LIST::iterator aceItr = _Module.m_DACLList.begin ();
  1260. wstring str;
  1261. ACE_SAMNAME* pAceSAMName = 0;
  1262. list<GUID*> guidList;
  1263. if ( !_Module.DoTabDelimitedOutput () )
  1264. {
  1265. LoadFromResource (str, IDS_PERMISSIONS_INHERITED_BY_SUBOBJECTS);
  1266. MyWprintf (str.c_str ());
  1267. LoadFromResource (str, IDS_INHERIT_TO_ALL_SUBOBJECTS);
  1268. MyWprintf (str.c_str ());
  1269. }
  1270. // Second iteration: Each ACE which has CONTAINER_INHERIT is inherited to
  1271. // sub-objects.
  1272. // Several "subiterations" are done to categorize inherit ACEs to the
  1273. // subobject type they apply.
  1274. // First subiteration is for ACEs which are not object type or have
  1275. // InheritedObjectType = NULL. These apply to "All Subobjects". We'll gather
  1276. // the GUIDs of the InheritedObjectType's which are not NULL at this point to
  1277. // use in the subsequent iterations.
  1278. // Subsequent subiterations are for each unique InheritedObjectType
  1279. // present in the DACL.
  1280. for (aceItr = _Module.m_DACLList.begin(); aceItr != _Module.m_DACLList.end(); aceItr++)
  1281. {
  1282. pAceSAMName = *aceItr;
  1283. if ( pAceSAMName->m_pAllowedAce->Header.AceFlags & CONTAINER_INHERIT_ACE )
  1284. {
  1285. switch (pAceSAMName->m_AceType)
  1286. {
  1287. case ACCESS_ALLOWED_ACE_TYPE:
  1288. hr = EnumeratePermissions (pAceSAMName, P_ALLOW, P_ALL_OBJECTS, L"");
  1289. break;
  1290. case ACCESS_DENIED_ACE_TYPE:
  1291. hr = EnumeratePermissions (pAceSAMName, P_DENY, P_ALL_OBJECTS, L"");
  1292. break;
  1293. case ACCESS_DENIED_OBJECT_ACE_TYPE:
  1294. if ( !(pAceSAMName->m_pDeniedObjectAce->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT) &&
  1295. ::IsEqualGUID (pAceSAMName->m_pDeniedObjectAce->ObjectType, NULLGUID) )
  1296. {
  1297. hr = EnumeratePermissions (pAceSAMName, P_DENY, P_ALL_OBJECTS, L"");
  1298. }
  1299. else
  1300. {
  1301. AddToInheritedObjectTypeGUIDList (guidList,
  1302. &(pAceSAMName->m_pDeniedObjectAce->ObjectType));
  1303. }
  1304. break;
  1305. case ACCESS_ALLOWED_OBJECT_ACE_TYPE:
  1306. if ( !(pAceSAMName->m_pAllowedObjectAce->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT) &&
  1307. ::IsEqualGUID (pAceSAMName->m_pAllowedObjectAce->ObjectType, NULLGUID) )
  1308. {
  1309. hr = EnumeratePermissions (pAceSAMName, P_ALLOW, P_ALL_OBJECTS, L"");
  1310. }
  1311. else
  1312. {
  1313. AddToInheritedObjectTypeGUIDList (guidList,
  1314. &(pAceSAMName->m_pAllowedObjectAce->ObjectType));
  1315. }
  1316. break;
  1317. default:
  1318. break;
  1319. }
  1320. }
  1321. }
  1322. GUID* pGuid = 0;
  1323. wstring strClassName;
  1324. GUID_TYPE guidType;
  1325. for (list<GUID*>::iterator guidItr = guidList.begin ();
  1326. guidItr != guidList.end ();
  1327. guidItr++)
  1328. {
  1329. pGuid = *guidItr;
  1330. hr = _Module.GetClassFromGUID (*pGuid, strClassName, &guidType);
  1331. if ( SUCCEEDED (hr) && GUID_TYPE_CLASS == guidType )
  1332. {
  1333. if ( !_Module.DoTabDelimitedOutput () )
  1334. {
  1335. FormatMessage (str, IDS_INHERIT_TO_X_OBJECTS_ONLY, strClassName.c_str ());
  1336. MyWprintf (str.c_str ());
  1337. }
  1338. for (aceItr = _Module.m_DACLList.begin(); aceItr != _Module.m_DACLList.end(); aceItr++)
  1339. {
  1340. pAceSAMName = *aceItr;
  1341. if ( pAceSAMName->m_pAllowedAce->Header.AceFlags & CONTAINER_INHERIT_ACE )
  1342. {
  1343. switch (pAceSAMName->m_AceType)
  1344. {
  1345. case ACCESS_ALLOWED_OBJECT_ACE_TYPE:
  1346. if ( ::IsEqualGUID (pAceSAMName->m_pAllowedObjectAce->ObjectType,
  1347. *pGuid) )
  1348. {
  1349. hr = EnumeratePermissions (pAceSAMName, P_ALLOW,
  1350. P_CLASS_OBJECT, strClassName.c_str ());
  1351. }
  1352. break;
  1353. case ACCESS_DENIED_OBJECT_ACE_TYPE:
  1354. if ( ::IsEqualGUID (pAceSAMName->m_pDeniedObjectAce->ObjectType,
  1355. *pGuid) )
  1356. {
  1357. hr = EnumeratePermissions (pAceSAMName, P_DENY,
  1358. P_CLASS_OBJECT, strClassName.c_str ());
  1359. }
  1360. break;
  1361. default:
  1362. break;
  1363. }
  1364. }
  1365. }
  1366. }
  1367. }
  1368. _TRACE (1, L"Entering PrintInheritedPermissions: 0x%x\n", hr);
  1369. return hr;
  1370. }
  1371. ///////////////////////////////////////////////////////////////////////////////
  1372. //
  1373. // Method: AddToInheritedObjectTypeGUIDList ()
  1374. //
  1375. // Purpose: Add a GUID to a list. Ensure that it is unique.
  1376. //
  1377. // Inputs: guidList - list to which the GUID should be added
  1378. //
  1379. // pGuid - GUID to add to the list
  1380. //
  1381. void AddToInheritedObjectTypeGUIDList (list<GUID*>& guidList, GUID* pGuid)
  1382. {
  1383. // The guidList should only contain unique GUIDs. Verify that the one we
  1384. // wish to add is not already in the list.
  1385. if ( pGuid )
  1386. {
  1387. bool bFound = false;
  1388. GUID* pCurrGuid = 0;
  1389. list<GUID*>::iterator guidItr = guidList.begin();
  1390. for (; guidItr != guidList.end(); guidItr++)
  1391. {
  1392. pCurrGuid = *guidItr;
  1393. if ( ::IsEqualGUID (*pCurrGuid, *pGuid) )
  1394. {
  1395. bFound = true;
  1396. break;
  1397. }
  1398. }
  1399. if ( !bFound )
  1400. {
  1401. guidList.push_back (pGuid);
  1402. }
  1403. }
  1404. }
  1405. ///////////////////////////////////////////////////////////////////////////////
  1406. //
  1407. // Method: PrintAuditingInformation ()
  1408. //
  1409. // Purpose: Print auditing information from the SACL
  1410. //
  1411. HRESULT PrintAuditingInformation ()
  1412. {
  1413. _TRACE (1, L"Entering PrintAuditingInformation\n");
  1414. HRESULT hr = S_OK;
  1415. wstring str;
  1416. MyWprintf (L"\n\n");
  1417. SECURITY_DESCRIPTOR_CONTROL control;
  1418. DWORD dwRevision = 0;
  1419. if ( GetSecurityDescriptorControl (
  1420. _Module.m_pSecurityDescriptor,
  1421. &control,
  1422. &dwRevision) )
  1423. {
  1424. if ( !_Module.DoTabDelimitedOutput () && (control & SE_SACL_PROTECTED) )
  1425. {
  1426. wstring str;
  1427. LoadFromResource (str, IDS_CONFIG_NO_INHERIT);
  1428. MyWprintf (str.c_str ());
  1429. }
  1430. }
  1431. else
  1432. {
  1433. _TRACE (0, L"GetSecurityDescriptorControl () failed: 0x%x\n", GetLastError ());
  1434. }
  1435. hr = PrintEffectiveAuditing ();
  1436. if ( SUCCEEDED (hr) )
  1437. hr = PrintInheritedAuditing ();
  1438. _TRACE (-1, L"Leaving PrintAuditingInformation: 0x%x\n", hr);
  1439. return hr;
  1440. }
  1441. HRESULT PrintEffectiveAuditing ()
  1442. {
  1443. _TRACE (1, L"Entering PrintEffectiveAuditing\n");
  1444. HRESULT hr = S_OK;
  1445. ACE_SAMNAME_LIST::iterator itr = _Module.m_SACLList.begin ();
  1446. wstring str;
  1447. ACE_SAMNAME* pAceSAMName = 0;
  1448. if ( !_Module.DoTabDelimitedOutput () )
  1449. {
  1450. LoadFromResource (str, IDS_AUDITING_EFFECTIVE_ON_THIS_OBJECT);
  1451. MyWprintf (str.c_str ());
  1452. }
  1453. for (itr = _Module.m_SACLList.begin(); itr != _Module.m_SACLList.end(); itr++)
  1454. {
  1455. pAceSAMName = *itr;
  1456. if ( !(pAceSAMName->m_pAllowedAce->Header.AceFlags & INHERIT_ONLY_ACE) )
  1457. {
  1458. switch (pAceSAMName->m_AceType)
  1459. {
  1460. case SYSTEM_AUDIT_OBJECT_ACE_TYPE:
  1461. case SYSTEM_AUDIT_ACE_TYPE:
  1462. hr = EnumerateAudits (pAceSAMName, P_THIS_OBJECT, L"");
  1463. break;
  1464. default:
  1465. break;
  1466. }
  1467. }
  1468. }
  1469. _TRACE (-1, L"Leaving PrintEffectiveAuditing: 0x%x\n", hr);
  1470. return hr;
  1471. }
  1472. HRESULT EnumerateAudits (ACE_SAMNAME* pAceSAMName, P_WHO pWho, PCWSTR pwszClassName)
  1473. {
  1474. _TRACE (1, L"Entering EnumerateAudits\n");
  1475. HRESULT hr = S_OK;
  1476. P_TYPE ptype = P_UNASSIGNED;
  1477. BYTE byBoth = SUCCESSFUL_ACCESS_ACE_FLAG | FAILED_ACCESS_ACE_FLAG;
  1478. if ( (pAceSAMName->m_pAllowedAce->Header.AceFlags & byBoth) == byBoth )
  1479. {
  1480. ptype = P_SUCCESS_AND_FAILURE;
  1481. }
  1482. else if ( pAceSAMName->m_pAllowedAce->Header.AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG )
  1483. ptype = P_SUCCESS;
  1484. else if ( pAceSAMName->m_pAllowedAce->Header.AceFlags & FAILED_ACCESS_ACE_FLAG )
  1485. ptype = P_FAILURE;
  1486. else
  1487. return E_UNEXPECTED;
  1488. if ( pAceSAMName )
  1489. {
  1490. hr = PrintPermission (pAceSAMName,
  1491. ACTRL_DS_CREATE_CHILD,
  1492. ptype,
  1493. IDS_CREATE_ALL_SUBOBJECTS,
  1494. IDS_CREATE_CLASS_OBJECTS,
  1495. pWho,
  1496. pwszClassName);
  1497. if ( SUCCEEDED (hr) )
  1498. {
  1499. hr = PrintPermission (pAceSAMName,
  1500. ACTRL_DS_DELETE_CHILD,
  1501. ptype,
  1502. IDS_DELETE_ALL_SUBOBJECTS,
  1503. IDS_DELETE_CLASS_OBJECTS,
  1504. pWho,
  1505. pwszClassName);
  1506. }
  1507. if ( SUCCEEDED (hr) )
  1508. {
  1509. hr = PrintPermission (pAceSAMName,
  1510. ACTRL_DS_READ_PROP,
  1511. ptype,
  1512. IDS_READ_ALL_PROPERTIES,
  1513. IDS_READ_PROPERTY_PROPERTY,
  1514. pWho,
  1515. pwszClassName);
  1516. }
  1517. if ( SUCCEEDED (hr) )
  1518. {
  1519. hr = PrintPermission (pAceSAMName,
  1520. ACTRL_DS_WRITE_PROP,
  1521. ptype,
  1522. IDS_WRITE_ALL_PROPERTIES,
  1523. IDS_WRITE_PROPERTY_PROPERTY,
  1524. pWho,
  1525. pwszClassName);
  1526. }
  1527. if ( SUCCEEDED (hr) )
  1528. {
  1529. hr = PrintPermission (pAceSAMName,
  1530. ACTRL_DS_LIST,
  1531. ptype,
  1532. IDS_LIST_CONTENTS, true,
  1533. pWho,
  1534. pwszClassName);
  1535. }
  1536. if ( SUCCEEDED (hr) )
  1537. {
  1538. hr = PrintPermission (pAceSAMName,
  1539. ACTRL_DS_LIST_OBJECT,
  1540. ptype,
  1541. IDS_LIST_OBJECT, true,
  1542. pWho,
  1543. pwszClassName);
  1544. }
  1545. if ( SUCCEEDED (hr) )
  1546. {
  1547. if ( pAceSAMName->m_pAllowedAce->Mask & ACTRL_DS_CONTROL_ACCESS )
  1548. hr = PrintPermission (pAceSAMName,
  1549. ACTRL_DS_CONTROL_ACCESS,
  1550. ptype,
  1551. IDS_ALL_CONTROL_ACCESSES,
  1552. IDS_CONTROL_ACCESS_DISPLAY_NAME,
  1553. pWho,
  1554. pwszClassName);
  1555. }
  1556. if ( SUCCEEDED (hr) )
  1557. {
  1558. hr = PrintPermission (pAceSAMName,
  1559. ACTRL_DELETE,
  1560. ptype,
  1561. IDS_DELETE_THIS_OBJECT, true,
  1562. pWho,
  1563. pwszClassName);
  1564. }
  1565. if ( SUCCEEDED (hr) )
  1566. {
  1567. hr = PrintPermission (pAceSAMName,
  1568. ACTRL_READ_CONTROL,
  1569. ptype,
  1570. IDS_READ_PERMISSIONS, true,
  1571. pWho,
  1572. pwszClassName);
  1573. }
  1574. if ( SUCCEEDED (hr) )
  1575. {
  1576. hr = PrintPermission (pAceSAMName,
  1577. ACTRL_CHANGE_ACCESS,
  1578. ptype,
  1579. IDS_MODIFY_PERMISSIONS, true,
  1580. pWho,
  1581. pwszClassName);
  1582. }
  1583. if ( SUCCEEDED (hr) )
  1584. {
  1585. hr = PrintPermission (pAceSAMName,
  1586. ACTRL_CHANGE_OWNER,
  1587. ptype,
  1588. IDS_TAKE_CHANGE_OWNERSHIP, true,
  1589. pWho,
  1590. pwszClassName);
  1591. }
  1592. if ( SUCCEEDED (hr) )
  1593. {
  1594. hr = PrintPermission (pAceSAMName,
  1595. ACTRL_DS_SELF,
  1596. ptype,
  1597. IDS_MODIFY_MEMBERSHIP, true,
  1598. pWho,
  1599. pwszClassName);
  1600. }
  1601. }
  1602. else
  1603. hr = E_POINTER;
  1604. _TRACE (-1, L"Leaving EnumerateAudits: 0x%x\n", hr);
  1605. return hr;
  1606. }
  1607. ///////////////////////////////////////////////////////////////////////////////
  1608. //
  1609. // Method: PrintInheritedAuditing ()
  1610. //
  1611. // Purpose: Print audits that are inherited to subobjects
  1612. //
  1613. HRESULT PrintInheritedAuditing ()
  1614. {
  1615. _TRACE (1, L"Entering PrintInheritedAuditing\n");
  1616. HRESULT hr = S_OK;
  1617. ACE_SAMNAME_LIST::iterator aceItr = _Module.m_SACLList.begin ();
  1618. wstring str;
  1619. ACE_SAMNAME* pAceSAMName = 0;
  1620. list<GUID*> guidList;
  1621. if ( !_Module.DoTabDelimitedOutput () )
  1622. {
  1623. LoadFromResource (str, IDS_AUDITING_INHERITED_TO_SUBOBJECTS);
  1624. MyWprintf (str.c_str ());
  1625. LoadFromResource (str, IDS_INHERIT_TO_ALL_SUBOBJECTS);
  1626. MyWprintf (str.c_str ());
  1627. }
  1628. // Second iteration: Each ACE which has CONTAINER_INHERIT is inherited to
  1629. // sub-objects.
  1630. // Several "subiterations" are done to categorize inherit ACEs to the
  1631. // subobject type they apply.
  1632. // First subiteration is for ACEs which are not object type or have
  1633. // InheritedObjectType = NULL. These apply to "All Subobjects". We'll gather
  1634. // the GUIDs of the InheritedObjectType's which are not NULL at this point to
  1635. // use in the subsequent iterations.
  1636. // Subsequent subiterations are for each unique InheritedObjectType
  1637. // present in the DACL.
  1638. for (aceItr = _Module.m_SACLList.begin(); aceItr != _Module.m_SACLList.end(); aceItr++)
  1639. {
  1640. pAceSAMName = *aceItr;
  1641. if ( pAceSAMName->m_pAllowedAce->Header.AceFlags & CONTAINER_INHERIT_ACE )
  1642. {
  1643. switch (pAceSAMName->m_AceType)
  1644. {
  1645. case SYSTEM_AUDIT_ACE_TYPE:
  1646. hr = EnumerateAudits (pAceSAMName, P_ALL_OBJECTS, L"");
  1647. break;
  1648. case SYSTEM_AUDIT_OBJECT_ACE_TYPE:
  1649. if ( !(pAceSAMName->m_pSystemAuditObjectAce->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT) &&
  1650. ::IsEqualGUID (pAceSAMName->m_pSystemAuditObjectAce->ObjectType, NULLGUID) )
  1651. {
  1652. hr = EnumerateAudits (pAceSAMName, P_ALL_OBJECTS, L"");
  1653. }
  1654. else
  1655. {
  1656. AddToInheritedObjectTypeGUIDList (guidList,
  1657. &(pAceSAMName->m_pSystemAuditObjectAce->ObjectType));
  1658. }
  1659. break;
  1660. default:
  1661. break;
  1662. }
  1663. }
  1664. }
  1665. GUID* pGuid = 0;
  1666. wstring strClassName;
  1667. for (list<GUID*>::iterator guidItr = guidList.begin ();
  1668. guidItr != guidList.end ();
  1669. guidItr++)
  1670. {
  1671. pGuid = *guidItr;
  1672. hr = _Module.GetClassFromGUID (*pGuid, strClassName);
  1673. if ( SUCCEEDED (hr) )
  1674. {
  1675. if ( !_Module.DoTabDelimitedOutput () )
  1676. {
  1677. FormatMessage (str, IDS_INHERIT_TO_X_OBJECTS_ONLY, strClassName.c_str ());
  1678. MyWprintf (str.c_str ());
  1679. }
  1680. for (aceItr = _Module.m_SACLList.begin(); aceItr != _Module.m_SACLList.end(); aceItr++)
  1681. {
  1682. pAceSAMName = *aceItr;
  1683. if ( pAceSAMName->m_pAllowedAce->Header.AceFlags & CONTAINER_INHERIT_ACE )
  1684. {
  1685. switch (pAceSAMName->m_AceType)
  1686. {
  1687. case SYSTEM_AUDIT_OBJECT_ACE_TYPE:
  1688. if ( ::IsEqualGUID (pAceSAMName->m_pSystemAuditObjectAce->ObjectType,
  1689. *pGuid) )
  1690. {
  1691. hr = EnumerateAudits (pAceSAMName, P_CLASS_OBJECT, strClassName.c_str ());
  1692. }
  1693. break;
  1694. case SYSTEM_AUDIT_ACE_TYPE:
  1695. default:
  1696. break;
  1697. }
  1698. }
  1699. }
  1700. }
  1701. }
  1702. _TRACE (-1, L"Leaving PrintInheritedAuditing: 0x%x\n", hr);
  1703. return hr;
  1704. }
  1705. HRESULT GetControlDisplayName (REFGUID guid, wstring& strDisplayName)
  1706. {
  1707. HRESULT hr = S_OK;
  1708. wstring strGUID;
  1709. hr = wstringFromGUID (strGUID, guid);
  1710. if ( SUCCEEDED (hr) )
  1711. {
  1712. // strip braces from GUID
  1713. wstring strRightsGUID (strGUID.substr (1, strGUID.length () - 2));
  1714. hr = GetControlDisplayName (strRightsGUID, strDisplayName);
  1715. }
  1716. else
  1717. hr = E_INVALIDARG;
  1718. return hr;
  1719. }
  1720. // TODO: Optimize this by searching for all controls and putting them in an
  1721. // array like the classes and attributes
  1722. HRESULT GetControlDisplayName (const wstring strGuid, wstring& strDisplayName)
  1723. {
  1724. HRESULT hr = S_OK;
  1725. CComPtr<IADsPathname> spPathname;
  1726. //
  1727. // Constructing the directory paths
  1728. //
  1729. hr = CoCreateInstance(
  1730. CLSID_Pathname,
  1731. NULL,
  1732. CLSCTX_ALL,
  1733. IID_PPV_ARG (IADsPathname, &spPathname));
  1734. if ( SUCCEEDED (hr) )
  1735. {
  1736. ASSERT (!!spPathname);
  1737. hr = spPathname->Set(CComBSTR (ACLDIAG_LDAP), ADS_SETTYPE_PROVIDER);
  1738. if ( SUCCEEDED (hr) )
  1739. {
  1740. //
  1741. // Open the root DSE object
  1742. //
  1743. hr = spPathname->AddLeafElement(CComBSTR (ACLDIAG_ROOTDSE));
  1744. if ( SUCCEEDED (hr) )
  1745. {
  1746. BSTR bstrFullPath = 0;
  1747. hr = spPathname->Retrieve(ADS_FORMAT_X500, &bstrFullPath);
  1748. if ( SUCCEEDED (hr) )
  1749. {
  1750. CComPtr<IADs> spRootDSEObject;
  1751. VARIANT varNamingContext;
  1752. hr = ADsOpenObjectHelper(bstrFullPath,IID_IADs, 0,(void**)&spRootDSEObject);
  1753. if ( SUCCEEDED (hr) )
  1754. {
  1755. ASSERT (!!spRootDSEObject);
  1756. //
  1757. // Get the configuration naming context from the root DSE
  1758. //
  1759. hr = spRootDSEObject->Get(CComBSTR (ACLDIAG_CONFIG_NAMING_CONTEXT),
  1760. &varNamingContext);
  1761. if ( SUCCEEDED (hr) )
  1762. {
  1763. if ( V_VT (&varNamingContext) == VT_BSTR )
  1764. {
  1765. hr = spPathname->Set(V_BSTR(&varNamingContext),
  1766. ADS_SETTYPE_DN);
  1767. if ( SUCCEEDED (hr) )
  1768. {
  1769. hr = spPathname->AddLeafElement (CComBSTR (L"CN=Extended-Rights"));
  1770. if ( SUCCEEDED (hr) )
  1771. {
  1772. BSTR bstrFullPath1 = 0;
  1773. hr = spPathname->Retrieve(ADS_FORMAT_X500, &bstrFullPath1);
  1774. if ( SUCCEEDED (hr) )
  1775. {
  1776. CComPtr<IDirectoryObject> spExtRightsContObj;
  1777. hr = ADsOpenObjectHelper (bstrFullPath1,
  1778. IID_IDirectoryObject,
  1779. 0,
  1780. (void**)&spExtRightsContObj);
  1781. if ( SUCCEEDED (hr) )
  1782. {
  1783. CComPtr<IDirectorySearch> spDsSearch;
  1784. hr = spExtRightsContObj->QueryInterface (IID_PPV_ARG(IDirectorySearch, &spDsSearch));
  1785. if ( SUCCEEDED (hr) )
  1786. {
  1787. ASSERT (!!spDsSearch);
  1788. ADS_SEARCHPREF_INFO pSearchPref[2];
  1789. DWORD dwNumPref = 2;
  1790. pSearchPref[0].dwSearchPref = ADS_SEARCHPREF_SEARCH_SCOPE;
  1791. pSearchPref[0].vValue.dwType = ADSTYPE_INTEGER;
  1792. pSearchPref[0].vValue.Integer = ADS_SCOPE_ONELEVEL;
  1793. pSearchPref[1].dwSearchPref = ADS_SEARCHPREF_CHASE_REFERRALS;
  1794. pSearchPref[1].vValue.dwType = ADSTYPE_INTEGER;
  1795. pSearchPref[1].vValue.Integer = ADS_CHASE_REFERRALS_NEVER;
  1796. hr = spDsSearch->SetSearchPreference(
  1797. pSearchPref,
  1798. dwNumPref
  1799. );
  1800. if ( SUCCEEDED (hr) )
  1801. {
  1802. PWSTR rgszAttrList[] = {L"displayName"};
  1803. ADS_SEARCH_HANDLE hSearchHandle = 0;
  1804. DWORD dwNumAttributes = 1;
  1805. wstring strQuery;
  1806. ADS_SEARCH_COLUMN Column;
  1807. Column.pszAttrName = 0;
  1808. FormatMessage (strQuery,
  1809. L"rightsGUID=%1",
  1810. strGuid.c_str ());
  1811. hr = spDsSearch->ExecuteSearch(
  1812. const_cast <LPWSTR>(strQuery.c_str ()),
  1813. rgszAttrList,
  1814. dwNumAttributes,
  1815. &hSearchHandle
  1816. );
  1817. if ( SUCCEEDED (hr) )
  1818. {
  1819. hr = spDsSearch->GetFirstRow (hSearchHandle);
  1820. if ( SUCCEEDED (hr) )
  1821. {
  1822. while (hr != S_ADS_NOMORE_ROWS )
  1823. {
  1824. //
  1825. // Getting current row's information
  1826. //
  1827. hr = spDsSearch->GetColumn(
  1828. hSearchHandle,
  1829. rgszAttrList[0],
  1830. &Column
  1831. );
  1832. if ( SUCCEEDED (hr) )
  1833. {
  1834. strDisplayName = Column.pADsValues->CaseIgnoreString;
  1835. spDsSearch->FreeColumn (&Column);
  1836. Column.pszAttrName = NULL;
  1837. break;
  1838. }
  1839. else if ( hr != E_ADS_COLUMN_NOT_SET )
  1840. {
  1841. break;
  1842. }
  1843. else
  1844. {
  1845. _TRACE (0, L"IDirectorySearch::GetColumn (): 0x%x\n", hr);
  1846. }
  1847. }
  1848. }
  1849. else
  1850. {
  1851. _TRACE (0, L"IDirectorySearch::GetFirstRow (): 0x%x\n", hr);
  1852. }
  1853. if (Column.pszAttrName)
  1854. {
  1855. spDsSearch->FreeColumn(&Column);
  1856. }
  1857. spDsSearch->CloseSearchHandle(hSearchHandle);
  1858. }
  1859. else
  1860. {
  1861. _TRACE (0, L"IDirectorySearch::ExecuteSearch (): 0x%x\n", hr);
  1862. hr = S_OK;
  1863. }
  1864. }
  1865. else
  1866. {
  1867. _TRACE (0, L"IDirectorySearch::SetSearchPreference (): 0x%x\n", hr);
  1868. }
  1869. }
  1870. else
  1871. {
  1872. _TRACE (0, L"IDirectoryObject::QueryInterface (IDirectorySearch): 0x%x\n", hr);
  1873. }
  1874. }
  1875. else
  1876. {
  1877. _TRACE (0, L"ADsOpenObjectHelper (%s): 0x%x\n", bstrFullPath1, hr);
  1878. }
  1879. }
  1880. else
  1881. {
  1882. _TRACE (0, L"IADsPathname->Retrieve (): 0x%x\n", hr);
  1883. }
  1884. }
  1885. else
  1886. {
  1887. _TRACE (0, L"IADsPathname->AddLeafElement (%s): 0x%x\n",
  1888. L"CN=Extended-Rights", hr);
  1889. }
  1890. }
  1891. else
  1892. {
  1893. _TRACE (0, L"IADsPathname->Set (): 0x%x\n", V_BSTR(&varNamingContext), hr);
  1894. }
  1895. }
  1896. else
  1897. hr = E_FAIL;
  1898. }
  1899. else
  1900. {
  1901. _TRACE (0, L"IADs->Get (%s): 0x%x\n", ACLDIAG_CONFIG_NAMING_CONTEXT, hr);
  1902. }
  1903. }
  1904. else
  1905. {
  1906. _TRACE (0, L"ADsOpenObjectHelper (%s): 0x%x\n", bstrFullPath, hr);
  1907. }
  1908. }
  1909. else
  1910. {
  1911. _TRACE (0, L"IADsPathname->Retrieve (): 0x%x\n", hr);
  1912. }
  1913. }
  1914. else
  1915. {
  1916. _TRACE (0, L"IADsPathname->AddLeafElement (%s): 0x%x\n", ACLDIAG_ROOTDSE, hr);
  1917. }
  1918. }
  1919. else
  1920. {
  1921. _TRACE (0, L"IADsPathname->Set (%s): 0x%x\n", ACLDIAG_LDAP, hr);
  1922. }
  1923. }
  1924. else
  1925. {
  1926. _TRACE (0, L"CoCreateInstance(CLSID_Pathname): 0x%x\n", hr);
  1927. }
  1928. return hr;
  1929. }