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.

1395 lines
43 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 pNetServiceSid = 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 Network Service sid
  189. //
  190. if ( AllocateAndInitializeSid(
  191. &siaNtAuthority,
  192. 1,
  193. SECURITY_NETWORK_SERVICE_RID,
  194. 0, 0, 0, 0, 0, 0, 0,
  195. &pNetServiceSid
  196. ) )
  197. {
  198. if ( BSidInSD( pSecurityDescriptor, pNetServiceSid ) )
  199. {
  200. hr = Pcsp()->HrSetSecurityDescriptor( pSecurityDescriptor );
  201. } // if: service SID in the SD
  202. else
  203. {
  204. strMsg.LoadString( IDS_NETSERVICE_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. if ( pNetServiceSid != NULL )
  240. {
  241. FreeSid( pNetServiceSid );
  242. }
  243. return hr;
  244. } //*** CClusterSecurityInformation::SetSecurity()
  245. /////////////////////////////////////////////////////////////////////////////
  246. //++
  247. //
  248. // CClusterSecurityInformation::HrInit
  249. //
  250. // Routine Description:
  251. // Initialize method.
  252. //
  253. // Arguments:
  254. // pcsp [IN] back pointer to parent property page wrapper
  255. // strServer [IN] cluster name
  256. //
  257. // Return Value:
  258. // S_OK for success. E_FAIL for failure.
  259. //
  260. //--
  261. /////////////////////////////////////////////////////////////////////////////
  262. HRESULT CClusterSecurityInformation::HrInit(
  263. IN CClusterSecurityPage * pcsp,
  264. IN CString const & strServer,
  265. IN CString const & strNode
  266. )
  267. {
  268. ASSERT( pcsp != NULL );
  269. ASSERT( strServer.GetLength() > 0 );
  270. AFX_MANAGE_STATE( ::AfxGetStaticModuleState() );
  271. m_pcsp = pcsp;
  272. m_strServer = strServer;
  273. m_strNode = strNode;
  274. m_nLocalSIDErrorMessageID = IDS_LOCAL_ACCOUNTS_SPECIFIED_CLUS;
  275. return S_OK;
  276. } //*** CClusterSecurityInformation::HrInit()
  277. /////////////////////////////////////////////////////////////////////////////
  278. //++
  279. //
  280. // CClusterSecurityInformation::BSidInSD
  281. //
  282. // Routine Description:
  283. // Determines if there is an ACEs for the passed in SID in the
  284. // Security Descriptor (pSD) after the ACL editor has been called
  285. //
  286. // Arguments:
  287. // pSD [IN] - Security Descriptor to be checked.
  288. // pSid [IN] - SID to look for
  289. //
  290. // Return Value:
  291. // TRUE if an ACE for the SID was found, False otherwise.
  292. //
  293. /////////////////////////////////////////////////////////////////////////////
  294. BOOL CClusterSecurityInformation::BSidInSD(
  295. IN PSECURITY_DESCRIPTOR pSD,
  296. IN PSID pSid
  297. )
  298. {
  299. BOOL bSIdInACL = FALSE;
  300. try
  301. {
  302. PACL pDACL = NULL;
  303. BOOL bHasDACL = FALSE;
  304. BOOL bDaclDefaulted = FALSE;
  305. if ( ::GetSecurityDescriptorDacl( pSD, &bHasDACL, &pDACL, &bDaclDefaulted ) )
  306. {
  307. if ( bHasDACL && ( pDACL != NULL ) && ::IsValidAcl( pDACL ) )
  308. {
  309. ACL_SIZE_INFORMATION asiAclSize;
  310. ACCESS_ALLOWED_ACE * paaAllowedAce;
  311. if ( ::GetAclInformation( pDACL, (LPVOID) &asiAclSize, sizeof( asiAclSize ), AclSizeInformation ) )
  312. {
  313. //
  314. // Search the ACL for the SID
  315. //
  316. for ( DWORD dwCount = 0; dwCount < asiAclSize.AceCount; dwCount++ )
  317. {
  318. if ( ::GetAce( pDACL, dwCount, (LPVOID *) &paaAllowedAce ) )
  319. {
  320. if ( paaAllowedAce->Header.AceType == ACCESS_ALLOWED_ACE_TYPE )
  321. {
  322. if ( EqualSid( &paaAllowedAce->SidStart, pSid ) )
  323. {
  324. bSIdInACL = TRUE;
  325. break;
  326. } // if: EqualSid
  327. } // if: is this an access allowed ace?
  328. } // if: can we get the ace from the DACL?
  329. } // for
  330. } // if: get ACL information
  331. } // if: is the ACL valid
  332. } // if: get the ACL from the SD
  333. }
  334. catch ( ... )
  335. {
  336. TRACE( _T("CClusterSecurityInformation::BSidInSD() - Unknown error occurred.\n") );
  337. }
  338. return bSIdInACL;
  339. } //*** CClusterSecurityInformation::BSidInSD()
  340. /////////////////////////////////////////////////////////////////////////////
  341. //++
  342. //
  343. // CClusterSecurityInformation::HrFixupSD
  344. //
  345. // Routine Description:
  346. // Performs any fixups to the SD that may be requrired.
  347. //
  348. // Arguments:
  349. // pSD [IN] - Security Descriptor to be checked.
  350. //
  351. // Return Value:
  352. // S_OK, or other Win32 error
  353. //
  354. /////////////////////////////////////////////////////////////////////////////
  355. HRESULT CClusterSecurityInformation::HrFixupSD(
  356. IN PSECURITY_DESCRIPTOR pSD
  357. )
  358. {
  359. HRESULT hr = S_OK;
  360. PSID pSystemSid = NULL;
  361. PSID pAdminSid = NULL;
  362. PSID pNetServiceSid = NULL;
  363. try
  364. {
  365. SID_IDENTIFIER_AUTHORITY siaNtAuthority = SECURITY_NT_AUTHORITY;
  366. if ( AllocateAndInitializeSid( &siaNtAuthority,
  367. 1,
  368. SECURITY_LOCAL_SYSTEM_RID,
  369. 0, 0, 0, 0, 0, 0, 0,
  370. &pSystemSid ) )
  371. {
  372. if ( ! BSidInSD( pSD, pSystemSid ) )
  373. {
  374. HrAddSidToSD( &pSD, pSystemSid );
  375. } // if: system SID found in SD
  376. } // if: allocate system SID
  377. //
  378. // allocate and init the Administrators group sid
  379. //
  380. if ( AllocateAndInitializeSid(
  381. &siaNtAuthority,
  382. 2,
  383. SECURITY_BUILTIN_DOMAIN_RID,
  384. DOMAIN_ALIAS_RID_ADMINS,
  385. 0, 0, 0, 0, 0, 0,
  386. &pAdminSid
  387. ) ) {
  388. if ( ! BSidInSD( pSD, pAdminSid ) )
  389. {
  390. HrAddSidToSD( &pSD, pAdminSid );
  391. } // if: admin SID found in SD
  392. } // if: allocate admin SID
  393. //
  394. // allocate and init the Network Service sid
  395. //
  396. if ( AllocateAndInitializeSid(
  397. &siaNtAuthority,
  398. 1,
  399. SECURITY_NETWORK_SERVICE_RID,
  400. 0, 0, 0, 0, 0, 0, 0,
  401. &pNetServiceSid
  402. ) ) {
  403. if ( ! BSidInSD( pSD, pNetServiceSid ) )
  404. {
  405. HrAddSidToSD( &pSD, pNetServiceSid );
  406. } // if: Network Service SID found in SD
  407. } // if: allocate Network Service SID
  408. }
  409. catch ( ... )
  410. {
  411. TRACE( _T("CClusterSecurityInformation::HrFixupSD() - Unknown error occurred.\n") );
  412. }
  413. if ( pSystemSid != NULL )
  414. {
  415. FreeSid( pSystemSid );
  416. }
  417. if ( pAdminSid != NULL )
  418. {
  419. FreeSid( pAdminSid );
  420. }
  421. if ( pNetServiceSid != NULL )
  422. {
  423. FreeSid( pNetServiceSid );
  424. }
  425. return hr;
  426. } //*** CClusterSecurityInformation::HrFixupSD()
  427. /////////////////////////////////////////////////////////////////////////////
  428. //++
  429. //
  430. // CClusterSecurityInformation::HrAddSidToSD
  431. //
  432. // Routine Description:
  433. // Adds the passed in SID to the DACL of the passed in SD
  434. //
  435. // Arguments:
  436. // ppSD [IN, OUT] - Security Descriptor to be added to
  437. // PSid [IN] - SID to add
  438. //
  439. // Return Value:
  440. // S_OK, or other Win32 error
  441. //
  442. /////////////////////////////////////////////////////////////////////////////
  443. HRESULT CClusterSecurityInformation::HrAddSidToSD(
  444. IN OUT PSECURITY_DESCRIPTOR * ppSD,
  445. IN PSID pSid
  446. )
  447. {
  448. HRESULT hr = S_OK;
  449. DWORD sc;
  450. SECURITY_DESCRIPTOR sd;
  451. DWORD dwSDLen = sizeof( SECURITY_DESCRIPTOR );
  452. PACL pDacl = NULL;
  453. DWORD dwDaclLen = 0;
  454. PACL pSacl = NULL;
  455. DWORD dwSaclLen = 0;
  456. PSID pOwnerSid = NULL;
  457. DWORD dwOwnerSidLen = 0;
  458. PSID pGroupSid = NULL;
  459. DWORD dwGroupSidLen = NULL;
  460. PSECURITY_DESCRIPTOR pNewSD = NULL;
  461. DWORD dwNewSDLen = 0;
  462. try
  463. {
  464. BOOL bRet = FALSE;
  465. bRet = ::MakeAbsoluteSD( *ppSD, // address of self relative SD
  466. &sd, // address of absolute SD
  467. &dwSDLen, // address of size of absolute SD
  468. NULL, // address of discretionary ACL
  469. &dwDaclLen, // address of size of discretionary ACL
  470. NULL, // address of system ACL
  471. &dwSaclLen, // address of size of system ACL
  472. NULL, // address of owner SID
  473. &dwOwnerSidLen, // address of size of owner SID
  474. NULL, // address of primary-group SID
  475. &dwGroupSidLen // address of size of group SID
  476. );
  477. if ( ! bRet )
  478. {
  479. sc = ::GetLastError();
  480. hr = HRESULT_FROM_WIN32( sc );
  481. if ( hr != ERROR_INSUFFICIENT_BUFFER ) // Duh, we're trying to find out how big the buffer should be?
  482. {
  483. goto fnExit;
  484. }
  485. }
  486. //
  487. // increase the DACL length to hold one more ace and its sid.
  488. //
  489. dwDaclLen += ( sizeof( ACCESS_ALLOWED_ACE ) + GetLengthSid( pSid ) +1024 );
  490. pDacl = (PACL) ::LocalAlloc( LMEM_ZEROINIT, dwDaclLen );
  491. if ( pDacl == NULL )
  492. {
  493. hr = E_OUTOFMEMORY;
  494. goto fnExit;
  495. }
  496. InitializeAcl( pDacl, dwDaclLen, ACL_REVISION );
  497. if ( dwSaclLen > 0 )
  498. {
  499. pSacl = (PACL) ::LocalAlloc( LMEM_ZEROINIT, dwSaclLen );
  500. if ( pSacl == NULL )
  501. {
  502. hr = E_OUTOFMEMORY;
  503. goto fnExit;
  504. }
  505. }
  506. if ( dwOwnerSidLen > 0 )
  507. {
  508. pOwnerSid = (PSID) ::LocalAlloc( LMEM_ZEROINIT, dwOwnerSidLen );
  509. if ( pOwnerSid == NULL )
  510. {
  511. hr = E_OUTOFMEMORY;
  512. goto fnExit;
  513. }
  514. }
  515. if ( dwGroupSidLen > 0 )
  516. {
  517. pGroupSid = (PSID) ::LocalAlloc( LMEM_ZEROINIT, dwGroupSidLen );
  518. if ( pGroupSid == NULL )
  519. {
  520. hr = E_OUTOFMEMORY;
  521. goto fnExit;
  522. }
  523. }
  524. bRet = ::MakeAbsoluteSD( *ppSD, // address of self relative SD
  525. &sd, // address of absolute SD
  526. &dwSDLen, // address of size of absolute SD
  527. pDacl, // address of discretionary ACL
  528. &dwDaclLen, // address of size of discretionary ACL
  529. pSacl, // address of system ACL
  530. &dwSaclLen, // address of size of system ACL
  531. pOwnerSid, // address of owner SID
  532. &dwOwnerSidLen, // address of size of owner SID
  533. pGroupSid, // address of primary-group SID
  534. &dwGroupSidLen // address of size of group SID
  535. );
  536. if ( !bRet )
  537. {
  538. goto fnExit;
  539. }
  540. //
  541. // Add the ACE for the SID to the DACL
  542. //
  543. // if ( !AddAccessAllowedAceEx( pDacl,
  544. // ACL_REVISION,
  545. // CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE,
  546. // CLUSAPI_ALL_ACCESS,
  547. // pSid ) )
  548. if ( ! AddAccessAllowedAce(
  549. pDacl,
  550. ACL_REVISION,
  551. CLUSAPI_ALL_ACCESS,
  552. pSid
  553. ) )
  554. {
  555. sc = ::GetLastError();
  556. hr = HRESULT_FROM_WIN32( sc );
  557. goto fnExit;
  558. }
  559. if ( ! ::SetSecurityDescriptorDacl( &sd, TRUE, pDacl, FALSE ) )
  560. {
  561. sc = ::GetLastError();
  562. hr = HRESULT_FROM_WIN32( sc );
  563. goto fnExit;
  564. }
  565. if ( ! ::SetSecurityDescriptorOwner( &sd, pOwnerSid, FALSE ) )
  566. {
  567. sc = ::GetLastError();
  568. hr = HRESULT_FROM_WIN32( sc );
  569. goto fnExit;
  570. }
  571. if ( ! ::SetSecurityDescriptorGroup( &sd, pGroupSid, FALSE ) )
  572. {
  573. sc = ::GetLastError();
  574. hr = HRESULT_FROM_WIN32( sc );
  575. goto fnExit;
  576. }
  577. if ( ! ::SetSecurityDescriptorSacl( &sd, TRUE, pSacl, FALSE ) )
  578. {
  579. sc = ::GetLastError();
  580. hr = HRESULT_FROM_WIN32( sc );
  581. goto fnExit;
  582. }
  583. dwNewSDLen = 0 ;
  584. if ( ! ::MakeSelfRelativeSD( &sd, NULL, &dwNewSDLen ) )
  585. {
  586. sc = ::GetLastError();
  587. hr = HRESULT_FROM_WIN32( sc );
  588. if ( hr != HRESULT_FROM_WIN32( ERROR_INSUFFICIENT_BUFFER ) ) // Duh, we're trying to find out how big the buffer should be?
  589. {
  590. goto fnExit;
  591. }
  592. }
  593. pNewSD = ::LocalAlloc( LPTR, dwNewSDLen );
  594. if ( pNewSD != NULL )
  595. {
  596. if ( ! ::MakeSelfRelativeSD( &sd, pNewSD, &dwNewSDLen ) )
  597. {
  598. sc = ::GetLastError();
  599. hr = HRESULT_FROM_WIN32( sc );
  600. goto fnExit;
  601. }
  602. ::LocalFree( *ppSD );
  603. *ppSD = pNewSD;
  604. hr = ERROR_SUCCESS;
  605. } else
  606. {
  607. hr = ERROR_NOT_ENOUGH_MEMORY;
  608. }
  609. }
  610. catch ( ... )
  611. {
  612. TRACE( _T("CClusterSecurityInformation::HrAddSidToSD() - Unknown error occurred.\n") );
  613. }
  614. fnExit:
  615. if ( pSacl != NULL )
  616. {
  617. ::LocalFree( pSacl );
  618. }
  619. if ( pOwnerSid != NULL )
  620. {
  621. ::LocalFree( pOwnerSid );
  622. }
  623. if ( pGroupSid != NULL )
  624. {
  625. ::LocalFree( pGroupSid );
  626. }
  627. return hr;
  628. } //*** CClusterSecurityInformation::HrAddSidToSD()
  629. //*************************************************************************//
  630. /////////////////////////////////////////////////////////////////////////////
  631. //++
  632. //
  633. // CClusterSecurityPage::CClusterSecurityPage
  634. //
  635. // Routine Description:
  636. // Default contructor.
  637. //
  638. // Arguments:
  639. // none
  640. //
  641. // Return Value:
  642. // none
  643. //
  644. //--
  645. /////////////////////////////////////////////////////////////////////////////
  646. CClusterSecurityPage::CClusterSecurityPage( void )
  647. : m_psec( NULL )
  648. , m_psecPrev( NULL )
  649. , m_hpage( 0 )
  650. , m_hkey( 0 )
  651. , m_psecinfo( NULL )
  652. , m_pOwner( NULL )
  653. , m_pGroup( NULL )
  654. , m_fOwnerDef( FALSE )
  655. , m_fGroupDef( FALSE )
  656. {
  657. AFX_MANAGE_STATE( ::AfxGetStaticModuleState() );
  658. m_bSecDescModified = FALSE;
  659. } //*** CClusterSecurityPage::CClusterSecurityPage()
  660. /////////////////////////////////////////////////////////////////////////////
  661. //++
  662. //
  663. // CClusterSecurityPage::~CClusterSecurityPage
  664. //
  665. // Routine Description:
  666. // Destructor
  667. //
  668. // Arguments:
  669. // none
  670. //
  671. // Return Value:
  672. // none
  673. //
  674. //--
  675. /////////////////////////////////////////////////////////////////////////////
  676. CClusterSecurityPage::~CClusterSecurityPage( void )
  677. {
  678. AFX_MANAGE_STATE( ::AfxGetStaticModuleState() );
  679. ::LocalFree( m_psec );
  680. m_psec = NULL;
  681. ::LocalFree( m_psecPrev );
  682. m_psecPrev = NULL;
  683. ::LocalFree( m_pOwner );
  684. m_pOwner = NULL;
  685. ::LocalFree( m_pGroup );
  686. m_pGroup = NULL;
  687. m_psecinfo->Release();
  688. } //*** CClusterSecurityPage::~CClusterSecurityPage()
  689. /////////////////////////////////////////////////////////////////////////////
  690. //++
  691. //
  692. // CClusterSecurityPage::HrInit
  693. //
  694. // Routine Description:
  695. // Initialize method.
  696. //
  697. // Arguments:
  698. // peo [IN] back pointer to parent extension object.
  699. //
  700. // Return Value:
  701. // S_OK Page was initialized successfully.
  702. // hr Error initializing the page.
  703. //
  704. //--
  705. /////////////////////////////////////////////////////////////////////////////
  706. HRESULT CClusterSecurityPage::HrInit( IN CExtObject * peo )
  707. {
  708. ASSERT( peo != NULL );
  709. AFX_MANAGE_STATE( ::AfxGetStaticModuleState() );
  710. HRESULT _hr = S_OK;
  711. DWORD _sc;
  712. if ( peo != NULL )
  713. {
  714. m_peo = peo;
  715. _hr = CComObject< CClusterSecurityInformation >::CreateInstance( &m_psecinfo );
  716. if ( SUCCEEDED( _hr ) )
  717. {
  718. m_psecinfo->AddRef();
  719. m_hkey = GetClusterKey( Hcluster(), KEY_ALL_ACCESS );
  720. if ( m_hkey != NULL )
  721. {
  722. _hr = HrGetSecurityDescriptor();
  723. if ( SUCCEEDED( _hr ) )
  724. {
  725. CString strServer;
  726. CString strNode;
  727. strServer.Format( _T( "\\\\%s" ), StrClusterName() );
  728. // Get the node on which the Cluster Name resource is online.
  729. if ( BGetClusterNetworkNameNode( strNode ) )
  730. {
  731. _hr = m_psecinfo->HrInit( this, strServer, strNode );
  732. if ( SUCCEEDED( _hr ) )
  733. {
  734. m_hpage = CreateClusterSecurityPage( m_psecinfo );
  735. if ( m_hpage == NULL )
  736. {
  737. _sc = ::GetLastError();
  738. _hr = HRESULT_FROM_WIN32( _sc );
  739. } // if: error creating the page
  740. } // if: initialized security info successfully
  741. } // if: retrieved cluster network name node successfully
  742. else
  743. {
  744. } // else: error getting cluster network name node
  745. } // if: error getting SD
  746. } // if: retrieved cluster key
  747. else
  748. {
  749. _sc = ::GetLastError();
  750. _hr = HRESULT_FROM_WIN32( _sc );
  751. TRACE( _T( "CClusterSecurityPage::ScInit() - Failed to get the cluster key, 0x%08lx.\n" ), _sc );
  752. } // else: error getting cluster key
  753. } // if: created security info object successfully
  754. else
  755. {
  756. TRACE( _T( "CClusterSecurityPage::ScInit() - Failed to create CClusterSecurityInformation object, %0x%08lx.\n" ), _hr );
  757. }
  758. } // if: extension object is available
  759. return _hr;
  760. } //*** CClusterSecurityPage::HrInit()
  761. /////////////////////////////////////////////////////////////////////////////
  762. //++
  763. //
  764. // CClusterSecurityPage::HrGetSecurityDescriptor
  765. //
  766. // Routine Description:
  767. // Get the security descriptor from the cluster database or create a
  768. // default one if it doesn't exist.
  769. //
  770. // Arguments:
  771. // none
  772. //
  773. // Return Value:
  774. //
  775. //
  776. //--
  777. /////////////////////////////////////////////////////////////////////////////
  778. HRESULT CClusterSecurityPage::HrGetSecurityDescriptor( void )
  779. {
  780. AFX_MANAGE_STATE( ::AfxGetStaticModuleState() );
  781. HRESULT hr = S_OK;
  782. PSECURITY_DESCRIPTOR psec = NULL;
  783. hr = HrGetSDFromClusterDB( &psec ); //uses localalloc
  784. if ( FAILED( hr ) || ( psec == NULL ) || ( IsValidSecurityDescriptor( psec ) == FALSE ) )
  785. {
  786. DWORD sc;
  787. DWORD dwLen = 0;
  788. //
  789. // If the SD was not found or was not a valid SD then build a default
  790. // SD and save it into the cluster DB...
  791. //
  792. TRACE( _T( "Security Descriptor is NULL. Build default SD" ) );
  793. sc = ::ClRtlBuildDefaultClusterSD( NULL, &psec, &dwLen ); //uses localalloc
  794. hr = HRESULT_FROM_WIN32( sc );
  795. if ( FAILED( hr ) )
  796. {
  797. TRACE( _T( "ClRtlBuildDefaultClusterSD failed, 0x%08x" ), hr );
  798. } // if: error building the default SD
  799. else
  800. {
  801. SetPermissions( psec );
  802. } // else:
  803. } // if: error getting SD from cluster database
  804. if ( SUCCEEDED( hr ) )
  805. {
  806. delete m_psec;
  807. m_psec = ClRtlCopySecurityDescriptor( psec );
  808. hr = GetLastError(); // Get the last error
  809. ::LocalFree( psec );
  810. psec = NULL;
  811. if ( m_psec == NULL )
  812. {
  813. hr = HRESULT_FROM_WIN32( hr ); // Convert to HRESULT
  814. goto Cleanup;
  815. } // if: error copying the security descriptor
  816. hr = HrGetSDOwner( m_psec );
  817. if ( SUCCEEDED( hr ) )
  818. {
  819. hr = HrGetSDGroup( m_psec );
  820. if ( SUCCEEDED( hr ) )
  821. {
  822. m_psecPrev = ClRtlCopySecurityDescriptor( m_psec );
  823. if ( m_psecPrev == NULL )
  824. {
  825. hr = GetLastError(); // Get the last error
  826. hr = HRESULT_FROM_WIN32( hr ); // Convert to HRESULT
  827. goto Cleanup;
  828. } // if: error copying the security descriptor
  829. } // if: got SD group successfully
  830. } // if: got SD owner successfully
  831. } // if: retrieved or built SD successfully
  832. #ifdef _DEBUG
  833. if ( m_psec != NULL )
  834. {
  835. ASSERT( IsValidSecurityDescriptor( m_psec ) );
  836. }
  837. #endif
  838. Cleanup:
  839. return hr;
  840. } //*** CClusterSecurityPage::HrGetSecurityDescriptor()
  841. /////////////////////////////////////////////////////////////////////////////
  842. //++
  843. //
  844. // CClusterSecurityPage::HrSetSecurityDescriptor
  845. //
  846. // Routine Description:
  847. // Save the new security descriptor to the cluster database.
  848. //
  849. // Arguments:
  850. // psec [IN] the new security descriptor
  851. //
  852. // Return Value:
  853. // hr
  854. //
  855. //--
  856. /////////////////////////////////////////////////////////////////////////////
  857. HRESULT CClusterSecurityPage::HrSetSecurityDescriptor(
  858. IN PSECURITY_DESCRIPTOR psec
  859. )
  860. {
  861. ASSERT( psec != NULL );
  862. AFX_MANAGE_STATE( ::AfxGetStaticModuleState() );
  863. HRESULT hr = S_OK;
  864. try
  865. {
  866. if ( psec != NULL )
  867. {
  868. CWaitCursor wc;
  869. ASSERT( IsValidSecurityDescriptor( psec ) );
  870. if ( IsValidSecurityDescriptor( psec ) )
  871. {
  872. hr = HrSetSDOwner( psec );
  873. if ( SUCCEEDED( hr ) )
  874. {
  875. hr = HrSetSDGroup( psec );
  876. if ( SUCCEEDED( hr ) )
  877. {
  878. LocalFree( m_psecPrev );
  879. m_psecPrev = NULL;
  880. if ( m_psec == NULL )
  881. {
  882. m_psecPrev = NULL;
  883. } // if: no previous value
  884. else
  885. {
  886. m_psecPrev = ClRtlCopySecurityDescriptor( m_psec );
  887. if ( m_psecPrev == NULL )
  888. {
  889. hr = GetLastError(); // Get the last error
  890. TRACE( _T( "CClusterSecurityPage::HrSetSecurityDescriptor() - Error %08.8x copying the previous SD.\n" ), hr );
  891. hr = HRESULT_FROM_WIN32( hr ); // Convert to HRESULT
  892. goto Cleanup;
  893. } // if: error copying the security descriptor
  894. } // else: previous value exists
  895. LocalFree( m_psec );
  896. m_psec = NULL;
  897. m_psec = ClRtlCopySecurityDescriptor( psec );
  898. if ( m_psec == NULL )
  899. {
  900. hr = GetLastError(); // Get the last error
  901. TRACE( _T( "CClusterSecurityPage::HrSetSecurityDescriptor() - Error %08.8x copying the new SD.\n" ), hr );
  902. hr = HRESULT_FROM_WIN32( hr ); // Convert to HRESULT
  903. goto Cleanup;
  904. } // if: error copying the security descriptor
  905. SetPermissions( m_psec );
  906. } // if: SD group set successfully
  907. } // if: SD owner set successfully
  908. } // if: security descriptor is valid
  909. else
  910. {
  911. hr = HRESULT_FROM_WIN32( ERROR_INVALID_SECURITY_DESCR );
  912. TRACE( _T( "CClusterSecurityPage::HrSetSecurityDescriptor() - Invalid security descriptor.\n" ) );
  913. } // else: invalid security descriptor
  914. } // if: security descriptor specified
  915. else
  916. {
  917. hr = HRESULT_FROM_WIN32( ERROR_INVALID_SECURITY_DESCR );
  918. } // else: no security descriptor specified
  919. } // try
  920. catch ( ... )
  921. {
  922. hr = E_FAIL;
  923. TRACE( _T( "CClusterSecurityPage::HrSetSecurityDescriptor() - Unknown error occurred.\n" ) );
  924. }
  925. Cleanup:
  926. return hr;
  927. } //*** CClusterSecurityPage::HrSetSecurityDescriptor()
  928. /////////////////////////////////////////////////////////////////////////////
  929. //++
  930. //
  931. // CClusterSecurityPage::SetPermissions
  932. //
  933. // Routine Description:
  934. // Set the permissions for accessing the cluster.
  935. //
  936. // Arguments:
  937. // psec [IN] Security descriptor.
  938. //
  939. // Return Value:
  940. // None.
  941. //
  942. // Exceptions Thrown:
  943. // Any exceptions thrown by CClusterItem::WriteValue().
  944. //--
  945. /////////////////////////////////////////////////////////////////////////////
  946. void CClusterSecurityPage::SetPermissions(
  947. IN const PSECURITY_DESCRIPTOR psec
  948. )
  949. {
  950. ASSERT( psec != NULL );
  951. ASSERT( IsValidSecurityDescriptor( psec ) );
  952. DWORD cbNew;
  953. DWORD cbOld;
  954. LPBYTE psecPrev; // buffer for use by ScWriteValue. Prev SD is saved elsewhere now.
  955. // Get the length of the two security descriptors.
  956. if ( m_psecPrev == NULL )
  957. {
  958. cbOld = 0;
  959. }
  960. else
  961. {
  962. cbOld = ::GetSecurityDescriptorLength( m_psecPrev );
  963. }
  964. if ( psec == NULL )
  965. {
  966. cbNew = 0;
  967. }
  968. else
  969. {
  970. cbNew = ::GetSecurityDescriptorLength( psec );
  971. }
  972. // Allocate a new buffer for the previous data pointer.
  973. try
  974. {
  975. psecPrev = new BYTE [cbOld];
  976. if ( psecPrev == NULL )
  977. {
  978. return;
  979. } // if: error allocating previous data buffer
  980. }
  981. catch ( CMemoryException * )
  982. {
  983. return;
  984. } // catch: CMemoryException
  985. ::CopyMemory( psecPrev, m_psecPrev, cbOld );
  986. ScWriteValue( CLUSREG_NAME_CLUS_SD, (LPBYTE) psec, cbNew, (LPBYTE *) &psecPrev, cbOld, m_hkey );
  987. //
  988. // Convert the NT5 SD to one that is compatible with the ACLEdit stuff on
  989. // NT4. If that conversion fails then don't write it to the cluster DB.
  990. //
  991. PSECURITY_DESCRIPTOR psd = NULL;
  992. psd = ClRtlConvertClusterSDToNT4Format( psec );
  993. if ( psd != NULL )
  994. {
  995. ScWriteValue( CLUSREG_NAME_CLUS_SECURITY, (LPBYTE) psd, cbNew, (LPBYTE *) &psecPrev, cbOld, m_hkey );
  996. ::LocalFree( psd );
  997. } // if:
  998. delete [] psecPrev;
  999. } //*** CClusterSecurityPage::SetPermissions()
  1000. /////////////////////////////////////////////////////////////////////////////
  1001. //++
  1002. //
  1003. // CClusterSecurityPage::HrGetSDOwner
  1004. //
  1005. // Routine Description:
  1006. // Get the owner sid and save it.
  1007. //
  1008. // Arguments:
  1009. // psec [IN] Security descriptor.
  1010. //
  1011. // Return Value:
  1012. // hr
  1013. //
  1014. //--
  1015. /////////////////////////////////////////////////////////////////////////////
  1016. HRESULT CClusterSecurityPage::HrGetSDOwner(
  1017. IN const PSECURITY_DESCRIPTOR psec
  1018. )
  1019. {
  1020. HRESULT hr = S_OK;
  1021. DWORD sc;
  1022. PSID pOwner = NULL;
  1023. if ( ::GetSecurityDescriptorOwner( psec, &pOwner, &m_fOwnerDef ) != 0 )
  1024. {
  1025. // The security descriptor does not have an owner.
  1026. if ( pOwner == NULL )
  1027. {
  1028. ::LocalFree( m_pOwner );
  1029. m_pOwner = NULL;
  1030. }
  1031. else
  1032. {
  1033. DWORD dwLen = ::GetLengthSid( pOwner );
  1034. // copy the sid since AclUi will free the SD...
  1035. hr = ::GetLastError();
  1036. if ( SUCCEEDED( hr ) )
  1037. {
  1038. ::LocalFree( m_pOwner );
  1039. m_pOwner = ::LocalAlloc( LMEM_ZEROINIT, dwLen );
  1040. if ( m_pOwner != NULL )
  1041. {
  1042. if ( ::CopySid( dwLen, m_pOwner, pOwner ) )
  1043. {
  1044. hr = S_OK;
  1045. }
  1046. else
  1047. {
  1048. sc = ::GetLastError();
  1049. hr = HRESULT_FROM_WIN32( sc );
  1050. }
  1051. }
  1052. else
  1053. {
  1054. sc = ::GetLastError();
  1055. hr = HRESULT_FROM_WIN32( sc );
  1056. }
  1057. }
  1058. }
  1059. }
  1060. else
  1061. {
  1062. sc = ::GetLastError();
  1063. hr = HRESULT_FROM_WIN32( sc );
  1064. }
  1065. return( hr );
  1066. } //*** CClusterSecurityPage::HrGetSDOwner()
  1067. /////////////////////////////////////////////////////////////////////////////
  1068. //++
  1069. //
  1070. // CClusterSecurityPage::HrGetSDGroup
  1071. //
  1072. // Routine Description:
  1073. // Get the group sid and save it.
  1074. //
  1075. // Arguments:
  1076. // psec [IN] Security descriptor.
  1077. //
  1078. // Return Value:
  1079. // None.
  1080. //
  1081. //--
  1082. /////////////////////////////////////////////////////////////////////////////
  1083. HRESULT CClusterSecurityPage::HrGetSDGroup(
  1084. IN const PSECURITY_DESCRIPTOR psec
  1085. )
  1086. {
  1087. HRESULT hr = S_OK;
  1088. DWORD sc;
  1089. PSID pGroup = NULL;
  1090. if ( ::GetSecurityDescriptorOwner( psec, &pGroup, &m_fOwnerDef ) != 0 )
  1091. {
  1092. // This SID does not contain group information.
  1093. if ( pGroup == NULL )
  1094. {
  1095. ::LocalFree( m_pGroup );
  1096. m_pGroup = NULL;
  1097. }
  1098. else
  1099. {
  1100. DWORD dwLen = ::GetLengthSid( pGroup );
  1101. // copy the sid since AclUi will free the SD...
  1102. hr = ::GetLastError();
  1103. if ( SUCCEEDED( hr ) )
  1104. {
  1105. ::LocalFree( m_pGroup );
  1106. m_pGroup = ::LocalAlloc( LMEM_ZEROINIT, dwLen );
  1107. if ( m_pGroup != NULL )
  1108. {
  1109. if ( ::CopySid( dwLen, m_pGroup, pGroup ) )
  1110. {
  1111. hr = S_OK;
  1112. }
  1113. else
  1114. {
  1115. sc = ::GetLastError();
  1116. hr = HRESULT_FROM_WIN32( sc );
  1117. }
  1118. }
  1119. else
  1120. {
  1121. sc = ::GetLastError();
  1122. hr = HRESULT_FROM_WIN32( sc );
  1123. }
  1124. }
  1125. }
  1126. }
  1127. else
  1128. {
  1129. sc = ::GetLastError();
  1130. hr = HRESULT_FROM_WIN32( sc );
  1131. }
  1132. return( hr );
  1133. } //*** CClusterSecurityPage::HrGetSDGroup()
  1134. /////////////////////////////////////////////////////////////////////////////
  1135. //++
  1136. //
  1137. // CClusterSecurityPage::HrSetSDOwner
  1138. //
  1139. // Routine Description:
  1140. // Set the owner sid.
  1141. //
  1142. // Arguments:
  1143. // psec [IN] Security descriptor.
  1144. //
  1145. // Return Value:
  1146. // None.
  1147. //
  1148. //--
  1149. /////////////////////////////////////////////////////////////////////////////
  1150. HRESULT CClusterSecurityPage::HrSetSDOwner(
  1151. IN PSECURITY_DESCRIPTOR psec
  1152. )
  1153. {
  1154. HRESULT hr = S_OK;
  1155. if ( !::SetSecurityDescriptorOwner( psec, m_pOwner, m_fOwnerDef ) )
  1156. {
  1157. DWORD sc = ::GetLastError();
  1158. hr = HRESULT_FROM_WIN32( sc );
  1159. }
  1160. return( hr );
  1161. } //*** CClusterSecurityPage::HrSetSDOwner()
  1162. /////////////////////////////////////////////////////////////////////////////
  1163. //++
  1164. //
  1165. // CClusterSecurityPage::HrSetSDGroup
  1166. //
  1167. // Routine Description:
  1168. // Set the group sid.
  1169. //
  1170. // Arguments:
  1171. // psec [IN] Security descriptor.
  1172. //
  1173. // Return Value:
  1174. // None.
  1175. //
  1176. //--
  1177. /////////////////////////////////////////////////////////////////////////////
  1178. HRESULT CClusterSecurityPage::HrSetSDGroup(
  1179. IN PSECURITY_DESCRIPTOR psec
  1180. )
  1181. {
  1182. HRESULT hr = S_OK;
  1183. if ( !::SetSecurityDescriptorGroup( psec, m_pGroup, m_fGroupDef ) )
  1184. {
  1185. DWORD sc = ::GetLastError();
  1186. hr = HRESULT_FROM_WIN32( sc );
  1187. }
  1188. return( hr );
  1189. } //*** CClusterSecurityPage::HrSetSDGroup()
  1190. /////////////////////////////////////////////////////////////////////////////
  1191. //++
  1192. //
  1193. // CClusterSecurityPage::HrGetSDFromClusterDB
  1194. //
  1195. // Routine Description:
  1196. // Retrieve the SD from the cluster database.
  1197. //
  1198. // Arguments:
  1199. // ppsec [OUT] Pointer to security descriptor.
  1200. //
  1201. // Return Value:
  1202. // S_OK for success
  1203. // Any error returned by ScReadValue
  1204. //
  1205. //--
  1206. /////////////////////////////////////////////////////////////////////////////
  1207. HRESULT CClusterSecurityPage::HrGetSDFromClusterDB(
  1208. OUT PSECURITY_DESCRIPTOR * ppsec
  1209. )
  1210. {
  1211. AFX_MANAGE_STATE( ::AfxGetStaticModuleState() );
  1212. ASSERT( ppsec != NULL );
  1213. HRESULT hr = E_FAIL;
  1214. PSECURITY_DESCRIPTOR psd = NULL;
  1215. if ( ppsec != NULL )
  1216. {
  1217. DWORD sc;
  1218. // Read the security descriptor.
  1219. sc = ScReadValue( CLUSREG_NAME_CLUS_SD, (LPBYTE *) &psd, m_hkey ); //alloc using new
  1220. hr = HRESULT_FROM_WIN32( sc );
  1221. if ( FAILED( hr ) || ( psd == NULL ) )
  1222. { // try getting the NT4 SD...
  1223. sc = ScReadValue( CLUSREG_NAME_CLUS_SECURITY, (LPBYTE *) &psd, m_hkey ); //alloc using new
  1224. hr = HRESULT_FROM_WIN32( sc );
  1225. if ( SUCCEEDED( hr ) )
  1226. {
  1227. *ppsec = ::ClRtlConvertClusterSDToNT5Format( psd );
  1228. }
  1229. }
  1230. else
  1231. {
  1232. *ppsec = ClRtlCopySecurityDescriptor( psd );
  1233. if ( *ppsec == NULL )
  1234. {
  1235. hr = GetLastError(); // Get the last error
  1236. hr = HRESULT_FROM_WIN32( hr ); // Convert to HRESULT
  1237. } // if: error copying the security descriptor
  1238. }
  1239. delete [] psd;
  1240. if ( *ppsec != NULL )
  1241. {
  1242. ::ClRtlExamineSD( *ppsec, "[ClusPage]" );
  1243. } // if: security descriptor is available to be examined
  1244. }
  1245. return hr;
  1246. } //*** CClusterSecurityPage::HrGetSDFromClusterDB