|
|
/*++
Copyright (c) 1999 Microsoft Corporation
Module Name:
qm-policy.c
Abstract:
Author:
Environment: User Mode
Revision History:
--*/
#include "precomp.h"
DWORD AddQMPolicy( LPWSTR pServerName, DWORD dwFlags, PIPSEC_QM_POLICY pQMPolicy ) /*++
Routine Description:
This function adds a quick mode policy to the SPD.
Arguments:
pServerName - Server on which the quick mode policy is to be added.
pQMPolicy - Quick mode policy to be added.
Return Value:
ERROR_SUCCESS - Success.
Win32 Error - Failure.
--*/ { DWORD dwError = 0; PINIQMPOLICY pIniQMPolicy = NULL; BOOL bPersist = FALSE;
bPersist = (BOOL) (dwFlags & PERSIST_SPD_OBJECT);
//
// Validate the quick mode policy.
//
dwError = ValidateQMPolicy( pQMPolicy ); BAIL_ON_WIN32_ERROR(dwError);
ENTER_SPD_SECTION();
dwError = ValidateSecurity( SPD_OBJECT_SERVER, SERVER_ACCESS_ADMINISTER, NULL, NULL ); BAIL_ON_LOCK_ERROR(dwError);
pIniQMPolicy = FindQMPolicy( gpIniQMPolicy, pQMPolicy->pszPolicyName ); if (pIniQMPolicy) { dwError = ERROR_IPSEC_QM_POLICY_EXISTS; BAIL_ON_LOCK_ERROR(dwError); }
pIniQMPolicy = FindQMPolicyByGuid( gpIniQMPolicy, pQMPolicy->gPolicyID ); if (pIniQMPolicy) { dwError = ERROR_IPSEC_QM_POLICY_EXISTS; BAIL_ON_LOCK_ERROR(dwError); }
if (bPersist && !gbLoadingPersistence) { dwError = PersistQMPolicy( pQMPolicy ); BAIL_ON_LOCK_ERROR(dwError); }
dwError = CreateIniQMPolicy( pQMPolicy, &pIniQMPolicy ); BAIL_ON_LOCK_ERROR(dwError);
pIniQMPolicy->bIsPersisted = bPersist;
pIniQMPolicy->pNext = gpIniQMPolicy; gpIniQMPolicy = pIniQMPolicy;
if ((pIniQMPolicy->dwFlags) & IPSEC_QM_POLICY_DEFAULT_POLICY) { gpIniDefaultQMPolicy = pIniQMPolicy; }
LEAVE_SPD_SECTION();
return (dwError);
lock:
LEAVE_SPD_SECTION();
error:
if (pQMPolicy && bPersist && !gbLoadingPersistence) { (VOID) SPDPurgeQMPolicy( pQMPolicy->gPolicyID ); }
return (dwError); }
DWORD ValidateQMPolicy( PIPSEC_QM_POLICY pQMPolicy ) { DWORD dwError = 0;
if (!pQMPolicy) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_WIN32_ERROR(dwError); }
if (!(pQMPolicy->pszPolicyName) || !(*(pQMPolicy->pszPolicyName))) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_WIN32_ERROR(dwError); }
dwError = ValidateQMOffers( pQMPolicy->dwOfferCount, pQMPolicy->pOffers ); BAIL_ON_WIN32_ERROR(dwError);
error:
return (dwError); }
DWORD ValidateQMOffers( DWORD dwOfferCount, PIPSEC_QM_OFFER pOffers ) { DWORD dwError = 0; DWORD i = 0; PIPSEC_QM_OFFER pTemp = NULL; DWORD j = 0; BOOL bAH = FALSE; BOOL bESP = FALSE; DWORD dwQMGroup = PFS_GROUP_NONE;
if (!dwOfferCount || !pOffers || (dwOfferCount > IPSEC_MAX_QM_OFFERS)) { 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;
if (pTemp->bPFSRequired) { if ((pTemp->dwPFSGroup != PFS_GROUP_1) && (pTemp->dwPFSGroup != PFS_GROUP_2) && (pTemp->dwPFSGroup != PFS_GROUP_MM)) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_WIN32_ERROR(dwError); } dwQMGroup=pTemp->dwPFSGroup; } else { if (pTemp->dwPFSGroup != PFS_GROUP_NONE) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_WIN32_ERROR(dwError); } }
for (i = 0; i < dwOfferCount; i++) { if (dwQMGroup) { if ((!pTemp->bPFSRequired) || (pTemp->dwPFSGroup != dwQMGroup)) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_WIN32_ERROR(dwError); } } else { if ((pTemp->bPFSRequired) || (pTemp->dwPFSGroup != PFS_GROUP_NONE)) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_WIN32_ERROR(dwError); } }
if (!(pTemp->dwNumAlgos) || (pTemp->dwNumAlgos > QM_MAX_ALGOS)) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_WIN32_ERROR(dwError); }
bAH = FALSE; bESP = FALSE;
for (j = 0; j < (pTemp->dwNumAlgos); j++) {
switch (pTemp->Algos[j].Operation) {
case AUTHENTICATION: if (bAH) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_WIN32_ERROR(dwError); } if ((pTemp->Algos[j].uAlgoIdentifier == IPSEC_DOI_AH_NONE) || (pTemp->Algos[j].uAlgoIdentifier >= IPSEC_DOI_AH_MAX)) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_WIN32_ERROR(dwError); } if (pTemp->Algos[j].uSecAlgoIdentifier != HMAC_AH_NONE) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_WIN32_ERROR(dwError); } bAH = TRUE; break;
case ENCRYPTION: if (bESP) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_WIN32_ERROR(dwError); } if (pTemp->Algos[j].uAlgoIdentifier >= IPSEC_DOI_ESP_MAX) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_WIN32_ERROR(dwError); } if (pTemp->Algos[j].uSecAlgoIdentifier >= HMAC_AH_MAX) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_WIN32_ERROR(dwError); } if (pTemp->Algos[j].uAlgoIdentifier == IPSEC_DOI_ESP_NONE) { if (pTemp->Algos[j].uSecAlgoIdentifier == HMAC_AH_NONE) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_WIN32_ERROR(dwError); } } bESP = TRUE; break;
case NONE: case COMPRESSION: default: dwError = ERROR_INVALID_PARAMETER; BAIL_ON_WIN32_ERROR(dwError); break;
}
}
pTemp++;
}
error:
return (dwError); }
DWORD CreateIniQMPolicy( PIPSEC_QM_POLICY pQMPolicy, PINIQMPOLICY * ppIniQMPolicy ) { DWORD dwError = 0; PINIQMPOLICY pIniQMPolicy = NULL;
dwError = AllocateSPDMemory( sizeof(INIQMPOLICY), &pIniQMPolicy ); BAIL_ON_WIN32_ERROR(dwError);
memcpy( &(pIniQMPolicy->gPolicyID), &(pQMPolicy->gPolicyID), sizeof(GUID) );
dwError = AllocateSPDString( pQMPolicy->pszPolicyName, &(pIniQMPolicy->pszPolicyName) ); BAIL_ON_WIN32_ERROR(dwError);
pIniQMPolicy->cRef = 0; pIniQMPolicy->bIsPersisted = FALSE;
pIniQMPolicy->dwFlags = pQMPolicy->dwFlags; pIniQMPolicy->pNext = NULL;
dwError = CreateIniQMOffers( pQMPolicy->dwOfferCount, pQMPolicy->pOffers, &(pIniQMPolicy->dwOfferCount), &(pIniQMPolicy->pOffers) ); BAIL_ON_WIN32_ERROR(dwError);
*ppIniQMPolicy = pIniQMPolicy; return (dwError);
error:
if (pIniQMPolicy) { FreeIniQMPolicy( pIniQMPolicy ); }
*ppIniQMPolicy = NULL; return (dwError); }
DWORD CreateIniQMOffers( DWORD dwInOfferCount, PIPSEC_QM_OFFER pInOffers, PDWORD pdwOfferCount, PIPSEC_QM_OFFER * ppOffers ) { DWORD dwError = 0; PIPSEC_QM_OFFER pOffers = NULL; PIPSEC_QM_OFFER pTemp = NULL; PIPSEC_QM_OFFER pInTempOffer = NULL; DWORD i = 0; DWORD j = 0;
//
// Offer count and the offers themselves have already been validated.
//
dwError = AllocateSPDMemory( sizeof(IPSEC_QM_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->bPFSRequired = pInTempOffer->bPFSRequired; pTemp->dwPFSGroup = pInTempOffer->dwPFSGroup; pTemp->dwNumAlgos = pInTempOffer->dwNumAlgos;
for (j = 0; j < (pInTempOffer->dwNumAlgos); j++) { memcpy( &(pTemp->Algos[j]), &(pInTempOffer->Algos[j]), sizeof(IPSEC_QM_ALGO) ); }
pInTempOffer++; pTemp++;
}
*pdwOfferCount = dwInOfferCount; *ppOffers = pOffers; return (dwError);
error:
if (pOffers) { FreeIniQMOffers( i, pOffers ); }
*pdwOfferCount = 0; *ppOffers = NULL; return (dwError); }
VOID FreeIniQMPolicy( PINIQMPOLICY pIniQMPolicy ) { if (pIniQMPolicy) {
if (pIniQMPolicy->pszPolicyName) { FreeSPDString(pIniQMPolicy->pszPolicyName); }
FreeIniQMOffers( pIniQMPolicy->dwOfferCount, pIniQMPolicy->pOffers );
FreeSPDMemory(pIniQMPolicy);
} }
VOID FreeIniQMOffers( DWORD dwOfferCount, PIPSEC_QM_OFFER pOffers ) { if (pOffers) { FreeSPDMemory(pOffers); } }
PINIQMPOLICY FindQMPolicy( PINIQMPOLICY pIniQMPolicyList, LPWSTR pszPolicyName ) { DWORD dwError = 0; PINIQMPOLICY pTemp = NULL;
pTemp = pIniQMPolicyList;
while (pTemp) {
if (!_wcsicmp(pTemp->pszPolicyName, pszPolicyName)) { return (pTemp); } pTemp = pTemp->pNext;
}
return (NULL); }
DWORD DeleteQMPolicy( LPWSTR pServerName, LPWSTR pszPolicyName ) /*++
Routine Description:
This function deletes a quick mode policy from the SPD.
Arguments:
pServerName - Server on which the quick mode policy is to be deleted.
pszPolicyName - Quick mode policy to be deleted.
Return Value:
ERROR_SUCCESS - Success.
Win32 Error - Failure.
--*/ { DWORD dwError = 0; PINIQMPOLICY pIniQMPolicy = 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);
pIniQMPolicy = FindQMPolicy( gpIniQMPolicy, pszPolicyName ); if (!pIniQMPolicy) { dwError = ERROR_IPSEC_QM_POLICY_NOT_FOUND; BAIL_ON_LOCK_ERROR(dwError); }
if (pIniQMPolicy->cRef) { dwError = ERROR_IPSEC_QM_POLICY_IN_USE; memcpy(&gPolicyID, &pIniQMPolicy->gPolicyID, sizeof(GUID)); BAIL_ON_LOCK_ERROR(dwError); }
memcpy(&gPolicyID, &pIniQMPolicy->gPolicyID, sizeof(GUID));
if (pIniQMPolicy->bIsPersisted) { dwError = SPDPurgeQMPolicy( gPolicyID ); BAIL_ON_LOCK_ERROR(dwError); }
dwError = DeleteIniQMPolicy( pIniQMPolicy ); BAIL_ON_LOCK_ERROR(dwError);
LEAVE_SPD_SECTION();
if (gbIKENotify) { (VOID) IKENotifyPolicyChange( &(gPolicyID), POLICY_GUID_QM ); }
return (dwError);
lock:
LEAVE_SPD_SECTION();
if ((dwError == ERROR_IPSEC_QM_POLICY_IN_USE) && gbIKENotify) { (VOID) IKENotifyPolicyChange( &(gPolicyID), POLICY_GUID_QM ); }
return (dwError); }
DWORD EnumQMPolicies( LPWSTR pServerName, PIPSEC_QM_POLICY * ppQMPolicies, DWORD dwPreferredNumEntries, LPDWORD pdwNumPolicies, LPDWORD pdwResumeHandle ) /*++
Routine Description:
This function enumerates quick mode policies from the SPD.
Arguments:
pServerName - Server on which the quick mode policies are to be enumerated.
ppQMPolicies - Enumerated quick mode policies returned to the caller.
dwPreferredNumEntries - Preferred number of enumeration entries.
pdwNumPolicies - Number of quick mode policies actually enumerated.
pdwResumeHandle - Handle to the location in the quick 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; PINIQMPOLICY pIniQMPolicy = NULL; DWORD i = 0; PINIQMPOLICY pTemp = NULL; DWORD dwNumPolicies = 0; PIPSEC_QM_POLICY pQMPolicies = NULL; PIPSEC_QM_POLICY pQMPolicy = NULL;
dwResumeHandle = *pdwResumeHandle;
if (!dwPreferredNumEntries || (dwPreferredNumEntries > MAX_QMPOLICY_ENUM_COUNT)) { dwNumToEnum = MAX_QMPOLICY_ENUM_COUNT; } else { dwNumToEnum = dwPreferredNumEntries; }
ENTER_SPD_SECTION();
dwError = ValidateSecurity( SPD_OBJECT_SERVER, SERVER_ACCESS_ADMINISTER, NULL, NULL ); BAIL_ON_LOCK_ERROR(dwError);
pIniQMPolicy = gpIniQMPolicy;
for (i = 0; (i < dwResumeHandle) && (pIniQMPolicy != NULL); i++) { pIniQMPolicy = pIniQMPolicy->pNext; }
if (!pIniQMPolicy) { dwError = ERROR_NO_DATA; BAIL_ON_LOCK_ERROR(dwError); }
pTemp = pIniQMPolicy;
while (pTemp && (dwNumPolicies < dwNumToEnum)) { dwNumPolicies++; pTemp = pTemp->pNext; }
dwError = SPDApiBufferAllocate( sizeof(IPSEC_QM_POLICY)*dwNumPolicies, &pQMPolicies ); BAIL_ON_LOCK_ERROR(dwError);
pTemp = pIniQMPolicy; pQMPolicy = pQMPolicies;
for (i = 0; i < dwNumPolicies; i++) {
dwError = CopyQMPolicy( pTemp, pQMPolicy ); BAIL_ON_LOCK_ERROR(dwError);
pTemp = pTemp->pNext; pQMPolicy++;
}
*ppQMPolicies = pQMPolicies; *pdwResumeHandle = dwResumeHandle + dwNumPolicies; *pdwNumPolicies = dwNumPolicies;
LEAVE_SPD_SECTION(); return (dwError);
lock:
LEAVE_SPD_SECTION();
if (pQMPolicies) { FreeQMPolicies( i, pQMPolicies ); }
*ppQMPolicies = NULL; *pdwResumeHandle = dwResumeHandle; *pdwNumPolicies = 0;
return (dwError); }
DWORD SetQMPolicy( LPWSTR pServerName, LPWSTR pszPolicyName, PIPSEC_QM_POLICY pQMPolicy ) /*++
Routine Description:
This function updates a quick mode policy in the SPD.
Arguments:
pServerName - Server on which the quick mode policy is to be updated.
pszPolicyName - Name of the quick mode policy to be updated.
pQMPolicy - New quick mode policy which will replace the existing policy.
Return Value:
ERROR_SUCCESS - Success.
Win32 Error - Failure.
--*/ { DWORD dwError = 0; PINIQMPOLICY pIniQMPolicy = NULL;
if (!pszPolicyName || !*pszPolicyName) { return (ERROR_INVALID_PARAMETER); } //
// Validate quick mode policy.
//
dwError = ValidateQMPolicy( pQMPolicy ); BAIL_ON_WIN32_ERROR(dwError);
ENTER_SPD_SECTION();
dwError = ValidateSecurity( SPD_OBJECT_SERVER, SERVER_ACCESS_ADMINISTER, NULL, NULL ); BAIL_ON_LOCK_ERROR(dwError);
pIniQMPolicy = FindQMPolicy( gpIniQMPolicy, pszPolicyName ); if (!pIniQMPolicy) { dwError = ERROR_IPSEC_QM_POLICY_NOT_FOUND; BAIL_ON_LOCK_ERROR(dwError); }
if (memcmp( &(pIniQMPolicy->gPolicyID), &(pQMPolicy->gPolicyID), sizeof(GUID))) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_LOCK_ERROR(dwError); }
dwError = SetIniQMPolicy( pIniQMPolicy, pQMPolicy ); BAIL_ON_LOCK_ERROR(dwError);
if (pIniQMPolicy->bIsPersisted) { dwError = PersistQMPolicy( pQMPolicy ); BAIL_ON_LOCK_ERROR(dwError); }
LEAVE_SPD_SECTION();
(VOID) IKENotifyPolicyChange( &(pQMPolicy->gPolicyID), POLICY_GUID_QM );
return (dwError);
lock:
LEAVE_SPD_SECTION();
error:
return (dwError); }
DWORD GetQMPolicy( LPWSTR pServerName, LPWSTR pszPolicyName, PIPSEC_QM_POLICY * ppQMPolicy ) /*++
Routine Description:
This function gets a quick mode policy from the SPD.
Arguments:
pServerName - Server from which to get the quick mode policy.
pszPolicyName - Name of the quick mode policy to get.
ppQMPolicy - Quick mode policy found returned to the caller.
Return Value:
ERROR_SUCCESS - Success.
Win32 Error - Failure.
--*/ { DWORD dwError = 0; PINIQMPOLICY pIniQMPolicy = NULL; PIPSEC_QM_POLICY pQMPolicy = 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);
pIniQMPolicy = FindQMPolicy( gpIniQMPolicy, pszPolicyName ); if (!pIniQMPolicy) { dwError = ERROR_IPSEC_QM_POLICY_NOT_FOUND; BAIL_ON_LOCK_ERROR(dwError); }
dwError = GetIniQMPolicy( pIniQMPolicy, &pQMPolicy ); BAIL_ON_LOCK_ERROR(dwError);
*ppQMPolicy = pQMPolicy;
LEAVE_SPD_SECTION(); return (dwError);
lock:
LEAVE_SPD_SECTION();
error:
*ppQMPolicy = NULL; return (dwError); }
DWORD SetIniQMPolicy( PINIQMPOLICY pIniQMPolicy, PIPSEC_QM_POLICY pQMPolicy ) { DWORD dwError = 0; DWORD dwOfferCount = 0; PIPSEC_QM_OFFER pOffers = NULL;
dwError = CreateIniQMOffers( pQMPolicy->dwOfferCount, pQMPolicy->pOffers, &dwOfferCount, &pOffers ); BAIL_ON_WIN32_ERROR(dwError);
FreeIniQMOffers( pIniQMPolicy->dwOfferCount, pIniQMPolicy->pOffers ); if ((pIniQMPolicy->dwFlags) & IPSEC_QM_POLICY_DEFAULT_POLICY) { gpIniDefaultQMPolicy = NULL; }
pIniQMPolicy->dwFlags = pQMPolicy->dwFlags; pIniQMPolicy->dwOfferCount = dwOfferCount; pIniQMPolicy->pOffers = pOffers;
if ((pIniQMPolicy->dwFlags) & IPSEC_QM_POLICY_DEFAULT_POLICY) { gpIniDefaultQMPolicy = pIniQMPolicy; }
error:
return (dwError); }
DWORD GetIniQMPolicy( PINIQMPOLICY pIniQMPolicy, PIPSEC_QM_POLICY * ppQMPolicy ) { DWORD dwError = 0; PIPSEC_QM_POLICY pQMPolicy = NULL;
dwError = SPDApiBufferAllocate( sizeof(IPSEC_QM_POLICY), &pQMPolicy ); BAIL_ON_WIN32_ERROR(dwError);
dwError = CopyQMPolicy( pIniQMPolicy, pQMPolicy ); BAIL_ON_WIN32_ERROR(dwError);
*ppQMPolicy = pQMPolicy; return (dwError);
error:
if (pQMPolicy) { SPDApiBufferFree(pQMPolicy); }
*ppQMPolicy = NULL; return (dwError); }
DWORD CopyQMPolicy( PINIQMPOLICY pIniQMPolicy, PIPSEC_QM_POLICY pQMPolicy ) { DWORD dwError = 0;
memcpy( &(pQMPolicy->gPolicyID), &(pIniQMPolicy->gPolicyID), sizeof(GUID) );
dwError = SPDApiBufferAllocate( wcslen(pIniQMPolicy->pszPolicyName)*sizeof(WCHAR) + sizeof(WCHAR), &(pQMPolicy->pszPolicyName) ); BAIL_ON_WIN32_ERROR(dwError);
wcscpy(pQMPolicy->pszPolicyName, pIniQMPolicy->pszPolicyName); pQMPolicy->dwFlags = pIniQMPolicy->dwFlags;
dwError = CreateQMOffers( pIniQMPolicy->dwOfferCount, pIniQMPolicy->pOffers, &(pQMPolicy->dwOfferCount), &(pQMPolicy->pOffers) ); BAIL_ON_WIN32_ERROR(dwError);
return (dwError);
error:
if (pQMPolicy->pszPolicyName) { SPDApiBufferFree(pQMPolicy->pszPolicyName); }
return (dwError); }
DWORD CreateQMOffers( DWORD dwInOfferCount, PIPSEC_QM_OFFER pInOffers, PDWORD pdwOfferCount, PIPSEC_QM_OFFER * ppOffers ) { DWORD dwError = 0; PIPSEC_QM_OFFER pOffers = NULL; PIPSEC_QM_OFFER pTemp = NULL; PIPSEC_QM_OFFER pInTempOffer = NULL; DWORD i = 0; DWORD j = 0; DWORD k = 0;
//
// Offer count and the offers themselves have already been validated.
//
dwError = SPDApiBufferAllocate( sizeof(IPSEC_QM_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->bPFSRequired = pInTempOffer->bPFSRequired; pTemp->dwPFSGroup = pInTempOffer->dwPFSGroup; pTemp->dwNumAlgos = pInTempOffer->dwNumAlgos;
for (j = 0; j < (pInTempOffer->dwNumAlgos); j++) { memcpy( &(pTemp->Algos[j]), &(pInTempOffer->Algos[j]), sizeof(IPSEC_QM_ALGO) ); }
for (k = j; k < QM_MAX_ALGOS; k++) { memset(&(pTemp->Algos[k]), 0, sizeof(IPSEC_QM_ALGO)); }
pInTempOffer++; pTemp++;
}
*pdwOfferCount = dwInOfferCount; *ppOffers = pOffers; return (dwError);
error:
if (pOffers) { FreeQMOffers( i, pOffers ); }
*pdwOfferCount = 0; *ppOffers = NULL; return (dwError); }
DWORD DeleteIniQMPolicy( PINIQMPOLICY pIniQMPolicy ) { DWORD dwError = 0; PINIQMPOLICY * ppTemp = NULL;
ppTemp = &gpIniQMPolicy;
while (*ppTemp) {
if (*ppTemp == pIniQMPolicy) { break; } ppTemp = &((*ppTemp)->pNext);
}
if (*ppTemp) { *ppTemp = pIniQMPolicy->pNext; }
if ((pIniQMPolicy->dwFlags) & IPSEC_QM_POLICY_DEFAULT_POLICY) { gpIniDefaultQMPolicy = NULL; }
FreeIniQMPolicy(pIniQMPolicy);
return (dwError); }
VOID FreeQMOffers( DWORD dwOfferCount, PIPSEC_QM_OFFER pOffers ) { if (pOffers) { SPDApiBufferFree(pOffers); } }
VOID FreeIniQMPolicyList( PINIQMPOLICY pIniQMPolicyList ) { PINIQMPOLICY pTemp = NULL; PINIQMPOLICY pIniQMPolicy = NULL;
pTemp = pIniQMPolicyList;
while (pTemp) {
pIniQMPolicy = pTemp; pTemp = pTemp->pNext;
FreeIniQMPolicy(pIniQMPolicy);
} }
PINIQMPOLICY FindQMPolicyByGuid( PINIQMPOLICY pIniQMPolicyList, GUID gPolicyID ) { DWORD dwError = 0; PINIQMPOLICY pTemp = NULL;
pTemp = pIniQMPolicyList;
while (pTemp) {
if (!memcmp(&(pTemp->gPolicyID), &gPolicyID, sizeof(GUID))) { return (pTemp); } pTemp = pTemp->pNext;
}
return (NULL); }
VOID FreeQMPolicies( DWORD dwNumQMPolicies, PIPSEC_QM_POLICY pQMPolicies ) { DWORD i = 0;
if (pQMPolicies) {
for (i = 0; i < dwNumQMPolicies; i++) {
if (pQMPolicies[i].pszPolicyName) { SPDApiBufferFree(pQMPolicies[i].pszPolicyName); }
FreeQMOffers( pQMPolicies[i].dwOfferCount, pQMPolicies[i].pOffers );
}
SPDApiBufferFree(pQMPolicies);
}
}
DWORD GetQMPolicyByID( LPWSTR pServerName, GUID gQMPolicyID, PIPSEC_QM_POLICY * ppQMPolicy ) /*++
Routine Description:
This function gets a quick mode policy from the SPD.
Arguments:
pServerName - Server from which to get the quick mode policy.
gQMFilter - Guid of the quick mode policy to get.
ppQMPolicy - Quick mode policy found returned to the caller.
Return Value:
ERROR_SUCCESS - Success.
Win32 Error - Failure.
--*/ { DWORD dwError = 0; PINIQMPOLICY pIniQMPolicy = NULL; PIPSEC_QM_POLICY pQMPolicy = NULL;
ENTER_SPD_SECTION();
dwError = ValidateSecurity( SPD_OBJECT_SERVER, SERVER_ACCESS_ADMINISTER, NULL, NULL ); BAIL_ON_LOCK_ERROR(dwError);
pIniQMPolicy = FindQMPolicyByGuid( gpIniQMPolicy, gQMPolicyID ); if (!pIniQMPolicy) { dwError = ERROR_IPSEC_QM_POLICY_NOT_FOUND; BAIL_ON_LOCK_ERROR(dwError); }
dwError = GetIniQMPolicy( pIniQMPolicy, &pQMPolicy ); BAIL_ON_LOCK_ERROR(dwError);
*ppQMPolicy = pQMPolicy;
LEAVE_SPD_SECTION(); return (dwError);
lock:
LEAVE_SPD_SECTION();
*ppQMPolicy = NULL; return (dwError); }
DWORD LocateQMPolicy( DWORD dwFlags, GUID gPolicyID, PINIQMPOLICY * ppIniQMPolicy ) { DWORD dwError = 0; PINIQMPOLICY pIniQMPolicy = NULL;
if (dwFlags & IPSEC_QM_POLICY_DEFAULT_POLICY) {
if (!gpIniDefaultQMPolicy) { dwError = ERROR_IPSEC_DEFAULT_QM_POLICY_NOT_FOUND; BAIL_ON_WIN32_ERROR(dwError); } pIniQMPolicy = gpIniDefaultQMPolicy;
} else {
pIniQMPolicy = FindQMPolicyByGuid( gpIniQMPolicy, gPolicyID ); if (!pIniQMPolicy) { dwError = ERROR_IPSEC_QM_POLICY_NOT_FOUND; BAIL_ON_WIN32_ERROR(dwError); }
}
*ppIniQMPolicy = pIniQMPolicy; return (dwError);
error:
*ppIniQMPolicy = NULL; return (dwError);
}
|