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.

2780 lines
70 KiB

  1. #include "precomp.h"
  2. #ifdef TRACE_ON
  3. #include "pastore.tmh"
  4. #endif
  5. VOID
  6. InitializePolicyStateBlock(
  7. PIPSEC_POLICY_STATE pIpsecPolicyState
  8. )
  9. {
  10. memset(pIpsecPolicyState, 0, sizeof(IPSEC_POLICY_STATE));
  11. pIpsecPolicyState->DefaultPollingInterval = gDefaultPollingInterval;
  12. }
  13. DWORD
  14. StartStatePollingManager(
  15. PIPSEC_POLICY_STATE pIpsecPolicyState
  16. )
  17. {
  18. DWORD dwError = 0;
  19. if (IsDirectoryPolicySpecified()) {
  20. dwError = PlumbDirectoryPolicy(
  21. pIpsecPolicyState
  22. );
  23. if (dwError) {
  24. dwError = PlumbCachePolicy(
  25. pIpsecPolicyState
  26. );
  27. }
  28. } else if (IsLocalPolicySpecified()) {
  29. dwError = PlumbLocalPolicy(
  30. pIpsecPolicyState
  31. );
  32. BAIL_ON_WIN32_ERROR(dwError);
  33. }
  34. #ifdef TRACE_ON
  35. else {
  36. TRACE(TRC_INFORMATION, ("Pastore did not detect any local or domain policy assigned."));
  37. }
  38. #endif
  39. //
  40. // The new polling interval has been set by either the
  41. // registry code or the DS code or remains at initialized value.
  42. //
  43. gCurrentPollingInterval = pIpsecPolicyState->CurrentPollingInterval;
  44. TRACE(
  45. TRC_INFORMATION,
  46. ("Set global polling interval to %d",
  47. gCurrentPollingInterval)
  48. );
  49. return (dwError);
  50. error:
  51. return (dwError);
  52. }
  53. DWORD
  54. PlumbDirectoryPolicy(
  55. PIPSEC_POLICY_STATE pIpsecPolicyState
  56. )
  57. {
  58. DWORD dwError = 0;
  59. LPWSTR pszDirectoryPolicyDN = NULL;
  60. PIPSEC_POLICY_OBJECT pIpsecPolicyObject = NULL;
  61. PIPSEC_POLICY_DATA pIpsecPolicyData = NULL;
  62. DWORD dwStoreType = IPSEC_DIRECTORY_PROVIDER;
  63. DWORD dwSlientErrorCode = 0;
  64. BOOL bIsActivePolicy = FALSE;
  65. SPD_ACTION SpdAction = SPD_POLICY_LOAD;
  66. TRACE(TRC_INFORMATION, (L"Plumbing directory policy"));
  67. dwError = GetDirectoryPolicyDN(
  68. &pszDirectoryPolicyDN
  69. );
  70. BAIL_ON_WIN32_ERROR(dwError);
  71. bIsActivePolicy = TRUE;
  72. dwError = LoadDirectoryPolicy(
  73. pszDirectoryPolicyDN,
  74. &pIpsecPolicyObject
  75. );
  76. BAIL_ON_WIN32_ERROR(dwError);
  77. dwError = ProcessNFAs(
  78. pIpsecPolicyObject,
  79. dwStoreType,
  80. &dwSlientErrorCode,
  81. &pIpsecPolicyData
  82. );
  83. BAIL_ON_WIN32_ERROR(dwError);
  84. AuditIPSecPolicyEvent(
  85. SE_CATEGID_POLICY_CHANGE,
  86. SE_AUDITID_IPSEC_POLICY_CHANGED,
  87. PASTORE_LOAD_DS_POLICY_SUCCESS,
  88. pIpsecPolicyData->pszIpsecName,
  89. TRUE,
  90. TRUE
  91. );
  92. SpdAction = SPD_POLICY_APPLY;
  93. if (pIpsecPolicyState->pIpsecPolicyObject) {
  94. FreeIpsecPolicyObject(pIpsecPolicyState->pIpsecPolicyObject);
  95. }
  96. if (pIpsecPolicyState->pIpsecPolicyData) {
  97. FreeIpsecPolicyData(pIpsecPolicyState->pIpsecPolicyData);
  98. }
  99. if (pIpsecPolicyState->pszDirectoryPolicyDN) {
  100. FreeSPDStr(pIpsecPolicyState->pszDirectoryPolicyDN);
  101. }
  102. pIpsecPolicyState->pIpsecPolicyObject = pIpsecPolicyObject;
  103. pIpsecPolicyObject = NULL;
  104. pIpsecPolicyState->pIpsecPolicyData = pIpsecPolicyData;
  105. pIpsecPolicyData = NULL;
  106. pIpsecPolicyState->pszDirectoryPolicyDN = pszDirectoryPolicyDN;
  107. pszDirectoryPolicyDN = NULL;
  108. //
  109. // Plumb the DS policy.
  110. //
  111. dwError = ApplyLoadedDirectoryPolicy(
  112. pIpsecPolicyState
  113. );
  114. // If error rollback. Ignoring rollback errors, because nothing can be done.
  115. //
  116. if (dwError) {
  117. TRACE(TRC_INFORMATION, ("Pastore rolling back policy application due to previous errors"));
  118. (VOID) DeletePolicyInformation(
  119. pIpsecPolicyState->pIpsecPolicyData
  120. );
  121. }
  122. BAIL_ON_WIN32_ERROR(dwError);
  123. dwError = ERROR_SUCCESS;
  124. if (dwSlientErrorCode) {
  125. AuditIPSecPolicyErrorEvent(
  126. SE_CATEGID_POLICY_CHANGE,
  127. SE_AUDITID_IPSEC_POLICY_CHANGED,
  128. PASTORE_FAILED_SOME_NFA_APPLICATION,
  129. pIpsecPolicyState->pIpsecPolicyData->pszIpsecName,
  130. dwSlientErrorCode,
  131. FALSE,
  132. TRUE
  133. );
  134. TRACE(
  135. TRC_WARNING,
  136. ("Pastore failed to process one or more NFAs. Please compare active policy in SPD with static policy in storage: %!winerr!",
  137. dwSlientErrorCode)
  138. );
  139. }
  140. return (dwError);
  141. error:
  142. SetSpdStateOnError(
  143. IPSEC_SOURCE_DOMAIN,
  144. SpdAction,
  145. dwError,
  146. &pIpsecPolicyState->CurrentState
  147. );
  148. //
  149. // Audit if we had an error loading policy (ApplyLoadedDirectoryPolicy handles
  150. // auditing for policy pplication)
  151. //
  152. if (bIsActivePolicy && pszDirectoryPolicyDN &&
  153. SpdAction == SPD_POLICY_LOAD)
  154. {
  155. AuditIPSecPolicyErrorEvent(
  156. SE_CATEGID_POLICY_CHANGE,
  157. SE_AUDITID_IPSEC_POLICY_CHANGED,
  158. PASTORE_LOAD_DS_POLICY_FAIL,
  159. pszDirectoryPolicyDN,
  160. dwError,
  161. FALSE,
  162. TRUE
  163. );
  164. }
  165. if (pszDirectoryPolicyDN) {
  166. FreeSPDStr(pszDirectoryPolicyDN);
  167. }
  168. if (pIpsecPolicyObject) {
  169. FreeIpsecPolicyObject(pIpsecPolicyObject);
  170. }
  171. if (pIpsecPolicyData) {
  172. FreeIpsecPolicyData(pIpsecPolicyData);
  173. }
  174. // ASSERT: if ApplyLoadedDirectoryPolicy failed, then pIpsecPolicyState->pIpsecPolicyObject, are set to the
  175. // pIpsecPolicyState->pIpsecPolicyData and pIpsecPolicyState->pszCachePolicyDN are filled
  176. // with the values of the loaded BUT Unapplied policy.
  177. return (dwError);
  178. }
  179. DWORD
  180. GetDirectoryPolicyDN(
  181. LPWSTR * ppszDirectoryPolicyDN
  182. )
  183. {
  184. DWORD dwError = 0;
  185. HKEY hPolicyKey = NULL;
  186. LPWSTR pszIpsecPolicyName = NULL;
  187. DWORD dwSize = 0;
  188. LPWSTR pszPolicyDN = NULL;
  189. LPWSTR pszDirectoryPolicyDN = NULL;
  190. *ppszDirectoryPolicyDN = NULL;
  191. dwError = RegOpenKeyExW(
  192. HKEY_LOCAL_MACHINE,
  193. gpszIpsecDSPolicyKey,
  194. 0,
  195. KEY_ALL_ACCESS,
  196. &hPolicyKey
  197. );
  198. BAIL_ON_WIN32_ERROR(dwError);
  199. dwError = RegstoreQueryValue(
  200. hPolicyKey,
  201. L"DSIPSECPolicyPath",
  202. REG_SZ,
  203. (LPBYTE *)&pszIpsecPolicyName,
  204. &dwSize
  205. );
  206. BAIL_ON_WIN32_ERROR(dwError);
  207. //
  208. // Move by LDAP:// to get the real DN and allocate
  209. // this string.
  210. // Fix this by fixing the gpo extension.
  211. //
  212. pszPolicyDN = pszIpsecPolicyName + wcslen(L"LDAP://");
  213. pszDirectoryPolicyDN = AllocSPDStr(pszPolicyDN);
  214. if (!pszDirectoryPolicyDN) {
  215. dwError = ERROR_OUTOFMEMORY;
  216. BAIL_ON_WIN32_ERROR(dwError);
  217. }
  218. *ppszDirectoryPolicyDN = pszDirectoryPolicyDN;
  219. error:
  220. #ifdef TRACE_ON
  221. if (dwError) {
  222. TRACE(TRC_ERROR, ("Failed to determine directory policy DN: %!winerr!", dwError));
  223. }
  224. #endif
  225. if (pszIpsecPolicyName) {
  226. FreeSPDStr(pszIpsecPolicyName);
  227. }
  228. if (hPolicyKey) {
  229. CloseHandle(hPolicyKey);
  230. }
  231. return (dwError);
  232. }
  233. DWORD
  234. LoadDirectoryPolicy(
  235. LPWSTR pszDirectoryPolicyDN,
  236. PIPSEC_POLICY_OBJECT * ppIpsecPolicyObject
  237. )
  238. {
  239. DWORD dwError = 0;
  240. LPWSTR pszDefaultDirectory = NULL;
  241. HLDAP hLdapBindHandle = NULL;
  242. PIPSEC_POLICY_OBJECT pIpsecPolicyObject = NULL;
  243. TRACE(TRC_INFORMATION, (L"Loading directory policy."));
  244. dwError = ComputeDefaultDirectory(
  245. &pszDefaultDirectory
  246. );
  247. BAIL_ON_WIN32_ERROR(dwError);
  248. dwError = OpenDirectoryServerHandle(
  249. pszDefaultDirectory,
  250. 389,
  251. &hLdapBindHandle
  252. );
  253. BAIL_ON_WIN32_ERROR(dwError);
  254. dwError = ReadPolicyObjectFromDirectory(
  255. hLdapBindHandle,
  256. pszDirectoryPolicyDN,
  257. &pIpsecPolicyObject
  258. );
  259. BAIL_ON_WIN32_ERROR(dwError);
  260. *ppIpsecPolicyObject = pIpsecPolicyObject;
  261. TRACE(TRC_INFORMATION, (L"Loaded directory policy from \"%ls\"", pszDirectoryPolicyDN));
  262. cleanup:
  263. if (pszDefaultDirectory) {
  264. FreeSPDStr(pszDefaultDirectory);
  265. }
  266. if (hLdapBindHandle) {
  267. CloseDirectoryServerHandle(hLdapBindHandle);
  268. }
  269. return (dwError);
  270. error:
  271. TRACE(
  272. TRC_ERROR,
  273. (L"Failed to load directory policy from \"%ls\": %!winerr!",
  274. pszDirectoryPolicyDN,
  275. dwError)
  276. );
  277. *ppIpsecPolicyObject = NULL;
  278. goto cleanup;
  279. }
  280. DWORD
  281. ApplyLoadedDirectoryPolicy(
  282. PIPSEC_POLICY_STATE pIpsecPolicyState
  283. )
  284. {
  285. DWORD dwError = 0;
  286. PIPSEC_POLICY_DATA pIpsecPolicyData = NULL;
  287. TRACE(TRC_INFORMATION, (L"Applying loaded directory policy."));
  288. pIpsecPolicyData = pIpsecPolicyState->pIpsecPolicyData;
  289. //
  290. // Plumb the DS policy.
  291. //
  292. dwError = AddPolicyInformation(
  293. pIpsecPolicyData,
  294. IPSEC_SOURCE_DOMAIN
  295. );
  296. BAIL_ON_WIN32_ERROR(dwError);
  297. //
  298. // Delete the old cache and write the new one in.
  299. //
  300. DeleteRegistryCache();
  301. CacheDirectorytoRegistry(pIpsecPolicyState->pIpsecPolicyObject);
  302. //
  303. // Set the state to DS_DOWNLOADED.
  304. //
  305. SetSpdStateOnError(
  306. IPSEC_SOURCE_DOMAIN,
  307. SPD_POLICY_APPLY,
  308. ERROR_SUCCESS,
  309. &pIpsecPolicyState->CurrentState
  310. );
  311. //
  312. // Compute the new polling interval.
  313. //
  314. pIpsecPolicyState->CurrentPollingInterval = pIpsecPolicyData->dwPollingInterval;
  315. pIpsecPolicyState->DSIncarnationNumber = pIpsecPolicyData->dwWhenChanged;
  316. pIpsecPolicyState->RegIncarnationNumber = 0;
  317. gCurrentPollingInterval = pIpsecPolicyState->CurrentPollingInterval;
  318. TRACE(
  319. TRC_INFORMATION,
  320. ("Set global polling interval to %d",
  321. gCurrentPollingInterval)
  322. );
  323. dwError = ERROR_SUCCESS;
  324. AuditIPSecPolicyEvent(
  325. SE_CATEGID_POLICY_CHANGE,
  326. SE_AUDITID_IPSEC_POLICY_CHANGED,
  327. PASTORE_APPLIED_DS_POLICY,
  328. pIpsecPolicyData->pszIpsecName,
  329. TRUE,
  330. TRUE
  331. );
  332. TRACE(
  333. TRC_INFORMATION,
  334. (L"Applied directory policy %ls loaded from %ls",
  335. pIpsecPolicyData->pszIpsecName,
  336. pIpsecPolicyState->pszDirectoryPolicyDN)
  337. );
  338. return (dwError);
  339. error:
  340. TRACE(
  341. TRC_ERROR,
  342. (L"Failed to apply directory policy %ls loaded from %ls",
  343. pIpsecPolicyData->pszIpsecName,
  344. pIpsecPolicyState->pszDirectoryPolicyDN)
  345. );
  346. SetSpdStateOnError(
  347. IPSEC_SOURCE_DOMAIN,
  348. SPD_POLICY_APPLY,
  349. dwError,
  350. &pIpsecPolicyState->CurrentState
  351. );
  352. AuditIPSecPolicyErrorEvent(
  353. SE_CATEGID_POLICY_CHANGE,
  354. SE_AUDITID_IPSEC_POLICY_CHANGED,
  355. PASTORE_FAILED_DS_POLICY_APPLICATION,
  356. pIpsecPolicyData->pszIpsecName,
  357. dwError,
  358. FALSE,
  359. TRUE
  360. );
  361. return (dwError);
  362. }
  363. DWORD
  364. PlumbCachePolicy(
  365. PIPSEC_POLICY_STATE pIpsecPolicyState
  366. )
  367. {
  368. DWORD dwError = 0;
  369. LPWSTR pszCachePolicyDN = NULL;
  370. PIPSEC_POLICY_OBJECT pIpsecPolicyObject = NULL;
  371. PIPSEC_POLICY_DATA pIpsecPolicyData = NULL;
  372. DWORD dwStoreType = IPSEC_REGISTRY_PROVIDER;
  373. DWORD dwSlientErrorCode = 0;
  374. BOOL bIsActivePolicy = FALSE;
  375. SPD_ACTION SpdAction = SPD_POLICY_LOAD;
  376. TRACE(TRC_INFORMATION, (L"Plumbing cache policy."));
  377. dwError = GetCachePolicyDN(
  378. &pszCachePolicyDN
  379. );
  380. BAIL_ON_WIN32_ERROR(dwError);
  381. bIsActivePolicy = TRUE;
  382. dwError = LoadCachePolicy(
  383. pszCachePolicyDN,
  384. &pIpsecPolicyObject
  385. );
  386. BAIL_ON_WIN32_ERROR(dwError);
  387. dwError = ProcessNFAs(
  388. pIpsecPolicyObject,
  389. dwStoreType,
  390. &dwSlientErrorCode,
  391. &pIpsecPolicyData
  392. );
  393. BAIL_ON_WIN32_ERROR(dwError);
  394. SpdAction = SPD_POLICY_APPLY;
  395. dwError = AddPolicyInformation(
  396. pIpsecPolicyData,
  397. IPSEC_SOURCE_CACHE
  398. );
  399. // If error rollback. Ignoring rollback errors, because nothing can be done.
  400. //
  401. if (dwError) {
  402. TRACE(TRC_INFORMATION, ("Pastore rolling back policy application due to previous errors"));
  403. (VOID) DeletePolicyInformation(
  404. pIpsecPolicyData
  405. );
  406. }
  407. BAIL_ON_WIN32_ERROR(dwError);
  408. if (pIpsecPolicyState->pIpsecPolicyObject) {
  409. FreeIpsecPolicyObject(pIpsecPolicyState->pIpsecPolicyObject);
  410. }
  411. if (pIpsecPolicyState->pIpsecPolicyData) {
  412. FreeIpsecPolicyData(pIpsecPolicyState->pIpsecPolicyData);
  413. }
  414. if (pIpsecPolicyState->pszCachePolicyDN) {
  415. FreeSPDStr(pIpsecPolicyState->pszCachePolicyDN);
  416. }
  417. pIpsecPolicyState->pIpsecPolicyObject = pIpsecPolicyObject;
  418. pIpsecPolicyState->pIpsecPolicyData = pIpsecPolicyData;
  419. pIpsecPolicyState->pszCachePolicyDN = pszCachePolicyDN;
  420. //
  421. // Set the state to SPD_STATE_CACHE_APPLY_SUCCESS.
  422. //
  423. //
  424. SetSpdStateOnError(
  425. IPSEC_SOURCE_CACHE,
  426. SPD_POLICY_APPLY,
  427. ERROR_SUCCESS,
  428. &pIpsecPolicyState->CurrentState
  429. );
  430. //
  431. // Compute the new polling interval.
  432. //
  433. pIpsecPolicyState->CurrentPollingInterval = pIpsecPolicyData->dwPollingInterval;
  434. pIpsecPolicyState->DSIncarnationNumber = 0;
  435. pIpsecPolicyState->RegIncarnationNumber = pIpsecPolicyData->dwWhenChanged;
  436. gCurrentPollingInterval = pIpsecPolicyState->CurrentPollingInterval;
  437. TRACE(
  438. TRC_INFORMATION,
  439. ("Set global polling interval to %d",
  440. gCurrentPollingInterval)
  441. );
  442. dwError = ERROR_SUCCESS;
  443. if (dwSlientErrorCode) {
  444. AuditIPSecPolicyErrorEvent(
  445. SE_CATEGID_POLICY_CHANGE,
  446. SE_AUDITID_IPSEC_POLICY_CHANGED,
  447. PASTORE_FAILED_SOME_NFA_APPLICATION,
  448. pIpsecPolicyData->pszIpsecName,
  449. dwSlientErrorCode,
  450. FALSE,
  451. TRUE
  452. );
  453. TRACE(
  454. TRC_WARNING,
  455. ("Pastore failed to process one or more NFAs. Please compare active policy in SPD with policy in storage: %!winerr!",
  456. dwSlientErrorCode)
  457. );
  458. }
  459. AuditIPSecPolicyEvent(
  460. SE_CATEGID_POLICY_CHANGE,
  461. SE_AUDITID_IPSEC_POLICY_CHANGED,
  462. PASTORE_APPLIED_CACHED_POLICY,
  463. pIpsecPolicyData->pszIpsecName,
  464. TRUE,
  465. TRUE
  466. );
  467. TRACE(
  468. TRC_INFORMATION,
  469. (L"Applied cache policy %ls loaded from %ls",
  470. pIpsecPolicyData->pszIpsecName,
  471. pIpsecPolicyState->pszCachePolicyDN)
  472. );
  473. return (dwError);
  474. error:
  475. TRACE(
  476. TRC_ERROR,
  477. (L"Failed to plumb cache policy.")
  478. );
  479. SetSpdStateOnError(
  480. IPSEC_SOURCE_CACHE,
  481. SpdAction,
  482. dwError,
  483. &pIpsecPolicyState->CurrentState
  484. );
  485. //
  486. // Check pszCachePolicyDN for non-NULL.
  487. //
  488. if (bIsActivePolicy && pszCachePolicyDN) {
  489. AuditIPSecPolicyErrorEvent(
  490. SE_CATEGID_POLICY_CHANGE,
  491. SE_AUDITID_IPSEC_POLICY_CHANGED,
  492. PASTORE_FAILED_CACHED_POLICY_APPLICATION,
  493. pszCachePolicyDN,
  494. dwError,
  495. FALSE,
  496. TRUE
  497. );
  498. }
  499. if (pszCachePolicyDN) {
  500. FreeSPDStr(pszCachePolicyDN);
  501. }
  502. if (pIpsecPolicyObject) {
  503. FreeIpsecPolicyObject(pIpsecPolicyObject);
  504. }
  505. if (pIpsecPolicyData) {
  506. FreeIpsecPolicyData(pIpsecPolicyData);
  507. }
  508. return (dwError);
  509. }
  510. DWORD
  511. GetCachePolicyDN(
  512. LPWSTR * ppszCachePolicyDN
  513. )
  514. {
  515. DWORD dwError = 0;
  516. LPWSTR pszDirectoryPolicyDN = NULL;
  517. LPWSTR pszCachePolicyDN = NULL;
  518. *ppszCachePolicyDN = NULL;
  519. dwError = GetDirectoryPolicyDN(
  520. &pszDirectoryPolicyDN
  521. );
  522. BAIL_ON_WIN32_ERROR(dwError);
  523. dwError = CopyPolicyDSToFQRegString(
  524. pszDirectoryPolicyDN,
  525. &pszCachePolicyDN
  526. );
  527. BAIL_ON_WIN32_ERROR(dwError);
  528. *ppszCachePolicyDN = pszCachePolicyDN;
  529. error:
  530. #ifdef TRACE_ON
  531. if (dwError) {
  532. TRACE(TRC_ERROR, ("Failed to determine cache policy DN: %!winerr!", dwError));
  533. }
  534. #endif
  535. if (pszDirectoryPolicyDN) {
  536. FreeSPDStr(pszDirectoryPolicyDN);
  537. }
  538. return (dwError);
  539. }
  540. DWORD
  541. LoadCachePolicy(
  542. LPWSTR pszCachePolicyDN,
  543. PIPSEC_POLICY_OBJECT * ppIpsecPolicyObject
  544. )
  545. {
  546. DWORD dwError = 0;
  547. HKEY hRegistryKey = NULL;
  548. PIPSEC_POLICY_OBJECT pIpsecPolicyObject = NULL;
  549. TRACE(TRC_INFORMATION, (L"Loading cache policy."));
  550. dwError = OpenRegistryIPSECRootKey(
  551. NULL,
  552. gpszIpsecCachePolicyKey,
  553. &hRegistryKey
  554. );
  555. BAIL_ON_WIN32_ERROR(dwError);
  556. dwError = ReadPolicyObjectFromRegistry(
  557. hRegistryKey,
  558. pszCachePolicyDN,
  559. gpszIpsecCachePolicyKey,
  560. &pIpsecPolicyObject
  561. );
  562. BAIL_ON_WIN32_ERROR(dwError);
  563. *ppIpsecPolicyObject = pIpsecPolicyObject;
  564. cleanup:
  565. if (hRegistryKey) {
  566. CloseHandle(hRegistryKey);
  567. }
  568. return (dwError);
  569. error:
  570. TRACE(
  571. TRC_ERROR,
  572. (L"Failed to load cache policy from \"%ls\": %!winerr!",
  573. pszCachePolicyDN,
  574. dwError)
  575. );
  576. *ppIpsecPolicyObject = NULL;
  577. goto cleanup;
  578. }
  579. DWORD
  580. PlumbLocalPolicy(
  581. PIPSEC_POLICY_STATE pIpsecPolicyState
  582. )
  583. {
  584. DWORD dwError = 0;
  585. LPWSTR pszRegistryPolicyDN = NULL;
  586. PIPSEC_POLICY_OBJECT pIpsecPolicyObject = NULL;
  587. PIPSEC_POLICY_DATA pIpsecPolicyData = NULL;
  588. DWORD dwStoreType = IPSEC_REGISTRY_PROVIDER;
  589. DWORD dwSlientErrorCode = 0;
  590. BOOL bIsActivePolicy = FALSE;
  591. SPD_ACTION SpdAction = SPD_POLICY_LOAD;
  592. TRACE(TRC_INFORMATION, (L"Plumbing local policy."));
  593. dwError = GetRegistryPolicyDN(
  594. &pszRegistryPolicyDN,
  595. IPSEC_STORE_LOCAL
  596. );
  597. BAIL_ON_WIN32_ERROR(dwError);
  598. bIsActivePolicy = TRUE;
  599. dwError = LoadRegistryPolicy(
  600. pszRegistryPolicyDN,
  601. &pIpsecPolicyObject,
  602. IPSEC_STORE_LOCAL
  603. );
  604. BAIL_ON_WIN32_ERROR(dwError);
  605. dwError = ProcessNFAs(
  606. pIpsecPolicyObject,
  607. dwStoreType,
  608. &dwSlientErrorCode,
  609. &pIpsecPolicyData
  610. );
  611. BAIL_ON_WIN32_ERROR(dwError);
  612. AuditIPSecPolicyEvent(
  613. SE_CATEGID_POLICY_CHANGE,
  614. SE_AUDITID_IPSEC_POLICY_CHANGED,
  615. PASTORE_LOAD_LOCAL_POLICY_SUCCESS,
  616. pIpsecPolicyData->pszIpsecName,
  617. TRUE,
  618. TRUE
  619. );
  620. SpdAction = SPD_POLICY_APPLY;
  621. if (pIpsecPolicyState->pIpsecPolicyObject) {
  622. FreeIpsecPolicyObject(pIpsecPolicyState->pIpsecPolicyObject);
  623. }
  624. if (pIpsecPolicyState->pIpsecPolicyData) {
  625. FreeIpsecPolicyData(pIpsecPolicyState->pIpsecPolicyData);
  626. }
  627. if (pIpsecPolicyState->pszRegistryPolicyDN) {
  628. FreeSPDStr(pIpsecPolicyState->pszRegistryPolicyDN);
  629. }
  630. pIpsecPolicyState->pIpsecPolicyObject = pIpsecPolicyObject;
  631. pIpsecPolicyObject = NULL;
  632. pIpsecPolicyState->pIpsecPolicyData = pIpsecPolicyData;
  633. pIpsecPolicyData = NULL;
  634. pIpsecPolicyState->pszRegistryPolicyDN = pszRegistryPolicyDN;
  635. pszRegistryPolicyDN = NULL;
  636. dwError = ApplyLoadedLocalPolicy(
  637. pIpsecPolicyState
  638. );
  639. // If error rollback. Ignoring rollback errors, because nothing can be done.
  640. //
  641. if (dwError) {
  642. TRACE(TRC_INFORMATION, ("Pastore rolling back policy application due to previous errors"));
  643. (VOID) DeletePolicyInformation(
  644. pIpsecPolicyState->pIpsecPolicyData
  645. );
  646. }
  647. BAIL_ON_WIN32_ERROR(dwError);
  648. dwError = ERROR_SUCCESS;
  649. if (dwSlientErrorCode) {
  650. AuditIPSecPolicyErrorEvent(
  651. SE_CATEGID_POLICY_CHANGE,
  652. SE_AUDITID_IPSEC_POLICY_CHANGED,
  653. PASTORE_FAILED_SOME_NFA_APPLICATION,
  654. pIpsecPolicyState->pIpsecPolicyData->pszIpsecName,
  655. dwSlientErrorCode,
  656. FALSE,
  657. TRUE
  658. );
  659. TRACE(
  660. TRC_WARNING,
  661. ("Pastore failed to process one or more NFAs. Please compare active policy in SPD with policy in storage: %!winerr!",
  662. dwSlientErrorCode)
  663. );
  664. }
  665. return (dwError);
  666. error:
  667. SetSpdStateOnError(
  668. IPSEC_SOURCE_LOCAL,
  669. SpdAction,
  670. dwError,
  671. &pIpsecPolicyState->CurrentState
  672. );
  673. //
  674. // Audit if we had an error loading policy (ApplyLoadedDirectoryPolicy handles
  675. // auditing for policy pplication)
  676. //
  677. if (bIsActivePolicy && pszRegistryPolicyDN &&
  678. SpdAction == SPD_POLICY_LOAD)
  679. {
  680. AuditIPSecPolicyErrorEvent(
  681. SE_CATEGID_POLICY_CHANGE,
  682. SE_AUDITID_IPSEC_POLICY_CHANGED,
  683. PASTORE_LOAD_LOCAL_POLICY_FAIL,
  684. pszRegistryPolicyDN,
  685. dwError,
  686. FALSE,
  687. TRUE
  688. );
  689. }
  690. if (pszRegistryPolicyDN) {
  691. FreeSPDStr(pszRegistryPolicyDN);
  692. }
  693. if (pIpsecPolicyObject) {
  694. FreeIpsecPolicyObject(pIpsecPolicyObject);
  695. }
  696. if (pIpsecPolicyData) {
  697. FreeIpsecPolicyData(pIpsecPolicyData);
  698. }
  699. // ASSERT: if ApplyLoadedLocalPolicy failed, then pIpsecPolicyState->pIpsecPolicyObject, are set to the
  700. // pIpsecPolicyState->pIpsecPolicyData and pIpsecPolicyState->pszCachePolicyDN are filled
  701. // with the values of the loaded BUT Unapplied policy.
  702. return (dwError);
  703. }
  704. DWORD
  705. ApplyLoadedLocalPolicy(
  706. PIPSEC_POLICY_STATE pIpsecPolicyState
  707. )
  708. {
  709. DWORD dwError = 0;
  710. PIPSEC_POLICY_DATA pIpsecPolicyData = NULL;
  711. TRACE(TRC_INFORMATION, (L"Applying loaded local policy."));
  712. pIpsecPolicyData = pIpsecPolicyState->pIpsecPolicyData;
  713. dwError = AddPolicyInformation(
  714. pIpsecPolicyData,
  715. IPSEC_SOURCE_LOCAL
  716. );
  717. BAIL_ON_WIN32_ERROR(dwError);
  718. SetSpdStateOnError(
  719. IPSEC_SOURCE_LOCAL,
  720. SPD_POLICY_APPLY,
  721. ERROR_SUCCESS,
  722. &pIpsecPolicyState->CurrentState
  723. );
  724. //
  725. // Compute the new polling interval.
  726. //
  727. pIpsecPolicyState->CurrentPollingInterval = pIpsecPolicyData->dwPollingInterval;
  728. pIpsecPolicyState->DSIncarnationNumber = 0;
  729. pIpsecPolicyState->RegIncarnationNumber = pIpsecPolicyData->dwWhenChanged;
  730. gCurrentPollingInterval = pIpsecPolicyState->CurrentPollingInterval;
  731. TRACE(
  732. TRC_INFORMATION,
  733. ("Set global polling interval to %d",
  734. gCurrentPollingInterval)
  735. );
  736. dwError = ERROR_SUCCESS;
  737. AuditIPSecPolicyEvent(
  738. SE_CATEGID_POLICY_CHANGE,
  739. SE_AUDITID_IPSEC_POLICY_CHANGED,
  740. PASTORE_APPLIED_LOCAL_POLICY,
  741. pIpsecPolicyData->pszIpsecName,
  742. TRUE,
  743. TRUE
  744. );
  745. TRACE(
  746. TRC_INFORMATION,
  747. (L"Applied local policy %ls loaded from %ls",
  748. pIpsecPolicyData->pszIpsecName,
  749. pIpsecPolicyState->pszRegistryPolicyDN)
  750. );
  751. return (dwError);
  752. error:
  753. TRACE(
  754. TRC_ERROR,
  755. (L"Failed to apply local policy %ls loaded from %ls",
  756. pIpsecPolicyData->pszIpsecName,
  757. pIpsecPolicyState->pszDirectoryPolicyDN)
  758. );
  759. SetSpdStateOnError(
  760. IPSEC_SOURCE_LOCAL,
  761. SPD_POLICY_APPLY,
  762. dwError,
  763. &pIpsecPolicyState->CurrentState
  764. );
  765. AuditIPSecPolicyErrorEvent(
  766. SE_CATEGID_POLICY_CHANGE,
  767. SE_AUDITID_IPSEC_POLICY_CHANGED,
  768. PASTORE_FAILED_LOCAL_POLICY_APPLICATION,
  769. pIpsecPolicyData->pszIpsecName,
  770. dwError,
  771. FALSE,
  772. TRUE
  773. );
  774. return (dwError);
  775. }
  776. DWORD
  777. PlumbPersistentPolicy(
  778. PIPSEC_POLICY_STATE pIpsecPolicyState
  779. )
  780. {
  781. DWORD dwError = 0;
  782. LPWSTR pszRegistryPolicyDN = NULL;
  783. PIPSEC_POLICY_OBJECT pIpsecPolicyObject = NULL;
  784. PIPSEC_POLICY_DATA pIpsecPolicyData = NULL;
  785. DWORD dwStoreType = IPSEC_REGISTRY_PROVIDER;
  786. DWORD dwSlientErrorCode = 0;
  787. BOOL bIsActivePolicy = FALSE;
  788. SPD_ACTION SpdAction = SPD_POLICY_LOAD;
  789. TRACE(TRC_INFORMATION, (L"Plumbing local policy."));
  790. dwError = GetRegistryPolicyDN(
  791. &pszRegistryPolicyDN,
  792. IPSEC_STORE_PERSISTENT
  793. );
  794. BAIL_ON_WIN32_ERROR(dwError);
  795. bIsActivePolicy = TRUE;
  796. dwError = LoadRegistryPolicy(
  797. pszRegistryPolicyDN,
  798. &pIpsecPolicyObject,
  799. IPSEC_STORE_PERSISTENT
  800. );
  801. BAIL_ON_WIN32_ERROR(dwError);
  802. dwError = ProcessNFAs(
  803. pIpsecPolicyObject,
  804. dwStoreType,
  805. &dwSlientErrorCode,
  806. &pIpsecPolicyData
  807. );
  808. BAIL_ON_WIN32_ERROR(dwError);
  809. AuditIPSecPolicyEvent(
  810. SE_CATEGID_POLICY_CHANGE,
  811. SE_AUDITID_IPSEC_POLICY_CHANGED,
  812. PASTORE_LOAD_PERSISTENT_POLICY_SUCCESS,
  813. pIpsecPolicyData->pszIpsecName,
  814. TRUE,
  815. TRUE
  816. );
  817. SpdAction = SPD_POLICY_APPLY;
  818. dwError = AddPolicyInformation(
  819. pIpsecPolicyData,
  820. IPSEC_SOURCE_PERSISTENT
  821. );
  822. BAIL_ON_WIN32_ERROR(dwError);
  823. if (pIpsecPolicyState->pIpsecPolicyObject) {
  824. FreeIpsecPolicyObject(pIpsecPolicyState->pIpsecPolicyObject);
  825. }
  826. if (pIpsecPolicyState->pIpsecPolicyData) {
  827. FreeIpsecPolicyData(pIpsecPolicyState->pIpsecPolicyData);
  828. }
  829. if (pIpsecPolicyState->pszRegistryPolicyDN) {
  830. FreeSPDStr(pIpsecPolicyState->pszRegistryPolicyDN);
  831. }
  832. pIpsecPolicyState->pIpsecPolicyObject = pIpsecPolicyObject;
  833. pIpsecPolicyState->pIpsecPolicyData = pIpsecPolicyData;
  834. pIpsecPolicyState->pszRegistryPolicyDN = pszRegistryPolicyDN;
  835. SetSpdStateOnError(
  836. IPSEC_SOURCE_PERSISTENT,
  837. SPD_POLICY_APPLY,
  838. ERROR_SUCCESS,
  839. &gpIpsecPolicyState->CurrentState
  840. );
  841. gbPersistentPolicyApplied = TRUE;
  842. pIpsecPolicyState->PersIncarnationNumber = pIpsecPolicyData->dwWhenChanged;
  843. dwError = ERROR_SUCCESS;
  844. if (dwSlientErrorCode) {
  845. AuditIPSecPolicyErrorEvent(
  846. SE_CATEGID_POLICY_CHANGE,
  847. SE_AUDITID_IPSEC_POLICY_CHANGED,
  848. PASTORE_FAILED_SOME_NFA_APPLICATION,
  849. pIpsecPolicyData->pszIpsecName,
  850. dwSlientErrorCode,
  851. FALSE,
  852. TRUE
  853. );
  854. TRACE(
  855. TRC_WARNING,
  856. ("Pastore failed to process one or more NFAs. Please compare active policy in SPD policy in storage: %!winerr!",
  857. dwSlientErrorCode)
  858. );
  859. }
  860. AuditIPSecPolicyEvent(
  861. SE_CATEGID_POLICY_CHANGE,
  862. SE_AUDITID_IPSEC_POLICY_CHANGED,
  863. PASTORE_APPLIED_PERSISTENT_POLICY,
  864. pIpsecPolicyData->pszIpsecName,
  865. TRUE,
  866. TRUE
  867. );
  868. TRACE(TRC_INFORMATION, ("Plumbed persistent policy"));
  869. return (dwError);
  870. error:
  871. TRACE(
  872. TRC_ERROR,
  873. (L"Failed to plumb persistent policy.")
  874. );
  875. SetSpdStateOnError(
  876. IPSEC_SOURCE_PERSISTENT,
  877. SpdAction,
  878. dwError,
  879. &gpIpsecPolicyState->CurrentState
  880. );
  881. gbPersistentPolicyApplied = FALSE;
  882. //
  883. // Check pszRegistryPolicyDN for non-NULL.
  884. //
  885. if (bIsActivePolicy && pszRegistryPolicyDN &&
  886. SpdAction == SPD_POLICY_LOAD)
  887. {
  888. AuditIPSecPolicyErrorEvent(
  889. SE_CATEGID_POLICY_CHANGE,
  890. SE_AUDITID_IPSEC_POLICY_CHANGED,
  891. PASTORE_LOAD_PERSISTENT_POLICY_FAIL,
  892. pszRegistryPolicyDN,
  893. dwError,
  894. FALSE,
  895. TRUE
  896. );
  897. } else if (SpdAction == SPD_POLICY_APPLY && pIpsecPolicyData) {
  898. // (Above pIPsecPolicyData can't be null if SPD_POLICY_APPLY,
  899. // but needed check to get prefast off our back)
  900. AuditIPSecPolicyErrorEvent(
  901. SE_CATEGID_POLICY_CHANGE,
  902. SE_AUDITID_IPSEC_POLICY_CHANGED,
  903. PASTORE_FAILED_PERSISTENT_POLICY_APPLICATION,
  904. pIpsecPolicyData->pszIpsecName,
  905. dwError,
  906. FALSE,
  907. TRUE
  908. );
  909. }
  910. if (pszRegistryPolicyDN) {
  911. FreeSPDStr(pszRegistryPolicyDN);
  912. }
  913. if (pIpsecPolicyObject) {
  914. FreeIpsecPolicyObject(pIpsecPolicyObject);
  915. }
  916. if (pIpsecPolicyData) {
  917. FreeIpsecPolicyData(pIpsecPolicyData);
  918. }
  919. return (dwError);
  920. }
  921. LPWSTR
  922. GetRegPathForStore(
  923. IN DWORD dwStore)
  924. {
  925. if (dwStore == IPSEC_STORE_PERSISTENT) {
  926. return gpszIpsecPersistentPolicyKey;
  927. }
  928. else if (dwStore == IPSEC_STORE_LOCAL) {
  929. return gpszIpsecLocalPolicyKey;
  930. }
  931. return NULL;
  932. }
  933. DWORD
  934. GetRegistryPolicyDN(
  935. LPWSTR * ppszRegistryPolicyDN,
  936. IN DWORD dwStore
  937. )
  938. {
  939. DWORD dwError = 0;
  940. HKEY hPolicyKey = NULL;
  941. LPWSTR pszIpsecPolicyName = NULL;
  942. DWORD dwSize = 0;
  943. LPWSTR pszRegPath = NULL;
  944. pszRegPath = GetRegPathForStore(dwStore);
  945. if (pszRegPath == NULL) {
  946. dwError = ERROR_INVALID_PARAMETER;
  947. BAIL_ON_WIN32_ERROR(dwError);
  948. }
  949. dwError = RegOpenKeyExW(
  950. HKEY_LOCAL_MACHINE,
  951. pszRegPath,
  952. 0,
  953. KEY_ALL_ACCESS,
  954. &hPolicyKey
  955. );
  956. BAIL_ON_WIN32_ERROR(dwError);
  957. dwError = RegstoreQueryValue(
  958. hPolicyKey,
  959. L"ActivePolicy",
  960. REG_SZ,
  961. (LPBYTE *)&pszIpsecPolicyName,
  962. &dwSize
  963. );
  964. BAIL_ON_WIN32_ERROR(dwError);
  965. if (!pszIpsecPolicyName || !*pszIpsecPolicyName) {
  966. dwError = ERROR_OUTOFMEMORY;
  967. BAIL_ON_WIN32_ERROR(dwError);
  968. }
  969. *ppszRegistryPolicyDN = pszIpsecPolicyName;
  970. cleanup:
  971. if (hPolicyKey) {
  972. CloseHandle(hPolicyKey);
  973. }
  974. return (dwError);
  975. error:
  976. TRACE(
  977. TRC_ERROR,
  978. (L"Failed to get %ls policy DN: %!winerr!",
  979. dwStore == IPSEC_STORE_LOCAL ? L"local" : L"persistent",
  980. dwError)
  981. );
  982. if (pszIpsecPolicyName) {
  983. FreeSPDStr(pszIpsecPolicyName);
  984. }
  985. *ppszRegistryPolicyDN = NULL;
  986. goto cleanup;
  987. }
  988. DWORD
  989. LoadRegistryPolicy(
  990. LPWSTR pszRegistryPolicyDN,
  991. PIPSEC_POLICY_OBJECT * ppIpsecPolicyObject,
  992. IN DWORD dwStore
  993. )
  994. {
  995. DWORD dwError = 0;
  996. HKEY hRegistryKey = NULL;
  997. PIPSEC_POLICY_OBJECT pIpsecPolicyObject = NULL;
  998. LPWSTR pszRegPath = NULL;
  999. TRACE(TRC_INFORMATION, (L"Loading registry policy."));
  1000. pszRegPath = GetRegPathForStore(dwStore);
  1001. if (pszRegPath == NULL) {
  1002. dwError = ERROR_INVALID_PARAMETER;
  1003. BAIL_ON_WIN32_ERROR(dwError);
  1004. }
  1005. dwError = OpenRegistryIPSECRootKey(
  1006. NULL,
  1007. pszRegPath,
  1008. &hRegistryKey
  1009. );
  1010. BAIL_ON_WIN32_ERROR(dwError);
  1011. dwError = ReadPolicyObjectFromRegistry(
  1012. hRegistryKey,
  1013. pszRegistryPolicyDN,
  1014. pszRegPath,
  1015. &pIpsecPolicyObject
  1016. );
  1017. BAIL_ON_WIN32_ERROR(dwError);
  1018. *ppIpsecPolicyObject = pIpsecPolicyObject;
  1019. cleanup:
  1020. if (hRegistryKey) {
  1021. CloseHandle(hRegistryKey);
  1022. }
  1023. return (dwError);
  1024. error:
  1025. TRACE(
  1026. TRC_ERROR,
  1027. (L"Failed to load %ls policy from \"%ls\": %!winerr!",
  1028. dwStore == IPSEC_STORE_LOCAL ? L"local" : L"persistent",
  1029. pszRegistryPolicyDN,
  1030. dwError)
  1031. );
  1032. *ppIpsecPolicyObject = NULL;
  1033. goto cleanup;
  1034. }
  1035. DWORD
  1036. LoadPersistedIPSecInformation(
  1037. )
  1038. {
  1039. DWORD dwError = ERROR_SUCCESS;
  1040. IPSEC_POLICY_STATE IpsecPolicyState;
  1041. // Initialize Policy State Block.
  1042. //
  1043. InitializePolicyStateBlock(&IpsecPolicyState);
  1044. // Load and apply the persisted store
  1045. //
  1046. if (IsPersistentPolicySpecified()) {
  1047. dwError = PlumbPersistentPolicy(
  1048. &IpsecPolicyState
  1049. );
  1050. BAIL_ON_WIN32_ERROR(dwError);
  1051. }
  1052. #ifdef TRACE_ON
  1053. else {
  1054. TRACE(TRC_INFORMATION, (L"No persistent policy specified."));
  1055. }
  1056. #endif
  1057. cleanup:
  1058. ClearPolicyStateBlock(&IpsecPolicyState);
  1059. return (dwError);
  1060. error:
  1061. goto cleanup;
  1062. }
  1063. DWORD
  1064. AddPolicyInformation(
  1065. PIPSEC_POLICY_DATA pIpsecPolicyData,
  1066. IN DWORD dwSource
  1067. )
  1068. {
  1069. DWORD dwError = 0;
  1070. BOOL bHardError = FALSE;
  1071. dwError = AddMMPolicyInformation(
  1072. pIpsecPolicyData,
  1073. dwSource
  1074. );
  1075. dwError = AddQMPolicyInformation(
  1076. pIpsecPolicyData,
  1077. dwSource,
  1078. &bHardError
  1079. );
  1080. if (bHardError) {
  1081. return (dwError);
  1082. } else {
  1083. return ERROR_SUCCESS;
  1084. }
  1085. }
  1086. DWORD
  1087. AddMMPolicyInformation(
  1088. PIPSEC_POLICY_DATA pIpsecPolicyData,
  1089. IN DWORD dwSource
  1090. )
  1091. {
  1092. DWORD dwError = 0;
  1093. dwError = PAAddMMPolicies(
  1094. &(pIpsecPolicyData->pIpsecISAKMPData),
  1095. 1,
  1096. dwSource
  1097. );
  1098. dwError = PAAddMMAuthMethods(
  1099. pIpsecPolicyData->ppIpsecNFAData,
  1100. pIpsecPolicyData->dwNumNFACount,
  1101. dwSource
  1102. );
  1103. dwError = PAAddMMFilters(
  1104. pIpsecPolicyData->pIpsecISAKMPData,
  1105. pIpsecPolicyData->ppIpsecNFAData,
  1106. pIpsecPolicyData->dwNumNFACount,
  1107. dwSource
  1108. );
  1109. BAIL_ON_WIN32_ERROR(dwError);
  1110. error:
  1111. return (dwError);
  1112. }
  1113. DWORD
  1114. AddQMPolicyInformation(
  1115. PIPSEC_POLICY_DATA pIpsecPolicyData,
  1116. IN DWORD dwSource,
  1117. BOOL * pbHardError
  1118. )
  1119. {
  1120. DWORD dwError = 0;
  1121. BOOL bHardError = FALSE;
  1122. dwError = PAAddQMPolicies(
  1123. pIpsecPolicyData->ppIpsecNFAData,
  1124. pIpsecPolicyData->dwNumNFACount,
  1125. dwSource
  1126. );
  1127. dwError = PAAddQMFilters(
  1128. pIpsecPolicyData->ppIpsecNFAData,
  1129. pIpsecPolicyData->dwNumNFACount,
  1130. dwSource,
  1131. &bHardError
  1132. );
  1133. BAIL_ON_WIN32_ERROR(dwError);
  1134. error:
  1135. *pbHardError = bHardError;
  1136. return (dwError);
  1137. }
  1138. DWORD
  1139. OnPolicyChanged(
  1140. PIPSEC_POLICY_STATE pIpsecPolicyState
  1141. )
  1142. {
  1143. DWORD dwError = 0;
  1144. //
  1145. // Remove all the old policy that was plumbed.
  1146. //
  1147. TRACE(TRC_INFORMATION, ("Pastore deleting existing policy since policy assignment change detected or forced."));
  1148. dwError = DeletePolicyInformation(
  1149. pIpsecPolicyState->pIpsecPolicyData
  1150. );
  1151. ClearPolicyStateBlock(
  1152. pIpsecPolicyState
  1153. );
  1154. // Don't lose track of the fact that we've loaded Persistent policy.
  1155. if (gbPersistentPolicyApplied) {
  1156. SetSpdStateOnError(
  1157. IPSEC_SOURCE_PERSISTENT,
  1158. SPD_POLICY_APPLY,
  1159. ERROR_SUCCESS,
  1160. &pIpsecPolicyState->CurrentState
  1161. );
  1162. }
  1163. //
  1164. // Calling the Initializer again.
  1165. //
  1166. dwError = StartStatePollingManager(
  1167. pIpsecPolicyState
  1168. );
  1169. return (dwError);
  1170. }
  1171. DWORD
  1172. DeletePolicyInformation(
  1173. PIPSEC_POLICY_DATA pIpsecPolicyData
  1174. )
  1175. {
  1176. DWORD dwError = 0;
  1177. if (!pIpsecPolicyData) {
  1178. dwError = ERROR_SUCCESS;
  1179. return (dwError);
  1180. }
  1181. dwError = DeleteMMPolicyInformation(pIpsecPolicyData);
  1182. dwError = DeleteQMPolicyInformation(pIpsecPolicyData);
  1183. dwError = ERROR_SUCCESS;
  1184. return (dwError);
  1185. }
  1186. DWORD
  1187. DeleteMMPolicyInformation(
  1188. PIPSEC_POLICY_DATA pIpsecPolicyData
  1189. )
  1190. {
  1191. DWORD dwError = 0;
  1192. dwError = PADeleteMMFilters(
  1193. pIpsecPolicyData->pIpsecISAKMPData,
  1194. pIpsecPolicyData->ppIpsecNFAData,
  1195. pIpsecPolicyData->dwNumNFACount
  1196. );
  1197. dwError = PADeleteMMAuthMethods(
  1198. pIpsecPolicyData->ppIpsecNFAData,
  1199. pIpsecPolicyData->dwNumNFACount
  1200. );
  1201. dwError = PADeleteMMPolicies(
  1202. &(pIpsecPolicyData->pIpsecISAKMPData),
  1203. 1
  1204. );
  1205. return (dwError);
  1206. }
  1207. DWORD
  1208. DeleteQMPolicyInformation(
  1209. PIPSEC_POLICY_DATA pIpsecPolicyData
  1210. )
  1211. {
  1212. DWORD dwError = 0;
  1213. dwError = PADeleteQMFilters(
  1214. pIpsecPolicyData->ppIpsecNFAData,
  1215. pIpsecPolicyData->dwNumNFACount
  1216. );
  1217. dwError = PADeleteQMPolicies(
  1218. pIpsecPolicyData->ppIpsecNFAData,
  1219. pIpsecPolicyData->dwNumNFACount
  1220. );
  1221. return (dwError);
  1222. }
  1223. DWORD
  1224. DeleteAllPolicyInformation(
  1225. )
  1226. {
  1227. DWORD dwError = 0;
  1228. TRACE(TRC_INFORMATION, (L"Deleting all policy information"));
  1229. dwError = DeleteAllMMPolicyInformation();
  1230. dwError = DeleteAllQMPolicyInformation();
  1231. dwError = ERROR_SUCCESS;
  1232. return (dwError);
  1233. }
  1234. DWORD
  1235. DeleteAllMMPolicyInformation(
  1236. )
  1237. {
  1238. DWORD dwError = 0;
  1239. dwError = PADeleteAllMMFilters();
  1240. dwError = PADeleteAllMMAuthMethods();
  1241. dwError = PADeleteAllMMPolicies();
  1242. return (dwError);
  1243. }
  1244. DWORD
  1245. DeleteAllQMPolicyInformation(
  1246. )
  1247. {
  1248. DWORD dwError = 0;
  1249. dwError = PADeleteAllTxFilters();
  1250. dwError = PADeleteAllTnFilters();
  1251. dwError = PADeleteAllQMPolicies();
  1252. return (dwError);
  1253. }
  1254. VOID
  1255. ClearPolicyStateBlock(
  1256. PIPSEC_POLICY_STATE pIpsecPolicyState
  1257. )
  1258. {
  1259. if (pIpsecPolicyState->pIpsecPolicyObject) {
  1260. FreeIpsecPolicyObject(
  1261. pIpsecPolicyState->pIpsecPolicyObject
  1262. );
  1263. pIpsecPolicyState->pIpsecPolicyObject = NULL;
  1264. }
  1265. if (pIpsecPolicyState->pIpsecPolicyData) {
  1266. FreeIpsecPolicyData(
  1267. pIpsecPolicyState->pIpsecPolicyData
  1268. );
  1269. pIpsecPolicyState->pIpsecPolicyData = NULL;
  1270. }
  1271. if (pIpsecPolicyState->pszDirectoryPolicyDN) {
  1272. FreeSPDStr(pIpsecPolicyState->pszDirectoryPolicyDN);
  1273. pIpsecPolicyState->pszDirectoryPolicyDN = NULL;
  1274. }
  1275. pIpsecPolicyState->CurrentPollingInterval = gDefaultPollingInterval;
  1276. pIpsecPolicyState->DefaultPollingInterval = gDefaultPollingInterval;
  1277. pIpsecPolicyState->DSIncarnationNumber = 0;
  1278. pIpsecPolicyState->RegIncarnationNumber = 0;
  1279. pIpsecPolicyState->CurrentState = SPD_STATE_INITIAL;
  1280. }
  1281. DWORD
  1282. OnPolicyPoll(
  1283. PIPSEC_POLICY_STATE pIpsecPolicyState
  1284. )
  1285. {
  1286. DWORD dwError = 0;
  1287. switch (pIpsecPolicyState->CurrentState) {
  1288. case SPD_STATE_DS_APPLY_SUCCESS:
  1289. // Tell group policy to refresh machine policy.
  1290. // Our GP extension will ping us with NEW_DS_POLICY_EVENT
  1291. // or GPUPDATE_REFRESH_EVENT when it's finished.
  1292. TRACE(TRC_INFORMATION, (L"Requesting group policy to notify policy agent to check for policy changes."));
  1293. RefreshPolicy(TRUE);
  1294. break;
  1295. case SPD_STATE_CACHE_APPLY_SUCCESS:
  1296. dwError = ProcessCachePolicyPollState(pIpsecPolicyState);
  1297. break;
  1298. case SPD_STATE_LOCAL_APPLY_SUCCESS:
  1299. dwError = ProcessLocalPolicyPollState(pIpsecPolicyState);
  1300. break;
  1301. case SPD_STATE_INITIAL:
  1302. case SPD_STATE_PERSISTENT_APPLY_SUCCESS:
  1303. // For these following states need to try to reload polcies from the start.
  1304. //
  1305. dwError = OnPolicyChanged(pIpsecPolicyState);
  1306. break;
  1307. case SPD_STATE_DS_APPLY_FAIL:
  1308. // If DS apply failed, then still have loaded DS data so to reapply loaded data.
  1309. //
  1310. dwError = ApplyLoadedDirectoryPolicy(pIpsecPolicyState);
  1311. // If error rollback. Ignoring rollback errors, because nothing can be done.
  1312. //
  1313. if (dwError) {
  1314. TRACE(TRC_INFORMATION, ("Pastore rolling back policy application due to previous errors"));
  1315. (VOID) DeletePolicyInformation(
  1316. pIpsecPolicyState->pIpsecPolicyData
  1317. );
  1318. }
  1319. break;
  1320. case SPD_STATE_LOCAL_APPLY_FAIL:
  1321. // If apply failed, then still have loaded policy data so to reapply loaded data.
  1322. //
  1323. dwError = ApplyLoadedLocalPolicy(pIpsecPolicyState);
  1324. // If error rollback. Ignoring rollback errors, because nothing can be done.
  1325. //
  1326. if (dwError) {
  1327. TRACE(TRC_INFORMATION, ("Pastore rolling back policy application due to previous errors"));
  1328. (VOID) DeletePolicyInformation(
  1329. pIpsecPolicyState->pIpsecPolicyData
  1330. );
  1331. }
  1332. break;
  1333. case SPD_STATE_LOCAL_LOAD_FAIL:
  1334. dwError = PlumbLocalPolicy(pIpsecPolicyState);
  1335. break;
  1336. case SPD_STATE_DS_LOAD_FAIL:
  1337. case SPD_STATE_CACHE_LOAD_FAIL:
  1338. case SPD_STATE_CACHE_APPLY_FAIL:
  1339. case SPD_STATE_CACHE_LOAD_SUCCESS:
  1340. // if DS policy load failed so try to load *and* apply again.
  1341. // In case of CACHE policy load/apply failue, little point in retrying again,
  1342. // so directly try DS policy again.
  1343. //
  1344. dwError = PlumbDirectoryPolicy(pIpsecPolicyState);
  1345. break;
  1346. default:
  1347. // Any other state is unexpected during polling
  1348. // We should be in *APPLY_SUCCESS or *APPLY_FAIL or *LOAD_FAIL
  1349. // SPD_STATE_DS_LOAD_SUCCESS,
  1350. // SPD_STATE_LOCAL_LOAD_SUCCESS,
  1351. // SPD_STATE_PERSISTENT_LOAD_SUCCESS
  1352. // For the following errors we should have shutdown and not
  1353. // be here.
  1354. // SPD_STATE_PERSISTENT_LOAD_FAIL
  1355. // SPD_STATE_PERSISTENT_APPLY_FAIL
  1356. ASSERT(FALSE);
  1357. break;
  1358. }
  1359. //
  1360. // Set the new polling interval.
  1361. //
  1362. gCurrentPollingInterval = pIpsecPolicyState->CurrentPollingInterval;
  1363. TRACE(
  1364. TRC_INFORMATION,
  1365. ("Set global polling interval to %d",
  1366. gCurrentPollingInterval)
  1367. );
  1368. if (InAcceptableState(pIpsecPolicyState->CurrentState)) {
  1369. gdwRetryCount = 0;
  1370. } else {
  1371. gdwRetryCount++;
  1372. }
  1373. return (dwError);
  1374. }
  1375. DWORD
  1376. ProcessDirectoryPolicyPollState(
  1377. PIPSEC_POLICY_STATE pIpsecPolicyState
  1378. )
  1379. {
  1380. DWORD dwError = 0;
  1381. DWORD dwIncarnationNumber = 0;
  1382. PIPSEC_POLICY_OBJECT pIpsecPolicyObject = NULL;
  1383. PIPSEC_POLICY_DATA pIpsecPolicyData = NULL;
  1384. DWORD dwStoreType = IPSEC_DIRECTORY_PROVIDER;
  1385. DWORD dwSlientErrorCode = 0;
  1386. if (pIpsecPolicyState->CurrentState != SPD_STATE_DS_APPLY_SUCCESS) {
  1387. TRACE(TRC_INFORMATION, (L"Pastore not checking whether directory policy has been modified because not in DS apply success."));
  1388. return ERROR_SUCCESS;
  1389. }
  1390. //
  1391. // The directory policy DN has to be the same, otherwise the
  1392. // IPSec extension in Winlogon would have already notified
  1393. // PA Store of the DS policy change.
  1394. //
  1395. TRACE(TRC_INFORMATION, (L"Pastore checking whether directory policy has been modified."));
  1396. dwError = GetDirectoryIncarnationNumber(
  1397. pIpsecPolicyState->pszDirectoryPolicyDN,
  1398. &dwIncarnationNumber
  1399. );
  1400. if (dwError) {
  1401. dwError = MigrateFromDSToCache(pIpsecPolicyState);
  1402. BAIL_ON_WIN32_ERROR(dwError);
  1403. return (ERROR_SUCCESS);
  1404. }
  1405. if (dwIncarnationNumber == pIpsecPolicyState->DSIncarnationNumber) {
  1406. //
  1407. // The policy has not changed at all.
  1408. //
  1409. AuditEvent(
  1410. SE_CATEGID_POLICY_CHANGE,
  1411. SE_AUDITID_IPSEC_POLICY_CHANGED,
  1412. PASTORE_POLLING_NO_CHANGES,
  1413. NULL,
  1414. TRUE,
  1415. TRUE
  1416. );
  1417. TRACE(TRC_INFORMATION, (L"Pastore did not detect any policy change."));
  1418. return (ERROR_SUCCESS);
  1419. }
  1420. //
  1421. // The incarnation number is different, so there's a need to
  1422. // update the policy.
  1423. //
  1424. TRACE(TRC_INFORMATION, (L"Pastore detected that policy has been modified. Performing policy update."));
  1425. dwError = LoadDirectoryPolicy(
  1426. pIpsecPolicyState->pszDirectoryPolicyDN,
  1427. &pIpsecPolicyObject
  1428. );
  1429. if (dwError) {
  1430. dwError = MigrateFromDSToCache(pIpsecPolicyState);
  1431. BAIL_ON_WIN32_ERROR(dwError);
  1432. return (ERROR_SUCCESS);
  1433. }
  1434. dwError = ProcessNFAs(
  1435. pIpsecPolicyObject,
  1436. dwStoreType,
  1437. &dwSlientErrorCode,
  1438. &pIpsecPolicyData
  1439. );
  1440. if (dwError) {
  1441. TRACE(
  1442. TRC_ERROR,
  1443. (L"Pastore failure when processing NFAs. Will migrate from directory to cache: %!winerr!",
  1444. dwError)
  1445. );
  1446. dwError = MigrateFromDSToCache(pIpsecPolicyState);
  1447. BAIL_ON_WIN32_ERROR(dwError);
  1448. if (pIpsecPolicyObject) {
  1449. FreeIpsecPolicyObject(pIpsecPolicyObject);
  1450. }
  1451. return (ERROR_SUCCESS);
  1452. }
  1453. dwError = UpdatePolicyInformation(
  1454. pIpsecPolicyState->pIpsecPolicyData,
  1455. pIpsecPolicyData,
  1456. IPSEC_SOURCE_DOMAIN
  1457. );
  1458. if (pIpsecPolicyState->pIpsecPolicyObject) {
  1459. FreeIpsecPolicyObject(pIpsecPolicyState->pIpsecPolicyObject);
  1460. }
  1461. if (pIpsecPolicyState->pIpsecPolicyData) {
  1462. FreeIpsecPolicyData(pIpsecPolicyState->pIpsecPolicyData);
  1463. }
  1464. //
  1465. // Now delete the old cache and write the new one in.
  1466. //
  1467. DeleteRegistryCache();
  1468. CacheDirectorytoRegistry(pIpsecPolicyObject);
  1469. pIpsecPolicyState->pIpsecPolicyObject = pIpsecPolicyObject;
  1470. pIpsecPolicyState->pIpsecPolicyData = pIpsecPolicyData;
  1471. pIpsecPolicyState->CurrentPollingInterval = pIpsecPolicyData->dwPollingInterval;
  1472. pIpsecPolicyState->DSIncarnationNumber = dwIncarnationNumber;
  1473. NotifyIpsecPolicyChange();
  1474. dwError = ERROR_SUCCESS;
  1475. if (dwSlientErrorCode) {
  1476. AuditIPSecPolicyErrorEvent(
  1477. SE_CATEGID_POLICY_CHANGE,
  1478. SE_AUDITID_IPSEC_POLICY_CHANGED,
  1479. PASTORE_FAILED_SOME_NFA_APPLICATION,
  1480. pIpsecPolicyData->pszIpsecName,
  1481. dwSlientErrorCode,
  1482. FALSE,
  1483. TRUE
  1484. );
  1485. TRACE(
  1486. TRC_WARNING,
  1487. ("Pastore failed to process one or more NFAs. Please compare active policy in SPD with policy in storage: %!winerr!",
  1488. dwSlientErrorCode)
  1489. );
  1490. }
  1491. AuditEvent(
  1492. SE_CATEGID_POLICY_CHANGE,
  1493. SE_AUDITID_IPSEC_POLICY_CHANGED,
  1494. PASTORE_POLLING_APPLIED_CHANGES,
  1495. NULL,
  1496. TRUE,
  1497. TRUE
  1498. );
  1499. return (dwError);
  1500. error:
  1501. TRACE(
  1502. TRC_ERROR,
  1503. (L"Pastore failed when checking for policy change on poll: %!winerr!",
  1504. dwError)
  1505. );
  1506. if (pIpsecPolicyObject) {
  1507. FreeIpsecPolicyObject(pIpsecPolicyObject);
  1508. }
  1509. if (pIpsecPolicyData) {
  1510. FreeIpsecPolicyData(pIpsecPolicyData);
  1511. }
  1512. return (dwError);
  1513. }
  1514. DWORD
  1515. GetDirectoryIncarnationNumber(
  1516. LPWSTR pszIpsecPolicyDN,
  1517. DWORD * pdwIncarnationNumber
  1518. )
  1519. {
  1520. DWORD dwError = 0;
  1521. LPWSTR pszDefaultDirectory = NULL;
  1522. HLDAP hLdapBindHandle = NULL;
  1523. LPWSTR Attributes[] = {L"whenChanged", NULL};
  1524. LDAPMessage *res = NULL;
  1525. LDAPMessage *e = NULL;
  1526. WCHAR **strvalues = NULL;
  1527. DWORD dwCount = 0;
  1528. time_t t_WhenChanged = 0;
  1529. *pdwIncarnationNumber = 0;
  1530. //
  1531. // Open the directory store.
  1532. //
  1533. dwError = ComputeDefaultDirectory(
  1534. &pszDefaultDirectory
  1535. );
  1536. BAIL_ON_WIN32_ERROR(dwError);
  1537. dwError = OpenDirectoryServerHandle(
  1538. pszDefaultDirectory,
  1539. 389,
  1540. &hLdapBindHandle
  1541. );
  1542. BAIL_ON_WIN32_ERROR(dwError);
  1543. dwError = LdapSearchST(
  1544. hLdapBindHandle,
  1545. pszIpsecPolicyDN,
  1546. LDAP_SCOPE_BASE,
  1547. L"(objectClass=*)",
  1548. Attributes,
  1549. 0,
  1550. NULL,
  1551. &res
  1552. );
  1553. BAIL_ON_WIN32_ERROR(dwError);
  1554. dwError = LdapFirstEntry(
  1555. hLdapBindHandle,
  1556. res,
  1557. &e
  1558. );
  1559. BAIL_ON_WIN32_ERROR(dwError);
  1560. dwError = LdapGetValues(
  1561. hLdapBindHandle,
  1562. e,
  1563. L"whenChanged",
  1564. (WCHAR ***)&strvalues,
  1565. (int *)&dwCount
  1566. );
  1567. BAIL_ON_WIN32_ERROR(dwError);
  1568. dwError = GeneralizedTimeToTime(
  1569. LDAPOBJECT_STRING((PLDAPOBJECT)strvalues),
  1570. &t_WhenChanged
  1571. );
  1572. BAIL_ON_WIN32_ERROR(dwError);
  1573. *pdwIncarnationNumber = TIME_T_TO_DWORD(t_WhenChanged);
  1574. error:
  1575. #ifdef TRACE_ON
  1576. if (dwError) {
  1577. TRACE(TRC_ERROR, ("Pastore failed to get directory policy change date/time: %!winerr!", dwError));
  1578. }
  1579. #endif
  1580. if (pszDefaultDirectory) {
  1581. FreeSPDStr(pszDefaultDirectory);
  1582. }
  1583. if (hLdapBindHandle) {
  1584. CloseDirectoryServerHandle(hLdapBindHandle);
  1585. }
  1586. if (res) {
  1587. LdapMsgFree(res);
  1588. }
  1589. if (strvalues) {
  1590. LdapValueFree(strvalues);
  1591. }
  1592. return (dwError);
  1593. }
  1594. DWORD
  1595. MigrateFromDSToCache(
  1596. PIPSEC_POLICY_STATE pIpsecPolicyState
  1597. )
  1598. {
  1599. DWORD dwError = 0;
  1600. LPWSTR pszCachePolicyDN = NULL;
  1601. TRACE(TRC_INFORMATION, ("Migrating from directory to cache policy."));
  1602. dwError = GetCachePolicyDN(
  1603. &pszCachePolicyDN
  1604. );
  1605. BAIL_ON_WIN32_ERROR(dwError);
  1606. if (pIpsecPolicyState->pszDirectoryPolicyDN) {
  1607. FreeSPDStr(pIpsecPolicyState->pszDirectoryPolicyDN);
  1608. pIpsecPolicyState->pszDirectoryPolicyDN = NULL;
  1609. }
  1610. pIpsecPolicyState->pszCachePolicyDN = pszCachePolicyDN;
  1611. //
  1612. // Keep pIpsecPolicyState->pIpsecPolicyData.
  1613. // Keep pIpsecPolicyState->pIpsecPolicyObject.
  1614. // Change the incarnation numbers.
  1615. //
  1616. pIpsecPolicyState->RegIncarnationNumber = pIpsecPolicyState->DSIncarnationNumber;
  1617. pIpsecPolicyState->DSIncarnationNumber = 0;
  1618. SetSpdStateOnError(
  1619. IPSEC_SOURCE_CACHE,
  1620. SPD_POLICY_APPLY,
  1621. ERROR_SUCCESS,
  1622. &pIpsecPolicyState->CurrentState
  1623. );
  1624. //
  1625. // Keep pIpsecPolicyState->CurrentPollingInterval.
  1626. // Keep pIpsecPolicyState->DefaultPollingInterval.
  1627. //
  1628. gCurrentPollingInterval = pIpsecPolicyState->CurrentPollingInterval;
  1629. TRACE(
  1630. TRC_INFORMATION,
  1631. ("Set global polling interval to %d",
  1632. gCurrentPollingInterval)
  1633. );
  1634. AuditEvent(
  1635. SE_CATEGID_POLICY_CHANGE,
  1636. SE_AUDITID_IPSEC_POLICY_CHANGED,
  1637. PASTORE_MIGRATE_DS_TO_CACHE,
  1638. NULL,
  1639. TRUE,
  1640. TRUE
  1641. );
  1642. TRACE(TRC_INFORMATION, (L"Pastore migrated from cache to directory policy."));
  1643. error:
  1644. return (dwError);
  1645. }
  1646. DWORD
  1647. ProcessCachePolicyPollState(
  1648. PIPSEC_POLICY_STATE pIpsecPolicyState
  1649. )
  1650. {
  1651. DWORD dwError = 0;
  1652. LPWSTR pszDirectoryPolicyDN = NULL;
  1653. DWORD dwIncarnationNumber = 0;
  1654. LPWSTR pszCachePolicyDN = NULL;
  1655. TRACE(TRC_INFORMATION, (L"Detecting if cache change time is different from directory change time."));
  1656. dwError = GetDirectoryPolicyDN(
  1657. &pszDirectoryPolicyDN
  1658. );
  1659. if (!dwError) {
  1660. dwError = GetDirectoryIncarnationNumber(
  1661. pszDirectoryPolicyDN,
  1662. &dwIncarnationNumber
  1663. );
  1664. if (!dwError) {
  1665. dwError = CopyPolicyDSToFQRegString(
  1666. pszDirectoryPolicyDN,
  1667. &pszCachePolicyDN
  1668. );
  1669. if (!dwError) {
  1670. if (!_wcsicmp(pIpsecPolicyState->pszCachePolicyDN, pszCachePolicyDN)) {
  1671. if (pIpsecPolicyState->RegIncarnationNumber == dwIncarnationNumber) {
  1672. dwError = MigrateFromCacheToDS(pIpsecPolicyState);
  1673. }
  1674. else {
  1675. dwError = UpdateFromCacheToDS(pIpsecPolicyState);
  1676. }
  1677. if (dwError) {
  1678. dwError = OnPolicyChanged(pIpsecPolicyState);
  1679. }
  1680. }
  1681. else {
  1682. dwError = OnPolicyChanged(pIpsecPolicyState);
  1683. }
  1684. }
  1685. }
  1686. }
  1687. if (pszDirectoryPolicyDN) {
  1688. FreeSPDStr(pszDirectoryPolicyDN);
  1689. }
  1690. if (pszCachePolicyDN) {
  1691. FreeSPDStr(pszCachePolicyDN);
  1692. }
  1693. return (ERROR_SUCCESS);
  1694. }
  1695. DWORD
  1696. MigrateFromCacheToDS(
  1697. PIPSEC_POLICY_STATE pIpsecPolicyState
  1698. )
  1699. {
  1700. DWORD dwError = 0;
  1701. LPWSTR pszDirectoryPolicyDN = NULL;
  1702. dwError = GetDirectoryPolicyDN(
  1703. &pszDirectoryPolicyDN
  1704. );
  1705. BAIL_ON_WIN32_ERROR(dwError);
  1706. if (pIpsecPolicyState->pszCachePolicyDN) {
  1707. FreeSPDStr(pIpsecPolicyState->pszCachePolicyDN);
  1708. pIpsecPolicyState->pszCachePolicyDN = NULL;
  1709. }
  1710. pIpsecPolicyState->pszDirectoryPolicyDN = pszDirectoryPolicyDN;
  1711. //
  1712. // Keep pIpsecPolicyState->pIpsecPolicyData.
  1713. // Keep pIpsecPolicyState->pIpsecPolicyObject.
  1714. // Change the incarnation numbers.
  1715. //
  1716. pIpsecPolicyState->DSIncarnationNumber = pIpsecPolicyState->RegIncarnationNumber;
  1717. pIpsecPolicyState->RegIncarnationNumber = 0;
  1718. SetSpdStateOnError(
  1719. IPSEC_SOURCE_DOMAIN,
  1720. SPD_POLICY_APPLY,
  1721. ERROR_SUCCESS,
  1722. &pIpsecPolicyState->CurrentState
  1723. );
  1724. //
  1725. // Keep pIpsecPolicyState->CurrentPollingInterval.
  1726. // Keep pIpsecPolicyState->DefaultPollingInterval.
  1727. //
  1728. gCurrentPollingInterval = pIpsecPolicyState->CurrentPollingInterval;
  1729. AuditEvent(
  1730. SE_CATEGID_POLICY_CHANGE,
  1731. SE_AUDITID_IPSEC_POLICY_CHANGED,
  1732. PASTORE_MIGRATE_CACHE_TO_DS,
  1733. NULL,
  1734. TRUE,
  1735. TRUE
  1736. );
  1737. error:
  1738. return (dwError);
  1739. }
  1740. DWORD
  1741. UpdateFromCacheToDS(
  1742. PIPSEC_POLICY_STATE pIpsecPolicyState
  1743. )
  1744. {
  1745. DWORD dwError = 0;
  1746. LPWSTR pszDirectoryPolicyDN = NULL;
  1747. PIPSEC_POLICY_OBJECT pIpsecPolicyObject = NULL;
  1748. PIPSEC_POLICY_DATA pIpsecPolicyData = NULL;
  1749. DWORD dwStoreType = IPSEC_DIRECTORY_PROVIDER;
  1750. DWORD dwSlientErrorCode = 0;
  1751. TRACE(TRC_INFORMATION, (L"Detect difference between plumbed cache, and directory policy. Updating plumbed policy."));
  1752. dwError = GetDirectoryPolicyDN(
  1753. &pszDirectoryPolicyDN
  1754. );
  1755. BAIL_ON_WIN32_ERROR(dwError);
  1756. dwError = LoadDirectoryPolicy(
  1757. pszDirectoryPolicyDN,
  1758. &pIpsecPolicyObject
  1759. );
  1760. BAIL_ON_WIN32_ERROR(dwError);
  1761. dwError = ProcessNFAs(
  1762. pIpsecPolicyObject,
  1763. dwStoreType,
  1764. &dwSlientErrorCode,
  1765. &pIpsecPolicyData
  1766. );
  1767. BAIL_ON_WIN32_ERROR(dwError);
  1768. dwError = UpdatePolicyInformation(
  1769. pIpsecPolicyState->pIpsecPolicyData,
  1770. pIpsecPolicyData,
  1771. IPSEC_SOURCE_DOMAIN
  1772. );
  1773. if (pIpsecPolicyState->pIpsecPolicyObject) {
  1774. FreeIpsecPolicyObject(pIpsecPolicyState->pIpsecPolicyObject);
  1775. }
  1776. if (pIpsecPolicyState->pIpsecPolicyData) {
  1777. FreeIpsecPolicyData(pIpsecPolicyState->pIpsecPolicyData);
  1778. }
  1779. if (pIpsecPolicyState->pszCachePolicyDN) {
  1780. FreeSPDStr(pIpsecPolicyState->pszCachePolicyDN);
  1781. }
  1782. //
  1783. // Now delete the old cache and write the new one in.
  1784. //
  1785. DeleteRegistryCache();
  1786. CacheDirectorytoRegistry(pIpsecPolicyObject);
  1787. pIpsecPolicyState->pIpsecPolicyObject = pIpsecPolicyObject;
  1788. pIpsecPolicyState->pIpsecPolicyData = pIpsecPolicyData;
  1789. pIpsecPolicyState->pszDirectoryPolicyDN = pszDirectoryPolicyDN;
  1790. //
  1791. // Set the state to DS-DOWNLOADED.
  1792. //
  1793. SetSpdStateOnError(
  1794. IPSEC_SOURCE_DOMAIN,
  1795. SPD_POLICY_APPLY,
  1796. ERROR_SUCCESS,
  1797. &pIpsecPolicyState->CurrentState
  1798. );
  1799. //
  1800. // Compute the new polling interval.
  1801. //
  1802. pIpsecPolicyState->CurrentPollingInterval = pIpsecPolicyData->dwPollingInterval;
  1803. pIpsecPolicyState->DSIncarnationNumber = pIpsecPolicyData->dwWhenChanged;
  1804. pIpsecPolicyState->RegIncarnationNumber = 0;
  1805. gCurrentPollingInterval = pIpsecPolicyState->CurrentPollingInterval;
  1806. NotifyIpsecPolicyChange();
  1807. dwError = ERROR_SUCCESS;
  1808. if (dwSlientErrorCode) {
  1809. AuditIPSecPolicyErrorEvent(
  1810. SE_CATEGID_POLICY_CHANGE,
  1811. SE_AUDITID_IPSEC_POLICY_CHANGED,
  1812. PASTORE_FAILED_SOME_NFA_APPLICATION,
  1813. pIpsecPolicyData->pszIpsecName,
  1814. dwSlientErrorCode,
  1815. FALSE,
  1816. TRUE
  1817. );
  1818. TRACE(
  1819. TRC_WARNING,
  1820. ("Pastore failed to process one or more NFAs. Please compare active policy in SPD with policy in storage: %!winerr!",
  1821. dwSlientErrorCode)
  1822. );
  1823. }
  1824. AuditEvent(
  1825. SE_CATEGID_POLICY_CHANGE,
  1826. SE_AUDITID_IPSEC_POLICY_CHANGED,
  1827. PASTORE_UPDATE_CACHE_TO_DS,
  1828. NULL,
  1829. TRUE,
  1830. TRUE
  1831. );
  1832. return (dwError);
  1833. error:
  1834. if (pszDirectoryPolicyDN) {
  1835. FreeSPDStr(pszDirectoryPolicyDN);
  1836. }
  1837. if (pIpsecPolicyObject) {
  1838. FreeIpsecPolicyObject(pIpsecPolicyObject);
  1839. }
  1840. if (pIpsecPolicyData) {
  1841. FreeIpsecPolicyData(pIpsecPolicyData);
  1842. }
  1843. return (dwError);
  1844. }
  1845. DWORD
  1846. ProcessLocalPolicyPollState(
  1847. PIPSEC_POLICY_STATE pIpsecPolicyState
  1848. )
  1849. {
  1850. DWORD dwStatus = 0;
  1851. LPWSTR pszDirectoryPolicyDN = NULL;
  1852. DWORD dwDSIncarnationNumber = 0;
  1853. DWORD dwError = 0;
  1854. BOOL bChanged = FALSE;
  1855. DWORD dwIncarnationNumber = 0;
  1856. PIPSEC_POLICY_OBJECT pIpsecPolicyObject = NULL;
  1857. PIPSEC_POLICY_DATA pIpsecPolicyData = NULL;
  1858. DWORD dwStoreType = IPSEC_REGISTRY_PROVIDER;
  1859. DWORD dwSlientErrorCode = 0;
  1860. TRACE(TRC_INFORMATION, (L"Pastore checking whether local policy assignment has changed."));
  1861. dwStatus = GetDirectoryPolicyDN(
  1862. &pszDirectoryPolicyDN
  1863. );
  1864. if (!dwStatus) {
  1865. dwStatus = GetDirectoryIncarnationNumber(
  1866. pszDirectoryPolicyDN,
  1867. &dwDSIncarnationNumber
  1868. );
  1869. if (pszDirectoryPolicyDN) {
  1870. FreeSPDStr(pszDirectoryPolicyDN);
  1871. }
  1872. if (!dwStatus) {
  1873. dwStatus = OnPolicyChanged(pIpsecPolicyState);
  1874. return (dwStatus);
  1875. }
  1876. }
  1877. dwError = HasRegistryPolicyChanged(
  1878. pIpsecPolicyState->pszRegistryPolicyDN,
  1879. &bChanged
  1880. );
  1881. BAIL_ON_WIN32_ERROR(dwError);
  1882. if (bChanged) {
  1883. dwError = OnPolicyChanged(pIpsecPolicyState);
  1884. return (dwError);
  1885. }
  1886. if (pIpsecPolicyState->CurrentState == SPD_STATE_INITIAL) {
  1887. return (ERROR_SUCCESS);
  1888. }
  1889. dwError = GetRegistryIncarnationNumber(
  1890. pIpsecPolicyState->pszRegistryPolicyDN,
  1891. &dwIncarnationNumber
  1892. );
  1893. BAIL_ON_WIN32_ERROR(dwError);
  1894. if (dwIncarnationNumber == pIpsecPolicyState->RegIncarnationNumber) {
  1895. //
  1896. // The policy has not changed at all.
  1897. //
  1898. AuditEvent(
  1899. SE_CATEGID_POLICY_CHANGE,
  1900. SE_AUDITID_IPSEC_POLICY_CHANGED,
  1901. PASTORE_POLLING_NO_CHANGES,
  1902. NULL,
  1903. TRUE,
  1904. TRUE
  1905. );
  1906. TRACE(TRC_INFORMATION, (L"Pastore did not detect any policy change."));
  1907. return (ERROR_SUCCESS);
  1908. }
  1909. TRACE(TRC_INFORMATION, (L"Pastore detected that policy has been modified. Performing policy update."));
  1910. dwError = LoadRegistryPolicy(
  1911. pIpsecPolicyState->pszRegistryPolicyDN,
  1912. &pIpsecPolicyObject,
  1913. IPSEC_STORE_LOCAL
  1914. );
  1915. BAIL_ON_WIN32_ERROR(dwError);
  1916. dwError = ProcessNFAs(
  1917. pIpsecPolicyObject,
  1918. dwStoreType,
  1919. &dwSlientErrorCode,
  1920. &pIpsecPolicyData
  1921. );
  1922. BAIL_ON_WIN32_ERROR(dwError);
  1923. dwError = UpdatePolicyInformation(
  1924. pIpsecPolicyState->pIpsecPolicyData,
  1925. pIpsecPolicyData,
  1926. IPSEC_SOURCE_LOCAL
  1927. );
  1928. if (pIpsecPolicyState->pIpsecPolicyObject) {
  1929. FreeIpsecPolicyObject(pIpsecPolicyState->pIpsecPolicyObject);
  1930. }
  1931. if (pIpsecPolicyState->pIpsecPolicyData) {
  1932. FreeIpsecPolicyData(pIpsecPolicyState->pIpsecPolicyData);
  1933. }
  1934. pIpsecPolicyState->pIpsecPolicyObject = pIpsecPolicyObject;
  1935. pIpsecPolicyState->pIpsecPolicyData = pIpsecPolicyData;
  1936. pIpsecPolicyState->CurrentPollingInterval = pIpsecPolicyData->dwPollingInterval;
  1937. pIpsecPolicyState->RegIncarnationNumber = dwIncarnationNumber;
  1938. NotifyIpsecPolicyChange();
  1939. dwError = ERROR_SUCCESS;
  1940. if (dwSlientErrorCode) {
  1941. AuditIPSecPolicyErrorEvent(
  1942. SE_CATEGID_POLICY_CHANGE,
  1943. SE_AUDITID_IPSEC_POLICY_CHANGED,
  1944. PASTORE_FAILED_SOME_NFA_APPLICATION,
  1945. pIpsecPolicyData->pszIpsecName,
  1946. dwSlientErrorCode,
  1947. FALSE,
  1948. TRUE
  1949. );
  1950. TRACE(
  1951. TRC_WARNING,
  1952. ("Pastore failed to process one or more NFAs. Please compare active policy in SPD with policy in storage: %!winerr!",
  1953. dwSlientErrorCode )
  1954. );
  1955. }
  1956. AuditEvent(
  1957. SE_CATEGID_POLICY_CHANGE,
  1958. SE_AUDITID_IPSEC_POLICY_CHANGED,
  1959. PASTORE_POLLING_APPLIED_CHANGES,
  1960. NULL,
  1961. TRUE,
  1962. TRUE
  1963. );
  1964. return (dwError);
  1965. error:
  1966. TRACE(
  1967. TRC_ERROR,
  1968. (L"Pastore failed when checking for policy change on poll: %!winerr!",
  1969. dwError)
  1970. );
  1971. if (pIpsecPolicyObject) {
  1972. FreeIpsecPolicyObject(pIpsecPolicyObject);
  1973. }
  1974. if (pIpsecPolicyData) {
  1975. FreeIpsecPolicyData(pIpsecPolicyData);
  1976. }
  1977. return (dwError);
  1978. }
  1979. DWORD
  1980. HasRegistryPolicyChanged(
  1981. LPWSTR pszCurrentPolicyDN,
  1982. PBOOL pbChanged
  1983. )
  1984. {
  1985. DWORD dwError = 0;
  1986. HKEY hRegKey = NULL;
  1987. LPWSTR pszIpsecPolicyName = NULL;
  1988. DWORD dwSize = 0;
  1989. BOOL bChanged = FALSE;
  1990. dwError = RegOpenKeyExW(
  1991. HKEY_LOCAL_MACHINE,
  1992. gpszIpsecLocalPolicyKey,
  1993. 0,
  1994. KEY_ALL_ACCESS,
  1995. &hRegKey
  1996. );
  1997. BAIL_ON_WIN32_ERROR(dwError);
  1998. dwError = RegstoreQueryValue(
  1999. hRegKey,
  2000. L"ActivePolicy",
  2001. REG_SZ,
  2002. (LPBYTE *)&pszIpsecPolicyName,
  2003. &dwSize
  2004. );
  2005. //
  2006. // Must not bail from here, as there can be no
  2007. // active local policy.
  2008. //
  2009. if (pszIpsecPolicyName && *pszIpsecPolicyName) {
  2010. if (!pszCurrentPolicyDN || !*pszCurrentPolicyDN) {
  2011. bChanged = TRUE;
  2012. }
  2013. else {
  2014. if (!_wcsicmp(pszIpsecPolicyName, pszCurrentPolicyDN)) {
  2015. bChanged = FALSE;
  2016. }
  2017. else {
  2018. bChanged = TRUE;
  2019. }
  2020. }
  2021. }
  2022. else {
  2023. if (!pszCurrentPolicyDN || !*pszCurrentPolicyDN) {
  2024. bChanged = FALSE;
  2025. }
  2026. else {
  2027. bChanged = TRUE;
  2028. }
  2029. }
  2030. *pbChanged = bChanged;
  2031. dwError = ERROR_SUCCESS;
  2032. cleanup:
  2033. if (hRegKey) {
  2034. CloseHandle(hRegKey);
  2035. }
  2036. if (pszIpsecPolicyName) {
  2037. FreeSPDStr(pszIpsecPolicyName);
  2038. }
  2039. return (dwError);
  2040. error:
  2041. TRACE(TRC_ERROR, ("Pastore failed when trying to detect if local policy assigment has changed: %!winerr!", dwError));
  2042. *pbChanged = FALSE;
  2043. goto cleanup;
  2044. }
  2045. DWORD
  2046. GetRegistryIncarnationNumber(
  2047. LPWSTR pszIpsecPolicyDN,
  2048. DWORD * pdwIncarnationNumber
  2049. )
  2050. {
  2051. DWORD dwError = 0;
  2052. HKEY hRegKey = NULL;
  2053. DWORD dwType = REG_DWORD;
  2054. DWORD dwWhenChanged = 0;
  2055. DWORD dwSize = sizeof(DWORD);
  2056. *pdwIncarnationNumber = 0;
  2057. dwError = RegOpenKeyExW(
  2058. HKEY_LOCAL_MACHINE,
  2059. pszIpsecPolicyDN,
  2060. 0,
  2061. KEY_ALL_ACCESS,
  2062. &hRegKey
  2063. );
  2064. BAIL_ON_WIN32_ERROR(dwError);
  2065. dwError = RegQueryValueExW(
  2066. hRegKey,
  2067. L"whenChanged",
  2068. NULL,
  2069. &dwType,
  2070. (LPBYTE)&dwWhenChanged,
  2071. &dwSize
  2072. );
  2073. BAIL_ON_WIN32_ERROR(dwError);
  2074. *pdwIncarnationNumber = dwWhenChanged;
  2075. error:
  2076. #ifdef TRACE_ON
  2077. if (dwError) {
  2078. TRACE(TRC_ERROR, ("Pastore failed to get registry change date/time: %!winerr!", dwError));
  2079. }
  2080. #endif
  2081. if (hRegKey) {
  2082. CloseHandle(hRegKey);
  2083. }
  2084. return(dwError);
  2085. }
  2086. DWORD
  2087. UpdatePolicyInformation(
  2088. PIPSEC_POLICY_DATA pOldIpsecPolicyData,
  2089. PIPSEC_POLICY_DATA pNewIpsecPolicyData,
  2090. IN DWORD dwSource
  2091. )
  2092. {
  2093. DWORD dwError = 0;
  2094. PIPSEC_ISAKMP_DATA pOldIpsecISAKMPData = NULL;
  2095. PIPSEC_NFA_DATA * ppOldIpsecNFAData = NULL;
  2096. DWORD dwNumOldNFACount = 0;
  2097. PIPSEC_ISAKMP_DATA pNewIpsecISAKMPData = NULL;
  2098. PIPSEC_NFA_DATA * ppNewIpsecNFAData = NULL;
  2099. DWORD dwNumNewNFACount = 0;
  2100. pOldIpsecISAKMPData = pOldIpsecPolicyData->pIpsecISAKMPData;
  2101. ppOldIpsecNFAData = pOldIpsecPolicyData->ppIpsecNFAData;
  2102. dwNumOldNFACount = pOldIpsecPolicyData->dwNumNFACount;
  2103. pNewIpsecISAKMPData = pNewIpsecPolicyData->pIpsecISAKMPData;
  2104. ppNewIpsecNFAData = pNewIpsecPolicyData->ppIpsecNFAData;
  2105. dwNumNewNFACount = pNewIpsecPolicyData->dwNumNFACount;
  2106. TRACE(
  2107. TRC_INFORMATION,
  2108. (L"Pastore performing policy update")
  2109. );
  2110. dwError = PADeleteObseleteISAKMPData(
  2111. &pOldIpsecISAKMPData,
  2112. 1,
  2113. ppOldIpsecNFAData,
  2114. dwNumOldNFACount,
  2115. &pNewIpsecISAKMPData,
  2116. 1
  2117. );
  2118. dwError = PAUpdateISAKMPData(
  2119. &pNewIpsecISAKMPData,
  2120. 1,
  2121. ppOldIpsecNFAData,
  2122. dwNumOldNFACount,
  2123. &pOldIpsecISAKMPData,
  2124. 1,
  2125. dwSource
  2126. );
  2127. dwError = PADeleteObseleteNFAData(
  2128. pNewIpsecISAKMPData,
  2129. ppOldIpsecNFAData,
  2130. dwNumOldNFACount,
  2131. ppNewIpsecNFAData,
  2132. dwNumNewNFACount
  2133. );
  2134. dwError = PAUpdateNFAData(
  2135. pNewIpsecISAKMPData,
  2136. ppNewIpsecNFAData,
  2137. dwNumNewNFACount,
  2138. ppOldIpsecNFAData,
  2139. dwNumOldNFACount,
  2140. dwSource
  2141. );
  2142. return (dwError);
  2143. }
  2144. DWORD
  2145. LoadDefaultISAKMPInformation(
  2146. LPWSTR pszDefaultISAKMPDN
  2147. )
  2148. {
  2149. DWORD dwError = 0;
  2150. gbLoadedISAKMPDefaults = TRUE;
  2151. return (dwError);
  2152. }
  2153. VOID
  2154. UnLoadDefaultISAKMPInformation(
  2155. LPWSTR pszDefaultISAKMPDN
  2156. )
  2157. {
  2158. return;
  2159. }
  2160. BOOL
  2161. IsDirectoryPolicySpecified(
  2162. )
  2163. {
  2164. DWORD dwError = ERROR_SUCCESS;
  2165. LPWSTR pszDirectoryPolicyDN = NULL;
  2166. dwError = GetDirectoryPolicyDN(
  2167. &pszDirectoryPolicyDN
  2168. );
  2169. if (pszDirectoryPolicyDN) {
  2170. FreeSPDStr(pszDirectoryPolicyDN);
  2171. }
  2172. if (dwError) {
  2173. return FALSE;
  2174. } else {
  2175. return TRUE;
  2176. }
  2177. }
  2178. BOOL
  2179. IsLocalPolicySpecified(
  2180. )
  2181. {
  2182. DWORD dwError = ERROR_SUCCESS;
  2183. LPWSTR pszRegistryPolicyDN = NULL;
  2184. dwError = GetRegistryPolicyDN(
  2185. &pszRegistryPolicyDN,
  2186. IPSEC_STORE_LOCAL
  2187. );
  2188. if (pszRegistryPolicyDN) {
  2189. FreeSPDStr(pszRegistryPolicyDN);
  2190. }
  2191. if (dwError) {
  2192. return FALSE;
  2193. } else {
  2194. return TRUE;
  2195. }
  2196. }
  2197. BOOL
  2198. IsPersistentPolicySpecified(
  2199. )
  2200. {
  2201. DWORD dwError = ERROR_SUCCESS;
  2202. LPWSTR pszRegistryPolicyDN = NULL;
  2203. dwError = GetRegistryPolicyDN(
  2204. &pszRegistryPolicyDN,
  2205. IPSEC_STORE_PERSISTENT
  2206. );
  2207. if (pszRegistryPolicyDN) {
  2208. FreeSPDStr(pszRegistryPolicyDN);
  2209. }
  2210. if (dwError) {
  2211. return FALSE;
  2212. } else {
  2213. return TRUE;
  2214. }
  2215. }