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.

738 lines
19 KiB

  1. ///////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright(C) 1997-1998 Microsoft Corporation all rights reserved.
  4. //
  5. // Module: sdocoremgr.cpp
  6. //
  7. // Project: Everest
  8. //
  9. // Description: IAS - Server Core Manager Implementation
  10. //
  11. // Log:
  12. //
  13. // When Who What
  14. // ---- --- ----
  15. // 6/08/98 TLP Initial Version
  16. //
  17. ///////////////////////////////////////////////////////////////////////////
  18. #include "stdafx.h"
  19. #include "sdocoremgr.h"
  20. #include "sdohelperfuncs.h"
  21. #include "sdocomponentfactory.h"
  22. #include "sdo.h"
  23. #include "sdoserviceias.h"
  24. /////////////////////////
  25. // Core manager retrieval
  26. CCoreMgr& GetCoreManager(void)
  27. {
  28. //////////////////////////////////////////////////////////////////////////
  29. static CCoreMgr theCoreManager; // The one and only core manager
  30. //////////////////////////////////////////////////////////////////////////
  31. return theCoreManager;
  32. }
  33. //////////////////////////////////////////////////////////////////////////////
  34. // IAS CORE MANAGER CLASS IMPLEMENTATION
  35. //
  36. // This class is responsible for managing the lifetimes of the components
  37. // that do "real" work. It also provides services to the class that
  38. // implements the ISdoService interface.
  39. //////////////////////////////////////////////////////////////////////////////
  40. //////////////////////////////////////////////////////////////////////////////
  41. // Constructor
  42. //////////////////////////////////////////////////////////////////////////////
  43. CCoreMgr::CCoreMgr()
  44. : m_eCoreState(CORE_STATE_SHUTDOWN)
  45. {
  46. }
  47. //////////////////////////////////////////////////////////////////////////////
  48. //
  49. // Function: CCoreMgr::StartService()
  50. //
  51. // Visibility: Public
  52. //
  53. // Inputs: eType: type of service to stop
  54. //
  55. // Outputs: S_OK - function succeeded - service started.
  56. // E_FAIL - function failed - service not started.
  57. //
  58. // Description: Starts a specified IAS service.
  59. //
  60. //////////////////////////////////////////////////////////////////////////////
  61. HRESULT CCoreMgr::StartService(SERVICE_TYPE eType)
  62. {
  63. HRESULT hr = S_OK;
  64. LONG lProtocolId;
  65. bool fUpdateConfiguration = true;
  66. do
  67. {
  68. // Initialize the core if we've not already done so...
  69. //
  70. if ( CORE_STATE_SHUTDOWN == m_eCoreState )
  71. {
  72. hr = InitializeComponents();
  73. if ( FAILED(hr) )
  74. break;
  75. // No need to update configuration (InitializeComponents() just did)
  76. //
  77. fUpdateConfiguration = false;
  78. }
  79. // Start the requested service if it ain't already started
  80. //
  81. if ( ! m_ServiceStatus.IsServiceStarted(eType) )
  82. {
  83. switch ( eType )
  84. {
  85. case SERVICE_TYPE_IAS:
  86. lProtocolId = IAS_PROTOCOL_MICROSOFT_RADIUS;
  87. break;
  88. case SERVICE_TYPE_RAS:
  89. lProtocolId = IAS_PROTOCOL_MICROSOFT_SURROGATE;
  90. break;
  91. default:
  92. // BAD! - tar and feather the caller
  93. //
  94. _ASSERT(FALSE);
  95. break;
  96. };
  97. hr = E_FAIL;
  98. // Brackets provide scope that ensures the protocol
  99. // handle is released before invoking ShutdownComponents().
  100. // This allows all protocols to be released in the
  101. // context of the ShutdownProtocols() function.
  102. {
  103. ComponentMapIterator iter = m_Protocols.find(lProtocolId);
  104. _ASSERT( iter != m_Protocols.end() );
  105. if ( iter != m_Protocols.end() )
  106. {
  107. // Update the service configuration if we're already
  108. // initialized and we're just resuming a protocol. We need
  109. // to do this because the service may be started in an
  110. // instance of svchost running another of our services.
  111. //
  112. // For example, RRAS is running automatically and then the
  113. // user configures IAS via the IAS UI and then starts the
  114. // IAS service. If the service starts in the instance of
  115. // svchost running RRAS then we need to update its
  116. // configuration.
  117. hr = S_OK;
  118. if ( fUpdateConfiguration )
  119. {
  120. hr = UpdateConfiguration();
  121. if ( FAILED(hr) )
  122. IASTracePrintf("IAS Core Manager was unable to configure service: %d...", eType);
  123. }
  124. if ( SUCCEEDED(hr) )
  125. {
  126. ComponentPtr pProtocol = (*iter).second;
  127. hr = pProtocol->Resume();
  128. }
  129. }
  130. }
  131. if ( SUCCEEDED(hr) )
  132. {
  133. m_ServiceStatus.SetServiceStatus(eType, IAS_SERVICE_STATUS_STARTED);
  134. // TODO: Log Service Started Event (IAS Only)
  135. IASTracePrintf("IAS Core Manager successfully started service %d...", eType);
  136. }
  137. else
  138. {
  139. // TODO: Log Service Failed Event (IAS Only)
  140. // This function did not succeed so shutdown the core if no
  141. // other services are started.
  142. //
  143. if ( ! m_ServiceStatus.IsAnyServiceStarted() )
  144. ShutdownComponents();
  145. }
  146. }
  147. } while ( FALSE );
  148. return hr;
  149. }
  150. //////////////////////////////////////////////////////////////////////////////
  151. //
  152. // Function: CCoreMgr::StopService()
  153. //
  154. // Visibility: Public
  155. //
  156. // Inputs: eType: type of service to stop
  157. //
  158. // Outputs: S_OK - function succeeded - service started.
  159. // E_FAIL - function failed - service not started.
  160. //
  161. // Description: Stops a specified IAS service.
  162. //
  163. //////////////////////////////////////////////////////////////////////////////
  164. HRESULT CCoreMgr::StopService(SERVICE_TYPE eType)
  165. {
  166. HRESULT hr = E_FAIL;
  167. LONG lProtocolId;
  168. do
  169. {
  170. switch ( eType )
  171. {
  172. case SERVICE_TYPE_IAS:
  173. lProtocolId = IAS_PROTOCOL_MICROSOFT_RADIUS;
  174. break;
  175. case SERVICE_TYPE_RAS:
  176. lProtocolId = IAS_PROTOCOL_MICROSOFT_SURROGATE;
  177. break;
  178. default:
  179. // BAD! - tar and feather the caller
  180. //
  181. _ASSERT(FALSE);
  182. break;
  183. };
  184. // Brackets provide scope that ensures the protocol
  185. // handle is released before invoking ShutdownComponents().
  186. // This allows all protocols to be released in the
  187. // context of the ShutdownProtocols() function.
  188. {
  189. ComponentMapIterator iter = m_Protocols.find(lProtocolId);
  190. if ( iter == m_Protocols.end() )
  191. break;
  192. ComponentPtr pProtocol = (*iter).second;
  193. hr = pProtocol->Suspend();
  194. if ( SUCCEEDED(hr) )
  195. IASTracePrintf("IAS Core Manager stopped service %d...", eType);
  196. }
  197. m_ServiceStatus.SetServiceStatus(eType, IAS_SERVICE_STATUS_STOPPED);
  198. // Shutdown the core if this was the last active service
  199. //
  200. if ( ! m_ServiceStatus.IsAnyServiceStarted() )
  201. ShutdownComponents();
  202. } while ( FALSE );
  203. return hr;
  204. }
  205. //////////////////////////////////////////////////////////////////////////////
  206. //
  207. // Function: CCoreMgr::UpdateConfiguration()
  208. //
  209. // Visibility: Public
  210. //
  211. // Inputs: None
  212. //
  213. // Outputs: S_OK - function succeeded - service started.
  214. // E_FAIL - function failed - service not started.
  215. //
  216. // Description: Used to update the configuration information used
  217. // by the core components.
  218. //
  219. //////////////////////////////////////////////////////////////////////////////
  220. HRESULT CCoreMgr::UpdateConfiguration()
  221. {
  222. HRESULT hr = E_FAIL;
  223. _ASSERT ( CORE_STATE_INITIALIZED == m_eCoreState );
  224. IASTracePrintf("IAS Core Manager is updating component configuration...");
  225. do
  226. {
  227. CComPtr<ISdoMachine> pSdoMachine;
  228. hr = CoCreateInstance(
  229. CLSID_SdoMachine,
  230. NULL,
  231. CLSCTX_INPROC_SERVER,
  232. IID_ISdoMachine,
  233. (void**)&pSdoMachine
  234. );
  235. if ( FAILED(hr) )
  236. break;
  237. IASTracePrintf("IAS Core Manager is attaching to the local machine...");
  238. hr = pSdoMachine->Attach(NULL);
  239. if ( FAILED(hr) )
  240. break;
  241. // Get the service SDO
  242. //
  243. CComPtr<IUnknown> pUnknown;
  244. hr = pSdoMachine->GetServiceSDO(GetDataStore(), IASServiceName, &pUnknown);
  245. if ( FAILED(hr) )
  246. break;
  247. CComPtr<CSdoServiceIAS> pSdoService;
  248. hr = pUnknown->QueryInterface(__uuidof(SdoService), (void**)&pSdoService);
  249. if ( FAILED(hr) )
  250. {
  251. IASTracePrintf("Error in Core Manager - InitializeComponents() - QueryInterface(ISdo) failed...");
  252. break;
  253. }
  254. hr = ConfigureAuditors(pSdoService);
  255. if ( FAILED(hr) )
  256. break;
  257. CComPtr<IDataStoreObject> dstore;
  258. pSdoService->getDataStoreObject(&dstore);
  259. hr = LinkHandlerProperties(pSdoService, dstore);
  260. if ( FAILED(hr) )
  261. break;
  262. hr = m_PipelineMgr.Configure(pSdoService);
  263. if ( FAILED(hr) )
  264. break;
  265. hr = ConfigureProtocols(pSdoService);
  266. if ( FAILED(hr) )
  267. break;
  268. } while ( FALSE );
  269. return hr;
  270. }
  271. //////////////////////////////////////////////////////////////////////////////
  272. // Core Manager Private Member Functions
  273. //////////////////////////////////////////////////////////////////////////////
  274. //////////////////////////////////////////////////////////////////////////////
  275. HRESULT CCoreMgr::InitializeComponents(void)
  276. {
  277. HRESULT hr;
  278. _ASSERT ( CORE_STATE_SHUTDOWN == m_eCoreState );
  279. do
  280. {
  281. IASTraceInitialize();
  282. IASTraceString("IAS Core Manager is initializing the IAS components...");
  283. IASInitialize();
  284. CComPtr<ISdoMachine> pSdoMachine;
  285. hr = CoCreateInstance(
  286. CLSID_SdoMachine,
  287. NULL,
  288. CLSCTX_INPROC_SERVER,
  289. IID_ISdoMachine,
  290. (void**)&pSdoMachine
  291. );
  292. if ( FAILED(hr) )
  293. break;
  294. IASTracePrintf("IAS Core Manager is attaching to the local machine...");
  295. hr = pSdoMachine->Attach(NULL);
  296. if ( FAILED(hr) )
  297. break;
  298. CComPtr<IUnknown> pUnknown;
  299. hr = pSdoMachine->GetServiceSDO(GetDataStore(), IASServiceName, &pUnknown);
  300. if ( FAILED(hr) )
  301. break;
  302. CComPtr<CSdoServiceIAS> pSdoService;
  303. hr = pUnknown->QueryInterface(__uuidof(SdoService), (void**)&pSdoService);
  304. if ( FAILED(hr) )
  305. {
  306. IASTracePrintf("Error in Core Manager - InitializeComponents() - QueryInterface(ISdo - Service) failed...");
  307. break;
  308. }
  309. hr = InitializeAuditors(pSdoService);
  310. if ( FAILED(hr) )
  311. break;
  312. CComPtr<IDataStoreObject> dstore;
  313. pSdoService->getDataStoreObject(&dstore);
  314. hr = LinkHandlerProperties(pSdoService, dstore);
  315. if ( FAILED(hr) )
  316. {
  317. ShutdownAuditors();
  318. break;
  319. }
  320. hr = m_PipelineMgr.Initialize(pSdoService);
  321. if ( FAILED(hr) )
  322. {
  323. ShutdownAuditors();
  324. break;
  325. }
  326. hr = InitializeProtocols(pSdoService);
  327. if ( FAILED(hr) )
  328. {
  329. m_PipelineMgr.Shutdown();
  330. ShutdownAuditors();
  331. break;
  332. }
  333. m_eCoreState = CORE_STATE_INITIALIZED;
  334. } while (FALSE);
  335. if ( FAILED(hr) )
  336. {
  337. IASUninitialize();
  338. IASTraceUninitialize();
  339. }
  340. return hr;
  341. }
  342. //////////////////////////////////////////////////////////////////////////////
  343. void CCoreMgr::ShutdownComponents(void)
  344. {
  345. _ASSERT ( CORE_STATE_INITIALIZED == m_eCoreState );
  346. IASTracePrintf("IAS Core Manager is shutting down the IAS components...");
  347. ShutdownProtocols();
  348. m_PipelineMgr.Shutdown();
  349. ShutdownAuditors();
  350. IASUninitialize();
  351. IASTraceUninitialize();
  352. m_eCoreState = CORE_STATE_SHUTDOWN;
  353. }
  354. //////////////////////////////////////////////////////////////////////////////
  355. IASDATASTORE CCoreMgr::GetDataStore()
  356. {
  357. CRegKey IASKey;
  358. LONG lResult = IASKey.Open( HKEY_LOCAL_MACHINE, IAS_POLICY_REG_KEY, KEY_READ );
  359. if ( lResult == ERROR_SUCCESS )
  360. {
  361. DWORD dwValue;
  362. lResult = IASKey.QueryValue( dwValue, (LPCTSTR)IAS_DATASTORE_TYPE );
  363. if ( lResult == ERROR_SUCCESS )
  364. return (IASDATASTORE)dwValue;
  365. }
  366. return DATA_STORE_LOCAL;
  367. }
  368. //////////////////////////////////////////////////////////////////////////////
  369. HRESULT CCoreMgr::InitializeAuditors(ISdo* pSdoService)
  370. {
  371. HRESULT hr;
  372. LONG lComponentId;
  373. CComPtr<IEnumVARIANT> pEnumAuditors;
  374. CComPtr<ISdo> pSdoAuditor;
  375. // Note about state: When this function completes, either all of the
  376. // auditors are initialized or none of the auditors are initialized
  377. IASTracePrintf("IAS Core Manager is initializing the auditors...");
  378. try
  379. {
  380. do
  381. {
  382. hr = ::SDOGetCollectionEnumerator(pSdoService, PROPERTY_IAS_AUDITORS_COLLECTION, &pEnumAuditors);
  383. if ( FAILED(hr) )
  384. break;
  385. hr = ::SDONextObjectFromCollection(pEnumAuditors, &pSdoAuditor);
  386. while ( S_OK == hr )
  387. {
  388. hr = ::SDOGetComponentIdFromObject(pSdoAuditor, &lComponentId);
  389. if ( FAILED(hr) )
  390. break;
  391. {
  392. ComponentPtr pAuditor = ::MakeComponent(COMPONENT_TYPE_AUDITOR, lComponentId);
  393. if ( ! pAuditor.IsValid() )
  394. {
  395. hr = E_FAIL;
  396. break;
  397. }
  398. hr = pAuditor->Initialize(pSdoAuditor);
  399. if ( FAILED(hr) )
  400. break;
  401. if ( ! AddComponent(lComponentId, pAuditor, m_Auditors) )
  402. {
  403. hr = E_FAIL;
  404. break;
  405. }
  406. }
  407. pSdoAuditor.Release();
  408. hr = ::SDONextObjectFromCollection(pEnumAuditors, &pSdoAuditor);
  409. }
  410. if ( S_FALSE == hr )
  411. hr = S_OK;
  412. } while ( FALSE );
  413. }
  414. catch(...)
  415. {
  416. IASTracePrintf("Error in IAS Core Manager - InitializeAuditors() - Caught unknown exception...");
  417. hr = E_FAIL;
  418. }
  419. if ( FAILED(hr) )
  420. {
  421. IASTracePrintf("Error in IAS Core Manager - InitializeAuditors() - Could not initialize the auditors...");
  422. ShutdownAuditors();
  423. }
  424. return hr;
  425. }
  426. //////////////////////////////////////////////////////////////////////////////
  427. HRESULT CCoreMgr::ConfigureAuditors(ISdo* pSdoService)
  428. {
  429. HRESULT hr = S_OK;
  430. IASTracePrintf("IAS Core Manager is configuring the auditors...");
  431. try
  432. {
  433. // Try to update the configuration settings for each request handler. We
  434. // assume that auditors are autonomous with respect to configuration
  435. // and if one fails to configure we'll continue to try to configure the others
  436. //
  437. ComponentMapIterator iter = m_Auditors.begin();
  438. while ( iter != m_Auditors.end() )
  439. {
  440. CComPtr <ISdo> pSdoComponent;
  441. ComponentPtr pAuditor = (*iter).second;
  442. // get the component from the collection
  443. hr = ::SDOGetComponentFromCollection (pSdoService, PROPERTY_IAS_AUDITORS_COLLECTION, pAuditor->GetId (), &pSdoComponent);
  444. if (SUCCEEDED (hr))
  445. {
  446. hr = pAuditor->Configure(pSdoComponent);
  447. if ( FAILED(hr) )
  448. {
  449. IASTracePrintf("IAS Core Manager - ConfigureAuditors() - Auditor %d could not be configured...", pAuditor->GetId());
  450. hr = S_OK;
  451. }
  452. }
  453. else
  454. {
  455. IASTracePrintf("IAS Core Manager - ConfigureAuditors() - unable to get component from collection in auditor %d...", pAuditor->GetId());
  456. hr = S_OK;
  457. }
  458. iter++;
  459. }
  460. }
  461. catch(...)
  462. {
  463. IASTracePrintf("Error in IAS Core Manager - ConfigureAuditors() - Caught unknown exception...");
  464. hr = E_FAIL;
  465. }
  466. return hr;
  467. }
  468. //////////////////////////////////////////////////////////////////////////////
  469. void CCoreMgr::ShutdownAuditors(void)
  470. {
  471. IASTracePrintf("IAS Core Manager is shutting down the auditors...");
  472. try
  473. {
  474. ComponentMapIterator iter = m_Auditors.begin();
  475. while ( iter != m_Auditors.end() )
  476. {
  477. ComponentPtr pAuditor = (*iter).second;
  478. pAuditor->Suspend();
  479. pAuditor->Shutdown();
  480. iter = m_Auditors.erase(iter);
  481. }
  482. }
  483. catch(...)
  484. {
  485. IASTracePrintf("Error in IAS Core Manager - ShutdownAuditors() - Caught unknown exception...");
  486. }
  487. }
  488. //////////////////////////////////////////////////////////////////////////////
  489. HRESULT CCoreMgr::InitializeProtocols(ISdo* pSdoService)
  490. {
  491. HRESULT hr = E_FAIL;
  492. IASTracePrintf("IAS Core Manager is initializing the protocols...");
  493. // Note about state: When this function completes, either all of the
  494. // protocols are initialized or none of the protocols are initialized
  495. try
  496. {
  497. do
  498. {
  499. CComPtr<IRequestHandler> pRequestHandler;
  500. m_PipelineMgr.GetPipeline(&pRequestHandler);
  501. CComPtr<IEnumVARIANT> pEnumProtocols;
  502. hr = ::SDOGetCollectionEnumerator(pSdoService, PROPERTY_IAS_PROTOCOLS_COLLECTION, &pEnumProtocols);
  503. if ( FAILED(hr) )
  504. break;
  505. LONG lComponentId;
  506. CComPtr<ISdo> pSdoProtocol;
  507. hr = ::SDONextObjectFromCollection(pEnumProtocols, &pSdoProtocol);
  508. while ( S_OK == hr )
  509. {
  510. hr = ::SDOGetComponentIdFromObject(pSdoProtocol, &lComponentId);
  511. if ( FAILED(hr) )
  512. break;
  513. {
  514. ComponentPtr pProtocol = ::MakeComponent(COMPONENT_TYPE_PROTOCOL, lComponentId);
  515. if ( ! pProtocol.IsValid() )
  516. {
  517. hr = E_FAIL;
  518. break;
  519. }
  520. // Don't treat protocol initialization as a critical failure
  521. //
  522. hr = pProtocol->Initialize(pSdoProtocol);
  523. if ( SUCCEEDED(hr) )
  524. {
  525. hr = pProtocol->PutObject(pRequestHandler, IID_IRequestHandler);
  526. if ( FAILED(hr) )
  527. break;
  528. hr = pProtocol->Suspend();
  529. if ( FAILED(hr) )
  530. break;
  531. if ( ! AddComponent(lComponentId, pProtocol, m_Protocols) )
  532. {
  533. hr = E_FAIL;
  534. break;
  535. }
  536. }
  537. pSdoProtocol.Release();
  538. }
  539. hr = ::SDONextObjectFromCollection(pEnumProtocols, &pSdoProtocol);
  540. }
  541. if ( S_FALSE == hr )
  542. hr = S_OK;
  543. } while ( FALSE );
  544. }
  545. catch(...)
  546. {
  547. IASTracePrintf("Error in IAS Core Manager - InitializeProtocols() - Caught unknown exception...");
  548. hr = E_FAIL;
  549. }
  550. if ( FAILED(hr) )
  551. {
  552. IASTracePrintf("Error in IAS Core Manager - InitializeProtocols() - Could not initialize the protocols...");
  553. ShutdownProtocols();
  554. }
  555. return hr;
  556. }
  557. //////////////////////////////////////////////////////////////////////////////
  558. HRESULT CCoreMgr::ConfigureProtocols(ISdo* pSdoService)
  559. {
  560. HRESULT hr = S_OK;
  561. IASTracePrintf("IAS Core Manager is configuring the protocols...");
  562. // Try to update the configuration settings for each protocol
  563. // Note we assume the request handler used by a protocol is not
  564. // dynamically configurable!
  565. //
  566. try
  567. {
  568. ComponentMapIterator iter = m_Protocols.begin();
  569. while ( iter != m_Protocols.end() )
  570. {
  571. CComPtr<ISdo> pSdoComponent;
  572. ComponentPtr pProtocol = (*iter).second;
  573. // get the protocol collection
  574. hr = ::SDOGetComponentFromCollection (pSdoService, PROPERTY_IAS_PROTOCOLS_COLLECTION, pProtocol->GetId (), &pSdoComponent);
  575. if (SUCCEEDED (hr))
  576. {
  577. hr = pProtocol->Configure(pSdoComponent);
  578. if ( FAILED(hr) )
  579. {
  580. IASTracePrintf("IAS Core Manager - ConfigureProtocols() - Protocol %d could not be configured...", pProtocol->GetId());
  581. hr = S_OK;
  582. }
  583. }
  584. else
  585. {
  586. IASTracePrintf("IAS Core Manager - ConfigureProtocols() - unnable to get component from collection for protocol %d...", pProtocol->GetId());
  587. hr = S_OK;
  588. }
  589. iter++;
  590. }
  591. }
  592. catch(...)
  593. {
  594. IASTracePrintf("Error in IAS Core Manager - ConfigureProtocols() - Caught unknown exception...");
  595. hr = E_FAIL;
  596. }
  597. return hr;
  598. }
  599. //////////////////////////////////////////////////////////////////////////////
  600. void CCoreMgr::ShutdownProtocols(void)
  601. {
  602. IASTracePrintf("IAS Core Manager is shutting down the protocols...");
  603. try
  604. {
  605. ComponentMapIterator iter = m_Protocols.begin();
  606. while ( iter != m_Protocols.end() )
  607. {
  608. ComponentPtr pProtocol = (*iter).second;
  609. // We only initialize a protocol when its associated
  610. // service (IAS or RAS currently) is started.
  611. if ( COMPONENT_STATE_INITIALIZED == pProtocol->GetState() )
  612. pProtocol->Suspend();
  613. pProtocol->Shutdown();
  614. iter = m_Protocols.erase(iter);
  615. }
  616. }
  617. catch(...)
  618. {
  619. IASTracePrintf("Error in IAS Core Manager - ShutdownProtocols() - Caught unknown exception...");
  620. }
  621. }