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.

893 lines
20 KiB

  1. #include "precomp.h"
  2. #ifdef TRACE_ON
  3. #include "paqm-pol.tmh"
  4. #endif
  5. DWORD
  6. PAAddQMPolicies(
  7. PIPSEC_NFA_DATA * ppIpsecNFAData,
  8. DWORD dwNumNFACount,
  9. DWORD dwSource
  10. )
  11. {
  12. DWORD dwError = 0;
  13. DWORD i = 0;
  14. PIPSEC_NFA_DATA pIpsecNFAData = NULL;
  15. PIPSEC_NEGPOL_DATA pIpsecNegPolData = NULL;
  16. PQMPOLICYSTATE pQMPolicyState = NULL;
  17. PIPSEC_QM_POLICY pSPDQMPolicy = NULL;
  18. LPWSTR pServerName = NULL;
  19. DWORD dwVersion = 0;
  20. for (i = 0; i < dwNumNFACount; i++) {
  21. pIpsecNFAData = *(ppIpsecNFAData + i);
  22. pIpsecNegPolData = pIpsecNFAData->pIpsecNegPolData;
  23. TRACE(
  24. TRC_INFORMATION,
  25. (L"Pastore adding QM policy based on Neg pol data %!guid!",
  26. &pIpsecNegPolData->NegPolIdentifier)
  27. );
  28. pQMPolicyState = FindQMPolicyState(
  29. pIpsecNegPolData->NegPolIdentifier
  30. );
  31. if (pQMPolicyState) {
  32. pQMPolicyState->cRef++;
  33. continue;
  34. }
  35. dwError = PACreateQMPolicyState(
  36. *(ppIpsecNFAData + i),
  37. &pQMPolicyState
  38. );
  39. if (dwError) {
  40. continue;
  41. }
  42. if (IsClearOnly(pQMPolicyState->gNegPolAction) ||
  43. IsBlocking(pQMPolicyState->gNegPolAction)) {
  44. pQMPolicyState->bInSPD = FALSE;
  45. pQMPolicyState->dwErrorCode = 0;
  46. pQMPolicyState->pNext = gpQMPolicyState;
  47. gpQMPolicyState = pQMPolicyState;
  48. continue;
  49. }
  50. dwError = PACreateQMPolicy(
  51. *(ppIpsecNFAData + i),
  52. pQMPolicyState,
  53. &pSPDQMPolicy
  54. );
  55. if (dwError) {
  56. pQMPolicyState->bInSPD = FALSE;
  57. pQMPolicyState->dwErrorCode = dwError;
  58. pQMPolicyState->pNext = gpQMPolicyState;
  59. gpQMPolicyState = pQMPolicyState;
  60. continue;
  61. }
  62. dwError = AddQMPolicyInternal(
  63. pServerName,
  64. dwVersion,
  65. 0,
  66. dwSource,
  67. pSPDQMPolicy,
  68. NULL
  69. );
  70. if (dwError && dwError != WARNING_IPSEC_QM_POLICY_PRUNED) {
  71. pQMPolicyState->bInSPD = FALSE;
  72. pQMPolicyState->dwErrorCode = dwError;
  73. }
  74. else {
  75. pQMPolicyState->bInSPD = TRUE;
  76. pQMPolicyState->dwErrorCode = ERROR_SUCCESS;
  77. dwError = ERROR_SUCCESS;
  78. }
  79. pQMPolicyState->pNext = gpQMPolicyState;
  80. gpQMPolicyState = pQMPolicyState;
  81. PAFreeQMPolicy(pSPDQMPolicy);
  82. }
  83. return (dwError);
  84. }
  85. DWORD
  86. PACreateQMPolicyState(
  87. PIPSEC_NFA_DATA pIpsecNFAData,
  88. PQMPOLICYSTATE * ppQMPolicyState
  89. )
  90. {
  91. DWORD dwError = 0;
  92. PQMPOLICYSTATE pQMPolicyState = NULL;
  93. PIPSEC_NEGPOL_DATA pIpsecNegPolData = NULL;
  94. WCHAR pszName[512];
  95. dwError = AllocateSPDMemory(
  96. sizeof(QMPOLICYSTATE),
  97. &pQMPolicyState
  98. );
  99. BAIL_ON_WIN32_ERROR(dwError);
  100. pIpsecNegPolData = pIpsecNFAData->pIpsecNegPolData;
  101. memcpy(
  102. &(pQMPolicyState->gPolicyID),
  103. &(pIpsecNegPolData->NegPolIdentifier),
  104. sizeof(GUID)
  105. );
  106. if (pIpsecNegPolData->pszIpsecName && *(pIpsecNegPolData->pszIpsecName)) {
  107. dwError = AllocateSPDString(
  108. pIpsecNegPolData->pszIpsecName,
  109. &(pQMPolicyState->pszPolicyName)
  110. );
  111. BAIL_ON_WIN32_ERROR(dwError);
  112. }
  113. else {
  114. wsprintf(pszName, L"%d", ++gdwQMPolicyCounter);
  115. dwError = AllocateSPDString(
  116. pszName,
  117. &(pQMPolicyState->pszPolicyName)
  118. );
  119. BAIL_ON_WIN32_ERROR(dwError);
  120. }
  121. memcpy(
  122. &(pQMPolicyState->gNegPolType),
  123. &(pIpsecNegPolData->NegPolType),
  124. sizeof(GUID)
  125. );
  126. memcpy(
  127. &(pQMPolicyState->gNegPolAction),
  128. &(pIpsecNegPolData->NegPolAction),
  129. sizeof(GUID)
  130. );
  131. pQMPolicyState->bAllowsSoft = FALSE;
  132. pQMPolicyState->cRef = 1;
  133. pQMPolicyState->bInSPD = FALSE;
  134. pQMPolicyState->dwErrorCode = 0;
  135. pQMPolicyState->pNext = NULL;
  136. *ppQMPolicyState = pQMPolicyState;
  137. return (dwError);
  138. error:
  139. TRACE(
  140. TRC_ERROR,
  141. (L"Pastore failed to create QM policy state for %!guid!",
  142. &pIpsecNegPolData->NegPolIdentifier)
  143. );
  144. if (pQMPolicyState) {
  145. PAFreeQMPolicyState(pQMPolicyState);
  146. }
  147. *ppQMPolicyState = NULL;
  148. return (dwError);
  149. }
  150. VOID
  151. PAFreeQMPolicyState(
  152. PQMPOLICYSTATE pQMPolicyState
  153. )
  154. {
  155. if (pQMPolicyState) {
  156. if (pQMPolicyState->pszPolicyName) {
  157. FreeSPDString(pQMPolicyState->pszPolicyName);
  158. }
  159. FreeSPDMemory(pQMPolicyState);
  160. }
  161. }
  162. BOOL
  163. IsClearOnly(
  164. GUID gNegPolAction
  165. )
  166. {
  167. if (!memcmp(
  168. &gNegPolAction,
  169. &(GUID_NEGOTIATION_ACTION_NO_IPSEC),
  170. sizeof(GUID))) {
  171. return (TRUE);
  172. }
  173. else {
  174. return (FALSE);
  175. }
  176. }
  177. BOOL
  178. IsBlocking(
  179. GUID gNegPolAction
  180. )
  181. {
  182. if (!memcmp(
  183. &gNegPolAction,
  184. &(GUID_NEGOTIATION_ACTION_BLOCK),
  185. sizeof(GUID))) {
  186. return (TRUE);
  187. }
  188. else {
  189. return (FALSE);
  190. }
  191. }
  192. BOOL
  193. IsInboundPassThru(
  194. GUID gNegPolAction
  195. )
  196. {
  197. if (!memcmp(
  198. &gNegPolAction,
  199. &(GUID_NEGOTIATION_ACTION_INBOUND_PASSTHRU),
  200. sizeof(GUID))) {
  201. return (TRUE);
  202. }
  203. else {
  204. return (FALSE);
  205. }
  206. }
  207. BOOL
  208. IsSecure(
  209. GUID gNegPolAction
  210. )
  211. {
  212. if (!memcmp(
  213. &gNegPolAction,
  214. &(GUID_NEGOTIATION_ACTION_NORMAL_IPSEC),
  215. sizeof(GUID))) {
  216. return (TRUE);
  217. }
  218. else {
  219. return (FALSE);
  220. }
  221. }
  222. DWORD
  223. PACreateQMPolicy(
  224. PIPSEC_NFA_DATA pIpsecNFAData,
  225. PQMPOLICYSTATE pQMPolicyState,
  226. PIPSEC_QM_POLICY * ppSPDQMPolicy
  227. )
  228. {
  229. DWORD dwError = 0;
  230. PIPSEC_QM_POLICY pSPDQMPolicy = NULL;
  231. PIPSEC_NEGPOL_DATA pIpsecNegPolData = NULL;
  232. pIpsecNegPolData = pIpsecNFAData->pIpsecNegPolData;
  233. dwError = AllocateSPDMemory(
  234. sizeof(IPSEC_QM_POLICY),
  235. &pSPDQMPolicy
  236. );
  237. BAIL_ON_WIN32_ERROR(dwError);
  238. memcpy(
  239. &(pSPDQMPolicy->gPolicyID),
  240. &(pIpsecNegPolData->NegPolIdentifier),
  241. sizeof(GUID)
  242. );
  243. dwError = AllocateSPDString(
  244. pQMPolicyState->pszPolicyName,
  245. &(pSPDQMPolicy->pszPolicyName)
  246. );
  247. BAIL_ON_WIN32_ERROR(dwError);
  248. dwError = PACreateQMOffers(
  249. pIpsecNegPolData->dwSecurityMethodCount,
  250. pIpsecNegPolData->pIpsecSecurityMethods,
  251. pQMPolicyState,
  252. &(pSPDQMPolicy->dwOfferCount),
  253. &(pSPDQMPolicy->pOffers)
  254. );
  255. BAIL_ON_WIN32_ERROR(dwError);
  256. pSPDQMPolicy->dwFlags = 0;
  257. if (!memcmp(
  258. &(pIpsecNegPolData->NegPolType),
  259. &(GUID_NEGOTIATION_TYPE_DEFAULT),
  260. sizeof(GUID))) {
  261. pSPDQMPolicy->dwFlags |= IPSEC_QM_POLICY_DEFAULT_POLICY;
  262. }
  263. if (pIpsecNFAData->dwTunnelFlags) {
  264. pSPDQMPolicy->dwFlags |= IPSEC_QM_POLICY_TUNNEL_MODE;
  265. }
  266. if (pQMPolicyState->bAllowsSoft) {
  267. pSPDQMPolicy->dwFlags |= IPSEC_QM_POLICY_ALLOW_SOFT;
  268. }
  269. pSPDQMPolicy->dwReserved = 0;
  270. *ppSPDQMPolicy = pSPDQMPolicy;
  271. return (dwError);
  272. error:
  273. TRACE(
  274. TRC_ERROR,
  275. (L"Pastore failed to create MM policy for %!guid!",
  276. &pIpsecNegPolData->NegPolIdentifier)
  277. );
  278. if (pSPDQMPolicy) {
  279. PAFreeQMPolicy(
  280. pSPDQMPolicy
  281. );
  282. }
  283. *ppSPDQMPolicy = NULL;
  284. return (dwError);
  285. }
  286. DWORD
  287. PACreateQMOffers(
  288. DWORD dwSecurityMethodCount,
  289. PIPSEC_SECURITY_METHOD pIpsecSecurityMethods,
  290. PQMPOLICYSTATE pQMPolicyState,
  291. PDWORD pdwOfferCount,
  292. PIPSEC_QM_OFFER * ppOffers
  293. )
  294. {
  295. DWORD dwError = 0;
  296. DWORD dwTempOfferCount = 0;
  297. PIPSEC_SECURITY_METHOD pTempMethod = NULL;
  298. BOOL bAllowsSoft = FALSE;
  299. DWORD i = 0;
  300. DWORD dwOfferCount = 0;
  301. PIPSEC_QM_OFFER pOffers = NULL;
  302. PIPSEC_QM_OFFER pTempOffer = NULL;
  303. if (!dwSecurityMethodCount || !pIpsecSecurityMethods) {
  304. dwError = ERROR_INVALID_PARAMETER;
  305. BAIL_ON_WIN32_ERROR(dwError);
  306. }
  307. if (dwSecurityMethodCount > IPSEC_MAX_QM_OFFERS) {
  308. dwTempOfferCount = IPSEC_MAX_QM_OFFERS;
  309. }
  310. else {
  311. dwTempOfferCount = dwSecurityMethodCount;
  312. }
  313. pTempMethod = pIpsecSecurityMethods;
  314. for (i = 0; i < dwTempOfferCount; i++) {
  315. if (pTempMethod->Count == 0) {
  316. bAllowsSoft = TRUE;
  317. }
  318. else {
  319. dwOfferCount++;
  320. }
  321. pTempMethod++;
  322. }
  323. if (!dwOfferCount) {
  324. dwError = ERROR_INVALID_PARAMETER;
  325. BAIL_ON_WIN32_ERROR(dwError);
  326. }
  327. dwError = AllocateSPDMemory(
  328. sizeof(IPSEC_QM_OFFER)*dwOfferCount,
  329. &(pOffers)
  330. );
  331. BAIL_ON_WIN32_ERROR(dwError);
  332. pTempOffer = pOffers;
  333. pTempMethod = pIpsecSecurityMethods;
  334. i = 0;
  335. while (i < dwOfferCount) {
  336. if (pTempMethod->Count) {
  337. PACopyQMOffers(
  338. pTempMethod,
  339. pTempOffer
  340. );
  341. i++;
  342. pTempOffer++;
  343. }
  344. pTempMethod++;
  345. }
  346. pQMPolicyState->bAllowsSoft = bAllowsSoft;
  347. *pdwOfferCount = dwOfferCount;
  348. *ppOffers = pOffers;
  349. return (dwError);
  350. error:
  351. if (pOffers) {
  352. PAFreeQMOffers(
  353. i,
  354. pOffers
  355. );
  356. }
  357. *pdwOfferCount = 0;
  358. *ppOffers = NULL;
  359. return (dwError);
  360. }
  361. VOID
  362. PACopyQMOffers(
  363. PIPSEC_SECURITY_METHOD pMethod,
  364. PIPSEC_QM_OFFER pOffer
  365. )
  366. {
  367. DWORD i = 0;
  368. DWORD j = 0;
  369. DWORD k = 0;
  370. pOffer->Lifetime.uKeyExpirationKBytes = pMethod->Lifetime.KeyExpirationBytes;
  371. pOffer->Lifetime.uKeyExpirationTime = pMethod->Lifetime.KeyExpirationTime;
  372. pOffer->dwFlags = pMethod->Flags;
  373. pOffer->bPFSRequired = pMethod->PfsQMRequired;
  374. if (pMethod->PfsQMRequired) {
  375. pOffer->dwPFSGroup = PFS_GROUP_MM;
  376. }
  377. else {
  378. pOffer->dwPFSGroup = PFS_GROUP_NONE;
  379. }
  380. i = 0;
  381. for (j = 0; (j < pMethod->Count) && (i < QM_MAX_ALGOS) ; j++) {
  382. switch (pMethod->Algos[j].operation) {
  383. case Auth:
  384. switch (pMethod->Algos[j].algoIdentifier) {
  385. case IPSEC_AH_MD5:
  386. pOffer->Algos[i].uAlgoIdentifier = AUTH_ALGO_MD5;
  387. break;
  388. case IPSEC_AH_SHA:
  389. pOffer->Algos[i].uAlgoIdentifier = AUTH_ALGO_SHA1;
  390. break;
  391. default:
  392. pOffer->Algos[i].uAlgoIdentifier = AUTH_ALGO_NONE;
  393. break;
  394. }
  395. pOffer->Algos[i].uSecAlgoIdentifier = HMAC_AUTH_ALGO_NONE;
  396. pOffer->Algos[i].Operation = AUTHENTICATION;
  397. pOffer->Algos[i].uAlgoKeyLen = pMethod->Algos[j].algoKeylen;
  398. pOffer->Algos[i].uAlgoRounds = pMethod->Algos[j].algoRounds;
  399. pOffer->Algos[i].uSecAlgoKeyLen = 0;
  400. pOffer->Algos[i].uSecAlgoRounds = 0;
  401. pOffer->Algos[i].MySpi = 0;
  402. pOffer->Algos[i].PeerSpi = 0;
  403. i++;
  404. break;
  405. case Encrypt:
  406. switch (pMethod->Algos[j].algoIdentifier) {
  407. case IPSEC_ESP_DES:
  408. pOffer->Algos[i].uAlgoIdentifier = CONF_ALGO_DES;
  409. break;
  410. case IPSEC_ESP_DES_40:
  411. pOffer->Algos[i].uAlgoIdentifier = CONF_ALGO_DES;
  412. break;
  413. case IPSEC_ESP_3_DES:
  414. pOffer->Algos[i].uAlgoIdentifier = CONF_ALGO_3_DES;
  415. break;
  416. default:
  417. pOffer->Algos[i].uAlgoIdentifier = CONF_ALGO_NONE;
  418. break;
  419. }
  420. switch (pMethod->Algos[j].secondaryAlgoIdentifier) {
  421. case IPSEC_AH_MD5:
  422. pOffer->Algos[i].uSecAlgoIdentifier = HMAC_AUTH_ALGO_MD5;
  423. break;
  424. case IPSEC_AH_SHA:
  425. pOffer->Algos[i].uSecAlgoIdentifier = HMAC_AUTH_ALGO_SHA1;
  426. break;
  427. default:
  428. pOffer->Algos[i].uSecAlgoIdentifier = HMAC_AUTH_ALGO_NONE;
  429. break;
  430. }
  431. pOffer->Algos[i].Operation = ENCRYPTION;
  432. pOffer->Algos[i].uAlgoKeyLen = pMethod->Algos[j].algoKeylen;
  433. pOffer->Algos[i].uAlgoRounds = pMethod->Algos[j].algoRounds;
  434. pOffer->Algos[i].uSecAlgoKeyLen = 0;
  435. pOffer->Algos[i].uSecAlgoRounds = 0;
  436. pOffer->Algos[i].MySpi = 0;
  437. pOffer->Algos[i].PeerSpi = 0;
  438. i++;
  439. break;
  440. case None:
  441. case Compress:
  442. default:
  443. break;
  444. }
  445. }
  446. for (k = i; k < QM_MAX_ALGOS; k++) {
  447. memset(&(pOffer->Algos[k]), 0, sizeof(IPSEC_QM_ALGO));
  448. }
  449. pOffer->dwNumAlgos = i;
  450. pOffer->dwReserved = 0;
  451. }
  452. VOID
  453. PAFreeQMPolicy(
  454. PIPSEC_QM_POLICY pSPDQMPolicy
  455. )
  456. {
  457. if (pSPDQMPolicy) {
  458. if (pSPDQMPolicy->pszPolicyName) {
  459. FreeSPDString(pSPDQMPolicy->pszPolicyName);
  460. }
  461. PAFreeQMOffers(
  462. pSPDQMPolicy->dwOfferCount,
  463. pSPDQMPolicy->pOffers
  464. );
  465. FreeSPDMemory(pSPDQMPolicy);
  466. }
  467. }
  468. VOID
  469. PAFreeQMOffers(
  470. DWORD dwOfferCount,
  471. PIPSEC_QM_OFFER pOffers
  472. )
  473. {
  474. if (pOffers) {
  475. FreeSPDMemory(pOffers);
  476. }
  477. }
  478. DWORD
  479. PADeleteAllQMPolicies(
  480. )
  481. {
  482. DWORD dwError = 0;
  483. PQMPOLICYSTATE pQMPolicyState = NULL;
  484. LPWSTR pServerName = NULL;
  485. PQMPOLICYSTATE pTemp = NULL;
  486. PQMPOLICYSTATE pLeftQMPolicyState = NULL;
  487. DWORD dwVersion = 0;
  488. TRACE(TRC_INFORMATION, (L"Pastore deleting all QM polcies."));
  489. pQMPolicyState = gpQMPolicyState;
  490. while (pQMPolicyState) {
  491. if (pQMPolicyState->bInSPD) {
  492. dwError = DeleteQMPolicy(
  493. pServerName,
  494. dwVersion,
  495. pQMPolicyState->pszPolicyName,
  496. NULL
  497. );
  498. if (!dwError) {
  499. pTemp = pQMPolicyState;
  500. pQMPolicyState = pQMPolicyState->pNext;
  501. PAFreeQMPolicyState(pTemp);
  502. }
  503. else {
  504. pQMPolicyState->dwErrorCode = dwError;
  505. pTemp = pQMPolicyState;
  506. pQMPolicyState = pQMPolicyState->pNext;
  507. pTemp->pNext = pLeftQMPolicyState;
  508. pLeftQMPolicyState = pTemp;
  509. }
  510. }
  511. else {
  512. pTemp = pQMPolicyState;
  513. pQMPolicyState = pQMPolicyState->pNext;
  514. PAFreeQMPolicyState(pTemp);
  515. }
  516. }
  517. gpQMPolicyState = pLeftQMPolicyState;
  518. return (dwError);
  519. }
  520. VOID
  521. PAFreeQMPolicyStateList(
  522. PQMPOLICYSTATE pQMPolicyState
  523. )
  524. {
  525. PQMPOLICYSTATE pTemp = NULL;
  526. while (pQMPolicyState) {
  527. pTemp = pQMPolicyState;
  528. pQMPolicyState = pQMPolicyState->pNext;
  529. PAFreeQMPolicyState(pTemp);
  530. }
  531. }
  532. PQMPOLICYSTATE
  533. FindQMPolicyState(
  534. GUID gPolicyID
  535. )
  536. {
  537. PQMPOLICYSTATE pQMPolicyState = NULL;
  538. pQMPolicyState = gpQMPolicyState;
  539. while (pQMPolicyState) {
  540. if (!memcmp(&(pQMPolicyState->gPolicyID), &gPolicyID, sizeof(GUID))) {
  541. return (pQMPolicyState);
  542. }
  543. pQMPolicyState = pQMPolicyState->pNext;
  544. }
  545. return (NULL);
  546. }
  547. DWORD
  548. PADeleteQMPolicies(
  549. PIPSEC_NFA_DATA * ppIpsecNFAData,
  550. DWORD dwNumNFACount
  551. )
  552. {
  553. DWORD dwError = 0;
  554. DWORD i = 0;
  555. PIPSEC_NFA_DATA pIpsecNFAData = NULL;
  556. PIPSEC_NEGPOL_DATA pIpsecNegPolData = NULL;
  557. for (i = 0; i < dwNumNFACount; i++) {
  558. pIpsecNFAData = *(ppIpsecNFAData + i);
  559. pIpsecNegPolData = pIpsecNFAData->pIpsecNegPolData;
  560. dwError = PADeleteQMPolicy(
  561. pIpsecNegPolData->NegPolIdentifier
  562. );
  563. }
  564. return (dwError);
  565. }
  566. DWORD
  567. PADeleteQMPolicy(
  568. GUID gPolicyID
  569. )
  570. {
  571. DWORD dwError = 0;
  572. PQMPOLICYSTATE pQMPolicyState = NULL;
  573. LPWSTR pServerName = NULL;
  574. DWORD dwVersion = 0;
  575. TRACE(
  576. TRC_INFORMATION,
  577. (L"Pastore deleting QM policy %!guid!",
  578. &gPolicyID)
  579. );
  580. pQMPolicyState = FindQMPolicyState(
  581. gPolicyID
  582. );
  583. if (!pQMPolicyState) {
  584. dwError = ERROR_SUCCESS;
  585. return (dwError);
  586. }
  587. pQMPolicyState->cRef--;
  588. if (pQMPolicyState->cRef > 0) {
  589. dwError = ERROR_SUCCESS;
  590. return (dwError);
  591. }
  592. if (pQMPolicyState->bInSPD) {
  593. dwError = DeleteQMPolicy(
  594. pServerName,
  595. dwVersion,
  596. pQMPolicyState->pszPolicyName,
  597. NULL
  598. );
  599. if (dwError) {
  600. pQMPolicyState->cRef++;
  601. pQMPolicyState->dwErrorCode = dwError;
  602. }
  603. BAIL_ON_WIN32_ERROR(dwError);
  604. }
  605. PADeleteQMPolicyState(pQMPolicyState);
  606. error:
  607. return (dwError);
  608. }
  609. VOID
  610. PADeleteQMPolicyState(
  611. PQMPOLICYSTATE pQMPolicyState
  612. )
  613. {
  614. PQMPOLICYSTATE * ppTemp = NULL;
  615. ppTemp = &gpQMPolicyState;
  616. while (*ppTemp) {
  617. if (*ppTemp == pQMPolicyState) {
  618. break;
  619. }
  620. ppTemp = &((*ppTemp)->pNext);
  621. }
  622. if (*ppTemp) {
  623. *ppTemp = pQMPolicyState->pNext;
  624. }
  625. PAFreeQMPolicyState(pQMPolicyState);
  626. return;
  627. }
  628. DWORD
  629. PADeleteInUseQMPolicies(
  630. )
  631. {
  632. DWORD dwError = 0;
  633. PQMPOLICYSTATE pQMPolicyState = NULL;
  634. LPWSTR pServerName = NULL;
  635. PQMPOLICYSTATE pTemp = NULL;
  636. PQMPOLICYSTATE pLeftQMPolicyState = NULL;
  637. DWORD dwVersion = 0;
  638. TRACE(TRC_INFORMATION, (L"Pastore deleting in-use QM polcies."));
  639. pQMPolicyState = gpQMPolicyState;
  640. while (pQMPolicyState) {
  641. if (pQMPolicyState->bInSPD &&
  642. (pQMPolicyState->dwErrorCode == ERROR_IPSEC_QM_POLICY_IN_USE)) {
  643. dwError = DeleteQMPolicy(
  644. pServerName,
  645. dwVersion,
  646. pQMPolicyState->pszPolicyName,
  647. NULL
  648. );
  649. if (!dwError) {
  650. pTemp = pQMPolicyState;
  651. pQMPolicyState = pQMPolicyState->pNext;
  652. PAFreeQMPolicyState(pTemp);
  653. }
  654. else {
  655. pTemp = pQMPolicyState;
  656. pQMPolicyState = pQMPolicyState->pNext;
  657. pTemp->pNext = pLeftQMPolicyState;
  658. pLeftQMPolicyState = pTemp;
  659. }
  660. }
  661. else {
  662. pTemp = pQMPolicyState;
  663. pQMPolicyState = pQMPolicyState->pNext;
  664. pTemp->pNext = pLeftQMPolicyState;
  665. pLeftQMPolicyState = pTemp;
  666. }
  667. }
  668. gpQMPolicyState = pLeftQMPolicyState;
  669. return (dwError);
  670. }