Leaked source code of windows server 2003

842 lines
22 KiB

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. ipsecspd.c
  5. Abstract:
  6. This module contains all of the code to drive
  7. the IPSecSPD Service.
  8. Author:
  9. abhisheV 30-September-1999
  10. Environment
  11. User Level: Win32
  12. Revision History:
  13. --*/
  14. #include "precomp.h"
  15. #ifdef TRACE_ON
  16. #include "ipsecspd.tmh"
  17. #endif
  18. SERVICE_STATUS IPSecSPDStatus;
  19. SERVICE_STATUS_HANDLE IPSecSPDStatusHandle = NULL;
  20. #define IPSECSPD_SERVICE L"PolicyAgent"
  21. void WINAPI
  22. SPDServiceMain(
  23. IN DWORD dwArgc,
  24. IN LPTSTR * lpszArgv
  25. )
  26. {
  27. DWORD dwError = 0;
  28. DWORD dwTempError = 0;
  29. WPP_INIT_TRACING(SPD_WPP_APPNAME);
  30. // Sleep(30000);
  31. InitMiscGlobals();
  32. dwError = InitAuditing();
  33. BAIL_ON_WIN32_ERROR(dwError);
  34. InitSPDThruRegistry();
  35. //
  36. // Open the IPSec Driver first, so that if we bail on error later,
  37. // we can still set driver in block mode.
  38. //
  39. dwError = SPDOpenIPSecDriver(
  40. &ghIPSecDriver
  41. );
  42. if (dwError) {
  43. AuditOneArgErrorEvent(
  44. SE_CATEGID_POLICY_CHANGE,
  45. SE_AUDITID_IPSEC_POLICY_CHANGED,
  46. IPSECSVC_DRIVER_INIT_FAILURE,
  47. dwError,
  48. FALSE,
  49. TRUE
  50. );
  51. }
  52. BAIL_ON_WIN32_ERROR(dwError);
  53. // Initialize all the status fields so that the subsequent calls
  54. // to SetServiceStatus need to only update fields that changed.
  55. IPSecSPDStatus.dwServiceType = SERVICE_WIN32_SHARE_PROCESS;
  56. IPSecSPDStatus.dwCurrentState = SERVICE_START_PENDING;
  57. IPSecSPDStatus.dwControlsAccepted = 0;
  58. IPSecSPDStatus.dwCheckPoint = 1;
  59. IPSecSPDStatus.dwWaitHint = 5000;
  60. IPSecSPDStatus.dwWin32ExitCode = NO_ERROR;
  61. IPSecSPDStatus.dwServiceSpecificExitCode = 0;
  62. // Initialize the workstation to receive service requests
  63. // by registering the service control handler.
  64. IPSecSPDStatusHandle = RegisterServiceCtrlHandlerExW(
  65. IPSECSPD_SERVICE,
  66. IPSecSPDControlHandler,
  67. NULL
  68. );
  69. if (IPSecSPDStatusHandle == (SERVICE_STATUS_HANDLE) NULL) {
  70. dwError = ERROR_INVALID_HANDLE;
  71. BAIL_ON_WIN32_ERROR(dwError);
  72. }
  73. (void) IPSecSPDUpdateStatus();
  74. dwError = InitSPDGlobals();
  75. BAIL_ON_WIN32_ERROR(dwError);
  76. IPSecSPDStatus.dwCurrentState = SERVICE_RUNNING;
  77. IPSecSPDStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP |
  78. SERVICE_ACCEPT_SHUTDOWN |
  79. SERVICE_ACCEPT_POWEREVENT;
  80. IPSecSPDStatus.dwCheckPoint = 0;
  81. IPSecSPDStatus.dwWaitHint = 0;
  82. IPSecSPDStatus.dwWin32ExitCode = NO_ERROR;
  83. IPSecSPDStatus.dwServiceSpecificExitCode = 0;
  84. (void) IPSecSPDUpdateStatus();
  85. //
  86. // Get the current list of active interfaces on the machine.
  87. //
  88. (VOID) CreateInterfaceList(
  89. &gpInterfaceList
  90. );
  91. //
  92. // Get a list of DNS, DHCP, etc servers.
  93. //
  94. (VOID) GetSpecialAddrsList(
  95. &gpSpecialAddrsList
  96. );
  97. gpIpsecPolicyState->PersIncarnationNumber = 0;
  98. dwError = LoadPersistedIPSecInformation();
  99. BAIL_ON_WIN32_ERROR(dwError);
  100. dwError = SPDSetIPSecDriverOpMode(
  101. (DWORD) IPSEC_SECURE_MODE
  102. );
  103. if (dwError) {
  104. AuditOneArgErrorEvent(
  105. SE_CATEGID_POLICY_CHANGE,
  106. SE_AUDITID_IPSEC_POLICY_CHANGED,
  107. IPSECSVC_DRIVER_INIT_FAILURE,
  108. dwError,
  109. FALSE,
  110. TRUE
  111. );
  112. }
  113. BAIL_ON_WIN32_ERROR(dwError);
  114. dwError = SPDRegisterIPSecDriverProtocols(
  115. (DWORD) IPSEC_REGISTER_PROTOCOLS
  116. );
  117. if (dwError) {
  118. AuditOneArgErrorEvent(
  119. SE_CATEGID_POLICY_CHANGE,
  120. SE_AUDITID_IPSEC_POLICY_CHANGED,
  121. IPSECSVC_DRIVER_INIT_FAILURE,
  122. dwError,
  123. FALSE,
  124. TRUE
  125. );
  126. }
  127. BAIL_ON_WIN32_ERROR(dwError);
  128. //
  129. // Start IKE Service.
  130. //
  131. dwError = IKEInit();
  132. if (dwError) {
  133. AuditOneArgErrorEvent(
  134. SE_CATEGID_POLICY_CHANGE,
  135. SE_AUDITID_IPSEC_POLICY_CHANGED,
  136. IPSECSVC_IKE_INIT_FAILURE,
  137. dwError,
  138. FALSE,
  139. TRUE
  140. );
  141. TRACE(TRC_ERROR, (L"Failed to initialize IKE: %!winerr!", dwError));
  142. }
  143. BAIL_ON_WIN32_ERROR(dwError);
  144. gbIsIKEUp = TRUE;
  145. gbIKENotify = TRUE;
  146. //
  147. // Start the RPC Server.
  148. //
  149. dwError = SPDStartRPCServer(
  150. );
  151. if (dwError) {
  152. AuditOneArgErrorEvent(
  153. SE_CATEGID_POLICY_CHANGE,
  154. SE_AUDITID_IPSEC_POLICY_CHANGED,
  155. IPSECSVC_RPC_INIT_FAILURE,
  156. dwError,
  157. FALSE,
  158. TRUE
  159. );
  160. TRACE(TRC_ERROR, (L"Failed to start RPC server: %!winerr!", dwError));
  161. }
  162. BAIL_ON_WIN32_ERROR(dwError);
  163. dwError = ServiceWait();
  164. error:
  165. #ifdef TRACE_ON
  166. if (dwError) {
  167. TRACE(TRC_ERROR, (L"Failed to start IPSec PolicyAgent: %!winerr!", dwError));
  168. }
  169. #endif
  170. if (dwError && ghIPSecDriver != INVALID_HANDLE_VALUE) {
  171. dwTempError = SPDSetIPSecDriverOpMode(
  172. (DWORD) IPSEC_BLOCK_MODE
  173. );
  174. if (gbAuditingInitialized) {
  175. AuditOneArgErrorEvent(
  176. SE_CATEGID_POLICY_CHANGE,
  177. SE_AUDITID_IPSEC_POLICY_CHANGED,
  178. IPSECSVC_SET_DRIVER_BLOCK,
  179. dwError,
  180. FALSE,
  181. TRUE
  182. );
  183. }
  184. }
  185. IPSecSPDShutdown(dwError);
  186. return;
  187. }
  188. DWORD
  189. IPSecSPDUpdateStatus(
  190. )
  191. {
  192. DWORD dwError = 0;
  193. if (!SetServiceStatus(IPSecSPDStatusHandle, &IPSecSPDStatus)) {
  194. dwError = GetLastError();
  195. }
  196. return (dwError);
  197. }
  198. DWORD
  199. IPSecSPDControlHandler(
  200. IN DWORD dwOpCode,
  201. IN DWORD dwEventType,
  202. IN LPVOID lpEventData,
  203. IN LPVOID lpContext
  204. )
  205. {
  206. DWORD dwErr = ERROR_SUCCESS;
  207. switch (dwOpCode)
  208. {
  209. case SERVICE_CONTROL_STOP:
  210. case SERVICE_CONTROL_SHUTDOWN:
  211. if (dwOpCode == SERVICE_CONTROL_SHUTDOWN) {
  212. gdwShutdownFlags = SPD_SHUTDOWN_MACHINE;
  213. } else {
  214. gdwShutdownFlags = SPD_SHUTDOWN_SERVICE;
  215. }
  216. if (IPSecSPDStatus.dwCurrentState != SERVICE_STOP_PENDING) {
  217. IPSecSPDStatus.dwCurrentState = SERVICE_STOP_PENDING;
  218. IPSecSPDStatus.dwCheckPoint = 1;
  219. IPSecSPDStatus.dwWaitHint = 60000;
  220. (void) IPSecSPDUpdateStatus();
  221. SetEvent(ghServiceStopEvent);
  222. return dwErr;
  223. }
  224. break;
  225. case SERVICE_CONTROL_NEW_LOCAL_POLICY:
  226. SetEvent(ghNewLocalPolicyEvent);
  227. break;
  228. case SERVICE_CONTROL_FORCED_POLICY_RELOAD:
  229. SetEvent(ghForcedPolicyReloadEvent);
  230. break;
  231. case SERVICE_CONTROL_INTERROGATE:
  232. break;
  233. case SERVICE_CONTROL_POWEREVENT:
  234. switch ( dwEventType ) {
  235. case PBT_APMRESUMEAUTOMATIC:
  236. case PBT_APMRESUMECRITICAL:
  237. case PBT_APMRESUMESUSPEND:
  238. // Notify IKE of power event, ignore error
  239. if (gbIKENotify) {
  240. IKENotifyPolicyChange(NULL,POLICY_GUID_POWEREVENT_RESUME);
  241. }
  242. break;
  243. default:
  244. break;
  245. }
  246. }
  247. (void) IPSecSPDUpdateStatus();
  248. return (dwErr);
  249. }
  250. VOID
  251. IPSecSPDShutdown(
  252. IN DWORD dwErrorCode
  253. )
  254. {
  255. BOOL bMachineShutdown = FALSE;
  256. TRACE(TRC_INFORMATION, (L"PolicyAgent shutting down."));
  257. bMachineShutdown = gdwShutdownFlags & SPD_SHUTDOWN_MACHINE;
  258. gbIKENotify = FALSE;
  259. (VOID) DeleteAllPolicyInformation();
  260. ClearPolicyStateBlock(
  261. gpIpsecPolicyState
  262. );
  263. if (gbLoadedISAKMPDefaults) {
  264. UnLoadDefaultISAKMPInformation(gpszDefaultISAKMPPolicyDN);
  265. }
  266. ClearPAStoreGlobals();
  267. //
  268. // Service stop still pending.
  269. // Increment checkpoint counter and update
  270. // the status with the Service Control Manager.
  271. //
  272. (IPSecSPDStatus.dwCheckPoint)++;
  273. (void) IPSecSPDUpdateStatus();
  274. if (gbSPDRPCServerUp) {
  275. gbSPDRPCServerUp = FALSE;
  276. SPDStopRPCServer();
  277. }
  278. if (gbIsIKEUp) {
  279. gbIsIKEUp = FALSE;
  280. if (bMachineShutdown) {
  281. IKEShutdown(SPD_SHUTDOWN_MACHINE);
  282. } else {
  283. IKEShutdown(SPD_SHUTDOWN_SERVICE);
  284. }
  285. }
  286. if (gpIniMMPolicy) {
  287. FreeIniMMPolicyList(gpIniMMPolicy);
  288. gpIniMMPolicy = NULL;
  289. }
  290. if (gpIniMMAuthMethods) {
  291. FreeIniMMAuthMethodsList(gpIniMMAuthMethods);
  292. gpIniMMAuthMethods = NULL;
  293. }
  294. if (gpIniQMPolicy) {
  295. FreeIniQMPolicyList(gpIniQMPolicy);
  296. gpIniQMPolicy = NULL;
  297. }
  298. if (gpIniMMSFilter) {
  299. FreeIniMMSFilterList(gpIniMMSFilter);
  300. gpIniMMSFilter = NULL;
  301. }
  302. if (gpMMFilterHandle) {
  303. FreeMMFilterHandleList(gpMMFilterHandle);
  304. gpMMFilterHandle = NULL;
  305. }
  306. if (gpIniMMFilter) {
  307. FreeIniMMFilterList(gpIniMMFilter);
  308. gpIniMMFilter = NULL;
  309. }
  310. if (gpIniTxSFilter) {
  311. // Following call will check gShutdownFlags and
  312. // not delete ipsec filters if shutting down machine
  313. (VOID) DeleteTransportFiltersFromIPSec(gpIniTxSFilter);
  314. FreeIniTxSFilterList(gpIniTxSFilter);
  315. gpIniTxSFilter = NULL;
  316. }
  317. if (gpTxFilterHandle) {
  318. FreeTxFilterHandleList(gpTxFilterHandle);
  319. gpTxFilterHandle = NULL;
  320. }
  321. if (gpIniTxFilter) {
  322. FreeIniTxFilterList(gpIniTxFilter);
  323. gpIniTxFilter = NULL;
  324. }
  325. if (gpIniTnSFilter) {
  326. // Following call will check gShutdownFlags and
  327. // not delete ipsec filters if shutting down machine
  328. (VOID) DeleteTunnelFiltersFromIPSec(gpIniTnSFilter);
  329. FreeIniTnSFilterList(gpIniTnSFilter);
  330. gpIniTnSFilter = NULL;
  331. }
  332. if (gpTnFilterHandle) {
  333. FreeTnFilterHandleList(gpTnFilterHandle);
  334. gpTnFilterHandle = NULL;
  335. }
  336. if (gpIniTnFilter) {
  337. FreeIniTnFilterList(gpIniTnFilter);
  338. gpIniTnFilter = NULL;
  339. }
  340. if (!bMachineShutdown) {
  341. (VOID) SPDRegisterIPSecDriverProtocols(
  342. (DWORD) IPSEC_DEREGISTER_PROTOCOLS
  343. );
  344. }
  345. if (ghIPSecDriver != INVALID_HANDLE_VALUE) {
  346. SPDCloseIPSecDriver(ghIPSecDriver);
  347. ghIPSecDriver = INVALID_HANDLE_VALUE;
  348. }
  349. if (gpInterfaceList) {
  350. DestroyInterfaceList(
  351. gpInterfaceList
  352. );
  353. gpInterfaceList = NULL;
  354. }
  355. if (gpSpecialAddrsList) {
  356. FreeSpecialAddrList(
  357. &gpSpecialAddrsList
  358. );
  359. gpSpecialAddrsList = NULL;
  360. }
  361. ClearSPDGlobals();
  362. IPSecSPDStatus.dwCurrentState = SERVICE_STOPPED;
  363. IPSecSPDStatus.dwControlsAccepted = 0;
  364. IPSecSPDStatus.dwCheckPoint = 0;
  365. IPSecSPDStatus.dwWaitHint = 0;
  366. IPSecSPDStatus.dwWin32ExitCode = dwErrorCode;
  367. IPSecSPDStatus.dwServiceSpecificExitCode = 0;
  368. (void) IPSecSPDUpdateStatus();
  369. WPP_CLEANUP();
  370. return;
  371. }
  372. VOID
  373. ClearSPDGlobals(
  374. )
  375. {
  376. DestroyInterfaceChangeEvent();
  377. if (gbSPDSection) {
  378. DeleteCriticalSection(&gcSPDSection);
  379. }
  380. if (gbServerListenSection == TRUE) {
  381. DeleteCriticalSection(&gcServerListenSection);
  382. }
  383. if (ghServiceStopEvent) {
  384. CloseHandle(ghServiceStopEvent);
  385. ghServiceStopEvent = NULL;
  386. }
  387. if (ghNewDSPolicyEvent) {
  388. CloseHandle(ghNewDSPolicyEvent);
  389. ghNewDSPolicyEvent = NULL;
  390. }
  391. if (ghNewLocalPolicyEvent) {
  392. CloseHandle(ghNewLocalPolicyEvent);
  393. ghNewLocalPolicyEvent = NULL;
  394. }
  395. if (ghForcedPolicyReloadEvent) {
  396. CloseHandle(ghForcedPolicyReloadEvent);
  397. ghForcedPolicyReloadEvent = NULL;
  398. }
  399. if (ghPolicyChangeNotifyEvent) {
  400. CloseHandle(ghPolicyChangeNotifyEvent);
  401. ghPolicyChangeNotifyEvent = NULL;
  402. }
  403. if (ghGpupdateRefreshEvent) {
  404. CloseHandle(ghGpupdateRefreshEvent);
  405. ghGpupdateRefreshEvent = NULL;
  406. }
  407. if (gbSPDAuditSection) {
  408. DeleteCriticalSection(&gcSPDAuditSection);
  409. }
  410. gbAuditingInitialized = FALSE;
  411. if (gpSPDSD) {
  412. LocalFree(gpSPDSD);
  413. gpSPDSD = NULL;
  414. }
  415. }
  416. VOID
  417. ClearPAStoreGlobals(
  418. )
  419. {
  420. if (gpMMFilterState) {
  421. PAFreeMMFilterStateList(gpMMFilterState);
  422. gpMMFilterState = NULL;
  423. }
  424. if (gpMMPolicyState) {
  425. PAFreeMMPolicyStateList(gpMMPolicyState);
  426. gpMMPolicyState = NULL;
  427. }
  428. if (gpMMAuthState) {
  429. PAFreeMMAuthStateList(gpMMAuthState);
  430. gpMMAuthState = NULL;
  431. }
  432. if (gpTxFilterState) {
  433. PAFreeTxFilterStateList(gpTxFilterState);
  434. gpTxFilterState = NULL;
  435. }
  436. if (gpTnFilterState) {
  437. PAFreeTnFilterStateList(gpTnFilterState);
  438. gpTnFilterState = NULL;
  439. }
  440. if (gpQMPolicyState) {
  441. PAFreeQMPolicyStateList(gpQMPolicyState);
  442. gpQMPolicyState = NULL;
  443. }
  444. }
  445. VOID
  446. InitMiscGlobals(
  447. )
  448. {
  449. //
  450. // Init globals that aren't cleared on service stop to make sure
  451. // everything's in a known state on start. This allows us to
  452. // stop/restart without having our DLL unloaded/reloaded first.
  453. //
  454. gbSPDRPCServerUp = FALSE;
  455. ghServiceStopEvent = NULL;
  456. gdwServersListening = 0;
  457. gbServerListenSection = FALSE;
  458. gpInterfaceList = NULL;
  459. gpSpecialAddrsList = NULL;
  460. gbwsaStarted = FALSE;
  461. gIfChangeEventSocket = INVALID_SOCKET;
  462. ghIfChangeEvent = NULL;
  463. ghOverlapEvent = NULL;
  464. gpIniTxFilter = NULL;
  465. gpIniTxSFilter = NULL;
  466. gpTxFilterHandle = NULL;
  467. gbSPDSection = FALSE;
  468. gpIniQMPolicy = NULL;
  469. gpIniDefaultQMPolicy = NULL;
  470. gpIniMMPolicy = NULL;
  471. gpIniDefaultMMPolicy = NULL;
  472. gpIniMMFilter = NULL;
  473. gpIniMMSFilter = NULL;
  474. gpMMFilterHandle = NULL;
  475. gpIniMMAuthMethods = NULL;
  476. gpIniDefaultMMAuthMethods = NULL;
  477. gpIpsecPolicyState = &gIpsecPolicyState;
  478. gCurrentPollingInterval = 0;
  479. gDefaultPollingInterval = 166*60; // (seconds).
  480. gdwRetryCount = 0;
  481. gpszIpsecDSPolicyKey = L"SOFTWARE\\Policies\\Microsoft\\Windows\\IPSec\\GPTIPSECPolicy";
  482. gpszIpsecLocalPolicyKey = L"SOFTWARE\\Policies\\Microsoft\\Windows\\IPSec\\Policy\\Local";
  483. gpszIpsecPersistentPolicyKey = L"SOFTWARE\\Policies\\Microsoft\\Windows\\IPSec\\Policy\\Persistent";
  484. gpszIpsecCachePolicyKey = L"SOFTWARE\\Policies\\Microsoft\\Windows\\IPSec\\Policy\\Cache";
  485. gpszDefaultISAKMPPolicyDN = L"SOFTWARE\\Policies\\Microsoft\\Windows\\IPSec\\Policy\\Local\\ipsecISAKMPPolicy{72385234-70FA-11D1-864C-14A300000000}";
  486. gpszLocPolicyAgent = L"SYSTEM\\CurrentControlSet\\Services\\PolicyAgent";
  487. ghNewDSPolicyEvent = NULL;
  488. ghNewLocalPolicyEvent = NULL;
  489. ghForcedPolicyReloadEvent = NULL;
  490. ghPolicyChangeNotifyEvent = NULL;
  491. ghGpupdateRefreshEvent = NULL;
  492. gbLoadedISAKMPDefaults = FALSE;
  493. gpMMPolicyState = NULL;
  494. gpMMAuthState = NULL;
  495. gpMMFilterState = NULL;
  496. gdwMMPolicyCounter = 0;
  497. gdwMMFilterCounter = 0;
  498. gpQMPolicyState = NULL;
  499. gdwQMPolicyCounter = 0;
  500. gpTxFilterState = NULL;
  501. gdwTxFilterCounter = 0;
  502. gpIniTnFilter = NULL;
  503. gpIniTnSFilter = NULL;
  504. gpTnFilterHandle = NULL;
  505. gpTnFilterState = NULL;
  506. gdwTnFilterCounter = 0;
  507. gbIsIKEUp = FALSE;
  508. gpSPDSD = NULL;
  509. gbIKENotify = FALSE;
  510. ghIPSecDriver = INVALID_HANDLE_VALUE;
  511. gbSPDAuditSection = FALSE;
  512. ghIpsecServerModule = NULL;
  513. gbAuditingInitialized = FALSE;
  514. gbIsIoctlPended = FALSE;
  515. gbBackwardSoftSA = FALSE;
  516. gdwShutdownFlags = 0;
  517. gbPersistentPolicyApplied = FALSE;
  518. return;
  519. }
  520. DWORD
  521. QuerySpdPolicyState(
  522. LPWSTR pServerName,
  523. DWORD dwVersion,
  524. PSPD_POLICY_STATE * ppSpdPolicyState,
  525. LPVOID pvReserved
  526. )
  527. {
  528. DWORD dwError = 0;
  529. PSPD_POLICY_STATE pSpdPolicyState = NULL;
  530. dwError = SPDApiBufferAllocate(
  531. sizeof(SPD_POLICY_STATE),
  532. &pSpdPolicyState
  533. );
  534. BAIL_ON_WIN32_ERROR(dwError);
  535. ENTER_SPD_SECTION();
  536. dwError = ValidateSecurity(
  537. SPD_OBJECT_SERVER,
  538. SERVER_ACCESS_ADMINISTER,
  539. NULL,
  540. NULL
  541. );
  542. BAIL_ON_LOCK_ERROR(dwError);
  543. pSpdPolicyState->PolicyLoadState = gpIpsecPolicyState->CurrentState;
  544. switch (gpIpsecPolicyState->CurrentState) {
  545. case SPD_STATE_DS_APPLY_SUCCESS:
  546. pSpdPolicyState->dwWhenChanged = gpIpsecPolicyState->DSIncarnationNumber;
  547. break;
  548. case SPD_STATE_LOCAL_APPLY_SUCCESS:
  549. case SPD_STATE_CACHE_APPLY_SUCCESS:
  550. pSpdPolicyState->dwWhenChanged = gpIpsecPolicyState->RegIncarnationNumber;
  551. break;
  552. case SPD_STATE_PERSISTENT_APPLY_SUCCESS:
  553. pSpdPolicyState->dwWhenChanged = gpIpsecPolicyState->PersIncarnationNumber;
  554. break;
  555. default:
  556. pSpdPolicyState->dwWhenChanged = 0;
  557. break;
  558. }
  559. LEAVE_SPD_SECTION();
  560. *ppSpdPolicyState = pSpdPolicyState;
  561. return (dwError);
  562. lock:
  563. LEAVE_SPD_SECTION();
  564. error:
  565. if (pSpdPolicyState) {
  566. SPDApiBufferFree(pSpdPolicyState);
  567. }
  568. *ppSpdPolicyState = NULL;
  569. return (dwError);
  570. }
  571. DWORD
  572. SetSpdStateOnError(
  573. DWORD dwPolicySource,
  574. SPD_ACTION SpdAction,
  575. DWORD ActionError,
  576. SPD_STATE * pSpdState
  577. )
  578. {
  579. SPD_STATE SpdPolicyState = 0;
  580. DWORD dwError = ERROR_SUCCESS;
  581. if (!pSpdState) {
  582. dwError = ERROR_INVALID_PARAMETER;
  583. BAIL_ON_WIN32_ERROR(dwError);
  584. }
  585. // Collapse triplet into one flag:
  586. // Long-winded, but by doing it like this we simplify readability
  587. // of other parts of code.
  588. if (!ActionError) {
  589. if (SpdAction == SPD_POLICY_APPLY) {
  590. switch(dwPolicySource) {
  591. case IPSEC_SOURCE_PERSISTENT:
  592. SpdPolicyState = SPD_STATE_PERSISTENT_APPLY_SUCCESS;
  593. break;
  594. case IPSEC_SOURCE_LOCAL:
  595. SpdPolicyState = SPD_STATE_LOCAL_APPLY_SUCCESS;
  596. break;
  597. case IPSEC_SOURCE_DOMAIN:
  598. SpdPolicyState = SPD_STATE_DS_APPLY_SUCCESS;
  599. break;
  600. case IPSEC_SOURCE_CACHE:
  601. SpdPolicyState = SPD_STATE_CACHE_APPLY_SUCCESS;
  602. break;
  603. }
  604. } else if (SpdAction == SPD_POLICY_LOAD) {
  605. switch(dwPolicySource) {
  606. case IPSEC_SOURCE_PERSISTENT:
  607. SpdPolicyState = SPD_STATE_PERSISTENT_LOAD_SUCCESS;
  608. break;
  609. case IPSEC_SOURCE_LOCAL:
  610. SpdPolicyState = SPD_STATE_LOCAL_LOAD_SUCCESS;
  611. break;
  612. case IPSEC_SOURCE_DOMAIN:
  613. SpdPolicyState = SPD_STATE_DS_LOAD_SUCCESS;
  614. break;
  615. case IPSEC_SOURCE_CACHE:
  616. SpdPolicyState = SPD_STATE_CACHE_LOAD_SUCCESS;
  617. break;
  618. }
  619. }
  620. } else {
  621. if (SpdAction == SPD_POLICY_APPLY) {
  622. switch(dwPolicySource) {
  623. case IPSEC_SOURCE_PERSISTENT:
  624. SpdPolicyState = SPD_STATE_PERSISTENT_APPLY_FAIL;
  625. break;
  626. case IPSEC_SOURCE_LOCAL:
  627. SpdPolicyState = SPD_STATE_LOCAL_APPLY_FAIL;
  628. break;
  629. case IPSEC_SOURCE_DOMAIN:
  630. SpdPolicyState = SPD_STATE_DS_APPLY_FAIL;
  631. break;
  632. case IPSEC_SOURCE_CACHE:
  633. SpdPolicyState = SPD_STATE_CACHE_APPLY_FAIL;
  634. break;
  635. }
  636. } else if (SpdAction == SPD_POLICY_LOAD) {
  637. switch(dwPolicySource) {
  638. case IPSEC_SOURCE_PERSISTENT:
  639. SpdPolicyState = SPD_STATE_PERSISTENT_LOAD_FAIL;
  640. break;
  641. case IPSEC_SOURCE_LOCAL:
  642. SpdPolicyState = SPD_STATE_LOCAL_LOAD_FAIL;
  643. break;
  644. case IPSEC_SOURCE_DOMAIN:
  645. SpdPolicyState = SPD_STATE_DS_LOAD_FAIL;
  646. break;
  647. case IPSEC_SOURCE_CACHE:
  648. SpdPolicyState = SPD_STATE_CACHE_LOAD_FAIL;
  649. break;
  650. }
  651. }
  652. }
  653. (*pSpdState) = SpdPolicyState;
  654. error:
  655. return ERROR_SUCCESS;
  656. }
  657. BOOL
  658. InAcceptableState(
  659. SPD_STATE SpdState
  660. )
  661. {
  662. BOOL AcceptableState = FALSE;
  663. switch (SpdState) {
  664. case SPD_STATE_LOCAL_APPLY_SUCCESS:
  665. case SPD_STATE_DS_APPLY_SUCCESS:
  666. case SPD_STATE_PERSISTENT_APPLY_SUCCESS:
  667. case SPD_STATE_INITIAL:
  668. AcceptableState = TRUE;
  669. break;
  670. }
  671. return AcceptableState;
  672. }