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.

1196 lines
30 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. SecStrCatW(szISAKMPReference, pszIpsecRootContainer, MAX_PATH);
  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 hHKLMKey,
  663. HKEY hRegistryKey,
  664. LPWSTR pszIpsecRootContainer,
  665. GUID PolicyIdentifier,
  666. LPWSTR pszLocationName
  667. )
  668. {
  669. DWORD dwError = 0;
  670. WCHAR szRelativeName[MAX_PATH];
  671. LPWSTR pszStringUuid = NULL;
  672. WCHAR szAbsPolicyRef[MAX_PATH];
  673. DWORD dwRealProvider = 0;
  674. szRelativeName[0] = L'\0';
  675. dwError = UuidToString(
  676. &PolicyIdentifier,
  677. &pszStringUuid
  678. );
  679. BAIL_ON_WIN32_ERROR(dwError);
  680. wcscpy(szRelativeName, L"ipsecPolicy");
  681. wcscat(szRelativeName, L"{");
  682. wcscat(szRelativeName, pszStringUuid);
  683. wcscat(szRelativeName, L"}");
  684. szAbsPolicyRef[0] = L'\0';
  685. SecStrCatW(szAbsPolicyRef, pszIpsecRootContainer, MAX_PATH);
  686. wcscat(szAbsPolicyRef, L"\\");
  687. wcscat(szAbsPolicyRef, szRelativeName);
  688. dwError = RegSetValueExW(
  689. hRegistryKey,
  690. L"ActivePolicy",
  691. 0,
  692. REG_SZ,
  693. (LPBYTE) szAbsPolicyRef,
  694. (wcslen(szAbsPolicyRef) + 1)*sizeof(WCHAR)
  695. );
  696. BAIL_ON_WIN32_ERROR(dwError);
  697. // dwProvider store is actually wrong because it's set to IPSEC_REGISTRY_PROVIDER for
  698. // both perstent and registry policy. Therefore check Container to determine
  699. // actual location of store.
  700. //
  701. if (wcscmp(pszIpsecRootContainer, gpszRegPersistentContainer) == 0) {
  702. dwRealProvider = IPSEC_PERSISTENT_PROVIDER;
  703. } else {
  704. dwRealProvider = IPSEC_REGISTRY_PROVIDER;
  705. }
  706. dwError = IPSecChooseDriverBootMode(
  707. hHKLMKey,
  708. dwRealProvider,
  709. POL_ACTION_ASSIGN
  710. );
  711. BAIL_ON_WIN32_ERROR(dwError);
  712. dwError = PingPolicyAgentSvc(pszLocationName);
  713. BAIL_ON_WIN32_ERROR(dwError);
  714. error:
  715. if (pszStringUuid) {
  716. RpcStringFree(&pszStringUuid);
  717. }
  718. return (dwError);
  719. }
  720. DWORD
  721. RegUnassignPolicy(
  722. HKEY hHKLMKey,
  723. HKEY hRegistryKey,
  724. LPWSTR pszIpsecRootContainer,
  725. GUID PolicyIdentifier,
  726. LPWSTR pszLocationName
  727. )
  728. {
  729. DWORD dwError = 0;
  730. DWORD dwRealProvider = 0;
  731. dwError = RegDeleteValueW(
  732. hRegistryKey,
  733. L"ActivePolicy"
  734. );
  735. BAIL_ON_WIN32_ERROR(dwError);
  736. // dwProvider in store is actually wrong because it's set to IPSEC_REGISTRY_PROVIDER for
  737. // both perstent and registry policy. Therefore check Container to determine
  738. // actual location of store.
  739. //
  740. if (wcscmp(pszIpsecRootContainer, gpszRegPersistentContainer) == 0) {
  741. dwRealProvider = IPSEC_PERSISTENT_PROVIDER;
  742. } else {
  743. dwRealProvider = IPSEC_REGISTRY_PROVIDER;
  744. }
  745. dwError = IPSecChooseDriverBootMode(
  746. hHKLMKey,
  747. dwRealProvider,
  748. POL_ACTION_UNASSIGN
  749. );
  750. BAIL_ON_WIN32_ERROR(dwError);
  751. dwError = PingPolicyAgentSvc(pszLocationName);
  752. BAIL_ON_WIN32_ERROR(dwError);
  753. error:
  754. return (dwError);
  755. }
  756. DWORD
  757. PingPolicyAgentSvc(
  758. LPWSTR pszLocationName
  759. )
  760. {
  761. SC_HANDLE ServiceDatabase = NULL;
  762. SC_HANDLE ServiceHandle = NULL;
  763. BOOL bStatus = FALSE;
  764. DWORD dwError = 0;
  765. SERVICE_STATUS IpsecStatus;
  766. memset(&IpsecStatus, 0, sizeof(SERVICE_STATUS));
  767. ServiceDatabase = OpenSCManagerW(
  768. pszLocationName,
  769. NULL,
  770. SC_MANAGER_ALL_ACCESS
  771. );
  772. if (ServiceDatabase == NULL) {
  773. dwError = GetLastError();
  774. BAIL_ON_WIN32_ERROR(dwError);
  775. }
  776. ServiceHandle = OpenService(
  777. ServiceDatabase,
  778. "PolicyAgent",
  779. SERVICE_ALL_ACCESS
  780. );
  781. if (ServiceHandle == NULL) {
  782. dwError = GetLastError();
  783. BAIL_ON_WIN32_ERROR(dwError);
  784. }
  785. bStatus = QueryServiceStatus(
  786. ServiceHandle,
  787. &IpsecStatus
  788. );
  789. if (bStatus == FALSE) {
  790. dwError = GetLastError();
  791. BAIL_ON_WIN32_ERROR(dwError);
  792. }
  793. if (IpsecStatus.dwCurrentState == SERVICE_STOPPED) {
  794. bStatus = StartService(
  795. ServiceHandle,
  796. 0,
  797. NULL
  798. );
  799. if (bStatus == FALSE) {
  800. dwError = GetLastError();
  801. BAIL_ON_WIN32_ERROR(dwError);
  802. }
  803. }
  804. else if (IpsecStatus.dwCurrentState == SERVICE_RUNNING) {
  805. bStatus = ControlService(
  806. ServiceHandle,
  807. 129,
  808. &IpsecStatus
  809. );
  810. if (bStatus == FALSE) {
  811. dwError = GetLastError();
  812. BAIL_ON_WIN32_ERROR(dwError);
  813. }
  814. }
  815. error:
  816. if (ServiceDatabase != NULL) {
  817. CloseServiceHandle(ServiceDatabase);
  818. }
  819. if (ServiceHandle != NULL) {
  820. CloseServiceHandle(ServiceHandle);
  821. }
  822. return (dwError);
  823. }
  824. DWORD
  825. IsRegPolicyCurrentlyActive(
  826. HKEY hRegistryKey,
  827. LPWSTR pszIpsecRootContainer,
  828. GUID PolicyIdentifier,
  829. PBOOL pbIsActive
  830. )
  831. {
  832. DWORD dwError = 0;
  833. PIPSEC_POLICY_DATA pIpsecPolicyData = NULL;
  834. *pbIsActive = FALSE;
  835. dwError = RegGetAssignedPolicyData(
  836. hRegistryKey,
  837. pszIpsecRootContainer,
  838. &pIpsecPolicyData
  839. );
  840. if (pIpsecPolicyData) {
  841. if (!memcmp(
  842. &PolicyIdentifier,
  843. &pIpsecPolicyData->PolicyIdentifier,
  844. sizeof(GUID))) {
  845. *pbIsActive = TRUE;
  846. }
  847. FreeIpsecPolicyData(pIpsecPolicyData);
  848. }
  849. dwError = ERROR_SUCCESS;
  850. return (dwError);
  851. }
  852. DWORD
  853. RegGetPolicyData(
  854. HKEY hRegistryKey,
  855. LPWSTR pszIpsecRootContainer,
  856. GUID PolicyGUID,
  857. PIPSEC_POLICY_DATA * ppIpsecPolicyData
  858. )
  859. {
  860. DWORD dwError = 0;
  861. PIPSEC_POLICY_OBJECT pIpsecPolicyObject = NULL;
  862. PIPSEC_POLICY_DATA pIpsecPolicyData = NULL;
  863. WCHAR szIpsecPolicyName[MAX_PATH];
  864. LPWSTR pszPolicyName = NULL;
  865. szIpsecPolicyName[0] = L'\0';
  866. wcscpy(szIpsecPolicyName, L"ipsecPolicy");
  867. dwError = UuidToString(&PolicyGUID, &pszPolicyName);
  868. BAIL_ON_WIN32_ERROR(dwError);
  869. wcscat(szIpsecPolicyName, L"{");
  870. wcscat(szIpsecPolicyName, pszPolicyName);
  871. wcscat(szIpsecPolicyName, L"}");
  872. dwError = UnMarshallRegistryPolicyObject(
  873. hRegistryKey,
  874. pszIpsecRootContainer,
  875. szIpsecPolicyName,
  876. REG_RELATIVE_NAME,
  877. &pIpsecPolicyObject
  878. );
  879. BAIL_ON_WIN32_ERROR(dwError);
  880. dwError = RegUnmarshallPolicyData(
  881. pIpsecPolicyObject,
  882. &pIpsecPolicyData
  883. );
  884. BAIL_ON_WIN32_ERROR(dwError);
  885. error:
  886. if (pIpsecPolicyObject) {
  887. FreeIpsecPolicyObject(
  888. pIpsecPolicyObject
  889. );
  890. }
  891. if (pszPolicyName) {
  892. RpcStringFree(&pszPolicyName);
  893. }
  894. *ppIpsecPolicyData = pIpsecPolicyData;
  895. return(dwError);
  896. }
  897. DWORD
  898. RegPingPASvcForActivePolicy(
  899. HKEY hRegistryKey,
  900. LPWSTR pszIpsecRootContainer,
  901. LPWSTR pszLocationName
  902. )
  903. {
  904. DWORD dwError = 0;
  905. PIPSEC_POLICY_DATA pIpsecPolicyData = NULL;
  906. WCHAR szIpsecPolicyName[MAX_PATH];
  907. LPWSTR pszPolicyName = NULL;
  908. WCHAR szAbsPolicyReference[MAX_PATH];
  909. dwError = RegGetAssignedPolicyData(
  910. hRegistryKey,
  911. pszIpsecRootContainer,
  912. &pIpsecPolicyData
  913. );
  914. BAIL_ON_WIN32_ERROR(dwError);
  915. if (!pIpsecPolicyData) {
  916. dwError = ERROR_SUCCESS;
  917. return (dwError);
  918. }
  919. szIpsecPolicyName[0] = L'\0';
  920. wcscpy(szIpsecPolicyName, L"ipsecPolicy");
  921. dwError = UuidToString(&pIpsecPolicyData->PolicyIdentifier, &pszPolicyName);
  922. BAIL_ON_WIN32_ERROR(dwError);
  923. wcscat(szIpsecPolicyName, L"{");
  924. wcscat(szIpsecPolicyName, pszPolicyName);
  925. wcscat(szIpsecPolicyName, L"}");
  926. szAbsPolicyReference[0] = L'\0';
  927. wcscpy(szAbsPolicyReference, pszIpsecRootContainer);
  928. wcscat(szAbsPolicyReference, L"\\");
  929. wcscat(szAbsPolicyReference, szIpsecPolicyName);
  930. dwError = RegUpdatePolicy(
  931. hRegistryKey,
  932. pszIpsecRootContainer,
  933. szAbsPolicyReference
  934. );
  935. BAIL_ON_WIN32_ERROR(dwError);
  936. dwError = PingPolicyAgentSvc(pszLocationName);
  937. BAIL_ON_WIN32_ERROR(dwError);
  938. error:
  939. if (pIpsecPolicyData) {
  940. FreeIpsecPolicyData(pIpsecPolicyData);
  941. }
  942. if (pszPolicyName) {
  943. RpcStringFree(&pszPolicyName);
  944. }
  945. return (dwError);
  946. }