Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1352 lines
40 KiB

  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1998-2000 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // ClusPage.cpp
  7. //
  8. // Abstract:
  9. // CClusterSecurityPage class implementation. This class will encapsulate
  10. // the cluster security extension page.
  11. //
  12. // Author:
  13. // Galen Barbee (galenb) February 11, 1998
  14. //
  15. // Revision History:
  16. //
  17. // Notes:
  18. //
  19. /////////////////////////////////////////////////////////////////////////////
  20. #include "stdafx.h"
  21. #include "resource.h"
  22. #include "ClusPage.h"
  23. #include "AclUtils.h"
  24. #include <clusudef.h>
  25. static GENERIC_MAPPING ShareMap =
  26. {
  27. CLUSAPI_READ_ACCESS,
  28. CLUSAPI_CHANGE_ACCESS,
  29. CLUSAPI_NO_ACCESS,
  30. CLUSAPI_ALL_ACCESS
  31. };
  32. static SI_ACCESS siClusterAccesses[] =
  33. {
  34. { &GUID_NULL, CLUSAPI_ALL_ACCESS, MAKEINTRESOURCE(IDS_ACLEDIT_PERM_GEN_ALL), SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC /*| OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE*/ }
  35. };
  36. /////////////////////////////////////////////////////////////////////////////
  37. //++
  38. //
  39. // CClusterSecurityInformation::CClusterSecurityInformation
  40. //
  41. // Routine Description:
  42. // Default contructor
  43. //
  44. // Arguments:
  45. // none
  46. //
  47. // Return Value:
  48. // none
  49. //
  50. //--
  51. /////////////////////////////////////////////////////////////////////////////
  52. CClusterSecurityInformation::CClusterSecurityInformation( void )
  53. : m_pcsp( NULL )
  54. {
  55. m_pShareMap = &ShareMap;
  56. m_psiAccess = (SI_ACCESS *) &siClusterAccesses;
  57. m_nAccessElems = ARRAYSIZE( siClusterAccesses );
  58. m_nDefAccess = 0;
  59. m_dwFlags = SI_EDIT_PERMS
  60. | SI_NO_ACL_PROTECT
  61. //| SI_UGOP_PROVIDED
  62. //| SI_NO_UGOP_ACCOUNT_GROUPS
  63. //| SI_NO_UGOP_USERS
  64. //| SI_NO_UGOP_LOCAL_GROUPS
  65. //| SI_NO_UGOP_WELLKNOWN
  66. //| SI_NO_UGOP_BUILTIN
  67. ;
  68. } //*** CClusterSecurityInformation::CClusterSecurityInformation()
  69. /////////////////////////////////////////////////////////////////////////////
  70. //++
  71. //
  72. // CClusterSecurityInformation::GetSecurity
  73. //
  74. // Routine Description:
  75. // Give our security descriptor to the ISecurityInfomation UI
  76. // so it can be displayed and edited.
  77. //
  78. // Arguments:
  79. // RequestedInformation [IN]
  80. // ppSecurityDescriptor [IN OUT]
  81. // fDefault [IN]
  82. //
  83. // Return Value:
  84. // E_FAIL for error and S_OK for success.
  85. //
  86. //--
  87. /////////////////////////////////////////////////////////////////////////////
  88. STDMETHODIMP CClusterSecurityInformation::GetSecurity(
  89. IN SECURITY_INFORMATION RequestedInformation,
  90. IN OUT PSECURITY_DESCRIPTOR *ppSecurityDescriptor,
  91. IN BOOL fDefault
  92. )
  93. {
  94. AFX_MANAGE_STATE( ::AfxGetStaticModuleState() );
  95. HRESULT hr = E_FAIL;
  96. try
  97. {
  98. if ( ppSecurityDescriptor != NULL )
  99. {
  100. PSECURITY_DESCRIPTOR pSD = NULL;
  101. pSD = ClRtlCopySecurityDescriptor( Pcsp()->Psec() );
  102. if ( pSD != NULL )
  103. {
  104. //hr = HrFixupSD( pSD );
  105. //if ( SUCCEEDED( hr ) )
  106. //{
  107. *ppSecurityDescriptor = pSD;
  108. //}
  109. hr = S_OK;
  110. } // if: no errors copying the security descriptor
  111. else
  112. {
  113. hr = GetLastError();
  114. TRACE( _T("CClusterSecurityInformation::GetSecurity() - Error %08.8x copying the security descriptor.\n"), hr );
  115. hr = HRESULT_FROM_WIN32( hr );
  116. } // else: error copying the security descriptor
  117. }
  118. else
  119. {
  120. hr = S_OK;
  121. } // else: no security descriptor pointer
  122. }
  123. catch ( ... )
  124. {
  125. TRACE( _T("CClusterSecurityInformation::GetSecurity() - Unknown error occurred.\n") );
  126. }
  127. return hr;
  128. } //*** CClusterSecurityInformation::GetSecurity()
  129. /////////////////////////////////////////////////////////////////////////////
  130. //++
  131. //
  132. // CClusterSecurityInformation::SetSecurity
  133. //
  134. // Routine Description:
  135. // ISecurityInformation is giving back the edited security descriptor.
  136. //
  137. // Arguments:
  138. // SecurityInformation [IN]
  139. // pSecurityDescriptor [IN OUT]
  140. //
  141. // Return Value:
  142. // E_FAIL for error and S_OK for success.
  143. //
  144. //--
  145. /////////////////////////////////////////////////////////////////////////////
  146. STDMETHODIMP CClusterSecurityInformation::SetSecurity(
  147. IN SECURITY_INFORMATION SecurityInformation,
  148. IN PSECURITY_DESCRIPTOR pSecurityDescriptor
  149. )
  150. {
  151. AFX_MANAGE_STATE( ::AfxGetStaticModuleState() );
  152. HRESULT hr = E_FAIL;
  153. PSID pSystemSid = NULL;
  154. PSID pAdminSid = NULL;
  155. PSID pServiceSid = NULL;
  156. try
  157. {
  158. SID_IDENTIFIER_AUTHORITY siaNtAuthority = SECURITY_NT_AUTHORITY;
  159. hr = CSecurityInformation::SetSecurity( SecurityInformation, pSecurityDescriptor );
  160. if ( hr == S_OK )
  161. {
  162. if ( AllocateAndInitializeSid(
  163. &siaNtAuthority,
  164. 1,
  165. SECURITY_LOCAL_SYSTEM_RID,
  166. 0, 0, 0, 0, 0, 0, 0,
  167. &pSystemSid
  168. ) )
  169. {
  170. CString strMsg;
  171. if ( BSidInSD( pSecurityDescriptor, pSystemSid ) )
  172. {
  173. //
  174. // allocate and init the Administrators group sid
  175. //
  176. if ( AllocateAndInitializeSid(
  177. &siaNtAuthority,
  178. 2,
  179. SECURITY_BUILTIN_DOMAIN_RID,
  180. DOMAIN_ALIAS_RID_ADMINS,
  181. 0, 0, 0, 0, 0, 0,
  182. &pAdminSid
  183. ) )
  184. {
  185. if ( BSidInSD( pSecurityDescriptor, pAdminSid ) )
  186. {
  187. //
  188. // allocate and init the Service sid
  189. //
  190. if ( AllocateAndInitializeSid(
  191. &siaNtAuthority,
  192. 1,
  193. SECURITY_SERVICE_RID,
  194. 0, 0, 0, 0, 0, 0, 0,
  195. &pServiceSid
  196. ) )
  197. {
  198. if ( BSidInSD( pSecurityDescriptor, pServiceSid ) )
  199. {
  200. hr = Pcsp()->HrSetSecurityDescriptor( pSecurityDescriptor );
  201. } // if: service SID in the SD
  202. else
  203. {
  204. strMsg.LoadString( IDS_SERVICE_ACCOUNT_NOT_SPECIFIED );
  205. AfxMessageBox( strMsg, MB_OK | MB_ICONSTOP );
  206. hr = S_FALSE; // if there are missing required accounts then return S_FALSE to keep AclUi alive.
  207. } // else
  208. } // if: allocate and init service SID
  209. } // if: admin SID in the SD
  210. else
  211. {
  212. strMsg.LoadString( IDS_ADMIN_ACCOUNT_NOT_SPECIFIED );
  213. AfxMessageBox( strMsg, MB_OK | MB_ICONSTOP );
  214. hr = S_FALSE; // if there are missing required accounts then return S_FALSE to keep AclUi alive.
  215. } // else
  216. } // if: allocate and init admin SID
  217. } // if: system SID in the SD
  218. else
  219. {
  220. strMsg.LoadString( IDS_SYS_ACCOUNT_NOT_SPECIFIED );
  221. AfxMessageBox( strMsg, MB_OK | MB_ICONSTOP );
  222. hr = S_FALSE; // if there are missing required accounts then return S_FALSE to keep AclUi alive.
  223. } // else
  224. } // if: allocate and init system SID
  225. } // if: CSecurityInformation::SetSecurity() worked
  226. }
  227. catch( ... )
  228. {
  229. ;
  230. }
  231. if ( pSystemSid != NULL )
  232. {
  233. FreeSid( pSystemSid );
  234. }
  235. if ( pAdminSid != NULL )
  236. {
  237. FreeSid( pAdminSid );
  238. }
  239. return hr;
  240. } //*** CClusterSecurityInformation::SetSecurity()
  241. /////////////////////////////////////////////////////////////////////////////
  242. //++
  243. //
  244. // CClusterSecurityInformation::HrInit
  245. //
  246. // Routine Description:
  247. // Initialize method.
  248. //
  249. // Arguments:
  250. // pcsp [IN] back pointer to parent property page wrapper
  251. // strServer [IN] cluster name
  252. //
  253. // Return Value:
  254. // S_OK for success. E_FAIL for failure.
  255. //
  256. //--
  257. /////////////////////////////////////////////////////////////////////////////
  258. HRESULT CClusterSecurityInformation::HrInit(
  259. IN CClusterSecurityPage * pcsp,
  260. IN CString const & strServer,
  261. IN CString const & strNode
  262. )
  263. {
  264. ASSERT( pcsp != NULL );
  265. ASSERT( strServer.GetLength() > 0 );
  266. AFX_MANAGE_STATE( ::AfxGetStaticModuleState() );
  267. m_pcsp = pcsp;
  268. m_strServer = strServer;
  269. m_strNode = strNode;
  270. m_nLocalSIDErrorMessageID = IDS_LOCAL_ACCOUNTS_SPECIFIED_CLUS;
  271. return S_OK;
  272. } //*** CClusterSecurityInformation::HrInit()
  273. /////////////////////////////////////////////////////////////////////////////
  274. //++
  275. //
  276. // CClusterSecurityInformation::BSidInSD
  277. //
  278. // Routine Description:
  279. // Determines if there is an ACEs for the passed in SID in the
  280. // Security Descriptor (pSD) after the ACL editor has been called
  281. //
  282. // Arguments:
  283. // pSD [IN] - Security Descriptor to be checked.
  284. // pSid [IN] - SID to look for
  285. //
  286. // Return Value:
  287. // TRUE if an ACE for the SID was found, False otherwise.
  288. //
  289. /////////////////////////////////////////////////////////////////////////////
  290. BOOL CClusterSecurityInformation::BSidInSD(
  291. IN PSECURITY_DESCRIPTOR pSD,
  292. IN PSID pSid
  293. )
  294. {
  295. BOOL bSIdInACL = FALSE;
  296. try
  297. {
  298. PACL pDACL = NULL;
  299. BOOL bHasDACL = FALSE;
  300. BOOL bDaclDefaulted = FALSE;
  301. if ( ::GetSecurityDescriptorDacl( pSD, &bHasDACL, &pDACL, &bDaclDefaulted ) )
  302. {
  303. if ( bHasDACL && ( pDACL != NULL ) && ::IsValidAcl( pDACL ) )
  304. {
  305. ACL_SIZE_INFORMATION asiAclSize;
  306. ACCESS_ALLOWED_ACE * paaAllowedAce;
  307. if ( ::GetAclInformation( pDACL, (LPVOID) &asiAclSize, sizeof( asiAclSize ), AclSizeInformation ) )
  308. {
  309. //
  310. // Search the ACL for the SID
  311. //
  312. for ( DWORD dwCount = 0; dwCount < asiAclSize.AceCount; dwCount++ )
  313. {
  314. if ( ::GetAce( pDACL, dwCount, (LPVOID *) &paaAllowedAce ) )
  315. {
  316. if ( paaAllowedAce->Header.AceType == ACCESS_ALLOWED_ACE_TYPE )
  317. {
  318. if ( EqualSid( &paaAllowedAce->SidStart, pSid ) )
  319. {
  320. bSIdInACL = TRUE;
  321. break;
  322. } // if: EqualSid
  323. } // if: is this an access allowed ace?
  324. } // if: can we get the ace from the DACL?
  325. } // for
  326. } // if: get ACL information
  327. } // if: is the ACL valid
  328. } // if: get the ACL from the SD
  329. }
  330. catch ( ... )
  331. {
  332. TRACE( _T("CClusterSecurityInformation::BSidInSD() - Unknown error occurred.\n") );
  333. }
  334. return bSIdInACL;
  335. } //*** CClusterSecurityInformation::BSidInSD()
  336. /////////////////////////////////////////////////////////////////////////////
  337. //++
  338. //
  339. // CClusterSecurityInformation::HrFixupSD
  340. //
  341. // Routine Description:
  342. // Performs any fixups to the SD that may be requrired.
  343. //
  344. // Arguments:
  345. // pSD [IN] - Security Descriptor to be checked.
  346. //
  347. // Return Value:
  348. // S_OK, or other Win32 error
  349. //
  350. /////////////////////////////////////////////////////////////////////////////
  351. HRESULT CClusterSecurityInformation::HrFixupSD(
  352. IN PSECURITY_DESCRIPTOR pSD
  353. )
  354. {
  355. HRESULT hr = S_OK;
  356. PSID pSystemSid = NULL;
  357. PSID pAdminSid = NULL;
  358. try
  359. {
  360. SID_IDENTIFIER_AUTHORITY siaNtAuthority = SECURITY_NT_AUTHORITY;
  361. if ( AllocateAndInitializeSid( &siaNtAuthority,
  362. 1,
  363. SECURITY_LOCAL_SYSTEM_RID,
  364. 0, 0, 0, 0, 0, 0, 0,
  365. &pSystemSid ) )
  366. {
  367. if ( ! BSidInSD( pSD, pSystemSid ) )
  368. {
  369. HrAddSidToSD( &pSD, pSystemSid );
  370. } // if: system SID found in SD
  371. } // if: allocate system SID
  372. //
  373. // allocate and init the Administrators group sid
  374. //
  375. if ( AllocateAndInitializeSid(
  376. &siaNtAuthority,
  377. 2,
  378. SECURITY_BUILTIN_DOMAIN_RID,
  379. DOMAIN_ALIAS_RID_ADMINS,
  380. 0, 0, 0, 0, 0, 0,
  381. &pAdminSid
  382. ) ) {
  383. if ( ! BSidInSD( pSD, pAdminSid ) )
  384. {
  385. HrAddSidToSD( &pSD, pAdminSid );
  386. } // if: admin SID found in SD
  387. } // if: allocate admin SID
  388. }
  389. catch ( ... )
  390. {
  391. TRACE( _T("CClusterSecurityInformation::HrFixupSD() - Unknown error occurred.\n") );
  392. }
  393. if ( pSystemSid != NULL )
  394. {
  395. FreeSid( pSystemSid );
  396. }
  397. if ( pAdminSid != NULL )
  398. {
  399. FreeSid( pAdminSid );
  400. }
  401. return hr;
  402. } //*** CClusterSecurityInformation::HrFixupSD()
  403. /////////////////////////////////////////////////////////////////////////////
  404. //++
  405. //
  406. // CClusterSecurityInformation::HrAddSidToSD
  407. //
  408. // Routine Description:
  409. // Adds the passed in SID to the DACL of the passed in SD
  410. //
  411. // Arguments:
  412. // ppSD [IN, OUT] - Security Descriptor to be added to
  413. // PSid [IN] - SID to add
  414. //
  415. // Return Value:
  416. // S_OK, or other Win32 error
  417. //
  418. /////////////////////////////////////////////////////////////////////////////
  419. HRESULT CClusterSecurityInformation::HrAddSidToSD(
  420. IN OUT PSECURITY_DESCRIPTOR * ppSD,
  421. IN PSID pSid
  422. )
  423. {
  424. HRESULT hr = S_OK;
  425. DWORD sc;
  426. SECURITY_DESCRIPTOR sd;
  427. DWORD dwSDLen = sizeof( SECURITY_DESCRIPTOR );
  428. PACL pDacl = NULL;
  429. DWORD dwDaclLen = 0;
  430. PACL pSacl = NULL;
  431. DWORD dwSaclLen = 0;
  432. PSID pOwnerSid = NULL;
  433. DWORD dwOwnerSidLen = 0;
  434. PSID pGroupSid = NULL;
  435. DWORD dwGroupSidLen = NULL;
  436. PSECURITY_DESCRIPTOR pNewSD = NULL;
  437. DWORD dwNewSDLen = 0;
  438. try
  439. {
  440. BOOL bRet = FALSE;
  441. bRet = ::MakeAbsoluteSD( *ppSD, // address of self relative SD
  442. &sd, // address of absolute SD
  443. &dwSDLen, // address of size of absolute SD
  444. NULL, // address of discretionary ACL
  445. &dwDaclLen, // address of size of discretionary ACL
  446. NULL, // address of system ACL
  447. &dwSaclLen, // address of size of system ACL
  448. NULL, // address of owner SID
  449. &dwOwnerSidLen, // address of size of owner SID
  450. NULL, // address of primary-group SID
  451. &dwGroupSidLen // address of size of group SID
  452. );
  453. if ( ! bRet )
  454. {
  455. sc = ::GetLastError();
  456. hr = HRESULT_FROM_WIN32( sc );
  457. if ( hr != ERROR_INSUFFICIENT_BUFFER ) // Duh, we're trying to find out how big the buffer should be?
  458. {
  459. goto fnExit;
  460. }
  461. }
  462. //
  463. // increase the DACL length to hold one more ace and its sid.
  464. //
  465. dwDaclLen += ( sizeof( ACCESS_ALLOWED_ACE ) + GetLengthSid( pSid ) +1024 );
  466. pDacl = (PACL) ::LocalAlloc( LMEM_ZEROINIT, dwDaclLen );
  467. if ( pDacl == NULL )
  468. {
  469. hr = E_OUTOFMEMORY;
  470. goto fnExit;
  471. }
  472. InitializeAcl( pDacl, dwDaclLen, ACL_REVISION );
  473. if ( dwSaclLen > 0 )
  474. {
  475. pSacl = (PACL) ::LocalAlloc( LMEM_ZEROINIT, dwSaclLen );
  476. if ( pSacl == NULL )
  477. {
  478. hr = E_OUTOFMEMORY;
  479. goto fnExit;
  480. }
  481. }
  482. if ( dwOwnerSidLen > 0 )
  483. {
  484. pOwnerSid = (PSID) ::LocalAlloc( LMEM_ZEROINIT, dwOwnerSidLen );
  485. if ( pOwnerSid == NULL )
  486. {
  487. hr = E_OUTOFMEMORY;
  488. goto fnExit;
  489. }
  490. }
  491. if ( dwGroupSidLen > 0 )
  492. {
  493. pGroupSid = (PSID) ::LocalAlloc( LMEM_ZEROINIT, dwGroupSidLen );
  494. if ( pGroupSid == NULL )
  495. {
  496. hr = E_OUTOFMEMORY;
  497. goto fnExit;
  498. }
  499. }
  500. bRet = ::MakeAbsoluteSD( *ppSD, // address of self relative SD
  501. &sd, // address of absolute SD
  502. &dwSDLen, // address of size of absolute SD
  503. pDacl, // address of discretionary ACL
  504. &dwDaclLen, // address of size of discretionary ACL
  505. pSacl, // address of system ACL
  506. &dwSaclLen, // address of size of system ACL
  507. pOwnerSid, // address of owner SID
  508. &dwOwnerSidLen, // address of size of owner SID
  509. pGroupSid, // address of primary-group SID
  510. &dwGroupSidLen // address of size of group SID
  511. );
  512. if ( !bRet )
  513. {
  514. goto fnExit;
  515. }
  516. //
  517. // Add the ACE for the SID to the DACL
  518. //
  519. // if ( !AddAccessAllowedAceEx( pDacl,
  520. // ACL_REVISION,
  521. // CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE,
  522. // CLUSAPI_ALL_ACCESS,
  523. // pSid ) )
  524. if ( ! AddAccessAllowedAce(
  525. pDacl,
  526. ACL_REVISION,
  527. CLUSAPI_ALL_ACCESS,
  528. pSid
  529. ) )
  530. {
  531. sc = ::GetLastError();
  532. hr = HRESULT_FROM_WIN32( sc );
  533. goto fnExit;
  534. }
  535. if ( ! ::SetSecurityDescriptorDacl( &sd, TRUE, pDacl, FALSE ) )
  536. {
  537. sc = ::GetLastError();
  538. hr = HRESULT_FROM_WIN32( sc );
  539. goto fnExit;
  540. }
  541. if ( ! ::SetSecurityDescriptorOwner( &sd, pOwnerSid, FALSE ) )
  542. {
  543. sc = ::GetLastError();
  544. hr = HRESULT_FROM_WIN32( sc );
  545. goto fnExit;
  546. }
  547. if ( ! ::SetSecurityDescriptorGroup( &sd, pGroupSid, FALSE ) )
  548. {
  549. sc = ::GetLastError();
  550. hr = HRESULT_FROM_WIN32( sc );
  551. goto fnExit;
  552. }
  553. if ( ! ::SetSecurityDescriptorSacl( &sd, TRUE, pSacl, FALSE ) )
  554. {
  555. sc = ::GetLastError();
  556. hr = HRESULT_FROM_WIN32( sc );
  557. goto fnExit;
  558. }
  559. dwNewSDLen = 0 ;
  560. if ( ! ::MakeSelfRelativeSD( &sd, NULL, &dwNewSDLen ) )
  561. {
  562. sc = ::GetLastError();
  563. hr = HRESULT_FROM_WIN32( sc );
  564. if ( hr != HRESULT_FROM_WIN32( ERROR_INSUFFICIENT_BUFFER ) ) // Duh, we're trying to find out how big the buffer should be?
  565. {
  566. goto fnExit;
  567. }
  568. }
  569. pNewSD = ::LocalAlloc( LPTR, dwNewSDLen );
  570. if ( pNewSD != NULL )
  571. {
  572. if ( ! ::MakeSelfRelativeSD( &sd, pNewSD, &dwNewSDLen ) )
  573. {
  574. sc = ::GetLastError();
  575. hr = HRESULT_FROM_WIN32( sc );
  576. goto fnExit;
  577. }
  578. ::LocalFree( *ppSD );
  579. *ppSD = pNewSD;
  580. hr = ERROR_SUCCESS;
  581. } else
  582. {
  583. hr = ERROR_NOT_ENOUGH_MEMORY;
  584. }
  585. }
  586. catch ( ... )
  587. {
  588. TRACE( _T("CClusterSecurityInformation::HrAddSidToSD() - Unknown error occurred.\n") );
  589. }
  590. fnExit:
  591. if ( pSacl != NULL )
  592. {
  593. ::LocalFree( pSacl );
  594. }
  595. if ( pOwnerSid != NULL )
  596. {
  597. ::LocalFree( pOwnerSid );
  598. }
  599. if ( pGroupSid != NULL )
  600. {
  601. ::LocalFree( pGroupSid );
  602. }
  603. return hr;
  604. } //*** CClusterSecurityInformation::HrAddSidToSD()
  605. //*************************************************************************//
  606. /////////////////////////////////////////////////////////////////////////////
  607. //++
  608. //
  609. // CClusterSecurityPage::CClusterSecurityPage
  610. //
  611. // Routine Description:
  612. // Default contructor.
  613. //
  614. // Arguments:
  615. // none
  616. //
  617. // Return Value:
  618. // none
  619. //
  620. //--
  621. /////////////////////////////////////////////////////////////////////////////
  622. CClusterSecurityPage::CClusterSecurityPage( void )
  623. : m_psec( NULL )
  624. , m_psecPrev( NULL )
  625. , m_hpage( 0 )
  626. , m_hkey( 0 )
  627. , m_psecinfo( NULL )
  628. , m_pOwner( NULL )
  629. , m_pGroup( NULL )
  630. , m_fOwnerDef( FALSE )
  631. , m_fGroupDef( FALSE )
  632. {
  633. AFX_MANAGE_STATE( ::AfxGetStaticModuleState() );
  634. m_bSecDescModified = FALSE;
  635. } //*** CClusterSecurityPage::CClusterSecurityPage()
  636. /////////////////////////////////////////////////////////////////////////////
  637. //++
  638. //
  639. // CClusterSecurityPage::~CClusterSecurityPage
  640. //
  641. // Routine Description:
  642. // Destructor
  643. //
  644. // Arguments:
  645. // none
  646. //
  647. // Return Value:
  648. // none
  649. //
  650. //--
  651. /////////////////////////////////////////////////////////////////////////////
  652. CClusterSecurityPage::~CClusterSecurityPage( void )
  653. {
  654. AFX_MANAGE_STATE( ::AfxGetStaticModuleState() );
  655. ::LocalFree( m_psec );
  656. m_psec = NULL;
  657. ::LocalFree( m_psecPrev );
  658. m_psecPrev = NULL;
  659. ::LocalFree( m_pOwner );
  660. m_pOwner = NULL;
  661. ::LocalFree( m_pGroup );
  662. m_pGroup = NULL;
  663. m_psecinfo->Release();
  664. } //*** CClusterSecurityPage::~CClusterSecurityPage()
  665. /////////////////////////////////////////////////////////////////////////////
  666. //++
  667. //
  668. // CClusterSecurityPage::HrInit
  669. //
  670. // Routine Description:
  671. // Initialize method.
  672. //
  673. // Arguments:
  674. // peo [IN] back pointer to parent extension object.
  675. //
  676. // Return Value:
  677. // S_OK Page was initialized successfully.
  678. // hr Error initializing the page.
  679. //
  680. //--
  681. /////////////////////////////////////////////////////////////////////////////
  682. HRESULT CClusterSecurityPage::HrInit( IN CExtObject * peo )
  683. {
  684. ASSERT( peo != NULL );
  685. AFX_MANAGE_STATE( ::AfxGetStaticModuleState() );
  686. HRESULT _hr = S_OK;
  687. DWORD _sc;
  688. if ( peo != NULL )
  689. {
  690. m_peo = peo;
  691. _hr = CComObject< CClusterSecurityInformation >::CreateInstance( &m_psecinfo );
  692. if ( SUCCEEDED( _hr ) )
  693. {
  694. m_psecinfo->AddRef();
  695. m_hkey = GetClusterKey( Hcluster(), KEY_ALL_ACCESS );
  696. if ( m_hkey != NULL )
  697. {
  698. _hr = HrGetSecurityDescriptor();
  699. if ( SUCCEEDED( _hr ) )
  700. {
  701. CString strServer;
  702. CString strNode;
  703. strServer.Format( _T( "\\\\%s" ), StrClusterName() );
  704. // Get the node on which the Cluster Name resource is online.
  705. if ( BGetClusterNetworkNameNode( strNode ) )
  706. {
  707. _hr = m_psecinfo->HrInit( this, strServer, strNode );
  708. if ( SUCCEEDED( _hr ) )
  709. {
  710. m_hpage = CreateClusterSecurityPage( m_psecinfo );
  711. if ( m_hpage == NULL )
  712. {
  713. _sc = ::GetLastError();
  714. _hr = HRESULT_FROM_WIN32( _sc );
  715. } // if: error creating the page
  716. } // if: initialized security info successfully
  717. } // if: retrieved cluster network name node successfully
  718. else
  719. {
  720. } // else: error getting cluster network name node
  721. } // if: error getting SD
  722. } // if: retrieved cluster key
  723. else
  724. {
  725. _sc = ::GetLastError();
  726. _hr = HRESULT_FROM_WIN32( _sc );
  727. TRACE( _T( "CClusterSecurityPage::ScInit() - Failed to get the cluster key, 0x%08lx.\n" ), _sc );
  728. } // else: error getting cluster key
  729. } // if: created security info object successfully
  730. else
  731. {
  732. TRACE( _T( "CClusterSecurityPage::ScInit() - Failed to create CClusterSecurityInformation object, %0x%08lx.\n" ), _hr );
  733. }
  734. } // if: extension object is available
  735. return _hr;
  736. } //*** CClusterSecurityPage::HrInit()
  737. /////////////////////////////////////////////////////////////////////////////
  738. //++
  739. //
  740. // CClusterSecurityPage::HrGetSecurityDescriptor
  741. //
  742. // Routine Description:
  743. // Get the security descriptor from the cluster database or create a
  744. // default one if it doesn't exist.
  745. //
  746. // Arguments:
  747. // none
  748. //
  749. // Return Value:
  750. //
  751. //
  752. //--
  753. /////////////////////////////////////////////////////////////////////////////
  754. HRESULT CClusterSecurityPage::HrGetSecurityDescriptor( void )
  755. {
  756. AFX_MANAGE_STATE( ::AfxGetStaticModuleState() );
  757. HRESULT hr = S_OK;
  758. PSECURITY_DESCRIPTOR psec = NULL;
  759. hr = HrGetSDFromClusterDB( &psec ); //uses localalloc
  760. if ( FAILED( hr ) || ( psec == NULL ) )
  761. {
  762. DWORD sc;
  763. DWORD dwLen = 0;
  764. TRACE( _T( "Security Descriptor is NULL. Build default SD" ) );
  765. sc = ::ClRtlBuildDefaultClusterSD( NULL, &psec, &dwLen ); //uses localalloc
  766. hr = HRESULT_FROM_WIN32( sc );
  767. if ( sc != ERROR_SUCCESS )
  768. {
  769. TRACE( _T( "ClRtlBuildDefaultClusterSD failed, 0x%08x" ), sc );
  770. } // if: error building the default SD
  771. hr = HRESULT_FROM_WIN32( sc );
  772. } // if: error getting SD from cluster database
  773. if ( SUCCEEDED( hr ) )
  774. {
  775. delete m_psec;
  776. m_psec = ClRtlCopySecurityDescriptor( psec );
  777. hr = GetLastError(); // Get the last error
  778. ::LocalFree( psec );
  779. psec = NULL;
  780. if ( m_psec == NULL )
  781. {
  782. hr = HRESULT_FROM_WIN32( hr ); // Convert to HRESULT
  783. goto Cleanup;
  784. } // if: error copying the security descriptor
  785. hr = HrGetSDOwner( m_psec );
  786. if ( SUCCEEDED( hr ) )
  787. {
  788. hr = HrGetSDGroup( m_psec );
  789. if ( SUCCEEDED( hr ) )
  790. {
  791. m_psecPrev = ClRtlCopySecurityDescriptor( m_psec );
  792. if ( m_psecPrev == NULL )
  793. {
  794. hr = GetLastError(); // Get the last error
  795. hr = HRESULT_FROM_WIN32( hr ); // Convert to HRESULT
  796. goto Cleanup;
  797. } // if: error copying the security descriptor
  798. } // if: got SD group successfully
  799. } // if: got SD owner successfully
  800. } // if: retrieved or built SD successfully
  801. #ifdef _DEBUG
  802. if ( m_psec != NULL )
  803. {
  804. ASSERT( IsValidSecurityDescriptor( m_psec ) );
  805. }
  806. #endif
  807. Cleanup:
  808. return hr;
  809. } //*** CClusterSecurityPage::HrGetSecurityDescriptor()
  810. /////////////////////////////////////////////////////////////////////////////
  811. //++
  812. //
  813. // CClusterSecurityPage::HrSetSecurityDescriptor
  814. //
  815. // Routine Description:
  816. // Save the new security descriptor to the cluster database.
  817. //
  818. // Arguments:
  819. // psec [IN] the new security descriptor
  820. //
  821. // Return Value:
  822. // hr
  823. //
  824. //--
  825. /////////////////////////////////////////////////////////////////////////////
  826. HRESULT CClusterSecurityPage::HrSetSecurityDescriptor(
  827. IN PSECURITY_DESCRIPTOR psec
  828. )
  829. {
  830. ASSERT( psec != NULL );
  831. AFX_MANAGE_STATE( ::AfxGetStaticModuleState() );
  832. HRESULT hr = S_OK;
  833. try
  834. {
  835. if ( psec != NULL )
  836. {
  837. CWaitCursor wc;
  838. ASSERT( IsValidSecurityDescriptor( psec ) );
  839. if ( IsValidSecurityDescriptor( psec ) )
  840. {
  841. hr = HrSetSDOwner( psec );
  842. if ( SUCCEEDED( hr ) )
  843. {
  844. hr = HrSetSDGroup( psec );
  845. if ( SUCCEEDED( hr ) )
  846. {
  847. LocalFree( m_psecPrev );
  848. m_psecPrev = NULL;
  849. if ( m_psec == NULL )
  850. {
  851. m_psecPrev = NULL;
  852. } // if: no previous value
  853. else
  854. {
  855. m_psecPrev = ClRtlCopySecurityDescriptor( m_psec );
  856. if ( m_psecPrev == NULL )
  857. {
  858. hr = GetLastError(); // Get the last error
  859. TRACE( _T( "CClusterSecurityPage::HrSetSecurityDescriptor() - Error %08.8x copying the previous SD.\n" ), hr );
  860. hr = HRESULT_FROM_WIN32( hr ); // Convert to HRESULT
  861. goto Cleanup;
  862. } // if: error copying the security descriptor
  863. } // else: previous value exists
  864. LocalFree( m_psec );
  865. m_psec = NULL;
  866. m_psec = ClRtlCopySecurityDescriptor( psec );
  867. if ( m_psec == NULL )
  868. {
  869. hr = GetLastError(); // Get the last error
  870. TRACE( _T( "CClusterSecurityPage::HrSetSecurityDescriptor() - Error %08.8x copying the new SD.\n" ), hr );
  871. hr = HRESULT_FROM_WIN32( hr ); // Convert to HRESULT
  872. goto Cleanup;
  873. } // if: error copying the security descriptor
  874. SetPermissions( m_psec );
  875. } // if: SD group set successfully
  876. } // if: SD owner set successfully
  877. } // if: security descriptor is valid
  878. else
  879. {
  880. hr = HRESULT_FROM_WIN32( ERROR_INVALID_SECURITY_DESCR );
  881. TRACE( _T( "CClusterSecurityPage::HrSetSecurityDescriptor() - Invalid security descriptor.\n" ) );
  882. } // else: invalid security descriptor
  883. } // if: security descriptor specified
  884. else
  885. {
  886. hr = HRESULT_FROM_WIN32( ERROR_INVALID_SECURITY_DESCR );
  887. } // else: no security descriptor specified
  888. } // try
  889. catch ( ... )
  890. {
  891. hr = E_FAIL;
  892. TRACE( _T( "CClusterSecurityPage::HrSetSecurityDescriptor() - Unknown error occurred.\n" ) );
  893. }
  894. Cleanup:
  895. return hr;
  896. } //*** CClusterSecurityPage::HrSetSecurityDescriptor()
  897. /////////////////////////////////////////////////////////////////////////////
  898. //++
  899. //
  900. // CClusterSecurityPage::SetPermissions
  901. //
  902. // Routine Description:
  903. // Set the permissions for accessing the cluster.
  904. //
  905. // Arguments:
  906. // psec [IN] Security descriptor.
  907. //
  908. // Return Value:
  909. // None.
  910. //
  911. // Exceptions Thrown:
  912. // Any exceptions thrown by CClusterItem::WriteValue().
  913. //--
  914. /////////////////////////////////////////////////////////////////////////////
  915. void CClusterSecurityPage::SetPermissions(
  916. IN const PSECURITY_DESCRIPTOR psec
  917. )
  918. {
  919. ASSERT( psec != NULL );
  920. ASSERT( IsValidSecurityDescriptor( psec ) );
  921. DWORD cbNew;
  922. DWORD cbOld;
  923. LPBYTE psecPrev; // buffer for use by ScWriteValue. Prev SD is saved elsewhere now.
  924. // Get the length of the two security descriptors.
  925. if ( m_psecPrev == NULL )
  926. {
  927. cbOld = 0;
  928. }
  929. else
  930. {
  931. cbOld = ::GetSecurityDescriptorLength( m_psecPrev );
  932. }
  933. if ( psec == NULL )
  934. {
  935. cbNew = 0;
  936. }
  937. else
  938. {
  939. cbNew = ::GetSecurityDescriptorLength( psec );
  940. }
  941. // Allocate a new buffer for the previous data pointer.
  942. try
  943. {
  944. psecPrev = new BYTE [cbOld];
  945. if ( psecPrev == NULL )
  946. {
  947. return;
  948. } // if: error allocating previous data buffer
  949. }
  950. catch ( CMemoryException * )
  951. {
  952. return;
  953. } // catch: CMemoryException
  954. ::CopyMemory( psecPrev, m_psecPrev, cbOld );
  955. ScWriteValue( CLUSREG_NAME_CLUS_SD, (LPBYTE) psec, cbNew, (LPBYTE *) &psecPrev, cbOld, m_hkey );
  956. PSECURITY_DESCRIPTOR psd = ClRtlConvertClusterSDToNT4Format( psec );
  957. ScWriteValue( CLUSREG_NAME_CLUS_SECURITY, (LPBYTE) psd, cbNew, (LPBYTE *) &psecPrev, cbOld, m_hkey );
  958. ::LocalFree( psd );
  959. delete [] psecPrev;
  960. } //*** CClusterSecurityPage::SetPermissions()
  961. /////////////////////////////////////////////////////////////////////////////
  962. //++
  963. //
  964. // CClusterSecurityPage::HrGetSDOwner
  965. //
  966. // Routine Description:
  967. // Get the owner sid and save it.
  968. //
  969. // Arguments:
  970. // psec [IN] Security descriptor.
  971. //
  972. // Return Value:
  973. // hr
  974. //
  975. //--
  976. /////////////////////////////////////////////////////////////////////////////
  977. HRESULT CClusterSecurityPage::HrGetSDOwner(
  978. IN const PSECURITY_DESCRIPTOR psec
  979. )
  980. {
  981. HRESULT hr = S_OK;
  982. DWORD sc;
  983. PSID pOwner = NULL;
  984. if ( ::GetSecurityDescriptorOwner( psec, &pOwner, &m_fOwnerDef ) != 0 )
  985. {
  986. // The security descriptor does not have an owner.
  987. if ( pOwner == NULL )
  988. {
  989. ::LocalFree( m_pOwner );
  990. m_pOwner = NULL;
  991. }
  992. else
  993. {
  994. DWORD dwLen = ::GetLengthSid( pOwner );
  995. // copy the sid since AclUi will free the SD...
  996. hr = ::GetLastError();
  997. if ( SUCCEEDED( hr ) )
  998. {
  999. ::LocalFree( m_pOwner );
  1000. m_pOwner = ::LocalAlloc( LMEM_ZEROINIT, dwLen );
  1001. if ( m_pOwner != NULL )
  1002. {
  1003. if ( ::CopySid( dwLen, m_pOwner, pOwner ) )
  1004. {
  1005. hr = S_OK;
  1006. }
  1007. else
  1008. {
  1009. sc = ::GetLastError();
  1010. hr = HRESULT_FROM_WIN32( sc );
  1011. }
  1012. }
  1013. else
  1014. {
  1015. sc = ::GetLastError();
  1016. hr = HRESULT_FROM_WIN32( sc );
  1017. }
  1018. }
  1019. }
  1020. }
  1021. else
  1022. {
  1023. sc = ::GetLastError();
  1024. hr = HRESULT_FROM_WIN32( sc );
  1025. }
  1026. return( hr );
  1027. } //*** CClusterSecurityPage::HrGetSDOwner()
  1028. /////////////////////////////////////////////////////////////////////////////
  1029. //++
  1030. //
  1031. // CClusterSecurityPage::HrGetSDGroup
  1032. //
  1033. // Routine Description:
  1034. // Get the group sid and save it.
  1035. //
  1036. // Arguments:
  1037. // psec [IN] Security descriptor.
  1038. //
  1039. // Return Value:
  1040. // None.
  1041. //
  1042. //--
  1043. /////////////////////////////////////////////////////////////////////////////
  1044. HRESULT CClusterSecurityPage::HrGetSDGroup(
  1045. IN const PSECURITY_DESCRIPTOR psec
  1046. )
  1047. {
  1048. HRESULT hr = S_OK;
  1049. DWORD sc;
  1050. PSID pGroup = NULL;
  1051. if ( ::GetSecurityDescriptorOwner( psec, &pGroup, &m_fOwnerDef ) != 0 )
  1052. {
  1053. // This SID does not contain group information.
  1054. if ( pGroup == NULL )
  1055. {
  1056. ::LocalFree( m_pGroup );
  1057. m_pGroup = NULL;
  1058. }
  1059. else
  1060. {
  1061. DWORD dwLen = ::GetLengthSid( pGroup );
  1062. // copy the sid since AclUi will free the SD...
  1063. hr = ::GetLastError();
  1064. if ( SUCCEEDED( hr ) )
  1065. {
  1066. ::LocalFree( m_pGroup );
  1067. m_pGroup = ::LocalAlloc( LMEM_ZEROINIT, dwLen );
  1068. if ( m_pGroup != NULL )
  1069. {
  1070. if ( ::CopySid( dwLen, m_pGroup, pGroup ) )
  1071. {
  1072. hr = S_OK;
  1073. }
  1074. else
  1075. {
  1076. sc = ::GetLastError();
  1077. hr = HRESULT_FROM_WIN32( sc );
  1078. }
  1079. }
  1080. else
  1081. {
  1082. sc = ::GetLastError();
  1083. hr = HRESULT_FROM_WIN32( sc );
  1084. }
  1085. }
  1086. }
  1087. }
  1088. else
  1089. {
  1090. sc = ::GetLastError();
  1091. hr = HRESULT_FROM_WIN32( sc );
  1092. }
  1093. return( hr );
  1094. } //*** CClusterSecurityPage::HrGetSDGroup()
  1095. /////////////////////////////////////////////////////////////////////////////
  1096. //++
  1097. //
  1098. // CClusterSecurityPage::HrSetSDOwner
  1099. //
  1100. // Routine Description:
  1101. // Set the owner sid.
  1102. //
  1103. // Arguments:
  1104. // psec [IN] Security descriptor.
  1105. //
  1106. // Return Value:
  1107. // None.
  1108. //
  1109. //--
  1110. /////////////////////////////////////////////////////////////////////////////
  1111. HRESULT CClusterSecurityPage::HrSetSDOwner(
  1112. IN PSECURITY_DESCRIPTOR psec
  1113. )
  1114. {
  1115. HRESULT hr = S_OK;
  1116. if ( !::SetSecurityDescriptorOwner( psec, m_pOwner, m_fOwnerDef ) )
  1117. {
  1118. DWORD sc = ::GetLastError();
  1119. hr = HRESULT_FROM_WIN32( sc );
  1120. }
  1121. return( hr );
  1122. } //*** CClusterSecurityPage::HrSetSDOwner()
  1123. /////////////////////////////////////////////////////////////////////////////
  1124. //++
  1125. //
  1126. // CClusterSecurityPage::HrSetSDGroup
  1127. //
  1128. // Routine Description:
  1129. // Set the group sid.
  1130. //
  1131. // Arguments:
  1132. // psec [IN] Security descriptor.
  1133. //
  1134. // Return Value:
  1135. // None.
  1136. //
  1137. //--
  1138. /////////////////////////////////////////////////////////////////////////////
  1139. HRESULT CClusterSecurityPage::HrSetSDGroup(
  1140. IN PSECURITY_DESCRIPTOR psec
  1141. )
  1142. {
  1143. HRESULT hr = S_OK;
  1144. if ( !::SetSecurityDescriptorGroup( psec, m_pGroup, m_fGroupDef ) )
  1145. {
  1146. DWORD sc = ::GetLastError();
  1147. hr = HRESULT_FROM_WIN32( sc );
  1148. }
  1149. return( hr );
  1150. } //*** CClusterSecurityPage::HrSetSDGroup()
  1151. /////////////////////////////////////////////////////////////////////////////
  1152. //++
  1153. //
  1154. // CClusterSecurityPage::HrGetSDFromClusterDB
  1155. //
  1156. // Routine Description:
  1157. // Retrieve the SD from the cluster database.
  1158. //
  1159. // Arguments:
  1160. // ppsec [OUT] Pointer to security descriptor.
  1161. //
  1162. // Return Value:
  1163. // S_OK for success
  1164. // Any error returned by ScReadValue
  1165. //
  1166. //--
  1167. /////////////////////////////////////////////////////////////////////////////
  1168. HRESULT CClusterSecurityPage::HrGetSDFromClusterDB(
  1169. OUT PSECURITY_DESCRIPTOR * ppsec
  1170. )
  1171. {
  1172. AFX_MANAGE_STATE( ::AfxGetStaticModuleState() );
  1173. ASSERT( ppsec != NULL );
  1174. HRESULT hr = E_FAIL;
  1175. PSECURITY_DESCRIPTOR psd = NULL;
  1176. if ( ppsec != NULL )
  1177. {
  1178. DWORD sc;
  1179. // Read the security descriptor.
  1180. sc = ScReadValue( CLUSREG_NAME_CLUS_SD, (LPBYTE *) &psd, m_hkey ); //alloc using new
  1181. hr = HRESULT_FROM_WIN32( sc );
  1182. if ( FAILED( hr ) || ( psd == NULL ) )
  1183. { // try getting the NT4 SD...
  1184. sc = ScReadValue( CLUSREG_NAME_CLUS_SECURITY, (LPBYTE *) &psd, m_hkey ); //alloc using new
  1185. hr = HRESULT_FROM_WIN32( sc );
  1186. if ( SUCCEEDED( hr ) )
  1187. {
  1188. *ppsec = ::ClRtlConvertClusterSDToNT5Format( psd );
  1189. }
  1190. }
  1191. else
  1192. {
  1193. *ppsec = ClRtlCopySecurityDescriptor( psd );
  1194. if ( *ppsec == NULL )
  1195. {
  1196. hr = GetLastError(); // Get the last error
  1197. hr = HRESULT_FROM_WIN32( hr ); // Convert to HRESULT
  1198. } // if: error copying the security descriptor
  1199. }
  1200. delete [] psd;
  1201. if ( *ppsec != NULL )
  1202. {
  1203. ::ClRtlExamineSD( *ppsec, "[ClusPage]" );
  1204. } // if: security descriptor is available to be examined
  1205. }
  1206. return hr;
  1207. } //*** CClusterSecurityPage::HrGetSDFromClusterDB