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.

2134 lines
55 KiB

  1. /*****************************************************************************/
  2. /* Copyright (c) 1999-2002 Microsoft Corporation, All Rights Reserved /
  3. /*****************************************************************************/
  4. /*
  5. * CAccessEntry.cpp - implementation file for CAccessEntry class.
  6. *
  7. * Created: 12-14-1997 by Sanjeev Surati
  8. * (based on classes from Windows NT Security by Nik Okuntseff)
  9. */
  10. #include "precomp.h"
  11. #include <assertbreak.h>
  12. #include "AccessEntryList.h"
  13. #include "DACL.h"
  14. #include "SACL.h"
  15. #include "securitydescriptor.h"
  16. #include "AdvApi32Api.h"
  17. #include <accctrl.h>
  18. #include "wbemnetapi32.h"
  19. #include "SecUtils.h"
  20. #ifndef MAXDWORD
  21. #define MAXDWORD MAXULONG
  22. #endif
  23. // We're using STL, so this is a requirement
  24. using namespace std;
  25. ///////////////////////////////////////////////////////////////////
  26. //
  27. // Function: CAccessEntryList::CAccessEntryList
  28. //
  29. // Default class constructor.
  30. //
  31. // Inputs:
  32. // None.
  33. //
  34. // Outputs:
  35. // None.
  36. //
  37. // Returns:
  38. // None.
  39. //
  40. // Comments:
  41. //
  42. ///////////////////////////////////////////////////////////////////
  43. CAccessEntryList::CAccessEntryList( void )
  44. : m_ACL()
  45. {
  46. }
  47. ///////////////////////////////////////////////////////////////////
  48. //
  49. // Function: CAccessEntryList::CAccessEntryList
  50. //
  51. // Class constructor.
  52. //
  53. // Inputs:
  54. // PACL pWin32ACL - ACL to initialize from.
  55. //
  56. // Outputs:
  57. // None.
  58. //
  59. // Returns:
  60. // None.
  61. //
  62. // Comments:
  63. //
  64. ///////////////////////////////////////////////////////////////////
  65. CAccessEntryList::CAccessEntryList( PACL pWin32ACL, bool fLookup /* = true */ )
  66. : m_ACL()
  67. {
  68. InitFromWin32ACL( pWin32ACL, ALL_ACE_TYPES, fLookup );
  69. }
  70. ///////////////////////////////////////////////////////////////////
  71. //
  72. // Function: CAccessEntryList::~CAccessEntryList
  73. //
  74. // Class destructor
  75. //
  76. // Inputs:
  77. // None.
  78. //
  79. // Outputs:
  80. // None.
  81. //
  82. // Returns:
  83. // None.
  84. //
  85. // Comments:
  86. //
  87. ///////////////////////////////////////////////////////////////////
  88. CAccessEntryList::~CAccessEntryList( void )
  89. {
  90. Clear();
  91. }
  92. ///////////////////////////////////////////////////////////////////
  93. //
  94. // Function: CAccessEntryList::Add
  95. //
  96. // Adds a CAccessEntry* pointer to the front of the list.
  97. //
  98. // Inputs:
  99. // CAccessEntry* pACE - ACE to add to the list
  100. //
  101. // Outputs:
  102. // None.
  103. //
  104. // Returns:
  105. // None.
  106. //
  107. // Comments:
  108. //
  109. ///////////////////////////////////////////////////////////////////
  110. void CAccessEntryList::Add( CAccessEntry* pACE )
  111. {
  112. // Add to the front of the list
  113. m_ACL.push_front( pACE );
  114. }
  115. ///////////////////////////////////////////////////////////////////
  116. //
  117. // Function: CAccessEntryList::Append
  118. //
  119. // Appends a CAccessEntry* pointer to the end of the list.
  120. //
  121. // Inputs:
  122. // CAccessEntry* pACE - ACE to add to the list
  123. //
  124. // Outputs:
  125. // None.
  126. //
  127. // Returns:
  128. // None.
  129. //
  130. // Comments:
  131. //
  132. ///////////////////////////////////////////////////////////////////
  133. void CAccessEntryList::Append( CAccessEntry* pACE )
  134. {
  135. // Add to the end of the list
  136. m_ACL.push_back( pACE );
  137. }
  138. ///////////////////////////////////////////////////////////////////
  139. //
  140. // Function: CAccessEntryList::Find
  141. //
  142. // Locates a CAccessEntry* pointer in our list
  143. //
  144. // Inputs:
  145. // CAccessEntry* pACE - ACE to find in the list
  146. //
  147. // Outputs:
  148. // None.
  149. //
  150. // Returns:
  151. // ACLIter iterator pointing at entry we found
  152. //
  153. // Comments:
  154. //
  155. ///////////////////////////////////////////////////////////////////
  156. ACLIter CAccessEntryList::Find( CAccessEntry* pACE )
  157. {
  158. for ( ACLIter acliter = m_ACL.begin();
  159. acliter != m_ACL.end()
  160. && *acliter != pACE;
  161. acliter++ );
  162. return acliter;
  163. }
  164. ///////////////////////////////////////////////////////////////////
  165. //
  166. // Function: CAccessEntryList::Find
  167. //
  168. // Locates a CAccessEntry* pointer in our list whose contents match
  169. // the supplied ACE.
  170. //
  171. // Inputs:
  172. // const CAccessEntry& ace - ACE to find in the list
  173. //
  174. // Outputs:
  175. // None.
  176. //
  177. // Returns:
  178. // CAccessEntry* pointer to matchiong ace.
  179. //
  180. // Comments:
  181. //
  182. ///////////////////////////////////////////////////////////////////
  183. CAccessEntry* CAccessEntryList::Find( const CAccessEntry& ace )
  184. {
  185. for ( ACLIter acliter = m_ACL.begin();
  186. acliter != m_ACL.end()
  187. && !( *(*acliter) == ace );
  188. acliter++ );
  189. return ( acliter == m_ACL.end() ? NULL : *acliter );
  190. }
  191. ///////////////////////////////////////////////////////////////////
  192. //
  193. // Function: CAccessEntryList::Find
  194. //
  195. // Locates a CAccessEntry* pointer in our list based on PSID,
  196. // bACEType and bACEFlags.
  197. //
  198. // Inputs:
  199. // PSID psid - SID
  200. // BYTE bACEType - ACE Type to find.
  201. // BYTE bACEFlags - ACE flags.
  202. //
  203. // Outputs:
  204. // None.
  205. //
  206. // Returns:
  207. // CAccessEntry* Pointer to object we found.
  208. //
  209. // Comments:
  210. //
  211. ///////////////////////////////////////////////////////////////////
  212. CAccessEntry* CAccessEntryList::Find( PSID psid, BYTE bACEType, BYTE bACEFlags, GUID *pguidObjGuid, GUID *pguidInhObjGuid, DWORD dwAccessMask, bool fLookup /* = true */ )
  213. {
  214. // Traverse the list until we find an element matching the psid, ACE Type and
  215. // ACE Flags, or run out of elements.
  216. for(ACLIter acliter = m_ACL.begin(); acliter != m_ACL.end(); acliter++)
  217. {
  218. CAccessEntry tempace(psid, bACEType, bACEFlags, pguidObjGuid, pguidInhObjGuid, dwAccessMask, NULL, fLookup);
  219. CAccessEntry *ptempace2 = *acliter;
  220. if(*ptempace2 == tempace) break;
  221. }
  222. return ( acliter == m_ACL.end() ? NULL : *acliter );
  223. }
  224. ///////////////////////////////////////////////////////////////////
  225. //
  226. // Function: CAccessEntryList::AddNoDup
  227. //
  228. // Locates a CAccessEntry* pointer in our list based on PSID,
  229. // bACEType and bACEFlags. If one is found, we replace the
  230. // values of that object. Otherwise, we add the new object to
  231. // the list.
  232. //
  233. // Inputs:
  234. // PSID psid - SID
  235. // BYTE bACEType - ACE Type to find.
  236. // BYTE bACEFlags - ACE flags.
  237. // DWORD dwMask - Access Mask.
  238. // BOOL fMerge - Merge flag.
  239. //
  240. // Outputs:
  241. // None.
  242. //
  243. // Returns:
  244. // BOOL success/failure.
  245. //
  246. // Comments:
  247. // If fMerge is TRUE, if we find a value, we or the
  248. // access masks together, otherwise, we replace
  249. // the mask.
  250. //
  251. ///////////////////////////////////////////////////////////////////
  252. bool CAccessEntryList::AddNoDup( PSID psid, BYTE bACEType, BYTE bACEFlags, DWORD dwMask, GUID *pguidObjGuid,
  253. GUID *pguidInhObjGuid, bool fMerge /* = false */ )
  254. {
  255. bool fReturn = true;
  256. // Look for a duplicate entry in our linked list. This means that
  257. // the sid, the ACEType and the flags are the same. If this happens,
  258. // we merge the entries by ORing in the new mask or overwrite (based
  259. // on the merge mask). Otherwise, we should add the new entry to the
  260. // front of the list
  261. CAccessEntry* pAccessEntry = Find( psid, bACEType, bACEFlags, pguidObjGuid, pguidInhObjGuid, dwMask );
  262. if ( NULL == pAccessEntry )
  263. {
  264. // NOT found, so we need to add a new entry.
  265. try
  266. {
  267. pAccessEntry = new CAccessEntry( psid,
  268. bACEType,
  269. bACEFlags,
  270. pguidObjGuid,
  271. pguidInhObjGuid,
  272. dwMask );
  273. if ( NULL != pAccessEntry )
  274. {
  275. Add( pAccessEntry );
  276. }
  277. else
  278. {
  279. fReturn = false;
  280. }
  281. }
  282. catch(...)
  283. {
  284. if(pAccessEntry != NULL)
  285. {
  286. delete pAccessEntry;
  287. pAccessEntry = NULL;
  288. }
  289. throw;
  290. }
  291. }
  292. else
  293. {
  294. if ( fMerge )
  295. {
  296. // OR in any new values.
  297. pAccessEntry->MergeAccessMask( dwMask );
  298. }
  299. else
  300. {
  301. pAccessEntry->SetAccessMask( dwMask );
  302. }
  303. }
  304. return fReturn;
  305. }
  306. ///////////////////////////////////////////////////////////////////
  307. //
  308. // Function: CAccessEntryList::AppendNoDup
  309. //
  310. // Locates a CAccessEntry* pointer in our list based on PSID,
  311. // bACEType and bACEFlags. If one is found, we replace the
  312. // values of that object. Otherwise, we append the new object to
  313. // the list.
  314. //
  315. // Inputs:
  316. // PSID psid - SID
  317. // BYTE bACEType - ACE Type to find.
  318. // BYTE bACEFlags - ACE flags.
  319. // DWORD dwMask - Access Mask.
  320. // BOOL fMerge - Merge flag.
  321. //
  322. // Outputs:
  323. // None.
  324. //
  325. // Returns:
  326. // BOOL success/failure.
  327. //
  328. // Comments:
  329. // If fMerge is TRUE, if we find a value, we or the
  330. // access masks together, otherwise, we replace
  331. // the mask.
  332. //
  333. ///////////////////////////////////////////////////////////////////
  334. bool CAccessEntryList::AppendNoDup( PSID psid,
  335. BYTE bACEType,
  336. BYTE bACEFlags,
  337. DWORD dwMask,
  338. GUID *pguidObjGuid,
  339. GUID *pguidInhObjGuid,
  340. bool fMerge /* = false */ )
  341. {
  342. bool fReturn = true;
  343. // Look for a duplicate entry in our linked list. This means that
  344. // the sid, the ACEType and the flags are the same. If this happens,
  345. // we merge the entries by ORing in the new mask or overwrite (based
  346. // on the merge mask). Otherwise, we should add the new entry to the
  347. // end of the list
  348. CAccessEntry* pAccessEntry = Find( psid, bACEType, bACEFlags, pguidObjGuid, pguidInhObjGuid, dwMask );
  349. if ( NULL == pAccessEntry )
  350. {
  351. // NOT found, so we need to append a new entry.
  352. try
  353. {
  354. pAccessEntry = new CAccessEntry( psid,
  355. bACEType,
  356. bACEFlags,
  357. pguidObjGuid,
  358. pguidInhObjGuid,
  359. dwMask );
  360. if ( NULL != pAccessEntry )
  361. {
  362. Append( pAccessEntry );
  363. }
  364. else
  365. {
  366. fReturn = false;
  367. }
  368. }
  369. catch(...)
  370. {
  371. if(pAccessEntry != NULL)
  372. {
  373. delete pAccessEntry;
  374. pAccessEntry = NULL;
  375. }
  376. throw;
  377. }
  378. }
  379. else
  380. {
  381. if ( fMerge )
  382. {
  383. // OR in any new values.
  384. pAccessEntry->MergeAccessMask( dwMask );
  385. }
  386. else
  387. {
  388. pAccessEntry->SetAccessMask( dwMask );
  389. }
  390. }
  391. return fReturn;
  392. }
  393. ///////////////////////////////////////////////////////////////////
  394. //
  395. // Function: CAccessEntryList::AppendNoDup
  396. //
  397. // Locates a CAccessEntry* pointer in our list based on PSID,
  398. // bACEType and bACEFlags. If one is found, we replace the
  399. // values of that object. Otherwise, we append the new object to
  400. // the list.
  401. //
  402. // Inputs:
  403. // PSID psid - SID
  404. // BYTE bACEType - ACE Type to find.
  405. // BYTE bACEFlags - ACE flags.
  406. // DWORD dwMask - Access Mask.
  407. // BOOL fMerge - Merge flag.
  408. //
  409. // Outputs:
  410. // None.
  411. //
  412. // Returns:
  413. // BOOL success/failure.
  414. //
  415. // Comments:
  416. // If fMerge is TRUE, if we find a value, we or the
  417. // access masks together, otherwise, we replace
  418. // the mask.
  419. //
  420. ///////////////////////////////////////////////////////////////////
  421. bool CAccessEntryList::AppendNoDup( PSID psid,
  422. BYTE bACEType,
  423. BYTE bACEFlags,
  424. DWORD dwMask,
  425. GUID *pguidObjGuid,
  426. GUID *pguidInhObjGuid,
  427. bool fMerge,
  428. bool fLookup )
  429. {
  430. bool fReturn = true;
  431. // Look for a duplicate entry in our linked list. This means that
  432. // the sid, the ACEType and the flags are the same. If this happens,
  433. // we merge the entries by ORing in the new mask or overwrite (based
  434. // on the merge mask). Otherwise, we should add the new entry to the
  435. // end of the list
  436. CAccessEntry* pAccessEntry = Find( psid, bACEType, bACEFlags, pguidObjGuid, pguidInhObjGuid, dwMask, fLookup );
  437. if ( NULL == pAccessEntry )
  438. {
  439. // NOT found, so we need to append a new entry.
  440. try
  441. {
  442. pAccessEntry = new CAccessEntry( psid,
  443. bACEType,
  444. bACEFlags,
  445. pguidObjGuid,
  446. pguidInhObjGuid,
  447. dwMask,
  448. NULL,
  449. fLookup );
  450. if ( NULL != pAccessEntry )
  451. {
  452. Append( pAccessEntry );
  453. }
  454. else
  455. {
  456. fReturn = false;
  457. }
  458. }
  459. catch(...)
  460. {
  461. if(pAccessEntry != NULL)
  462. {
  463. delete pAccessEntry;
  464. pAccessEntry = NULL;
  465. }
  466. throw;
  467. }
  468. }
  469. else
  470. {
  471. if ( fMerge )
  472. {
  473. // OR in any new values.
  474. pAccessEntry->MergeAccessMask( dwMask );
  475. }
  476. else
  477. {
  478. pAccessEntry->SetAccessMask( dwMask );
  479. }
  480. }
  481. return fReturn;
  482. }
  483. ///////////////////////////////////////////////////////////////////
  484. //
  485. // Function: CAccessEntryList::Remove
  486. //
  487. // Removes the specified pointer from our list.
  488. //
  489. // Inputs:
  490. // CAccessEntry* pACE - ACE to remove.
  491. //
  492. // Outputs:
  493. // None.
  494. //
  495. // Returns:
  496. // None.
  497. //
  498. // Comments:
  499. //
  500. // We DO NOT free the pointer.
  501. //
  502. ///////////////////////////////////////////////////////////////////
  503. void CAccessEntryList::Remove( CAccessEntry* pACE )
  504. {
  505. ACLIter acliter = Find( pACE );
  506. if ( acliter != m_ACL.end() )
  507. {
  508. m_ACL.erase( acliter );
  509. }
  510. }
  511. ///////////////////////////////////////////////////////////////////
  512. //
  513. // Function: CAccessEntryList::Clear
  514. //
  515. // Clears and empties out the list. Frees the pointers as they
  516. // are located.
  517. //
  518. // Inputs:
  519. // None.
  520. //
  521. // Outputs:
  522. // None.
  523. //
  524. // Returns:
  525. // None.
  526. //
  527. // Comments:
  528. //
  529. ///////////////////////////////////////////////////////////////////
  530. void CAccessEntryList::Clear( void )
  531. {
  532. // Delete all list entries and then clear out the list.
  533. for ( ACLIter acliter = m_ACL.begin();
  534. acliter != m_ACL.end();
  535. acliter++ )
  536. {
  537. delete *acliter;
  538. }
  539. m_ACL.erase( m_ACL.begin(), m_ACL.end() );
  540. }
  541. ///////////////////////////////////////////////////////////////////
  542. //
  543. // Function: CAccessEntryList::Find
  544. //
  545. // Locates an ACE in our list matching the specified criteria.
  546. //
  547. // Inputs:
  548. // const CSid& sid - SID
  549. // BYTE bACEType - ACE Type
  550. // DWORD dwAccessMask - Access Mask
  551. // BYTE bACEFlags - ACE Flags
  552. //
  553. // Outputs:
  554. // CAccessEntry& ace
  555. //
  556. // Returns:
  557. // BOOL success/failure
  558. //
  559. // Comments:
  560. //
  561. ///////////////////////////////////////////////////////////////////
  562. bool CAccessEntryList::Find( const CSid& sid,
  563. BYTE bACEType,
  564. BYTE bACEFlags,
  565. GUID *pguidObjGuid,
  566. GUID *pguidInhObjGuid,
  567. DWORD dwAccessMask,
  568. CAccessEntry& ace )
  569. {
  570. CAccessEntry tempace( sid, bACEType, bACEFlags, pguidObjGuid, pguidInhObjGuid, dwAccessMask );
  571. CAccessEntry* pACE = NULL;
  572. try
  573. {
  574. pACE = Find( tempace );
  575. if ( NULL != pACE )
  576. {
  577. ace = *pACE;
  578. }
  579. }
  580. catch(...)
  581. {
  582. if(pACE != NULL)
  583. {
  584. delete pACE;
  585. pACE = NULL;
  586. }
  587. throw;
  588. }
  589. return ( NULL != pACE );
  590. }
  591. ///////////////////////////////////////////////////////////////////
  592. //
  593. // Function: CAccessEntryList::Find
  594. //
  595. // Locates an ACE in our list matching the specified criteria.
  596. //
  597. // Inputs:
  598. // PSID psid - PSID.
  599. // BYTE bACEType - ACE Type
  600. // BYTE bACEFlags - ACE Flags
  601. //
  602. // Outputs:
  603. // CAccessEntry& ace
  604. //
  605. // Returns:
  606. // BOOL success/failure
  607. //
  608. // Comments:
  609. //
  610. ///////////////////////////////////////////////////////////////////
  611. bool CAccessEntryList::Find( PSID psid, BYTE bACEType, BYTE bACEFlags, GUID *pguidObjGuid, GUID *pguidInhObjGuid, DWORD dwAccessMask, CAccessEntry& ace )
  612. {
  613. CAccessEntry* pACE = NULL;
  614. try
  615. {
  616. CAccessEntry* pACE = Find( psid, bACEType, bACEFlags, pguidObjGuid, pguidInhObjGuid, dwAccessMask);
  617. if ( NULL != pACE )
  618. {
  619. ace = *pACE;
  620. }
  621. }
  622. catch(...)
  623. {
  624. if(pACE != NULL)
  625. {
  626. delete pACE;
  627. pACE = NULL;
  628. }
  629. throw;
  630. }
  631. return ( NULL != pACE );
  632. }
  633. ///////////////////////////////////////////////////////////////////
  634. //
  635. // Function: CAccessEntryList::Copy
  636. //
  637. // Copies list into another one. Pointers are not copied, as we
  638. // new more CAccessEntry objects using the Copy Constructor.
  639. //
  640. // Inputs:
  641. // const CAccessEntryList& ACL - ACL to copy.
  642. //
  643. // Outputs:
  644. // None.
  645. //
  646. // Returns:
  647. // None.
  648. //
  649. // Comments:
  650. //
  651. ///////////////////////////////////////////////////////////////////
  652. bool CAccessEntryList::Copy( CAccessEntryList& ACL )
  653. {
  654. // Dump out our existing entries
  655. Clear();
  656. // Now iterate our list, duping the ACEs into the ACL
  657. for ( ACLIter acliter = ACL.m_ACL.begin();
  658. acliter != ACL.m_ACL.end();
  659. acliter++ )
  660. {
  661. CAccessEntry* pACE = NULL;
  662. try
  663. {
  664. pACE = new CAccessEntry( *(*acliter) );
  665. if ( NULL != pACE )
  666. {
  667. Append( pACE );
  668. }
  669. else
  670. {
  671. break;
  672. }
  673. }
  674. catch(...)
  675. {
  676. if(pACE != NULL)
  677. {
  678. delete pACE;
  679. pACE = NULL;
  680. }
  681. throw;
  682. }
  683. }
  684. // We should be at the end of the source list
  685. return ( acliter == ACL.m_ACL.end() );
  686. }
  687. ///////////////////////////////////////////////////////////////////
  688. //
  689. // Function: CAccessEntryList::CopyACEs
  690. //
  691. // Copies list into another one. Pointers are not copied, as we
  692. // new more CAccessEntry objects using the Copy Constructor. This
  693. // function ONLY copies non-Inherited ACEs
  694. //
  695. // Inputs:
  696. // const CAccessEntryList& ACL - ACL to copy.
  697. // BYTE bACEType - ACE type to copy.
  698. //
  699. // Outputs:
  700. // None.
  701. //
  702. // Returns:
  703. // None.
  704. //
  705. // Comments:
  706. //
  707. ///////////////////////////////////////////////////////////////////
  708. bool CAccessEntryList::CopyACEs( CAccessEntryList& ACL, BYTE bACEType )
  709. {
  710. // Dump out our existing entries
  711. Clear();
  712. // Now iterate our list, duping the ACEs into the ACL
  713. for ( ACLIter acliter = ACL.m_ACL.begin();
  714. acliter != ACL.m_ACL.end();
  715. acliter++ )
  716. {
  717. // We don't want inherited ACEs
  718. if ( (*acliter)->GetACEType() == bACEType
  719. && !(*acliter)->IsInherited() )
  720. {
  721. CAccessEntry* pACE = NULL;
  722. try
  723. {
  724. pACE = new CAccessEntry( *(*acliter) );
  725. if ( NULL != pACE )
  726. {
  727. Append( pACE );
  728. }
  729. else
  730. {
  731. break;
  732. }
  733. }
  734. catch(...)
  735. {
  736. if(pACE != NULL)
  737. {
  738. delete pACE;
  739. pACE = NULL;
  740. }
  741. throw;
  742. }
  743. }
  744. }
  745. // We should be at the end of the source list
  746. return ( acliter == ACL.m_ACL.end() );
  747. }
  748. ///////////////////////////////////////////////////////////////////
  749. //
  750. // Function: CAccessEntryList::CopyInheritedACEs
  751. //
  752. // Copies list into another one. Pointers are not copied, as we
  753. // new more CAccessEntry objects using the Copy Constructor. This
  754. // function ONLY copies Inherited ACEs
  755. //
  756. // Inputs:
  757. // const CAccessEntryList& ACL - ACL to copy.
  758. // BYTE bACEType - ACE type to copy.
  759. //
  760. // Outputs:
  761. // None.
  762. //
  763. // Returns:
  764. // None.
  765. //
  766. // Comments:
  767. //
  768. ///////////////////////////////////////////////////////////////////
  769. bool CAccessEntryList::CopyInheritedACEs( CAccessEntryList& ACL, BYTE bACEType )
  770. {
  771. // Dump out our existing entries
  772. Clear();
  773. // Now iterate our list, duping the ACEs into the ACL
  774. for ( ACLIter acliter = ACL.m_ACL.begin();
  775. acliter != ACL.m_ACL.end();
  776. acliter++ )
  777. {
  778. // We want inherited ACEs
  779. if ( (*acliter)->GetACEType() == bACEType
  780. && (*acliter)->IsInherited() )
  781. {
  782. CAccessEntry* pACE = NULL;
  783. try
  784. {
  785. CAccessEntry* pACE = new CAccessEntry( *(*acliter) );
  786. if ( NULL != pACE )
  787. {
  788. Append( pACE );
  789. }
  790. else
  791. {
  792. break;
  793. }
  794. }
  795. catch(...)
  796. {
  797. if(pACE != NULL)
  798. {
  799. delete pACE;
  800. pACE = NULL;
  801. }
  802. throw;
  803. }
  804. }
  805. }
  806. // We should be at the end of the source list
  807. return ( acliter == ACL.m_ACL.end() );
  808. }
  809. ///////////////////////////////////////////////////////////////////
  810. //
  811. // Function: CAccessEntryList::CopyAllowedACEs
  812. //
  813. // Copies list into another one. Pointers are not copied, as we
  814. // new more CAccessEntry objects using the Copy Constructor. This
  815. // function ONLY copies Allowed ACEs
  816. //
  817. // Inputs:
  818. // const CAccessEntryList& ACL - ACL to copy.
  819. //
  820. // Outputs:
  821. // None.
  822. //
  823. // Returns:
  824. // None.
  825. //
  826. // Comments:
  827. //
  828. ///////////////////////////////////////////////////////////////////
  829. bool CAccessEntryList::CopyAllowedACEs( CAccessEntryList& ACL )
  830. {
  831. // Dump out our existing entries
  832. Clear();
  833. // Now iterate our list, duping the ACEs into the ACL
  834. for ( ACLIter acliter = ACL.m_ACL.begin();
  835. acliter != ACL.m_ACL.end();
  836. acliter++ )
  837. {
  838. // We want allowed ACEs
  839. if ( (*acliter)->IsAllowed() )
  840. {
  841. CAccessEntry* pACE = NULL;
  842. try
  843. {
  844. CAccessEntry* pACE = new CAccessEntry( *(*acliter) );
  845. if ( NULL != pACE )
  846. {
  847. Append( pACE );
  848. }
  849. else
  850. {
  851. break;
  852. }
  853. }
  854. catch(...)
  855. {
  856. if(pACE != NULL)
  857. {
  858. delete pACE;
  859. pACE = NULL;
  860. }
  861. throw;
  862. }
  863. }
  864. }
  865. // We should be at the end of the source list
  866. return ( acliter == ACL.m_ACL.end() );
  867. }
  868. ///////////////////////////////////////////////////////////////////
  869. //
  870. // Function: CAccessEntryList::CopyDeniedACEs
  871. //
  872. // Copies list into another one. Pointers are not copied, as we
  873. // new more CAccessEntry objects using the Copy Constructor. This
  874. // function ONLY copies Denied ACEs
  875. //
  876. // Inputs:
  877. // const CAccessEntryList& ACL - ACL to copy.
  878. // BYTE bACEType - ACE type to copy.
  879. //
  880. // Outputs:
  881. // None.
  882. //
  883. // Returns:
  884. // None.
  885. //
  886. // Comments:
  887. //
  888. ///////////////////////////////////////////////////////////////////
  889. bool CAccessEntryList::CopyDeniedACEs( CAccessEntryList& ACL )
  890. {
  891. // Dump out our existing entries
  892. Clear();
  893. // Now iterate our list, duping the ACEs into the ACL
  894. for ( ACLIter acliter = ACL.m_ACL.begin();
  895. acliter != ACL.m_ACL.end();
  896. acliter++ )
  897. {
  898. // We want denied ACEs
  899. if ( (*acliter)->IsDenied() )
  900. {
  901. CAccessEntry* pACE = NULL;
  902. try
  903. {
  904. CAccessEntry* pACE = new CAccessEntry( *(*acliter) );
  905. if ( NULL != pACE )
  906. {
  907. Append( pACE );
  908. }
  909. else
  910. {
  911. break;
  912. }
  913. }
  914. catch(...)
  915. {
  916. if(pACE != NULL)
  917. {
  918. delete pACE;
  919. pACE = NULL;
  920. }
  921. throw;
  922. }
  923. }
  924. }
  925. // We should be at the end of the source list
  926. return ( acliter == ACL.m_ACL.end() );
  927. }
  928. ///////////////////////////////////////////////////////////////////
  929. //
  930. // Function: CAccessEntryList::CopyByACEType
  931. //
  932. // Copies list into another one. Pointers are not copied, as we
  933. // new more CAccessEntry objects using the Copy Constructor. This
  934. // function ONLY copies ACEs of the specified type and inheritence.
  935. //
  936. // Inputs:
  937. // const CAccessEntryList& ACL - ACL to copy.
  938. // BYTE bACEType - ACE type to copy.
  939. //
  940. // Outputs:
  941. // None.
  942. //
  943. // Returns:
  944. // None.
  945. //
  946. // Comments:
  947. //
  948. ///////////////////////////////////////////////////////////////////
  949. bool CAccessEntryList::CopyByACEType(CAccessEntryList& ACL, BYTE bACEType, bool fInherited)
  950. {
  951. // Dump out our existing entries
  952. Clear();
  953. bool fIsInh;
  954. fInherited ? fIsInh = true : fIsInh = false;
  955. // Now iterate our list, duping the ACEs into the ACL
  956. for ( ACLIter acliter = ACL.m_ACL.begin();
  957. acliter != ACL.m_ACL.end();
  958. acliter++ )
  959. {
  960. // We want inherited ACEs
  961. if ( ( (*acliter)->GetACEType() == bACEType ) &&
  962. ( ((*acliter)->IsInherited() != 0) == fIsInh ) )
  963. {
  964. CAccessEntry* pACE = NULL;
  965. try
  966. {
  967. CAccessEntry* pACE = new CAccessEntry( *(*acliter) );
  968. if ( NULL != pACE )
  969. {
  970. Append( pACE );
  971. }
  972. else
  973. {
  974. break;
  975. }
  976. }
  977. catch(...)
  978. {
  979. if(pACE != NULL)
  980. {
  981. delete pACE;
  982. pACE = NULL;
  983. }
  984. throw;
  985. }
  986. }
  987. }
  988. // We should be at the end of the source list
  989. return ( acliter == ACL.m_ACL.end() );
  990. }
  991. ///////////////////////////////////////////////////////////////////
  992. //
  993. // Function: CAccessEntryList::AppendList
  994. //
  995. // Appends list into another one. Pointers are not copied, as we
  996. // new more CAccessEntry objects using the Copy Constructor.
  997. //
  998. // Inputs:
  999. // const CAccessEntryList& ACL - ACL to append.
  1000. //
  1001. // Outputs:
  1002. // None.
  1003. //
  1004. // Returns:
  1005. // None.
  1006. //
  1007. // Comments:
  1008. //
  1009. ///////////////////////////////////////////////////////////////////
  1010. bool CAccessEntryList::AppendList( CAccessEntryList& ACL )
  1011. {
  1012. // Now iterate our list, duping the ACEs into the ACL
  1013. for ( ACLIter acliter = ACL.m_ACL.begin();
  1014. acliter != ACL.m_ACL.end();
  1015. acliter++ )
  1016. {
  1017. CAccessEntry* pACE = NULL;
  1018. try
  1019. {
  1020. pACE = new CAccessEntry( *(*acliter) );
  1021. if ( NULL != pACE )
  1022. {
  1023. Append( pACE );
  1024. }
  1025. else
  1026. {
  1027. break;
  1028. }
  1029. }
  1030. catch(...)
  1031. {
  1032. if(pACE != NULL)
  1033. {
  1034. delete pACE;
  1035. pACE = NULL;
  1036. }
  1037. throw;
  1038. }
  1039. }
  1040. // We should be at the end of the source list
  1041. return ( acliter == ACL.m_ACL.end() );
  1042. }
  1043. ///////////////////////////////////////////////////////////////////
  1044. //
  1045. // Function: CAccessEntryList::BeginEnum
  1046. //
  1047. // Call to establish an ACLPOSIION& value for continung enumerations.
  1048. //
  1049. // Inputs:
  1050. // None.
  1051. //
  1052. // Outputs:
  1053. // ACLPOSITION& pos - Beginning position.
  1054. //
  1055. // Returns:
  1056. // BOOL Success/Failure.
  1057. //
  1058. // Comments:
  1059. //
  1060. // User MUST call EndEnum() on pos.
  1061. //
  1062. ///////////////////////////////////////////////////////////////////
  1063. bool CAccessEntryList::BeginEnum( ACLPOSITION& pos )
  1064. {
  1065. // Allocate a new iterator and stick it at the beginning
  1066. ACLIter* pACLIter = NULL;
  1067. try
  1068. {
  1069. pACLIter = new ACLIter;
  1070. }
  1071. catch(...)
  1072. {
  1073. if(pACLIter != NULL)
  1074. {
  1075. delete pACLIter;
  1076. pACLIter = NULL;
  1077. }
  1078. throw;
  1079. }
  1080. if ( NULL != pACLIter )
  1081. {
  1082. *pACLIter = m_ACL.begin();
  1083. }
  1084. pos = (ACLPOSITION) pACLIter;
  1085. return ( NULL != pACLIter );
  1086. }
  1087. ///////////////////////////////////////////////////////////////////
  1088. //
  1089. // Function: CAccessEntryList::GetNext
  1090. //
  1091. // Enumeration call using ACLPOSITION.
  1092. //
  1093. // Inputs:
  1094. // None.
  1095. //
  1096. // Outputs:
  1097. // ACLPOSITION& pos - Beginning position.
  1098. // CAccessEntry& ACE - enumed value.
  1099. //
  1100. // Returns:
  1101. // BOOL Success/Failure.
  1102. //
  1103. // Comments:
  1104. //
  1105. // Because it returns copies, this function is FOR public use.
  1106. //
  1107. ///////////////////////////////////////////////////////////////////
  1108. bool CAccessEntryList::GetNext( ACLPOSITION& pos, CAccessEntry& ACE )
  1109. {
  1110. CAccessEntry* pACE = NULL;
  1111. try
  1112. {
  1113. pACE = GetNext( pos );
  1114. }
  1115. catch(...)
  1116. {
  1117. if(pACE != NULL)
  1118. {
  1119. delete pACE;
  1120. pACE = NULL;
  1121. }
  1122. throw;
  1123. }
  1124. if ( NULL != pACE )
  1125. {
  1126. ACE = *pACE;
  1127. }
  1128. // TRUE/FALSE return based on whether we got back a pointer or not.
  1129. return ( NULL != pACE );
  1130. }
  1131. ///////////////////////////////////////////////////////////////////
  1132. //
  1133. // Function: CAccessEntryList::GetNext
  1134. //
  1135. // Enumeration call using ACLPOSITION.
  1136. //
  1137. // Inputs:
  1138. // None.
  1139. //
  1140. // Outputs:
  1141. // ACLPOSITION& pos - Beginning position.
  1142. //
  1143. // Returns:
  1144. // CAccessEntry* enumed pointer
  1145. //
  1146. // Comments:
  1147. //
  1148. // Because it returns actual pointers, DO NOT make this function
  1149. // public.
  1150. //
  1151. ///////////////////////////////////////////////////////////////////
  1152. CAccessEntry* CAccessEntryList::GetNext( ACLPOSITION& pos )
  1153. {
  1154. CAccessEntry* pACE = NULL;
  1155. ACLIter* pACLIter = (ACLIter*) pos;
  1156. // We'll want to get the current value and increment
  1157. // if we're anywhere but the end.
  1158. if ( *pACLIter != m_ACL.end() )
  1159. {
  1160. // Get the ACE out
  1161. pACE = *(*pACLIter);
  1162. (*pACLIter)++;
  1163. }
  1164. return pACE;
  1165. }
  1166. ///////////////////////////////////////////////////////////////////
  1167. //
  1168. // Function: CAccessEntryList:EndEnum
  1169. //
  1170. // Enumeration End call.
  1171. //
  1172. // Inputs:
  1173. // None.
  1174. //
  1175. // Outputs:
  1176. // ACLPOSITION& pos - Position to end on.
  1177. //
  1178. // Returns:
  1179. // None.
  1180. //
  1181. // Comments:
  1182. //
  1183. // ACLPOSITION passed in will be invalidated.
  1184. //
  1185. ///////////////////////////////////////////////////////////////////
  1186. void CAccessEntryList::EndEnum( ACLPOSITION& pos )
  1187. {
  1188. ACLIter* pACLIter = (ACLIter*) pos;
  1189. delete pACLIter;
  1190. }
  1191. ///////////////////////////////////////////////////////////////////
  1192. //
  1193. // Function: CAccessEntryList:GetAt
  1194. //
  1195. // Locates ACE at specified index.
  1196. //
  1197. // Inputs:
  1198. // DWORD dwIndex - Index to find.
  1199. //
  1200. // Outputs:
  1201. // CAccessEntry& ace - ACE located at dwIndex.
  1202. //
  1203. // Returns:
  1204. // BOOL Success/Failure
  1205. //
  1206. // Comments:
  1207. //
  1208. ///////////////////////////////////////////////////////////////////
  1209. bool CAccessEntryList::GetAt( DWORD dwIndex, CAccessEntry& ace )
  1210. {
  1211. bool fReturn = false;
  1212. if ( dwIndex < m_ACL.size() )
  1213. {
  1214. ACLIter acliter = m_ACL.begin();
  1215. // Enum the list until we hit the index or run out of values.
  1216. // we should hit the index since we verified that dwIndex is
  1217. // indeed < m_ACL.size().
  1218. for ( DWORD dwCtr = 0;
  1219. dwCtr < dwIndex
  1220. && acliter != m_ACL.end();
  1221. acliter++, dwCtr++ );
  1222. if ( acliter != m_ACL.end() )
  1223. {
  1224. // Copy the ACE
  1225. ace = *(*acliter);
  1226. fReturn = true;
  1227. }
  1228. }
  1229. return fReturn;
  1230. }
  1231. ///////////////////////////////////////////////////////////////////
  1232. //
  1233. // Function: CAccessEntryList:SetAt
  1234. //
  1235. // Locates ACE at specified index and overwrites it.
  1236. //
  1237. // Inputs:
  1238. // DWORD dwIndex - Index to find.
  1239. // CAccessEntry& ace - ACE to set at dwIndex.
  1240. //
  1241. // Outputs:
  1242. // None.
  1243. //
  1244. // Returns:
  1245. // BOOL Success/Failure
  1246. //
  1247. // Comments:
  1248. //
  1249. ///////////////////////////////////////////////////////////////////
  1250. bool CAccessEntryList::SetAt( DWORD dwIndex, const CAccessEntry& ace )
  1251. {
  1252. bool fReturn = false;
  1253. if ( dwIndex < m_ACL.size() )
  1254. {
  1255. ACLIter acliter = m_ACL.begin();
  1256. // Enum the list until we hit the index, at which point we will
  1257. // replace the existing entry data with the supplied data.
  1258. for ( DWORD dwCtr = 0;
  1259. dwCtr < dwIndex
  1260. && acliter != m_ACL.end();
  1261. acliter++, dwCtr++ );
  1262. if ( acliter != m_ACL.end() )
  1263. {
  1264. // Copy the ACE
  1265. *(*acliter) = ace;
  1266. fReturn = true;
  1267. }
  1268. }
  1269. return fReturn;
  1270. }
  1271. ///////////////////////////////////////////////////////////////////
  1272. //
  1273. // Function: CAccessEntryList:RemoveAt
  1274. //
  1275. // Locates ACE at specified index and removes it.
  1276. //
  1277. // Inputs:
  1278. // DWORD dwIndex - Index to find.
  1279. //
  1280. // Outputs:
  1281. // None.
  1282. //
  1283. // Returns:
  1284. // BOOL Success/Failure
  1285. //
  1286. // Comments:
  1287. //
  1288. ///////////////////////////////////////////////////////////////////
  1289. bool CAccessEntryList::RemoveAt( DWORD dwIndex )
  1290. {
  1291. bool fReturn = false;
  1292. if ( dwIndex < m_ACL.size() )
  1293. {
  1294. ACLIter acliter = m_ACL.begin();
  1295. // Enum the list until we hit the index, at which point we will
  1296. // delete the pointer at the entry and erase it from the list.
  1297. for ( DWORD dwCtr = 0;
  1298. dwCtr < dwIndex
  1299. && acliter != m_ACL.end();
  1300. acliter++, dwCtr++ );
  1301. if ( acliter != m_ACL.end() )
  1302. {
  1303. delete *acliter;
  1304. m_ACL.erase( acliter );
  1305. fReturn = true;
  1306. }
  1307. }
  1308. return fReturn;
  1309. }
  1310. ///////////////////////////////////////////////////////////////////
  1311. //
  1312. // Function: CAccessEntryList:CalculateWin32ACLSize
  1313. //
  1314. // Traverses our list and calculates the size of a Win32ACL
  1315. // containing corresponding values.
  1316. //
  1317. // Inputs:
  1318. // None.
  1319. //
  1320. // Outputs:
  1321. // LPDWORD pdwACLSize - ACL Size.
  1322. //
  1323. // Returns:
  1324. // BOOL Success/Failure
  1325. //
  1326. // Comments:
  1327. //
  1328. ///////////////////////////////////////////////////////////////////
  1329. BOOL CAccessEntryList::CalculateWin32ACLSize( LPDWORD pdwACLSize )
  1330. {
  1331. BOOL fReturn = TRUE;
  1332. if ( 0 == *pdwACLSize )
  1333. {
  1334. *pdwACLSize = sizeof(ACL);
  1335. }
  1336. // Objects for internal manipulations and gyrationships
  1337. CAccessEntry* pAce = NULL;
  1338. CSid sid;
  1339. ACLPOSITION pos;
  1340. if ( BeginEnum( pos ) )
  1341. {
  1342. try
  1343. {
  1344. while ( fReturn
  1345. && ( pAce = GetNext( pos ) ) != NULL )
  1346. {
  1347. // Different structures for different ACEs
  1348. switch ( pAce->GetACEType() )
  1349. {
  1350. case ACCESS_ALLOWED_ACE_TYPE: *pdwACLSize += sizeof( ACCESS_ALLOWED_ACE ); break;
  1351. case ACCESS_DENIED_ACE_TYPE: *pdwACLSize += sizeof( ACCESS_DENIED_ACE ); break;
  1352. case SYSTEM_AUDIT_ACE_TYPE: *pdwACLSize += sizeof( SYSTEM_AUDIT_ACE ); break;
  1353. case ACCESS_ALLOWED_OBJECT_ACE_TYPE: *pdwACLSize += sizeof( ACCESS_ALLOWED_OBJECT_ACE ); break;
  1354. //case ACCESS_ALLOWED_COMPOUND_ACE_TYPE: *pdwACLSize += sizeof( ACCESS_ALLOWED_COMPOUND_ACE ); break;
  1355. case ACCESS_DENIED_OBJECT_ACE_TYPE: *pdwACLSize += sizeof( ACCESS_DENIED_OBJECT_ACE ); break;
  1356. case SYSTEM_AUDIT_OBJECT_ACE_TYPE: *pdwACLSize += sizeof( SYSTEM_AUDIT_OBJECT_ACE ); break;
  1357. //case SYSTEM_ALARM_ACE_TYPE: *pdwACLSize += sizeof( SYSTEM_ALARM_ACE_TYPE ); break;
  1358. //case SYSTEM_ALARM_OBJECT_ACE_TYPE: *pdwACLSize += sizeof( SYSTEM_ALARM_OBJECT_ACE ); break;
  1359. default: ASSERT_BREAK(0); fReturn = FALSE; break;
  1360. }
  1361. pAce->GetSID( sid );
  1362. // Calculate the storage required for the Sid using the formula
  1363. // from the security reference code samples
  1364. *pdwACLSize += GetLengthSid( sid.GetPSid() ) - sizeof( DWORD );
  1365. }
  1366. }
  1367. catch(...)
  1368. {
  1369. if(pAce != NULL)
  1370. {
  1371. delete pAce;
  1372. pAce = NULL;
  1373. }
  1374. throw;
  1375. }
  1376. EndEnum( pos );
  1377. }
  1378. return fReturn;
  1379. }
  1380. ///////////////////////////////////////////////////////////////////
  1381. //
  1382. // Function: CAccessEntryList:FillWin32ACL
  1383. //
  1384. // Traverses our list and adds ACE entries to a Win32 ACL.
  1385. //
  1386. // Inputs:
  1387. // PACL pACL - ACL to add ACEs to.
  1388. //
  1389. // Outputs:
  1390. // None.
  1391. //
  1392. // Returns:
  1393. // BOOL Success/Failure
  1394. //
  1395. // Comments:
  1396. //
  1397. ///////////////////////////////////////////////////////////////////
  1398. DWORD CAccessEntryList::FillWin32ACL( PACL pACL )
  1399. {
  1400. DWORD dwReturn = ERROR_SUCCESS;
  1401. if(pACL == NULL)
  1402. {
  1403. return E_POINTER;
  1404. }
  1405. // Objects for internal manipulations and gyrationships
  1406. CAccessEntry* pACE = NULL;
  1407. ACLPOSITION pos;
  1408. ACE_HEADER* pAceHeader = NULL;
  1409. #if NTONLY >= 5
  1410. CAdvApi32Api *t_pAdvApi32 = NULL;
  1411. t_pAdvApi32 = (CAdvApi32Api*) CResourceManager::sm_TheResourceManager.GetResource(g_guidAdvApi32Api, NULL);
  1412. #endif
  1413. // Enumerate the List.
  1414. if ( BeginEnum( pos ) )
  1415. {
  1416. while ( ERROR_SUCCESS == dwReturn
  1417. && ( pACE = GetNext( pos ) ) != NULL )
  1418. {
  1419. #if NTONLY >= 5
  1420. if(pACE->GetACEType() == ACCESS_ALLOWED_OBJECT_ACE_TYPE)
  1421. {
  1422. if(t_pAdvApi32 != NULL)
  1423. {
  1424. // Call the new function AddAccessAllowedObjectAce...
  1425. CSid sid;
  1426. pACE->GetSID(sid);
  1427. BOOL fRetval = FALSE;
  1428. GUID guidObjType, guidInhObjType;
  1429. GUID *pguidObjType = NULL;
  1430. GUID *pguidInhObjType = NULL;
  1431. if(pACE->GetObjType(guidObjType)) pguidObjType = &guidObjType;
  1432. if(pACE->GetInhObjType(guidInhObjType)) pguidInhObjType = &guidInhObjType;
  1433. if(!t_pAdvApi32->AddAccessAllowedObjectAce(pACL,
  1434. ACL_REVISION_DS,
  1435. pACE->GetACEFlags(),
  1436. pACE->GetAccessMask(),
  1437. pguidObjType,
  1438. pguidInhObjType,
  1439. sid.GetPSid(),
  1440. &fRetval))
  1441. {
  1442. dwReturn = ERROR_PROC_NOT_FOUND;
  1443. }
  1444. else // fn exists in dll
  1445. {
  1446. if(!fRetval)
  1447. {
  1448. dwReturn = ::GetLastError();
  1449. }
  1450. }
  1451. }
  1452. else
  1453. {
  1454. dwReturn = E_FAIL;
  1455. }
  1456. }
  1457. else if(pACE->GetACEType() == ACCESS_DENIED_OBJECT_ACE_TYPE)
  1458. {
  1459. if(t_pAdvApi32 != NULL)
  1460. {
  1461. // Call the new function AddAccessDeniedObjectAce...
  1462. CSid sid;
  1463. pACE->GetSID(sid);
  1464. BOOL fRetval = FALSE;
  1465. GUID guidObjType, guidInhObjType;
  1466. GUID *pguidObjType = NULL;
  1467. GUID *pguidInhObjType = NULL;
  1468. if(pACE->GetObjType(guidObjType)) pguidObjType = &guidObjType;
  1469. if(pACE->GetInhObjType(guidInhObjType)) pguidInhObjType = &guidInhObjType;
  1470. if(!t_pAdvApi32->AddAccessDeniedObjectAce(pACL,
  1471. ACL_REVISION_DS,
  1472. pACE->GetACEFlags(),
  1473. pACE->GetAccessMask(),
  1474. pguidObjType,
  1475. pguidInhObjType,
  1476. sid.GetPSid(),
  1477. &fRetval))
  1478. {
  1479. dwReturn = ERROR_PROC_NOT_FOUND;
  1480. }
  1481. else // fn exists in dll
  1482. {
  1483. if(!fRetval)
  1484. {
  1485. dwReturn = ::GetLastError();
  1486. }
  1487. }
  1488. }
  1489. else
  1490. {
  1491. dwReturn = E_FAIL;
  1492. }
  1493. }
  1494. else if(pACE->GetACEType() == SYSTEM_AUDIT_OBJECT_ACE_TYPE)
  1495. {
  1496. if(t_pAdvApi32 != NULL)
  1497. {
  1498. // Call the new function AddAccessDeniedObjectAce...
  1499. CSid sid;
  1500. pACE->GetSID(sid);
  1501. BOOL fRetval = FALSE;
  1502. if(!t_pAdvApi32->AddAuditAccessObjectAce(pACL,
  1503. ACL_REVISION_DS,
  1504. pACE->GetACEFlags(),
  1505. pACE->GetAccessMask(),
  1506. NULL,
  1507. NULL,
  1508. sid.GetPSid(),
  1509. FALSE, // we pick this up through the third argument
  1510. FALSE, // we pick this up through the third argument
  1511. &fRetval))
  1512. {
  1513. if(!fRetval)
  1514. {
  1515. dwReturn = ::GetLastError();
  1516. }
  1517. else
  1518. {
  1519. dwReturn = ERROR_PROC_NOT_FOUND;
  1520. }
  1521. }
  1522. }
  1523. else
  1524. {
  1525. dwReturn = E_FAIL;
  1526. }
  1527. }
  1528. else
  1529. #endif
  1530. {
  1531. // For Each ACE we enum, allocate a Win32 ACE, and stick that bad boy at the
  1532. // end of the Win32 ACL.
  1533. if ( pACE->AllocateACE( &pAceHeader ) )
  1534. {
  1535. if ( !::AddAce( pACL, pACL->AclRevision, MAXDWORD, (void*) pAceHeader, pAceHeader->AceSize ) )
  1536. {
  1537. dwReturn = ::GetLastError();
  1538. }
  1539. // Cleanup the memory block
  1540. pACE->FreeACE( pAceHeader );
  1541. }
  1542. else
  1543. {
  1544. dwReturn = ERROR_NOT_ENOUGH_MEMORY;
  1545. }
  1546. }
  1547. }
  1548. EndEnum( pos );
  1549. }
  1550. #if NTONLY >= 5
  1551. if(t_pAdvApi32 != NULL)
  1552. {
  1553. CResourceManager::sm_TheResourceManager.ReleaseResource(g_guidAdvApi32Api, t_pAdvApi32);
  1554. t_pAdvApi32 = NULL;
  1555. }
  1556. #endif
  1557. return dwReturn;
  1558. }
  1559. ///////////////////////////////////////////////////////////////////
  1560. //
  1561. // Function: CAccessEntryList:InitFromWin32ACL
  1562. //
  1563. // Traverses a Win32ACL and copies ACEs into our list.
  1564. //
  1565. // Inputs:
  1566. // PACL pACL - ACL to add ACEs to.
  1567. // BYTE bACEFilter - ACEs to filter on.
  1568. // bool fLookup - whether the sids should be
  1569. // resolved to their domain and name values.
  1570. //
  1571. // Outputs:
  1572. // None.
  1573. //
  1574. // Returns:
  1575. // BOOL Success/Failure
  1576. //
  1577. // Comments:
  1578. //
  1579. // If bACEFilter is not ALL_ACE_TYPES, then we will only copy out
  1580. // ACEs of the specified type.
  1581. //
  1582. ///////////////////////////////////////////////////////////////////
  1583. DWORD CAccessEntryList::InitFromWin32ACL( PACL pWin32ACL, BYTE bACEFilter /* = ALL_ACE_TYPES */, bool fLookup /* = true */ )
  1584. {
  1585. DWORD dwError = 0;
  1586. ACE_HEADER* pACEHeader = NULL;
  1587. DWORD dwAceIndex = 0;
  1588. BOOL fGotACE = FALSE;
  1589. DWORD dwMask = 0;
  1590. PSID psid = NULL;
  1591. GUID *pguidObjType = NULL;
  1592. GUID *pguidInhObjType = NULL;
  1593. // Empty out
  1594. Clear();
  1595. // For each ACE we find, get the values necessary to initialize our
  1596. // CAccessEntries
  1597. do
  1598. {
  1599. fGotACE = ::GetAce( pWin32ACL, dwAceIndex, (LPVOID*) &pACEHeader );
  1600. if ( fGotACE )
  1601. {
  1602. switch ( pACEHeader->AceType )
  1603. {
  1604. case ACCESS_ALLOWED_ACE_TYPE:
  1605. {
  1606. ACCESS_ALLOWED_ACE* pACE = (ACCESS_ALLOWED_ACE*) pACEHeader;
  1607. psid = (PSID) &pACE->SidStart;
  1608. dwMask = pACE->Mask;
  1609. }
  1610. break;
  1611. case ACCESS_DENIED_ACE_TYPE:
  1612. {
  1613. ACCESS_DENIED_ACE* pACE = (ACCESS_DENIED_ACE*) pACEHeader;
  1614. psid = (PSID) &pACE->SidStart;
  1615. dwMask = pACE->Mask;
  1616. }
  1617. break;
  1618. case SYSTEM_AUDIT_ACE_TYPE:
  1619. {
  1620. SYSTEM_AUDIT_ACE* pACE = (SYSTEM_AUDIT_ACE*) pACEHeader;
  1621. psid = (PSID) &pACE->SidStart;
  1622. dwMask = pACE->Mask;
  1623. }
  1624. break;
  1625. case ACCESS_ALLOWED_OBJECT_ACE_TYPE:
  1626. {
  1627. ACCESS_ALLOWED_OBJECT_ACE* pACE = (ACCESS_ALLOWED_OBJECT_ACE*) pACEHeader;
  1628. psid = (PSID) &pACE->SidStart;
  1629. dwMask = pACE->Mask;
  1630. if(pACE->Flags & ACE_OBJECT_TYPE_PRESENT)
  1631. {
  1632. try
  1633. {
  1634. pguidObjType = new GUID;
  1635. if(pguidObjType != NULL)
  1636. {
  1637. memcpy(pguidObjType,&pACE->ObjectType, sizeof(GUID));
  1638. }
  1639. else
  1640. {
  1641. dwError = ERROR_NOT_ENOUGH_MEMORY;
  1642. }
  1643. }
  1644. catch(...)
  1645. {
  1646. if(pguidObjType != NULL)
  1647. {
  1648. delete pguidObjType;
  1649. pguidObjType = NULL;
  1650. }
  1651. throw;
  1652. }
  1653. }
  1654. if(pACE->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT)
  1655. {
  1656. try
  1657. {
  1658. pguidInhObjType = new GUID;
  1659. if(pguidInhObjType != NULL)
  1660. {
  1661. memcpy(pguidInhObjType,&pACE->InheritedObjectType, sizeof(GUID));
  1662. }
  1663. else
  1664. {
  1665. dwError = ERROR_NOT_ENOUGH_MEMORY;
  1666. }
  1667. }
  1668. catch(...)
  1669. {
  1670. if(pguidInhObjType != NULL)
  1671. {
  1672. delete pguidInhObjType;
  1673. pguidInhObjType = NULL;
  1674. }
  1675. throw;
  1676. }
  1677. }
  1678. }
  1679. break;
  1680. /********************************* type not yet supported under w2k ********************************************
  1681. case ACCESS_ALLOWED_COMPOUND_ACE_TYPE:
  1682. {
  1683. ACCESS_ALLOWED_COMPOUND_ACE_TYPE* pACE = (ACCESS_ALLOWED_COMPOUND_ACE_TYPE*) pACEHeader;
  1684. psid = (PSID) &pACE->SidStart;
  1685. dwMask = pACE->Mask;
  1686. }
  1687. break;
  1688. ***************************************************************************************************************/
  1689. case ACCESS_DENIED_OBJECT_ACE_TYPE:
  1690. {
  1691. ACCESS_DENIED_OBJECT_ACE* pACE = (ACCESS_DENIED_OBJECT_ACE*) pACEHeader;
  1692. psid = (PSID) &pACE->SidStart;
  1693. dwMask = pACE->Mask;
  1694. if(pACE->Flags & ACE_OBJECT_TYPE_PRESENT)
  1695. {
  1696. try
  1697. {
  1698. pguidObjType = new GUID;
  1699. if(pguidObjType != NULL)
  1700. {
  1701. memcpy(pguidObjType,&pACE->ObjectType, sizeof(GUID));
  1702. }
  1703. else
  1704. {
  1705. dwError = ERROR_NOT_ENOUGH_MEMORY;
  1706. }
  1707. }
  1708. catch(...)
  1709. {
  1710. if(pguidObjType != NULL)
  1711. {
  1712. delete pguidObjType;
  1713. pguidObjType = NULL;
  1714. }
  1715. throw;
  1716. }
  1717. }
  1718. if(pACE->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT)
  1719. {
  1720. try
  1721. {
  1722. pguidInhObjType = new GUID;
  1723. if(pguidInhObjType != NULL)
  1724. {
  1725. memcpy(pguidInhObjType,&pACE->InheritedObjectType, sizeof(GUID));
  1726. }
  1727. else
  1728. {
  1729. dwError = ERROR_NOT_ENOUGH_MEMORY;
  1730. }
  1731. }
  1732. catch(...)
  1733. {
  1734. if(pguidInhObjType != NULL)
  1735. {
  1736. delete pguidInhObjType;
  1737. pguidInhObjType = NULL;
  1738. }
  1739. throw;
  1740. }
  1741. }
  1742. }
  1743. break;
  1744. case SYSTEM_AUDIT_OBJECT_ACE_TYPE:
  1745. {
  1746. SYSTEM_AUDIT_OBJECT_ACE* pACE = (SYSTEM_AUDIT_OBJECT_ACE*) pACEHeader;
  1747. psid = (PSID) &pACE->SidStart;
  1748. dwMask = pACE->Mask;
  1749. if(pACE->Flags & ACE_OBJECT_TYPE_PRESENT)
  1750. {
  1751. try
  1752. {
  1753. pguidObjType = new GUID;
  1754. if(pguidObjType != NULL)
  1755. {
  1756. memcpy(pguidObjType,&pACE->ObjectType, sizeof(GUID));
  1757. }
  1758. else
  1759. {
  1760. dwError = ERROR_NOT_ENOUGH_MEMORY;
  1761. }
  1762. }
  1763. catch(...)
  1764. {
  1765. if(pguidObjType != NULL)
  1766. {
  1767. delete pguidObjType;
  1768. pguidObjType = NULL;
  1769. }
  1770. throw;
  1771. }
  1772. }
  1773. if(pACE->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT)
  1774. {
  1775. try
  1776. {
  1777. pguidInhObjType = new GUID;
  1778. if(pguidInhObjType != NULL)
  1779. {
  1780. memcpy(pguidInhObjType,&pACE->InheritedObjectType, sizeof(GUID));
  1781. }
  1782. else
  1783. {
  1784. dwError = ERROR_NOT_ENOUGH_MEMORY;
  1785. }
  1786. }
  1787. catch(...)
  1788. {
  1789. if(pguidInhObjType != NULL)
  1790. {
  1791. delete pguidInhObjType;
  1792. pguidInhObjType = NULL;
  1793. }
  1794. throw;
  1795. }
  1796. }
  1797. }
  1798. break;
  1799. /********************************* type not yet supported under w2k ********************************************
  1800. case SYSTEM_ALARM_ACE_TYPE:
  1801. {
  1802. SYSTEM_ALARM_ACE* pACE = (SYSTEM_ALARM_ACE*) pACEHeader;
  1803. psid = (PSID) &pACE->SidStart;
  1804. dwMask = pACE->Mask;
  1805. }
  1806. break;
  1807. /********************************* type not yet supported under w2k ********************************************/
  1808. /********************************* type not yet supported under w2k ********************************************
  1809. case SYSTEM_ALARM_OBJECT_ACE_TYPE:
  1810. {
  1811. SYSTEM_ALARM_OBJECT_ACE* pACE = (SYSTEM_ALARM_OBJECT_ACE*) pACEHeader;
  1812. psid = (PSID) &pACE->SidStart;
  1813. dwMask = pACE->Mask;
  1814. if(pACE->Flags & ACE_OBJECT_TYPE_PRESENT)
  1815. {
  1816. try
  1817. {
  1818. pguidObjType = new GUID;
  1819. if(pguidObjType != NULL)
  1820. {
  1821. memcpy(pguidObjType,&pACE->ObjectType, sizeof(GUID));
  1822. }
  1823. else
  1824. {
  1825. dwError = ERROR_NOT_ENOUGH_MEMORY;
  1826. }
  1827. }
  1828. catch(...)
  1829. {
  1830. if(pguidObjType != NULL)
  1831. {
  1832. delete pguidObjType;
  1833. pguidObjType = NULL;
  1834. }
  1835. throw;
  1836. }
  1837. }
  1838. if(pACE->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT)
  1839. {
  1840. try
  1841. {
  1842. pguidInhObjType = new GUID;
  1843. if(pguidInhObjType != NULL)
  1844. {
  1845. memcpy(pguidInhObjType,&pACE->InheritedObjectType, sizeof(GUID));
  1846. }
  1847. else
  1848. {
  1849. dwError = ERROR_NOT_ENOUGH_MEMORY;
  1850. }
  1851. }
  1852. catch(...)
  1853. {
  1854. if(pguidInhObjType != NULL)
  1855. {
  1856. delete pguidInhObjType;
  1857. pguidInhObjType = NULL;
  1858. }
  1859. throw;
  1860. }
  1861. }
  1862. }
  1863. break;
  1864. /********************************* type not yet supported under w2k ********************************************/
  1865. default:
  1866. {
  1867. ASSERT_BREAK(0); // BAD, we don't know what this is!
  1868. dwError = ERROR_INVALID_PARAMETER;
  1869. }
  1870. }
  1871. // We must have no errors, and the filter MUST accept all ACE Types
  1872. // or the ACE Type must match the filter.
  1873. if ( ERROR_SUCCESS == dwError
  1874. && ( ALL_ACE_TYPES == bACEFilter
  1875. || bACEFilter == pACEHeader->AceType ) )
  1876. {
  1877. // We merge duplicate entries during initialization
  1878. if ( !AppendNoDup( psid,
  1879. pACEHeader->AceType,
  1880. pACEHeader->AceFlags,
  1881. dwMask,
  1882. pguidObjType,
  1883. pguidInhObjType,
  1884. true, // Merge flag
  1885. fLookup ) ) // whether to resolve domain and name of sid
  1886. {
  1887. dwError = ERROR_NOT_ENOUGH_MEMORY;
  1888. }
  1889. }
  1890. } // IF fGot ACE
  1891. // Get the next ACE
  1892. ++dwAceIndex;
  1893. }
  1894. while ( fGotACE && ERROR_SUCCESS == dwError );
  1895. return dwError;
  1896. }
  1897. void CAccessEntryList::DumpAccessEntryList(LPCWSTR wstrFilename)
  1898. {
  1899. Output(L"AccessEntryList contents follow...", wstrFilename);
  1900. // Run through the list, outputting each...
  1901. CAccessEntry* pACE = NULL;
  1902. ACLPOSITION pos;
  1903. if(BeginEnum(pos))
  1904. {
  1905. while((pACE = GetNext(pos)) != NULL)
  1906. {
  1907. pACE->DumpAccessEntry(wstrFilename);
  1908. }
  1909. EndEnum(pos);
  1910. }
  1911. }