Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

563 lines
16 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation 1996-2001.
  5. //
  6. // File: aservice.cpp
  7. //
  8. // Contents: implementation of CAnalysisService
  9. //
  10. //----------------------------------------------------------------------------
  11. #include "stdafx.h"
  12. #include "wsecmgr.h"
  13. #include "resource.h"
  14. #include "snapmgr.h"
  15. #include "attr.h"
  16. #include "cservice.h"
  17. #include "Aservice.h"
  18. #include "util.h"
  19. #include "servperm.h"
  20. #ifdef _DEBUG
  21. #define new DEBUG_NEW
  22. #undef THIS_FILE
  23. static char THIS_FILE[] = __FILE__;
  24. #endif
  25. BYTE
  26. CompareServiceNode(
  27. PSCE_SERVICES pBaseService,
  28. PSCE_SERVICES pAnalService
  29. )
  30. {
  31. if ( NULL == pBaseService ||
  32. NULL == pAnalService ) {
  33. // one or both are not configured
  34. return SCE_STATUS_NOT_CONFIGURED;
  35. }
  36. if ( pBaseService == pAnalService ) {
  37. // same address
  38. pAnalService->Status = SCE_STATUS_GOOD;
  39. return SCE_STATUS_GOOD;
  40. }
  41. if ( pBaseService->Startup != pAnalService->Startup ) {
  42. // startup type is different
  43. pAnalService->Status = SCE_STATUS_MISMATCH;
  44. return SCE_STATUS_MISMATCH;
  45. }
  46. if ( NULL == pBaseService->General.pSecurityDescriptor &&
  47. NULL == pAnalService->General.pSecurityDescriptor ) {
  48. // both do not have SD - everyone full control
  49. pAnalService->Status = SCE_STATUS_GOOD;
  50. return SCE_STATUS_GOOD;
  51. }
  52. if ( NULL == pBaseService->General.pSecurityDescriptor ||
  53. NULL == pAnalService->General.pSecurityDescriptor ) {
  54. // one SD is NULL
  55. pAnalService->Status = SCE_STATUS_MISMATCH;
  56. return SCE_STATUS_MISMATCH;
  57. }
  58. BOOL bIsDif=FALSE;
  59. SCESTATUS rc = SceCompareSecurityDescriptors(
  60. AREA_SYSTEM_SERVICE,
  61. pBaseService->General.pSecurityDescriptor,
  62. pAnalService->General.pSecurityDescriptor,
  63. pBaseService->SeInfo | pAnalService->SeInfo,
  64. &bIsDif
  65. );
  66. if ( SCESTATUS_SUCCESS == rc &&
  67. bIsDif == FALSE ) {
  68. pAnalService->Status = SCE_STATUS_GOOD;
  69. return SCE_STATUS_GOOD;
  70. }
  71. pAnalService->Status = SCE_STATUS_MISMATCH;
  72. return SCE_STATUS_MISMATCH;
  73. }
  74. /////////////////////////////////////////////////////////////////////////////
  75. // CAnalysisService dialog
  76. CAnalysisService::CAnalysisService()
  77. : CAttribute(IDD),
  78. m_pNewSD(NULL),
  79. m_NewSeInfo(0),
  80. m_pAnalSD(NULL),
  81. m_hwndShow(NULL),
  82. m_hwndChange(NULL),
  83. m_SecInfo(DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION),
  84. m_pEditSec(NULL),
  85. m_pShowSec(NULL)
  86. {
  87. //{{AFX_DATA_INIT(CAnalysisService)
  88. m_nStartupRadio = -1;
  89. m_CurrentStr = _T("");
  90. //}}AFX_DATA_INIT
  91. m_pHelpIDs = (DWORD_PTR)a194HelpIDs;
  92. m_uTemplateResID = IDD;
  93. }
  94. CAnalysisService::~CAnalysisService()
  95. {
  96. if (::IsWindow(m_hwndShow))
  97. {
  98. m_pShowSec->Destroy(m_hwndShow);
  99. m_hwndShow = NULL;
  100. }
  101. delete m_pShowSec;
  102. m_pShowSec = NULL;
  103. if (::IsWindow(m_hwndChange))
  104. {
  105. m_pEditSec->Destroy(m_hwndChange);
  106. m_hwndChange = NULL;
  107. }
  108. delete m_pEditSec;
  109. m_pEditSec = NULL;
  110. }
  111. void CAnalysisService::DoDataExchange(CDataExchange* pDX)
  112. {
  113. CAttribute::DoDataExchange(pDX);
  114. //{{AFX_DATA_MAP(CAnalysisService)
  115. DDX_Text(pDX, IDC_CURRENT, m_CurrentStr);
  116. DDX_Radio(pDX, IDC_ENABLED, m_nStartupRadio);
  117. DDX_Control(pDX, IDC_BASESD, m_bPermission);
  118. //}}AFX_DATA_MAP
  119. }
  120. BEGIN_MESSAGE_MAP(CAnalysisService, CAttribute)
  121. //{{AFX_MSG_MAP(CAnalysisService)
  122. ON_BN_CLICKED(IDC_BASESD, OnChangeSecurity)
  123. ON_BN_CLICKED(IDC_CURRENTSD, OnShowSecurity)
  124. ON_BN_CLICKED(IDC_CONFIGURE, OnConfigure)
  125. //}}AFX_MSG_MAP
  126. END_MESSAGE_MAP()
  127. /////////////////////////////////////////////////////////////////////////////
  128. // CAnalysisService message handlers
  129. BOOL CAnalysisService::OnApply()
  130. {
  131. if ( !m_bReadOnly )
  132. {
  133. // OnQueryCancel does all gestures and returns false if child windows are up
  134. if (!OnQueryCancel())
  135. return FALSE;
  136. DWORD dw = 0;
  137. PEDITTEMPLATE pet = 0;
  138. UpdateData(TRUE);
  139. PSCE_SERVICES pNode = (PSCE_SERVICES)(m_pData->GetBase());
  140. if (!m_bConfigure )
  141. {
  142. if ( NULL != pNode )
  143. {
  144. m_pSnapin->SetupLinkServiceNodeToBase(FALSE, m_pData->GetBase());
  145. if ( m_pData->GetBase() != m_pData->GetSetting() )
  146. {
  147. //
  148. // analysis is not using the same node, free it
  149. //
  150. pNode->Next = NULL;
  151. SceFreeMemory(pNode, SCE_STRUCT_SERVICES);
  152. }
  153. else
  154. {
  155. //
  156. // add the node to analysis
  157. //
  158. pNode->Status = SCE_STATUS_NOT_CONFIGURED;
  159. m_pSnapin->AddServiceNodeToProfile(pNode);
  160. }
  161. m_pData->SetBase(0);
  162. }
  163. m_pData->SetStatus(SCE_STATUS_NOT_CONFIGURED);
  164. if ( m_pNewSD )
  165. {
  166. LocalFree(m_pNewSD);
  167. m_pNewSD = NULL;
  168. }
  169. }
  170. else
  171. {
  172. switch(m_nStartupRadio)
  173. {
  174. case 0:
  175. // Automatic
  176. dw = SCE_STARTUP_AUTOMATIC;
  177. break;
  178. case 1:
  179. // Manual
  180. dw = SCE_STARTUP_MANUAL;
  181. break;
  182. default:
  183. // DISABLED
  184. dw = SCE_STARTUP_DISABLED;
  185. break;
  186. }
  187. if ( NULL != pNode &&
  188. m_pData->GetBase() == m_pData->GetSetting() )
  189. {
  190. //
  191. // a matched item is changed to mismatch
  192. // needs to create a new node
  193. //
  194. m_pSnapin->SetupLinkServiceNodeToBase(FALSE, m_pData->GetBase());
  195. m_pData->SetBase(0);
  196. //
  197. // add to analysis profile
  198. //
  199. pNode->Status = SCE_STATUS_MISMATCH;
  200. m_pSnapin->AddServiceNodeToProfile(pNode);
  201. pNode = NULL;
  202. }
  203. PSCE_SERVICES pSetting = (PSCE_SERVICES)(m_pData->GetSetting());
  204. BYTE status = 0;
  205. if ( NULL == pNode )
  206. {
  207. //
  208. // a node is changed from not configured to configured
  209. // or from match to mismatch
  210. //
  211. pNode = CreateServiceNode(m_pData->GetUnits(),
  212. m_pData->GetAttr(),
  213. dw,
  214. m_pNewSD,
  215. m_NewSeInfo);
  216. if ( pNode != NULL )
  217. {
  218. //
  219. // add to the service list
  220. //
  221. m_pSnapin->SetupLinkServiceNodeToBase(TRUE, (LONG_PTR)pNode);
  222. m_pData->SetBase((LONG_PTR)pNode);
  223. if ( pSetting )
  224. {
  225. status = CompareServiceNode(pNode, pSetting);
  226. m_pData->SetStatus(status);
  227. }
  228. else
  229. {
  230. //
  231. // this is a new configured service
  232. // should create a "dump" analysis node to indictae
  233. // this service is not a "matched" item
  234. //
  235. pSetting = CreateServiceNode(m_pData->GetUnits(),
  236. m_pData->GetAttr(),
  237. 0,
  238. NULL,
  239. 0);
  240. if ( pSetting )
  241. {
  242. //
  243. // link it to analysis profile
  244. //
  245. pet = 0;//Raid #prefast
  246. PSCE_PROFILE_INFO pInfo=NULL;
  247. pet = m_pSnapin->GetTemplate(GT_LAST_INSPECTION, AREA_SYSTEM_SERVICE);
  248. if (NULL != pet )
  249. pInfo = pet->pTemplate;
  250. if ( pInfo )
  251. {
  252. pSetting->Status = SCE_STATUS_NOT_CONFIGURED;
  253. pSetting->Next = pInfo->pServices;
  254. pInfo->pServices = pSetting;
  255. m_pData->SetSetting( (LONG_PTR)pSetting);
  256. }
  257. else
  258. {
  259. //
  260. // free pSetting
  261. //
  262. LocalFree(pSetting->DisplayName);
  263. LocalFree(pSetting->ServiceName);
  264. LocalFree(pSetting);
  265. pSetting = NULL;
  266. }
  267. }
  268. m_pData->SetStatus(SCE_STATUS_NOT_CONFIGURED);
  269. }
  270. }
  271. else
  272. {
  273. //
  274. // no memory, error out
  275. //
  276. if ( m_pNewSD )
  277. {
  278. LocalFree(m_pNewSD);
  279. m_pNewSD = NULL;
  280. }
  281. }
  282. }
  283. else
  284. {
  285. //
  286. // an existing service
  287. //
  288. pNode->Startup = (BYTE)dw;
  289. if ( m_pNewSD != NULL )
  290. {
  291. if ( pNode->General.pSecurityDescriptor != m_pNewSD &&
  292. pNode->General.pSecurityDescriptor != NULL )
  293. {
  294. LocalFree(pNode->General.pSecurityDescriptor);
  295. }
  296. pNode->General.pSecurityDescriptor = m_pNewSD;
  297. m_pNewSD = NULL;
  298. pNode->SeInfo = m_NewSeInfo;
  299. }
  300. //
  301. // update status field in the analysis node
  302. //
  303. if ( pSetting )
  304. {
  305. status = CompareServiceNode(pNode, pSetting);
  306. m_pData->SetStatus(status);
  307. }
  308. else
  309. {
  310. // this is a new configured service
  311. m_pData->SetStatus(SCE_STATUS_NOT_CONFIGURED);
  312. }
  313. }
  314. }
  315. pet = m_pData->GetBaseProfile();
  316. if( NULL != pet ) //Raid #prefast
  317. {
  318. pet->SetDirty(AREA_SYSTEM_SERVICE);
  319. }
  320. m_pData->Update(m_pSnapin);
  321. m_NewSeInfo = 0;
  322. m_hwndParent = NULL;
  323. m_hwndShow = NULL;
  324. m_hwndChange = NULL;
  325. }
  326. return CAttribute::OnApply();
  327. }
  328. void CAnalysisService::OnCancel()
  329. {
  330. if ( m_pNewSD )
  331. {
  332. LocalFree(m_pNewSD);
  333. m_pNewSD = NULL;
  334. }
  335. m_NewSeInfo = 0;
  336. m_hwndParent = NULL;
  337. m_pAnalSD = NULL;
  338. m_hwndShow = NULL;
  339. m_hwndChange = NULL;
  340. CAttribute::OnCancel();
  341. }
  342. BOOL CAnalysisService::OnInitDialog()
  343. {
  344. CAttribute::OnInitDialog();
  345. if ( 0 == m_pData->GetSetting() ) {
  346. CButton *rb = (CButton *)GetDlgItem(IDC_CURRENTSD);
  347. rb->EnableWindow(FALSE);
  348. }
  349. AddUserControl(IDC_ENABLED);
  350. AddUserControl(IDC_DISABLED);
  351. AddUserControl(IDC_IGNORE);
  352. AddUserControl(IDC_BASESD);
  353. OnConfigure();
  354. return TRUE; // return TRUE unless you set the focus to a control
  355. // EXCEPTION: OCX Property Pages should return FALSE
  356. }
  357. void CAnalysisService::Initialize(CResult * pResult)
  358. {
  359. CAttribute::Initialize(pResult);
  360. //
  361. // initialize setting
  362. //
  363. m_pNewSD = NULL;
  364. m_NewSeInfo = 0;
  365. m_pAnalSD = NULL;
  366. //
  367. // Never start up with do not configure set. If they're coming
  368. // here it is probably to set a value
  369. //
  370. m_bConfigure = TRUE;
  371. if ( 0 != pResult->GetSetting() ) {
  372. PSCE_SERVICES pServSetting = (PSCE_SERVICES)(pResult->GetSetting());
  373. switch ( pServSetting->Startup ) {
  374. case SCE_STARTUP_AUTOMATIC:
  375. m_CurrentStr.LoadString(IDS_AUTOMATIC);
  376. break;
  377. case SCE_STARTUP_MANUAL:
  378. m_CurrentStr.LoadString(IDS_MANUAL);
  379. break;
  380. default: // disabled
  381. m_CurrentStr.LoadString(IDS_DISABLED);
  382. break;
  383. }
  384. m_pAnalSD = pServSetting->General.pSecurityDescriptor;
  385. }
  386. PSCE_SERVICES pService;
  387. pService = (PSCE_SERVICES)(pResult->GetBase());
  388. if ( NULL == pService ) {
  389. m_bConfigure = FALSE;
  390. pService = (PSCE_SERVICES)(pResult->GetSetting());
  391. }
  392. if ( pService != NULL ) {
  393. switch ( pService->Startup ) {
  394. case SCE_STARTUP_AUTOMATIC:
  395. m_nStartupRadio = 0;
  396. break;
  397. case SCE_STARTUP_MANUAL:
  398. m_nStartupRadio = 1;
  399. break;
  400. default: // disabled
  401. m_nStartupRadio = 2;
  402. break;
  403. }
  404. if ( pService->General.pSecurityDescriptor ) {
  405. MyMakeSelfRelativeSD(pService->General.pSecurityDescriptor,
  406. &m_pNewSD);
  407. }
  408. m_NewSeInfo = pService->SeInfo;
  409. }
  410. }
  411. void CAnalysisService::OnShowSecurity()
  412. {
  413. if ( IsWindow(m_hwndShow) ) {
  414. ::BringWindowToTop(m_hwndShow);
  415. return;
  416. }
  417. PSCE_SERVICES pService = (PSCE_SERVICES)(m_pData->GetSetting());
  418. SECURITY_INFORMATION SeInfo;
  419. if (pService)
  420. m_SecInfo = pService->SeInfo;
  421. // prepare the modeless property page data for the thread to create
  422. // the property sheet.
  423. if (NULL == m_pShowSec)
  424. {
  425. m_pShowSec = new CModelessSceEditor(false,
  426. ANALYSIS_SECURITY_PAGE_RO_NP,
  427. GetSafeHwnd(),
  428. SE_SERVICE,
  429. m_pData->GetAttr());
  430. }
  431. if (NULL != m_pShowSec)
  432. m_pShowSec->Create(&m_pAnalSD, &m_SecInfo, &m_hwndShow);
  433. }
  434. void CAnalysisService::OnConfigure()
  435. {
  436. CAttribute::OnConfigure();
  437. if (m_bConfigure && !m_pNewSD) {
  438. OnChangeSecurity();
  439. }
  440. else if (!m_bConfigure && IsWindow(m_hwndChange))
  441. {
  442. m_pEditSec->Destroy(m_hwndChange);
  443. m_hwndChange = NULL;
  444. }
  445. }
  446. void CAnalysisService::OnChangeSecurity()
  447. {
  448. if ( IsWindow(m_hwndChange) ) {
  449. ::BringWindowToTop(m_hwndChange);
  450. return;
  451. }
  452. if ( !m_pNewSD ) {
  453. GetDefaultServiceSecurity(&m_pNewSD,&m_NewSeInfo);
  454. }
  455. // if it comes to this point, the m_hwndChange must not be a valid Window
  456. // so the can ask to create a modeless dialog
  457. if (NULL == m_pEditSec)
  458. {
  459. m_pEditSec = new CModelessSceEditor(false,
  460. CONFIG_SECURITY_PAGE_NO_PROTECT,
  461. GetSafeHwnd(),
  462. SE_SERVICE,
  463. m_pData->GetAttr());
  464. }
  465. if (NULL != m_pEditSec)
  466. m_pEditSec->Create(&m_pNewSD, &m_NewSeInfo, &m_hwndChange);
  467. }
  468. //------------------------------------------------------------------
  469. // override to prevent the sheet from being destroyed when there is
  470. // child dialogs still up and running.
  471. //------------------------------------------------------------------
  472. BOOL CAnalysisService::OnQueryCancel()
  473. {
  474. if (::IsWindow(m_hwndChange) || ::IsWindow(m_hwndShow))
  475. {
  476. CString strMsg;
  477. strMsg.LoadString(IDS_CLOSESUBSHEET_BEFORE_APPLY);
  478. AfxMessageBox(strMsg);
  479. return FALSE;
  480. }
  481. else
  482. return TRUE;
  483. }