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.

2058 lines
46 KiB

  1. /*****************************************************************************/
  2. /* Copyright (c) 1999-2001 Microsoft Corporation, All Rights Reserved /
  3. /*****************************************************************************/
  4. /*
  5. * SecurityDescriptor.cpp - implementation file for CSecurityDescriptor 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 "AccessEntry.h" // CAccessEntry class
  13. #include "AccessEntryList.h"
  14. #include "aclapi.h"
  15. #include "DACL.h" // CDACL class
  16. #include "SACL.h" // CSACL class
  17. #include "SecurityDescriptor.h"
  18. #include "TokenPrivilege.h"
  19. #include "AdvApi32Api.h"
  20. #include "accctrl.h"
  21. #include "wbemnetapi32.h"
  22. #include "SecUtils.h"
  23. /*
  24. * This constructor is the default
  25. */
  26. ///////////////////////////////////////////////////////////////////
  27. //
  28. // Function: CSecurityDescriptor::CSecurityDescriptor
  29. //
  30. // Default class constructor.
  31. //
  32. // Inputs:
  33. // None.
  34. //
  35. // Outputs:
  36. // None.
  37. //
  38. // Returns:
  39. // None.
  40. //
  41. // Comments:
  42. //
  43. ///////////////////////////////////////////////////////////////////
  44. CSecurityDescriptor::CSecurityDescriptor()
  45. : m_pOwnerSid( NULL ),
  46. m_pGroupSid( NULL ),
  47. m_pSACL( NULL ),
  48. m_pDACL(NULL),
  49. m_fOwnerDefaulted( false ),
  50. m_fGroupDefaulted( false ),
  51. m_fDACLDefaulted( false ),
  52. m_fSACLDefaulted( false ),
  53. m_fDaclAutoInherited( false ),
  54. m_fSaclAutoInherited( false ),
  55. m_SecurityDescriptorControl(0)
  56. {
  57. }
  58. ///////////////////////////////////////////////////////////////////
  59. //
  60. // Function: CSecurityDescriptor::CSecurityDescriptor
  61. //
  62. // Alternate class constructor.
  63. //
  64. // Inputs:
  65. // PSECURITY_DESCRIPTOR psd - descriptor to initialize
  66. // from.
  67. //
  68. // Outputs:
  69. // None.
  70. //
  71. // Returns:
  72. // None.
  73. //
  74. // Comments:
  75. //
  76. ///////////////////////////////////////////////////////////////////
  77. CSecurityDescriptor::CSecurityDescriptor( PSECURITY_DESCRIPTOR psd )
  78. : m_pOwnerSid( NULL ),
  79. m_pGroupSid( NULL ),
  80. m_pSACL( NULL ),
  81. m_pDACL(NULL),
  82. m_fOwnerDefaulted( false ),
  83. m_fGroupDefaulted( false ),
  84. m_fDACLDefaulted( false ),
  85. m_fSACLDefaulted( false ),
  86. m_fDaclAutoInherited( false ),
  87. m_fSaclAutoInherited( false ),
  88. m_SecurityDescriptorControl(0)
  89. {
  90. InitSecurity( psd );
  91. }
  92. ///////////////////////////////////////////////////////////////////
  93. //
  94. // Function: CSecurityDescriptor::CSecurityDescriptor
  95. //
  96. // Alternate class constructor.
  97. //
  98. //
  99. // Outputs:
  100. // None.
  101. //
  102. // Returns:
  103. // None.
  104. //
  105. // Comments:
  106. //
  107. ///////////////////////////////////////////////////////////////////
  108. CSecurityDescriptor::CSecurityDescriptor
  109. (
  110. CSid* a_psidOwner,
  111. bool a_fOwnerDefaulted,
  112. CSid* a_psidGroup,
  113. bool a_fGroupDefaulted,
  114. CDACL* a_pDacl,
  115. bool a_fDaclDefaulted,
  116. bool a_fDaclAutoInherited,
  117. CSACL* a_pSacl,
  118. bool a_fSaclDefaulted,
  119. bool a_fSaclAutoInherited
  120. )
  121. : m_pOwnerSid( NULL ),
  122. m_pGroupSid( NULL ),
  123. m_pSACL( NULL ),
  124. m_pDACL(NULL),
  125. m_fOwnerDefaulted( false ),
  126. m_fGroupDefaulted( false ),
  127. m_fDACLDefaulted( false ),
  128. m_fSACLDefaulted( false ),
  129. m_fDaclAutoInherited( false ),
  130. m_fSaclAutoInherited( false ),
  131. m_SecurityDescriptorControl(0)
  132. {
  133. try
  134. {
  135. bool fRet = true;
  136. if(a_psidOwner != NULL )
  137. {
  138. fRet = (SetOwner(*a_psidOwner) == ERROR_SUCCESS);
  139. if(fRet)
  140. {
  141. m_fOwnerDefaulted = a_fOwnerDefaulted;
  142. }
  143. }
  144. if(fRet)
  145. {
  146. if(a_psidGroup != NULL )
  147. {
  148. fRet = (SetGroup(*a_psidGroup) == ERROR_SUCCESS);
  149. if(fRet)
  150. {
  151. m_fGroupDefaulted = a_fGroupDefaulted;
  152. }
  153. }
  154. }
  155. if(fRet)
  156. {
  157. // Handle the DACL
  158. if(a_pDacl != NULL)
  159. {
  160. fRet = InitDACL(a_pDacl);
  161. if(fRet)
  162. {
  163. m_fDACLDefaulted = a_fDaclDefaulted;
  164. m_fDaclAutoInherited = a_fDaclAutoInherited;
  165. }
  166. }
  167. }
  168. // Handle the SACL
  169. if(fRet)
  170. {
  171. if(a_pSacl != NULL)
  172. {
  173. fRet = InitSACL(a_pSacl);
  174. if(fRet)
  175. {
  176. m_fSACLDefaulted = a_fSaclDefaulted;
  177. m_fSaclAutoInherited = a_fSaclAutoInherited;
  178. }
  179. }
  180. }
  181. // Clean us up if something beefed
  182. if(!fRet)
  183. {
  184. Clear();
  185. }
  186. }
  187. catch(...)
  188. {
  189. Clear();
  190. throw;
  191. }
  192. }
  193. ///////////////////////////////////////////////////////////////////
  194. //
  195. // Function: CSecurityDescriptor::~CSecurityDescriptor
  196. //
  197. // Class Destructor.
  198. //
  199. // Inputs:
  200. // None.
  201. //
  202. // Outputs:
  203. // None.
  204. //
  205. // Returns:
  206. // None.
  207. //
  208. // Comments:
  209. //
  210. ///////////////////////////////////////////////////////////////////
  211. CSecurityDescriptor::~CSecurityDescriptor( void )
  212. {
  213. Clear();
  214. }
  215. ///////////////////////////////////////////////////////////////////
  216. //
  217. // Function: CSecurityDescriptor::IsNT5
  218. //
  219. // Tells us if we're running on NT 5 or not, in which case
  220. // we need to do some special handling.
  221. //
  222. // Inputs:
  223. // None.
  224. //
  225. // Outputs:
  226. // None.
  227. //
  228. // Returns:
  229. // BOOL TRUE/FALSE
  230. //
  231. // Comments:
  232. //
  233. ///////////////////////////////////////////////////////////////////
  234. ///////////////////////////////////////////////////////////////////
  235. //
  236. // Function: CSecurityDescriptor::InitSecurity
  237. //
  238. // Initializes the class with data from the supplied security
  239. // descriptor.
  240. //
  241. // Inputs:
  242. // PSECURITY_DESCRIPTOR psd - Security Descriptor
  243. //
  244. // Outputs:
  245. // None.
  246. //
  247. // Returns:
  248. // TRUE/FALSE Success/Failure.
  249. //
  250. // Comments:
  251. //
  252. // Keep this function protected so only derived classes have
  253. // access to laying waste to our internals.
  254. //
  255. ///////////////////////////////////////////////////////////////////
  256. BOOL CSecurityDescriptor::InitSecurity( PSECURITY_DESCRIPTOR psd )
  257. {
  258. BOOL fReturn = FALSE;
  259. PSID psid = NULL;
  260. DWORD dwRevision = 0;
  261. SECURITY_DESCRIPTOR_CONTROL Control;
  262. BOOL bTemp;
  263. // Clean up existing values.
  264. Clear();
  265. // Get the security descriptor Owner Sid.
  266. fReturn = GetSecurityDescriptorOwner( psd, &psid, &bTemp );
  267. if ( fReturn )
  268. {
  269. // As long as we have a psid, intialize the owner member
  270. if ( NULL != psid )
  271. {
  272. if(SetOwner(CSid(psid)) != ERROR_SUCCESS)
  273. {
  274. fReturn = FALSE;
  275. }
  276. }
  277. }
  278. else
  279. {
  280. bTemp = FALSE;
  281. }
  282. bTemp ? m_fOwnerDefaulted = true : m_fOwnerDefaulted = false;
  283. fReturn = GetSecurityDescriptorGroup (psd, &psid, &bTemp );
  284. if ( fReturn )
  285. {
  286. // as long as we have a psid, initialize the group member
  287. if ( NULL != psid )
  288. {
  289. if(SetGroup(CSid(psid)) != ERROR_SUCCESS)
  290. {
  291. fReturn = FALSE;
  292. }
  293. }
  294. }
  295. else
  296. {
  297. bTemp = FALSE;
  298. }
  299. bTemp ? m_fGroupDefaulted = true : m_fGroupDefaulted = false;
  300. fReturn = GetSecurityDescriptorControl( psd, &Control, &dwRevision);
  301. if (fReturn)
  302. {
  303. SetControl( &Control );
  304. // BAD, BAD, BAD, BAD
  305. }
  306. // Handle the DACL and then the SACL
  307. if ( fReturn )
  308. {
  309. fReturn = InitDACL( psd );
  310. }
  311. if ( fReturn )
  312. {
  313. fReturn = InitSACL( psd );
  314. }
  315. // Clean us up if something beefed
  316. if ( !fReturn )
  317. {
  318. Clear();
  319. }
  320. return fReturn;
  321. }
  322. ///////////////////////////////////////////////////////////////////
  323. //
  324. // Function: CSecurityDescriptor::InitDACL
  325. //
  326. // Initializes the DACL data member.
  327. //
  328. // Inputs:
  329. // PSECURITY_DESCRIPTOR psd - Security Descriptor
  330. //
  331. // Outputs:
  332. // None.
  333. //
  334. // Returns:
  335. // TRUE/FALSE Success/Failure.
  336. //
  337. // Comments:
  338. //
  339. ///////////////////////////////////////////////////////////////////
  340. BOOL CSecurityDescriptor::InitDACL ( PSECURITY_DESCRIPTOR psd )
  341. {
  342. BOOL fReturn = FALSE,
  343. fDACLPresent = FALSE,
  344. fDACLDefaulted = FALSE;
  345. PACL pDACL = NULL;
  346. if ( GetSecurityDescriptorDacl( psd, &fDACLPresent, &pDACL, &fDACLDefaulted ) )
  347. {
  348. ACE_HEADER* pACEHeader = NULL;
  349. DWORD dwAceIndex = 0;
  350. BOOL fGotACE = FALSE;
  351. // Be optimistic. Shut up, be happy, etc.
  352. fReturn = TRUE;
  353. // Note that although fDACLPresent is SUPPOSED to tell us whether or not the
  354. // DACL is there, I'm seeing cases when this is returning TRUE, but the pDACL
  355. // value is NULL. Not what the documenetation sez, but I'll take reality.
  356. if (fDACLPresent && (pDACL != NULL))
  357. {
  358. // Create a working dacl and initialize it with all ace entries...
  359. if(m_pDACL != NULL)
  360. {
  361. delete m_pDACL;
  362. m_pDACL = NULL;
  363. }
  364. try
  365. {
  366. m_pDACL = new CDACL;
  367. }
  368. catch(...)
  369. {
  370. if(m_pDACL != NULL)
  371. {
  372. delete m_pDACL;
  373. m_pDACL = NULL;
  374. }
  375. throw;
  376. }
  377. if(m_pDACL != NULL)
  378. {
  379. if(m_pDACL->Init(pDACL) == ERROR_SUCCESS)
  380. {
  381. fReturn = TRUE;
  382. // Allocated a dacl for that type only if an entry of that type was present.
  383. // If we had an empty dacl (dacl present, yet empty), we won't have allocated
  384. // any dacls in the array m_rgDACLPtrArray. This won't be confused with a NULL
  385. // DACL, as this module knows that it always represents a NULL DACL as all of
  386. // the elements of m_rgDACLPtrArray as null except for ACCESS_ALLOWED_OBJECT,
  387. // which will have one entry - namely, the Everyone ace.
  388. }
  389. }
  390. } // IF fDACL Present
  391. else
  392. {
  393. if(m_pDACL != NULL)
  394. {
  395. delete m_pDACL;
  396. m_pDACL = NULL;
  397. }
  398. try
  399. {
  400. m_pDACL = new CDACL;
  401. }
  402. catch(...)
  403. {
  404. if(m_pDACL != NULL)
  405. {
  406. delete m_pDACL;
  407. m_pDACL = NULL;
  408. }
  409. throw;
  410. }
  411. if(m_pDACL != NULL)
  412. {
  413. fReturn = m_pDACL->CreateNullDACL(); // No DACL, so gin up an Empty Dacl
  414. }
  415. }
  416. } // IF Got DACL
  417. return fReturn;
  418. }
  419. // Another version
  420. bool CSecurityDescriptor::InitDACL( CDACL* a_pDACL )
  421. {
  422. bool fRet = false;
  423. if (a_pDACL != NULL)
  424. {
  425. // Create a working dacl and initialize it with all ace entries...
  426. if(m_pDACL != NULL)
  427. {
  428. delete m_pDACL;
  429. m_pDACL = NULL;
  430. }
  431. try
  432. {
  433. m_pDACL = new CDACL;
  434. }
  435. catch(...)
  436. {
  437. if(m_pDACL != NULL)
  438. {
  439. delete m_pDACL;
  440. m_pDACL = NULL;
  441. }
  442. throw;
  443. }
  444. if(m_pDACL != NULL)
  445. {
  446. if(m_pDACL->CopyDACL(*a_pDACL))
  447. {
  448. fRet = true;
  449. // Allocated a dacl for that type only if an entry of that type was present.
  450. // If we had an empty dacl (dacl present, yet empty), we won't have allocated
  451. // any dacls in the array m_rgDACLPtrArray. This won't be confused with a NULL
  452. // DACL, as this module knows that it always represents a NULL DACL as all of
  453. // the elements of m_rgDACLPtrArray as null except for ACCESS_ALLOWED_OBJECT,
  454. // which will have one entry - namely, the Everyone ace.
  455. }
  456. }
  457. } // IF fDACL Present
  458. else
  459. {
  460. if(m_pDACL != NULL)
  461. {
  462. delete m_pDACL;
  463. m_pDACL = NULL;
  464. }
  465. try
  466. {
  467. m_pDACL = new CDACL;
  468. }
  469. catch(...)
  470. {
  471. if(m_pDACL != NULL)
  472. {
  473. delete m_pDACL;
  474. m_pDACL = NULL;
  475. }
  476. throw;
  477. }
  478. if(m_pDACL != NULL)
  479. {
  480. fRet = m_pDACL->CreateNullDACL(); // No DACL, so gin up an Empty Dacl
  481. }
  482. }
  483. return fRet;
  484. }
  485. ///////////////////////////////////////////////////////////////////
  486. //
  487. // Function: CSecurityDescriptor::InitSACL
  488. //
  489. // Initializes the SACL data member.
  490. //
  491. // Inputs:
  492. // PSECURITY_DESCRIPTOR psd - Security Descriptor
  493. //
  494. // Outputs:
  495. // None.
  496. //
  497. // Returns:
  498. // TRUE/FALSE Success/Failure.
  499. //
  500. // Comments:
  501. //
  502. ///////////////////////////////////////////////////////////////////
  503. BOOL CSecurityDescriptor::InitSACL ( PSECURITY_DESCRIPTOR psd )
  504. {
  505. BOOL fReturn = FALSE,
  506. fSACLPresent = FALSE,
  507. fSACLDefaulted = FALSE;
  508. PACL pSACL = NULL;
  509. if ( GetSecurityDescriptorSacl( psd, &fSACLPresent, &pSACL, &fSACLDefaulted ) )
  510. {
  511. // Be optimistic. Shut up, be happy, etc.
  512. fReturn = TRUE;
  513. // Note that although fSACLPresent is SUPPOSED to tell us whether or not the
  514. // SACL is there, I'm seeing cases when this is returning TRUE, but the pSACL
  515. // value is NULL. Not what the documenetation sez, but I'll take reality
  516. // for a thousand, Alex.
  517. if ( fSACLPresent
  518. && NULL != pSACL )
  519. {
  520. // Allocate SACL although it may stay empty
  521. if(m_pSACL != NULL)
  522. {
  523. delete m_pSACL;
  524. m_pSACL = NULL;
  525. }
  526. try
  527. {
  528. m_pSACL = new CSACL;
  529. }
  530. catch(...)
  531. {
  532. if(m_pSACL != NULL)
  533. {
  534. delete m_pSACL;
  535. m_pSACL = NULL;
  536. }
  537. throw;
  538. }
  539. if(m_pSACL != NULL)
  540. {
  541. if(m_pSACL->Init(pSACL) == ERROR_SUCCESS)
  542. {
  543. fReturn = TRUE;
  544. }
  545. }
  546. } // IF fSACL Present
  547. else
  548. {
  549. fReturn = TRUE; // No SACL, so no worries
  550. }
  551. } // IF Got SACL
  552. return fReturn;
  553. }
  554. // Another version...
  555. bool CSecurityDescriptor::InitSACL( CSACL* a_pSACL )
  556. {
  557. bool fRet = false;
  558. if (a_pSACL != NULL)
  559. {
  560. // Allocate SACL although it may stay empty
  561. if(m_pSACL != NULL)
  562. {
  563. delete m_pSACL;
  564. m_pSACL = NULL;
  565. }
  566. try
  567. {
  568. m_pSACL = new CSACL;
  569. }
  570. catch(...)
  571. {
  572. if(m_pSACL != NULL)
  573. {
  574. delete m_pSACL;
  575. m_pSACL = NULL;
  576. }
  577. throw;
  578. }
  579. if(m_pSACL != NULL)
  580. {
  581. if(m_pSACL->CopySACL(*a_pSACL))
  582. {
  583. fRet = true;
  584. }
  585. }
  586. } // IF fSACL Present
  587. else
  588. {
  589. fRet = true; // No SACL, so no worries
  590. }
  591. return fRet;
  592. }
  593. ///////////////////////////////////////////////////////////////////
  594. //
  595. // Function: CSecurityDescriptor::SecureObject
  596. //
  597. // Private entry point function which takes an Absolute Security
  598. // Descriptor, and depending on the user supplied security
  599. // information flags, divvies the actual object security handling
  600. // out to the appropriate WriteOwner() and WriteAcls() virtual
  601. // functions.
  602. //
  603. // Inputs:
  604. // PSECURITY_DESCRIPTOR pAbsoluteSD - Security Descriptor
  605. // SECURITY_INFORMATION securityinfo - Security flags.
  606. //
  607. // Outputs:
  608. // None.
  609. //
  610. // Returns:
  611. // DWORD ERROR_SUCCESS if ok.
  612. //
  613. // Comments:
  614. //
  615. ///////////////////////////////////////////////////////////////////
  616. DWORD CSecurityDescriptor::SecureObject( PSECURITY_DESCRIPTOR pAbsoluteSD, SECURITY_INFORMATION securityinfo )
  617. {
  618. DWORD dwReturn = ERROR_SUCCESS;
  619. // We might need this guy to handle some special access stuff
  620. CTokenPrivilege restorePrivilege( SE_RESTORE_NAME );
  621. //try to set the owner first, since setting the dacl may preclude setting the owner, depending on what access we set
  622. if ( securityinfo & OWNER_SECURITY_INFORMATION )
  623. {
  624. dwReturn = WriteOwner( pAbsoluteSD ) ;
  625. if ( ERROR_INVALID_OWNER == dwReturn )
  626. {
  627. // If we enable the privilege, retry setting the owner info
  628. if ( ERROR_SUCCESS == restorePrivilege.Enable() )
  629. {
  630. dwReturn = WriteOwner( pAbsoluteSD );
  631. // Clear the privilege
  632. restorePrivilege.Enable( FALSE );
  633. }
  634. }
  635. }
  636. // If we need to write sacl/dacl information, try to write that piece now
  637. if ( dwReturn == ERROR_SUCCESS && ( securityinfo & DACL_SECURITY_INFORMATION ||
  638. securityinfo & SACL_SECURITY_INFORMATION ||
  639. securityinfo & PROTECTED_DACL_SECURITY_INFORMATION ||
  640. securityinfo & PROTECTED_SACL_SECURITY_INFORMATION ||
  641. securityinfo & UNPROTECTED_DACL_SECURITY_INFORMATION ||
  642. securityinfo & UNPROTECTED_SACL_SECURITY_INFORMATION) )
  643. {
  644. SECURITY_INFORMATION daclsecinfo = 0;
  645. // Fill out security information with only the appropriate DACL/SACL values.
  646. if ( securityinfo & DACL_SECURITY_INFORMATION )
  647. {
  648. daclsecinfo |= DACL_SECURITY_INFORMATION;
  649. }
  650. if ( securityinfo & SACL_SECURITY_INFORMATION )
  651. {
  652. daclsecinfo |= SACL_SECURITY_INFORMATION;
  653. }
  654. #if NTONLY >= 5
  655. if(securityinfo & PROTECTED_DACL_SECURITY_INFORMATION)
  656. {
  657. daclsecinfo |= PROTECTED_DACL_SECURITY_INFORMATION;
  658. }
  659. if(securityinfo & PROTECTED_SACL_SECURITY_INFORMATION)
  660. {
  661. daclsecinfo |= PROTECTED_SACL_SECURITY_INFORMATION;
  662. }
  663. if(securityinfo & UNPROTECTED_DACL_SECURITY_INFORMATION)
  664. {
  665. daclsecinfo |= UNPROTECTED_DACL_SECURITY_INFORMATION;
  666. }
  667. if(securityinfo & UNPROTECTED_SACL_SECURITY_INFORMATION)
  668. {
  669. daclsecinfo |= UNPROTECTED_SACL_SECURITY_INFORMATION;
  670. }
  671. #endif
  672. dwReturn = WriteAcls( pAbsoluteSD, daclsecinfo );
  673. }
  674. return dwReturn;
  675. }
  676. ///////////////////////////////////////////////////////////////////
  677. //
  678. // Function: CSecurityDescriptor::SetOwner
  679. //
  680. // Sets the owner data member to the supplied SID.
  681. //
  682. // Inputs:
  683. // CSid& sid - New Owner.
  684. //
  685. // Outputs:
  686. // None.
  687. //
  688. // Returns:
  689. // DWORD ERROR_SUCCESS if ok.
  690. //
  691. // Comments:
  692. //
  693. ///////////////////////////////////////////////////////////////////
  694. DWORD CSecurityDescriptor::SetOwner( CSid& sid )
  695. {
  696. DWORD dwError = ERROR_SUCCESS;
  697. // Make sure the new sid is valid
  698. if ( sid.IsValid() )
  699. {
  700. // We will write in the sid, if the Owner is NULL, or the
  701. // sids are not equal.
  702. if ( NULL == m_pOwnerSid
  703. || !( *m_pOwnerSid == sid ) )
  704. {
  705. if ( NULL != m_pOwnerSid )
  706. {
  707. delete m_pOwnerSid;
  708. }
  709. m_pOwnerSid = NULL;
  710. try
  711. {
  712. m_pOwnerSid = new CSid( sid );
  713. }
  714. catch(...)
  715. {
  716. if(m_pOwnerSid != NULL)
  717. {
  718. delete m_pOwnerSid;
  719. m_pOwnerSid = NULL;
  720. }
  721. throw;
  722. }
  723. if ( NULL == m_pOwnerSid )
  724. {
  725. dwError = ERROR_NOT_ENOUGH_MEMORY;
  726. }
  727. else
  728. {
  729. m_fOwnerDefaulted = FALSE;
  730. }
  731. } // IF NULL == m_pOwnerSid || !SidsEqual
  732. } // IF IsValidSid
  733. else
  734. {
  735. dwError = ::GetLastError();
  736. }
  737. return dwError;
  738. }
  739. ///////////////////////////////////////////////////////////////////
  740. //
  741. // Function: CSecurityDescriptor::SetGroup
  742. //
  743. // Sets the group data member to the supplied SID.
  744. //
  745. // Inputs:
  746. // CSid& sid - New Group.
  747. //
  748. // Outputs:
  749. // None.
  750. //
  751. // Returns:
  752. // DWORD ERROR_SUCCESS if ok.
  753. //
  754. // Comments:
  755. //
  756. ///////////////////////////////////////////////////////////////////
  757. DWORD CSecurityDescriptor::SetGroup( CSid& sid )
  758. {
  759. DWORD dwError = ERROR_SUCCESS;
  760. // Make sure the new sid is valid
  761. if ( sid.IsValid() )
  762. {
  763. // We will write in the sid, if the Owner is NULL, or the
  764. // sids are not equal.
  765. if ( NULL == m_pGroupSid
  766. || !( *m_pGroupSid == sid ) )
  767. {
  768. if ( NULL != m_pGroupSid )
  769. {
  770. delete m_pGroupSid;
  771. }
  772. m_pGroupSid = NULL;
  773. try
  774. {
  775. m_pGroupSid = new CSid( sid );
  776. }
  777. catch(...)
  778. {
  779. if(m_pGroupSid != NULL)
  780. {
  781. delete m_pGroupSid;
  782. m_pGroupSid = NULL;
  783. }
  784. throw;
  785. }
  786. if ( NULL == m_pGroupSid )
  787. {
  788. dwError = ERROR_NOT_ENOUGH_MEMORY;
  789. }
  790. else
  791. {
  792. m_fGroupDefaulted = FALSE;
  793. }
  794. } // IF NULL == m_pOwnerSid || !SidsEqual
  795. } // IF IsValidSid
  796. else
  797. {
  798. dwError = ::GetLastError();
  799. }
  800. return dwError;
  801. }
  802. ///////////////////////////////////////////////////////////////////
  803. //
  804. // Function: CSecurityDescriptor::AddDACLEntry
  805. //
  806. // Adds an entry to our DACL. Replaces an
  807. // existing entry if it meets the matching criteria.
  808. //
  809. // Inputs:
  810. // CSid& sid - Sid for the entry.
  811. // DWORD dwAccessMask - The access mask
  812. // BOOL bACEFlags - ACE Flags.
  813. //
  814. // Outputs:
  815. // None.
  816. //
  817. // Returns:
  818. // BOOL TRUE/FALSE
  819. //
  820. // Comments:
  821. //
  822. ///////////////////////////////////////////////////////////////////
  823. bool CSecurityDescriptor::AddDACLEntry( CSid& sid, DACL_Types DaclType, DWORD dwAccessMask, BYTE bACEFlags, GUID *pguidObjGuid, GUID *pguidInhObjGuid )
  824. {
  825. bool fReturn = false;
  826. if(m_pDACL == NULL)
  827. {
  828. try
  829. {
  830. m_pDACL = new CDACL;
  831. }
  832. catch(...)
  833. {
  834. if(m_pDACL != NULL)
  835. {
  836. delete m_pDACL;
  837. m_pDACL = NULL;
  838. }
  839. throw;
  840. }
  841. if(m_pDACL != NULL)
  842. {
  843. fReturn = m_pDACL->AddDACLEntry(sid.GetPSid(), DaclType, dwAccessMask, bACEFlags, pguidObjGuid, pguidInhObjGuid);
  844. }
  845. }
  846. else
  847. {
  848. fReturn = m_pDACL->AddDACLEntry(sid.GetPSid(), DaclType, dwAccessMask, bACEFlags, pguidObjGuid, pguidInhObjGuid);
  849. }
  850. return fReturn;
  851. }
  852. ///////////////////////////////////////////////////////////////////
  853. //
  854. // Function: CSecurityDescriptor::AddSACLEntry
  855. //
  856. // Adds an entry to our SACL. Replaces an
  857. // existing entry if it meets the matching criteria.
  858. //
  859. // Inputs:
  860. // CSid& sid - Sid for the entry.
  861. // DWORD dwAccessMask - The access mask
  862. // BOOL bACEFlags - ACE Flags.
  863. //
  864. // Outputs:
  865. // None.
  866. //
  867. // Returns:
  868. // BOOL TRUE/FALSE
  869. //
  870. // Comments:
  871. //
  872. ///////////////////////////////////////////////////////////////////
  873. bool CSecurityDescriptor::AddSACLEntry( CSid& sid, SACL_Types SaclType, DWORD dwAccessMask, BYTE bACEFlags, GUID *pguidObjGuid, GUID *pguidInhObjGuid )
  874. {
  875. bool fReturn = false;
  876. if(m_pSACL == NULL)
  877. {
  878. try
  879. {
  880. m_pSACL = new CSACL;
  881. }
  882. catch(...)
  883. {
  884. if(m_pSACL != NULL)
  885. {
  886. delete m_pSACL;
  887. m_pSACL = NULL;
  888. }
  889. throw;
  890. }
  891. if(m_pSACL != NULL)
  892. {
  893. fReturn = m_pSACL->AddSACLEntry(sid.GetPSid(), SaclType, dwAccessMask, bACEFlags, pguidObjGuid, pguidInhObjGuid);
  894. }
  895. }
  896. else
  897. {
  898. fReturn = m_pSACL->AddSACLEntry(sid.GetPSid(), SaclType, dwAccessMask, bACEFlags, pguidObjGuid, pguidInhObjGuid);
  899. }
  900. return fReturn;
  901. }
  902. ///////////////////////////////////////////////////////////////////
  903. //
  904. // Function: CSecurityDescriptor::RemoveDACLEntry
  905. //
  906. // Removes a DACL entry from our DACL.
  907. //
  908. // Inputs:
  909. // CSid& sid - Sid for the entry.
  910. // DWORD dwAccessMask - The access mask
  911. // BOOL bACEFlags - ACE Flags.
  912. //
  913. // Outputs:
  914. // None.
  915. //
  916. // Returns:
  917. // BOOL TRUE/FALSE
  918. //
  919. // Comments:
  920. //
  921. // The entry that is removed must match all specified criteria.
  922. //
  923. ///////////////////////////////////////////////////////////////////
  924. bool CSecurityDescriptor::RemoveDACLEntry( CSid& sid, DACL_Types DaclType, DWORD dwAccessMask, BYTE bACEFlags, GUID *pguidObjGuid, GUID *pguidInhObjGuid )
  925. {
  926. bool fReturn = false;
  927. if ( NULL != m_pDACL )
  928. {
  929. fReturn = m_pDACL->RemoveDACLEntry( sid, DaclType, dwAccessMask, bACEFlags, pguidObjGuid, pguidInhObjGuid );
  930. }
  931. return fReturn;
  932. }
  933. ///////////////////////////////////////////////////////////////////
  934. //
  935. // Function: CSecurityDescriptor::RemoveDACLEntry
  936. //
  937. // Removes a DACL entry from our DACL.
  938. //
  939. // Inputs:
  940. // CSid& sid - Sid for the entry.
  941. // BOOL bACEFlags - ACE Flags.
  942. //
  943. // Outputs:
  944. // None.
  945. //
  946. // Returns:
  947. // BOOL TRUE/FALSE
  948. //
  949. // Comments:
  950. //
  951. // The entry that is removed must match only the specified criteria.
  952. //
  953. ///////////////////////////////////////////////////////////////////
  954. bool CSecurityDescriptor::RemoveDACLEntry( CSid& sid, DACL_Types DaclType, BYTE bACEFlags, GUID *pguidObjGuid, GUID *pguidInhObjGuid )
  955. {
  956. bool fReturn = false;
  957. if ( NULL != m_pDACL )
  958. {
  959. fReturn = m_pDACL->RemoveDACLEntry( sid, DaclType, bACEFlags, pguidObjGuid, pguidInhObjGuid );
  960. }
  961. return fReturn;
  962. }
  963. ///////////////////////////////////////////////////////////////////
  964. //
  965. // Function: CSecurityDescriptor::RemoveDACLEntry
  966. //
  967. // Removes a DACL entry from our DACL.
  968. //
  969. // Inputs:
  970. // CSid& sid - Sid for the entry.
  971. // DWORD dwIndex - Index of entry.
  972. //
  973. // Outputs:
  974. // None.
  975. //
  976. // Returns:
  977. // BOOL TRUE/FALSE
  978. //
  979. // Comments:
  980. //
  981. // Removes the dwIndex instance of a SID in the SACL.
  982. //
  983. ///////////////////////////////////////////////////////////////////
  984. bool CSecurityDescriptor::RemoveDACLEntry( CSid& sid, DACL_Types DaclType, DWORD dwIndex )
  985. {
  986. bool fReturn = false;
  987. if ( NULL != m_pDACL )
  988. {
  989. fReturn = m_pDACL->RemoveDACLEntry( sid, DaclType, dwIndex );
  990. }
  991. return fReturn;
  992. }
  993. ///////////////////////////////////////////////////////////////////
  994. //
  995. // Function: CSecurityDescriptor::RemoveSACLEntry
  996. //
  997. // Removes a SACL entry from our SACL.
  998. //
  999. // Inputs:
  1000. // CSid& sid - Sid for the entry.
  1001. // DWORD dwAccessMask - The access mask
  1002. // BOOL bACEFlags - ACE Flags.
  1003. //
  1004. // Outputs:
  1005. // None.
  1006. //
  1007. // Returns:
  1008. // BOOL TRUE/FALSE
  1009. //
  1010. // Comments:
  1011. //
  1012. // The entry that is removed must match all specified criteria.
  1013. //
  1014. ///////////////////////////////////////////////////////////////////
  1015. bool CSecurityDescriptor::RemoveSACLEntry( CSid& sid, SACL_Types SaclType, DWORD dwAccessMask, BYTE bACEFlags, GUID *pguidObjGuid, GUID *pguidInhObjGuid )
  1016. {
  1017. bool fReturn = false;
  1018. if ( NULL != m_pSACL )
  1019. {
  1020. fReturn = m_pSACL->RemoveSACLEntry( sid, SaclType, dwAccessMask, bACEFlags, pguidObjGuid, pguidInhObjGuid );
  1021. }
  1022. return fReturn;
  1023. }
  1024. ///////////////////////////////////////////////////////////////////
  1025. //
  1026. // Function: CSecurityDescriptor::RemoveSACLEntry
  1027. //
  1028. // Removes a SACL entry from our SACL.
  1029. //
  1030. // Inputs:
  1031. // CSid& sid - Sid for the entry.
  1032. // BOOL bACEFlags - ACE Flags.
  1033. //
  1034. // Outputs:
  1035. // None.
  1036. //
  1037. // Returns:
  1038. // BOOL TRUE/FALSE
  1039. //
  1040. // Comments:
  1041. //
  1042. // The entry that is removed must match only the specified criteria.
  1043. //
  1044. ///////////////////////////////////////////////////////////////////
  1045. bool CSecurityDescriptor::RemoveSACLEntry( CSid& sid, SACL_Types SaclType, BYTE bACEFlags, GUID *pguidObjGuid, GUID *pguidInhObjGuid )
  1046. {
  1047. bool fReturn = false;
  1048. if ( NULL != m_pSACL )
  1049. {
  1050. fReturn = m_pSACL->RemoveSACLEntry( sid, SaclType, bACEFlags, pguidObjGuid, pguidInhObjGuid );
  1051. }
  1052. return fReturn;
  1053. }
  1054. ///////////////////////////////////////////////////////////////////
  1055. //
  1056. // Function: CSecurityDescriptor::RemoveSACLEntry
  1057. //
  1058. // Removes a SACL entry from our SACL.
  1059. //
  1060. // Inputs:
  1061. // CSid& sid - Sid for the entry.
  1062. // DWORD dwIndex - Index of entry.
  1063. //
  1064. // Outputs:
  1065. // None.
  1066. //
  1067. // Returns:
  1068. // BOOL TRUE/FALSE
  1069. //
  1070. // Comments:
  1071. //
  1072. // Removes the dwIndex instance of a SID in the SACL.
  1073. //
  1074. ///////////////////////////////////////////////////////////////////
  1075. bool CSecurityDescriptor::RemoveSACLEntry( CSid& sid, SACL_Types SaclType, DWORD dwIndex )
  1076. {
  1077. bool fReturn = false;
  1078. if ( NULL != m_pSACL )
  1079. {
  1080. fReturn = m_pSACL->RemoveSACLEntry( sid, SaclType, dwIndex );
  1081. }
  1082. return fReturn;
  1083. }
  1084. ///////////////////////////////////////////////////////////////////
  1085. //
  1086. // Function: CSecurityDescriptor::FindACE
  1087. //
  1088. // Locates an ACE in either the SACL or DACL based on the supplied
  1089. // criteria.
  1090. //
  1091. // Inputs:
  1092. // const CSid& sid - Sid for the entry.
  1093. // BYTE bACEType - ACE Type
  1094. // DWORD dwMask - Access Mask
  1095. // BYTE bACEFlags - Flags
  1096. //
  1097. // Outputs:
  1098. // CAccessEntry& ace - Filled out with located values.
  1099. //
  1100. // Returns:
  1101. // BOOL TRUE/FALSE
  1102. //
  1103. // Comments:
  1104. //
  1105. // Locates an ACE that matches ALL supplied criteria
  1106. //
  1107. ///////////////////////////////////////////////////////////////////
  1108. bool CSecurityDescriptor::FindACE( const CSid& sid, BYTE bACEType, DWORD dwMask, BYTE bACEFlags, GUID *pguidObjGuid, GUID *pguidInhObjGuid, CAccessEntry& ace )
  1109. {
  1110. bool fReturn = false;
  1111. if ( SYSTEM_AUDIT_ACE_TYPE == bACEType ||
  1112. SYSTEM_AUDIT_OBJECT_ACE_TYPE == bACEType /* ||
  1113. SYSTEM_ALARM_ACE_TYPE == bACEType || <- ALARM ACE TYPES NOT YET SUPPORTED UNDER W2K
  1114. SYSTEM_ALARM_OBJECT_ACE_TYPE == bACEType */ )
  1115. {
  1116. if ( NULL != m_pSACL )
  1117. {
  1118. fReturn = m_pSACL->Find( sid, bACEType, bACEFlags, pguidObjGuid, pguidInhObjGuid, dwMask, ace );
  1119. }
  1120. }
  1121. else
  1122. {
  1123. if ( NULL != m_pDACL )
  1124. {
  1125. fReturn = m_pDACL->Find( sid, bACEType, bACEFlags, pguidObjGuid, pguidInhObjGuid, dwMask, ace );
  1126. }
  1127. }
  1128. return fReturn;
  1129. }
  1130. ///////////////////////////////////////////////////////////////////
  1131. //
  1132. // Function: CSecurityDescriptor::FindACE
  1133. //
  1134. // Locates an ACE in either the SACL or DACL based on the supplied
  1135. // criteria.
  1136. //
  1137. // Inputs:
  1138. // const CSid& sid - Sid for the entry.
  1139. // BYTE bACEType - ACE Type
  1140. // BYTE bACEFlags - Flags
  1141. //
  1142. // Outputs:
  1143. // CAccessEntry& ace - Filled out with located values.
  1144. //
  1145. // Returns:
  1146. // BOOL TRUE/FALSE
  1147. //
  1148. // Comments:
  1149. //
  1150. // Locates an ACE that matches ALL supplied criteria
  1151. //
  1152. ///////////////////////////////////////////////////////////////////
  1153. bool CSecurityDescriptor::FindACE( PSID psid, BYTE bACEType, BYTE bACEFlags, GUID *pguidObjGuid, GUID *pguidInhObjGuid, DWORD dwAccessMask, CAccessEntry& ace )
  1154. {
  1155. bool fReturn = false;
  1156. if ( SYSTEM_AUDIT_ACE_TYPE == bACEType ||
  1157. SYSTEM_AUDIT_OBJECT_ACE_TYPE == bACEType ||
  1158. SYSTEM_ALARM_ACE_TYPE == bACEType ||
  1159. SYSTEM_ALARM_OBJECT_ACE_TYPE == bACEType)
  1160. {
  1161. if ( NULL != m_pSACL )
  1162. {
  1163. fReturn = m_pSACL->Find( psid, bACEType, bACEFlags, pguidObjGuid, pguidInhObjGuid, dwAccessMask, ace );
  1164. }
  1165. }
  1166. else
  1167. {
  1168. if ( NULL != m_pDACL )
  1169. {
  1170. fReturn = m_pDACL->Find( psid, bACEType, bACEFlags, pguidObjGuid, pguidInhObjGuid, dwAccessMask, ace );
  1171. }
  1172. }
  1173. return fReturn;
  1174. }
  1175. ///////////////////////////////////////////////////////////////////
  1176. //
  1177. // Function: CSecurityDescriptor::ApplySecurity
  1178. //
  1179. // Using the user specified flags, builds an appropriate descriptor
  1180. // and loads it with the necessary information, then passes this
  1181. // descriptor off to SecureObject() which will farm out the
  1182. // actual setting of security to the virtual Write functions.
  1183. //
  1184. // Inputs:
  1185. // SECURITY_INFORMATION securityinfo - flags to control
  1186. // how the descriptor is used.
  1187. //
  1188. // Outputs:
  1189. // None.
  1190. //
  1191. // Returns:
  1192. // DWORD ERROR_SUCCESS if successful.
  1193. //
  1194. // Comments:
  1195. //
  1196. // This should be the only public method for applying security
  1197. // to an object.
  1198. //
  1199. ///////////////////////////////////////////////////////////////////
  1200. DWORD CSecurityDescriptor::ApplySecurity( SECURITY_INFORMATION securityinfo )
  1201. {
  1202. DWORD dwError = ERROR_SUCCESS;
  1203. PSID pOwnerSid = NULL;
  1204. PACL pDacl = NULL,
  1205. pSacl = NULL;
  1206. // Allocate and initialize the security descriptor
  1207. PSECURITY_DESCRIPTOR pAbsoluteSD = NULL;
  1208. try
  1209. {
  1210. pAbsoluteSD = new SECURITY_DESCRIPTOR;
  1211. }
  1212. catch(...)
  1213. {
  1214. if(pAbsoluteSD != NULL)
  1215. {
  1216. delete pAbsoluteSD;
  1217. pAbsoluteSD = NULL;
  1218. }
  1219. throw;
  1220. }
  1221. if ( NULL != pAbsoluteSD )
  1222. {
  1223. if ( !InitializeSecurityDescriptor( pAbsoluteSD, SECURITY_DESCRIPTOR_REVISION ) )
  1224. {
  1225. dwError = ::GetLastError();
  1226. }
  1227. }
  1228. else
  1229. {
  1230. dwError = ERROR_NOT_ENOUGH_MEMORY;
  1231. }
  1232. // If we're supposed to set the owner, place the sid from the internal
  1233. // value in the absoluteSD.
  1234. if ( ERROR_SUCCESS == dwError
  1235. && securityinfo & OWNER_SECURITY_INFORMATION )
  1236. {
  1237. if ( NULL != m_pOwnerSid )
  1238. {
  1239. pOwnerSid = m_pOwnerSid->GetPSid();
  1240. }
  1241. if ( !SetSecurityDescriptorOwner( pAbsoluteSD, pOwnerSid, m_fOwnerDefaulted ) )
  1242. {
  1243. dwError = ::GetLastError();
  1244. }
  1245. }
  1246. // If we're supposed to set the DACL, this is a non-trivial operation so
  1247. // call out for reinforcements.
  1248. if ( ERROR_SUCCESS == dwError
  1249. && securityinfo & DACL_SECURITY_INFORMATION || securityinfo & PROTECTED_DACL_SECURITY_INFORMATION || securityinfo & UNPROTECTED_DACL_SECURITY_INFORMATION
  1250. && m_pDACL != NULL)
  1251. {
  1252. if ( ( dwError = m_pDACL->ConfigureDACL( pDacl ) ) == ERROR_SUCCESS )
  1253. {
  1254. if ( !SetSecurityDescriptorDacl( pAbsoluteSD,
  1255. ( NULL != pDacl ), // Set Dacl present flag
  1256. pDacl,
  1257. m_fDACLDefaulted ) )
  1258. {
  1259. dwError = ::GetLastError();
  1260. }
  1261. }
  1262. }
  1263. // If we're supposed to set the SACL, this also is a non-trivial operation so
  1264. // call out for reinforcements.
  1265. if (ERROR_SUCCESS == dwError)
  1266. {
  1267. if((securityinfo & SACL_SECURITY_INFORMATION || securityinfo & PROTECTED_SACL_SECURITY_INFORMATION || securityinfo & UNPROTECTED_SACL_SECURITY_INFORMATION)
  1268. && (m_pSACL != NULL))
  1269. {
  1270. if ( ( dwError = m_pSACL->ConfigureSACL( pSacl ) ) == ERROR_SUCCESS )
  1271. {
  1272. if ( !SetSecurityDescriptorSacl( pAbsoluteSD,
  1273. ( NULL != pSacl ), // Set Sacl present flag
  1274. pSacl,
  1275. m_fSACLDefaulted ) )
  1276. {
  1277. dwError = ::GetLastError();
  1278. }
  1279. }
  1280. }
  1281. }
  1282. // If we're OK, let the object try to secure itself, the default implementation
  1283. // fails with ERROR_INVALID_FUNCTION.
  1284. if ( ERROR_SUCCESS == dwError )
  1285. {
  1286. ASSERT_BREAK( IsValidSecurityDescriptor( pAbsoluteSD ) );
  1287. dwError = SecureObject( pAbsoluteSD, securityinfo );
  1288. }
  1289. // Clean up allocated memory
  1290. if ( NULL != pAbsoluteSD )
  1291. {
  1292. delete pAbsoluteSD;
  1293. }
  1294. if ( NULL != pDacl )
  1295. {
  1296. // This guy gets malloced in ConfigureDACL
  1297. free( pDacl );
  1298. }
  1299. if ( NULL != pSacl )
  1300. {
  1301. // This guy gets malloced in ConfigureSACL
  1302. free( pSacl );
  1303. }
  1304. return dwError;
  1305. }
  1306. ///////////////////////////////////////////////////////////////////
  1307. //
  1308. // Function: CSecurityDescriptor::Clear
  1309. //
  1310. // Empties out our class, freeing up all allocated memory.
  1311. //
  1312. // Inputs:
  1313. // None.
  1314. //
  1315. // Outputs:
  1316. // None.
  1317. //
  1318. // Returns:
  1319. // None.
  1320. //
  1321. // Comments:
  1322. //
  1323. ///////////////////////////////////////////////////////////////////
  1324. void CSecurityDescriptor::Clear( void )
  1325. {
  1326. if ( NULL != m_pOwnerSid )
  1327. {
  1328. delete m_pOwnerSid;
  1329. m_pOwnerSid = NULL;
  1330. }
  1331. m_fOwnerDefaulted = FALSE;
  1332. if ( NULL != m_pDACL )
  1333. {
  1334. delete m_pDACL;
  1335. m_pDACL = NULL;
  1336. }
  1337. if ( NULL != m_pSACL )
  1338. {
  1339. delete m_pSACL;
  1340. m_pSACL = NULL;
  1341. }
  1342. if ( NULL != m_pGroupSid )
  1343. {
  1344. delete m_pGroupSid;
  1345. m_pGroupSid = NULL;
  1346. }
  1347. }
  1348. ///////////////////////////////////////////////////////////////////
  1349. //
  1350. // Function: CSecurityDescriptor::GetDACL
  1351. //
  1352. // Makes a copy of our DACL entries and places them in the supplied
  1353. // DACL, in proper canonical order.
  1354. //
  1355. // Inputs:
  1356. // None.
  1357. //
  1358. // Outputs:
  1359. // CDACL& DACL - Dacl to copy into.
  1360. //
  1361. // Returns:
  1362. // BOOL TRUE/FALSE
  1363. //
  1364. // Comments:
  1365. //
  1366. ///////////////////////////////////////////////////////////////////
  1367. bool CSecurityDescriptor::GetDACL ( CDACL& DACL )
  1368. {
  1369. bool fRet = false;
  1370. if(m_pDACL != NULL)
  1371. {
  1372. fRet = DACL.CopyDACL( *m_pDACL );
  1373. }
  1374. return fRet;
  1375. }
  1376. ///////////////////////////////////////////////////////////////////
  1377. //
  1378. // Function: CSecurityDescriptor::GetSACL
  1379. //
  1380. // Makes a copy of our SACL entries and places them in the supplied
  1381. // SACL.
  1382. //
  1383. // Inputs:
  1384. // None.
  1385. //
  1386. // Outputs:
  1387. // CSACL& SACL - Sacl to copy into.
  1388. //
  1389. // Returns:
  1390. // BOOL TRUE/FALSE
  1391. //
  1392. // Comments:
  1393. //
  1394. ///////////////////////////////////////////////////////////////////
  1395. bool CSecurityDescriptor::GetSACL ( CSACL& SACL )
  1396. {
  1397. bool fRet = false;
  1398. if(m_pSACL != NULL)
  1399. {
  1400. fRet = SACL.CopySACL( *m_pSACL );
  1401. }
  1402. return fRet;
  1403. }
  1404. ///////////////////////////////////////////////////////////////////
  1405. //
  1406. // Function: CSecurityDescriptor::EmptyDACL
  1407. //
  1408. // Clears our DACL lists, allocating them if they DO NOT exist.
  1409. //
  1410. // Inputs:
  1411. // None.
  1412. //
  1413. // Outputs:
  1414. // None.
  1415. //
  1416. // Returns:
  1417. // BOOL TRUE/FALSE
  1418. //
  1419. // Comments:
  1420. //
  1421. // Remember, an empty DACL is different from a NULL DACL, in that
  1422. // empty means nobody has access and NULL means everyone has
  1423. // full control.
  1424. //
  1425. ///////////////////////////////////////////////////////////////////
  1426. void CSecurityDescriptor::EmptyDACL()
  1427. {
  1428. if(m_pDACL != NULL)
  1429. {
  1430. m_pDACL->Clear();
  1431. }
  1432. }
  1433. ///////////////////////////////////////////////////////////////////
  1434. //
  1435. // Function: CSecurityDescriptor::EmptySACL
  1436. //
  1437. // Clears our SACL lists, allocating it if it DOES NOT exist
  1438. //
  1439. // Inputs:
  1440. // None.
  1441. //
  1442. // Outputs:
  1443. // None.
  1444. //
  1445. // Returns:
  1446. // BOOL TRUE/FALSE
  1447. //
  1448. // Comments:
  1449. //
  1450. // In the case of a sacl, there is no distinction between a NULL
  1451. // and an Empty. So we will consider this sacl Empty if its data
  1452. // member is NULL.
  1453. //
  1454. ///////////////////////////////////////////////////////////////////
  1455. void CSecurityDescriptor::EmptySACL()
  1456. {
  1457. if(m_pSACL != NULL)
  1458. {
  1459. m_pSACL->Clear();
  1460. }
  1461. }
  1462. ///////////////////////////////////////////////////////////////////
  1463. //
  1464. // Function: CSecurityDescriptor::ClearSACL
  1465. //
  1466. // Deletes our SACL list.
  1467. //
  1468. // Inputs:
  1469. // None.
  1470. //
  1471. // Outputs:
  1472. // None.
  1473. //
  1474. // Returns:
  1475. // BOOL TRUE/FALSE
  1476. //
  1477. // Comments:
  1478. //
  1479. // In the case of a sacl, there is no distinction between a NULL
  1480. // and an Empty. So we will consider this sacl Empty if its data
  1481. // member is NULL.
  1482. //
  1483. ///////////////////////////////////////////////////////////////////
  1484. bool CSecurityDescriptor::MakeSACLNull()
  1485. {
  1486. bool fReturn = false;
  1487. if(m_pSACL == NULL)
  1488. {
  1489. try
  1490. {
  1491. m_pSACL = new CSACL;
  1492. }
  1493. catch(...)
  1494. {
  1495. if(m_pSACL != NULL)
  1496. {
  1497. delete m_pSACL;
  1498. m_pSACL = NULL;
  1499. }
  1500. throw;
  1501. }
  1502. if(m_pSACL != NULL)
  1503. {
  1504. m_pSACL->Clear();
  1505. fReturn = true;
  1506. }
  1507. }
  1508. else
  1509. {
  1510. m_pSACL->Clear();
  1511. m_pSACL->Clear();
  1512. fReturn = true;
  1513. }
  1514. return fReturn;
  1515. }
  1516. ///////////////////////////////////////////////////////////////////
  1517. //
  1518. // Function: CSecurityDescriptor::MakeDACLNull
  1519. //
  1520. // NULLs out our DACL Lists except for the ACCESS_ALLOWED_ACE_TYPE
  1521. // list, which it clears, then enters an Everybody ace into.
  1522. //
  1523. // Inputs:
  1524. // None.
  1525. //
  1526. // Outputs:
  1527. // None.
  1528. //
  1529. // Returns:
  1530. // BOOL TRUE/FALSE
  1531. //
  1532. // Comments:
  1533. //
  1534. // Remember, an empty DACL is different from a NULL DACL, in that
  1535. // empty means nobody has access and NULL means everyone has
  1536. // full control.
  1537. //
  1538. ///////////////////////////////////////////////////////////////////
  1539. bool CSecurityDescriptor::MakeDACLNull( void )
  1540. {
  1541. bool fReturn = false;
  1542. if(m_pDACL == NULL)
  1543. {
  1544. try
  1545. {
  1546. m_pDACL = new CDACL;
  1547. }
  1548. catch(...)
  1549. {
  1550. if(m_pDACL != NULL)
  1551. {
  1552. delete m_pDACL;
  1553. m_pDACL = NULL;
  1554. }
  1555. throw;
  1556. }
  1557. if(m_pDACL != NULL)
  1558. {
  1559. m_pDACL->CreateNullDACL();
  1560. fReturn = true;
  1561. }
  1562. }
  1563. else
  1564. {
  1565. m_pDACL->Clear();
  1566. fReturn = m_pDACL->CreateNullDACL();
  1567. fReturn = true;
  1568. }
  1569. return fReturn;
  1570. }
  1571. ///////////////////////////////////////////////////////////////////
  1572. //
  1573. // Function: CSecurityDescriptor::IsNULLDACL
  1574. //
  1575. // Checks our DACL Lists to see if we have a NULL DACL. Which
  1576. // means that all our lists are NULL, except for the
  1577. // ACCESS_ALLOWED_ACE_TYPE list, which will have exactly one entry
  1578. // in it - namely, an ACE for Everyone.
  1579. //
  1580. // Inputs:
  1581. // None.
  1582. //
  1583. // Outputs:
  1584. // None.
  1585. //
  1586. // Returns:
  1587. // BOOL TRUE/FALSE
  1588. //
  1589. // Comments:
  1590. //
  1591. // Remember, a NULL DACL is the same as "Everyone" has Full Control,
  1592. // so if a single Access Allowed entry exists that meets these
  1593. // criteria, we consider ourselves to be NULL.
  1594. //
  1595. ///////////////////////////////////////////////////////////////////
  1596. bool CSecurityDescriptor::IsNULLDACL()
  1597. {
  1598. bool fRet = false;
  1599. if(m_pDACL != NULL)
  1600. {
  1601. fRet = m_pDACL->IsNULLDACL();
  1602. }
  1603. return fRet;
  1604. }
  1605. void CSecurityDescriptor::DumpDescriptor(LPCWSTR wstrFilename)
  1606. {
  1607. CHString chstrTemp;
  1608. Output(L"Security descriptor contents follow...", wstrFilename);
  1609. // Output the control flags
  1610. chstrTemp.Format(L"Control Flags (hex): %x", m_SecurityDescriptorControl);
  1611. Output(chstrTemp, wstrFilename);
  1612. // Ouput the owner
  1613. Output(L"Owner contents: ", wstrFilename);
  1614. if(m_pOwnerSid != NULL)
  1615. {
  1616. m_pOwnerSid->DumpSid(wstrFilename);
  1617. }
  1618. else
  1619. {
  1620. Output(L"(Owner is null)", wstrFilename);
  1621. }
  1622. // Output the group
  1623. Output(L"Group contents: ", wstrFilename);
  1624. if(m_pGroupSid != NULL)
  1625. {
  1626. m_pGroupSid->DumpSid(wstrFilename);
  1627. }
  1628. else
  1629. {
  1630. Output(L"(Group is null)", wstrFilename);
  1631. }
  1632. // Output the DACL
  1633. Output(L"DACL contents: ", wstrFilename);
  1634. if(m_pDACL != NULL)
  1635. {
  1636. m_pDACL->DumpDACL(wstrFilename);
  1637. }
  1638. else
  1639. {
  1640. Output(L"(DACL is null)", wstrFilename);
  1641. }
  1642. // Output the SACL
  1643. Output(L"SACL contents: ", wstrFilename);
  1644. if(m_pSACL != NULL)
  1645. {
  1646. m_pSACL->DumpSACL(wstrFilename);
  1647. }
  1648. else
  1649. {
  1650. Output(L"(SACL is null)", wstrFilename);
  1651. }
  1652. }
  1653. ///////////////////////////////////////////////////////////////////
  1654. //
  1655. // Function: CSecurityDescriptor::GetPSD
  1656. //
  1657. // Takes our internal members and constructs a PSECURITY_DESCRIPTOR,
  1658. // which the caller must free.
  1659. //
  1660. // Inputs:
  1661. // None.
  1662. //
  1663. // Outputs:
  1664. // None.
  1665. //
  1666. // Returns:
  1667. // BOOL TRUE/FALSE
  1668. //
  1669. // Comments:
  1670. //
  1671. // Remember, a NULL DACL is the same as "Everyone" has Full Control,
  1672. // so if a single Access Allowed entry exists that meets these
  1673. // criteria, we consider ourselves to be NULL.
  1674. //
  1675. ///////////////////////////////////////////////////////////////////
  1676. DWORD CSecurityDescriptor::GetSelfRelativeSD(
  1677. SECURITY_INFORMATION securityinfo,
  1678. PSECURITY_DESCRIPTOR psd)
  1679. {
  1680. DWORD dwError = ERROR_SUCCESS;
  1681. PSID pOwnerSid = NULL;
  1682. PACL pDacl = NULL,
  1683. pSacl = NULL;
  1684. // Allocate and initialize the security descriptor
  1685. PSECURITY_DESCRIPTOR pAbsoluteSD = NULL;
  1686. try
  1687. {
  1688. pAbsoluteSD = new SECURITY_DESCRIPTOR;
  1689. }
  1690. catch(...)
  1691. {
  1692. if(pAbsoluteSD != NULL)
  1693. {
  1694. delete pAbsoluteSD;
  1695. pAbsoluteSD = NULL;
  1696. }
  1697. throw;
  1698. }
  1699. if ( NULL != pAbsoluteSD )
  1700. {
  1701. if ( !::InitializeSecurityDescriptor( pAbsoluteSD, SECURITY_DESCRIPTOR_REVISION ) )
  1702. {
  1703. dwError = ::GetLastError();
  1704. }
  1705. }
  1706. else
  1707. {
  1708. dwError = ERROR_NOT_ENOUGH_MEMORY;
  1709. }
  1710. // If we're supposed to set the owner, place the sid from the internal
  1711. // value in the absoluteSD.
  1712. if ( ERROR_SUCCESS == dwError
  1713. && securityinfo & OWNER_SECURITY_INFORMATION )
  1714. {
  1715. if ( NULL != m_pOwnerSid )
  1716. {
  1717. pOwnerSid = m_pOwnerSid->GetPSid();
  1718. }
  1719. if ( !::SetSecurityDescriptorOwner( pAbsoluteSD, pOwnerSid, m_fOwnerDefaulted ) )
  1720. {
  1721. dwError = ::GetLastError();
  1722. }
  1723. }
  1724. // If we're supposed to set the DACL, this is a non-trivial operation so
  1725. // call out for reinforcements.
  1726. if ( ERROR_SUCCESS == dwError
  1727. && securityinfo & DACL_SECURITY_INFORMATION || securityinfo & PROTECTED_DACL_SECURITY_INFORMATION || securityinfo & UNPROTECTED_DACL_SECURITY_INFORMATION
  1728. && m_pDACL != NULL)
  1729. {
  1730. if ( ( dwError = m_pDACL->ConfigureDACL( pDacl ) ) == ERROR_SUCCESS )
  1731. {
  1732. if ( !::SetSecurityDescriptorDacl( pAbsoluteSD,
  1733. ( NULL != pDacl ), // Set Dacl present flag
  1734. pDacl,
  1735. m_fDACLDefaulted ) )
  1736. {
  1737. dwError = ::GetLastError();
  1738. }
  1739. }
  1740. }
  1741. // If we're supposed to set the SACL, this also is a non-trivial operation so
  1742. // call out for reinforcements.
  1743. if (ERROR_SUCCESS == dwError)
  1744. {
  1745. if((securityinfo & SACL_SECURITY_INFORMATION || securityinfo & PROTECTED_SACL_SECURITY_INFORMATION || securityinfo & UNPROTECTED_SACL_SECURITY_INFORMATION)
  1746. && (m_pSACL != NULL))
  1747. {
  1748. if ( ( dwError = m_pSACL->ConfigureSACL( pSacl ) ) == ERROR_SUCCESS )
  1749. {
  1750. if ( !::SetSecurityDescriptorSacl( pAbsoluteSD,
  1751. ( NULL != pSacl ), // Set Sacl present flag
  1752. pSacl,
  1753. m_fSACLDefaulted ) )
  1754. {
  1755. dwError = ::GetLastError();
  1756. }
  1757. }
  1758. }
  1759. }
  1760. // If we're OK, let the object try to secure itself, the default implementation
  1761. // fails with ERROR_INVALID_FUNCTION.
  1762. if ( ERROR_SUCCESS == dwError )
  1763. {
  1764. ASSERT_BREAK( ::IsValidSecurityDescriptor( pAbsoluteSD ) );
  1765. // Now make it self relative... Caller frees this...
  1766. DWORD dwSize = 0L;
  1767. if(!::MakeSelfRelativeSD(
  1768. pAbsoluteSD,
  1769. NULL,
  1770. &dwSize) &&
  1771. (dwError = ::GetLastError()) == ERROR_INSUFFICIENT_BUFFER)
  1772. {
  1773. PSECURITY_DESCRIPTOR pSelfRelSD = NULL;
  1774. pSelfRelSD = new BYTE[dwSize];
  1775. if(pSelfRelSD &&
  1776. !::MakeSelfRelativeSD(
  1777. pAbsoluteSD,
  1778. pSelfRelSD,
  1779. &dwSize))
  1780. {
  1781. dwError = ::GetLastError();
  1782. }
  1783. else
  1784. {
  1785. psd = pSelfRelSD;
  1786. dwError = ERROR_SUCCESS;
  1787. }
  1788. }
  1789. }
  1790. // Clean up allocated memory
  1791. if ( NULL != pAbsoluteSD )
  1792. {
  1793. delete pAbsoluteSD;
  1794. }
  1795. if ( NULL != pDacl )
  1796. {
  1797. // This guy gets malloced in ConfigureDACL
  1798. free( pDacl );
  1799. }
  1800. if ( NULL != pSacl )
  1801. {
  1802. // This guy gets malloced in ConfigureSACL
  1803. free( pSacl );
  1804. }
  1805. return dwError;
  1806. }