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.

2104 lines
72 KiB

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