Source code of Windows XP (NT5)
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.

1980 lines
44 KiB

  1. #include "precomp.h"
  2. VOID
  3. InitializePolicyStateBlock(
  4. PIPSEC_POLICY_STATE pIpsecPolicyState
  5. )
  6. {
  7. memset(pIpsecPolicyState, 0, sizeof(IPSEC_POLICY_STATE));
  8. pIpsecPolicyState->DefaultPollingInterval = gDefaultPollingInterval;
  9. }
  10. DWORD
  11. StartStatePollingManager(
  12. PIPSEC_POLICY_STATE pIpsecPolicyState
  13. )
  14. {
  15. DWORD dwError = 0;
  16. dwError = PlumbDirectoryPolicy(
  17. pIpsecPolicyState
  18. );
  19. if (dwError) {
  20. dwError = PlumbCachePolicy(
  21. pIpsecPolicyState
  22. );
  23. if (dwError) {
  24. dwError = PlumbRegistryPolicy(
  25. pIpsecPolicyState
  26. );
  27. BAIL_ON_WIN32_ERROR(dwError);
  28. }
  29. }
  30. //
  31. // The new polling interval has been set by either the
  32. // registry code or the DS code.
  33. //
  34. gCurrentPollingInterval = pIpsecPolicyState->CurrentPollingInterval;
  35. return (dwError);
  36. error:
  37. //
  38. // On error, set the state to INITIAL.
  39. //
  40. pIpsecPolicyState->dwCurrentState = POLL_STATE_INITIAL;
  41. gCurrentPollingInterval = pIpsecPolicyState->DefaultPollingInterval;
  42. return (dwError);
  43. }
  44. DWORD
  45. PlumbDirectoryPolicy(
  46. PIPSEC_POLICY_STATE pIpsecPolicyState
  47. )
  48. {
  49. DWORD dwError = 0;
  50. LPWSTR pszDirectoryPolicyDN = NULL;
  51. PIPSEC_POLICY_OBJECT pIpsecPolicyObject = NULL;
  52. PIPSEC_POLICY_DATA pIpsecPolicyData = NULL;
  53. DWORD dwStoreType = IPSEC_DIRECTORY_PROVIDER;
  54. DWORD dwSlientErrorCode = 0;
  55. BOOL bIsActivePolicy = FALSE;
  56. dwError = GetDirectoryPolicyDN(
  57. &pszDirectoryPolicyDN
  58. );
  59. BAIL_ON_WIN32_ERROR(dwError);
  60. bIsActivePolicy = TRUE;
  61. dwError = LoadDirectoryPolicy(
  62. pszDirectoryPolicyDN,
  63. &pIpsecPolicyObject
  64. );
  65. BAIL_ON_WIN32_ERROR(dwError);
  66. dwError = ProcessNFAs(
  67. pIpsecPolicyObject,
  68. dwStoreType,
  69. &dwSlientErrorCode,
  70. &pIpsecPolicyData
  71. );
  72. BAIL_ON_WIN32_ERROR(dwError);
  73. //
  74. // Plumb the DS policy.
  75. //
  76. dwError = AddPolicyInformation(
  77. pIpsecPolicyData
  78. );
  79. if (pIpsecPolicyState->pIpsecPolicyObject) {
  80. FreeIpsecPolicyObject(pIpsecPolicyState->pIpsecPolicyObject);
  81. }
  82. if (pIpsecPolicyState->pIpsecPolicyData) {
  83. FreeIpsecPolicyData(pIpsecPolicyState->pIpsecPolicyData);
  84. }
  85. if (pIpsecPolicyState->pszDirectoryPolicyDN) {
  86. FreeSPDStr(pIpsecPolicyState->pszDirectoryPolicyDN);
  87. }
  88. //
  89. // Delete the old cache and write the new one in.
  90. //
  91. DeleteRegistryCache();
  92. CacheDirectorytoRegistry(pIpsecPolicyObject);
  93. pIpsecPolicyState->pIpsecPolicyObject = pIpsecPolicyObject;
  94. pIpsecPolicyState->pIpsecPolicyData = pIpsecPolicyData;
  95. pIpsecPolicyState->pszDirectoryPolicyDN = pszDirectoryPolicyDN;
  96. //
  97. // Set the state to DS_DOWNLOADED.
  98. //
  99. pIpsecPolicyState->dwCurrentState = POLL_STATE_DS_DOWNLOADED;
  100. //
  101. // Compute the new polling interval.
  102. //
  103. pIpsecPolicyState->CurrentPollingInterval = pIpsecPolicyData->dwPollingInterval;
  104. pIpsecPolicyState->DSIncarnationNumber = pIpsecPolicyData->dwWhenChanged;
  105. pIpsecPolicyState->RegIncarnationNumber = 0;
  106. gCurrentPollingInterval = pIpsecPolicyState->CurrentPollingInterval;
  107. dwError = ERROR_SUCCESS;
  108. if (dwSlientErrorCode) {
  109. AuditIPSecPolicyErrorEvent(
  110. SE_CATEGID_POLICY_CHANGE,
  111. SE_AUDITID_IPSEC_POLICY_CHANGED,
  112. PASTORE_FAILED_SOME_NFA_APPLICATION,
  113. pIpsecPolicyData->pszIpsecName,
  114. dwSlientErrorCode,
  115. FALSE,
  116. TRUE
  117. );
  118. }
  119. AuditIPSecPolicyEvent(
  120. SE_CATEGID_POLICY_CHANGE,
  121. SE_AUDITID_IPSEC_POLICY_CHANGED,
  122. PASTORE_APPLIED_DS_POLICY,
  123. pIpsecPolicyData->pszIpsecName,
  124. TRUE,
  125. TRUE
  126. );
  127. return (dwError);
  128. error:
  129. //
  130. // Check pszDirectoryPolicyDN for non-NULL.
  131. //
  132. if (bIsActivePolicy && pszDirectoryPolicyDN) {
  133. AuditIPSecPolicyErrorEvent(
  134. SE_CATEGID_POLICY_CHANGE,
  135. SE_AUDITID_IPSEC_POLICY_CHANGED,
  136. PASTORE_FAILED_DS_POLICY_APPLICATION,
  137. pszDirectoryPolicyDN,
  138. dwError,
  139. FALSE,
  140. TRUE
  141. );
  142. }
  143. if (pszDirectoryPolicyDN) {
  144. FreeSPDStr(pszDirectoryPolicyDN);
  145. }
  146. if (pIpsecPolicyObject) {
  147. FreeIpsecPolicyObject(pIpsecPolicyObject);
  148. }
  149. if (pIpsecPolicyData) {
  150. FreeIpsecPolicyData(pIpsecPolicyData);
  151. }
  152. return (dwError);
  153. }
  154. DWORD
  155. GetDirectoryPolicyDN(
  156. LPWSTR * ppszDirectoryPolicyDN
  157. )
  158. {
  159. DWORD dwError = 0;
  160. HKEY hPolicyKey = NULL;
  161. LPWSTR pszIpsecPolicyName = NULL;
  162. DWORD dwSize = 0;
  163. LPWSTR pszPolicyDN = NULL;
  164. LPWSTR pszDirectoryPolicyDN = NULL;
  165. *ppszDirectoryPolicyDN = NULL;
  166. dwError = RegOpenKeyExW(
  167. HKEY_LOCAL_MACHINE,
  168. gpszIpsecDSPolicyKey,
  169. 0,
  170. KEY_ALL_ACCESS,
  171. &hPolicyKey
  172. );
  173. BAIL_ON_WIN32_ERROR(dwError);
  174. dwError = RegstoreQueryValue(
  175. hPolicyKey,
  176. L"DSIPSECPolicyPath",
  177. REG_SZ,
  178. (LPBYTE *)&pszIpsecPolicyName,
  179. &dwSize
  180. );
  181. BAIL_ON_WIN32_ERROR(dwError);
  182. //
  183. // Move by LDAP:// to get the real DN and allocate
  184. // this string.
  185. // Fix this by fixing the gpo extension.
  186. //
  187. pszPolicyDN = pszIpsecPolicyName + wcslen(L"LDAP://");
  188. pszDirectoryPolicyDN = AllocSPDStr(pszPolicyDN);
  189. if (!pszDirectoryPolicyDN) {
  190. dwError = ERROR_OUTOFMEMORY;
  191. BAIL_ON_WIN32_ERROR(dwError);
  192. }
  193. *ppszDirectoryPolicyDN = pszDirectoryPolicyDN;
  194. error:
  195. if (pszIpsecPolicyName) {
  196. FreeSPDStr(pszIpsecPolicyName);
  197. }
  198. if (hPolicyKey) {
  199. CloseHandle(hPolicyKey);
  200. }
  201. return (dwError);
  202. }
  203. DWORD
  204. LoadDirectoryPolicy(
  205. LPWSTR pszDirectoryPolicyDN,
  206. PIPSEC_POLICY_OBJECT * ppIpsecPolicyObject
  207. )
  208. {
  209. DWORD dwError = 0;
  210. LPWSTR pszDefaultDirectory = NULL;
  211. HLDAP hLdapBindHandle = NULL;
  212. PIPSEC_POLICY_OBJECT pIpsecPolicyObject = NULL;
  213. dwError = ComputeDefaultDirectory(
  214. &pszDefaultDirectory
  215. );
  216. BAIL_ON_WIN32_ERROR(dwError);
  217. dwError = OpenDirectoryServerHandle(
  218. pszDefaultDirectory,
  219. 389,
  220. &hLdapBindHandle
  221. );
  222. BAIL_ON_WIN32_ERROR(dwError);
  223. dwError = ReadPolicyObjectFromDirectory(
  224. hLdapBindHandle,
  225. pszDirectoryPolicyDN,
  226. &pIpsecPolicyObject
  227. );
  228. BAIL_ON_WIN32_ERROR(dwError);
  229. *ppIpsecPolicyObject = pIpsecPolicyObject;
  230. cleanup:
  231. if (pszDefaultDirectory) {
  232. FreeSPDStr(pszDefaultDirectory);
  233. }
  234. if (hLdapBindHandle) {
  235. CloseDirectoryServerHandle(hLdapBindHandle);
  236. }
  237. return (dwError);
  238. error:
  239. *ppIpsecPolicyObject = NULL;
  240. goto cleanup;
  241. }
  242. DWORD
  243. PlumbCachePolicy(
  244. PIPSEC_POLICY_STATE pIpsecPolicyState
  245. )
  246. {
  247. DWORD dwError = 0;
  248. LPWSTR pszCachePolicyDN = NULL;
  249. PIPSEC_POLICY_OBJECT pIpsecPolicyObject = NULL;
  250. PIPSEC_POLICY_DATA pIpsecPolicyData = NULL;
  251. DWORD dwStoreType = IPSEC_REGISTRY_PROVIDER;
  252. DWORD dwSlientErrorCode = 0;
  253. BOOL bIsActivePolicy = FALSE;
  254. dwError = GetCachePolicyDN(
  255. &pszCachePolicyDN
  256. );
  257. BAIL_ON_WIN32_ERROR(dwError);
  258. bIsActivePolicy = TRUE;
  259. dwError = LoadCachePolicy(
  260. pszCachePolicyDN,
  261. &pIpsecPolicyObject
  262. );
  263. BAIL_ON_WIN32_ERROR(dwError);
  264. dwError = ProcessNFAs(
  265. pIpsecPolicyObject,
  266. dwStoreType,
  267. &dwSlientErrorCode,
  268. &pIpsecPolicyData
  269. );
  270. BAIL_ON_WIN32_ERROR(dwError);
  271. dwError = AddPolicyInformation(
  272. pIpsecPolicyData
  273. );
  274. if (pIpsecPolicyState->pIpsecPolicyObject) {
  275. FreeIpsecPolicyObject(pIpsecPolicyState->pIpsecPolicyObject);
  276. }
  277. if (pIpsecPolicyState->pIpsecPolicyData) {
  278. FreeIpsecPolicyData(pIpsecPolicyState->pIpsecPolicyData);
  279. }
  280. if (pIpsecPolicyState->pszCachePolicyDN) {
  281. FreeSPDStr(pIpsecPolicyState->pszCachePolicyDN);
  282. }
  283. pIpsecPolicyState->pIpsecPolicyObject = pIpsecPolicyObject;
  284. pIpsecPolicyState->pIpsecPolicyData = pIpsecPolicyData;
  285. pIpsecPolicyState->pszCachePolicyDN = pszCachePolicyDN;
  286. //
  287. // Set the state to CACHE_DOWNLOADED.
  288. //
  289. //
  290. pIpsecPolicyState->dwCurrentState = POLL_STATE_CACHE_DOWNLOADED;
  291. //
  292. // Compute the new polling interval.
  293. //
  294. pIpsecPolicyState->CurrentPollingInterval = pIpsecPolicyData->dwPollingInterval;
  295. pIpsecPolicyState->DSIncarnationNumber = 0;
  296. pIpsecPolicyState->RegIncarnationNumber = pIpsecPolicyData->dwWhenChanged;
  297. gCurrentPollingInterval = pIpsecPolicyState->CurrentPollingInterval;
  298. dwError = ERROR_SUCCESS;
  299. if (dwSlientErrorCode) {
  300. AuditIPSecPolicyErrorEvent(
  301. SE_CATEGID_POLICY_CHANGE,
  302. SE_AUDITID_IPSEC_POLICY_CHANGED,
  303. PASTORE_FAILED_SOME_NFA_APPLICATION,
  304. pIpsecPolicyData->pszIpsecName,
  305. dwSlientErrorCode,
  306. FALSE,
  307. TRUE
  308. );
  309. }
  310. AuditIPSecPolicyEvent(
  311. SE_CATEGID_POLICY_CHANGE,
  312. SE_AUDITID_IPSEC_POLICY_CHANGED,
  313. PASTORE_APPLIED_CACHED_POLICY,
  314. pIpsecPolicyData->pszIpsecName,
  315. TRUE,
  316. TRUE
  317. );
  318. return (dwError);
  319. error:
  320. //
  321. // Check pszCachePolicyDN for non-NULL.
  322. //
  323. if (bIsActivePolicy && pszCachePolicyDN) {
  324. AuditIPSecPolicyErrorEvent(
  325. SE_CATEGID_POLICY_CHANGE,
  326. SE_AUDITID_IPSEC_POLICY_CHANGED,
  327. PASTORE_FAILED_CACHED_POLICY_APPLICATION,
  328. pszCachePolicyDN,
  329. dwError,
  330. FALSE,
  331. TRUE
  332. );
  333. }
  334. if (pszCachePolicyDN) {
  335. FreeSPDStr(pszCachePolicyDN);
  336. }
  337. if (pIpsecPolicyObject) {
  338. FreeIpsecPolicyObject(pIpsecPolicyObject);
  339. }
  340. if (pIpsecPolicyData) {
  341. FreeIpsecPolicyData(pIpsecPolicyData);
  342. }
  343. return (dwError);
  344. }
  345. DWORD
  346. GetCachePolicyDN(
  347. LPWSTR * ppszCachePolicyDN
  348. )
  349. {
  350. DWORD dwError = 0;
  351. LPWSTR pszDirectoryPolicyDN = NULL;
  352. LPWSTR pszCachePolicyDN = NULL;
  353. *ppszCachePolicyDN = NULL;
  354. dwError = GetDirectoryPolicyDN(
  355. &pszDirectoryPolicyDN
  356. );
  357. BAIL_ON_WIN32_ERROR(dwError);
  358. dwError = CopyPolicyDSToFQRegString(
  359. pszDirectoryPolicyDN,
  360. &pszCachePolicyDN
  361. );
  362. BAIL_ON_WIN32_ERROR(dwError);
  363. *ppszCachePolicyDN = pszCachePolicyDN;
  364. error:
  365. if (pszDirectoryPolicyDN) {
  366. FreeSPDStr(pszDirectoryPolicyDN);
  367. }
  368. return (dwError);
  369. }
  370. DWORD
  371. LoadCachePolicy(
  372. LPWSTR pszCachePolicyDN,
  373. PIPSEC_POLICY_OBJECT * ppIpsecPolicyObject
  374. )
  375. {
  376. DWORD dwError = 0;
  377. HKEY hRegistryKey = NULL;
  378. PIPSEC_POLICY_OBJECT pIpsecPolicyObject = NULL;
  379. dwError = OpenRegistryIPSECRootKey(
  380. NULL,
  381. gpszIpsecCachePolicyKey,
  382. &hRegistryKey
  383. );
  384. BAIL_ON_WIN32_ERROR(dwError);
  385. dwError = ReadPolicyObjectFromRegistry(
  386. hRegistryKey,
  387. pszCachePolicyDN,
  388. gpszIpsecCachePolicyKey,
  389. &pIpsecPolicyObject
  390. );
  391. BAIL_ON_WIN32_ERROR(dwError);
  392. *ppIpsecPolicyObject = pIpsecPolicyObject;
  393. cleanup:
  394. if (hRegistryKey) {
  395. CloseHandle(hRegistryKey);
  396. }
  397. return (dwError);
  398. error:
  399. *ppIpsecPolicyObject = NULL;
  400. goto cleanup;
  401. }
  402. DWORD
  403. PlumbRegistryPolicy(
  404. PIPSEC_POLICY_STATE pIpsecPolicyState
  405. )
  406. {
  407. DWORD dwError = 0;
  408. LPWSTR pszRegistryPolicyDN = NULL;
  409. PIPSEC_POLICY_OBJECT pIpsecPolicyObject = NULL;
  410. PIPSEC_POLICY_DATA pIpsecPolicyData = NULL;
  411. DWORD dwStoreType = IPSEC_REGISTRY_PROVIDER;
  412. DWORD dwSlientErrorCode = 0;
  413. BOOL bIsActivePolicy = FALSE;
  414. dwError = GetRegistryPolicyDN(
  415. &pszRegistryPolicyDN
  416. );
  417. BAIL_ON_WIN32_ERROR(dwError);
  418. bIsActivePolicy = TRUE;
  419. dwError = LoadRegistryPolicy(
  420. pszRegistryPolicyDN,
  421. &pIpsecPolicyObject
  422. );
  423. BAIL_ON_WIN32_ERROR(dwError);
  424. dwError = ProcessNFAs(
  425. pIpsecPolicyObject,
  426. dwStoreType,
  427. &dwSlientErrorCode,
  428. &pIpsecPolicyData
  429. );
  430. BAIL_ON_WIN32_ERROR(dwError);
  431. dwError = AddPolicyInformation(
  432. pIpsecPolicyData
  433. );
  434. if (pIpsecPolicyState->pIpsecPolicyObject) {
  435. FreeIpsecPolicyObject(pIpsecPolicyState->pIpsecPolicyObject);
  436. }
  437. if (pIpsecPolicyState->pIpsecPolicyData) {
  438. FreeIpsecPolicyData(pIpsecPolicyState->pIpsecPolicyData);
  439. }
  440. if (pIpsecPolicyState->pszRegistryPolicyDN) {
  441. FreeSPDStr(pIpsecPolicyState->pszRegistryPolicyDN);
  442. }
  443. pIpsecPolicyState->pIpsecPolicyObject = pIpsecPolicyObject;
  444. pIpsecPolicyState->pIpsecPolicyData = pIpsecPolicyData;
  445. pIpsecPolicyState->pszRegistryPolicyDN = pszRegistryPolicyDN;
  446. //
  447. // Set the state to LOCAL_DOWNLOADED.
  448. //
  449. pIpsecPolicyState->dwCurrentState = POLL_STATE_LOCAL_DOWNLOADED;
  450. //
  451. // Compute the new polling interval.
  452. //
  453. pIpsecPolicyState->CurrentPollingInterval = pIpsecPolicyData->dwPollingInterval;
  454. pIpsecPolicyState->DSIncarnationNumber = 0;
  455. pIpsecPolicyState->RegIncarnationNumber = pIpsecPolicyData->dwWhenChanged;
  456. gCurrentPollingInterval = pIpsecPolicyState->CurrentPollingInterval;
  457. dwError = ERROR_SUCCESS;
  458. if (dwSlientErrorCode) {
  459. AuditIPSecPolicyErrorEvent(
  460. SE_CATEGID_POLICY_CHANGE,
  461. SE_AUDITID_IPSEC_POLICY_CHANGED,
  462. PASTORE_FAILED_SOME_NFA_APPLICATION,
  463. pIpsecPolicyData->pszIpsecName,
  464. dwSlientErrorCode,
  465. FALSE,
  466. TRUE
  467. );
  468. }
  469. AuditIPSecPolicyEvent(
  470. SE_CATEGID_POLICY_CHANGE,
  471. SE_AUDITID_IPSEC_POLICY_CHANGED,
  472. PASTORE_APPLIED_LOCAL_POLICY,
  473. pIpsecPolicyData->pszIpsecName,
  474. TRUE,
  475. TRUE
  476. );
  477. return (dwError);
  478. error:
  479. //
  480. // Check pszRegistryPolicyDN for non-NULL.
  481. //
  482. if (bIsActivePolicy && pszRegistryPolicyDN) {
  483. AuditIPSecPolicyErrorEvent(
  484. SE_CATEGID_POLICY_CHANGE,
  485. SE_AUDITID_IPSEC_POLICY_CHANGED,
  486. PASTORE_FAILED_LOCAL_POLICY_APPLICATION,
  487. pszRegistryPolicyDN,
  488. dwError,
  489. FALSE,
  490. TRUE
  491. );
  492. }
  493. if (pszRegistryPolicyDN) {
  494. FreeSPDStr(pszRegistryPolicyDN);
  495. }
  496. if (pIpsecPolicyObject) {
  497. FreeIpsecPolicyObject(pIpsecPolicyObject);
  498. }
  499. if (pIpsecPolicyData) {
  500. FreeIpsecPolicyData(pIpsecPolicyData);
  501. }
  502. return (dwError);
  503. }
  504. DWORD
  505. GetRegistryPolicyDN(
  506. LPWSTR * ppszRegistryPolicyDN
  507. )
  508. {
  509. DWORD dwError = 0;
  510. HKEY hPolicyKey = NULL;
  511. LPWSTR pszIpsecPolicyName = NULL;
  512. DWORD dwSize = 0;
  513. dwError = RegOpenKeyExW(
  514. HKEY_LOCAL_MACHINE,
  515. gpszIpsecLocalPolicyKey,
  516. 0,
  517. KEY_ALL_ACCESS,
  518. &hPolicyKey
  519. );
  520. BAIL_ON_WIN32_ERROR(dwError);
  521. dwError = RegstoreQueryValue(
  522. hPolicyKey,
  523. L"ActivePolicy",
  524. REG_SZ,
  525. (LPBYTE *)&pszIpsecPolicyName,
  526. &dwSize
  527. );
  528. BAIL_ON_WIN32_ERROR(dwError);
  529. if (!pszIpsecPolicyName || !*pszIpsecPolicyName) {
  530. dwError = ERROR_OUTOFMEMORY;
  531. BAIL_ON_WIN32_ERROR(dwError);
  532. }
  533. *ppszRegistryPolicyDN = pszIpsecPolicyName;
  534. cleanup:
  535. if (hPolicyKey) {
  536. CloseHandle(hPolicyKey);
  537. }
  538. return (dwError);
  539. error:
  540. if (pszIpsecPolicyName) {
  541. FreeSPDStr(pszIpsecPolicyName);
  542. }
  543. *ppszRegistryPolicyDN = NULL;
  544. goto cleanup;
  545. }
  546. DWORD
  547. LoadRegistryPolicy(
  548. LPWSTR pszRegistryPolicyDN,
  549. PIPSEC_POLICY_OBJECT * ppIpsecPolicyObject
  550. )
  551. {
  552. DWORD dwError = 0;
  553. HKEY hRegistryKey = NULL;
  554. PIPSEC_POLICY_OBJECT pIpsecPolicyObject = NULL;
  555. dwError = OpenRegistryIPSECRootKey(
  556. NULL,
  557. gpszIpsecLocalPolicyKey,
  558. &hRegistryKey
  559. );
  560. BAIL_ON_WIN32_ERROR(dwError);
  561. dwError = ReadPolicyObjectFromRegistry(
  562. hRegistryKey,
  563. pszRegistryPolicyDN,
  564. gpszIpsecLocalPolicyKey,
  565. &pIpsecPolicyObject
  566. );
  567. BAIL_ON_WIN32_ERROR(dwError);
  568. *ppIpsecPolicyObject = pIpsecPolicyObject;
  569. cleanup:
  570. if (hRegistryKey) {
  571. CloseHandle(hRegistryKey);
  572. }
  573. return (dwError);
  574. error:
  575. *ppIpsecPolicyObject = NULL;
  576. goto cleanup;
  577. }
  578. DWORD
  579. AddPolicyInformation(
  580. PIPSEC_POLICY_DATA pIpsecPolicyData
  581. )
  582. {
  583. DWORD dwError = 0;
  584. dwError = AddMMPolicyInformation(pIpsecPolicyData);
  585. dwError = AddQMPolicyInformation(pIpsecPolicyData);
  586. dwError = ERROR_SUCCESS;
  587. return (dwError);
  588. }
  589. DWORD
  590. AddMMPolicyInformation(
  591. PIPSEC_POLICY_DATA pIpsecPolicyData
  592. )
  593. {
  594. DWORD dwError = 0;
  595. dwError = PAAddMMPolicies(
  596. &(pIpsecPolicyData->pIpsecISAKMPData),
  597. 1
  598. );
  599. dwError = PAAddMMAuthMethods(
  600. pIpsecPolicyData->ppIpsecNFAData,
  601. pIpsecPolicyData->dwNumNFACount
  602. );
  603. dwError = PAAddMMFilters(
  604. pIpsecPolicyData->pIpsecISAKMPData,
  605. pIpsecPolicyData->ppIpsecNFAData,
  606. pIpsecPolicyData->dwNumNFACount
  607. );
  608. BAIL_ON_WIN32_ERROR(dwError);
  609. error:
  610. return (dwError);
  611. }
  612. DWORD
  613. AddQMPolicyInformation(
  614. PIPSEC_POLICY_DATA pIpsecPolicyData
  615. )
  616. {
  617. DWORD dwError = 0;
  618. dwError = PAAddQMPolicies(
  619. pIpsecPolicyData->ppIpsecNFAData,
  620. pIpsecPolicyData->dwNumNFACount
  621. );
  622. dwError = PAAddQMFilters(
  623. pIpsecPolicyData->ppIpsecNFAData,
  624. pIpsecPolicyData->dwNumNFACount
  625. );
  626. BAIL_ON_WIN32_ERROR(dwError);
  627. error:
  628. return (dwError);
  629. }
  630. DWORD
  631. OnPolicyChanged(
  632. PIPSEC_POLICY_STATE pIpsecPolicyState
  633. )
  634. {
  635. DWORD dwError = 0;
  636. //
  637. // Remove all the old policy that was plumbed.
  638. //
  639. dwError = DeletePolicyInformation(
  640. pIpsecPolicyState->pIpsecPolicyData
  641. );
  642. ClearPolicyStateBlock(
  643. pIpsecPolicyState
  644. );
  645. //
  646. // Calling the Initializer again.
  647. //
  648. dwError = StartStatePollingManager(
  649. pIpsecPolicyState
  650. );
  651. return (dwError);
  652. }
  653. DWORD
  654. DeletePolicyInformation(
  655. PIPSEC_POLICY_DATA pIpsecPolicyData
  656. )
  657. {
  658. DWORD dwError = 0;
  659. if (!pIpsecPolicyData) {
  660. dwError = ERROR_SUCCESS;
  661. return (dwError);
  662. }
  663. dwError = DeleteMMPolicyInformation(pIpsecPolicyData);
  664. dwError = DeleteQMPolicyInformation(pIpsecPolicyData);
  665. dwError = ERROR_SUCCESS;
  666. return (dwError);
  667. }
  668. DWORD
  669. DeleteMMPolicyInformation(
  670. PIPSEC_POLICY_DATA pIpsecPolicyData
  671. )
  672. {
  673. DWORD dwError = 0;
  674. dwError = PADeleteMMFilters(
  675. pIpsecPolicyData->pIpsecISAKMPData,
  676. pIpsecPolicyData->ppIpsecNFAData,
  677. pIpsecPolicyData->dwNumNFACount
  678. );
  679. dwError = PADeleteMMAuthMethods(
  680. pIpsecPolicyData->ppIpsecNFAData,
  681. pIpsecPolicyData->dwNumNFACount
  682. );
  683. dwError = PADeleteMMPolicies(
  684. &(pIpsecPolicyData->pIpsecISAKMPData),
  685. 1
  686. );
  687. return (dwError);
  688. }
  689. DWORD
  690. DeleteQMPolicyInformation(
  691. PIPSEC_POLICY_DATA pIpsecPolicyData
  692. )
  693. {
  694. DWORD dwError = 0;
  695. dwError = PADeleteQMFilters(
  696. pIpsecPolicyData->ppIpsecNFAData,
  697. pIpsecPolicyData->dwNumNFACount
  698. );
  699. dwError = PADeleteQMPolicies(
  700. pIpsecPolicyData->ppIpsecNFAData,
  701. pIpsecPolicyData->dwNumNFACount
  702. );
  703. return (dwError);
  704. }
  705. DWORD
  706. DeleteAllPolicyInformation(
  707. )
  708. {
  709. DWORD dwError = 0;
  710. dwError = DeleteAllMMPolicyInformation();
  711. dwError = DeleteAllQMPolicyInformation();
  712. dwError = ERROR_SUCCESS;
  713. return (dwError);
  714. }
  715. DWORD
  716. DeleteAllMMPolicyInformation(
  717. )
  718. {
  719. DWORD dwError = 0;
  720. dwError = PADeleteAllMMFilters();
  721. dwError = PADeleteAllMMAuthMethods();
  722. dwError = PADeleteAllMMPolicies();
  723. return (dwError);
  724. }
  725. DWORD
  726. DeleteAllQMPolicyInformation(
  727. )
  728. {
  729. DWORD dwError = 0;
  730. dwError = PADeleteAllTxFilters();
  731. dwError = PADeleteAllTnFilters();
  732. dwError = PADeleteAllQMPolicies();
  733. return (dwError);
  734. }
  735. VOID
  736. ClearPolicyStateBlock(
  737. PIPSEC_POLICY_STATE pIpsecPolicyState
  738. )
  739. {
  740. if (pIpsecPolicyState->pIpsecPolicyObject) {
  741. FreeIpsecPolicyObject(
  742. pIpsecPolicyState->pIpsecPolicyObject
  743. );
  744. pIpsecPolicyState->pIpsecPolicyObject = NULL;
  745. }
  746. if (pIpsecPolicyState->pIpsecPolicyData) {
  747. FreeIpsecPolicyData(
  748. pIpsecPolicyState->pIpsecPolicyData
  749. );
  750. pIpsecPolicyState->pIpsecPolicyData = NULL;
  751. }
  752. if (pIpsecPolicyState->pszDirectoryPolicyDN) {
  753. FreeSPDStr(pIpsecPolicyState->pszDirectoryPolicyDN);
  754. pIpsecPolicyState->pszDirectoryPolicyDN = NULL;
  755. }
  756. pIpsecPolicyState->CurrentPollingInterval = gDefaultPollingInterval;
  757. pIpsecPolicyState->DefaultPollingInterval = gDefaultPollingInterval;
  758. pIpsecPolicyState->DSIncarnationNumber = 0;
  759. pIpsecPolicyState->RegIncarnationNumber = 0;
  760. pIpsecPolicyState->dwCurrentState = POLL_STATE_INITIAL;
  761. }
  762. DWORD
  763. OnPolicyPoll(
  764. PIPSEC_POLICY_STATE pIpsecPolicyState
  765. )
  766. {
  767. DWORD dwError = 0;
  768. switch (pIpsecPolicyState->dwCurrentState) {
  769. case POLL_STATE_DS_DOWNLOADED:
  770. dwError = ProcessDirectoryPolicyPollState(pIpsecPolicyState);
  771. BAIL_ON_WIN32_ERROR(dwError);
  772. break;
  773. case POLL_STATE_CACHE_DOWNLOADED:
  774. dwError = ProcessCachePolicyPollState(pIpsecPolicyState);
  775. BAIL_ON_WIN32_ERROR(dwError);
  776. break;
  777. case POLL_STATE_LOCAL_DOWNLOADED:
  778. dwError = ProcessLocalPolicyPollState(pIpsecPolicyState);
  779. BAIL_ON_WIN32_ERROR(dwError);
  780. break;
  781. case POLL_STATE_INITIAL:
  782. dwError = OnPolicyChanged(pIpsecPolicyState);
  783. BAIL_ON_WIN32_ERROR(dwError);
  784. break;
  785. }
  786. //
  787. // Set the new polling interval.
  788. //
  789. gCurrentPollingInterval = pIpsecPolicyState->CurrentPollingInterval;
  790. return (dwError);
  791. error:
  792. //
  793. // If in any of the three states other than the initial state,
  794. // then there was an error in pulling down the incarnation number
  795. // or the IPSec Policy from either the directory or the registry
  796. // or there might not no longer be any IPSec policy assigned to
  797. // this machine. So the polling state must reset back to the
  798. // start state through a forced policy change. This is also
  799. // necessary if the polling state is already in the initial state.
  800. //
  801. dwError = OnPolicyChanged(
  802. pIpsecPolicyState
  803. );
  804. return (dwError);
  805. }
  806. DWORD
  807. ProcessDirectoryPolicyPollState(
  808. PIPSEC_POLICY_STATE pIpsecPolicyState
  809. )
  810. {
  811. DWORD dwError = 0;
  812. DWORD dwIncarnationNumber = 0;
  813. PIPSEC_POLICY_OBJECT pIpsecPolicyObject = NULL;
  814. PIPSEC_POLICY_DATA pIpsecPolicyData = NULL;
  815. DWORD dwStoreType = IPSEC_DIRECTORY_PROVIDER;
  816. DWORD dwSlientErrorCode = 0;
  817. //
  818. // The directory policy DN has to be the same, otherwise the
  819. // IPSec extension in Winlogon would have already notified
  820. // PA Store of the DS policy change.
  821. //
  822. dwError = GetDirectoryIncarnationNumber(
  823. pIpsecPolicyState->pszDirectoryPolicyDN,
  824. &dwIncarnationNumber
  825. );
  826. if (dwError) {
  827. dwError = MigrateFromDSToCache(pIpsecPolicyState);
  828. BAIL_ON_WIN32_ERROR(dwError);
  829. return (ERROR_SUCCESS);
  830. }
  831. if (dwIncarnationNumber == pIpsecPolicyState->DSIncarnationNumber) {
  832. //
  833. // The policy has not changed at all.
  834. //
  835. AuditEvent(
  836. SE_CATEGID_POLICY_CHANGE,
  837. SE_AUDITID_IPSEC_POLICY_CHANGED,
  838. PASTORE_POLLING_NO_CHANGES,
  839. NULL,
  840. TRUE,
  841. TRUE
  842. );
  843. return (ERROR_SUCCESS);
  844. }
  845. //
  846. // The incarnation number is different, so there's a need to
  847. // update the policy.
  848. //
  849. dwError = LoadDirectoryPolicy(
  850. pIpsecPolicyState->pszDirectoryPolicyDN,
  851. &pIpsecPolicyObject
  852. );
  853. if (dwError) {
  854. dwError = MigrateFromDSToCache(pIpsecPolicyState);
  855. BAIL_ON_WIN32_ERROR(dwError);
  856. return (ERROR_SUCCESS);
  857. }
  858. dwError = ProcessNFAs(
  859. pIpsecPolicyObject,
  860. dwStoreType,
  861. &dwSlientErrorCode,
  862. &pIpsecPolicyData
  863. );
  864. if (dwError) {
  865. dwError = MigrateFromDSToCache(pIpsecPolicyState);
  866. BAIL_ON_WIN32_ERROR(dwError);
  867. if (pIpsecPolicyObject) {
  868. FreeIpsecPolicyObject(pIpsecPolicyObject);
  869. }
  870. return (ERROR_SUCCESS);
  871. }
  872. dwError = UpdatePolicyInformation(
  873. pIpsecPolicyState->pIpsecPolicyData,
  874. pIpsecPolicyData
  875. );
  876. if (pIpsecPolicyState->pIpsecPolicyObject) {
  877. FreeIpsecPolicyObject(pIpsecPolicyState->pIpsecPolicyObject);
  878. }
  879. if (pIpsecPolicyState->pIpsecPolicyData) {
  880. FreeIpsecPolicyData(pIpsecPolicyState->pIpsecPolicyData);
  881. }
  882. //
  883. // Now delete the old cache and write the new one in.
  884. //
  885. DeleteRegistryCache();
  886. CacheDirectorytoRegistry(pIpsecPolicyObject);
  887. pIpsecPolicyState->pIpsecPolicyObject = pIpsecPolicyObject;
  888. pIpsecPolicyState->pIpsecPolicyData = pIpsecPolicyData;
  889. pIpsecPolicyState->CurrentPollingInterval = pIpsecPolicyData->dwPollingInterval;
  890. pIpsecPolicyState->DSIncarnationNumber = dwIncarnationNumber;
  891. NotifyIpsecPolicyChange();
  892. dwError = ERROR_SUCCESS;
  893. if (dwSlientErrorCode) {
  894. AuditIPSecPolicyErrorEvent(
  895. SE_CATEGID_POLICY_CHANGE,
  896. SE_AUDITID_IPSEC_POLICY_CHANGED,
  897. PASTORE_FAILED_SOME_NFA_APPLICATION,
  898. pIpsecPolicyData->pszIpsecName,
  899. dwSlientErrorCode,
  900. FALSE,
  901. TRUE
  902. );
  903. }
  904. AuditEvent(
  905. SE_CATEGID_POLICY_CHANGE,
  906. SE_AUDITID_IPSEC_POLICY_CHANGED,
  907. PASTORE_POLLING_APPLIED_CHANGES,
  908. NULL,
  909. TRUE,
  910. TRUE
  911. );
  912. return (dwError);
  913. error:
  914. if (pIpsecPolicyObject) {
  915. FreeIpsecPolicyObject(pIpsecPolicyObject);
  916. }
  917. if (pIpsecPolicyData) {
  918. FreeIpsecPolicyData(pIpsecPolicyData);
  919. }
  920. return (dwError);
  921. }
  922. DWORD
  923. GetDirectoryIncarnationNumber(
  924. LPWSTR pszIpsecPolicyDN,
  925. DWORD * pdwIncarnationNumber
  926. )
  927. {
  928. DWORD dwError = 0;
  929. LPWSTR pszDefaultDirectory = NULL;
  930. HLDAP hLdapBindHandle = NULL;
  931. LPWSTR Attributes[] = {L"whenChanged", NULL};
  932. LDAPMessage *res = NULL;
  933. LDAPMessage *e = NULL;
  934. WCHAR **strvalues = NULL;
  935. DWORD dwCount = 0;
  936. DWORD dwWhenChanged = 0;
  937. *pdwIncarnationNumber = 0;
  938. //
  939. // Open the directory store.
  940. //
  941. dwError = ComputeDefaultDirectory(
  942. &pszDefaultDirectory
  943. );
  944. BAIL_ON_WIN32_ERROR(dwError);
  945. dwError = OpenDirectoryServerHandle(
  946. pszDefaultDirectory,
  947. 389,
  948. &hLdapBindHandle
  949. );
  950. BAIL_ON_WIN32_ERROR(dwError);
  951. dwError = LdapSearchST(
  952. hLdapBindHandle,
  953. pszIpsecPolicyDN,
  954. LDAP_SCOPE_BASE,
  955. L"(objectClass=*)",
  956. Attributes,
  957. 0,
  958. NULL,
  959. &res
  960. );
  961. BAIL_ON_WIN32_ERROR(dwError);
  962. dwError = LdapFirstEntry(
  963. hLdapBindHandle,
  964. res,
  965. &e
  966. );
  967. BAIL_ON_WIN32_ERROR(dwError);
  968. dwError = LdapGetValues(
  969. hLdapBindHandle,
  970. e,
  971. L"whenChanged",
  972. (WCHAR ***)&strvalues,
  973. (int *)&dwCount
  974. );
  975. BAIL_ON_WIN32_ERROR(dwError);
  976. dwWhenChanged = _wtol(LDAPOBJECT_STRING((PLDAPOBJECT)strvalues));
  977. *pdwIncarnationNumber = dwWhenChanged;
  978. error:
  979. if (pszDefaultDirectory) {
  980. FreeSPDStr(pszDefaultDirectory);
  981. }
  982. if (hLdapBindHandle) {
  983. CloseDirectoryServerHandle(hLdapBindHandle);
  984. }
  985. if (res) {
  986. LdapMsgFree(res);
  987. }
  988. if (strvalues) {
  989. LdapValueFree(strvalues);
  990. }
  991. return (dwError);
  992. }
  993. DWORD
  994. MigrateFromDSToCache(
  995. PIPSEC_POLICY_STATE pIpsecPolicyState
  996. )
  997. {
  998. DWORD dwError = 0;
  999. LPWSTR pszCachePolicyDN = NULL;
  1000. dwError = GetCachePolicyDN(
  1001. &pszCachePolicyDN
  1002. );
  1003. BAIL_ON_WIN32_ERROR(dwError);
  1004. if (pIpsecPolicyState->pszDirectoryPolicyDN) {
  1005. FreeSPDStr(pIpsecPolicyState->pszDirectoryPolicyDN);
  1006. pIpsecPolicyState->pszDirectoryPolicyDN = NULL;
  1007. }
  1008. pIpsecPolicyState->pszCachePolicyDN = pszCachePolicyDN;
  1009. //
  1010. // Keep pIpsecPolicyState->pIpsecPolicyData.
  1011. // Keep pIpsecPolicyState->pIpsecPolicyObject.
  1012. // Change the incarnation numbers.
  1013. //
  1014. pIpsecPolicyState->RegIncarnationNumber = pIpsecPolicyState->DSIncarnationNumber;
  1015. pIpsecPolicyState->DSIncarnationNumber = 0;
  1016. pIpsecPolicyState->dwCurrentState = POLL_STATE_CACHE_DOWNLOADED;
  1017. //
  1018. // Keep pIpsecPolicyState->CurrentPollingInterval.
  1019. // Keep pIpsecPolicyState->DefaultPollingInterval.
  1020. //
  1021. gCurrentPollingInterval = pIpsecPolicyState->CurrentPollingInterval;
  1022. AuditEvent(
  1023. SE_CATEGID_POLICY_CHANGE,
  1024. SE_AUDITID_IPSEC_POLICY_CHANGED,
  1025. PASTORE_MIGRATE_DS_TO_CACHE,
  1026. NULL,
  1027. TRUE,
  1028. TRUE
  1029. );
  1030. error:
  1031. return (dwError);
  1032. }
  1033. DWORD
  1034. ProcessCachePolicyPollState(
  1035. PIPSEC_POLICY_STATE pIpsecPolicyState
  1036. )
  1037. {
  1038. DWORD dwError = 0;
  1039. LPWSTR pszDirectoryPolicyDN = NULL;
  1040. DWORD dwIncarnationNumber = 0;
  1041. LPWSTR pszCachePolicyDN = NULL;
  1042. dwError = GetDirectoryPolicyDN(
  1043. &pszDirectoryPolicyDN
  1044. );
  1045. if (!dwError) {
  1046. dwError = GetDirectoryIncarnationNumber(
  1047. pszDirectoryPolicyDN,
  1048. &dwIncarnationNumber
  1049. );
  1050. if (!dwError) {
  1051. dwError = CopyPolicyDSToFQRegString(
  1052. pszDirectoryPolicyDN,
  1053. &pszCachePolicyDN
  1054. );
  1055. if (!dwError) {
  1056. if (!_wcsicmp(pIpsecPolicyState->pszCachePolicyDN, pszCachePolicyDN)) {
  1057. if (pIpsecPolicyState->RegIncarnationNumber == dwIncarnationNumber) {
  1058. dwError = MigrateFromCacheToDS(pIpsecPolicyState);
  1059. }
  1060. else {
  1061. dwError = UpdateFromCacheToDS(pIpsecPolicyState);
  1062. }
  1063. if (dwError) {
  1064. dwError = OnPolicyChanged(pIpsecPolicyState);
  1065. }
  1066. }
  1067. else {
  1068. dwError = OnPolicyChanged(pIpsecPolicyState);
  1069. }
  1070. }
  1071. }
  1072. }
  1073. if (pszDirectoryPolicyDN) {
  1074. FreeSPDStr(pszDirectoryPolicyDN);
  1075. }
  1076. if (pszCachePolicyDN) {
  1077. FreeSPDStr(pszCachePolicyDN);
  1078. }
  1079. return (ERROR_SUCCESS);
  1080. }
  1081. DWORD
  1082. MigrateFromCacheToDS(
  1083. PIPSEC_POLICY_STATE pIpsecPolicyState
  1084. )
  1085. {
  1086. DWORD dwError = 0;
  1087. LPWSTR pszDirectoryPolicyDN = NULL;
  1088. dwError = GetDirectoryPolicyDN(
  1089. &pszDirectoryPolicyDN
  1090. );
  1091. BAIL_ON_WIN32_ERROR(dwError);
  1092. if (pIpsecPolicyState->pszCachePolicyDN) {
  1093. FreeSPDStr(pIpsecPolicyState->pszCachePolicyDN);
  1094. pIpsecPolicyState->pszCachePolicyDN = NULL;
  1095. }
  1096. pIpsecPolicyState->pszDirectoryPolicyDN = pszDirectoryPolicyDN;
  1097. //
  1098. // Keep pIpsecPolicyState->pIpsecPolicyData.
  1099. // Keep pIpsecPolicyState->pIpsecPolicyObject.
  1100. // Change the incarnation numbers.
  1101. //
  1102. pIpsecPolicyState->DSIncarnationNumber = pIpsecPolicyState->RegIncarnationNumber;
  1103. pIpsecPolicyState->RegIncarnationNumber = 0;
  1104. pIpsecPolicyState->dwCurrentState = POLL_STATE_DS_DOWNLOADED;
  1105. //
  1106. // Keep pIpsecPolicyState->CurrentPollingInterval.
  1107. // Keep pIpsecPolicyState->DefaultPollingInterval.
  1108. //
  1109. gCurrentPollingInterval = pIpsecPolicyState->CurrentPollingInterval;
  1110. AuditEvent(
  1111. SE_CATEGID_POLICY_CHANGE,
  1112. SE_AUDITID_IPSEC_POLICY_CHANGED,
  1113. PASTORE_MIGRATE_CACHE_TO_DS,
  1114. NULL,
  1115. TRUE,
  1116. TRUE
  1117. );
  1118. error:
  1119. return (dwError);
  1120. }
  1121. DWORD
  1122. UpdateFromCacheToDS(
  1123. PIPSEC_POLICY_STATE pIpsecPolicyState
  1124. )
  1125. {
  1126. DWORD dwError = 0;
  1127. LPWSTR pszDirectoryPolicyDN = NULL;
  1128. PIPSEC_POLICY_OBJECT pIpsecPolicyObject = NULL;
  1129. PIPSEC_POLICY_DATA pIpsecPolicyData = NULL;
  1130. DWORD dwStoreType = IPSEC_DIRECTORY_PROVIDER;
  1131. DWORD dwSlientErrorCode = 0;
  1132. dwError = GetDirectoryPolicyDN(
  1133. &pszDirectoryPolicyDN
  1134. );
  1135. BAIL_ON_WIN32_ERROR(dwError);
  1136. dwError = LoadDirectoryPolicy(
  1137. pszDirectoryPolicyDN,
  1138. &pIpsecPolicyObject
  1139. );
  1140. BAIL_ON_WIN32_ERROR(dwError);
  1141. dwError = ProcessNFAs(
  1142. pIpsecPolicyObject,
  1143. dwStoreType,
  1144. &dwSlientErrorCode,
  1145. &pIpsecPolicyData
  1146. );
  1147. BAIL_ON_WIN32_ERROR(dwError);
  1148. dwError = UpdatePolicyInformation(
  1149. pIpsecPolicyState->pIpsecPolicyData,
  1150. pIpsecPolicyData
  1151. );
  1152. if (pIpsecPolicyState->pIpsecPolicyObject) {
  1153. FreeIpsecPolicyObject(pIpsecPolicyState->pIpsecPolicyObject);
  1154. }
  1155. if (pIpsecPolicyState->pIpsecPolicyData) {
  1156. FreeIpsecPolicyData(pIpsecPolicyState->pIpsecPolicyData);
  1157. }
  1158. if (pIpsecPolicyState->pszCachePolicyDN) {
  1159. FreeSPDStr(pIpsecPolicyState->pszCachePolicyDN);
  1160. }
  1161. //
  1162. // Now delete the old cache and write the new one in.
  1163. //
  1164. DeleteRegistryCache();
  1165. CacheDirectorytoRegistry(pIpsecPolicyObject);
  1166. pIpsecPolicyState->pIpsecPolicyObject = pIpsecPolicyObject;
  1167. pIpsecPolicyState->pIpsecPolicyData = pIpsecPolicyData;
  1168. pIpsecPolicyState->pszDirectoryPolicyDN = pszDirectoryPolicyDN;
  1169. //
  1170. // Set the state to DS-DOWNLOADED.
  1171. //
  1172. pIpsecPolicyState->dwCurrentState = POLL_STATE_DS_DOWNLOADED;
  1173. //
  1174. // Compute the new polling interval.
  1175. //
  1176. pIpsecPolicyState->CurrentPollingInterval = pIpsecPolicyData->dwPollingInterval;
  1177. pIpsecPolicyState->DSIncarnationNumber = pIpsecPolicyData->dwWhenChanged;
  1178. pIpsecPolicyState->RegIncarnationNumber = 0;
  1179. gCurrentPollingInterval = pIpsecPolicyState->CurrentPollingInterval;
  1180. NotifyIpsecPolicyChange();
  1181. dwError = ERROR_SUCCESS;
  1182. if (dwSlientErrorCode) {
  1183. AuditIPSecPolicyErrorEvent(
  1184. SE_CATEGID_POLICY_CHANGE,
  1185. SE_AUDITID_IPSEC_POLICY_CHANGED,
  1186. PASTORE_FAILED_SOME_NFA_APPLICATION,
  1187. pIpsecPolicyData->pszIpsecName,
  1188. dwSlientErrorCode,
  1189. FALSE,
  1190. TRUE
  1191. );
  1192. }
  1193. AuditEvent(
  1194. SE_CATEGID_POLICY_CHANGE,
  1195. SE_AUDITID_IPSEC_POLICY_CHANGED,
  1196. PASTORE_UPDATE_CACHE_TO_DS,
  1197. NULL,
  1198. TRUE,
  1199. TRUE
  1200. );
  1201. return (dwError);
  1202. error:
  1203. if (pszDirectoryPolicyDN) {
  1204. FreeSPDStr(pszDirectoryPolicyDN);
  1205. }
  1206. if (pIpsecPolicyObject) {
  1207. FreeIpsecPolicyObject(pIpsecPolicyObject);
  1208. }
  1209. if (pIpsecPolicyData) {
  1210. FreeIpsecPolicyData(pIpsecPolicyData);
  1211. }
  1212. return (dwError);
  1213. }
  1214. DWORD
  1215. ProcessLocalPolicyPollState(
  1216. PIPSEC_POLICY_STATE pIpsecPolicyState
  1217. )
  1218. {
  1219. DWORD dwStatus = 0;
  1220. LPWSTR pszDirectoryPolicyDN = NULL;
  1221. DWORD dwDSIncarnationNumber = 0;
  1222. DWORD dwError = 0;
  1223. BOOL bChanged = FALSE;
  1224. DWORD dwIncarnationNumber = 0;
  1225. PIPSEC_POLICY_OBJECT pIpsecPolicyObject = NULL;
  1226. PIPSEC_POLICY_DATA pIpsecPolicyData = NULL;
  1227. DWORD dwStoreType = IPSEC_REGISTRY_PROVIDER;
  1228. DWORD dwSlientErrorCode = 0;
  1229. dwStatus = GetDirectoryPolicyDN(
  1230. &pszDirectoryPolicyDN
  1231. );
  1232. if (!dwStatus) {
  1233. dwStatus = GetDirectoryIncarnationNumber(
  1234. pszDirectoryPolicyDN,
  1235. &dwDSIncarnationNumber
  1236. );
  1237. if (pszDirectoryPolicyDN) {
  1238. FreeSPDStr(pszDirectoryPolicyDN);
  1239. }
  1240. if (!dwStatus) {
  1241. dwStatus = OnPolicyChanged(pIpsecPolicyState);
  1242. return (dwStatus);
  1243. }
  1244. }
  1245. dwError = HasRegistryPolicyChanged(
  1246. pIpsecPolicyState->pszRegistryPolicyDN,
  1247. &bChanged
  1248. );
  1249. BAIL_ON_WIN32_ERROR(dwError);
  1250. if (bChanged) {
  1251. dwError = OnPolicyChanged(pIpsecPolicyState);
  1252. return (dwError);
  1253. }
  1254. if (pIpsecPolicyState->dwCurrentState == POLL_STATE_INITIAL) {
  1255. return (ERROR_SUCCESS);
  1256. }
  1257. dwError = GetRegistryIncarnationNumber(
  1258. pIpsecPolicyState->pszRegistryPolicyDN,
  1259. &dwIncarnationNumber
  1260. );
  1261. BAIL_ON_WIN32_ERROR(dwError);
  1262. if (dwIncarnationNumber == pIpsecPolicyState->RegIncarnationNumber) {
  1263. //
  1264. // The policy has not changed at all.
  1265. //
  1266. AuditEvent(
  1267. SE_CATEGID_POLICY_CHANGE,
  1268. SE_AUDITID_IPSEC_POLICY_CHANGED,
  1269. PASTORE_POLLING_NO_CHANGES,
  1270. NULL,
  1271. TRUE,
  1272. TRUE
  1273. );
  1274. return (ERROR_SUCCESS);
  1275. }
  1276. dwError = LoadRegistryPolicy(
  1277. pIpsecPolicyState->pszRegistryPolicyDN,
  1278. &pIpsecPolicyObject
  1279. );
  1280. BAIL_ON_WIN32_ERROR(dwError);
  1281. dwError = ProcessNFAs(
  1282. pIpsecPolicyObject,
  1283. dwStoreType,
  1284. &dwSlientErrorCode,
  1285. &pIpsecPolicyData
  1286. );
  1287. BAIL_ON_WIN32_ERROR(dwError);
  1288. dwError = UpdatePolicyInformation(
  1289. pIpsecPolicyState->pIpsecPolicyData,
  1290. pIpsecPolicyData
  1291. );
  1292. if (pIpsecPolicyState->pIpsecPolicyObject) {
  1293. FreeIpsecPolicyObject(pIpsecPolicyState->pIpsecPolicyObject);
  1294. }
  1295. if (pIpsecPolicyState->pIpsecPolicyData) {
  1296. FreeIpsecPolicyData(pIpsecPolicyState->pIpsecPolicyData);
  1297. }
  1298. pIpsecPolicyState->pIpsecPolicyObject = pIpsecPolicyObject;
  1299. pIpsecPolicyState->pIpsecPolicyData = pIpsecPolicyData;
  1300. pIpsecPolicyState->CurrentPollingInterval = pIpsecPolicyData->dwPollingInterval;
  1301. pIpsecPolicyState->RegIncarnationNumber = dwIncarnationNumber;
  1302. NotifyIpsecPolicyChange();
  1303. dwError = ERROR_SUCCESS;
  1304. if (dwSlientErrorCode) {
  1305. AuditIPSecPolicyErrorEvent(
  1306. SE_CATEGID_POLICY_CHANGE,
  1307. SE_AUDITID_IPSEC_POLICY_CHANGED,
  1308. PASTORE_FAILED_SOME_NFA_APPLICATION,
  1309. pIpsecPolicyData->pszIpsecName,
  1310. dwSlientErrorCode,
  1311. FALSE,
  1312. TRUE
  1313. );
  1314. }
  1315. AuditEvent(
  1316. SE_CATEGID_POLICY_CHANGE,
  1317. SE_AUDITID_IPSEC_POLICY_CHANGED,
  1318. PASTORE_POLLING_APPLIED_CHANGES,
  1319. NULL,
  1320. TRUE,
  1321. TRUE
  1322. );
  1323. return (dwError);
  1324. error:
  1325. if (pIpsecPolicyObject) {
  1326. FreeIpsecPolicyObject(pIpsecPolicyObject);
  1327. }
  1328. if (pIpsecPolicyData) {
  1329. FreeIpsecPolicyData(pIpsecPolicyData);
  1330. }
  1331. return (dwError);
  1332. }
  1333. DWORD
  1334. HasRegistryPolicyChanged(
  1335. LPWSTR pszCurrentPolicyDN,
  1336. PBOOL pbChanged
  1337. )
  1338. {
  1339. DWORD dwError = 0;
  1340. HKEY hRegKey = NULL;
  1341. LPWSTR pszIpsecPolicyName = NULL;
  1342. DWORD dwSize = 0;
  1343. BOOL bChanged = FALSE;
  1344. dwError = RegOpenKeyExW(
  1345. HKEY_LOCAL_MACHINE,
  1346. gpszIpsecLocalPolicyKey,
  1347. 0,
  1348. KEY_ALL_ACCESS,
  1349. &hRegKey
  1350. );
  1351. BAIL_ON_WIN32_ERROR(dwError);
  1352. dwError = RegstoreQueryValue(
  1353. hRegKey,
  1354. L"ActivePolicy",
  1355. REG_SZ,
  1356. (LPBYTE *)&pszIpsecPolicyName,
  1357. &dwSize
  1358. );
  1359. //
  1360. // Must not bail from here, as there can be no
  1361. // active local policy.
  1362. //
  1363. if (pszIpsecPolicyName && *pszIpsecPolicyName) {
  1364. if (!pszCurrentPolicyDN || !*pszCurrentPolicyDN) {
  1365. bChanged = TRUE;
  1366. }
  1367. else {
  1368. if (!_wcsicmp(pszIpsecPolicyName, pszCurrentPolicyDN)) {
  1369. bChanged = FALSE;
  1370. }
  1371. else {
  1372. bChanged = TRUE;
  1373. }
  1374. }
  1375. }
  1376. else {
  1377. if (!pszCurrentPolicyDN || !*pszCurrentPolicyDN) {
  1378. bChanged = FALSE;
  1379. }
  1380. else {
  1381. bChanged = TRUE;
  1382. }
  1383. }
  1384. *pbChanged = bChanged;
  1385. dwError = ERROR_SUCCESS;
  1386. cleanup:
  1387. if (hRegKey) {
  1388. CloseHandle(hRegKey);
  1389. }
  1390. if (pszIpsecPolicyName) {
  1391. FreeSPDStr(pszIpsecPolicyName);
  1392. }
  1393. return (dwError);
  1394. error:
  1395. *pbChanged = FALSE;
  1396. goto cleanup;
  1397. }
  1398. DWORD
  1399. GetRegistryIncarnationNumber(
  1400. LPWSTR pszIpsecPolicyDN,
  1401. DWORD * pdwIncarnationNumber
  1402. )
  1403. {
  1404. DWORD dwError = 0;
  1405. HKEY hRegKey = NULL;
  1406. DWORD dwType = REG_DWORD;
  1407. DWORD dwWhenChanged = 0;
  1408. DWORD dwSize = sizeof(DWORD);
  1409. *pdwIncarnationNumber = 0;
  1410. dwError = RegOpenKeyExW(
  1411. HKEY_LOCAL_MACHINE,
  1412. pszIpsecPolicyDN,
  1413. 0,
  1414. KEY_ALL_ACCESS,
  1415. &hRegKey
  1416. );
  1417. BAIL_ON_WIN32_ERROR(dwError);
  1418. dwError = RegQueryValueExW(
  1419. hRegKey,
  1420. L"whenChanged",
  1421. NULL,
  1422. &dwType,
  1423. (LPBYTE)&dwWhenChanged,
  1424. &dwSize
  1425. );
  1426. BAIL_ON_WIN32_ERROR(dwError);
  1427. *pdwIncarnationNumber = dwWhenChanged;
  1428. error:
  1429. if (hRegKey) {
  1430. CloseHandle(hRegKey);
  1431. }
  1432. return(dwError);
  1433. }
  1434. DWORD
  1435. UpdatePolicyInformation(
  1436. PIPSEC_POLICY_DATA pOldIpsecPolicyData,
  1437. PIPSEC_POLICY_DATA pNewIpsecPolicyData
  1438. )
  1439. {
  1440. DWORD dwError = 0;
  1441. PIPSEC_ISAKMP_DATA pOldIpsecISAKMPData = NULL;
  1442. PIPSEC_NFA_DATA * ppOldIpsecNFAData = NULL;
  1443. DWORD dwNumOldNFACount = 0;
  1444. PIPSEC_ISAKMP_DATA pNewIpsecISAKMPData = NULL;
  1445. PIPSEC_NFA_DATA * ppNewIpsecNFAData = NULL;
  1446. DWORD dwNumNewNFACount = 0;
  1447. pOldIpsecISAKMPData = pOldIpsecPolicyData->pIpsecISAKMPData;
  1448. ppOldIpsecNFAData = pOldIpsecPolicyData->ppIpsecNFAData;
  1449. dwNumOldNFACount = pOldIpsecPolicyData->dwNumNFACount;
  1450. pNewIpsecISAKMPData = pNewIpsecPolicyData->pIpsecISAKMPData;
  1451. ppNewIpsecNFAData = pNewIpsecPolicyData->ppIpsecNFAData;
  1452. dwNumNewNFACount = pNewIpsecPolicyData->dwNumNFACount;
  1453. dwError = PADeleteObseleteISAKMPData(
  1454. &pOldIpsecISAKMPData,
  1455. 1,
  1456. ppOldIpsecNFAData,
  1457. dwNumOldNFACount,
  1458. &pNewIpsecISAKMPData,
  1459. 1
  1460. );
  1461. dwError = PAUpdateISAKMPData(
  1462. &pNewIpsecISAKMPData,
  1463. 1,
  1464. ppOldIpsecNFAData,
  1465. dwNumOldNFACount,
  1466. &pOldIpsecISAKMPData,
  1467. 1
  1468. );
  1469. dwError = PADeleteObseleteNFAData(
  1470. pNewIpsecISAKMPData,
  1471. ppOldIpsecNFAData,
  1472. dwNumOldNFACount,
  1473. ppNewIpsecNFAData,
  1474. dwNumNewNFACount
  1475. );
  1476. dwError = PAUpdateNFAData(
  1477. pNewIpsecISAKMPData,
  1478. ppNewIpsecNFAData,
  1479. dwNumNewNFACount,
  1480. ppOldIpsecNFAData,
  1481. dwNumOldNFACount
  1482. );
  1483. return (dwError);
  1484. }
  1485. DWORD
  1486. LoadDefaultISAKMPInformation(
  1487. LPWSTR pszDefaultISAKMPDN
  1488. )
  1489. {
  1490. DWORD dwError = 0;
  1491. gbLoadedISAKMPDefaults = TRUE;
  1492. return (dwError);
  1493. }
  1494. VOID
  1495. UnLoadDefaultISAKMPInformation(
  1496. LPWSTR pszDefaultISAKMPDN
  1497. )
  1498. {
  1499. return;
  1500. }