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.

1414 lines
30 KiB

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. mm-policy.c
  5. Abstract:
  6. Author:
  7. Environment: User Mode
  8. Revision History:
  9. --*/
  10. #include "precomp.h"
  11. #ifdef TRACE_ON
  12. #include "mm-policy.tmh"
  13. #endif
  14. DWORD
  15. AddMMPolicyInternal(
  16. LPWSTR pServerName,
  17. DWORD dwVersion,
  18. DWORD dwFlags,
  19. DWORD dwSource,
  20. PIPSEC_MM_POLICY pMMPolicy,
  21. LPVOID pvReserved
  22. )
  23. /*++
  24. Routine Description:
  25. This function adds a main mode policy to the SPD.
  26. Arguments:
  27. pServerName - Server on which the main mode policy is to be added.
  28. pMMPolicy - Main mode policy to be added.
  29. Return Value:
  30. ERROR_SUCCESS - Success.
  31. Win32 Error - Failure.
  32. --*/
  33. {
  34. DWORD dwError = 0;
  35. PINIMMPOLICY pIniMMPolicy = NULL;
  36. //
  37. // Validate the main mode policy.
  38. //
  39. dwError = ValidateMMPolicy(
  40. pMMPolicy
  41. );
  42. BAIL_ON_WIN32_ERROR(dwError);
  43. ENTER_SPD_SECTION();
  44. dwError = ValidateSecurity(
  45. SPD_OBJECT_SERVER,
  46. SERVER_ACCESS_ADMINISTER,
  47. NULL,
  48. NULL
  49. );
  50. BAIL_ON_LOCK_ERROR(dwError);
  51. pIniMMPolicy = FindMMPolicy(
  52. gpIniMMPolicy,
  53. pMMPolicy->pszPolicyName
  54. );
  55. if (pIniMMPolicy) {
  56. dwError = ERROR_IPSEC_MM_POLICY_EXISTS;
  57. BAIL_ON_LOCK_ERROR(dwError);
  58. }
  59. pIniMMPolicy = FindMMPolicyByGuid(
  60. gpIniMMPolicy,
  61. pMMPolicy->gPolicyID
  62. );
  63. if (pIniMMPolicy) {
  64. dwError = ERROR_IPSEC_MM_POLICY_EXISTS;
  65. BAIL_ON_LOCK_ERROR(dwError);
  66. }
  67. dwError = CreateIniMMPolicy(
  68. pMMPolicy,
  69. &pIniMMPolicy
  70. );
  71. if (dwError != WARNING_IPSEC_MM_POLICY_PRUNED) {
  72. BAIL_ON_LOCK_ERROR(dwError);
  73. }
  74. pIniMMPolicy->dwSource = dwSource;
  75. pIniMMPolicy->pNext = gpIniMMPolicy;
  76. gpIniMMPolicy = pIniMMPolicy;
  77. if ((pIniMMPolicy->dwFlags) & IPSEC_MM_POLICY_DEFAULT_POLICY) {
  78. gpIniDefaultMMPolicy = pIniMMPolicy;
  79. TRACE(
  80. TRC_INFORMATION,
  81. (L"Set default MM policy to \"%ls\" (%!guid!)",
  82. pMMPolicy->pszPolicyName,
  83. &pMMPolicy->gPolicyID)
  84. );
  85. }
  86. LEAVE_SPD_SECTION();
  87. TRACE(
  88. TRC_INFORMATION,
  89. (L"Added MM policy \"%ls\"(%!guid!)",
  90. pMMPolicy->pszPolicyName,
  91. &pMMPolicy->gPolicyID)
  92. );
  93. return (dwError);
  94. lock:
  95. LEAVE_SPD_SECTION();
  96. error:
  97. #ifdef TRACE_ON
  98. if (pMMPolicy) {
  99. TRACE(
  100. TRC_ERROR,
  101. (L"Failed to add MM policy \"%ls\"(%!guid!): %!winerr!",
  102. pMMPolicy->pszPolicyName,
  103. &pMMPolicy->gPolicyID,
  104. dwError)
  105. );
  106. } else {
  107. TRACE(
  108. TRC_ERROR,
  109. (L"Failed to add MM policy. Policy details unavailable since pMMPolicy is null: %!winerr!",
  110. dwError)
  111. );
  112. }
  113. #endif
  114. return (dwError);
  115. }
  116. DWORD
  117. AddMMPolicy(
  118. LPWSTR pServerName,
  119. DWORD dwVersion,
  120. DWORD dwFlags,
  121. PIPSEC_MM_POLICY pMMPolicy,
  122. LPVOID pvReserved
  123. )
  124. {
  125. return AddMMPolicyInternal(
  126. pServerName,
  127. dwVersion,
  128. dwFlags,
  129. IPSEC_SOURCE_WINIPSEC,
  130. pMMPolicy,
  131. pvReserved);
  132. }
  133. DWORD
  134. ValidateMMPolicy(
  135. PIPSEC_MM_POLICY pMMPolicy
  136. )
  137. {
  138. DWORD dwError = 0;
  139. if (!pMMPolicy) {
  140. dwError = ERROR_INVALID_PARAMETER;
  141. BAIL_ON_WIN32_ERROR(dwError);
  142. }
  143. if (!(pMMPolicy->pszPolicyName) || !(*(pMMPolicy->pszPolicyName))) {
  144. dwError = ERROR_INVALID_PARAMETER;
  145. BAIL_ON_WIN32_ERROR(dwError);
  146. }
  147. dwError = ValidateMMOffers(
  148. pMMPolicy->dwOfferCount,
  149. pMMPolicy->pOffers
  150. );
  151. BAIL_ON_WIN32_ERROR(dwError);
  152. error:
  153. #ifdef TRACE_ON
  154. if (dwError) {
  155. TRACE(TRC_ERROR, ("Failed MM policy validation: %!winerr!", dwError));
  156. }
  157. #endif
  158. return (dwError);
  159. }
  160. DWORD
  161. ValidateMMOffers(
  162. DWORD dwOfferCount,
  163. PIPSEC_MM_OFFER pOffers
  164. )
  165. {
  166. DWORD dwError = 0;
  167. if (!dwOfferCount || !pOffers || dwOfferCount > IPSEC_MAX_MM_OFFERS) {
  168. dwError = ERROR_INVALID_PARAMETER;
  169. BAIL_ON_WIN32_ERROR(dwError);
  170. }
  171. error:
  172. #ifdef TRACE_ON
  173. if (dwError) {
  174. TRACE(TRC_ERROR, ("Failed MM offers validation: %!winerr!", dwError));
  175. }
  176. #endif
  177. return (dwError);
  178. }
  179. DWORD
  180. ValidateMMOffer(
  181. PIPSEC_MM_OFFER pOffer
  182. )
  183. {
  184. DWORD dwError = 0;
  185. if ((pOffer->dwDHGroup != DH_GROUP_1) &&
  186. (pOffer->dwDHGroup != DH_GROUP_2) &&
  187. (pOffer->dwDHGroup != DH_GROUP_2048)) {
  188. dwError = ERROR_INVALID_PARAMETER;
  189. BAIL_ON_WIN32_ERROR(dwError);
  190. }
  191. if (pOffer->EncryptionAlgorithm.uAlgoIdentifier >= CONF_ALGO_MAX ||
  192. pOffer->EncryptionAlgorithm.uAlgoIdentifier == CONF_ALGO_NONE) {
  193. dwError = ERROR_INVALID_PARAMETER;
  194. BAIL_ON_WIN32_ERROR(dwError);
  195. }
  196. if (pOffer->HashingAlgorithm.uAlgoIdentifier >= AUTH_ALGO_MAX ||
  197. pOffer->HashingAlgorithm.uAlgoIdentifier == AUTH_ALGO_NONE) {
  198. dwError = ERROR_INVALID_PARAMETER;
  199. BAIL_ON_WIN32_ERROR(dwError);
  200. }
  201. error:
  202. #ifdef TRACE_ON
  203. if (dwError) {
  204. TRACE(TRC_ERROR, ("Failed a MM offer validation: %!winerr!", dwError));
  205. }
  206. #endif
  207. return (dwError);
  208. }
  209. DWORD
  210. CreateIniMMPolicy(
  211. PIPSEC_MM_POLICY pMMPolicy,
  212. PINIMMPOLICY * ppIniMMPolicy
  213. )
  214. {
  215. DWORD dwError = 0;
  216. PINIMMPOLICY pIniMMPolicy = NULL;
  217. dwError = AllocateSPDMemory(
  218. sizeof(INIMMPOLICY),
  219. &pIniMMPolicy
  220. );
  221. BAIL_ON_WIN32_ERROR(dwError);
  222. memcpy(
  223. &(pIniMMPolicy->gPolicyID),
  224. &(pMMPolicy->gPolicyID),
  225. sizeof(GUID)
  226. );
  227. dwError = AllocateSPDString(
  228. pMMPolicy->pszPolicyName,
  229. &(pIniMMPolicy->pszPolicyName)
  230. );
  231. BAIL_ON_WIN32_ERROR(dwError);
  232. pIniMMPolicy->cRef = 0;
  233. pIniMMPolicy->dwSource = 0;
  234. pIniMMPolicy->dwFlags = pMMPolicy->dwFlags;
  235. pIniMMPolicy->uSoftExpirationTime = pMMPolicy->uSoftExpirationTime;
  236. pIniMMPolicy->pNext = NULL;
  237. dwError = CreateIniMMOffers(
  238. pMMPolicy->dwOfferCount,
  239. pMMPolicy->pOffers,
  240. &(pIniMMPolicy->dwOfferCount),
  241. &(pIniMMPolicy->pOffers)
  242. );
  243. if (dwError != WARNING_IPSEC_MM_POLICY_PRUNED) {
  244. BAIL_ON_WIN32_ERROR(dwError);
  245. }
  246. *ppIniMMPolicy = pIniMMPolicy;
  247. return (dwError);
  248. error:
  249. TRACE(TRC_ERROR, ("Failed to create MM Policy link node: %!winerr!", dwError));
  250. if (pIniMMPolicy) {
  251. FreeIniMMPolicy(
  252. pIniMMPolicy
  253. );
  254. }
  255. *ppIniMMPolicy = NULL;
  256. return (dwError);
  257. }
  258. DWORD
  259. CreateIniMMOffers(
  260. DWORD dwInOfferCount,
  261. PIPSEC_MM_OFFER pInOffers,
  262. PDWORD pdwOfferCount,
  263. PIPSEC_MM_OFFER * ppOffers
  264. )
  265. {
  266. DWORD dwError = 0;
  267. PIPSEC_MM_OFFER pOffers = NULL;
  268. PIPSEC_MM_OFFER pTemp = NULL;
  269. PIPSEC_MM_OFFER pInTempOffer = NULL;
  270. DWORD i = 0;
  271. DWORD dwOfferCount = 0;
  272. DWORD dwCurIndex = 0;
  273. for (i = 0; i < dwInOfferCount; i++) {
  274. dwError = ValidateMMOffer(&pInOffers[i]);
  275. if (dwError == ERROR_SUCCESS) {
  276. dwOfferCount++;
  277. }
  278. }
  279. if (dwOfferCount == 0) {
  280. dwError = ERROR_INVALID_PARAMETER;
  281. BAIL_ON_WIN32_ERROR(dwError);
  282. }
  283. dwError = AllocateSPDMemory(
  284. sizeof(IPSEC_MM_OFFER) * dwOfferCount,
  285. &(pOffers)
  286. );
  287. BAIL_ON_WIN32_ERROR(dwError);
  288. for (i = 0; i < dwInOfferCount; i++) {
  289. pTemp = &pOffers[dwCurIndex];
  290. pInTempOffer = &pInOffers[i];
  291. dwError = ValidateMMOffer(pInTempOffer);
  292. if (dwError) {
  293. continue;
  294. }
  295. memcpy(
  296. &(pTemp->Lifetime),
  297. &(pInTempOffer->Lifetime),
  298. sizeof(KEY_LIFETIME)
  299. );
  300. if (!(pTemp->Lifetime.uKeyExpirationTime)) {
  301. pTemp->Lifetime.uKeyExpirationTime = DEFAULT_MM_KEY_EXPIRATION_TIME;
  302. }
  303. pTemp->dwFlags = pInTempOffer->dwFlags;
  304. pTemp->dwQuickModeLimit = pInTempOffer->dwQuickModeLimit;
  305. pTemp->dwDHGroup = pInTempOffer->dwDHGroup;
  306. memcpy(
  307. &(pTemp->EncryptionAlgorithm),
  308. &(pInTempOffer->EncryptionAlgorithm),
  309. sizeof(IPSEC_MM_ALGO)
  310. );
  311. memcpy(
  312. &(pTemp->HashingAlgorithm),
  313. &(pInTempOffer->HashingAlgorithm),
  314. sizeof(IPSEC_MM_ALGO)
  315. );
  316. dwCurIndex++;
  317. }
  318. *pdwOfferCount = dwOfferCount;
  319. *ppOffers = pOffers;
  320. if (dwOfferCount != dwInOfferCount) {
  321. TRACE(TRC_WARNING, ("Pruned MM offers node."));
  322. return WARNING_IPSEC_MM_POLICY_PRUNED;
  323. }
  324. return (ERROR_SUCCESS);
  325. error:
  326. TRACE(TRC_ERROR, ("Failed to create MM offers node: %!winerr!", dwError));
  327. if (pOffers) {
  328. FreeIniMMOffers(
  329. i,
  330. pOffers
  331. );
  332. }
  333. *pdwOfferCount = 0;
  334. *ppOffers = NULL;
  335. return (dwError);
  336. }
  337. VOID
  338. FreeIniMMPolicy(
  339. PINIMMPOLICY pIniMMPolicy
  340. )
  341. {
  342. if (pIniMMPolicy) {
  343. if (pIniMMPolicy->pszPolicyName) {
  344. FreeSPDString(pIniMMPolicy->pszPolicyName);
  345. }
  346. FreeIniMMOffers(
  347. pIniMMPolicy->dwOfferCount,
  348. pIniMMPolicy->pOffers
  349. );
  350. FreeSPDMemory(pIniMMPolicy);
  351. }
  352. }
  353. VOID
  354. FreeIniMMOffers(
  355. DWORD dwOfferCount,
  356. PIPSEC_MM_OFFER pOffers
  357. )
  358. {
  359. if (pOffers) {
  360. FreeSPDMemory(pOffers);
  361. }
  362. }
  363. PINIMMPOLICY
  364. FindMMPolicy(
  365. PINIMMPOLICY pIniMMPolicyList,
  366. LPWSTR pszPolicyName
  367. )
  368. {
  369. DWORD dwError = 0;
  370. PINIMMPOLICY pTemp = NULL;
  371. pTemp = pIniMMPolicyList;
  372. while (pTemp) {
  373. if (!_wcsicmp(pTemp->pszPolicyName, pszPolicyName)) {
  374. return (pTemp);
  375. }
  376. pTemp = pTemp->pNext;
  377. }
  378. return (NULL);
  379. }
  380. DWORD
  381. DeleteMMPolicy(
  382. LPWSTR pServerName,
  383. DWORD dwVersion,
  384. LPWSTR pszPolicyName,
  385. LPVOID pvReserved
  386. )
  387. /*++
  388. Routine Description:
  389. This function deletes a main mode policy from the SPD.
  390. Arguments:
  391. pServerName - Server on which the main mode policy is to be deleted.
  392. pszPolicyName - Main mode policy to be deleted.
  393. Return Value:
  394. ERROR_SUCCESS - Success.
  395. Win32 Error - Failure.
  396. --*/
  397. {
  398. DWORD dwError = 0;
  399. PINIMMPOLICY pIniMMPolicy = NULL;
  400. GUID gPolicyID;
  401. if (!pszPolicyName || !*pszPolicyName) {
  402. return (ERROR_INVALID_PARAMETER);
  403. }
  404. ENTER_SPD_SECTION();
  405. dwError = ValidateSecurity(
  406. SPD_OBJECT_SERVER,
  407. SERVER_ACCESS_ADMINISTER,
  408. NULL,
  409. NULL
  410. );
  411. BAIL_ON_LOCK_ERROR(dwError);
  412. pIniMMPolicy = FindMMPolicy(
  413. gpIniMMPolicy,
  414. pszPolicyName
  415. );
  416. if (!pIniMMPolicy) {
  417. dwError = ERROR_IPSEC_MM_POLICY_NOT_FOUND;
  418. BAIL_ON_LOCK_ERROR(dwError);
  419. }
  420. if (pIniMMPolicy->cRef) {
  421. dwError = ERROR_IPSEC_MM_POLICY_IN_USE;
  422. memcpy(&gPolicyID, &pIniMMPolicy->gPolicyID, sizeof(GUID));
  423. BAIL_ON_LOCK_ERROR(dwError);
  424. }
  425. memcpy(&gPolicyID, &pIniMMPolicy->gPolicyID, sizeof(GUID));
  426. dwError = DeleteIniMMPolicy(
  427. pIniMMPolicy
  428. );
  429. BAIL_ON_LOCK_ERROR(dwError);
  430. LEAVE_SPD_SECTION();
  431. if (gbIKENotify) {
  432. (VOID) IKENotifyPolicyChange(
  433. &(gPolicyID),
  434. POLICY_GUID_MM
  435. );
  436. }
  437. TRACE(
  438. TRC_INFORMATION,
  439. ("Deleted MM Policy \"%ls\"(%!guid!)",
  440. pszPolicyName,
  441. &gPolicyID)
  442. );
  443. return (dwError);
  444. lock:
  445. LEAVE_SPD_SECTION();
  446. #ifdef TRACE_ON
  447. if (pIniMMPolicy) {
  448. TRACE(
  449. TRC_ERROR,
  450. (L"Failed to delete MM policy \"%ls\"(%!guid!): %!winerr!",
  451. pIniMMPolicy->pszPolicyName,
  452. &pIniMMPolicy->gPolicyID,
  453. dwError)
  454. );
  455. } else {
  456. TRACE(
  457. TRC_ERROR,
  458. (L"Failed to delete MM policy \"%ls\": %!winerr!",
  459. pszPolicyName,
  460. dwError)
  461. );
  462. }
  463. #endif
  464. return (dwError);
  465. }
  466. DWORD
  467. EnumMMPolicies(
  468. LPWSTR pServerName,
  469. DWORD dwVersion,
  470. PIPSEC_MM_POLICY pMMTemplatePolicy,
  471. DWORD dwFlags,
  472. DWORD dwPreferredNumEntries,
  473. PIPSEC_MM_POLICY * ppMMPolicies,
  474. LPDWORD pdwNumPolicies,
  475. LPDWORD pdwResumeHandle,
  476. LPVOID pvReserved
  477. )
  478. /*++
  479. Routine Description:
  480. This function enumerates main mode policies from the SPD.
  481. Arguments:
  482. pServerName - Server on which the main mode policies are to
  483. be enumerated.
  484. ppMMPolicies - Enumerated main mode policies returned to the
  485. caller.
  486. dwPreferredNumEntries - Preferred number of enumeration entries.
  487. pdwNumPolicies - Number of main mode policies actually enumerated.
  488. pdwResumeHandle - Handle to the location in the main mode policy
  489. list from which to resume enumeration.
  490. Return Value:
  491. ERROR_SUCCESS - Success.
  492. Win32 Error - Failure.
  493. --*/
  494. {
  495. DWORD dwError = 0;
  496. DWORD dwResumeHandle = 0;
  497. DWORD dwNumToEnum = 0;
  498. PINIMMPOLICY pIniMMPolicy = NULL;
  499. DWORD i = 0;
  500. PINIMMPOLICY pTemp = NULL;
  501. DWORD dwNumPolicies = 0;
  502. PIPSEC_MM_POLICY pMMPolicies = NULL;
  503. PIPSEC_MM_POLICY pMMPolicy = NULL;
  504. dwResumeHandle = *pdwResumeHandle;
  505. if (!dwPreferredNumEntries || (dwPreferredNumEntries > MAX_MMPOLICY_ENUM_COUNT)) {
  506. dwNumToEnum = MAX_MMPOLICY_ENUM_COUNT;
  507. }
  508. else {
  509. dwNumToEnum = dwPreferredNumEntries;
  510. }
  511. ENTER_SPD_SECTION();
  512. dwError = ValidateSecurity(
  513. SPD_OBJECT_SERVER,
  514. SERVER_ACCESS_ADMINISTER,
  515. NULL,
  516. NULL
  517. );
  518. BAIL_ON_LOCK_ERROR(dwError);
  519. pIniMMPolicy = gpIniMMPolicy;
  520. for (i = 0; (i < dwResumeHandle) && (pIniMMPolicy != NULL); i++) {
  521. pIniMMPolicy = pIniMMPolicy->pNext;
  522. }
  523. if (!pIniMMPolicy) {
  524. dwError = ERROR_NO_DATA;
  525. BAIL_ON_LOCK_ERROR(dwError);
  526. }
  527. pTemp = pIniMMPolicy;
  528. while (pTemp && (dwNumPolicies < dwNumToEnum)) {
  529. dwNumPolicies++;
  530. pTemp = pTemp->pNext;
  531. }
  532. dwError = SPDApiBufferAllocate(
  533. sizeof(IPSEC_MM_POLICY)*dwNumPolicies,
  534. &pMMPolicies
  535. );
  536. BAIL_ON_LOCK_ERROR(dwError);
  537. pTemp = pIniMMPolicy;
  538. pMMPolicy = pMMPolicies;
  539. for (i = 0; i < dwNumPolicies; i++) {
  540. dwError = CopyMMPolicy(
  541. pTemp,
  542. pMMPolicy
  543. );
  544. BAIL_ON_LOCK_ERROR(dwError);
  545. pTemp = pTemp->pNext;
  546. pMMPolicy++;
  547. }
  548. *ppMMPolicies = pMMPolicies;
  549. *pdwResumeHandle = dwResumeHandle + dwNumPolicies;
  550. *pdwNumPolicies = dwNumPolicies;
  551. LEAVE_SPD_SECTION();
  552. TRACE(TRC_INFORMATION, (L"Enumerated policies."));
  553. return (dwError);
  554. lock:
  555. LEAVE_SPD_SECTION();
  556. if (pMMPolicies) {
  557. FreeMMPolicies(
  558. i,
  559. pMMPolicies
  560. );
  561. }
  562. *ppMMPolicies = NULL;
  563. *pdwResumeHandle = dwResumeHandle;
  564. *pdwNumPolicies = 0;
  565. TRACE(TRC_ERROR, ("Failed to enumerate policies: %!winerr!", dwError));
  566. return (dwError);
  567. }
  568. DWORD
  569. SetMMPolicy(
  570. LPWSTR pServerName,
  571. DWORD dwVersion,
  572. LPWSTR pszPolicyName,
  573. PIPSEC_MM_POLICY pMMPolicy,
  574. LPVOID pvReserved
  575. )
  576. /*++
  577. Routine Description:
  578. This function updates a main mode policy in the SPD.
  579. Arguments:
  580. pServerName - Server on which the main mode policy is to be
  581. updated.
  582. pszPolicyName - Name of the main mode policy to be updated.
  583. pMMPolicy - New main mode policy which will replace the
  584. existing policy.
  585. Return Value:
  586. ERROR_SUCCESS - Success.
  587. Win32 Error - Failure.
  588. --*/
  589. {
  590. DWORD dwError = 0;
  591. PINIMMPOLICY pIniMMPolicy = NULL;
  592. DWORD dwStatus = 0;
  593. if (!pszPolicyName || !*pszPolicyName) {
  594. return (ERROR_INVALID_PARAMETER);
  595. }
  596. //
  597. // Validate main mode policy.
  598. //
  599. dwError = ValidateMMPolicy(
  600. pMMPolicy
  601. );
  602. BAIL_ON_WIN32_ERROR(dwError);
  603. ENTER_SPD_SECTION();
  604. dwError = ValidateSecurity(
  605. SPD_OBJECT_SERVER,
  606. SERVER_ACCESS_ADMINISTER,
  607. NULL,
  608. NULL
  609. );
  610. BAIL_ON_LOCK_ERROR(dwError);
  611. pIniMMPolicy = FindMMPolicy(
  612. gpIniMMPolicy,
  613. pszPolicyName
  614. );
  615. if (!pIniMMPolicy) {
  616. dwError = ERROR_IPSEC_MM_POLICY_NOT_FOUND;
  617. BAIL_ON_LOCK_ERROR(dwError);
  618. }
  619. if (memcmp(
  620. &(pIniMMPolicy->gPolicyID),
  621. &(pMMPolicy->gPolicyID),
  622. sizeof(GUID))) {
  623. dwError = ERROR_INVALID_PARAMETER;
  624. BAIL_ON_LOCK_ERROR(dwError);
  625. }
  626. dwError = SetIniMMPolicy(
  627. pIniMMPolicy,
  628. pMMPolicy
  629. );
  630. if (dwError != WARNING_IPSEC_MM_POLICY_PRUNED) {
  631. BAIL_ON_LOCK_ERROR(dwError);
  632. } else {
  633. dwStatus = dwError;
  634. }
  635. LEAVE_SPD_SECTION();
  636. (VOID) IKENotifyPolicyChange(
  637. &(pMMPolicy->gPolicyID),
  638. POLICY_GUID_MM
  639. );
  640. TRACE(
  641. TRC_INFORMATION,
  642. (L"Changed MM Policy \"%ls\" (%!guid!)",
  643. pMMPolicy->pszPolicyName,
  644. &pMMPolicy->gPolicyID)
  645. );
  646. return (dwStatus);
  647. lock:
  648. LEAVE_SPD_SECTION();
  649. error:
  650. #ifdef TRACE_ON
  651. if (pIniMMPolicy) {
  652. TRACE(
  653. TRC_ERROR,
  654. (L"Failed to change MM policy \"%ls\"(%!guid!): %!winerr!",
  655. pIniMMPolicy->pszPolicyName,
  656. &pIniMMPolicy->gPolicyID,
  657. dwError)
  658. );
  659. } else {
  660. TRACE(
  661. TRC_ERROR,
  662. (L"Failed to change MM policy \"%ls\": %!winerr!",
  663. pszPolicyName,
  664. dwError)
  665. );
  666. }
  667. #endif
  668. return (dwError);
  669. }
  670. DWORD
  671. GetMMPolicy(
  672. LPWSTR pServerName,
  673. DWORD dwVersion,
  674. LPWSTR pszPolicyName,
  675. PIPSEC_MM_POLICY * ppMMPolicy,
  676. LPVOID pvReserved
  677. )
  678. /*++
  679. Routine Description:
  680. This function gets a main mode policy from the SPD.
  681. Arguments:
  682. pServerName - Server from which to get the main mode policy.
  683. pszPolicyName - Name of the main mode policy to get.
  684. ppMMPolicy - Main mode policy found returned to the caller.
  685. Return Value:
  686. ERROR_SUCCESS - Success.
  687. Win32 Error - Failure.
  688. --*/
  689. {
  690. DWORD dwError = 0;
  691. PINIMMPOLICY pIniMMPolicy = NULL;
  692. PIPSEC_MM_POLICY pMMPolicy = NULL;
  693. if (!pszPolicyName || !*pszPolicyName) {
  694. dwError = ERROR_INVALID_PARAMETER;
  695. BAIL_ON_WIN32_ERROR(dwError);
  696. }
  697. ENTER_SPD_SECTION();
  698. dwError = ValidateSecurity(
  699. SPD_OBJECT_SERVER,
  700. SERVER_ACCESS_ADMINISTER,
  701. NULL,
  702. NULL
  703. );
  704. BAIL_ON_LOCK_ERROR(dwError);
  705. pIniMMPolicy = FindMMPolicy(
  706. gpIniMMPolicy,
  707. pszPolicyName
  708. );
  709. if (!pIniMMPolicy) {
  710. dwError = ERROR_IPSEC_MM_POLICY_NOT_FOUND;
  711. BAIL_ON_LOCK_ERROR(dwError);
  712. }
  713. dwError = GetIniMMPolicy(
  714. pIniMMPolicy,
  715. &pMMPolicy
  716. );
  717. BAIL_ON_LOCK_ERROR(dwError);
  718. *ppMMPolicy = pMMPolicy;
  719. LEAVE_SPD_SECTION();
  720. return (dwError);
  721. lock:
  722. LEAVE_SPD_SECTION();
  723. error:
  724. *ppMMPolicy = NULL;
  725. return (dwError);
  726. }
  727. DWORD
  728. SetIniMMPolicy(
  729. PINIMMPOLICY pIniMMPolicy,
  730. PIPSEC_MM_POLICY pMMPolicy
  731. )
  732. {
  733. DWORD dwError = 0;
  734. DWORD dwOfferCount = 0;
  735. PIPSEC_MM_OFFER pOffers = NULL;
  736. dwError = CreateIniMMOffers(
  737. pMMPolicy->dwOfferCount,
  738. pMMPolicy->pOffers,
  739. &dwOfferCount,
  740. &pOffers
  741. );
  742. if (dwError != WARNING_IPSEC_MM_POLICY_PRUNED) {
  743. BAIL_ON_WIN32_ERROR(dwError);
  744. }
  745. FreeIniMMOffers(
  746. pIniMMPolicy->dwOfferCount,
  747. pIniMMPolicy->pOffers
  748. );
  749. if ((pIniMMPolicy->dwFlags) & IPSEC_MM_POLICY_DEFAULT_POLICY) {
  750. gpIniDefaultMMPolicy = NULL;
  751. TRACE(
  752. TRC_INFORMATION,
  753. (L"Cleared default MM policy \"%ls\" (%!guid!)",
  754. pIniMMPolicy->pszPolicyName,
  755. &pIniMMPolicy->gPolicyID)
  756. );
  757. }
  758. pIniMMPolicy->dwFlags = pMMPolicy->dwFlags;
  759. pIniMMPolicy->uSoftExpirationTime = pMMPolicy->uSoftExpirationTime;
  760. pIniMMPolicy->dwOfferCount = dwOfferCount;
  761. pIniMMPolicy->pOffers = pOffers;
  762. if ((pIniMMPolicy->dwFlags) & IPSEC_MM_POLICY_DEFAULT_POLICY) {
  763. gpIniDefaultMMPolicy = pIniMMPolicy;
  764. TRACE(
  765. TRC_INFORMATION,
  766. (L"Set default MM policy to \"%ls\" (%!guid!)",
  767. pIniMMPolicy->pszPolicyName,
  768. &pIniMMPolicy->gPolicyID)
  769. );
  770. }
  771. error:
  772. return (dwError);
  773. }
  774. DWORD
  775. GetIniMMPolicy(
  776. PINIMMPOLICY pIniMMPolicy,
  777. PIPSEC_MM_POLICY * ppMMPolicy
  778. )
  779. {
  780. DWORD dwError = 0;
  781. PIPSEC_MM_POLICY pMMPolicy = NULL;
  782. dwError = SPDApiBufferAllocate(
  783. sizeof(IPSEC_MM_POLICY),
  784. &pMMPolicy
  785. );
  786. BAIL_ON_WIN32_ERROR(dwError);
  787. dwError = CopyMMPolicy(
  788. pIniMMPolicy,
  789. pMMPolicy
  790. );
  791. BAIL_ON_WIN32_ERROR(dwError);
  792. *ppMMPolicy = pMMPolicy;
  793. return (dwError);
  794. error:
  795. if (pMMPolicy) {
  796. SPDApiBufferFree(pMMPolicy);
  797. }
  798. *ppMMPolicy = NULL;
  799. return (dwError);
  800. }
  801. DWORD
  802. CopyMMPolicy(
  803. PINIMMPOLICY pIniMMPolicy,
  804. PIPSEC_MM_POLICY pMMPolicy
  805. )
  806. {
  807. DWORD dwError = 0;
  808. memcpy(
  809. &(pMMPolicy->gPolicyID),
  810. &(pIniMMPolicy->gPolicyID),
  811. sizeof(GUID)
  812. );
  813. dwError = SPDApiBufferAllocate(
  814. wcslen(pIniMMPolicy->pszPolicyName)*sizeof(WCHAR)
  815. + sizeof(WCHAR),
  816. &(pMMPolicy->pszPolicyName)
  817. );
  818. BAIL_ON_WIN32_ERROR(dwError);
  819. wcscpy(pMMPolicy->pszPolicyName, pIniMMPolicy->pszPolicyName);
  820. pMMPolicy->dwFlags = pIniMMPolicy->dwFlags;
  821. pMMPolicy->uSoftExpirationTime = pIniMMPolicy->uSoftExpirationTime;
  822. dwError = CreateMMOffers(
  823. pIniMMPolicy->dwOfferCount,
  824. pIniMMPolicy->pOffers,
  825. &(pMMPolicy->dwOfferCount),
  826. &(pMMPolicy->pOffers)
  827. );
  828. BAIL_ON_WIN32_ERROR(dwError);
  829. return (dwError);
  830. error:
  831. if (pMMPolicy->pszPolicyName) {
  832. SPDApiBufferFree(pMMPolicy->pszPolicyName);
  833. }
  834. return (dwError);
  835. }
  836. DWORD
  837. CreateMMOffers(
  838. DWORD dwInOfferCount,
  839. PIPSEC_MM_OFFER pInOffers,
  840. PDWORD pdwOfferCount,
  841. PIPSEC_MM_OFFER * ppOffers
  842. )
  843. {
  844. DWORD dwError = 0;
  845. PIPSEC_MM_OFFER pOffers = NULL;
  846. PIPSEC_MM_OFFER pTemp = NULL;
  847. PIPSEC_MM_OFFER pInTempOffer = NULL;
  848. DWORD i = 0;
  849. //
  850. // Offer count and the offers themselves have already been validated.
  851. //
  852. dwError = SPDApiBufferAllocate(
  853. sizeof(IPSEC_MM_OFFER) * dwInOfferCount,
  854. &(pOffers)
  855. );
  856. BAIL_ON_WIN32_ERROR(dwError);
  857. pTemp = pOffers;
  858. pInTempOffer = pInOffers;
  859. for (i = 0; i < dwInOfferCount; i++) {
  860. memcpy(
  861. &(pTemp->Lifetime),
  862. &(pInTempOffer->Lifetime),
  863. sizeof(KEY_LIFETIME)
  864. );
  865. pTemp->dwFlags = pInTempOffer->dwFlags;
  866. pTemp->dwQuickModeLimit = pInTempOffer->dwQuickModeLimit;
  867. pTemp->dwDHGroup = pInTempOffer->dwDHGroup;
  868. memcpy(
  869. &(pTemp->EncryptionAlgorithm),
  870. &(pInTempOffer->EncryptionAlgorithm),
  871. sizeof(IPSEC_MM_ALGO)
  872. );
  873. memcpy(
  874. &(pTemp->HashingAlgorithm),
  875. &(pInTempOffer->HashingAlgorithm),
  876. sizeof(IPSEC_MM_ALGO)
  877. );
  878. pInTempOffer++;
  879. pTemp++;
  880. }
  881. *pdwOfferCount = dwInOfferCount;
  882. *ppOffers = pOffers;
  883. return (dwError);
  884. error:
  885. TRACE(TRC_ERROR, ("Failed to create MM offers"));
  886. if (pOffers) {
  887. FreeMMOffers(
  888. i,
  889. pOffers
  890. );
  891. }
  892. *pdwOfferCount = 0;
  893. *ppOffers = NULL;
  894. return (dwError);
  895. }
  896. DWORD
  897. DeleteIniMMPolicy(
  898. PINIMMPOLICY pIniMMPolicy
  899. )
  900. {
  901. DWORD dwError = 0;
  902. PINIMMPOLICY * ppTemp = NULL;
  903. ppTemp = &gpIniMMPolicy;
  904. while (*ppTemp) {
  905. if (*ppTemp == pIniMMPolicy) {
  906. break;
  907. }
  908. ppTemp = &((*ppTemp)->pNext);
  909. }
  910. if (*ppTemp) {
  911. *ppTemp = pIniMMPolicy->pNext;
  912. }
  913. if ((pIniMMPolicy->dwFlags) & IPSEC_MM_POLICY_DEFAULT_POLICY) {
  914. gpIniDefaultMMPolicy = NULL;
  915. TRACE(
  916. TRC_INFORMATION,
  917. (L"Cleared default MM policy \"%ls\" (%!guid!)",
  918. pIniMMPolicy->pszPolicyName,
  919. &pIniMMPolicy->gPolicyID)
  920. );
  921. }
  922. FreeIniMMPolicy(pIniMMPolicy);
  923. return (dwError);
  924. }
  925. VOID
  926. FreeMMOffers(
  927. DWORD dwOfferCount,
  928. PIPSEC_MM_OFFER pOffers
  929. )
  930. {
  931. if (pOffers) {
  932. SPDApiBufferFree(pOffers);
  933. }
  934. }
  935. VOID
  936. FreeIniMMPolicyList(
  937. PINIMMPOLICY pIniMMPolicyList
  938. )
  939. {
  940. PINIMMPOLICY pTemp = NULL;
  941. PINIMMPOLICY pIniMMPolicy = NULL;
  942. pTemp = pIniMMPolicyList;
  943. while (pTemp) {
  944. pIniMMPolicy = pTemp;
  945. pTemp = pTemp->pNext;
  946. FreeIniMMPolicy(pIniMMPolicy);
  947. }
  948. }
  949. PINIMMPOLICY
  950. FindMMPolicyByGuid(
  951. PINIMMPOLICY pIniMMPolicyList,
  952. GUID gPolicyID
  953. )
  954. {
  955. DWORD dwError = 0;
  956. PINIMMPOLICY pTemp = NULL;
  957. pTemp = pIniMMPolicyList;
  958. while (pTemp) {
  959. if (!memcmp(&(pTemp->gPolicyID), &gPolicyID, sizeof(GUID))) {
  960. return (pTemp);
  961. }
  962. pTemp = pTemp->pNext;
  963. }
  964. return (NULL);
  965. }
  966. VOID
  967. FreeMMPolicies(
  968. DWORD dwNumMMPolicies,
  969. PIPSEC_MM_POLICY pMMPolicies
  970. )
  971. {
  972. DWORD i = 0;
  973. if (pMMPolicies) {
  974. for (i = 0; i < dwNumMMPolicies; i++) {
  975. if (pMMPolicies[i].pszPolicyName) {
  976. SPDApiBufferFree(pMMPolicies[i].pszPolicyName);
  977. }
  978. FreeMMOffers(
  979. pMMPolicies[i].dwOfferCount,
  980. pMMPolicies[i].pOffers
  981. );
  982. }
  983. SPDApiBufferFree(pMMPolicies);
  984. }
  985. }
  986. DWORD
  987. GetMMPolicyByID(
  988. LPWSTR pServerName,
  989. DWORD dwVersion,
  990. GUID gMMPolicyID,
  991. PIPSEC_MM_POLICY * ppMMPolicy,
  992. LPVOID pvReserved
  993. )
  994. /*++
  995. Routine Description:
  996. This function gets a main mode policy from the SPD.
  997. Arguments:
  998. pServerName - Server from which to get the main mode policy.
  999. gMMPolicyID - Guid of the main mode policy to get.
  1000. ppMMPolicy - Main mode policy found returned to the caller.
  1001. Return Value:
  1002. ERROR_SUCCESS - Success.
  1003. Win32 Error - Failure.
  1004. --*/
  1005. {
  1006. DWORD dwError = 0;
  1007. PINIMMPOLICY pIniMMPolicy = NULL;
  1008. PIPSEC_MM_POLICY pMMPolicy = NULL;
  1009. ENTER_SPD_SECTION();
  1010. dwError = ValidateSecurity(
  1011. SPD_OBJECT_SERVER,
  1012. SERVER_ACCESS_ADMINISTER,
  1013. NULL,
  1014. NULL
  1015. );
  1016. BAIL_ON_LOCK_ERROR(dwError);
  1017. pIniMMPolicy = FindMMPolicyByGuid(
  1018. gpIniMMPolicy,
  1019. gMMPolicyID
  1020. );
  1021. if (!pIniMMPolicy) {
  1022. dwError = ERROR_IPSEC_MM_POLICY_NOT_FOUND;
  1023. BAIL_ON_LOCK_ERROR(dwError);
  1024. }
  1025. dwError = GetIniMMPolicy(
  1026. pIniMMPolicy,
  1027. &pMMPolicy
  1028. );
  1029. BAIL_ON_LOCK_ERROR(dwError);
  1030. *ppMMPolicy = pMMPolicy;
  1031. LEAVE_SPD_SECTION();
  1032. return (dwError);
  1033. lock:
  1034. LEAVE_SPD_SECTION();
  1035. *ppMMPolicy = NULL;
  1036. return (dwError);
  1037. }
  1038. DWORD
  1039. LocateMMPolicy(
  1040. PMM_FILTER pMMFilter,
  1041. PINIMMPOLICY * ppIniMMPolicy
  1042. )
  1043. {
  1044. DWORD dwError = 0;
  1045. PINIMMPOLICY pIniMMPolicy = NULL;
  1046. if ((pMMFilter->dwFlags) & IPSEC_MM_POLICY_DEFAULT_POLICY) {
  1047. if (!gpIniDefaultMMPolicy) {
  1048. dwError = ERROR_IPSEC_DEFAULT_MM_POLICY_NOT_FOUND;
  1049. BAIL_ON_WIN32_ERROR(dwError);
  1050. }
  1051. pIniMMPolicy = gpIniDefaultMMPolicy;
  1052. }
  1053. else {
  1054. pIniMMPolicy = FindMMPolicyByGuid(
  1055. gpIniMMPolicy,
  1056. pMMFilter->gPolicyID
  1057. );
  1058. if (!pIniMMPolicy) {
  1059. dwError = ERROR_IPSEC_MM_POLICY_NOT_FOUND;
  1060. BAIL_ON_WIN32_ERROR(dwError);
  1061. }
  1062. }
  1063. *ppIniMMPolicy = pIniMMPolicy;
  1064. return (dwError);
  1065. error:
  1066. *ppIniMMPolicy = NULL;
  1067. return (dwError);
  1068. }