|
|
/////////////////////////////////////////////////////////////////////////////
// FILE : SecurityInfo.cpp //
// //
// DESCRIPTION : The ISecurityInformation implmentation used to //
// instantiate a security page. //
// //
// AUTHOR : yossg //
// //
// HISTORY : //
// Feb 7 2000 yossg Create //
// //
// Copyright (C) 2000 Microsoft Corporation All Rights Reserved //
/////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "SecurityInfo.h"
#include "FaxServer.h"
#include "FaxServerNode.h"
#include "MsFxsSnp.h"
//#pragma hdrstop
const GENERIC_MAPPING gc_FaxGenericMapping = { (STANDARD_RIGHTS_READ | FAX_GENERIC_READ), (STANDARD_RIGHTS_WRITE | FAX_GENERIC_WRITE), (STANDARD_RIGHTS_EXECUTE | FAX_GENERIC_EXECUTE), (READ_CONTROL | WRITE_DAC | WRITE_OWNER | FAX_GENERIC_ALL) };
CFaxSecurityInformation::CFaxSecurityInformation() { DebugPrint(( TEXT("CFaxSecurityInfo Created") )); }
CFaxSecurityInformation::~CFaxSecurityInformation() { DebugPrint(( TEXT("CFaxSecurityInfo Destroyed") )); }
/////////////////////////////////////////////////////////////////////////////
// CFaxSecurityInformation
// *** ISecurityInformation methods implementation ***
/*
- CFaxSecurityInformation::GetObjectInformation - * Purpose: * Performs an access check against the fax service security descriptor * * Arguments: * [in] pObjectInfo - pointer to object information structure. * * Return: * OLE error code */ HRESULT STDMETHODCALLTYPE CFaxSecurityInformation::GetObjectInformation( IN OUT PSI_OBJECT_INFO pObjectInfo ) { DEBUG_FUNCTION_NAME( _T("CFaxSecurityInformation::GetObjectInformation"));
DWORD ec = ERROR_SUCCESS; CFaxServer * pFaxServer = NULL;
HINSTANCE hInst;
HANDLE hPrivBeforeSE_TAKE_OWNERSHIP = INVALID_HANDLE_VALUE; HANDLE hPrivBeforeSE_SECURITY = INVALID_HANDLE_VALUE;
ATLASSERT( pObjectInfo != NULL ); if( pObjectInfo == NULL ) { DebugPrintEx( DEBUG_ERR, _T("Invalid parameter - pObjectInfo == NULL")); return E_POINTER; }
//
// Set Flags
//
pObjectInfo->dwFlags = SI_EDIT_ALL | SI_NO_TREE_APPLY | SI_NO_ACL_PROTECT | SI_ADVANCED;
pFaxServer = m_pFaxServerNode->GetFaxServer(); ATLASSERT(pFaxServer);
if (!pFaxServer->GetFaxServerHandle()) { ec= GetLastError(); DebugPrintEx( DEBUG_ERR, _T("Failed to GetFaxServerHandle. (ec: %ld)"), ec); goto Error; }
//
// Check if to add SI_READONLY
//
if (!FaxAccessCheckEx( pFaxServer->GetFaxServerHandle(), WRITE_DAC, NULL)) { ec = GetLastError(); if (ERROR_SUCCESS == ec) { pObjectInfo->dwFlags |= SI_READONLY; } else { DebugPrintEx( DEBUG_ERR, _T("Fail check access for WRITE_DAC.")); goto Error; } }
//
// Check if to add SI_OWNER_READONLY
//
hPrivBeforeSE_TAKE_OWNERSHIP = EnablePrivilege (SE_TAKE_OWNERSHIP_NAME); //
// No error checking - If we failed we will get ERROR_ACCESS_DENIED in the access check
//
if (!FaxAccessCheckEx( pFaxServer->GetFaxServerHandle(), WRITE_OWNER, NULL)) { ec = GetLastError(); if (ERROR_SUCCESS == ec) { pObjectInfo->dwFlags |= SI_OWNER_READONLY; } else { DebugPrintEx( DEBUG_ERR, _T("Fail check access for WRITE_OWNER.")); goto Error; } }
//
// Check if to remove SI_EDIT_AUDITS
//
hPrivBeforeSE_SECURITY = EnablePrivilege (SE_SECURITY_NAME); //
// No error checking - If we failed we will get ERROR_ACCESS_DENIED in the access check
//
if (!FaxAccessCheckEx( pFaxServer->GetFaxServerHandle(), ACCESS_SYSTEM_SECURITY, NULL)) { ec = GetLastError(); if (ERROR_SUCCESS == ec) { pObjectInfo->dwFlags &= ~SI_EDIT_AUDITS; } else { DebugPrintEx( DEBUG_ERR, _T("Fail check access for ACCESS_SYSTEM_SECURITY.")); goto Error; } }
//
// Set all other fields
//
hInst = _Module.GetResourceInstance(); pObjectInfo->hInstance = hInst; m_bstrServerName = m_pFaxServerNode->GetServerName(); if ( 0 == m_bstrServerName.Length() ) { pObjectInfo->pszServerName = NULL; DebugPrintEx( DEBUG_MSG, _T("NULL ServerName ie: Local machine.")); } else { pObjectInfo->pszServerName = m_bstrServerName; DebugPrintEx( DEBUG_MSG, _T("ServerName is: %s."), pObjectInfo->pszServerName); } if (!m_bstrObjectName.LoadString(IDS_SECURITY_CAT_NODE_DESC)) { ec = ERROR_NOT_ENOUGH_MEMORY; DebugPrintEx( DEBUG_ERR, TEXT("Out of memory. Failed to load string.")); goto Error; } pObjectInfo->pszObjectName = m_bstrObjectName;
ATLASSERT ( ERROR_SUCCESS == ec ); ReleasePrivilege (hPrivBeforeSE_SECURITY); ReleasePrivilege (hPrivBeforeSE_TAKE_OWNERSHIP); goto Exit;
Error: ATLASSERT(ERROR_SUCCESS != ec); ReleasePrivilege (hPrivBeforeSE_SECURITY); ReleasePrivilege (hPrivBeforeSE_TAKE_OWNERSHIP); return HRESULT_FROM_WIN32(ec);
Exit: return S_OK; }
/*
- CFaxSecurityInformation::GetSecurity - * Purpose: * requests a security descriptor for the securable object whose * security descriptor is being edited. The access control editor * calls this method to retrieve the object's current or default security descriptor. * * Arguments: * [in] RequestedInformation - security information. * [out] ppSecurityDescriptor - pointer to security descriptor. * [in] fDefault - not implemented * * Return: * OLE error code */ HRESULT STDMETHODCALLTYPE CFaxSecurityInformation::GetSecurity( IN SECURITY_INFORMATION RequestedInformation, OUT PSECURITY_DESCRIPTOR *ppSecurityDescriptor, IN BOOL fDefault ) { DEBUG_FUNCTION_NAME( _T("CFaxSecurityInformation::GetSecurity")); HRESULT hRc = S_OK; CFaxServer * pFaxServer = NULL; PSECURITY_DESCRIPTOR pSecurityDescriptor = NULL; DWORD ec = ERROR_SUCCESS; BOOL bResult; HANDLE hPrivBeforeSE_SECURITY = INVALID_HANDLE_VALUE;
ATLASSERT( ppSecurityDescriptor); if( fDefault == TRUE ) { DebugPrintEx( DEBUG_MSG, _T("Non implemeted feature -> fDefault == TRUE")); return E_NOTIMPL; }
if (RequestedInformation & SACL_SECURITY_INFORMATION) { hPrivBeforeSE_SECURITY = EnablePrivilege (SE_SECURITY_NAME); }
pFaxServer = m_pFaxServerNode->GetFaxServer(); ATLASSERT(pFaxServer);
if (!pFaxServer->GetFaxServerHandle()) { ec= GetLastError(); DebugPrintEx( DEBUG_ERR, _T("Failed to GetFaxServerHandle. (ec: %ld)"), ec); hRc = HRESULT_FROM_WIN32(ec); goto Exit; }
//
// Get the current relative descriptor from the fax server
//
bResult = FaxGetSecurityEx( pFaxServer->GetFaxServerHandle(), RequestedInformation, &pSecurityDescriptor); if( bResult == FALSE ) { ec = GetLastError(); if (IsNetworkError(ec)) { DebugPrintEx( DEBUG_ERR, _T("Network Error was found. Failed to set security info.(ec: %ld)"), ec); pFaxServer->Disconnect(); } else { DebugPrintEx( DEBUG_ERR, _T("Failed while call to FaxGetSecurityEx. (ec: %ld)"), ec); } hRc = HRESULT_FROM_WIN32(ec); goto Exit; }
//
// return a self relative descriptor copy allocated with LocalAlloc()
//
hRc = MakeSelfRelativeCopy( pSecurityDescriptor, ppSecurityDescriptor ); if( FAILED( hRc ) ) { DebugPrintEx( DEBUG_ERR, _T("MakeSelfRelativeCopy Failed. (hRc : %08X)"), hRc); goto Exit; } ATLASSERT(S_OK == hRc);
Exit: if (NULL != pSecurityDescriptor) { FaxFreeBuffer(pSecurityDescriptor); } ReleasePrivilege (hPrivBeforeSE_SECURITY); return hRc; }
/*
- CFaxSecurityInformation::SetSecurity - * Purpose: * Provides a security descriptor containing the security information * the user wants to apply to the securable object. The access control * editor calls this method when the user clicks the Okay or Apply buttons. * * Arguments: * [in] SecurityInformation - security information structure. * [in] pSecurityDescriptor - pointer to security descriptor. * * Return: * OLE error code */ HRESULT STDMETHODCALLTYPE CFaxSecurityInformation::SetSecurity( IN SECURITY_INFORMATION SecurityInformation, IN PSECURITY_DESCRIPTOR pSecurityDescriptor ) { DEBUG_FUNCTION_NAME( _T("CFaxSecurityInformation::SetSecurity")); HRESULT hRc = S_OK; DWORD ec = ERROR_SUCCESS; BOOL bResult;
HINSTANCE hInst = _Module.GetResourceInstance(); PSECURITY_DESCRIPTOR psdSelfRelativeCopy = NULL; CFaxServer * pFaxServer = NULL;
HANDLE hPrivBeforeSE_TAKE_OWNERSHIP = INVALID_HANDLE_VALUE; HANDLE hPrivBeforeSE_SECURITY = INVALID_HANDLE_VALUE; ATLASSERT( NULL != pSecurityDescriptor ); ATLASSERT( IsValidSecurityDescriptor( pSecurityDescriptor ) ); //
// Prepare self relative descriptor
//
hRc = MakeSelfRelativeCopy( pSecurityDescriptor, &psdSelfRelativeCopy ); if( FAILED( hRc ) ) { DebugPrintEx( DEBUG_ERR, _T("MakeSelfRelativeCopy Failed. (hRc : %08X)"), hRc); goto Exit; }
if (SecurityInformation & OWNER_SECURITY_INFORMATION) { hPrivBeforeSE_TAKE_OWNERSHIP = EnablePrivilege (SE_TAKE_OWNERSHIP_NAME); }
if (SecurityInformation & SACL_SECURITY_INFORMATION) { hPrivBeforeSE_SECURITY = EnablePrivilege (SE_SECURITY_NAME); } pFaxServer = m_pFaxServerNode->GetFaxServer(); ATLASSERT(pFaxServer);
if (!pFaxServer->GetFaxServerHandle()) { ec= GetLastError(); DebugPrintEx( DEBUG_ERR, _T("Failed to GetFaxServerHandle. (ec: %ld)"), ec); hRc = HRESULT_FROM_WIN32(ec); goto Exit; }
//
// save the new relative descriptor to the fax server
//
bResult = FaxSetSecurity( pFaxServer->GetFaxServerHandle(), SecurityInformation, psdSelfRelativeCopy); if( bResult == FALSE ) { ec = GetLastError(); if (IsNetworkError(ec)) { DebugPrintEx( DEBUG_ERR, _T("Network Error was found. Failed to set security info.(ec: %ld)"), ec); pFaxServer->Disconnect(); } else { DebugPrintEx( DEBUG_ERR, _T("Failed while call to FaxSetSecurity. (ec: %ld)"), ec); } hRc = HRESULT_FROM_WIN32(ec); goto Exit; }
ATLASSERT( S_OK == hRc || E_ACCESSDENIED == hRc);
Exit: if (NULL != psdSelfRelativeCopy) { ::LocalFree(psdSelfRelativeCopy); psdSelfRelativeCopy = NULL; }
ReleasePrivilege (hPrivBeforeSE_SECURITY); ReleasePrivilege (hPrivBeforeSE_TAKE_OWNERSHIP);
return hRc; }
/*
- CFaxSecurityInformation::GetAccessRights - * Purpose: * Requests information about the access rights that can be * controlled for a securable object. The access control * editor calls this method to retrieve display strings and * other information used to initialize the property pages. * * Arguments: * [in] pguidObjectType - Pointer to a GUID structure that * identifies the type of object for which * access rights are being requested. * [in] dwFlags - A set of bit flags that indicate the property * page being initialized * [out] ppAccess - Pointer to a variable that you should * set to a pointer to an array of SI_ACCESS * structures. * [out] pcAccesses - Pointer to a variable that you should set * to indicate the number of entries in the ppAccess array. * [out] piDefaultAccess - Pointer to a variable that you should set * to indicate the zero-based index of the array entry that contains * the default access rights. * The access control editor uses this entry as the initial access rights in a new ACE. * * Return: * OLE error code */ HRESULT STDMETHODCALLTYPE CFaxSecurityInformation::GetAccessRights( IN const GUID* pguidObjectType, IN DWORD dwFlags, // SI_EDIT_AUDITS, SI_EDIT_PROPERTIES
OUT PSI_ACCESS *ppAccess, OUT ULONG *pcAccesses, OUT ULONG *piDefaultAccess ) { DEBUG_FUNCTION_NAME( _T("CFaxSecurityInformation::GetAccessRights")); ATLASSERT( ppAccess ); ATLASSERT( pcAccesses ); ATLASSERT( piDefaultAccess ); //
// Access rights for the Advanced security page
//
static SI_ACCESS siFaxAccesses[] = { // 0 submit permission
{ &GUID_NULL, FAX_ACCESS_SUBMIT , MAKEINTRESOURCE(IDS_FAXSEC_SUB_LOW), SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC }, // 1 submit normal permission
{ &GUID_NULL, FAX_ACCESS_SUBMIT_NORMAL , MAKEINTRESOURCE(IDS_FAXSEC_SUB_NORMAL), SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC }, // 2 submit high permission
{ &GUID_NULL, FAX_ACCESS_SUBMIT_HIGH , MAKEINTRESOURCE(IDS_FAXSEC_SUB_HIGH), SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC }, // 3 query jobs
{ &GUID_NULL, FAX_ACCESS_QUERY_JOBS, MAKEINTRESOURCE(IDS_FAXSEC_JOB_QRY), SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC }, // 4 Manage jobs
{ &GUID_NULL, FAX_ACCESS_MANAGE_JOBS, MAKEINTRESOURCE(IDS_FAXSEC_JOB_MNG), SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC }, // 5 query configuration
{ &GUID_NULL, FAX_ACCESS_QUERY_CONFIG, MAKEINTRESOURCE(IDS_FAXSEC_CONFIG_QRY), SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC }, // 6 Manage configuration
{ &GUID_NULL, FAX_ACCESS_MANAGE_CONFIG, MAKEINTRESOURCE(IDS_FAXSEC_CONFIG_SET), SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC }, // 7 Query incoming faxes archive
{ &GUID_NULL, FAX_ACCESS_QUERY_IN_ARCHIVE, MAKEINTRESOURCE(IDS_FAXSEC_QRY_IN_ARCH), SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC }, // 8 Manage incoming faxes archive
{ &GUID_NULL, FAX_ACCESS_MANAGE_IN_ARCHIVE, MAKEINTRESOURCE(IDS_FAXSEC_MNG_IN_ARCH), SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC }, // 9 Query outgoing faxes archive
{ &GUID_NULL, FAX_ACCESS_QUERY_OUT_ARCHIVE, MAKEINTRESOURCE(IDS_FAXSEC_QRY_OUT_ARCH), SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC }, // 10 Manage outgoing faxes archive
{ &GUID_NULL, FAX_ACCESS_MANAGE_OUT_ARCHIVE, MAKEINTRESOURCE(IDS_FAXSEC_MNG_OUT_ARCH), SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC }, // specific permissions
// 11 Read permission
{ &GUID_NULL, READ_CONTROL, MAKEINTRESOURCE(IDS_FAXSEC_READ_PERM), SI_ACCESS_SPECIFIC }, // 12 Change Permissions
{ &GUID_NULL, WRITE_DAC, MAKEINTRESOURCE(IDS_FAXSEC_CHNG_PERM), SI_ACCESS_SPECIFIC }, // 13 Take ownership
{ &GUID_NULL, WRITE_OWNER, MAKEINTRESOURCE(IDS_FAXSEC_CHNG_OWNER), SI_ACCESS_SPECIFIC } };
//
// Access rights for the Basic security page
//
static SI_ACCESS siFaxBasicAccess[] = { // 0 Fax
{ &GUID_NULL, FAX_ACCESS_SUBMIT_NORMAL | FAX_ACCESS_SUBMIT, MAKEINTRESOURCE(IDS_RIGHT_FAX), SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC }, // 1 Manage fax configuration
{ &GUID_NULL, FAX_ACCESS_MANAGE_CONFIG | FAX_ACCESS_QUERY_CONFIG, MAKEINTRESOURCE(IDS_RIGHT_MNG_CFG), SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC }, // 2 Manage fax documents
{ &GUID_NULL, FAX_ACCESS_MANAGE_JOBS | FAX_ACCESS_QUERY_JOBS | FAX_ACCESS_MANAGE_IN_ARCHIVE | FAX_ACCESS_QUERY_IN_ARCHIVE | FAX_ACCESS_MANAGE_OUT_ARCHIVE | FAX_ACCESS_QUERY_OUT_ARCHIVE, MAKEINTRESOURCE(IDS_RIGHT_MNG_DOC), SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC } };
*ppAccess = (0 == dwFlags) ? siFaxBasicAccess : siFaxAccesses; *pcAccesses = ULONG((0 == dwFlags) ? ARR_SIZE(siFaxBasicAccess) : ARR_SIZE(siFaxAccesses)); *piDefaultAccess = (0 == dwFlags) ? 0 : 1;
return S_OK; }
/*
- CFaxSecurityInformation::MapGeneric - * Purpose: * Requests that the generic access rights in an access mask * be mapped to their corresponding standard and specific access rights. * * Arguments: * * Return: * OLE error code */ HRESULT STDMETHODCALLTYPE CFaxSecurityInformation::MapGeneric( IN const GUID *pguidObjectType, IN UCHAR *pAceFlags, IN OUT ACCESS_MASK *pMask ) { DEBUG_FUNCTION_NAME( _T("CFaxSecurityInformation::MapGeneric"));
MapGenericMask( pMask, const_cast<PGENERIC_MAPPING>(&gc_FaxGenericMapping) );
return S_OK; }
/*
- CFaxSecurityInformation::GetInheritTypes - * Purpose: * Not implemented. * * Arguments: * * Return: * OLE error code */ HRESULT STDMETHODCALLTYPE CFaxSecurityInformation::GetInheritTypes( OUT PSI_INHERIT_TYPE *ppInheritTypes, OUT ULONG *pcInheritTypes ) { DEBUG_FUNCTION_NAME( _T("CFaxSecurityInformation::GetInheritTypes --- Not implemented")); return E_NOTIMPL; }
/*
- CFaxSecurityInformation::PropertySheetPageCallback - * Purpose: * Notifies an EditSecurity or CreateSecurityPage caller * that an access control editor property page is being created or destroyed. * * Arguments: * * Return: * OLE error code */ HRESULT STDMETHODCALLTYPE CFaxSecurityInformation::PropertySheetPageCallback( IN HWND hwnd, IN UINT uMsg, IN SI_PAGE_TYPE uPage ) { DEBUG_FUNCTION_NAME( _T("CFaxSecurityInformation::PropertySheetPageCallback")); return S_OK; }
/*
- CFaxSecurityInformation::MakeSelfRelativeCopy - * Purpose: * This pravite method copies Security descriptors * * Arguments: * * Return: * OLE error code */ HRESULT CFaxSecurityInformation::MakeSelfRelativeCopy( PSECURITY_DESCRIPTOR psdOriginal, PSECURITY_DESCRIPTOR* ppsdNew ) { DEBUG_FUNCTION_NAME( _T("CFaxSecurityInformation::MakeSelfRelativeCopy")); ATLASSERT( NULL != psdOriginal );
// we have to find out whether the original is already self-relative
SECURITY_DESCRIPTOR_CONTROL sdc = 0; PSECURITY_DESCRIPTOR psdSelfRelativeCopy = NULL; DWORD dwRevision = 0; DWORD cb = 0;
ATLASSERT( IsValidSecurityDescriptor( psdOriginal ) );
if( !::GetSecurityDescriptorControl( psdOriginal, &sdc, &dwRevision ) ) { DWORD err = ::GetLastError(); DebugPrintEx( DEBUG_ERR, _T("Invalid security descriptor."));
return HRESULT_FROM_WIN32( err ); }
if( sdc & SE_SELF_RELATIVE ) { // the original is in self-relative format, just byte-copy it
// get size
cb = ::GetSecurityDescriptorLength( psdOriginal );
// alloc the memory
psdSelfRelativeCopy = (PSECURITY_DESCRIPTOR) ::LocalAlloc( LMEM_ZEROINIT, cb ); if(NULL == psdSelfRelativeCopy) { DebugPrintEx( DEBUG_ERR, TEXT("Out of memory.")); //GetRootNode()->NodeMsgBox(IDS_MEMORY);
return E_OUTOFMEMORY; }
// make the copy
::memcpy( psdSelfRelativeCopy, psdOriginal, cb ); } else { // the original is in absolute format, convert-copy it
// get new size - it will fail and set cb to the correct buffer size
::MakeSelfRelativeSD( psdOriginal, NULL, &cb );
// alloc the new amount of memory
psdSelfRelativeCopy = (PSECURITY_DESCRIPTOR) ::LocalAlloc( LMEM_ZEROINIT, cb ); if(NULL == psdSelfRelativeCopy) { DebugPrintEx( DEBUG_ERR, TEXT("Out of memory.")); //GetRootNode()->NodeMsgBox(IDS_MEMORY);
return E_OUTOFMEMORY; // just in case the exception is ignored
}
if( !::MakeSelfRelativeSD( psdOriginal, psdSelfRelativeCopy, &cb ) ) { DebugPrintEx( DEBUG_ERR, _T("::MakeSelfRelativeSD returned NULL"));
if( NULL == ::LocalFree( psdSelfRelativeCopy ) ) { DWORD err = ::GetLastError(); return HRESULT_FROM_WIN32( err ); } psdSelfRelativeCopy = NULL; } }
*ppsdNew = psdSelfRelativeCopy; return S_OK; }
|