|
|
/////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 1998-2000 Microsoft Corporation
//
// Module Name:
// ClusPage.cpp
//
// Abstract:
// CClusterSecurityPage class implementation. This class will encapsulate
// the cluster security extension page.
//
// Author:
// Galen Barbee (galenb) February 11, 1998
//
// Revision History:
//
// Notes:
//
/////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "resource.h"
#include "ClusPage.h"
#include "AclUtils.h"
#include <clusudef.h>
static GENERIC_MAPPING ShareMap = { CLUSAPI_READ_ACCESS, CLUSAPI_CHANGE_ACCESS, CLUSAPI_NO_ACCESS, CLUSAPI_ALL_ACCESS };
static SI_ACCESS siClusterAccesses[] = { { &GUID_NULL, CLUSAPI_ALL_ACCESS, MAKEINTRESOURCE(IDS_ACLEDIT_PERM_GEN_ALL), SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC /*| OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE*/ } };
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusterSecurityInformation::CClusterSecurityInformation
//
// Routine Description:
// Default contructor
//
// Arguments:
// none
//
// Return Value:
// none
//
//--
/////////////////////////////////////////////////////////////////////////////
CClusterSecurityInformation::CClusterSecurityInformation( void ) : m_pcsp( NULL ) { m_pShareMap = &ShareMap; m_psiAccess = (SI_ACCESS *) &siClusterAccesses; m_nAccessElems = ARRAYSIZE( siClusterAccesses ); m_nDefAccess = 0; m_dwFlags = SI_EDIT_PERMS | SI_NO_ACL_PROTECT //| SI_UGOP_PROVIDED
//| SI_NO_UGOP_ACCOUNT_GROUPS
//| SI_NO_UGOP_USERS
//| SI_NO_UGOP_LOCAL_GROUPS
//| SI_NO_UGOP_WELLKNOWN
//| SI_NO_UGOP_BUILTIN
;
} //*** CClusterSecurityInformation::CClusterSecurityInformation()
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusterSecurityInformation::GetSecurity
//
// Routine Description:
// Give our security descriptor to the ISecurityInfomation UI
// so it can be displayed and edited.
//
// Arguments:
// RequestedInformation [IN]
// ppSecurityDescriptor [IN OUT]
// fDefault [IN]
//
// Return Value:
// E_FAIL for error and S_OK for success.
//
//--
/////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CClusterSecurityInformation::GetSecurity( IN SECURITY_INFORMATION RequestedInformation, IN OUT PSECURITY_DESCRIPTOR *ppSecurityDescriptor, IN BOOL fDefault ) { AFX_MANAGE_STATE( ::AfxGetStaticModuleState() );
HRESULT hr = E_FAIL;
try { if ( ppSecurityDescriptor != NULL ) { PSECURITY_DESCRIPTOR pSD = NULL;
pSD = ClRtlCopySecurityDescriptor( Pcsp()->Psec() ); if ( pSD != NULL ) { //hr = HrFixupSD( pSD );
//if ( SUCCEEDED( hr ) )
//{
*ppSecurityDescriptor = pSD; //}
hr = S_OK; } // if: no errors copying the security descriptor
else { hr = GetLastError(); TRACE( _T("CClusterSecurityInformation::GetSecurity() - Error %08.8x copying the security descriptor.\n"), hr ); hr = HRESULT_FROM_WIN32( hr ); } // else: error copying the security descriptor
} else { hr = S_OK; } // else: no security descriptor pointer
} catch ( ... ) { TRACE( _T("CClusterSecurityInformation::GetSecurity() - Unknown error occurred.\n") ); }
return hr;
} //*** CClusterSecurityInformation::GetSecurity()
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusterSecurityInformation::SetSecurity
//
// Routine Description:
// ISecurityInformation is giving back the edited security descriptor.
//
// Arguments:
// SecurityInformation [IN]
// pSecurityDescriptor [IN OUT]
//
// Return Value:
// E_FAIL for error and S_OK for success.
//
//--
/////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CClusterSecurityInformation::SetSecurity( IN SECURITY_INFORMATION SecurityInformation, IN PSECURITY_DESCRIPTOR pSecurityDescriptor ) { AFX_MANAGE_STATE( ::AfxGetStaticModuleState() );
HRESULT hr = E_FAIL; PSID pSystemSid = NULL; PSID pAdminSid = NULL; PSID pNetServiceSid = NULL;
try { SID_IDENTIFIER_AUTHORITY siaNtAuthority = SECURITY_NT_AUTHORITY;
hr = CSecurityInformation::SetSecurity( SecurityInformation, pSecurityDescriptor ); if ( hr == S_OK ) { if ( AllocateAndInitializeSid( &siaNtAuthority, 1, SECURITY_LOCAL_SYSTEM_RID, 0, 0, 0, 0, 0, 0, 0, &pSystemSid ) ) { CString strMsg;
if ( BSidInSD( pSecurityDescriptor, pSystemSid ) ) { //
// allocate and init the Administrators group sid
//
if ( AllocateAndInitializeSid( &siaNtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &pAdminSid ) ) { if ( BSidInSD( pSecurityDescriptor, pAdminSid ) ) { //
// allocate and init the Network Service sid
//
if ( AllocateAndInitializeSid( &siaNtAuthority, 1, SECURITY_NETWORK_SERVICE_RID, 0, 0, 0, 0, 0, 0, 0, &pNetServiceSid ) ) { if ( BSidInSD( pSecurityDescriptor, pNetServiceSid ) ) { hr = Pcsp()->HrSetSecurityDescriptor( pSecurityDescriptor ); } // if: service SID in the SD
else { strMsg.LoadString( IDS_NETSERVICE_ACCOUNT_NOT_SPECIFIED ); AfxMessageBox( strMsg, MB_OK | MB_ICONSTOP );
hr = S_FALSE; // if there are missing required accounts then return S_FALSE to keep AclUi alive.
} // else
} // if: allocate and init service SID
} // if: admin SID in the SD
else { strMsg.LoadString( IDS_ADMIN_ACCOUNT_NOT_SPECIFIED ); AfxMessageBox( strMsg, MB_OK | MB_ICONSTOP );
hr = S_FALSE; // if there are missing required accounts then return S_FALSE to keep AclUi alive.
} // else
} // if: allocate and init admin SID
} // if: system SID in the SD
else { strMsg.LoadString( IDS_SYS_ACCOUNT_NOT_SPECIFIED ); AfxMessageBox( strMsg, MB_OK | MB_ICONSTOP );
hr = S_FALSE; // if there are missing required accounts then return S_FALSE to keep AclUi alive.
} // else
} // if: allocate and init system SID
} // if: CSecurityInformation::SetSecurity() worked
} catch( ... ) { ; }
if ( pSystemSid != NULL ) { FreeSid( pSystemSid ); }
if ( pAdminSid != NULL ) { FreeSid( pAdminSid ); }
if ( pNetServiceSid != NULL ) { FreeSid( pNetServiceSid ); }
return hr;
} //*** CClusterSecurityInformation::SetSecurity()
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusterSecurityInformation::HrInit
//
// Routine Description:
// Initialize method.
//
// Arguments:
// pcsp [IN] back pointer to parent property page wrapper
// strServer [IN] cluster name
//
// Return Value:
// S_OK for success. E_FAIL for failure.
//
//--
/////////////////////////////////////////////////////////////////////////////
HRESULT CClusterSecurityInformation::HrInit( IN CClusterSecurityPage * pcsp, IN CString const & strServer, IN CString const & strNode ) { ASSERT( pcsp != NULL ); ASSERT( strServer.GetLength() > 0 ); AFX_MANAGE_STATE( ::AfxGetStaticModuleState() );
m_pcsp = pcsp; m_strServer = strServer; m_strNode = strNode; m_nLocalSIDErrorMessageID = IDS_LOCAL_ACCOUNTS_SPECIFIED_CLUS;
return S_OK;
} //*** CClusterSecurityInformation::HrInit()
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusterSecurityInformation::BSidInSD
//
// Routine Description:
// Determines if there is an ACEs for the passed in SID in the
// Security Descriptor (pSD) after the ACL editor has been called
//
// Arguments:
// pSD [IN] - Security Descriptor to be checked.
// pSid [IN] - SID to look for
//
// Return Value:
// TRUE if an ACE for the SID was found, False otherwise.
//
/////////////////////////////////////////////////////////////////////////////
BOOL CClusterSecurityInformation::BSidInSD( IN PSECURITY_DESCRIPTOR pSD, IN PSID pSid ) { BOOL bSIdInACL = FALSE;
try { PACL pDACL = NULL; BOOL bHasDACL = FALSE; BOOL bDaclDefaulted = FALSE;
if ( ::GetSecurityDescriptorDacl( pSD, &bHasDACL, &pDACL, &bDaclDefaulted ) ) { if ( bHasDACL && ( pDACL != NULL ) && ::IsValidAcl( pDACL ) ) { ACL_SIZE_INFORMATION asiAclSize; ACCESS_ALLOWED_ACE * paaAllowedAce;
if ( ::GetAclInformation( pDACL, (LPVOID) &asiAclSize, sizeof( asiAclSize ), AclSizeInformation ) ) { //
// Search the ACL for the SID
//
for ( DWORD dwCount = 0; dwCount < asiAclSize.AceCount; dwCount++ ) { if ( ::GetAce( pDACL, dwCount, (LPVOID *) &paaAllowedAce ) ) { if ( paaAllowedAce->Header.AceType == ACCESS_ALLOWED_ACE_TYPE ) { if ( EqualSid( &paaAllowedAce->SidStart, pSid ) ) { bSIdInACL = TRUE; break; } // if: EqualSid
} // if: is this an access allowed ace?
} // if: can we get the ace from the DACL?
} // for
} // if: get ACL information
} // if: is the ACL valid
} // if: get the ACL from the SD
} catch ( ... ) { TRACE( _T("CClusterSecurityInformation::BSidInSD() - Unknown error occurred.\n") ); }
return bSIdInACL;
} //*** CClusterSecurityInformation::BSidInSD()
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusterSecurityInformation::HrFixupSD
//
// Routine Description:
// Performs any fixups to the SD that may be requrired.
//
// Arguments:
// pSD [IN] - Security Descriptor to be checked.
//
// Return Value:
// S_OK, or other Win32 error
//
/////////////////////////////////////////////////////////////////////////////
HRESULT CClusterSecurityInformation::HrFixupSD( IN PSECURITY_DESCRIPTOR pSD ) { HRESULT hr = S_OK; PSID pSystemSid = NULL; PSID pAdminSid = NULL; PSID pNetServiceSid = NULL;
try { SID_IDENTIFIER_AUTHORITY siaNtAuthority = SECURITY_NT_AUTHORITY;
if ( AllocateAndInitializeSid( &siaNtAuthority, 1, SECURITY_LOCAL_SYSTEM_RID, 0, 0, 0, 0, 0, 0, 0, &pSystemSid ) ) { if ( ! BSidInSD( pSD, pSystemSid ) ) { HrAddSidToSD( &pSD, pSystemSid ); } // if: system SID found in SD
} // if: allocate system SID
//
// allocate and init the Administrators group sid
//
if ( AllocateAndInitializeSid( &siaNtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &pAdminSid ) ) { if ( ! BSidInSD( pSD, pAdminSid ) ) { HrAddSidToSD( &pSD, pAdminSid ); } // if: admin SID found in SD
} // if: allocate admin SID
//
// allocate and init the Network Service sid
//
if ( AllocateAndInitializeSid( &siaNtAuthority, 1, SECURITY_NETWORK_SERVICE_RID, 0, 0, 0, 0, 0, 0, 0, &pNetServiceSid ) ) { if ( ! BSidInSD( pSD, pNetServiceSid ) ) { HrAddSidToSD( &pSD, pNetServiceSid ); } // if: Network Service SID found in SD
} // if: allocate Network Service SID
} catch ( ... ) { TRACE( _T("CClusterSecurityInformation::HrFixupSD() - Unknown error occurred.\n") ); }
if ( pSystemSid != NULL ) { FreeSid( pSystemSid ); }
if ( pAdminSid != NULL ) { FreeSid( pAdminSid ); }
if ( pNetServiceSid != NULL ) { FreeSid( pNetServiceSid ); }
return hr;
} //*** CClusterSecurityInformation::HrFixupSD()
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusterSecurityInformation::HrAddSidToSD
//
// Routine Description:
// Adds the passed in SID to the DACL of the passed in SD
//
// Arguments:
// ppSD [IN, OUT] - Security Descriptor to be added to
// PSid [IN] - SID to add
//
// Return Value:
// S_OK, or other Win32 error
//
/////////////////////////////////////////////////////////////////////////////
HRESULT CClusterSecurityInformation::HrAddSidToSD( IN OUT PSECURITY_DESCRIPTOR * ppSD, IN PSID pSid ) { HRESULT hr = S_OK; DWORD sc; SECURITY_DESCRIPTOR sd; DWORD dwSDLen = sizeof( SECURITY_DESCRIPTOR ); PACL pDacl = NULL; DWORD dwDaclLen = 0; PACL pSacl = NULL; DWORD dwSaclLen = 0; PSID pOwnerSid = NULL; DWORD dwOwnerSidLen = 0; PSID pGroupSid = NULL; DWORD dwGroupSidLen = NULL; PSECURITY_DESCRIPTOR pNewSD = NULL; DWORD dwNewSDLen = 0;
try { BOOL bRet = FALSE;
bRet = ::MakeAbsoluteSD( *ppSD, // address of self relative SD
&sd, // address of absolute SD
&dwSDLen, // address of size of absolute SD
NULL, // address of discretionary ACL
&dwDaclLen, // address of size of discretionary ACL
NULL, // address of system ACL
&dwSaclLen, // address of size of system ACL
NULL, // address of owner SID
&dwOwnerSidLen, // address of size of owner SID
NULL, // address of primary-group SID
&dwGroupSidLen // address of size of group SID
); if ( ! bRet ) { sc = ::GetLastError(); hr = HRESULT_FROM_WIN32( sc ); if ( hr != ERROR_INSUFFICIENT_BUFFER ) // Duh, we're trying to find out how big the buffer should be?
{ goto fnExit; } }
//
// increase the DACL length to hold one more ace and its sid.
//
dwDaclLen += ( sizeof( ACCESS_ALLOWED_ACE ) + GetLengthSid( pSid ) +1024 ); pDacl = (PACL) ::LocalAlloc( LMEM_ZEROINIT, dwDaclLen ); if ( pDacl == NULL ) { hr = E_OUTOFMEMORY; goto fnExit; }
InitializeAcl( pDacl, dwDaclLen, ACL_REVISION );
if ( dwSaclLen > 0 ) { pSacl = (PACL) ::LocalAlloc( LMEM_ZEROINIT, dwSaclLen ); if ( pSacl == NULL ) { hr = E_OUTOFMEMORY; goto fnExit; } }
if ( dwOwnerSidLen > 0 ) { pOwnerSid = (PSID) ::LocalAlloc( LMEM_ZEROINIT, dwOwnerSidLen ); if ( pOwnerSid == NULL ) { hr = E_OUTOFMEMORY; goto fnExit; } }
if ( dwGroupSidLen > 0 ) { pGroupSid = (PSID) ::LocalAlloc( LMEM_ZEROINIT, dwGroupSidLen ); if ( pGroupSid == NULL ) { hr = E_OUTOFMEMORY; goto fnExit; } }
bRet = ::MakeAbsoluteSD( *ppSD, // address of self relative SD
&sd, // address of absolute SD
&dwSDLen, // address of size of absolute SD
pDacl, // address of discretionary ACL
&dwDaclLen, // address of size of discretionary ACL
pSacl, // address of system ACL
&dwSaclLen, // address of size of system ACL
pOwnerSid, // address of owner SID
&dwOwnerSidLen, // address of size of owner SID
pGroupSid, // address of primary-group SID
&dwGroupSidLen // address of size of group SID
); if ( !bRet ) { goto fnExit; }
//
// Add the ACE for the SID to the DACL
//
// if ( !AddAccessAllowedAceEx( pDacl,
// ACL_REVISION,
// CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE,
// CLUSAPI_ALL_ACCESS,
// pSid ) )
if ( ! AddAccessAllowedAce( pDacl, ACL_REVISION, CLUSAPI_ALL_ACCESS, pSid ) ) { sc = ::GetLastError(); hr = HRESULT_FROM_WIN32( sc ); goto fnExit; }
if ( ! ::SetSecurityDescriptorDacl( &sd, TRUE, pDacl, FALSE ) ) { sc = ::GetLastError(); hr = HRESULT_FROM_WIN32( sc ); goto fnExit; }
if ( ! ::SetSecurityDescriptorOwner( &sd, pOwnerSid, FALSE ) ) { sc = ::GetLastError(); hr = HRESULT_FROM_WIN32( sc ); goto fnExit; }
if ( ! ::SetSecurityDescriptorGroup( &sd, pGroupSid, FALSE ) ) { sc = ::GetLastError(); hr = HRESULT_FROM_WIN32( sc ); goto fnExit; }
if ( ! ::SetSecurityDescriptorSacl( &sd, TRUE, pSacl, FALSE ) ) { sc = ::GetLastError(); hr = HRESULT_FROM_WIN32( sc ); goto fnExit; }
dwNewSDLen = 0 ;
if ( ! ::MakeSelfRelativeSD( &sd, NULL, &dwNewSDLen ) ) { sc = ::GetLastError(); hr = HRESULT_FROM_WIN32( sc ); if ( hr != HRESULT_FROM_WIN32( ERROR_INSUFFICIENT_BUFFER ) ) // Duh, we're trying to find out how big the buffer should be?
{ goto fnExit; } }
pNewSD = ::LocalAlloc( LPTR, dwNewSDLen ); if ( pNewSD != NULL ) { if ( ! ::MakeSelfRelativeSD( &sd, pNewSD, &dwNewSDLen ) ) { sc = ::GetLastError(); hr = HRESULT_FROM_WIN32( sc ); goto fnExit; }
::LocalFree( *ppSD ); *ppSD = pNewSD; hr = ERROR_SUCCESS; } else { hr = ERROR_NOT_ENOUGH_MEMORY; } } catch ( ... ) { TRACE( _T("CClusterSecurityInformation::HrAddSidToSD() - Unknown error occurred.\n") ); }
fnExit:
if ( pSacl != NULL ) { ::LocalFree( pSacl ); }
if ( pOwnerSid != NULL ) { ::LocalFree( pOwnerSid ); }
if ( pGroupSid != NULL ) { ::LocalFree( pGroupSid ); }
return hr;
} //*** CClusterSecurityInformation::HrAddSidToSD()
//*************************************************************************//
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusterSecurityPage::CClusterSecurityPage
//
// Routine Description:
// Default contructor.
//
// Arguments:
// none
//
// Return Value:
// none
//
//--
/////////////////////////////////////////////////////////////////////////////
CClusterSecurityPage::CClusterSecurityPage( void ) : m_psec( NULL ) , m_psecPrev( NULL ) , m_hpage( 0 ) , m_hkey( 0 ) , m_psecinfo( NULL ) , m_pOwner( NULL ) , m_pGroup( NULL ) , m_fOwnerDef( FALSE ) , m_fGroupDef( FALSE ) { AFX_MANAGE_STATE( ::AfxGetStaticModuleState() );
m_bSecDescModified = FALSE;
} //*** CClusterSecurityPage::CClusterSecurityPage()
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusterSecurityPage::~CClusterSecurityPage
//
// Routine Description:
// Destructor
//
// Arguments:
// none
//
// Return Value:
// none
//
//--
/////////////////////////////////////////////////////////////////////////////
CClusterSecurityPage::~CClusterSecurityPage( void ) { AFX_MANAGE_STATE( ::AfxGetStaticModuleState() );
::LocalFree( m_psec ); m_psec = NULL;
::LocalFree( m_psecPrev ); m_psecPrev = NULL;
::LocalFree( m_pOwner ); m_pOwner = NULL;
::LocalFree( m_pGroup ); m_pGroup = NULL;
m_psecinfo->Release();
} //*** CClusterSecurityPage::~CClusterSecurityPage()
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusterSecurityPage::HrInit
//
// Routine Description:
// Initialize method.
//
// Arguments:
// peo [IN] back pointer to parent extension object.
//
// Return Value:
// S_OK Page was initialized successfully.
// hr Error initializing the page.
//
//--
/////////////////////////////////////////////////////////////////////////////
HRESULT CClusterSecurityPage::HrInit( IN CExtObject * peo ) { ASSERT( peo != NULL ); AFX_MANAGE_STATE( ::AfxGetStaticModuleState() );
HRESULT _hr = S_OK; DWORD _sc;
if ( peo != NULL ) { m_peo = peo;
_hr = CComObject< CClusterSecurityInformation >::CreateInstance( &m_psecinfo ); if ( SUCCEEDED( _hr ) ) { m_psecinfo->AddRef();
m_hkey = GetClusterKey( Hcluster(), KEY_ALL_ACCESS ); if ( m_hkey != NULL ) { _hr = HrGetSecurityDescriptor(); if ( SUCCEEDED( _hr ) ) { CString strServer; CString strNode;
strServer.Format( _T( "\\\\%s" ), StrClusterName() );
// Get the node on which the Cluster Name resource is online.
if ( BGetClusterNetworkNameNode( strNode ) ) { _hr = m_psecinfo->HrInit( this, strServer, strNode ); if ( SUCCEEDED( _hr ) ) { m_hpage = CreateClusterSecurityPage( m_psecinfo ); if ( m_hpage == NULL ) { _sc = ::GetLastError(); _hr = HRESULT_FROM_WIN32( _sc ); } // if: error creating the page
} // if: initialized security info successfully
} // if: retrieved cluster network name node successfully
else { } // else: error getting cluster network name node
} // if: error getting SD
} // if: retrieved cluster key
else { _sc = ::GetLastError(); _hr = HRESULT_FROM_WIN32( _sc ); TRACE( _T( "CClusterSecurityPage::ScInit() - Failed to get the cluster key, 0x%08lx.\n" ), _sc ); } // else: error getting cluster key
} // if: created security info object successfully
else { TRACE( _T( "CClusterSecurityPage::ScInit() - Failed to create CClusterSecurityInformation object, %0x%08lx.\n" ), _hr ); } } // if: extension object is available
return _hr;
} //*** CClusterSecurityPage::HrInit()
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusterSecurityPage::HrGetSecurityDescriptor
//
// Routine Description:
// Get the security descriptor from the cluster database or create a
// default one if it doesn't exist.
//
// Arguments:
// none
//
// Return Value:
//
//
//--
/////////////////////////////////////////////////////////////////////////////
HRESULT CClusterSecurityPage::HrGetSecurityDescriptor( void ) { AFX_MANAGE_STATE( ::AfxGetStaticModuleState() ); HRESULT hr = S_OK; PSECURITY_DESCRIPTOR psec = NULL;
hr = HrGetSDFromClusterDB( &psec ); //uses localalloc
if ( FAILED( hr ) || ( psec == NULL ) || ( IsValidSecurityDescriptor( psec ) == FALSE ) ) { DWORD sc; DWORD dwLen = 0; //
// If the SD was not found or was not a valid SD then build a default
// SD and save it into the cluster DB...
//
TRACE( _T( "Security Descriptor is NULL. Build default SD" ) ); sc = ::ClRtlBuildDefaultClusterSD( NULL, &psec, &dwLen ); //uses localalloc
hr = HRESULT_FROM_WIN32( sc ); if ( FAILED( hr ) ) { TRACE( _T( "ClRtlBuildDefaultClusterSD failed, 0x%08x" ), hr ); } // if: error building the default SD
else { SetPermissions( psec ); } // else:
} // if: error getting SD from cluster database
if ( SUCCEEDED( hr ) ) { delete m_psec; m_psec = ClRtlCopySecurityDescriptor( psec ); hr = GetLastError(); // Get the last error
::LocalFree( psec ); psec = NULL; if ( m_psec == NULL ) { hr = HRESULT_FROM_WIN32( hr ); // Convert to HRESULT
goto Cleanup; } // if: error copying the security descriptor
hr = HrGetSDOwner( m_psec ); if ( SUCCEEDED( hr ) ) { hr = HrGetSDGroup( m_psec ); if ( SUCCEEDED( hr ) ) { m_psecPrev = ClRtlCopySecurityDescriptor( m_psec ); if ( m_psecPrev == NULL ) { hr = GetLastError(); // Get the last error
hr = HRESULT_FROM_WIN32( hr ); // Convert to HRESULT
goto Cleanup; } // if: error copying the security descriptor
} // if: got SD group successfully
} // if: got SD owner successfully
} // if: retrieved or built SD successfully
#ifdef _DEBUG
if ( m_psec != NULL ) { ASSERT( IsValidSecurityDescriptor( m_psec ) ); } #endif
Cleanup: return hr;
} //*** CClusterSecurityPage::HrGetSecurityDescriptor()
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusterSecurityPage::HrSetSecurityDescriptor
//
// Routine Description:
// Save the new security descriptor to the cluster database.
//
// Arguments:
// psec [IN] the new security descriptor
//
// Return Value:
// hr
//
//--
/////////////////////////////////////////////////////////////////////////////
HRESULT CClusterSecurityPage::HrSetSecurityDescriptor( IN PSECURITY_DESCRIPTOR psec ) { ASSERT( psec != NULL ); AFX_MANAGE_STATE( ::AfxGetStaticModuleState() );
HRESULT hr = S_OK;
try { if ( psec != NULL ) { CWaitCursor wc;
ASSERT( IsValidSecurityDescriptor( psec ) ); if ( IsValidSecurityDescriptor( psec ) ) { hr = HrSetSDOwner( psec ); if ( SUCCEEDED( hr ) ) { hr = HrSetSDGroup( psec ); if ( SUCCEEDED( hr ) ) { LocalFree( m_psecPrev ); m_psecPrev = NULL;
if ( m_psec == NULL ) { m_psecPrev = NULL; } // if: no previous value
else { m_psecPrev = ClRtlCopySecurityDescriptor( m_psec ); if ( m_psecPrev == NULL ) { hr = GetLastError(); // Get the last error
TRACE( _T( "CClusterSecurityPage::HrSetSecurityDescriptor() - Error %08.8x copying the previous SD.\n" ), hr ); hr = HRESULT_FROM_WIN32( hr ); // Convert to HRESULT
goto Cleanup; } // if: error copying the security descriptor
} // else: previous value exists
LocalFree( m_psec ); m_psec = NULL;
m_psec = ClRtlCopySecurityDescriptor( psec ); if ( m_psec == NULL ) { hr = GetLastError(); // Get the last error
TRACE( _T( "CClusterSecurityPage::HrSetSecurityDescriptor() - Error %08.8x copying the new SD.\n" ), hr ); hr = HRESULT_FROM_WIN32( hr ); // Convert to HRESULT
goto Cleanup; } // if: error copying the security descriptor
SetPermissions( m_psec ); } // if: SD group set successfully
} // if: SD owner set successfully
} // if: security descriptor is valid
else { hr = HRESULT_FROM_WIN32( ERROR_INVALID_SECURITY_DESCR ); TRACE( _T( "CClusterSecurityPage::HrSetSecurityDescriptor() - Invalid security descriptor.\n" ) ); } // else: invalid security descriptor
} // if: security descriptor specified
else { hr = HRESULT_FROM_WIN32( ERROR_INVALID_SECURITY_DESCR ); } // else: no security descriptor specified
} // try
catch ( ... ) { hr = E_FAIL; TRACE( _T( "CClusterSecurityPage::HrSetSecurityDescriptor() - Unknown error occurred.\n" ) ); }
Cleanup: return hr;
} //*** CClusterSecurityPage::HrSetSecurityDescriptor()
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusterSecurityPage::SetPermissions
//
// Routine Description:
// Set the permissions for accessing the cluster.
//
// Arguments:
// psec [IN] Security descriptor.
//
// Return Value:
// None.
//
// Exceptions Thrown:
// Any exceptions thrown by CClusterItem::WriteValue().
//--
/////////////////////////////////////////////////////////////////////////////
void CClusterSecurityPage::SetPermissions( IN const PSECURITY_DESCRIPTOR psec ) { ASSERT( psec != NULL ); ASSERT( IsValidSecurityDescriptor( psec ) );
DWORD cbNew; DWORD cbOld; LPBYTE psecPrev; // buffer for use by ScWriteValue. Prev SD is saved elsewhere now.
// Get the length of the two security descriptors.
if ( m_psecPrev == NULL ) { cbOld = 0; } else { cbOld = ::GetSecurityDescriptorLength( m_psecPrev ); }
if ( psec == NULL ) { cbNew = 0; } else { cbNew = ::GetSecurityDescriptorLength( psec ); }
// Allocate a new buffer for the previous data pointer.
try { psecPrev = new BYTE [cbOld]; if ( psecPrev == NULL ) { return; } // if: error allocating previous data buffer
} catch ( CMemoryException * ) { return; } // catch: CMemoryException
::CopyMemory( psecPrev, m_psecPrev, cbOld );
ScWriteValue( CLUSREG_NAME_CLUS_SD, (LPBYTE) psec, cbNew, (LPBYTE *) &psecPrev, cbOld, m_hkey );
//
// Convert the NT5 SD to one that is compatible with the ACLEdit stuff on
// NT4. If that conversion fails then don't write it to the cluster DB.
//
PSECURITY_DESCRIPTOR psd = NULL;
psd = ClRtlConvertClusterSDToNT4Format( psec ); if ( psd != NULL ) { ScWriteValue( CLUSREG_NAME_CLUS_SECURITY, (LPBYTE) psd, cbNew, (LPBYTE *) &psecPrev, cbOld, m_hkey ); ::LocalFree( psd ); } // if:
delete [] psecPrev;
} //*** CClusterSecurityPage::SetPermissions()
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusterSecurityPage::HrGetSDOwner
//
// Routine Description:
// Get the owner sid and save it.
//
// Arguments:
// psec [IN] Security descriptor.
//
// Return Value:
// hr
//
//--
/////////////////////////////////////////////////////////////////////////////
HRESULT CClusterSecurityPage::HrGetSDOwner( IN const PSECURITY_DESCRIPTOR psec ) { HRESULT hr = S_OK; DWORD sc; PSID pOwner = NULL;
if ( ::GetSecurityDescriptorOwner( psec, &pOwner, &m_fOwnerDef ) != 0 ) { // The security descriptor does not have an owner.
if ( pOwner == NULL ) { ::LocalFree( m_pOwner ); m_pOwner = NULL; } else { DWORD dwLen = ::GetLengthSid( pOwner );
// copy the sid since AclUi will free the SD...
hr = ::GetLastError(); if ( SUCCEEDED( hr ) ) { ::LocalFree( m_pOwner );
m_pOwner = ::LocalAlloc( LMEM_ZEROINIT, dwLen ); if ( m_pOwner != NULL ) { if ( ::CopySid( dwLen, m_pOwner, pOwner ) ) { hr = S_OK; } else { sc = ::GetLastError(); hr = HRESULT_FROM_WIN32( sc ); } } else { sc = ::GetLastError(); hr = HRESULT_FROM_WIN32( sc ); } } } } else { sc = ::GetLastError(); hr = HRESULT_FROM_WIN32( sc ); }
return( hr );
} //*** CClusterSecurityPage::HrGetSDOwner()
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusterSecurityPage::HrGetSDGroup
//
// Routine Description:
// Get the group sid and save it.
//
// Arguments:
// psec [IN] Security descriptor.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
HRESULT CClusterSecurityPage::HrGetSDGroup( IN const PSECURITY_DESCRIPTOR psec ) { HRESULT hr = S_OK; DWORD sc; PSID pGroup = NULL;
if ( ::GetSecurityDescriptorOwner( psec, &pGroup, &m_fOwnerDef ) != 0 ) { // This SID does not contain group information.
if ( pGroup == NULL ) { ::LocalFree( m_pGroup ); m_pGroup = NULL; } else { DWORD dwLen = ::GetLengthSid( pGroup );
// copy the sid since AclUi will free the SD...
hr = ::GetLastError(); if ( SUCCEEDED( hr ) ) { ::LocalFree( m_pGroup ); m_pGroup = ::LocalAlloc( LMEM_ZEROINIT, dwLen ); if ( m_pGroup != NULL ) { if ( ::CopySid( dwLen, m_pGroup, pGroup ) ) { hr = S_OK; } else { sc = ::GetLastError(); hr = HRESULT_FROM_WIN32( sc ); } } else { sc = ::GetLastError(); hr = HRESULT_FROM_WIN32( sc ); } } } } else { sc = ::GetLastError(); hr = HRESULT_FROM_WIN32( sc ); }
return( hr );
} //*** CClusterSecurityPage::HrGetSDGroup()
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusterSecurityPage::HrSetSDOwner
//
// Routine Description:
// Set the owner sid.
//
// Arguments:
// psec [IN] Security descriptor.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
HRESULT CClusterSecurityPage::HrSetSDOwner( IN PSECURITY_DESCRIPTOR psec ) { HRESULT hr = S_OK;
if ( !::SetSecurityDescriptorOwner( psec, m_pOwner, m_fOwnerDef ) ) { DWORD sc = ::GetLastError(); hr = HRESULT_FROM_WIN32( sc ); }
return( hr );
} //*** CClusterSecurityPage::HrSetSDOwner()
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusterSecurityPage::HrSetSDGroup
//
// Routine Description:
// Set the group sid.
//
// Arguments:
// psec [IN] Security descriptor.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
HRESULT CClusterSecurityPage::HrSetSDGroup( IN PSECURITY_DESCRIPTOR psec ) { HRESULT hr = S_OK;
if ( !::SetSecurityDescriptorGroup( psec, m_pGroup, m_fGroupDef ) ) { DWORD sc = ::GetLastError(); hr = HRESULT_FROM_WIN32( sc ); }
return( hr );
} //*** CClusterSecurityPage::HrSetSDGroup()
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusterSecurityPage::HrGetSDFromClusterDB
//
// Routine Description:
// Retrieve the SD from the cluster database.
//
// Arguments:
// ppsec [OUT] Pointer to security descriptor.
//
// Return Value:
// S_OK for success
// Any error returned by ScReadValue
//
//--
/////////////////////////////////////////////////////////////////////////////
HRESULT CClusterSecurityPage::HrGetSDFromClusterDB( OUT PSECURITY_DESCRIPTOR * ppsec ) { AFX_MANAGE_STATE( ::AfxGetStaticModuleState() ); ASSERT( ppsec != NULL );
HRESULT hr = E_FAIL; PSECURITY_DESCRIPTOR psd = NULL;
if ( ppsec != NULL ) { DWORD sc;
// Read the security descriptor.
sc = ScReadValue( CLUSREG_NAME_CLUS_SD, (LPBYTE *) &psd, m_hkey ); //alloc using new
hr = HRESULT_FROM_WIN32( sc );
if ( FAILED( hr ) || ( psd == NULL ) ) { // try getting the NT4 SD...
sc = ScReadValue( CLUSREG_NAME_CLUS_SECURITY, (LPBYTE *) &psd, m_hkey ); //alloc using new
hr = HRESULT_FROM_WIN32( sc );
if ( SUCCEEDED( hr ) ) { *ppsec = ::ClRtlConvertClusterSDToNT5Format( psd ); } } else { *ppsec = ClRtlCopySecurityDescriptor( psd ); if ( *ppsec == NULL ) { hr = GetLastError(); // Get the last error
hr = HRESULT_FROM_WIN32( hr ); // Convert to HRESULT
} // if: error copying the security descriptor
}
delete [] psd;
if ( *ppsec != NULL ) { ::ClRtlExamineSD( *ppsec, "[ClusPage]" ); } // if: security descriptor is available to be examined
}
return hr;
} //*** CClusterSecurityPage::HrGetSDFromClusterDB
|