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.

1157 lines
28 KiB

  1. //----------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 2000.
  5. //
  6. // File: policy-r.c
  7. //
  8. // Contents: Policy management for registry.
  9. //
  10. //
  11. // History: KrishnaG.
  12. // AbhisheV.
  13. //
  14. //----------------------------------------------------------------------------
  15. #include "precomp.h"
  16. extern LPWSTR PolicyDNAttributes[];
  17. DWORD
  18. RegEnumPolicyData(
  19. HKEY hRegistryKey,
  20. LPWSTR pszIpsecRootContainer,
  21. PIPSEC_POLICY_DATA ** pppIpsecPolicyData,
  22. PDWORD pdwNumPolicyObjects
  23. )
  24. {
  25. DWORD dwError = 0;
  26. PIPSEC_POLICY_OBJECT * ppIpsecPolicyObjects = NULL;
  27. PIPSEC_POLICY_DATA pIpsecPolicyData = NULL;
  28. PIPSEC_POLICY_DATA * ppIpsecPolicyData = NULL;
  29. DWORD dwNumPolicyObjects = 0;
  30. DWORD i = 0;
  31. DWORD j = 0;
  32. dwError = RegEnumPolicyObjects(
  33. hRegistryKey,
  34. pszIpsecRootContainer,
  35. &ppIpsecPolicyObjects,
  36. &dwNumPolicyObjects
  37. );
  38. BAIL_ON_WIN32_ERROR(dwError);
  39. if (dwNumPolicyObjects) {
  40. ppIpsecPolicyData = (PIPSEC_POLICY_DATA *) AllocPolMem(
  41. dwNumPolicyObjects*sizeof(PIPSEC_POLICY_DATA));
  42. if (!ppIpsecPolicyData) {
  43. dwError = ERROR_OUTOFMEMORY;
  44. BAIL_ON_WIN32_ERROR(dwError);
  45. }
  46. }
  47. for (i = 0; i < dwNumPolicyObjects; i++) {
  48. dwError = RegUnmarshallPolicyData(
  49. *(ppIpsecPolicyObjects + i),
  50. &pIpsecPolicyData
  51. );
  52. if (!dwError) {
  53. *(ppIpsecPolicyData + j) = pIpsecPolicyData;
  54. j++;
  55. }
  56. }
  57. if (j == 0) {
  58. if (ppIpsecPolicyData) {
  59. FreePolMem(ppIpsecPolicyData);
  60. ppIpsecPolicyData = NULL;
  61. }
  62. }
  63. *pppIpsecPolicyData = ppIpsecPolicyData;
  64. *pdwNumPolicyObjects = j;
  65. dwError = ERROR_SUCCESS;
  66. cleanup:
  67. if (ppIpsecPolicyObjects) {
  68. FreeIpsecPolicyObjects(
  69. ppIpsecPolicyObjects,
  70. dwNumPolicyObjects
  71. );
  72. }
  73. return(dwError);
  74. error:
  75. if (ppIpsecPolicyData) {
  76. FreeMulIpsecPolicyData(
  77. ppIpsecPolicyData,
  78. i
  79. );
  80. }
  81. *pppIpsecPolicyData = NULL;
  82. *pdwNumPolicyObjects = 0;
  83. goto cleanup;
  84. }
  85. DWORD
  86. RegEnumPolicyObjects(
  87. HKEY hRegistryKey,
  88. LPWSTR pszIpsecRootContainer,
  89. PIPSEC_POLICY_OBJECT ** pppIpsecPolicyObjects,
  90. PDWORD pdwNumPolicyObjects
  91. )
  92. {
  93. DWORD dwError = 0;
  94. DWORD i = 0;
  95. DWORD dwCount = 0;
  96. PIPSEC_POLICY_OBJECT pIpsecPolicyObject = NULL;
  97. PIPSEC_POLICY_OBJECT * ppIpsecPolicyObjects = NULL;
  98. DWORD dwNumPolicyObjectsReturned = 0;
  99. DWORD dwIndex = 0;
  100. WCHAR szPolicyName[MAX_PATH];
  101. DWORD dwSize = 0;
  102. *pppIpsecPolicyObjects = NULL;
  103. *pdwNumPolicyObjects = 0;
  104. while (1) {
  105. dwSize = MAX_PATH;
  106. szPolicyName[0] = L'\0';
  107. dwError = RegEnumKeyExW(
  108. hRegistryKey,
  109. dwIndex,
  110. szPolicyName,
  111. &dwSize,
  112. NULL,
  113. NULL,
  114. 0,
  115. 0
  116. );
  117. if (dwError == ERROR_NO_MORE_ITEMS) {
  118. break;
  119. }
  120. BAIL_ON_WIN32_ERROR(dwError);
  121. if (!wcsstr(szPolicyName, L"ipsecPolicy")) {
  122. dwIndex++;
  123. continue;
  124. }
  125. pIpsecPolicyObject = NULL;
  126. dwError =UnMarshallRegistryPolicyObject(
  127. hRegistryKey,
  128. pszIpsecRootContainer,
  129. szPolicyName,
  130. REG_RELATIVE_NAME,
  131. &pIpsecPolicyObject
  132. );
  133. if (dwError == ERROR_SUCCESS) {
  134. dwError = ReallocatePolMem(
  135. (LPVOID *) &ppIpsecPolicyObjects,
  136. sizeof(PIPSEC_POLICY_OBJECT)*(dwNumPolicyObjectsReturned),
  137. sizeof(PIPSEC_POLICY_OBJECT)*(dwNumPolicyObjectsReturned + 1)
  138. );
  139. BAIL_ON_WIN32_ERROR(dwError);
  140. *(ppIpsecPolicyObjects + dwNumPolicyObjectsReturned) = pIpsecPolicyObject;
  141. dwNumPolicyObjectsReturned++;
  142. }
  143. dwIndex++;
  144. }
  145. *pppIpsecPolicyObjects = ppIpsecPolicyObjects;
  146. *pdwNumPolicyObjects = dwNumPolicyObjectsReturned;
  147. dwError = ERROR_SUCCESS;
  148. return(dwError);
  149. error:
  150. if (ppIpsecPolicyObjects) {
  151. FreeIpsecPolicyObjects(
  152. ppIpsecPolicyObjects,
  153. dwNumPolicyObjectsReturned
  154. );
  155. }
  156. if (pIpsecPolicyObject) {
  157. FreeIpsecPolicyObject(
  158. pIpsecPolicyObject
  159. );
  160. }
  161. *pppIpsecPolicyObjects = NULL;
  162. *pdwNumPolicyObjects = 0;
  163. return(dwError);
  164. }
  165. DWORD
  166. RegSetPolicyData(
  167. HKEY hRegistryKey,
  168. LPWSTR pszIpsecRootContainer,
  169. LPWSTR pszLocationName,
  170. PIPSEC_POLICY_DATA pIpsecPolicyData
  171. )
  172. {
  173. DWORD dwError = 0;
  174. PIPSEC_POLICY_OBJECT pIpsecPolicyObject = NULL;
  175. LPWSTR pszAbsOldISAKMPRef = NULL;
  176. LPWSTR pszRelOldISAKMPRef = NULL;
  177. WCHAR szAbsPolicyReference[MAX_PATH];
  178. LPWSTR pszRelISAKMPReference = NULL;
  179. DWORD dwRootPathLen = 0;
  180. BOOL bIsActive = FALSE;
  181. dwRootPathLen = wcslen(pszIpsecRootContainer);
  182. dwError = RegGetPolicyExistingISAKMPRef(
  183. hRegistryKey,
  184. pIpsecPolicyData,
  185. &pszAbsOldISAKMPRef
  186. );
  187. // BAIL_ON_WIN32_ERROR(dwError);
  188. if (pszAbsOldISAKMPRef && *pszAbsOldISAKMPRef) {
  189. pszRelOldISAKMPRef = pszAbsOldISAKMPRef + dwRootPathLen + 1;
  190. }
  191. dwError = RegMarshallPolicyObject(
  192. pIpsecPolicyData,
  193. pszIpsecRootContainer,
  194. &pIpsecPolicyObject
  195. );
  196. BAIL_ON_WIN32_ERROR(dwError);
  197. dwError = RegSetPolicyObject(
  198. hRegistryKey,
  199. pszIpsecRootContainer,
  200. pIpsecPolicyObject
  201. );
  202. BAIL_ON_WIN32_ERROR(dwError);
  203. szAbsPolicyReference[0] = L'\0';
  204. wcscpy(szAbsPolicyReference, pszIpsecRootContainer);
  205. wcscat(szAbsPolicyReference, L"\\");
  206. wcscat(szAbsPolicyReference, pIpsecPolicyObject->pszIpsecOwnersReference);
  207. pszRelISAKMPReference = pIpsecPolicyObject->pszIpsecISAKMPReference
  208. + dwRootPathLen + 1;
  209. if (pszRelOldISAKMPRef) {
  210. dwError = RegRemovePolicyReferenceFromISAKMPObject(
  211. hRegistryKey,
  212. pszRelOldISAKMPRef,
  213. szAbsPolicyReference
  214. );
  215. // BAIL_ON_WIN32_ERROR(dwError);
  216. }
  217. dwError = RegAddPolicyReferenceToISAKMPObject(
  218. hRegistryKey,
  219. pszRelISAKMPReference,
  220. szAbsPolicyReference
  221. );
  222. BAIL_ON_WIN32_ERROR(dwError);
  223. dwError = RegUpdateISAKMPReferenceInPolicyObject(
  224. hRegistryKey,
  225. pIpsecPolicyObject->pszIpsecOwnersReference,
  226. pszAbsOldISAKMPRef,
  227. pIpsecPolicyObject->pszIpsecISAKMPReference
  228. );
  229. BAIL_ON_WIN32_ERROR(dwError);
  230. dwError = IsRegPolicyCurrentlyActive(
  231. hRegistryKey,
  232. pszIpsecRootContainer,
  233. pIpsecPolicyData->PolicyIdentifier,
  234. &bIsActive
  235. );
  236. BAIL_ON_WIN32_ERROR(dwError);
  237. if (bIsActive) {
  238. dwError = PingPolicyAgentSvc(pszLocationName);
  239. BAIL_ON_WIN32_ERROR(dwError);
  240. }
  241. error:
  242. if (pIpsecPolicyObject) {
  243. FreeIpsecPolicyObject(pIpsecPolicyObject);
  244. }
  245. if (pszAbsOldISAKMPRef) {
  246. FreePolStr(pszAbsOldISAKMPRef);
  247. }
  248. return(dwError);
  249. }
  250. DWORD
  251. RegSetPolicyObject(
  252. HKEY hRegistryKey,
  253. LPWSTR pszIpsecRootContainer,
  254. PIPSEC_POLICY_OBJECT pIpsecPolicyObject
  255. )
  256. {
  257. DWORD dwError = 0;
  258. dwError = PersistPolicyObject(
  259. hRegistryKey,
  260. pIpsecPolicyObject
  261. );
  262. BAIL_ON_WIN32_ERROR(dwError);
  263. error:
  264. return(dwError);
  265. }
  266. DWORD
  267. RegCreatePolicyData(
  268. HKEY hRegistryKey,
  269. LPWSTR pszIpsecRootContainer,
  270. PIPSEC_POLICY_DATA pIpsecPolicyData
  271. )
  272. {
  273. DWORD dwError = 0;
  274. PIPSEC_POLICY_OBJECT pIpsecPolicyObject = NULL;
  275. WCHAR szAbsPolicyReference[MAX_PATH];
  276. LPWSTR pszRelISAKMPReference = NULL;
  277. DWORD dwRootPathLen = 0;
  278. dwRootPathLen = wcslen(pszIpsecRootContainer);
  279. dwError = RegMarshallPolicyObject(
  280. pIpsecPolicyData,
  281. pszIpsecRootContainer,
  282. &pIpsecPolicyObject
  283. );
  284. BAIL_ON_WIN32_ERROR(dwError);
  285. dwError = RegCreatePolicyObject(
  286. hRegistryKey,
  287. pszIpsecRootContainer,
  288. pIpsecPolicyObject
  289. );
  290. BAIL_ON_WIN32_ERROR(dwError);
  291. szAbsPolicyReference[0] = L'\0';
  292. wcscpy(szAbsPolicyReference, pszIpsecRootContainer);
  293. wcscat(szAbsPolicyReference, L"\\");
  294. wcscat(szAbsPolicyReference, pIpsecPolicyObject->pszIpsecOwnersReference);
  295. pszRelISAKMPReference = pIpsecPolicyObject->pszIpsecISAKMPReference
  296. + dwRootPathLen + 1;
  297. //
  298. // Write the ISAKMP object reference.
  299. //
  300. dwError = RegAddPolicyReferenceToISAKMPObject(
  301. hRegistryKey,
  302. pszRelISAKMPReference,
  303. szAbsPolicyReference
  304. );
  305. BAIL_ON_WIN32_ERROR(dwError);
  306. //
  307. // Write the Policy object reference.
  308. //
  309. dwError = RegAddISAKMPReferenceToPolicyObject(
  310. hRegistryKey,
  311. pIpsecPolicyObject->pszIpsecOwnersReference,
  312. pIpsecPolicyObject->pszIpsecISAKMPReference
  313. );
  314. BAIL_ON_WIN32_ERROR(dwError);
  315. error:
  316. if (pIpsecPolicyObject) {
  317. FreeIpsecPolicyObject(
  318. pIpsecPolicyObject
  319. );
  320. }
  321. return(dwError);
  322. }
  323. DWORD
  324. RegCreatePolicyObject(
  325. HKEY hRegistryKey,
  326. LPWSTR pszIpsecRootContainer,
  327. PIPSEC_POLICY_OBJECT pIpsecPolicyObject
  328. )
  329. {
  330. DWORD dwError = 0;
  331. dwError = PersistPolicyObject(
  332. hRegistryKey,
  333. pIpsecPolicyObject
  334. );
  335. BAIL_ON_WIN32_ERROR(dwError);
  336. error:
  337. return(dwError);
  338. }
  339. DWORD
  340. RegDeletePolicyData(
  341. HKEY hRegistryKey,
  342. LPWSTR pszIpsecRootContainer,
  343. PIPSEC_POLICY_DATA pIpsecPolicyData
  344. )
  345. {
  346. DWORD dwError = ERROR_SUCCESS;
  347. PIPSEC_POLICY_OBJECT pIpsecPolicyObject = NULL;
  348. WCHAR szAbsPolicyReference[MAX_PATH];
  349. LPWSTR pszRelISAKMPReference = NULL;
  350. DWORD dwRootPathLen = 0;
  351. BOOL bIsActive = FALSE;
  352. dwError = IsRegPolicyCurrentlyActive(
  353. hRegistryKey,
  354. pszIpsecRootContainer,
  355. pIpsecPolicyData->PolicyIdentifier,
  356. &bIsActive
  357. );
  358. BAIL_ON_WIN32_ERROR(dwError);
  359. if (bIsActive) {
  360. dwError = ERROR_INVALID_PARAMETER;
  361. BAIL_ON_WIN32_ERROR(dwError);
  362. }
  363. dwRootPathLen = wcslen(pszIpsecRootContainer);
  364. dwError = RegMarshallPolicyObject(
  365. pIpsecPolicyData,
  366. pszIpsecRootContainer,
  367. &pIpsecPolicyObject
  368. );
  369. BAIL_ON_WIN32_ERROR(dwError);
  370. szAbsPolicyReference[0] = L'\0';
  371. wcscpy(szAbsPolicyReference, pszIpsecRootContainer);
  372. wcscat(szAbsPolicyReference, L"\\");
  373. wcscat(szAbsPolicyReference, pIpsecPolicyObject->pszIpsecOwnersReference);
  374. pszRelISAKMPReference = pIpsecPolicyObject->pszIpsecISAKMPReference
  375. + dwRootPathLen + 1;
  376. dwError = RegRemovePolicyReferenceFromISAKMPObject(
  377. hRegistryKey,
  378. pszRelISAKMPReference,
  379. szAbsPolicyReference
  380. );
  381. // BAIL_ON_WIN32_ERROR(dwError);
  382. dwError = RegDeleteKeyW(
  383. hRegistryKey,
  384. pIpsecPolicyObject->pszIpsecOwnersReference
  385. );
  386. BAIL_ON_WIN32_ERROR(dwError);
  387. error:
  388. if (pIpsecPolicyObject) {
  389. FreeIpsecPolicyObject(pIpsecPolicyObject);
  390. }
  391. return(dwError);
  392. }
  393. DWORD
  394. RegUnmarshallPolicyData(
  395. PIPSEC_POLICY_OBJECT pIpsecPolicyObject,
  396. PIPSEC_POLICY_DATA * ppIpsecPolicyData
  397. )
  398. {
  399. DWORD dwError = 0;
  400. dwError = UnmarshallPolicyObject(
  401. pIpsecPolicyObject,
  402. IPSEC_REGISTRY_PROVIDER,
  403. ppIpsecPolicyData
  404. );
  405. return(dwError);
  406. }
  407. DWORD
  408. RegMarshallPolicyObject(
  409. PIPSEC_POLICY_DATA pIpsecPolicyData,
  410. LPWSTR pszIpsecRootContainer,
  411. PIPSEC_POLICY_OBJECT * ppIpsecPolicyObject
  412. )
  413. {
  414. DWORD dwError = 0;
  415. PIPSEC_POLICY_OBJECT pIpsecPolicyObject = NULL;
  416. WCHAR szGuid[MAX_PATH];
  417. WCHAR szDistinguishedName[MAX_PATH];
  418. LPBYTE pBuffer = NULL;
  419. DWORD dwBufferLen = 0;
  420. LPWSTR pszStringUuid = NULL;
  421. LPWSTR pszIpsecISAKMPReference = NULL;
  422. time_t PresentTime;
  423. szGuid[0] = L'\0';
  424. szDistinguishedName[0] = L'\0';
  425. pIpsecPolicyObject = (PIPSEC_POLICY_OBJECT)AllocPolMem(
  426. sizeof(IPSEC_POLICY_OBJECT)
  427. );
  428. if (!pIpsecPolicyObject) {
  429. dwError = ERROR_OUTOFMEMORY;
  430. BAIL_ON_WIN32_ERROR(dwError);
  431. }
  432. dwError = UuidToString(
  433. &pIpsecPolicyData->PolicyIdentifier,
  434. &pszStringUuid
  435. );
  436. BAIL_ON_WIN32_ERROR(dwError);
  437. wcscpy(szGuid, L"{");
  438. wcscat(szGuid, pszStringUuid);
  439. wcscat(szGuid, L"}");
  440. //
  441. // Fill in the distinguishedName
  442. //
  443. wcscpy(szDistinguishedName,L"ipsecPolicy");
  444. wcscat(szDistinguishedName, szGuid);
  445. pIpsecPolicyObject->pszIpsecOwnersReference = AllocPolStr(
  446. szDistinguishedName
  447. );
  448. if (!pIpsecPolicyObject->pszIpsecOwnersReference) {
  449. dwError = ERROR_OUTOFMEMORY;
  450. BAIL_ON_WIN32_ERROR(dwError);
  451. }
  452. //
  453. // Fill in the ipsecName
  454. //
  455. if (pIpsecPolicyData->pszIpsecName &&
  456. *pIpsecPolicyData->pszIpsecName) {
  457. pIpsecPolicyObject->pszIpsecName = AllocPolStr(
  458. pIpsecPolicyData->pszIpsecName
  459. );
  460. if (!pIpsecPolicyObject->pszIpsecName) {
  461. dwError = ERROR_OUTOFMEMORY;
  462. BAIL_ON_WIN32_ERROR(dwError);
  463. }
  464. }
  465. if (pIpsecPolicyData->pszDescription &&
  466. *pIpsecPolicyData->pszDescription) {
  467. pIpsecPolicyObject->pszDescription = AllocPolStr(
  468. pIpsecPolicyData->pszDescription
  469. );
  470. if (!pIpsecPolicyObject->pszDescription) {
  471. dwError = ERROR_OUTOFMEMORY;
  472. BAIL_ON_WIN32_ERROR(dwError);
  473. }
  474. }
  475. //
  476. // Fill in the ipsecID
  477. //
  478. pIpsecPolicyObject->pszIpsecID = AllocPolStr(
  479. szGuid
  480. );
  481. if (!pIpsecPolicyObject->pszIpsecID) {
  482. dwError = ERROR_OUTOFMEMORY;
  483. BAIL_ON_WIN32_ERROR(dwError);
  484. }
  485. //
  486. // Fill in the ipsecDataType
  487. //
  488. pIpsecPolicyObject->dwIpsecDataType = 0x100;
  489. //
  490. // Marshall the pIpsecDataBuffer and the Length
  491. //
  492. dwError = MarshallPolicyBuffer(
  493. pIpsecPolicyData,
  494. &pBuffer,
  495. &dwBufferLen
  496. );
  497. BAIL_ON_WIN32_ERROR(dwError);
  498. pIpsecPolicyObject->pIpsecData = pBuffer;
  499. pIpsecPolicyObject->dwIpsecDataLen = dwBufferLen;
  500. dwError = ConvertGuidToISAKMPString(
  501. pIpsecPolicyData->ISAKMPIdentifier,
  502. pszIpsecRootContainer,
  503. &pszIpsecISAKMPReference
  504. );
  505. BAIL_ON_WIN32_ERROR(dwError);
  506. pIpsecPolicyObject->pszIpsecISAKMPReference = pszIpsecISAKMPReference;
  507. time(&PresentTime);
  508. pIpsecPolicyObject->dwWhenChanged = (DWORD) PresentTime;
  509. *ppIpsecPolicyObject = pIpsecPolicyObject;
  510. cleanup:
  511. if (pszStringUuid) {
  512. RpcStringFree(
  513. &pszStringUuid
  514. );
  515. }
  516. return(dwError);
  517. error:
  518. if (pIpsecPolicyObject) {
  519. FreeIpsecPolicyObject(
  520. pIpsecPolicyObject
  521. );
  522. }
  523. *ppIpsecPolicyObject = NULL;
  524. goto cleanup;
  525. }
  526. DWORD
  527. MarshallPolicyBuffer(
  528. PIPSEC_POLICY_DATA pIpsecPolicyData,
  529. LPBYTE * ppBuffer,
  530. DWORD * pdwBufferLen
  531. )
  532. {
  533. LPBYTE pBuffer = NULL;
  534. DWORD dwSize = 0;
  535. DWORD dwError = 0;
  536. DWORD dwPollingInterval = 0;
  537. LPBYTE pCurrentPos = NULL;
  538. DWORD dwEffectiveSize = 0;
  539. // {22202163-4F4C-11d1-863B-00A0248D3021}
  540. static const GUID GUID_IPSEC_POLICY_DATA_BLOB =
  541. { 0x22202163, 0x4f4c, 0x11d1, { 0x86, 0x3b, 0x0, 0xa0, 0x24, 0x8d, 0x30, 0x21 } };
  542. dwSize += sizeof(GUID);
  543. dwSize += sizeof(DWORD);
  544. dwSize += sizeof(DWORD);
  545. dwSize++;
  546. pBuffer = AllocPolMem(dwSize);
  547. if (!pBuffer) {
  548. dwError = ERROR_OUTOFMEMORY;
  549. BAIL_ON_WIN32_ERROR(dwError);
  550. }
  551. pCurrentPos = pBuffer;
  552. memcpy(pCurrentPos, &GUID_IPSEC_POLICY_DATA_BLOB, sizeof(GUID));
  553. pCurrentPos += sizeof(GUID);
  554. dwEffectiveSize = dwSize - sizeof(GUID) - sizeof(DWORD) - 1;
  555. memcpy(pCurrentPos, &dwEffectiveSize, sizeof(DWORD));
  556. pCurrentPos += sizeof(DWORD);
  557. dwPollingInterval = pIpsecPolicyData->dwPollingInterval;
  558. memcpy(pCurrentPos, &dwPollingInterval, sizeof(DWORD));
  559. *ppBuffer = pBuffer;
  560. *pdwBufferLen = dwSize;
  561. return(dwError);
  562. error:
  563. if (pBuffer) {
  564. FreePolMem(pBuffer);
  565. }
  566. *ppBuffer = NULL;
  567. *pdwBufferLen = 0;
  568. return(dwError);
  569. }
  570. DWORD
  571. ConvertGuidToISAKMPString(
  572. GUID ISAKMPIdentifier,
  573. LPWSTR pszIpsecRootContainer,
  574. LPWSTR * ppszIpsecISAKMPReference
  575. )
  576. {
  577. DWORD dwError = 0;
  578. WCHAR szISAKMPReference[MAX_PATH];
  579. LPWSTR pszIpsecISAKMPReference = NULL;
  580. WCHAR szGuidString[MAX_PATH];
  581. LPWSTR pszStringUuid = NULL;
  582. dwError = UuidToString(
  583. &ISAKMPIdentifier,
  584. &pszStringUuid
  585. );
  586. BAIL_ON_WIN32_ERROR(dwError);
  587. szGuidString[0] = L'\0';
  588. wcscpy(szGuidString, L"{");
  589. wcscat(szGuidString, pszStringUuid);
  590. wcscat(szGuidString, L"}");
  591. szISAKMPReference[0] = L'\0';
  592. wcscpy(szISAKMPReference, pszIpsecRootContainer);
  593. wcscat(szISAKMPReference, L"\\");
  594. wcscat(szISAKMPReference, L"ipsecISAKMPPolicy");
  595. wcscat(szISAKMPReference, szGuidString);
  596. pszIpsecISAKMPReference = AllocPolStr(
  597. szISAKMPReference
  598. );
  599. if (!pszIpsecISAKMPReference) {
  600. dwError = ERROR_OUTOFMEMORY;
  601. BAIL_ON_WIN32_ERROR(dwError);
  602. }
  603. *ppszIpsecISAKMPReference = pszIpsecISAKMPReference;
  604. cleanup:
  605. if (pszStringUuid) {
  606. RpcStringFree(&pszStringUuid);
  607. }
  608. return(dwError);
  609. error:
  610. *ppszIpsecISAKMPReference = NULL;
  611. goto cleanup;
  612. }
  613. DWORD
  614. RegGetPolicyExistingISAKMPRef(
  615. HKEY hRegistryKey,
  616. PIPSEC_POLICY_DATA pIpsecPolicyData,
  617. LPWSTR * ppszISAKMPName
  618. )
  619. {
  620. DWORD dwError = 0;
  621. LPWSTR pszStringUuid = NULL;
  622. WCHAR szRelativeName[MAX_PATH];
  623. HKEY hRegKey = NULL;
  624. DWORD dwSize = 0;
  625. szRelativeName[0] = L'\0';
  626. dwError = UuidToString(
  627. &pIpsecPolicyData->PolicyIdentifier,
  628. &pszStringUuid
  629. );
  630. BAIL_ON_WIN32_ERROR(dwError);
  631. wcscpy(szRelativeName, L"ipsecPolicy");
  632. wcscat(szRelativeName, L"{");
  633. wcscat(szRelativeName, pszStringUuid);
  634. wcscat(szRelativeName, L"}");
  635. dwError = RegOpenKeyExW(
  636. hRegistryKey,
  637. szRelativeName,
  638. 0,
  639. KEY_ALL_ACCESS,
  640. &hRegKey
  641. );
  642. BAIL_ON_WIN32_ERROR(dwError);
  643. dwError = RegstoreQueryValue(
  644. hRegKey,
  645. L"ipsecISAKMPReference",
  646. REG_SZ,
  647. (LPBYTE *)ppszISAKMPName,
  648. &dwSize
  649. );
  650. BAIL_ON_WIN32_ERROR(dwError);
  651. error:
  652. if (pszStringUuid) {
  653. RpcStringFree(&pszStringUuid);
  654. }
  655. if (hRegKey) {
  656. RegCloseKey(hRegKey);
  657. }
  658. return (dwError);
  659. }
  660. DWORD
  661. RegAssignPolicy(
  662. HKEY hRegistryKey,
  663. LPWSTR pszIpsecRootContainer,
  664. GUID PolicyIdentifier,
  665. LPWSTR pszLocationName
  666. )
  667. {
  668. DWORD dwError = 0;
  669. WCHAR szRelativeName[MAX_PATH];
  670. LPWSTR pszStringUuid = NULL;
  671. WCHAR szAbsPolicyRef[MAX_PATH];
  672. szRelativeName[0] = L'\0';
  673. dwError = UuidToString(
  674. &PolicyIdentifier,
  675. &pszStringUuid
  676. );
  677. BAIL_ON_WIN32_ERROR(dwError);
  678. wcscpy(szRelativeName, L"ipsecPolicy");
  679. wcscat(szRelativeName, L"{");
  680. wcscat(szRelativeName, pszStringUuid);
  681. wcscat(szRelativeName, L"}");
  682. szAbsPolicyRef[0] = L'\0';
  683. wcscpy(szAbsPolicyRef, pszIpsecRootContainer);
  684. wcscat(szAbsPolicyRef, L"\\");
  685. wcscat(szAbsPolicyRef, szRelativeName);
  686. dwError = RegSetValueExW(
  687. hRegistryKey,
  688. L"ActivePolicy",
  689. 0,
  690. REG_SZ,
  691. (LPBYTE) szAbsPolicyRef,
  692. (wcslen(szAbsPolicyRef) + 1)*sizeof(WCHAR)
  693. );
  694. BAIL_ON_WIN32_ERROR(dwError);
  695. dwError = PingPolicyAgentSvc(pszLocationName);
  696. BAIL_ON_WIN32_ERROR(dwError);
  697. error:
  698. if (pszStringUuid) {
  699. RpcStringFree(&pszStringUuid);
  700. }
  701. return (dwError);
  702. }
  703. DWORD
  704. RegUnassignPolicy(
  705. HKEY hRegistryKey,
  706. LPWSTR pszIpsecRootContainer,
  707. GUID PolicyIdentifier,
  708. LPWSTR pszLocationName
  709. )
  710. {
  711. DWORD dwError = 0;
  712. dwError = RegDeleteValueW(
  713. hRegistryKey,
  714. L"ActivePolicy"
  715. );
  716. BAIL_ON_WIN32_ERROR(dwError);
  717. dwError = PingPolicyAgentSvc(pszLocationName);
  718. BAIL_ON_WIN32_ERROR(dwError);
  719. error:
  720. return (dwError);
  721. }
  722. DWORD
  723. PingPolicyAgentSvc(
  724. LPWSTR pszLocationName
  725. )
  726. {
  727. SC_HANDLE ServiceDatabase = NULL;
  728. SC_HANDLE ServiceHandle = NULL;
  729. BOOL bStatus = FALSE;
  730. DWORD dwError = 0;
  731. SERVICE_STATUS IpsecStatus;
  732. memset(&IpsecStatus, 0, sizeof(SERVICE_STATUS));
  733. ServiceDatabase = OpenSCManagerW(
  734. pszLocationName,
  735. NULL,
  736. SC_MANAGER_ALL_ACCESS
  737. );
  738. if (ServiceDatabase == NULL) {
  739. dwError = GetLastError();
  740. BAIL_ON_WIN32_ERROR(dwError);
  741. }
  742. ServiceHandle = OpenService(
  743. ServiceDatabase,
  744. "PolicyAgent",
  745. SERVICE_ALL_ACCESS
  746. );
  747. if (ServiceHandle == NULL) {
  748. dwError = GetLastError();
  749. BAIL_ON_WIN32_ERROR(dwError);
  750. }
  751. bStatus = QueryServiceStatus(
  752. ServiceHandle,
  753. &IpsecStatus
  754. );
  755. if (bStatus == FALSE) {
  756. dwError = GetLastError();
  757. BAIL_ON_WIN32_ERROR(dwError);
  758. }
  759. if (IpsecStatus.dwCurrentState == SERVICE_STOPPED) {
  760. bStatus = StartService(
  761. ServiceHandle,
  762. 0,
  763. NULL
  764. );
  765. if (bStatus == FALSE) {
  766. dwError = GetLastError();
  767. BAIL_ON_WIN32_ERROR(dwError);
  768. }
  769. }
  770. else if (IpsecStatus.dwCurrentState == SERVICE_RUNNING) {
  771. bStatus = ControlService(
  772. ServiceHandle,
  773. 129,
  774. &IpsecStatus
  775. );
  776. if (bStatus == FALSE) {
  777. dwError = GetLastError();
  778. BAIL_ON_WIN32_ERROR(dwError);
  779. }
  780. }
  781. error:
  782. if (ServiceDatabase != NULL) {
  783. CloseServiceHandle(ServiceDatabase);
  784. }
  785. if (ServiceHandle != NULL) {
  786. CloseServiceHandle(ServiceHandle);
  787. }
  788. return (dwError);
  789. }
  790. DWORD
  791. IsRegPolicyCurrentlyActive(
  792. HKEY hRegistryKey,
  793. LPWSTR pszIpsecRootContainer,
  794. GUID PolicyIdentifier,
  795. PBOOL pbIsActive
  796. )
  797. {
  798. DWORD dwError = 0;
  799. PIPSEC_POLICY_DATA pIpsecPolicyData = NULL;
  800. *pbIsActive = FALSE;
  801. dwError = RegGetAssignedPolicyData(
  802. hRegistryKey,
  803. pszIpsecRootContainer,
  804. &pIpsecPolicyData
  805. );
  806. if (pIpsecPolicyData) {
  807. if (!memcmp(
  808. &PolicyIdentifier,
  809. &pIpsecPolicyData->PolicyIdentifier,
  810. sizeof(GUID))) {
  811. *pbIsActive = TRUE;
  812. }
  813. FreeIpsecPolicyData(pIpsecPolicyData);
  814. }
  815. dwError = ERROR_SUCCESS;
  816. return (dwError);
  817. }
  818. DWORD
  819. RegGetPolicyData(
  820. HKEY hRegistryKey,
  821. LPWSTR pszIpsecRootContainer,
  822. GUID PolicyGUID,
  823. PIPSEC_POLICY_DATA * ppIpsecPolicyData
  824. )
  825. {
  826. DWORD dwError = 0;
  827. PIPSEC_POLICY_OBJECT pIpsecPolicyObject = NULL;
  828. PIPSEC_POLICY_DATA pIpsecPolicyData = NULL;
  829. WCHAR szIpsecPolicyName[MAX_PATH];
  830. LPWSTR pszPolicyName = NULL;
  831. szIpsecPolicyName[0] = L'\0';
  832. wcscpy(szIpsecPolicyName, L"ipsecPolicy");
  833. dwError = UuidToString(&PolicyGUID, &pszPolicyName);
  834. BAIL_ON_WIN32_ERROR(dwError);
  835. wcscat(szIpsecPolicyName, L"{");
  836. wcscat(szIpsecPolicyName, pszPolicyName);
  837. wcscat(szIpsecPolicyName, L"}");
  838. dwError = UnMarshallRegistryPolicyObject(
  839. hRegistryKey,
  840. pszIpsecRootContainer,
  841. szIpsecPolicyName,
  842. REG_RELATIVE_NAME,
  843. &pIpsecPolicyObject
  844. );
  845. BAIL_ON_WIN32_ERROR(dwError);
  846. dwError = RegUnmarshallPolicyData(
  847. pIpsecPolicyObject,
  848. &pIpsecPolicyData
  849. );
  850. BAIL_ON_WIN32_ERROR(dwError);
  851. error:
  852. if (pIpsecPolicyObject) {
  853. FreeIpsecPolicyObject(
  854. pIpsecPolicyObject
  855. );
  856. }
  857. if (pszPolicyName) {
  858. RpcStringFree(&pszPolicyName);
  859. }
  860. *ppIpsecPolicyData = pIpsecPolicyData;
  861. return(dwError);
  862. }
  863. DWORD
  864. RegPingPASvcForActivePolicy(
  865. HKEY hRegistryKey,
  866. LPWSTR pszIpsecRootContainer,
  867. LPWSTR pszLocationName
  868. )
  869. {
  870. DWORD dwError = 0;
  871. PIPSEC_POLICY_DATA pIpsecPolicyData = NULL;
  872. WCHAR szIpsecPolicyName[MAX_PATH];
  873. LPWSTR pszPolicyName = NULL;
  874. WCHAR szAbsPolicyReference[MAX_PATH];
  875. dwError = RegGetAssignedPolicyData(
  876. hRegistryKey,
  877. pszIpsecRootContainer,
  878. &pIpsecPolicyData
  879. );
  880. BAIL_ON_WIN32_ERROR(dwError);
  881. if (!pIpsecPolicyData) {
  882. dwError = ERROR_SUCCESS;
  883. return (dwError);
  884. }
  885. szIpsecPolicyName[0] = L'\0';
  886. wcscpy(szIpsecPolicyName, L"ipsecPolicy");
  887. dwError = UuidToString(&pIpsecPolicyData->PolicyIdentifier, &pszPolicyName);
  888. BAIL_ON_WIN32_ERROR(dwError);
  889. wcscat(szIpsecPolicyName, L"{");
  890. wcscat(szIpsecPolicyName, pszPolicyName);
  891. wcscat(szIpsecPolicyName, L"}");
  892. szAbsPolicyReference[0] = L'\0';
  893. wcscpy(szAbsPolicyReference, pszIpsecRootContainer);
  894. wcscat(szAbsPolicyReference, L"\\");
  895. wcscat(szAbsPolicyReference, szIpsecPolicyName);
  896. dwError = RegUpdatePolicy(
  897. hRegistryKey,
  898. pszIpsecRootContainer,
  899. szAbsPolicyReference
  900. );
  901. BAIL_ON_WIN32_ERROR(dwError);
  902. dwError = PingPolicyAgentSvc(pszLocationName);
  903. BAIL_ON_WIN32_ERROR(dwError);
  904. error:
  905. if (pIpsecPolicyData) {
  906. FreeIpsecPolicyData(pIpsecPolicyData);
  907. }
  908. if (pszPolicyName) {
  909. RpcStringFree(&pszPolicyName);
  910. }
  911. return (dwError);
  912. }