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.

1485 lines
41 KiB

  1. /*****************************************************************************/
  2. /* Copyright (c) 1999-2002 Microsoft Corporation, All Rights Reserved /
  3. /*****************************************************************************/
  4. /*
  5. * CAccessEntry.cpp - implementation file for CAccessEntry class.
  6. */
  7. #include "precomp.h"
  8. #include "AccessEntryList.h"
  9. #include "aclapi.h"
  10. #include "DACL.h"
  11. #include <accctrl.h>
  12. #include "wbemnetapi32.h"
  13. #include "SecUtils.h"
  14. ///////////////////////////////////////////////////////////////////
  15. //
  16. // Function: CDACL::CDACL
  17. //
  18. // Default class constructor.
  19. //
  20. // Inputs:
  21. // None.
  22. //
  23. // Outputs:
  24. // None.
  25. //
  26. // Returns:
  27. // None.
  28. //
  29. // Comments:
  30. //
  31. ///////////////////////////////////////////////////////////////////
  32. CDACL::CDACL( void )
  33. {
  34. for(short s = 0; s < NUM_DACL_TYPES; s++)
  35. {
  36. m_rgDACLSections[s] = NULL;
  37. }
  38. }
  39. ///////////////////////////////////////////////////////////////////
  40. //
  41. // Function: CDACL::~CDACL
  42. //
  43. // Class destructor.
  44. //
  45. // Inputs:
  46. // None.
  47. //
  48. // Outputs:
  49. // None.
  50. //
  51. // Returns:
  52. // None.
  53. //
  54. // Comments:
  55. //
  56. ///////////////////////////////////////////////////////////////////
  57. CDACL::~CDACL( void )
  58. {
  59. Clear();
  60. }
  61. ///////////////////////////////////////////////////////////////////
  62. //
  63. // Function: CDACL::Init
  64. //
  65. // Initializes the DACL member lists.
  66. //
  67. // Inputs:
  68. //
  69. //
  70. // Outputs:
  71. // None.
  72. //
  73. // Returns:
  74. // DWORD Success/Failure
  75. //
  76. // Comments:
  77. //
  78. ///////////////////////////////////////////////////////////////////
  79. DWORD CDACL::Init(PACL a_pDACL)
  80. {
  81. DWORD t_dwRes = E_FAIL;
  82. if(a_pDACL == NULL)
  83. {
  84. return ERROR_INVALID_PARAMETER;
  85. }
  86. CAccessEntryList t_aclTemp;
  87. t_dwRes = t_aclTemp.InitFromWin32ACL(a_pDACL);
  88. if(t_dwRes == ERROR_SUCCESS)
  89. {
  90. if(!SplitIntoCanonicalSections(t_aclTemp))
  91. {
  92. for(short s = 0; s < NUM_DACL_TYPES; s++)
  93. {
  94. delete m_rgDACLSections[s];
  95. m_rgDACLSections[s] = NULL;
  96. }
  97. t_dwRes = ERROR_SUCCESS;
  98. }
  99. }
  100. return t_dwRes;
  101. }
  102. ///////////////////////////////////////////////////////////////////
  103. //
  104. // Function: CDACL::AddDACLEntry
  105. //
  106. // Adds an access allowed entry to the ACL. By default, these go
  107. // to the end of the list.
  108. //
  109. // Inputs:
  110. // PSID psid - PSID
  111. // DWORD dwAccessMask - Access Mask
  112. // BYTE bAceFlags - Flags
  113. //
  114. // Outputs:
  115. // None.
  116. //
  117. // Returns:
  118. // BOOL Success/Failure
  119. //
  120. // Comments:
  121. //
  122. ///////////////////////////////////////////////////////////////////
  123. bool CDACL::AddDACLEntry( PSID psid, DACLTYPE DaclType, DWORD dwAccessMask, BYTE bAceFlags, GUID *pguidObjGuid, GUID *pguidInhObjGuid )
  124. {
  125. bool fReturn = true;
  126. BYTE bACEType;
  127. // Sid must be valid
  128. if ( (psid != NULL) && IsValidSid( psid ) )
  129. {
  130. switch(DaclType)
  131. {
  132. case ENUM_ACCESS_DENIED_ACE_TYPE:
  133. bACEType = ACCESS_DENIED_ACE_TYPE;
  134. break;
  135. case ENUM_ACCESS_DENIED_OBJECT_ACE_TYPE:
  136. bACEType = ACCESS_DENIED_OBJECT_ACE_TYPE;
  137. break;
  138. case ENUM_ACCESS_ALLOWED_ACE_TYPE:
  139. bACEType = ACCESS_ALLOWED_ACE_TYPE;
  140. break;
  141. case ENUM_ACCESS_ALLOWED_COMPOUND_ACE_TYPE:
  142. bACEType = ACCESS_ALLOWED_COMPOUND_ACE_TYPE;
  143. break;
  144. case ENUM_ACCESS_ALLOWED_OBJECT_ACE_TYPE:
  145. bACEType = ACCESS_ALLOWED_OBJECT_ACE_TYPE;
  146. break;
  147. case ENUM_INH_ACCESS_DENIED_ACE_TYPE:
  148. bACEType = ACCESS_DENIED_ACE_TYPE;
  149. break;
  150. case ENUM_INH_ACCESS_DENIED_OBJECT_ACE_TYPE:
  151. bACEType = ACCESS_DENIED_OBJECT_ACE_TYPE;
  152. break;
  153. case ENUM_INH_ACCESS_ALLOWED_ACE_TYPE:
  154. bACEType = ACCESS_ALLOWED_ACE_TYPE;
  155. break;
  156. case ENUM_INH_ACCESS_ALLOWED_COMPOUND_ACE_TYPE:
  157. bACEType = ACCESS_ALLOWED_COMPOUND_ACE_TYPE;
  158. break;
  159. case ENUM_INH_ACCESS_ALLOWED_OBJECT_ACE_TYPE:
  160. bACEType = ACCESS_ALLOWED_OBJECT_ACE_TYPE;
  161. break;
  162. default:
  163. fReturn = false;
  164. break;
  165. }
  166. if(fReturn)
  167. {
  168. if(m_rgDACLSections[DaclType] == NULL)
  169. {
  170. try
  171. {
  172. m_rgDACLSections[DaclType] = new CAccessEntryList;
  173. }
  174. catch(...)
  175. {
  176. if(m_rgDACLSections[DaclType] != NULL)
  177. {
  178. delete m_rgDACLSections[DaclType];
  179. m_rgDACLSections[DaclType] = NULL;
  180. }
  181. throw;
  182. }
  183. if(m_rgDACLSections[DaclType] != NULL)
  184. {
  185. fReturn = m_rgDACLSections[DaclType]->AppendNoDup( psid, bACEType, bAceFlags, dwAccessMask, pguidObjGuid, pguidInhObjGuid );
  186. }
  187. }
  188. else
  189. {
  190. fReturn = m_rgDACLSections[DaclType]->AppendNoDup( psid, bACEType, bAceFlags, dwAccessMask, pguidObjGuid, pguidInhObjGuid );
  191. }
  192. }
  193. }
  194. else
  195. {
  196. fReturn = false;
  197. }
  198. return fReturn;
  199. }
  200. ///////////////////////////////////////////////////////////////////
  201. //
  202. // Function: CDACL::RemoveDACLEntry
  203. //
  204. // Removes an access allowed entry from the ACL.
  205. //
  206. // Inputs:
  207. // CSID& sid - PSID
  208. // DWORD dwAccessMask - Access Mask
  209. // BYTE bAceFlags - Flags
  210. //
  211. // Outputs:
  212. // None.
  213. //
  214. // Returns:
  215. // BOOL Success/Failure
  216. //
  217. // Comments:
  218. //
  219. // Removed entry MUST match the supplied parameters.
  220. //
  221. ///////////////////////////////////////////////////////////////////
  222. bool CDACL::RemoveDACLEntry( CSid& sid, DACLTYPE DaclType, DWORD dwAccessMask, BYTE bAceFlags, GUID *pguidObjGuid, GUID *pguidInhObjGuid )
  223. {
  224. bool fReturn = false;
  225. // We need an ACE to compare
  226. CAccessEntry ACE( &sid, DaclType, bAceFlags, pguidObjGuid, pguidInhObjGuid, dwAccessMask);
  227. ACLPOSITION pos;
  228. if ( m_rgDACLSections[DaclType]->BeginEnum( pos ) )
  229. {
  230. ON_BLOCK_EXIT_OBJ ( *m_rgDACLSections [ DaclType ], CAccessEntryList::EndEnum, ByRef ( pos ) ) ;
  231. // For loop will try to find a matching ACE in the list
  232. CAccessEntry* pACE = NULL;
  233. try
  234. {
  235. for ( pACE = m_rgDACLSections[DaclType]->GetNext( pos );
  236. NULL != pACE
  237. && !(ACE == *pACE);
  238. pACE = m_rgDACLSections[DaclType]->GetNext( pos ) );
  239. // If we got a match, delete the ACE.
  240. if ( NULL != pACE )
  241. {
  242. m_rgDACLSections[DaclType]->Remove( pACE );
  243. delete pACE;
  244. fReturn = true;
  245. }
  246. }
  247. catch(...)
  248. {
  249. if(pACE != NULL)
  250. {
  251. delete pACE;
  252. pACE = NULL;
  253. }
  254. throw;
  255. }
  256. }
  257. return fReturn;
  258. }
  259. ///////////////////////////////////////////////////////////////////
  260. //
  261. // Function: CDACL::RemoveDACLEntry
  262. //
  263. // Removes an access allowed entry from the ACL.
  264. //
  265. // Inputs:
  266. // CSID& sid - PSID
  267. // BYTE bAceFlags - Flags
  268. //
  269. // Outputs:
  270. // None.
  271. //
  272. // Returns:
  273. // BOOL Success/Failure
  274. //
  275. // Comments:
  276. //
  277. // Removed entry MUST match the supplied parameters.
  278. //
  279. ///////////////////////////////////////////////////////////////////
  280. bool CDACL::RemoveDACLEntry( CSid& sid, DACLTYPE DaclType, BYTE bAceFlags, GUID *pguidObjGuid, GUID *pguidInhObjGuid )
  281. {
  282. bool fReturn = false;
  283. // We need an ACE to compare
  284. ACLPOSITION pos;
  285. if ( m_rgDACLSections[DaclType]->BeginEnum( pos ) )
  286. {
  287. ON_BLOCK_EXIT_OBJ ( *m_rgDACLSections [ DaclType ], CAccessEntryList::EndEnum, ByRef ( pos ) ) ;
  288. // For loop will try to find a matching ACE in the list
  289. CAccessEntry* pACE = NULL;
  290. try
  291. {
  292. for ( CAccessEntry* pACE = m_rgDACLSections[DaclType]->GetNext( pos );
  293. NULL != pACE;
  294. pACE = m_rgDACLSections[DaclType]->GetNext( pos ) )
  295. {
  296. CAccessEntry caeTemp(sid, DaclType, bAceFlags, pguidObjGuid, pguidInhObjGuid, pACE->GetAccessMask());
  297. // If we got a match, delete the ACE.
  298. if (*pACE == caeTemp)
  299. {
  300. m_rgDACLSections[DaclType]->Remove( pACE );
  301. fReturn = true;
  302. break;
  303. }
  304. delete pACE;
  305. }
  306. }
  307. catch(...)
  308. {
  309. if(pACE != NULL)
  310. {
  311. delete pACE;
  312. pACE = NULL;
  313. }
  314. throw;
  315. }
  316. }
  317. return fReturn;
  318. }
  319. ///////////////////////////////////////////////////////////////////
  320. //
  321. // Function: CDACL::RemoveDACLEntry
  322. //
  323. // Removes an access allowed entry from the ACL.
  324. //
  325. // Inputs:
  326. // CSID& sid - PSID
  327. // DWORD dwIndex - Index to remove.
  328. //
  329. // Outputs:
  330. // None.
  331. //
  332. // Returns:
  333. // BOOL Success/Failure
  334. //
  335. // Comments:
  336. //
  337. // Removed entry MUST be dwIndex entry matching CSid.
  338. //
  339. ///////////////////////////////////////////////////////////////////
  340. bool CDACL::RemoveDACLEntry( CSid& sid, DACLTYPE DaclType, DWORD dwIndex /*= 0*/ )
  341. {
  342. bool fReturn = false;
  343. // We need an ACE to compare
  344. CSid tempsid;
  345. ACLPOSITION pos;
  346. DWORD dwCtr = 0;
  347. if ( m_rgDACLSections[DaclType]->BeginEnum( pos ) )
  348. {
  349. ON_BLOCK_EXIT_OBJ ( *m_rgDACLSections [ DaclType ], CAccessEntryList::EndEnum, ByRef ( pos ) ) ;
  350. // For each ACE we find, see if it is an ACCESS_ALLOWED_ACE_TYPE,
  351. // and if the Sid matches the one passed in. If it does, increment
  352. // the counter, then if we're on the right index remove the ACE,
  353. // delete it and quit.
  354. CAccessEntry* pACE = NULL;
  355. try
  356. {
  357. for ( pACE = m_rgDACLSections[DaclType]->GetNext( pos );
  358. NULL != pACE;
  359. pACE = m_rgDACLSections[DaclType]->GetNext( pos ) )
  360. {
  361. if ( DaclType == pACE->GetACEType() )
  362. {
  363. pACE->GetSID( tempsid );
  364. if ( sid == tempsid )
  365. {
  366. if ( dwCtr == dwIndex )
  367. {
  368. m_rgDACLSections[DaclType]->Remove( pACE );
  369. fReturn = true;
  370. break;
  371. }
  372. else
  373. {
  374. ++dwCtr;
  375. }
  376. }
  377. delete pACE;
  378. }
  379. }
  380. }
  381. catch(...)
  382. {
  383. if(pACE != NULL)
  384. {
  385. delete pACE;
  386. pACE = NULL;
  387. }
  388. throw;
  389. }
  390. }
  391. return fReturn;
  392. }
  393. ///////////////////////////////////////////////////////////////////
  394. //
  395. // Function: CDACL::Find
  396. //
  397. // Finds the specified ace in the dacl
  398. //
  399. //
  400. // Returns:
  401. // true if found it.
  402. //
  403. // Comments:
  404. //
  405. // Helps support NT 5 canonical order in DACLs.
  406. //
  407. ///////////////////////////////////////////////////////////////////
  408. bool CDACL::Find( const CSid& sid, BYTE bACEType, BYTE bACEFlags, GUID *pguidObjGuid, GUID *pguidInhObjGuid, DWORD dwAccessMask, CAccessEntry& ace )
  409. {
  410. bool fReturn = false;
  411. switch(bACEType)
  412. {
  413. case ACCESS_DENIED_ACE_TYPE:
  414. {
  415. if(bACEFlags & INHERITED_ACE)
  416. {
  417. if(m_rgDACLSections[ENUM_INH_ACCESS_DENIED_ACE_TYPE] != NULL)
  418. {
  419. fReturn = m_rgDACLSections[ENUM_INH_ACCESS_DENIED_ACE_TYPE]->Find( sid, bACEType, bACEFlags, pguidObjGuid, pguidInhObjGuid, dwAccessMask, ace );
  420. }
  421. }
  422. else
  423. {
  424. if(m_rgDACLSections[ENUM_ACCESS_DENIED_ACE_TYPE] != NULL)
  425. {
  426. fReturn = m_rgDACLSections[ENUM_ACCESS_DENIED_ACE_TYPE]->Find( sid, bACEType, bACEFlags, pguidObjGuid, pguidInhObjGuid, dwAccessMask, ace );
  427. }
  428. }
  429. break;
  430. }
  431. case ACCESS_DENIED_OBJECT_ACE_TYPE:
  432. {
  433. if(bACEFlags & INHERITED_ACE)
  434. {
  435. if(m_rgDACLSections[ENUM_INH_ACCESS_DENIED_OBJECT_ACE_TYPE] != NULL)
  436. {
  437. fReturn = m_rgDACLSections[ENUM_INH_ACCESS_DENIED_OBJECT_ACE_TYPE]->Find( sid, bACEType, bACEFlags, pguidObjGuid, pguidInhObjGuid, dwAccessMask, ace );
  438. }
  439. }
  440. else
  441. {
  442. if(m_rgDACLSections[ENUM_ACCESS_DENIED_OBJECT_ACE_TYPE] != NULL)
  443. {
  444. fReturn = m_rgDACLSections[ENUM_ACCESS_DENIED_OBJECT_ACE_TYPE]->Find( sid, bACEType, bACEFlags, pguidObjGuid, pguidInhObjGuid, dwAccessMask, ace );
  445. }
  446. }
  447. break;
  448. }
  449. case ACCESS_ALLOWED_ACE_TYPE:
  450. {
  451. if(bACEFlags & INHERITED_ACE)
  452. {
  453. if(m_rgDACLSections[ENUM_INH_ACCESS_ALLOWED_ACE_TYPE] != NULL)
  454. {
  455. fReturn = m_rgDACLSections[ENUM_INH_ACCESS_ALLOWED_ACE_TYPE]->Find( sid, bACEType, bACEFlags, pguidObjGuid, pguidInhObjGuid, dwAccessMask, ace );
  456. }
  457. }
  458. else
  459. {
  460. if(m_rgDACLSections[ENUM_ACCESS_ALLOWED_ACE_TYPE] != NULL)
  461. {
  462. fReturn = m_rgDACLSections[ENUM_ACCESS_ALLOWED_ACE_TYPE]->Find( sid, bACEType, bACEFlags, pguidObjGuid, pguidInhObjGuid, dwAccessMask, ace );
  463. }
  464. }
  465. break;
  466. }
  467. case ACCESS_ALLOWED_COMPOUND_ACE_TYPE:
  468. {
  469. if(bACEFlags & INHERITED_ACE)
  470. {
  471. if(m_rgDACLSections[ENUM_INH_ACCESS_ALLOWED_COMPOUND_ACE_TYPE] != NULL)
  472. {
  473. fReturn = m_rgDACLSections[ENUM_INH_ACCESS_ALLOWED_COMPOUND_ACE_TYPE]->Find( sid, bACEType, bACEFlags, pguidObjGuid, pguidInhObjGuid, dwAccessMask, ace );
  474. }
  475. }
  476. else
  477. {
  478. if(m_rgDACLSections[ENUM_ACCESS_ALLOWED_COMPOUND_ACE_TYPE] != NULL)
  479. {
  480. fReturn = m_rgDACLSections[ENUM_ACCESS_ALLOWED_COMPOUND_ACE_TYPE]->Find( sid, bACEType, bACEFlags, pguidObjGuid, pguidInhObjGuid, dwAccessMask, ace );
  481. }
  482. }
  483. break;
  484. }
  485. case ACCESS_ALLOWED_OBJECT_ACE_TYPE:
  486. {
  487. if(bACEFlags & INHERITED_ACE)
  488. {
  489. if(m_rgDACLSections[ENUM_INH_ACCESS_ALLOWED_OBJECT_ACE_TYPE] != NULL)
  490. {
  491. fReturn = m_rgDACLSections[ENUM_INH_ACCESS_ALLOWED_OBJECT_ACE_TYPE]->Find( sid, bACEType, bACEFlags, pguidObjGuid, pguidInhObjGuid, dwAccessMask, ace );
  492. }
  493. }
  494. else
  495. {
  496. if(m_rgDACLSections[ENUM_ACCESS_ALLOWED_OBJECT_ACE_TYPE] != NULL)
  497. {
  498. fReturn = m_rgDACLSections[ENUM_ACCESS_ALLOWED_OBJECT_ACE_TYPE]->Find( sid, bACEType, bACEFlags, pguidObjGuid, pguidInhObjGuid, dwAccessMask, ace );
  499. }
  500. }
  501. break;
  502. }
  503. default:
  504. {
  505. fReturn = false;
  506. }
  507. }
  508. return fReturn;
  509. }
  510. ///////////////////////////////////////////////////////////////////
  511. //
  512. // Function: CDACL::Find
  513. //
  514. // Finds the specified ace in the dacl
  515. //
  516. //
  517. // Returns:
  518. // true if found it.
  519. //
  520. // Comments:
  521. //
  522. // Helps support NT 5 canonical order in DACLs.
  523. //
  524. ///////////////////////////////////////////////////////////////////
  525. bool CDACL::Find( PSID psid, BYTE bACEType, BYTE bACEFlags, GUID *pguidObjGuid, GUID *pguidInhObjGuid, DWORD dwAccessMask, CAccessEntry& ace )
  526. {
  527. bool fReturn = false;
  528. switch(bACEType)
  529. {
  530. case ACCESS_DENIED_ACE_TYPE:
  531. {
  532. if(bACEFlags & INHERITED_ACE)
  533. {
  534. if(m_rgDACLSections[ENUM_INH_ACCESS_DENIED_ACE_TYPE] != NULL)
  535. {
  536. fReturn = m_rgDACLSections[ENUM_INH_ACCESS_DENIED_ACE_TYPE]->Find( psid, bACEType, bACEFlags, pguidObjGuid, pguidInhObjGuid, dwAccessMask, ace );
  537. }
  538. }
  539. else
  540. {
  541. if(m_rgDACLSections[ENUM_ACCESS_DENIED_ACE_TYPE] != NULL)
  542. {
  543. fReturn = m_rgDACLSections[ENUM_ACCESS_DENIED_ACE_TYPE]->Find( psid, bACEType, bACEFlags, pguidObjGuid, pguidInhObjGuid, dwAccessMask, ace );
  544. }
  545. }
  546. break;
  547. }
  548. case ACCESS_DENIED_OBJECT_ACE_TYPE:
  549. {
  550. if(bACEFlags & INHERITED_ACE)
  551. {
  552. if(m_rgDACLSections[ENUM_INH_ACCESS_DENIED_OBJECT_ACE_TYPE] != NULL)
  553. {
  554. fReturn = m_rgDACLSections[ENUM_INH_ACCESS_DENIED_OBJECT_ACE_TYPE]->Find( psid, bACEType, bACEFlags, pguidObjGuid, pguidInhObjGuid, dwAccessMask, ace );
  555. }
  556. }
  557. else
  558. {
  559. if(m_rgDACLSections[ENUM_ACCESS_DENIED_OBJECT_ACE_TYPE] != NULL)
  560. {
  561. fReturn = m_rgDACLSections[ENUM_ACCESS_DENIED_OBJECT_ACE_TYPE]->Find( psid, bACEType, bACEFlags, pguidObjGuid, pguidInhObjGuid, dwAccessMask, ace );
  562. }
  563. }
  564. break;
  565. }
  566. case ACCESS_ALLOWED_ACE_TYPE:
  567. {
  568. if(bACEFlags & INHERITED_ACE)
  569. {
  570. if(m_rgDACLSections[ENUM_INH_ACCESS_ALLOWED_ACE_TYPE] != NULL)
  571. {
  572. fReturn = m_rgDACLSections[ENUM_INH_ACCESS_ALLOWED_ACE_TYPE]->Find( psid, bACEType, bACEFlags, pguidObjGuid, pguidInhObjGuid, dwAccessMask, ace );
  573. }
  574. }
  575. else
  576. {
  577. if(m_rgDACLSections[ENUM_ACCESS_ALLOWED_ACE_TYPE] != NULL)
  578. {
  579. fReturn = m_rgDACLSections[ENUM_ACCESS_ALLOWED_ACE_TYPE]->Find( psid, bACEType, bACEFlags, pguidObjGuid, pguidInhObjGuid, dwAccessMask, ace );
  580. }
  581. }
  582. break;
  583. }
  584. case ACCESS_ALLOWED_COMPOUND_ACE_TYPE:
  585. {
  586. if(bACEFlags & INHERITED_ACE)
  587. {
  588. if(m_rgDACLSections[ENUM_INH_ACCESS_ALLOWED_COMPOUND_ACE_TYPE] != NULL)
  589. {
  590. fReturn = m_rgDACLSections[ENUM_INH_ACCESS_ALLOWED_COMPOUND_ACE_TYPE]->Find( psid, bACEType, bACEFlags, pguidObjGuid, pguidInhObjGuid, dwAccessMask, ace );
  591. }
  592. }
  593. else
  594. {
  595. if(m_rgDACLSections[ENUM_ACCESS_ALLOWED_COMPOUND_ACE_TYPE] != NULL)
  596. {
  597. fReturn = m_rgDACLSections[ENUM_ACCESS_ALLOWED_COMPOUND_ACE_TYPE]->Find( psid, bACEType, bACEFlags, pguidObjGuid, pguidInhObjGuid, dwAccessMask, ace );
  598. }
  599. }
  600. break;
  601. }
  602. case ACCESS_ALLOWED_OBJECT_ACE_TYPE:
  603. {
  604. if(bACEFlags & INHERITED_ACE)
  605. {
  606. if(m_rgDACLSections[ENUM_INH_ACCESS_ALLOWED_OBJECT_ACE_TYPE] != NULL)
  607. {
  608. fReturn = m_rgDACLSections[ENUM_INH_ACCESS_ALLOWED_OBJECT_ACE_TYPE]->Find( psid, bACEType, bACEFlags, pguidObjGuid, pguidInhObjGuid, dwAccessMask, ace );
  609. }
  610. }
  611. else
  612. {
  613. if(m_rgDACLSections[ENUM_ACCESS_ALLOWED_OBJECT_ACE_TYPE] != NULL)
  614. {
  615. fReturn = m_rgDACLSections[ENUM_ACCESS_ALLOWED_OBJECT_ACE_TYPE]->Find( psid, bACEType, bACEFlags, pguidObjGuid, pguidInhObjGuid, dwAccessMask, ace );
  616. }
  617. }
  618. break;
  619. }
  620. default:
  621. {
  622. fReturn = false;
  623. }
  624. }
  625. return fReturn;
  626. }
  627. ///////////////////////////////////////////////////////////////////
  628. //
  629. // Function: CDACL::ConfigureDACL
  630. //
  631. // Configures a Win32 PACL with DACL information, maintaining
  632. // proper canonical order.
  633. //
  634. // Inputs:
  635. // None.
  636. //
  637. // Outputs:
  638. // PACL& pDacl - Pointer to a DACL.
  639. //
  640. // Returns:
  641. // DWORD ERROR_SUCCESS if successful.
  642. //
  643. // Comments:
  644. //
  645. ///////////////////////////////////////////////////////////////////
  646. DWORD CDACL::ConfigureDACL( PACL& pDacl )
  647. {
  648. DWORD dwReturn = ERROR_SUCCESS,
  649. dwDaclLength = 0;
  650. // Since we actually fake a NULL DACL with full control access for everyone.
  651. // If that's what we have, then we have what we call a NULL DACL, so we
  652. // shouldn't allocate a PACL.
  653. if ( !IsNULLDACL() )
  654. {
  655. if ( CalculateDACLSize( &dwDaclLength ) )
  656. {
  657. if ( 0 != dwDaclLength )
  658. {
  659. pDacl = NULL;
  660. try
  661. {
  662. pDacl = (PACL) malloc( dwDaclLength );
  663. if ( NULL != pDacl )
  664. {
  665. if ( !InitializeAcl( (PACL) pDacl, dwDaclLength, ACL_REVISION ) )
  666. {
  667. dwReturn = ::GetLastError();
  668. }
  669. } // If NULL != pDacl
  670. }
  671. catch(...)
  672. {
  673. if(pDacl != NULL)
  674. {
  675. free(pDacl);
  676. pDacl = NULL;
  677. }
  678. throw;
  679. }
  680. } // If 0 != dwDaclLength
  681. else // we have an empty dacl
  682. {
  683. pDacl = NULL;
  684. try
  685. {
  686. pDacl = (PACL) malloc( sizeof(ACL) );
  687. if ( NULL != pDacl )
  688. {
  689. if ( !InitializeAcl( (PACL) pDacl, sizeof(ACL), ACL_REVISION ) )
  690. {
  691. dwReturn = ::GetLastError();
  692. }
  693. } // If NULL != pDacl
  694. }
  695. catch(...)
  696. {
  697. if(pDacl != NULL)
  698. {
  699. free(pDacl);
  700. pDacl = NULL;
  701. }
  702. throw;
  703. }
  704. }
  705. } // If Calcaulate DACL Size
  706. else
  707. {
  708. dwReturn = ERROR_INVALID_PARAMETER; // One or more of the DACLs is bad
  709. }
  710. if ( ERROR_SUCCESS == dwReturn )
  711. {
  712. dwReturn = FillDACL( pDacl );
  713. }
  714. if ( ERROR_SUCCESS != dwReturn )
  715. {
  716. free( pDacl );
  717. pDacl = NULL;
  718. }
  719. } // IF !IsNULLDACL
  720. return dwReturn;
  721. }
  722. ///////////////////////////////////////////////////////////////////
  723. //
  724. // Function: CDACL::CalculateDACLSize
  725. //
  726. // Obtains the size necessary to populate a DACL.
  727. //
  728. // Inputs:
  729. // None.
  730. //
  731. // Outputs:
  732. // LPDWORD pdwDaclLength - Calculated Length.
  733. //
  734. // Returns:
  735. // BOOL TRUE/FALSE
  736. //
  737. // Comments:
  738. //
  739. ///////////////////////////////////////////////////////////////////
  740. BOOL CDACL::CalculateDACLSize( LPDWORD pdwDaclLength )
  741. {
  742. BOOL fReturn = TRUE;
  743. *pdwDaclLength = 0;
  744. for(short s = 0; s < NUM_DACL_TYPES && fReturn; s++)
  745. {
  746. if(m_rgDACLSections[s] != NULL)
  747. {
  748. fReturn = m_rgDACLSections[s]->CalculateWin32ACLSize( pdwDaclLength );
  749. }
  750. }
  751. return fReturn;
  752. }
  753. ///////////////////////////////////////////////////////////////////
  754. //
  755. // Function: CDACL::FillDACL
  756. //
  757. // Fills out a DACL, maintaining proper canonical order.
  758. //
  759. // Inputs:
  760. // PACL pDacl - Dacl to fill out.
  761. //
  762. // Outputs:
  763. // None.
  764. //
  765. // Returns:
  766. // BOOL TRUE/FALSE
  767. //
  768. // Comments:
  769. //
  770. ///////////////////////////////////////////////////////////////////
  771. DWORD CDACL::FillDACL( PACL pDacl )
  772. {
  773. DWORD dwReturn = E_FAIL;
  774. // For NT 5, we need to split out Inherited ACEs and add those in after the
  775. // current ones (which override). The real trick here, is that the canonical
  776. // order of Access Denied, Access Denied Object, Access Allowed, Access Allowed Compound, Access Allowed Object,
  777. // Inherited Access Denied, Inherrited Access Denied Object, Inherited Access Allowed, Inherrited Access Allowed Compound,
  778. // and Inherrited Access Allowed Object must be maintained.
  779. // For prior versions, the only canonical order is Access Denied followed
  780. // by Access Allowed.
  781. // Create a working dacl
  782. CAccessEntryList t_daclCombined;
  783. ReassembleFromCanonicalSections(t_daclCombined);
  784. dwReturn = t_daclCombined.FillWin32ACL(pDacl);
  785. return dwReturn;
  786. }
  787. ///////////////////////////////////////////////////////////////////
  788. //
  789. // Function: CDACL::SplitIntoCanonicalSections
  790. //
  791. // Splits a DACL by into its canonical parts.
  792. //
  793. // Inputs: accessentrylist to split up. Results stored with
  794. // this CDACL.
  795. //
  796. //
  797. // Returns:
  798. // None.
  799. //
  800. // Comments:
  801. //
  802. // Helps support NT 5 canonical order in DACLs.
  803. //
  804. ///////////////////////////////////////////////////////////////////
  805. bool CDACL::SplitIntoCanonicalSections
  806. (
  807. CAccessEntryList& a_aclIn
  808. )
  809. {
  810. for(short s = 0; s < NUM_DACL_TYPES; s++)
  811. {
  812. if(m_rgDACLSections[s] != NULL)
  813. {
  814. delete m_rgDACLSections[s];
  815. m_rgDACLSections[s] = NULL;
  816. }
  817. }
  818. CAccessEntryList t_aclTemp;
  819. bool fRet = false;
  820. fRet = t_aclTemp.CopyByACEType(a_aclIn, ACCESS_DENIED_ACE_TYPE, false);
  821. if(!t_aclTemp.IsEmpty())
  822. {
  823. try
  824. {
  825. m_rgDACLSections[ENUM_ACCESS_DENIED_ACE_TYPE] = new CAccessEntryList;
  826. }
  827. catch(...)
  828. {
  829. if(m_rgDACLSections[ENUM_ACCESS_DENIED_ACE_TYPE] != NULL)
  830. {
  831. delete m_rgDACLSections[ENUM_ACCESS_DENIED_ACE_TYPE];
  832. m_rgDACLSections[ENUM_ACCESS_DENIED_ACE_TYPE] = NULL;
  833. }
  834. throw;
  835. }
  836. m_rgDACLSections[ENUM_ACCESS_DENIED_ACE_TYPE]->Copy(t_aclTemp);
  837. t_aclTemp.Clear();
  838. }
  839. if(fRet)
  840. {
  841. fRet = t_aclTemp.CopyByACEType(a_aclIn, ACCESS_DENIED_OBJECT_ACE_TYPE, false);
  842. if(!t_aclTemp.IsEmpty())
  843. {
  844. try
  845. {
  846. m_rgDACLSections[ENUM_ACCESS_DENIED_OBJECT_ACE_TYPE] = new CAccessEntryList;
  847. }
  848. catch(...)
  849. {
  850. if(m_rgDACLSections[ENUM_ACCESS_DENIED_OBJECT_ACE_TYPE] != NULL)
  851. {
  852. delete m_rgDACLSections[ENUM_ACCESS_DENIED_OBJECT_ACE_TYPE];
  853. m_rgDACLSections[ENUM_ACCESS_DENIED_OBJECT_ACE_TYPE] = NULL;
  854. }
  855. throw;
  856. }
  857. m_rgDACLSections[ENUM_ACCESS_DENIED_OBJECT_ACE_TYPE]->Copy(t_aclTemp);
  858. t_aclTemp.Clear();
  859. }
  860. }
  861. if(fRet)
  862. {
  863. fRet = t_aclTemp.CopyByACEType(a_aclIn, ACCESS_ALLOWED_ACE_TYPE, false);
  864. if(!t_aclTemp.IsEmpty())
  865. {
  866. try
  867. {
  868. m_rgDACLSections[ENUM_ACCESS_ALLOWED_ACE_TYPE] = new CAccessEntryList;
  869. }
  870. catch(...)
  871. {
  872. if(m_rgDACLSections[ENUM_ACCESS_ALLOWED_ACE_TYPE]!= NULL)
  873. {
  874. delete m_rgDACLSections[ENUM_ACCESS_ALLOWED_ACE_TYPE];
  875. m_rgDACLSections[ENUM_ACCESS_ALLOWED_ACE_TYPE] = NULL;
  876. }
  877. throw;
  878. }
  879. m_rgDACLSections[ENUM_ACCESS_ALLOWED_ACE_TYPE]->Copy(t_aclTemp);
  880. t_aclTemp.Clear();
  881. }
  882. }
  883. if(fRet)
  884. {
  885. fRet = t_aclTemp.CopyByACEType(a_aclIn, ACCESS_ALLOWED_COMPOUND_ACE_TYPE, false);
  886. if(!t_aclTemp.IsEmpty())
  887. {
  888. try
  889. {
  890. m_rgDACLSections[ENUM_ACCESS_ALLOWED_COMPOUND_ACE_TYPE] = new CAccessEntryList;
  891. }
  892. catch(...)
  893. {
  894. if(m_rgDACLSections[ENUM_ACCESS_ALLOWED_COMPOUND_ACE_TYPE] != NULL)
  895. {
  896. delete m_rgDACLSections[ENUM_ACCESS_ALLOWED_COMPOUND_ACE_TYPE];
  897. m_rgDACLSections[ENUM_ACCESS_ALLOWED_COMPOUND_ACE_TYPE] = NULL;
  898. }
  899. throw;
  900. }
  901. m_rgDACLSections[ENUM_ACCESS_ALLOWED_COMPOUND_ACE_TYPE]->Copy(t_aclTemp);
  902. t_aclTemp.Clear();
  903. }
  904. }
  905. if(fRet)
  906. {
  907. fRet = t_aclTemp.CopyByACEType(a_aclIn, ACCESS_ALLOWED_OBJECT_ACE_TYPE, false);
  908. if(!t_aclTemp.IsEmpty())
  909. {
  910. try
  911. {
  912. m_rgDACLSections[ENUM_ACCESS_ALLOWED_OBJECT_ACE_TYPE] = new CAccessEntryList;
  913. }
  914. catch(...)
  915. {
  916. if(m_rgDACLSections[ENUM_ACCESS_ALLOWED_OBJECT_ACE_TYPE] != NULL)
  917. {
  918. delete m_rgDACLSections[ENUM_ACCESS_ALLOWED_OBJECT_ACE_TYPE];
  919. m_rgDACLSections[ENUM_ACCESS_ALLOWED_OBJECT_ACE_TYPE] = NULL;
  920. }
  921. throw;
  922. }
  923. m_rgDACLSections[ENUM_ACCESS_ALLOWED_OBJECT_ACE_TYPE]->Copy(t_aclTemp);
  924. t_aclTemp.Clear();
  925. }
  926. }
  927. if(fRet)
  928. {
  929. fRet = t_aclTemp.CopyByACEType(a_aclIn, ACCESS_DENIED_ACE_TYPE, true);
  930. if(!t_aclTemp.IsEmpty())
  931. {
  932. try
  933. {
  934. m_rgDACLSections[ENUM_INH_ACCESS_DENIED_ACE_TYPE] = new CAccessEntryList;
  935. }
  936. catch(...)
  937. {
  938. if(m_rgDACLSections[ENUM_INH_ACCESS_DENIED_ACE_TYPE] != NULL)
  939. {
  940. delete m_rgDACLSections[ENUM_INH_ACCESS_DENIED_ACE_TYPE];
  941. m_rgDACLSections[ENUM_INH_ACCESS_DENIED_ACE_TYPE] = NULL;
  942. }
  943. throw;
  944. }
  945. m_rgDACLSections[ENUM_INH_ACCESS_DENIED_ACE_TYPE]->Copy(t_aclTemp);
  946. t_aclTemp.Clear();
  947. }
  948. }
  949. if(fRet)
  950. {
  951. fRet = t_aclTemp.CopyByACEType(a_aclIn, ACCESS_DENIED_OBJECT_ACE_TYPE, true);
  952. if(!t_aclTemp.IsEmpty())
  953. {
  954. try
  955. {
  956. m_rgDACLSections[ENUM_INH_ACCESS_DENIED_OBJECT_ACE_TYPE] = new CAccessEntryList;
  957. }
  958. catch(...)
  959. {
  960. if(m_rgDACLSections[ENUM_INH_ACCESS_DENIED_OBJECT_ACE_TYPE] != NULL)
  961. {
  962. delete m_rgDACLSections[ENUM_INH_ACCESS_DENIED_OBJECT_ACE_TYPE];
  963. m_rgDACLSections[ENUM_INH_ACCESS_DENIED_OBJECT_ACE_TYPE] = NULL;
  964. }
  965. throw;
  966. }
  967. m_rgDACLSections[ENUM_INH_ACCESS_DENIED_OBJECT_ACE_TYPE]->Copy(t_aclTemp);
  968. t_aclTemp.Clear();
  969. }
  970. }
  971. if(fRet)
  972. {
  973. fRet = t_aclTemp.CopyByACEType(a_aclIn, ACCESS_ALLOWED_ACE_TYPE, true);
  974. if(!t_aclTemp.IsEmpty())
  975. {
  976. try
  977. {
  978. m_rgDACLSections[ENUM_INH_ACCESS_ALLOWED_ACE_TYPE] = new CAccessEntryList;
  979. }
  980. catch(...)
  981. {
  982. if(m_rgDACLSections[ENUM_INH_ACCESS_ALLOWED_ACE_TYPE] != NULL)
  983. {
  984. delete m_rgDACLSections[ENUM_INH_ACCESS_ALLOWED_ACE_TYPE];
  985. m_rgDACLSections[ENUM_INH_ACCESS_ALLOWED_ACE_TYPE] = NULL;
  986. }
  987. throw;
  988. }
  989. m_rgDACLSections[ENUM_INH_ACCESS_ALLOWED_ACE_TYPE]->Copy(t_aclTemp);
  990. t_aclTemp.Clear();
  991. }
  992. }
  993. if(fRet)
  994. {
  995. fRet = t_aclTemp.CopyByACEType(a_aclIn, ACCESS_ALLOWED_COMPOUND_ACE_TYPE, true);
  996. if(!t_aclTemp.IsEmpty())
  997. {
  998. try
  999. {
  1000. m_rgDACLSections[ENUM_INH_ACCESS_ALLOWED_COMPOUND_ACE_TYPE] = new CAccessEntryList;
  1001. }
  1002. catch(...)
  1003. {
  1004. if(m_rgDACLSections[ENUM_INH_ACCESS_ALLOWED_COMPOUND_ACE_TYPE] != NULL)
  1005. {
  1006. delete m_rgDACLSections[ENUM_INH_ACCESS_ALLOWED_COMPOUND_ACE_TYPE];
  1007. m_rgDACLSections[ENUM_INH_ACCESS_ALLOWED_COMPOUND_ACE_TYPE] = NULL;
  1008. }
  1009. throw;
  1010. }
  1011. m_rgDACLSections[ENUM_INH_ACCESS_ALLOWED_COMPOUND_ACE_TYPE]->Copy(t_aclTemp);
  1012. t_aclTemp.Clear();
  1013. }
  1014. }
  1015. if(fRet)
  1016. {
  1017. fRet = t_aclTemp.CopyByACEType(a_aclIn, ACCESS_ALLOWED_OBJECT_ACE_TYPE, true);
  1018. if(!t_aclTemp.IsEmpty())
  1019. {
  1020. try
  1021. {
  1022. m_rgDACLSections[ENUM_INH_ACCESS_ALLOWED_OBJECT_ACE_TYPE] = new CAccessEntryList;
  1023. }
  1024. catch(...)
  1025. {
  1026. if(m_rgDACLSections[ENUM_INH_ACCESS_ALLOWED_OBJECT_ACE_TYPE] != NULL)
  1027. {
  1028. delete m_rgDACLSections[ENUM_INH_ACCESS_ALLOWED_OBJECT_ACE_TYPE];
  1029. m_rgDACLSections[ENUM_INH_ACCESS_ALLOWED_OBJECT_ACE_TYPE] = NULL;
  1030. }
  1031. throw;
  1032. }
  1033. m_rgDACLSections[ENUM_INH_ACCESS_ALLOWED_OBJECT_ACE_TYPE]->Copy(t_aclTemp);
  1034. t_aclTemp.Clear();
  1035. }
  1036. }
  1037. return fRet;
  1038. }
  1039. ///////////////////////////////////////////////////////////////////
  1040. //
  1041. // Function: CDACL::ReassembleFromCanonicalSections
  1042. //
  1043. // Reassembles a DACL by from its canonical parts.
  1044. //
  1045. // Inputs: reference to accessentrylist that gets built up.
  1046. // Comments:
  1047. //
  1048. // Helps support NT 5 canonical order in DACLs.
  1049. //
  1050. ///////////////////////////////////////////////////////////////////
  1051. bool CDACL::ReassembleFromCanonicalSections
  1052. (
  1053. CAccessEntryList& a_aclIn
  1054. )
  1055. {
  1056. bool fRet = true;
  1057. // and reassemble a new one (we rely on the fact that the enumeration
  1058. // was layed out in the proper order) ...
  1059. for(short s = 0; s < NUM_DACL_TYPES; s++)
  1060. {
  1061. if(m_rgDACLSections[s] != NULL)
  1062. {
  1063. fRet = a_aclIn.AppendList(*m_rgDACLSections[s]);
  1064. }
  1065. }
  1066. return fRet;
  1067. }
  1068. bool CDACL::PutInNT5CanonicalOrder()
  1069. {
  1070. bool t_fRet = false;
  1071. CAccessEntryList t_ael;
  1072. if(SplitIntoCanonicalSections(t_ael))
  1073. {
  1074. t_fRet = ReassembleFromCanonicalSections(t_ael);
  1075. }
  1076. return t_fRet;
  1077. }
  1078. bool CDACL::GetMergedACL
  1079. (
  1080. CAccessEntryList& a_aclIn
  1081. )
  1082. {
  1083. return ReassembleFromCanonicalSections(a_aclIn);
  1084. }
  1085. void CDACL::Clear()
  1086. {
  1087. for(short s = 0; s < NUM_DACL_TYPES; s++)
  1088. {
  1089. if(m_rgDACLSections[s] != NULL)
  1090. {
  1091. delete m_rgDACLSections[s];
  1092. m_rgDACLSections[s] = NULL;
  1093. }
  1094. }
  1095. }
  1096. bool CDACL::CopyDACL ( CDACL& dacl )
  1097. {
  1098. bool fRet = true;
  1099. Clear();
  1100. for(short s = 0; s < NUM_DACL_TYPES && fRet; s++)
  1101. {
  1102. if(dacl.m_rgDACLSections[s] != NULL)
  1103. {
  1104. try
  1105. {
  1106. m_rgDACLSections[s] = new CAccessEntryList;
  1107. }
  1108. catch(...)
  1109. {
  1110. if(m_rgDACLSections[s] != NULL)
  1111. {
  1112. delete m_rgDACLSections[s];
  1113. m_rgDACLSections[s] = NULL;
  1114. }
  1115. throw;
  1116. }
  1117. if(m_rgDACLSections[s] != NULL)
  1118. {
  1119. fRet = m_rgDACLSections[s]->Copy(*(dacl.m_rgDACLSections[s]));
  1120. }
  1121. else
  1122. {
  1123. fRet = false;
  1124. }
  1125. }
  1126. }
  1127. return fRet;
  1128. }
  1129. bool CDACL::AppendDACL ( CDACL& dacl )
  1130. {
  1131. bool fRet = true;
  1132. for(short s = 0; s < NUM_DACL_TYPES && fRet; s++)
  1133. {
  1134. if(dacl.m_rgDACLSections[s] != NULL)
  1135. {
  1136. if(m_rgDACLSections[s] == NULL)
  1137. {
  1138. try
  1139. {
  1140. m_rgDACLSections[s] = new CAccessEntryList;
  1141. }
  1142. catch(...)
  1143. {
  1144. if(m_rgDACLSections[s] != NULL)
  1145. {
  1146. delete m_rgDACLSections[s];
  1147. m_rgDACLSections[s] = NULL;
  1148. }
  1149. throw;
  1150. }
  1151. }
  1152. if(m_rgDACLSections[s] != NULL)
  1153. {
  1154. fRet = m_rgDACLSections[s]->AppendList(*(dacl.m_rgDACLSections[s]));
  1155. }
  1156. else
  1157. {
  1158. fRet = false;
  1159. }
  1160. }
  1161. }
  1162. return fRet;
  1163. }
  1164. ///////////////////////////////////////////////////////////////////
  1165. //
  1166. // Function: CSecurityDescriptor::IsNULLDACL
  1167. //
  1168. // Checks our DACL Lists to see if we have a NULL DACL. Which
  1169. // means that all our lists are NULL, except for the
  1170. // ACCESS_ALLOWED_ACE_TYPE list, which will have exactly one entry
  1171. // in it - namely, an ACE for Everyone.
  1172. //
  1173. // Inputs:
  1174. // None.
  1175. //
  1176. // Outputs:
  1177. // None.
  1178. //
  1179. // Returns:
  1180. // BOOL TRUE/FALSE
  1181. //
  1182. // Comments:
  1183. //
  1184. // Remember, a NULL DACL is the same as "Everyone" has Full Control,
  1185. // so if a single Access Allowed entry exists that meets these
  1186. // criteria, we consider ourselves to be NULL.
  1187. //
  1188. ///////////////////////////////////////////////////////////////////
  1189. bool CDACL::IsNULLDACL()
  1190. {
  1191. bool fReturn = false;
  1192. // We have a NULL DACL if all the elements of our DACL array
  1193. // are NULL
  1194. if (m_rgDACLSections[ENUM_ACCESS_DENIED_ACE_TYPE] == NULL &&
  1195. m_rgDACLSections[ENUM_ACCESS_DENIED_OBJECT_ACE_TYPE] == NULL &&
  1196. m_rgDACLSections[ENUM_ACCESS_ALLOWED_COMPOUND_ACE_TYPE] == NULL &&
  1197. m_rgDACLSections[ENUM_ACCESS_ALLOWED_OBJECT_ACE_TYPE] == NULL &&
  1198. m_rgDACLSections[ENUM_INH_ACCESS_DENIED_ACE_TYPE] == NULL &&
  1199. m_rgDACLSections[ENUM_INH_ACCESS_DENIED_OBJECT_ACE_TYPE] == NULL &&
  1200. m_rgDACLSections[ENUM_INH_ACCESS_ALLOWED_ACE_TYPE] == NULL &&
  1201. m_rgDACLSections[ENUM_INH_ACCESS_ALLOWED_COMPOUND_ACE_TYPE] == NULL &&
  1202. m_rgDACLSections[ENUM_INH_ACCESS_ALLOWED_OBJECT_ACE_TYPE] == NULL)
  1203. {
  1204. if(m_rgDACLSections[ENUM_ACCESS_ALLOWED_ACE_TYPE] != NULL)
  1205. {
  1206. // There can be only one.
  1207. if(m_rgDACLSections[ENUM_ACCESS_ALLOWED_ACE_TYPE]->NumEntries() == 1)
  1208. {
  1209. CSid sid(_T("Everyone"));
  1210. CAccessEntry ace;
  1211. // Get the entry and check that it is "Everyone" with
  1212. // Full Control and no flags
  1213. if (m_rgDACLSections[ENUM_ACCESS_ALLOWED_ACE_TYPE]->GetAt( 0, ace ) )
  1214. {
  1215. CSid aceSID;
  1216. ace.GetSID( aceSID );
  1217. fReturn = ( sid == aceSID
  1218. && ace.GetAccessMask() == AllAccessMask()
  1219. && ace.GetACEFlags() == 0 );
  1220. }
  1221. } // IF only one entry
  1222. }
  1223. } // If we had entries in other lists, no go.
  1224. return fReturn;
  1225. }
  1226. ///////////////////////////////////////////////////////////////////
  1227. //
  1228. // Function: CDACL::IsEmpty
  1229. //
  1230. // Checks if our various lists are empty.
  1231. //
  1232. // Inputs:
  1233. // None.
  1234. //
  1235. // Outputs:
  1236. // None.
  1237. //
  1238. // Returns:
  1239. // bool true if we have at least one entry in at
  1240. // least one of our lists.
  1241. //
  1242. // Comments:
  1243. //
  1244. //
  1245. ///////////////////////////////////////////////////////////////////
  1246. bool CDACL::IsEmpty()
  1247. {
  1248. bool fIsEmpty = true;
  1249. for(short s = 0; s < NUM_DACL_TYPES && fIsEmpty; s++)
  1250. {
  1251. if(m_rgDACLSections[s] != NULL)
  1252. {
  1253. fIsEmpty = m_rgDACLSections[s]->IsEmpty();
  1254. }
  1255. }
  1256. return fIsEmpty;
  1257. }
  1258. ///////////////////////////////////////////////////////////////////
  1259. //
  1260. // Function: CDACL::CreateNullDacl
  1261. //
  1262. // NULLs out our DACL Lists except for the ACCESS_ALLOWED_ACE_TYPE
  1263. // list, which it clears, then enters an Everybody ace into.
  1264. //
  1265. // Inputs:
  1266. // None.
  1267. //
  1268. // Outputs:
  1269. // None.
  1270. //
  1271. // Returns:
  1272. // BOOL TRUE/FALSE
  1273. //
  1274. // Comments:
  1275. //
  1276. // Remember, an empty DACL is different from a NULL DACL, in that
  1277. // empty means nobody has access and NULL means everyone has
  1278. // full control.
  1279. //
  1280. ///////////////////////////////////////////////////////////////////
  1281. bool CDACL::CreateNullDACL()
  1282. {
  1283. bool fReturn = false;
  1284. // Clear out our DACLs first...
  1285. for(short s = 0; s < NUM_DACL_TYPES; s++)
  1286. {
  1287. if(m_rgDACLSections[s] != NULL)
  1288. {
  1289. delete m_rgDACLSections[s];
  1290. m_rgDACLSections[s] = NULL;
  1291. }
  1292. }
  1293. // then allocate an ACCESS_ALLOWED_ACE_TYPE dacl...
  1294. try
  1295. {
  1296. m_rgDACLSections[ENUM_ACCESS_ALLOWED_ACE_TYPE] = new CAccessEntryList;
  1297. }
  1298. catch(...)
  1299. {
  1300. if(m_rgDACLSections[ENUM_ACCESS_ALLOWED_ACE_TYPE] != NULL)
  1301. {
  1302. delete m_rgDACLSections[ENUM_ACCESS_ALLOWED_ACE_TYPE];
  1303. m_rgDACLSections[ENUM_ACCESS_ALLOWED_ACE_TYPE] = NULL;
  1304. }
  1305. throw;
  1306. }
  1307. // then fake a null dacl by adding an Everyone entry...
  1308. if (m_rgDACLSections[ENUM_ACCESS_ALLOWED_ACE_TYPE] != NULL)
  1309. {
  1310. CSid sid( _T("Everyone") );
  1311. if(sid.IsOK() && sid.IsValid())
  1312. {
  1313. fReturn = m_rgDACLSections[ENUM_ACCESS_ALLOWED_ACE_TYPE]->AppendNoDup(sid.GetPSid(),
  1314. ACCESS_ALLOWED_ACE_TYPE,
  1315. CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE,
  1316. AllAccessMask(),
  1317. NULL,
  1318. NULL,
  1319. false,
  1320. false);
  1321. }
  1322. }
  1323. return fReturn;
  1324. }
  1325. DWORD CDACL::AllAccessMask()
  1326. {
  1327. return GENERIC_ALL;
  1328. //return 0x01FFFFFF;
  1329. }
  1330. void CDACL::DumpDACL(LPCWSTR wstrFilename)
  1331. {
  1332. CAccessEntryList aelCombo;
  1333. Output(L"DACL contents follow...", wstrFilename);
  1334. if(ReassembleFromCanonicalSections(aelCombo))
  1335. {
  1336. aelCombo.DumpAccessEntryList(wstrFilename);
  1337. }
  1338. }