windows-nt/Source/XPSP1/NT/net/ipsec/spd/server/mm-policy.c
2020-09-26 16:20:57 +08:00

1272 lines
24 KiB
C

/*++
Copyright (c) 1999 Microsoft Corporation
Module Name:
mm-policy.c
Abstract:
Author:
Environment: User Mode
Revision History:
--*/
#include "precomp.h"
DWORD
AddMMPolicy(
LPWSTR pServerName,
DWORD dwFlags,
PIPSEC_MM_POLICY pMMPolicy
)
/*++
Routine Description:
This function adds a main mode policy to the SPD.
Arguments:
pServerName - Server on which the main mode policy is to be added.
pMMPolicy - Main mode policy to be added.
Return Value:
ERROR_SUCCESS - Success.
Win32 Error - Failure.
--*/
{
DWORD dwError = 0;
PINIMMPOLICY pIniMMPolicy = NULL;
BOOL bPersist = FALSE;
bPersist = (BOOL) (dwFlags & PERSIST_SPD_OBJECT);
//
// Validate the main mode policy.
//
dwError = ValidateMMPolicy(
pMMPolicy
);
BAIL_ON_WIN32_ERROR(dwError);
ENTER_SPD_SECTION();
dwError = ValidateSecurity(
SPD_OBJECT_SERVER,
SERVER_ACCESS_ADMINISTER,
NULL,
NULL
);
BAIL_ON_LOCK_ERROR(dwError);
pIniMMPolicy = FindMMPolicy(
gpIniMMPolicy,
pMMPolicy->pszPolicyName
);
if (pIniMMPolicy) {
dwError = ERROR_IPSEC_MM_POLICY_EXISTS;
BAIL_ON_LOCK_ERROR(dwError);
}
pIniMMPolicy = FindMMPolicyByGuid(
gpIniMMPolicy,
pMMPolicy->gPolicyID
);
if (pIniMMPolicy) {
dwError = ERROR_IPSEC_MM_POLICY_EXISTS;
BAIL_ON_LOCK_ERROR(dwError);
}
if (bPersist && !gbLoadingPersistence) {
dwError = PersistMMPolicy(
pMMPolicy
);
BAIL_ON_LOCK_ERROR(dwError);
}
dwError = CreateIniMMPolicy(
pMMPolicy,
&pIniMMPolicy
);
BAIL_ON_LOCK_ERROR(dwError);
pIniMMPolicy->bIsPersisted = bPersist;
pIniMMPolicy->pNext = gpIniMMPolicy;
gpIniMMPolicy = pIniMMPolicy;
if ((pIniMMPolicy->dwFlags) & IPSEC_MM_POLICY_DEFAULT_POLICY) {
gpIniDefaultMMPolicy = pIniMMPolicy;
}
LEAVE_SPD_SECTION();
return (dwError);
lock:
LEAVE_SPD_SECTION();
error:
if (pMMPolicy && bPersist && !gbLoadingPersistence) {
(VOID) SPDPurgeMMPolicy(
pMMPolicy->gPolicyID
);
}
return (dwError);
}
DWORD
ValidateMMPolicy(
PIPSEC_MM_POLICY pMMPolicy
)
{
DWORD dwError = 0;
if (!pMMPolicy) {
dwError = ERROR_INVALID_PARAMETER;
BAIL_ON_WIN32_ERROR(dwError);
}
if (!(pMMPolicy->pszPolicyName) || !(*(pMMPolicy->pszPolicyName))) {
dwError = ERROR_INVALID_PARAMETER;
BAIL_ON_WIN32_ERROR(dwError);
}
dwError = ValidateMMOffers(
pMMPolicy->dwOfferCount,
pMMPolicy->pOffers
);
BAIL_ON_WIN32_ERROR(dwError);
error:
return (dwError);
}
DWORD
ValidateMMOffers(
DWORD dwOfferCount,
PIPSEC_MM_OFFER pOffers
)
{
DWORD dwError = 0;
DWORD i = 0;
PIPSEC_MM_OFFER pTemp = NULL;
if (!dwOfferCount || !pOffers) {
dwError = ERROR_INVALID_PARAMETER;
BAIL_ON_WIN32_ERROR(dwError);
}
//
// Need to catch the exception when the number of offers
// specified is more than the actual number of offers.
//
pTemp = pOffers;
for (i = 0; i < dwOfferCount; i++) {
if ((pTemp->dwDHGroup != DH_GROUP_1) &&
(pTemp->dwDHGroup != DH_GROUP_2)) {
dwError = ERROR_INVALID_PARAMETER;
BAIL_ON_WIN32_ERROR(dwError);
}
if (pTemp->EncryptionAlgorithm.uAlgoIdentifier >= IPSEC_DOI_ESP_MAX) {
dwError = ERROR_INVALID_PARAMETER;
BAIL_ON_WIN32_ERROR(dwError);
}
if (pTemp->HashingAlgorithm.uAlgoIdentifier >= IPSEC_DOI_AH_MAX) {
dwError = ERROR_INVALID_PARAMETER;
BAIL_ON_WIN32_ERROR(dwError);
}
pTemp++;
}
error:
return (dwError);
}
DWORD
CreateIniMMPolicy(
PIPSEC_MM_POLICY pMMPolicy,
PINIMMPOLICY * ppIniMMPolicy
)
{
DWORD dwError = 0;
PINIMMPOLICY pIniMMPolicy = NULL;
dwError = AllocateSPDMemory(
sizeof(INIMMPOLICY),
&pIniMMPolicy
);
BAIL_ON_WIN32_ERROR(dwError);
memcpy(
&(pIniMMPolicy->gPolicyID),
&(pMMPolicy->gPolicyID),
sizeof(GUID)
);
dwError = AllocateSPDString(
pMMPolicy->pszPolicyName,
&(pIniMMPolicy->pszPolicyName)
);
BAIL_ON_WIN32_ERROR(dwError);
pIniMMPolicy->cRef = 0;
pIniMMPolicy->bIsPersisted = FALSE;
pIniMMPolicy->dwFlags = pMMPolicy->dwFlags;
pIniMMPolicy->uSoftSAExpirationTime = pMMPolicy->uSoftSAExpirationTime;
pIniMMPolicy->pNext = NULL;
dwError = CreateIniMMOffers(
pMMPolicy->dwOfferCount,
pMMPolicy->pOffers,
&(pIniMMPolicy->dwOfferCount),
&(pIniMMPolicy->pOffers)
);
BAIL_ON_WIN32_ERROR(dwError);
*ppIniMMPolicy = pIniMMPolicy;
return (dwError);
error:
if (pIniMMPolicy) {
FreeIniMMPolicy(
pIniMMPolicy
);
}
*ppIniMMPolicy = NULL;
return (dwError);
}
DWORD
CreateIniMMOffers(
DWORD dwInOfferCount,
PIPSEC_MM_OFFER pInOffers,
PDWORD pdwOfferCount,
PIPSEC_MM_OFFER * ppOffers
)
{
DWORD dwError = 0;
PIPSEC_MM_OFFER pOffers = NULL;
PIPSEC_MM_OFFER pTemp = NULL;
PIPSEC_MM_OFFER pInTempOffer = NULL;
DWORD i = 0;
//
// Offer count and the offers themselves have already been validated.
//
dwError = AllocateSPDMemory(
sizeof(IPSEC_MM_OFFER) * dwInOfferCount,
&(pOffers)
);
BAIL_ON_WIN32_ERROR(dwError);
pTemp = pOffers;
pInTempOffer = pInOffers;
for (i = 0; i < dwInOfferCount; i++) {
memcpy(
&(pTemp->Lifetime),
&(pInTempOffer->Lifetime),
sizeof(KEY_LIFETIME)
);
if (!(pTemp->Lifetime.uKeyExpirationTime)) {
pTemp->Lifetime.uKeyExpirationTime = DEFAULT_MM_KEY_EXPIRATION_TIME;
}
pTemp->dwFlags = pInTempOffer->dwFlags;
pTemp->dwQuickModeLimit = pInTempOffer->dwQuickModeLimit;
pTemp->dwDHGroup = pInTempOffer->dwDHGroup;
memcpy(
&(pTemp->EncryptionAlgorithm),
&(pInTempOffer->EncryptionAlgorithm),
sizeof(IPSEC_MM_ALGO)
);
memcpy(
&(pTemp->HashingAlgorithm),
&(pInTempOffer->HashingAlgorithm),
sizeof(IPSEC_MM_ALGO)
);
pInTempOffer++;
pTemp++;
}
*pdwOfferCount = dwInOfferCount;
*ppOffers = pOffers;
return (dwError);
error:
if (pOffers) {
FreeIniMMOffers(
i,
pOffers
);
}
*pdwOfferCount = 0;
*ppOffers = NULL;
return (dwError);
}
VOID
FreeIniMMPolicy(
PINIMMPOLICY pIniMMPolicy
)
{
if (pIniMMPolicy) {
if (pIniMMPolicy->pszPolicyName) {
FreeSPDString(pIniMMPolicy->pszPolicyName);
}
FreeIniMMOffers(
pIniMMPolicy->dwOfferCount,
pIniMMPolicy->pOffers
);
FreeSPDMemory(pIniMMPolicy);
}
}
VOID
FreeIniMMOffers(
DWORD dwOfferCount,
PIPSEC_MM_OFFER pOffers
)
{
if (pOffers) {
FreeSPDMemory(pOffers);
}
}
PINIMMPOLICY
FindMMPolicy(
PINIMMPOLICY pIniMMPolicyList,
LPWSTR pszPolicyName
)
{
DWORD dwError = 0;
PINIMMPOLICY pTemp = NULL;
pTemp = pIniMMPolicyList;
while (pTemp) {
if (!_wcsicmp(pTemp->pszPolicyName, pszPolicyName)) {
return (pTemp);
}
pTemp = pTemp->pNext;
}
return (NULL);
}
DWORD
DeleteMMPolicy(
LPWSTR pServerName,
LPWSTR pszPolicyName
)
/*++
Routine Description:
This function deletes a main mode policy from the SPD.
Arguments:
pServerName - Server on which the main mode policy is to be deleted.
pszPolicyName - Main mode policy to be deleted.
Return Value:
ERROR_SUCCESS - Success.
Win32 Error - Failure.
--*/
{
DWORD dwError = 0;
PINIMMPOLICY pIniMMPolicy = NULL;
GUID gPolicyID;
if (!pszPolicyName || !*pszPolicyName) {
return (ERROR_INVALID_PARAMETER);
}
ENTER_SPD_SECTION();
dwError = ValidateSecurity(
SPD_OBJECT_SERVER,
SERVER_ACCESS_ADMINISTER,
NULL,
NULL
);
BAIL_ON_LOCK_ERROR(dwError);
pIniMMPolicy = FindMMPolicy(
gpIniMMPolicy,
pszPolicyName
);
if (!pIniMMPolicy) {
dwError = ERROR_IPSEC_MM_POLICY_NOT_FOUND;
BAIL_ON_LOCK_ERROR(dwError);
}
if (pIniMMPolicy->cRef) {
dwError = ERROR_IPSEC_MM_POLICY_IN_USE;
memcpy(&gPolicyID, &pIniMMPolicy->gPolicyID, sizeof(GUID));
BAIL_ON_LOCK_ERROR(dwError);
}
memcpy(&gPolicyID, &pIniMMPolicy->gPolicyID, sizeof(GUID));
if (pIniMMPolicy->bIsPersisted) {
dwError = SPDPurgeMMPolicy(
gPolicyID
);
BAIL_ON_LOCK_ERROR(dwError);
}
dwError = DeleteIniMMPolicy(
pIniMMPolicy
);
BAIL_ON_LOCK_ERROR(dwError);
LEAVE_SPD_SECTION();
if (gbIKENotify) {
(VOID) IKENotifyPolicyChange(
&(gPolicyID),
POLICY_GUID_MM
);
}
return (dwError);
lock:
LEAVE_SPD_SECTION();
if ((dwError == ERROR_IPSEC_MM_POLICY_IN_USE) && gbIKENotify) {
(VOID) IKENotifyPolicyChange(
&(gPolicyID),
POLICY_GUID_MM
);
}
return (dwError);
}
DWORD
EnumMMPolicies(
LPWSTR pServerName,
PIPSEC_MM_POLICY * ppMMPolicies,
DWORD dwPreferredNumEntries,
LPDWORD pdwNumPolicies,
LPDWORD pdwResumeHandle
)
/*++
Routine Description:
This function enumerates main mode policies from the SPD.
Arguments:
pServerName - Server on which the main mode policies are to
be enumerated.
ppMMPolicies - Enumerated main mode policies returned to the
caller.
dwPreferredNumEntries - Preferred number of enumeration entries.
pdwNumPolicies - Number of main mode policies actually enumerated.
pdwResumeHandle - Handle to the location in the main mode policy
list from which to resume enumeration.
Return Value:
ERROR_SUCCESS - Success.
Win32 Error - Failure.
--*/
{
DWORD dwError = 0;
DWORD dwResumeHandle = 0;
DWORD dwNumToEnum = 0;
PINIMMPOLICY pIniMMPolicy = NULL;
DWORD i = 0;
PINIMMPOLICY pTemp = NULL;
DWORD dwNumPolicies = 0;
PIPSEC_MM_POLICY pMMPolicies = NULL;
PIPSEC_MM_POLICY pMMPolicy = NULL;
dwResumeHandle = *pdwResumeHandle;
if (!dwPreferredNumEntries || (dwPreferredNumEntries > MAX_MMPOLICY_ENUM_COUNT)) {
dwNumToEnum = MAX_MMPOLICY_ENUM_COUNT;
}
else {
dwNumToEnum = dwPreferredNumEntries;
}
ENTER_SPD_SECTION();
dwError = ValidateSecurity(
SPD_OBJECT_SERVER,
SERVER_ACCESS_ADMINISTER,
NULL,
NULL
);
BAIL_ON_LOCK_ERROR(dwError);
pIniMMPolicy = gpIniMMPolicy;
for (i = 0; (i < dwResumeHandle) && (pIniMMPolicy != NULL); i++) {
pIniMMPolicy = pIniMMPolicy->pNext;
}
if (!pIniMMPolicy) {
dwError = ERROR_NO_DATA;
BAIL_ON_LOCK_ERROR(dwError);
}
pTemp = pIniMMPolicy;
while (pTemp && (dwNumPolicies < dwNumToEnum)) {
dwNumPolicies++;
pTemp = pTemp->pNext;
}
dwError = SPDApiBufferAllocate(
sizeof(IPSEC_MM_POLICY)*dwNumPolicies,
&pMMPolicies
);
BAIL_ON_LOCK_ERROR(dwError);
pTemp = pIniMMPolicy;
pMMPolicy = pMMPolicies;
for (i = 0; i < dwNumPolicies; i++) {
dwError = CopyMMPolicy(
pTemp,
pMMPolicy
);
BAIL_ON_LOCK_ERROR(dwError);
pTemp = pTemp->pNext;
pMMPolicy++;
}
*ppMMPolicies = pMMPolicies;
*pdwResumeHandle = dwResumeHandle + dwNumPolicies;
*pdwNumPolicies = dwNumPolicies;
LEAVE_SPD_SECTION();
return (dwError);
lock:
LEAVE_SPD_SECTION();
if (pMMPolicies) {
FreeMMPolicies(
i,
pMMPolicies
);
}
*ppMMPolicies = NULL;
*pdwResumeHandle = dwResumeHandle;
*pdwNumPolicies = 0;
return (dwError);
}
DWORD
SetMMPolicy(
LPWSTR pServerName,
LPWSTR pszPolicyName,
PIPSEC_MM_POLICY pMMPolicy
)
/*++
Routine Description:
This function updates a main mode policy in the SPD.
Arguments:
pServerName - Server on which the main mode policy is to be
updated.
pszPolicyName - Name of the main mode policy to be updated.
pMMPolicy - New main mode policy which will replace the
existing policy.
Return Value:
ERROR_SUCCESS - Success.
Win32 Error - Failure.
--*/
{
DWORD dwError = 0;
PINIMMPOLICY pIniMMPolicy = NULL;
if (!pszPolicyName || !*pszPolicyName) {
return (ERROR_INVALID_PARAMETER);
}
//
// Validate main mode policy.
//
dwError = ValidateMMPolicy(
pMMPolicy
);
BAIL_ON_WIN32_ERROR(dwError);
ENTER_SPD_SECTION();
dwError = ValidateSecurity(
SPD_OBJECT_SERVER,
SERVER_ACCESS_ADMINISTER,
NULL,
NULL
);
BAIL_ON_LOCK_ERROR(dwError);
pIniMMPolicy = FindMMPolicy(
gpIniMMPolicy,
pszPolicyName
);
if (!pIniMMPolicy) {
dwError = ERROR_IPSEC_MM_POLICY_NOT_FOUND;
BAIL_ON_LOCK_ERROR(dwError);
}
if (memcmp(
&(pIniMMPolicy->gPolicyID),
&(pMMPolicy->gPolicyID),
sizeof(GUID))) {
dwError = ERROR_INVALID_PARAMETER;
BAIL_ON_LOCK_ERROR(dwError);
}
dwError = SetIniMMPolicy(
pIniMMPolicy,
pMMPolicy
);
BAIL_ON_LOCK_ERROR(dwError);
if (pIniMMPolicy->bIsPersisted) {
dwError = PersistMMPolicy(
pMMPolicy
);
BAIL_ON_LOCK_ERROR(dwError);
}
LEAVE_SPD_SECTION();
(VOID) IKENotifyPolicyChange(
&(pMMPolicy->gPolicyID),
POLICY_GUID_MM
);
return (dwError);
lock:
LEAVE_SPD_SECTION();
error:
return (dwError);
}
DWORD
GetMMPolicy(
LPWSTR pServerName,
LPWSTR pszPolicyName,
PIPSEC_MM_POLICY * ppMMPolicy
)
/*++
Routine Description:
This function gets a main mode policy from the SPD.
Arguments:
pServerName - Server from which to get the main mode policy.
pszPolicyName - Name of the main mode policy to get.
ppMMPolicy - Main mode policy found returned to the caller.
Return Value:
ERROR_SUCCESS - Success.
Win32 Error - Failure.
--*/
{
DWORD dwError = 0;
PINIMMPOLICY pIniMMPolicy = NULL;
PIPSEC_MM_POLICY pMMPolicy = NULL;
if (!pszPolicyName || !*pszPolicyName) {
dwError = ERROR_INVALID_PARAMETER;
BAIL_ON_WIN32_ERROR(dwError);
}
ENTER_SPD_SECTION();
dwError = ValidateSecurity(
SPD_OBJECT_SERVER,
SERVER_ACCESS_ADMINISTER,
NULL,
NULL
);
BAIL_ON_LOCK_ERROR(dwError);
pIniMMPolicy = FindMMPolicy(
gpIniMMPolicy,
pszPolicyName
);
if (!pIniMMPolicy) {
dwError = ERROR_IPSEC_MM_POLICY_NOT_FOUND;
BAIL_ON_LOCK_ERROR(dwError);
}
dwError = GetIniMMPolicy(
pIniMMPolicy,
&pMMPolicy
);
BAIL_ON_LOCK_ERROR(dwError);
*ppMMPolicy = pMMPolicy;
LEAVE_SPD_SECTION();
return (dwError);
lock:
LEAVE_SPD_SECTION();
error:
*ppMMPolicy = NULL;
return (dwError);
}
DWORD
SetIniMMPolicy(
PINIMMPOLICY pIniMMPolicy,
PIPSEC_MM_POLICY pMMPolicy
)
{
DWORD dwError = 0;
DWORD dwOfferCount = 0;
PIPSEC_MM_OFFER pOffers = NULL;
dwError = CreateIniMMOffers(
pMMPolicy->dwOfferCount,
pMMPolicy->pOffers,
&dwOfferCount,
&pOffers
);
BAIL_ON_WIN32_ERROR(dwError);
FreeIniMMOffers(
pIniMMPolicy->dwOfferCount,
pIniMMPolicy->pOffers
);
if ((pIniMMPolicy->dwFlags) & IPSEC_MM_POLICY_DEFAULT_POLICY) {
gpIniDefaultMMPolicy = NULL;
}
pIniMMPolicy->dwFlags = pMMPolicy->dwFlags;
pIniMMPolicy->uSoftSAExpirationTime = pMMPolicy->uSoftSAExpirationTime;
pIniMMPolicy->dwOfferCount = dwOfferCount;
pIniMMPolicy->pOffers = pOffers;
if ((pIniMMPolicy->dwFlags) & IPSEC_MM_POLICY_DEFAULT_POLICY) {
gpIniDefaultMMPolicy = pIniMMPolicy;
}
error:
return (dwError);
}
DWORD
GetIniMMPolicy(
PINIMMPOLICY pIniMMPolicy,
PIPSEC_MM_POLICY * ppMMPolicy
)
{
DWORD dwError = 0;
PIPSEC_MM_POLICY pMMPolicy = NULL;
dwError = SPDApiBufferAllocate(
sizeof(IPSEC_MM_POLICY),
&pMMPolicy
);
BAIL_ON_WIN32_ERROR(dwError);
dwError = CopyMMPolicy(
pIniMMPolicy,
pMMPolicy
);
BAIL_ON_WIN32_ERROR(dwError);
*ppMMPolicy = pMMPolicy;
return (dwError);
error:
if (pMMPolicy) {
SPDApiBufferFree(pMMPolicy);
}
*ppMMPolicy = NULL;
return (dwError);
}
DWORD
CopyMMPolicy(
PINIMMPOLICY pIniMMPolicy,
PIPSEC_MM_POLICY pMMPolicy
)
{
DWORD dwError = 0;
memcpy(
&(pMMPolicy->gPolicyID),
&(pIniMMPolicy->gPolicyID),
sizeof(GUID)
);
dwError = SPDApiBufferAllocate(
wcslen(pIniMMPolicy->pszPolicyName)*sizeof(WCHAR)
+ sizeof(WCHAR),
&(pMMPolicy->pszPolicyName)
);
BAIL_ON_WIN32_ERROR(dwError);
wcscpy(pMMPolicy->pszPolicyName, pIniMMPolicy->pszPolicyName);
pMMPolicy->dwFlags = pIniMMPolicy->dwFlags;
pMMPolicy->uSoftSAExpirationTime = pIniMMPolicy->uSoftSAExpirationTime;
dwError = CreateMMOffers(
pIniMMPolicy->dwOfferCount,
pIniMMPolicy->pOffers,
&(pMMPolicy->dwOfferCount),
&(pMMPolicy->pOffers)
);
BAIL_ON_WIN32_ERROR(dwError);
return (dwError);
error:
if (pMMPolicy->pszPolicyName) {
SPDApiBufferFree(pMMPolicy->pszPolicyName);
}
return (dwError);
}
DWORD
CreateMMOffers(
DWORD dwInOfferCount,
PIPSEC_MM_OFFER pInOffers,
PDWORD pdwOfferCount,
PIPSEC_MM_OFFER * ppOffers
)
{
DWORD dwError = 0;
PIPSEC_MM_OFFER pOffers = NULL;
PIPSEC_MM_OFFER pTemp = NULL;
PIPSEC_MM_OFFER pInTempOffer = NULL;
DWORD i = 0;
//
// Offer count and the offers themselves have already been validated.
//
dwError = SPDApiBufferAllocate(
sizeof(IPSEC_MM_OFFER) * dwInOfferCount,
&(pOffers)
);
BAIL_ON_WIN32_ERROR(dwError);
pTemp = pOffers;
pInTempOffer = pInOffers;
for (i = 0; i < dwInOfferCount; i++) {
memcpy(
&(pTemp->Lifetime),
&(pInTempOffer->Lifetime),
sizeof(KEY_LIFETIME)
);
pTemp->dwFlags = pInTempOffer->dwFlags;
pTemp->dwQuickModeLimit = pInTempOffer->dwQuickModeLimit;
pTemp->dwDHGroup = pInTempOffer->dwDHGroup;
memcpy(
&(pTemp->EncryptionAlgorithm),
&(pInTempOffer->EncryptionAlgorithm),
sizeof(IPSEC_MM_ALGO)
);
memcpy(
&(pTemp->HashingAlgorithm),
&(pInTempOffer->HashingAlgorithm),
sizeof(IPSEC_MM_ALGO)
);
pInTempOffer++;
pTemp++;
}
*pdwOfferCount = dwInOfferCount;
*ppOffers = pOffers;
return (dwError);
error:
if (pOffers) {
FreeMMOffers(
i,
pOffers
);
}
*pdwOfferCount = 0;
*ppOffers = NULL;
return (dwError);
}
DWORD
DeleteIniMMPolicy(
PINIMMPOLICY pIniMMPolicy
)
{
DWORD dwError = 0;
PINIMMPOLICY * ppTemp = NULL;
ppTemp = &gpIniMMPolicy;
while (*ppTemp) {
if (*ppTemp == pIniMMPolicy) {
break;
}
ppTemp = &((*ppTemp)->pNext);
}
if (*ppTemp) {
*ppTemp = pIniMMPolicy->pNext;
}
if ((pIniMMPolicy->dwFlags) & IPSEC_MM_POLICY_DEFAULT_POLICY) {
gpIniDefaultMMPolicy = NULL;
}
FreeIniMMPolicy(pIniMMPolicy);
return (dwError);
}
VOID
FreeMMOffers(
DWORD dwOfferCount,
PIPSEC_MM_OFFER pOffers
)
{
if (pOffers) {
SPDApiBufferFree(pOffers);
}
}
VOID
FreeIniMMPolicyList(
PINIMMPOLICY pIniMMPolicyList
)
{
PINIMMPOLICY pTemp = NULL;
PINIMMPOLICY pIniMMPolicy = NULL;
pTemp = pIniMMPolicyList;
while (pTemp) {
pIniMMPolicy = pTemp;
pTemp = pTemp->pNext;
FreeIniMMPolicy(pIniMMPolicy);
}
}
PINIMMPOLICY
FindMMPolicyByGuid(
PINIMMPOLICY pIniMMPolicyList,
GUID gPolicyID
)
{
DWORD dwError = 0;
PINIMMPOLICY pTemp = NULL;
pTemp = pIniMMPolicyList;
while (pTemp) {
if (!memcmp(&(pTemp->gPolicyID), &gPolicyID, sizeof(GUID))) {
return (pTemp);
}
pTemp = pTemp->pNext;
}
return (NULL);
}
VOID
FreeMMPolicies(
DWORD dwNumMMPolicies,
PIPSEC_MM_POLICY pMMPolicies
)
{
DWORD i = 0;
if (pMMPolicies) {
for (i = 0; i < dwNumMMPolicies; i++) {
if (pMMPolicies[i].pszPolicyName) {
SPDApiBufferFree(pMMPolicies[i].pszPolicyName);
}
FreeMMOffers(
pMMPolicies[i].dwOfferCount,
pMMPolicies[i].pOffers
);
}
SPDApiBufferFree(pMMPolicies);
}
}
DWORD
GetMMPolicyByID(
LPWSTR pServerName,
GUID gMMPolicyID,
PIPSEC_MM_POLICY * ppMMPolicy
)
/*++
Routine Description:
This function gets a main mode policy from the SPD.
Arguments:
pServerName - Server from which to get the main mode policy.
gMMPolicyID - Guid of the main mode policy to get.
ppMMPolicy - Main mode policy found returned to the caller.
Return Value:
ERROR_SUCCESS - Success.
Win32 Error - Failure.
--*/
{
DWORD dwError = 0;
PINIMMPOLICY pIniMMPolicy = NULL;
PIPSEC_MM_POLICY pMMPolicy = NULL;
ENTER_SPD_SECTION();
dwError = ValidateSecurity(
SPD_OBJECT_SERVER,
SERVER_ACCESS_ADMINISTER,
NULL,
NULL
);
BAIL_ON_LOCK_ERROR(dwError);
pIniMMPolicy = FindMMPolicyByGuid(
gpIniMMPolicy,
gMMPolicyID
);
if (!pIniMMPolicy) {
dwError = ERROR_IPSEC_MM_POLICY_NOT_FOUND;
BAIL_ON_LOCK_ERROR(dwError);
}
dwError = GetIniMMPolicy(
pIniMMPolicy,
&pMMPolicy
);
BAIL_ON_LOCK_ERROR(dwError);
*ppMMPolicy = pMMPolicy;
LEAVE_SPD_SECTION();
return (dwError);
lock:
LEAVE_SPD_SECTION();
*ppMMPolicy = NULL;
return (dwError);
}
DWORD
LocateMMPolicy(
PMM_FILTER pMMFilter,
PINIMMPOLICY * ppIniMMPolicy
)
{
DWORD dwError = 0;
PINIMMPOLICY pIniMMPolicy = NULL;
if ((pMMFilter->dwFlags) & IPSEC_MM_POLICY_DEFAULT_POLICY) {
if (!gpIniDefaultMMPolicy) {
dwError = ERROR_IPSEC_DEFAULT_MM_POLICY_NOT_FOUND;
BAIL_ON_WIN32_ERROR(dwError);
}
pIniMMPolicy = gpIniDefaultMMPolicy;
}
else {
pIniMMPolicy = FindMMPolicyByGuid(
gpIniMMPolicy,
pMMFilter->gPolicyID
);
if (!pIniMMPolicy) {
dwError = ERROR_IPSEC_MM_POLICY_NOT_FOUND;
BAIL_ON_WIN32_ERROR(dwError);
}
}
*ppIniMMPolicy = pIniMMPolicy;
return (dwError);
error:
*ppIniMMPolicy = NULL;
return (dwError);
}