1353 lines
40 KiB
C++
1353 lines
40 KiB
C++
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// 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 pServiceSid = 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 Service sid
|
|
//
|
|
if ( AllocateAndInitializeSid(
|
|
&siaNtAuthority,
|
|
1,
|
|
SECURITY_SERVICE_RID,
|
|
0, 0, 0, 0, 0, 0, 0,
|
|
&pServiceSid
|
|
) )
|
|
{
|
|
if ( BSidInSD( pSecurityDescriptor, pServiceSid ) )
|
|
{
|
|
hr = Pcsp()->HrSetSecurityDescriptor( pSecurityDescriptor );
|
|
} // if: service SID in the SD
|
|
else
|
|
{
|
|
strMsg.LoadString( IDS_SERVICE_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 );
|
|
}
|
|
|
|
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;
|
|
|
|
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
|
|
}
|
|
catch ( ... )
|
|
{
|
|
TRACE( _T("CClusterSecurityInformation::HrFixupSD() - Unknown error occurred.\n") );
|
|
}
|
|
|
|
if ( pSystemSid != NULL )
|
|
{
|
|
FreeSid( pSystemSid );
|
|
}
|
|
|
|
if ( pAdminSid != NULL )
|
|
{
|
|
FreeSid( pAdminSid );
|
|
}
|
|
|
|
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 ) )
|
|
{
|
|
DWORD sc;
|
|
DWORD dwLen = 0;
|
|
|
|
TRACE( _T( "Security Descriptor is NULL. Build default SD" ) );
|
|
sc = ::ClRtlBuildDefaultClusterSD( NULL, &psec, &dwLen ); //uses localalloc
|
|
hr = HRESULT_FROM_WIN32( sc );
|
|
|
|
if ( sc != ERROR_SUCCESS )
|
|
{
|
|
TRACE( _T( "ClRtlBuildDefaultClusterSD failed, 0x%08x" ), sc );
|
|
} // if: error building the default SD
|
|
hr = HRESULT_FROM_WIN32( sc );
|
|
} // 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 );
|
|
|
|
PSECURITY_DESCRIPTOR psd = ClRtlConvertClusterSDToNT4Format( psec );
|
|
|
|
ScWriteValue( CLUSREG_NAME_CLUS_SECURITY, (LPBYTE) psd, cbNew, (LPBYTE *) &psecPrev, cbOld, m_hkey );
|
|
::LocalFree( psd );
|
|
|
|
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
|