//+--------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation 1996-2001. // // File: aservice.cpp // // Contents: implementation of CAnalysisService // //---------------------------------------------------------------------------- #include "stdafx.h" #include "wsecmgr.h" #include "resource.h" #include "snapmgr.h" #include "attr.h" #include "cservice.h" #include "Aservice.h" #include "util.h" #include "servperm.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif BYTE CompareServiceNode( PSCE_SERVICES pBaseService, PSCE_SERVICES pAnalService ) { if ( NULL == pBaseService || NULL == pAnalService ) { // one or both are not configured return SCE_STATUS_NOT_CONFIGURED; } if ( pBaseService == pAnalService ) { // same address pAnalService->Status = SCE_STATUS_GOOD; return SCE_STATUS_GOOD; } if ( pBaseService->Startup != pAnalService->Startup ) { // startup type is different pAnalService->Status = SCE_STATUS_MISMATCH; return SCE_STATUS_MISMATCH; } if ( NULL == pBaseService->General.pSecurityDescriptor && NULL == pAnalService->General.pSecurityDescriptor ) { // both do not have SD - everyone full control pAnalService->Status = SCE_STATUS_GOOD; return SCE_STATUS_GOOD; } if ( NULL == pBaseService->General.pSecurityDescriptor || NULL == pAnalService->General.pSecurityDescriptor ) { // one SD is NULL pAnalService->Status = SCE_STATUS_MISMATCH; return SCE_STATUS_MISMATCH; } BOOL bIsDif=FALSE; SCESTATUS rc = SceCompareSecurityDescriptors( AREA_SYSTEM_SERVICE, pBaseService->General.pSecurityDescriptor, pAnalService->General.pSecurityDescriptor, pBaseService->SeInfo | pAnalService->SeInfo, &bIsDif ); if ( SCESTATUS_SUCCESS == rc && bIsDif == FALSE ) { pAnalService->Status = SCE_STATUS_GOOD; return SCE_STATUS_GOOD; } pAnalService->Status = SCE_STATUS_MISMATCH; return SCE_STATUS_MISMATCH; } ///////////////////////////////////////////////////////////////////////////// // CAnalysisService dialog CAnalysisService::CAnalysisService() : CAttribute(IDD), m_pNewSD(NULL), m_NewSeInfo(0), m_pAnalSD(NULL), m_hwndShow(NULL), m_hwndChange(NULL), m_SecInfo(DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION), m_pEditSec(NULL), m_pShowSec(NULL) { //{{AFX_DATA_INIT(CAnalysisService) m_nStartupRadio = -1; m_CurrentStr = _T(""); //}}AFX_DATA_INIT m_pHelpIDs = (DWORD_PTR)a194HelpIDs; m_uTemplateResID = IDD; } CAnalysisService::~CAnalysisService() { if (::IsWindow(m_hwndShow)) { m_pShowSec->Destroy(m_hwndShow); m_hwndShow = NULL; } delete m_pShowSec; m_pShowSec = NULL; if (::IsWindow(m_hwndChange)) { m_pEditSec->Destroy(m_hwndChange); m_hwndChange = NULL; } delete m_pEditSec; m_pEditSec = NULL; } void CAnalysisService::DoDataExchange(CDataExchange* pDX) { CAttribute::DoDataExchange(pDX); //{{AFX_DATA_MAP(CAnalysisService) DDX_Text(pDX, IDC_CURRENT, m_CurrentStr); DDX_Radio(pDX, IDC_ENABLED, m_nStartupRadio); DDX_Control(pDX, IDC_BASESD, m_bPermission); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CAnalysisService, CAttribute) //{{AFX_MSG_MAP(CAnalysisService) ON_BN_CLICKED(IDC_BASESD, OnChangeSecurity) ON_BN_CLICKED(IDC_CURRENTSD, OnShowSecurity) ON_BN_CLICKED(IDC_CONFIGURE, OnConfigure) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CAnalysisService message handlers BOOL CAnalysisService::OnApply() { if ( !m_bReadOnly ) { // OnQueryCancel does all gestures and returns false if child windows are up if (!OnQueryCancel()) return FALSE; DWORD dw = 0; int status = 0; PEDITTEMPLATE pet = 0; UpdateData(TRUE); PSCE_SERVICES pNode = (PSCE_SERVICES)(m_pData->GetBase()); if (!m_bConfigure ) { if ( NULL != pNode ) { m_pSnapin->SetupLinkServiceNodeToBase(FALSE, m_pData->GetBase()); if ( m_pData->GetBase() != m_pData->GetSetting() ) { // // analysis is not using the same node, free it // pNode->Next = NULL; SceFreeMemory(pNode, SCE_STRUCT_SERVICES); } else { // // add the node to analysis // pNode->Status = SCE_STATUS_NOT_CONFIGURED; m_pSnapin->AddServiceNodeToProfile(pNode); } m_pData->SetBase(0); } m_pData->SetStatus(SCE_STATUS_NOT_CONFIGURED); if ( m_pNewSD ) { LocalFree(m_pNewSD); m_pNewSD = NULL; } } else { switch(m_nStartupRadio) { case 0: // Automatic dw = SCE_STARTUP_AUTOMATIC; break; case 1: // Manual dw = SCE_STARTUP_MANUAL; break; default: // DISABLED dw = SCE_STARTUP_DISABLED; break; } if ( NULL != pNode && m_pData->GetBase() == m_pData->GetSetting() ) { // // a matched item is changed to mismatch // needs to create a new node // m_pSnapin->SetupLinkServiceNodeToBase(FALSE, m_pData->GetBase()); m_pData->SetBase(0); // // add to analysis profile // pNode->Status = SCE_STATUS_MISMATCH; m_pSnapin->AddServiceNodeToProfile(pNode); pNode = NULL; } PSCE_SERVICES pSetting = (PSCE_SERVICES)(m_pData->GetSetting()); BYTE status = 0; if ( NULL == pNode ) { // // a node is changed from not configured to configured // or from match to mismatch // pNode = CreateServiceNode(m_pData->GetUnits(), m_pData->GetAttr(), dw, m_pNewSD, m_NewSeInfo); if ( pNode != NULL ) { // // add to the service list // m_pSnapin->SetupLinkServiceNodeToBase(TRUE, (LONG_PTR)pNode); m_pData->SetBase((LONG_PTR)pNode); if ( pSetting ) { status = CompareServiceNode(pNode, pSetting); m_pData->SetStatus(status); } else { // // this is a new configured service // should create a "dump" analysis node to indictae // this service is not a "matched" item // pSetting = CreateServiceNode(m_pData->GetUnits(), m_pData->GetAttr(), 0, NULL, 0); if ( pSetting ) { // // link it to analysis profile // PEDITTEMPLATE pet = 0; PSCE_PROFILE_INFO pInfo=NULL; pet = m_pSnapin->GetTemplate(GT_LAST_INSPECTION, AREA_SYSTEM_SERVICE); if (NULL != pet ) pInfo = pet->pTemplate; if ( pInfo ) { pSetting->Status = SCE_STATUS_NOT_CONFIGURED; pSetting->Next = pInfo->pServices; pInfo->pServices = pSetting; m_pData->SetSetting( (LONG_PTR)pSetting); } else { // // free pSetting // LocalFree(pSetting->DisplayName); LocalFree(pSetting->ServiceName); LocalFree(pSetting); pSetting = NULL; } } m_pData->SetStatus(SCE_STATUS_NOT_CONFIGURED); } } else { // // no memory, error out // if ( m_pNewSD ) { LocalFree(m_pNewSD); m_pNewSD = NULL; } } } else { // // an existing service // pNode->Startup = (BYTE)dw; if ( m_pNewSD != NULL ) { if ( pNode->General.pSecurityDescriptor != m_pNewSD && pNode->General.pSecurityDescriptor != NULL ) { LocalFree(pNode->General.pSecurityDescriptor); } pNode->General.pSecurityDescriptor = m_pNewSD; m_pNewSD = NULL; pNode->SeInfo = m_NewSeInfo; } // // update status field in the analysis node // if ( pSetting ) { status = CompareServiceNode(pNode, pSetting); m_pData->SetStatus(status); } else { // this is a new configured service m_pData->SetStatus(SCE_STATUS_NOT_CONFIGURED); } } } pet = m_pData->GetBaseProfile(); pet->SetDirty(AREA_SYSTEM_SERVICE); m_pData->Update(m_pSnapin); m_NewSeInfo = 0; m_hwndParent = NULL; m_hwndShow = NULL; m_hwndChange = NULL; } return CAttribute::OnApply(); } void CAnalysisService::OnCancel() { if ( m_pNewSD ) { LocalFree(m_pNewSD); m_pNewSD = NULL; } m_NewSeInfo = 0; m_hwndParent = NULL; m_pAnalSD = NULL; m_hwndShow = NULL; m_hwndChange = NULL; CAttribute::OnCancel(); } BOOL CAnalysisService::OnInitDialog() { CAttribute::OnInitDialog(); if ( 0 == m_pData->GetSetting() ) { CButton *rb = (CButton *)GetDlgItem(IDC_CURRENTSD); rb->EnableWindow(FALSE); } AddUserControl(IDC_ENABLED); AddUserControl(IDC_DISABLED); AddUserControl(IDC_IGNORE); AddUserControl(IDC_BASESD); OnConfigure(); return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } void CAnalysisService::Initialize(CResult * pResult) { CAttribute::Initialize(pResult); // // initialize setting // m_pNewSD = NULL; m_NewSeInfo = 0; m_pAnalSD = NULL; // // Never start up with do not configure set. If they're coming // here it is probably to set a value // m_bConfigure = TRUE; if ( 0 != pResult->GetSetting() ) { PSCE_SERVICES pServSetting = (PSCE_SERVICES)(pResult->GetSetting()); switch ( pServSetting->Startup ) { case SCE_STARTUP_AUTOMATIC: m_CurrentStr.LoadString(IDS_AUTOMATIC); break; case SCE_STARTUP_MANUAL: m_CurrentStr.LoadString(IDS_MANUAL); break; default: // disabled m_CurrentStr.LoadString(IDS_DISABLED); break; } m_pAnalSD = pServSetting->General.pSecurityDescriptor; } PSCE_SERVICES pService; pService = (PSCE_SERVICES)(pResult->GetBase()); if ( NULL == pService ) { m_bConfigure = FALSE; pService = (PSCE_SERVICES)(pResult->GetSetting()); } if ( pService != NULL ) { switch ( pService->Startup ) { case SCE_STARTUP_AUTOMATIC: m_nStartupRadio = 0; break; case SCE_STARTUP_MANUAL: m_nStartupRadio = 1; break; default: // disabled m_nStartupRadio = 2; break; } if ( pService->General.pSecurityDescriptor ) { MyMakeSelfRelativeSD(pService->General.pSecurityDescriptor, &m_pNewSD); } m_NewSeInfo = pService->SeInfo; } } void CAnalysisService::OnShowSecurity() { if ( IsWindow(m_hwndShow) ) { ::BringWindowToTop(m_hwndShow); return; } PSCE_SERVICES pService = (PSCE_SERVICES)(m_pData->GetSetting()); SECURITY_INFORMATION SeInfo; if (pService) m_SecInfo = pService->SeInfo; // prepare the modeless property page data for the thread to create // the property sheet. if (NULL == m_pShowSec) { m_pShowSec = new CModelessSceEditor(false, ANALYSIS_SECURITY_PAGE_RO_NP, GetSafeHwnd(), SE_SERVICE, m_pData->GetAttr()); } if (NULL != m_pShowSec) m_pShowSec->Create(&m_pAnalSD, &m_SecInfo, &m_hwndShow); } void CAnalysisService::OnConfigure() { CAttribute::OnConfigure(); if (m_bConfigure && !m_pNewSD) { OnChangeSecurity(); } else if (!m_bConfigure && IsWindow(m_hwndChange)) { m_pEditSec->Destroy(m_hwndChange); m_hwndChange = NULL; } } void CAnalysisService::OnChangeSecurity() { if ( IsWindow(m_hwndChange) ) { ::BringWindowToTop(m_hwndChange); return; } if ( !m_pNewSD ) { GetDefaultServiceSecurity(&m_pNewSD,&m_NewSeInfo); } // if it comes to this point, the m_hwndChange must not be a valid Window // so the can ask to create a modeless dialog if (NULL == m_pEditSec) { m_pEditSec = new CModelessSceEditor(false, CONFIG_SECURITY_PAGE_NO_PROTECT, GetSafeHwnd(), SE_SERVICE, m_pData->GetAttr()); } if (NULL != m_pEditSec) m_pEditSec->Create(&m_pNewSD, &m_NewSeInfo, &m_hwndChange); } //------------------------------------------------------------------ // override to prevent the sheet from being destroyed when there is // child dialogs still up and running. //------------------------------------------------------------------ BOOL CAnalysisService::OnQueryCancel() { if (::IsWindow(m_hwndChange) || ::IsWindow(m_hwndShow)) { CString strMsg; strMsg.LoadString(IDS_CLOSESUBSHEET_BEFORE_APPLY); AfxMessageBox(strMsg); return FALSE; } else return TRUE; }