1187 lines
33 KiB
C++
1187 lines
33 KiB
C++
/////////////////////////////////////////////////////////////
|
|
// Copyright(c) 1998, Microsoft Corporation
|
|
//
|
|
// useparpc.cpp
|
|
//
|
|
// Created on 8/15/98 by Randyram
|
|
// Revisions:
|
|
// 2/29/00 - DKalin
|
|
// Removed out-of-date PA RPC routines, added Ipsecpol service management
|
|
//
|
|
// This holds all the init and cleanup code for using the
|
|
// SPD API and for using SCM for controlling PA and ipsecpolsvc
|
|
// see usepa.h for usage
|
|
//
|
|
/////////////////////////////////////////////////////////////
|
|
|
|
#include "ipseccmd.h"
|
|
|
|
const TCHAR szIpsecpolsvc[] = TEXT("ipsecpolsvc");
|
|
|
|
bool PAIsRunning(OUT DWORD &dwError, TCHAR *szServ)
|
|
{
|
|
bool bReturn = true;
|
|
dwError = ERROR_SUCCESS;
|
|
|
|
SERVICE_STATUS ServStat;
|
|
memset(&ServStat, 0, sizeof(SERVICE_STATUS));
|
|
|
|
SC_HANDLE schMan = OpenSCManager(szServ, NULL, SC_MANAGER_ALL_ACCESS);
|
|
|
|
if (schMan == NULL)
|
|
{
|
|
dwError = GetLastError();
|
|
bReturn = false;
|
|
}
|
|
else
|
|
{
|
|
SC_HANDLE schPA = OpenService(schMan, TEXT("policyagent"),
|
|
SERVICE_QUERY_STATUS | SERVICE_START | SERVICE_STOP);
|
|
if (schPA == NULL)
|
|
{
|
|
dwError = GetLastError();
|
|
bReturn = false;
|
|
}
|
|
else if (QueryServiceStatus(schPA, &ServStat))
|
|
{
|
|
// check the status finally
|
|
if (ServStat.dwCurrentState != SERVICE_RUNNING)
|
|
{
|
|
bReturn = false;
|
|
}
|
|
CloseServiceHandle(schPA);
|
|
}
|
|
CloseServiceHandle(schMan);
|
|
}
|
|
|
|
return bReturn;
|
|
}
|
|
|
|
bool StartPA(OUT DWORD &dwError, OPTIONAL TCHAR *szServ)
|
|
{
|
|
bool bReturn = true;
|
|
dwError = ERROR_SUCCESS;
|
|
|
|
SERVICE_STATUS ServStat;
|
|
memset(&ServStat, 0, sizeof(SERVICE_STATUS));
|
|
|
|
SC_HANDLE schMan = OpenSCManager(szServ, NULL, SC_MANAGER_ALL_ACCESS);
|
|
|
|
if (schMan == NULL)
|
|
{
|
|
dwError = GetLastError();
|
|
bReturn = false;
|
|
}
|
|
else
|
|
{
|
|
SC_HANDLE schPA = OpenService(schMan, TEXT("policyagent"),
|
|
SERVICE_QUERY_STATUS | SERVICE_START | SERVICE_STOP);
|
|
if (schPA == NULL)
|
|
{
|
|
dwError = GetLastError();
|
|
bReturn = false;
|
|
}
|
|
else if (QueryServiceStatus(schPA, &ServStat))
|
|
{
|
|
// check the status finally
|
|
if (ServStat.dwCurrentState != SERVICE_RUNNING)
|
|
{
|
|
if (!StartService(schPA, 0, NULL))
|
|
{
|
|
dwError = GetLastError();
|
|
bReturn = false;
|
|
}
|
|
}
|
|
CloseServiceHandle(schPA);
|
|
}
|
|
CloseServiceHandle(schMan);
|
|
}
|
|
|
|
return bReturn;
|
|
}
|
|
|
|
/*********************************************************************
|
|
FUNCTION: InstallIpsecpolService
|
|
PURPOSE: Installs ipsecpolsvc service (incl. copying .exe to system32 dir)
|
|
PARAMS:
|
|
pszFilename - name of the .exe file (full path recommended)
|
|
bFailIfExists - if TRUE, fail if service already exists,
|
|
if FALSE, stop service, delete it and proceed
|
|
( default = TRUE )
|
|
RETURNS: ERROR_SUCESS or GetLastError code
|
|
COMMENTS:
|
|
*********************************************************************/
|
|
DWORD InstallIpsecpolService (IN LPCTSTR pszFilename, IN OPTIONAL BOOL bFailIfExists)
|
|
{
|
|
DWORD dwReturn = ERROR_SUCCESS;
|
|
|
|
// open SCM Manager first
|
|
SC_HANDLE schMan = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
|
|
SC_HANDLE schIpsecpolsvc;
|
|
|
|
if (schMan == NULL)
|
|
{
|
|
dwReturn = GetLastError();
|
|
}
|
|
else
|
|
{
|
|
// OK, we have handle access to SCM manager
|
|
// if bFailIfExists == FALSE, let's check if service is running and stop it
|
|
if (!bFailIfExists)
|
|
{
|
|
if (IsIpsecpolServiceRunning(dwReturn))
|
|
{
|
|
dwReturn = StopIpsecpolService();
|
|
}
|
|
}
|
|
|
|
// continue only if we're okay so far
|
|
if (dwReturn != ERROR_SUCCESS)
|
|
{
|
|
CloseServiceHandle(schMan);
|
|
return dwReturn;
|
|
}
|
|
|
|
// now handle copyfile stuff
|
|
TCHAR pszDestination[MAX_PATH+1];
|
|
TCHAR* pszWindir = _tgetenv(TEXT("WINDIR"));
|
|
TCHAR* pTmp;
|
|
if (pszWindir == NULL || pszFilename == NULL || pszFilename[0] == 0)
|
|
{
|
|
CloseServiceHandle(schMan);
|
|
return ERROR_PATH_NOT_FOUND;
|
|
}
|
|
|
|
_tcscpy(pszDestination, pszWindir);
|
|
_tcscat(pszDestination, TEXT("\\system32\\"));
|
|
|
|
pTmp = (TCHAR*) _tcsrchr(pszFilename, TEXT('\\'));
|
|
if (pTmp == NULL)
|
|
{
|
|
_tcscat(pszDestination, pszFilename);
|
|
}
|
|
else
|
|
{
|
|
_tcscat(pszDestination, pTmp+1);
|
|
}
|
|
|
|
// now copy file
|
|
if (!CopyFile(pszFilename, pszDestination, FALSE))
|
|
{
|
|
CloseServiceHandle(schMan);
|
|
return GetLastError();
|
|
}
|
|
|
|
// now delete service if it already exists and bFailIfExists is FALSE
|
|
if (!bFailIfExists)
|
|
{
|
|
// check if it exists and try to delete
|
|
schIpsecpolsvc = OpenService(schMan, szIpsecpolsvc,
|
|
SERVICE_QUERY_STATUS | SERVICE_START | SERVICE_STOP | STANDARD_RIGHTS_REQUIRED );
|
|
if (schIpsecpolsvc == NULL)
|
|
{
|
|
dwReturn = GetLastError();
|
|
if (dwReturn == ERROR_INVALID_NAME || dwReturn == ERROR_SERVICE_DOES_NOT_EXIST)
|
|
{
|
|
// doesn't exist, continue normally
|
|
dwReturn = ERROR_SUCCESS;
|
|
}
|
|
else
|
|
{ // some real error
|
|
CloseServiceHandle(schMan);
|
|
return dwReturn;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// service exists, delete
|
|
DeleteService(schIpsecpolsvc);
|
|
CloseServiceHandle(schIpsecpolsvc);
|
|
}
|
|
|
|
}
|
|
|
|
// now create new service
|
|
schIpsecpolsvc = CreateService(schMan,
|
|
szIpsecpolsvc,
|
|
szIpsecpolsvc,
|
|
SERVICE_QUERY_STATUS | SERVICE_START | SERVICE_STOP | STANDARD_RIGHTS_REQUIRED,
|
|
SERVICE_WIN32_OWN_PROCESS,
|
|
SERVICE_DEMAND_START,
|
|
SERVICE_ERROR_NORMAL,
|
|
pszDestination,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL);
|
|
if (schIpsecpolsvc == NULL)
|
|
{
|
|
// some error
|
|
CloseServiceHandle(schMan);
|
|
return GetLastError();
|
|
}
|
|
CloseServiceHandle(schIpsecpolsvc);
|
|
CloseServiceHandle(schMan);
|
|
}
|
|
|
|
return dwReturn;
|
|
} /* InstallIpsecpolService */
|
|
|
|
/*********************************************************************
|
|
FUNCTION: StartIpsecpolService
|
|
PURPOSE: Attempts to start ipsecpolsvc service
|
|
PARAMS:
|
|
pszServ - optional name of the server (default is NULL, start on local machine)
|
|
RETURNS: ERROR_SUCESS or GetLastError code
|
|
COMMENTS:
|
|
*********************************************************************/
|
|
DWORD StartIpsecpolService (IN OPTIONAL LPCTSTR pszServ)
|
|
{
|
|
DWORD dwReturn = ERROR_SUCCESS;
|
|
|
|
SERVICE_STATUS ServStat;
|
|
memset(&ServStat, 0, sizeof(SERVICE_STATUS));
|
|
|
|
SC_HANDLE schMan = OpenSCManager(pszServ, NULL, SC_MANAGER_ALL_ACCESS);
|
|
|
|
if (schMan == NULL)
|
|
{
|
|
dwReturn = GetLastError();
|
|
}
|
|
else
|
|
{
|
|
SC_HANDLE schIpsecpolsvc = OpenService(schMan, szIpsecpolsvc,
|
|
SERVICE_QUERY_STATUS | SERVICE_START | SERVICE_STOP);
|
|
if (schIpsecpolsvc == NULL)
|
|
{
|
|
dwReturn = GetLastError();
|
|
}
|
|
else if (QueryServiceStatus(schIpsecpolsvc, &ServStat))
|
|
{
|
|
// check the status finally
|
|
if (ServStat.dwCurrentState != SERVICE_RUNNING)
|
|
{
|
|
if (!StartService(schIpsecpolsvc, 0, NULL))
|
|
{
|
|
dwReturn = GetLastError();
|
|
}
|
|
}
|
|
CloseServiceHandle(schIpsecpolsvc);
|
|
}
|
|
CloseServiceHandle(schMan);
|
|
}
|
|
|
|
return dwReturn;
|
|
} /* StartIpsecpolService */
|
|
|
|
/*********************************************************************
|
|
FUNCTION: StopIpsecpolService
|
|
PURPOSE: Attempts to stop ipsecpolsvc service
|
|
PARAMS:
|
|
pszServ - optional name of the server (default is NULL, start on local machine)
|
|
RETURNS: ERROR_SUCESS or GetLastError code
|
|
COMMENTS:
|
|
*********************************************************************/
|
|
DWORD StopIpsecpolService (IN OPTIONAL LPCTSTR pszServ)
|
|
{
|
|
DWORD dwReturn = ERROR_SUCCESS;
|
|
|
|
SERVICE_STATUS ServStat;
|
|
memset(&ServStat, 0, sizeof(SERVICE_STATUS));
|
|
|
|
SC_HANDLE schMan = OpenSCManager(pszServ, NULL, SC_MANAGER_ALL_ACCESS);
|
|
|
|
if (schMan == NULL)
|
|
{
|
|
dwReturn = GetLastError();
|
|
}
|
|
else
|
|
{
|
|
SC_HANDLE schIpsecpolsvc = OpenService(schMan, szIpsecpolsvc,
|
|
SERVICE_QUERY_STATUS | SERVICE_START | SERVICE_STOP);
|
|
if (schIpsecpolsvc == NULL)
|
|
{
|
|
dwReturn = GetLastError();
|
|
}
|
|
else if (QueryServiceStatus(schIpsecpolsvc, &ServStat))
|
|
{
|
|
// check the status finally
|
|
if (ServStat.dwCurrentState == SERVICE_RUNNING)
|
|
{
|
|
if (!ControlService(schIpsecpolsvc, SERVICE_CONTROL_STOP, &ServStat))
|
|
{
|
|
dwReturn = GetLastError();
|
|
}
|
|
}
|
|
CloseServiceHandle(schIpsecpolsvc);
|
|
}
|
|
CloseServiceHandle(schMan);
|
|
}
|
|
|
|
return dwReturn;
|
|
} /* StopIpsecpolService */
|
|
|
|
/*********************************************************************
|
|
FUNCTION: IsIpsecpolServiceRunning
|
|
PURPOSE: Checks if ipsecpolsvc service is currently running
|
|
PARAMS:
|
|
dwReturn - holds errors retuned by SCM if any
|
|
pszServ - optional name of the server (default is NULL, start on local machine)
|
|
RETURNS: TRUE/FALSE
|
|
COMMENTS: TRUE returned means service is running
|
|
FALSE and dwReturn == ERROR_SUCCESS means service is not running
|
|
FALSE and dwReturn != ERROR_SUCCESS means SCM operation failed (dwReturn is error code)
|
|
*********************************************************************/
|
|
BOOL IsIpsecpolServiceRunning (OUT DWORD &dwReturn, OPTIONAL LPCTSTR pszServ)
|
|
{
|
|
BOOL bReturn = TRUE;
|
|
dwReturn = ERROR_SUCCESS;
|
|
|
|
SERVICE_STATUS ServStat;
|
|
memset(&ServStat, 0, sizeof(SERVICE_STATUS));
|
|
|
|
SC_HANDLE schMan = OpenSCManager(pszServ, NULL, SC_MANAGER_ALL_ACCESS);
|
|
|
|
if (schMan == NULL)
|
|
{
|
|
dwReturn = GetLastError();
|
|
bReturn = FALSE;
|
|
}
|
|
else
|
|
{
|
|
SC_HANDLE schIpsecpolsvc = OpenService(schMan, szIpsecpolsvc,
|
|
SERVICE_QUERY_STATUS | SERVICE_START | SERVICE_STOP);
|
|
if (schIpsecpolsvc == NULL)
|
|
{
|
|
dwReturn = GetLastError();
|
|
bReturn = FALSE;
|
|
}
|
|
else if (QueryServiceStatus(schIpsecpolsvc, &ServStat))
|
|
{
|
|
// check the status finally
|
|
if (ServStat.dwCurrentState != SERVICE_RUNNING)
|
|
{
|
|
bReturn = FALSE;
|
|
}
|
|
CloseServiceHandle(schIpsecpolsvc);
|
|
}
|
|
CloseServiceHandle(schMan);
|
|
}
|
|
|
|
return bReturn;
|
|
} /* IsIpsecpolServiceRunning */
|
|
|
|
/*********************************************************************
|
|
FUNCTION: InitIpsecpolsvcRPC
|
|
PURPOSE: Get an RPC handle from ipsecpolsvc that can be used to call its APIs
|
|
PARAMS:
|
|
pszServ - name of the server (pass NULL for the local machine)
|
|
hIpsecpolsvc - returned handle
|
|
RETURNS: RPC_S_OK or RPC api error code
|
|
COMMENTS: Service running is not prereq
|
|
*********************************************************************/
|
|
RPC_STATUS InitIpsecpolsvcRPC (IN TCHAR *pszServ, OUT handle_t &hIpsecpolsvc)
|
|
{
|
|
RPC_STATUS status = RPC_S_OK;
|
|
TCHAR localProtocol[] = TEXT("ncacn_np");
|
|
TCHAR remoteProtocol[] = TEXT("ncacn_np");
|
|
TCHAR endpoint[] = TEXT("\\pipe\\ipsecpolsvc");
|
|
PUSHORT stringBinding = NULL;
|
|
ULONG SecurityLevel = RPC_C_AUTHN_LEVEL_CONNECT;
|
|
|
|
if (pszServ != 0)
|
|
{
|
|
if (pszServ[0] == 0)
|
|
{
|
|
// empty string
|
|
pszServ = NULL;
|
|
}
|
|
}
|
|
|
|
status = RpcStringBindingCompose(0,
|
|
(PUSHORT)((pszServ == NULL) ? localProtocol : remoteProtocol),
|
|
(PUSHORT)pszServ,
|
|
(PUSHORT)endpoint,
|
|
0,
|
|
&stringBinding);
|
|
if (status == RPC_S_OK)
|
|
{
|
|
status = RpcBindingFromStringBinding(stringBinding, &hIpsecpolsvc);
|
|
}
|
|
|
|
|
|
if (status == RPC_S_OK)
|
|
{
|
|
status =
|
|
RpcBindingSetAuthInfo(hIpsecpolsvc,
|
|
0,
|
|
SecurityLevel,
|
|
RPC_C_AUTHN_WINNT,
|
|
0,
|
|
0
|
|
);
|
|
}
|
|
|
|
|
|
if (stringBinding != NULL)
|
|
{
|
|
status = RpcStringFree(&stringBinding);
|
|
}
|
|
|
|
return status;
|
|
} /* InitIpsecpolsvcRPC */
|
|
|
|
/*********************************************************************
|
|
FUNCTION: ShutdownIpsecpolsvcRPC
|
|
PURPOSE: Close RPC handle
|
|
PARAMS:
|
|
hIpsecpolsvc - handle
|
|
RETURNS: RPC_S_OK or RPC api error code
|
|
COMMENTS:
|
|
*********************************************************************/
|
|
RPC_STATUS ShutdownIpsecpolsvcRPC (IN handle_t hIpsecpolsvc)
|
|
{
|
|
return RpcBindingFree(&hIpsecpolsvc);
|
|
} /* ShutdownIpsecpolsvcRPC */
|
|
|
|
/*********************************************************************
|
|
FUNCTION: PlumbIPSecPolicy
|
|
PURPOSE: Plumbs IPSEC_IKE_POLICY to the specified machine
|
|
PARAMS:
|
|
pszServerName - machine name or NULL for local
|
|
pIPSecIkePol - pointer to IPSEC_IKE_POLICY.
|
|
GUIDs/names must be generated prior to the call
|
|
bFailMMIfExists - specifies MM filter behavior
|
|
bFailMMIfExists == FALSE will cause the call not to break
|
|
on ERROR_MM_FILTER_EXISTS when duplicate MM filters are there
|
|
bFailMMIfExists == TRUE will fail on any SPD API error
|
|
ppMMFilterHandles - array of mm filter handles will be returned here
|
|
ppFilterHandles - array of qm filter handles will be returned here
|
|
bPersist - if TRUE, information will be persisted
|
|
RETURNS: ERROR_SUCCESS or win32 error code
|
|
COMMENTS: CALLER is responsible for freeing the memory for the handle arrays
|
|
*********************************************************************/
|
|
DWORD
|
|
PlumbIPSecPolicy(
|
|
IN LPWSTR pServerName,
|
|
IN PIPSEC_IKE_POLICY pIPSecIkePol,
|
|
IN BOOL bFailMMIfExists,
|
|
OUT PHANDLE *ppMMFilterHandles,
|
|
OUT PHANDLE *ppFilterHandles,
|
|
IN OPTIONAL BOOL bPersist
|
|
)
|
|
{
|
|
DWORD dwReturn = ERROR_SUCCESS;
|
|
RPC_STATUS RpcStat = RPC_S_OK;
|
|
int i;
|
|
HANDLE hFilter;
|
|
BOOL bDefaultRule = FALSE; // will be true if default response rule is specified
|
|
// default response rule is specified if there is exactly 1 transport filter that is Me-to-Me
|
|
|
|
if (!pIPSecIkePol)
|
|
{
|
|
return ERROR_NO_DATA;
|
|
}
|
|
|
|
if (pIPSecIkePol->dwNumFilters == 1 && pIPSecIkePol->QMFilterType == QM_TRANSPORT_FILTER)
|
|
{
|
|
if (pIPSecIkePol->pTransportFilters[0].SrcAddr.AddrType == IP_ADDR_UNIQUE
|
|
&& pIPSecIkePol->pTransportFilters[0].SrcAddr.uIpAddr == IP_ADDRESS_ME
|
|
&& pIPSecIkePol->pTransportFilters[0].DesAddr.AddrType == IP_ADDR_UNIQUE
|
|
&& pIPSecIkePol->pTransportFilters[0].DesAddr.uIpAddr == IP_ADDRESS_ME
|
|
&& pIPSecIkePol->pTransportFilters[0].InboundFilterFlag == (FILTER_FLAG) POTF_DEFAULT_RESPONSE_FLAG
|
|
&& pIPSecIkePol->pTransportFilters[0].OutboundFilterFlag == (FILTER_FLAG) POTF_DEFAULT_RESPONSE_FLAG)
|
|
{
|
|
bDefaultRule = TRUE;
|
|
}
|
|
}
|
|
|
|
// allocate handle arrays first
|
|
if (bDefaultRule)
|
|
{
|
|
*ppMMFilterHandles = *ppFilterHandles = 0;
|
|
pIPSecIkePol->AuthInfos.dwFlags |= IPSEC_MM_AUTH_DEFAULT_AUTH;
|
|
pIPSecIkePol->IkePol.dwFlags |= IPSEC_MM_POLICY_DEFAULT_POLICY;
|
|
pIPSecIkePol->IpsPol.dwFlags |= IPSEC_QM_POLICY_DEFAULT_POLICY;
|
|
}
|
|
else
|
|
{
|
|
if (ppMMFilterHandles && pIPSecIkePol->dwNumMMFilters)
|
|
{
|
|
*ppMMFilterHandles = new HANDLE[pIPSecIkePol->dwNumMMFilters];
|
|
if (*ppMMFilterHandles == 0)
|
|
{
|
|
return ERROR_OUTOFMEMORY;
|
|
}
|
|
memset(*ppMMFilterHandles, 0, sizeof(HANDLE)*pIPSecIkePol->dwNumMMFilters);
|
|
}
|
|
if (ppFilterHandles && pIPSecIkePol->dwNumFilters)
|
|
{
|
|
*ppFilterHandles = new HANDLE[pIPSecIkePol->dwNumFilters];
|
|
if (*ppFilterHandles == 0)
|
|
{
|
|
if (ppMMFilterHandles)
|
|
{
|
|
if (*ppMMFilterHandles) { delete[] *ppMMFilterHandles; *ppMMFilterHandles = 0; }
|
|
}
|
|
return ERROR_OUTOFMEMORY;
|
|
}
|
|
memset(*ppFilterHandles, 0, sizeof(HANDLE)*pIPSecIkePol->dwNumFilters);
|
|
}
|
|
}
|
|
|
|
// let's go and plumb everything
|
|
// authinfos first
|
|
if (!UuidIsNil(&(pIPSecIkePol->AuthInfos.gMMAuthID), &RpcStat))
|
|
{
|
|
dwReturn = AddMMAuthMethods(pServerName, bPersist ? PERSIST_SPD_OBJECT : 0, &(pIPSecIkePol->AuthInfos));
|
|
}
|
|
|
|
if (dwReturn != ERROR_SUCCESS)
|
|
{
|
|
if (ppMMFilterHandles && *ppMMFilterHandles) { delete[] *ppMMFilterHandles; *ppMMFilterHandles = 0; }
|
|
if (ppFilterHandles && *ppFilterHandles) { delete[] *ppFilterHandles; *ppFilterHandles = 0; }
|
|
return dwReturn;
|
|
}
|
|
if (RpcStat != RPC_S_OK)
|
|
{
|
|
if (ppMMFilterHandles && *ppMMFilterHandles) { delete[] *ppMMFilterHandles; *ppMMFilterHandles = 0; }
|
|
if (ppFilterHandles && *ppFilterHandles) { delete[] *ppFilterHandles; *ppFilterHandles = 0; }
|
|
return GetLastError();
|
|
}
|
|
|
|
// mm policy
|
|
if (!UuidIsNil(&(pIPSecIkePol->IkePol.gPolicyID), &RpcStat))
|
|
{
|
|
dwReturn = AddMMPolicy(pServerName, bPersist ? PERSIST_SPD_OBJECT : 0, &(pIPSecIkePol->IkePol));
|
|
}
|
|
|
|
if (dwReturn != ERROR_SUCCESS)
|
|
{
|
|
if (ppMMFilterHandles && *ppMMFilterHandles) { delete[] *ppMMFilterHandles; *ppMMFilterHandles = 0; }
|
|
if (ppFilterHandles && *ppFilterHandles) { delete[] *ppFilterHandles; *ppFilterHandles = 0; }
|
|
return dwReturn;
|
|
}
|
|
if (RpcStat != RPC_S_OK)
|
|
{
|
|
if (ppMMFilterHandles && *ppMMFilterHandles) { delete[] *ppMMFilterHandles; *ppMMFilterHandles = 0; }
|
|
if (ppFilterHandles && *ppFilterHandles) { delete[] *ppFilterHandles; *ppFilterHandles = 0; }
|
|
return GetLastError();
|
|
}
|
|
|
|
// qm policy
|
|
if (!UuidIsNil(&(pIPSecIkePol->IpsPol.gPolicyID), &RpcStat))
|
|
{
|
|
dwReturn = AddQMPolicy(pServerName, bPersist ? PERSIST_SPD_OBJECT : 0, &(pIPSecIkePol->IpsPol));
|
|
}
|
|
|
|
if (dwReturn != ERROR_SUCCESS)
|
|
{
|
|
if (ppMMFilterHandles && *ppMMFilterHandles) { delete[] *ppMMFilterHandles; *ppMMFilterHandles = 0; }
|
|
if (ppFilterHandles && *ppFilterHandles) { delete[] *ppFilterHandles; *ppFilterHandles = 0; }
|
|
return dwReturn;
|
|
}
|
|
if (RpcStat != RPC_S_OK)
|
|
{
|
|
if (ppMMFilterHandles && *ppMMFilterHandles) { delete[] *ppMMFilterHandles; *ppMMFilterHandles = 0; }
|
|
if (ppFilterHandles && *ppFilterHandles) { delete[] *ppFilterHandles; *ppFilterHandles = 0; }
|
|
return GetLastError();
|
|
}
|
|
|
|
if (bDefaultRule)
|
|
{
|
|
// return here
|
|
return dwReturn;
|
|
}
|
|
|
|
// mm filters
|
|
for (i = 0; i < (int) pIPSecIkePol->dwNumMMFilters; i++)
|
|
{
|
|
hFilter = NULL;
|
|
if (!UuidIsNil(&(pIPSecIkePol->pMMFilters[i].gFilterID), &RpcStat))
|
|
{
|
|
dwReturn = AddMMFilter(pServerName, bPersist ? PERSIST_SPD_OBJECT : 0, &(pIPSecIkePol->pMMFilters[i]), &hFilter);
|
|
}
|
|
|
|
if (RpcStat != RPC_S_OK)
|
|
{
|
|
if (ppFilterHandles && *ppFilterHandles) { delete[] *ppFilterHandles; *ppFilterHandles = 0; }
|
|
return GetLastError();
|
|
}
|
|
|
|
if (!bFailMMIfExists && (dwReturn == ERROR_IPSEC_MM_POLICY_EXISTS || dwReturn == ERROR_IPSEC_MM_AUTH_EXISTS || dwReturn == ERROR_IPSEC_MM_FILTER_EXISTS))
|
|
{
|
|
dwReturn = ERROR_SUCCESS; // it's not actually an error
|
|
}
|
|
|
|
if (dwReturn != ERROR_SUCCESS)
|
|
{
|
|
if (ppFilterHandles && *ppFilterHandles) { delete[] *ppFilterHandles; *ppFilterHandles = 0; }
|
|
return dwReturn;
|
|
}
|
|
|
|
if (ppMMFilterHandles)
|
|
{
|
|
(*ppMMFilterHandles)[i] = hFilter;
|
|
}
|
|
}
|
|
|
|
// qm filters
|
|
for (i = 0; i < (int) pIPSecIkePol->dwNumFilters; i++)
|
|
{
|
|
hFilter = NULL;
|
|
if (pIPSecIkePol->QMFilterType == QM_TRANSPORT_FILTER)
|
|
{
|
|
if (!UuidIsNil(&(pIPSecIkePol->pTransportFilters[i].gFilterID), &RpcStat))
|
|
{
|
|
dwReturn = AddTransportFilter(pServerName, bPersist ? PERSIST_SPD_OBJECT : 0, &(pIPSecIkePol->pTransportFilters[i]), &hFilter);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// tunnel
|
|
if (!UuidIsNil(&(pIPSecIkePol->pTunnelFilters[i].gFilterID), &RpcStat))
|
|
{
|
|
dwReturn = AddTunnelFilter(pServerName, bPersist ? PERSIST_SPD_OBJECT : 0, &(pIPSecIkePol->pTunnelFilters[i]), &hFilter);
|
|
}
|
|
}
|
|
|
|
if (dwReturn != ERROR_SUCCESS)
|
|
{
|
|
return dwReturn;
|
|
}
|
|
if (RpcStat != RPC_S_OK)
|
|
{
|
|
return GetLastError();
|
|
}
|
|
|
|
if (ppFilterHandles)
|
|
{
|
|
(*ppFilterHandles)[i] = hFilter;
|
|
}
|
|
}
|
|
|
|
return dwReturn;
|
|
} /* PlumbIPSecPolicy */
|
|
|
|
/*********************************************************************
|
|
FUNCTION: DeleteIPSecPolicy
|
|
PURPOSE: Complementary to PlumbIPSecPolicy, removes IPSEC_IKE_POLICY
|
|
PARAMS:
|
|
pszServerName - machine name or NULL for local
|
|
pIPSecIkePol - pointer to IPSEC_IKE_POLICY.
|
|
GUIDs/names must be generated prior to the call
|
|
pMMFilterHandles - array of main mode filter handles
|
|
pFilterHandles - array of quick mode filter handles
|
|
RETURNS: ERROR_SUCCESS or win32 error code
|
|
COMMENTS: Function will try to
|
|
remove everything specified in the IPSEC_IKE_POLICY structure.
|
|
It is possible that one or several errors will be encountered.
|
|
Function will continue, but later first error will be returned.
|
|
*********************************************************************/
|
|
DWORD
|
|
DeleteIPSecPolicy(
|
|
IN LPWSTR pServerName,
|
|
IN PIPSEC_IKE_POLICY pIPSecIkePol,
|
|
IN PHANDLE pMMFilterHandles,
|
|
IN PHANDLE pFilterHandles
|
|
)
|
|
{
|
|
DWORD dwReturn = ERROR_SUCCESS;
|
|
DWORD dwErrorCode = ERROR_SUCCESS;
|
|
RPC_STATUS RpcStat = RPC_S_OK;
|
|
int i;
|
|
|
|
// mm filters
|
|
if (pMMFilterHandles)
|
|
{
|
|
for (i = 0; i < (int) pIPSecIkePol->dwNumMMFilters; i++)
|
|
{
|
|
if (!UuidIsNil(&(pIPSecIkePol->pMMFilters[i].gFilterID), &RpcStat))
|
|
{
|
|
dwReturn = DeleteMMFilter(pMMFilterHandles[i]);
|
|
}
|
|
|
|
if (RpcStat != RPC_S_OK && dwErrorCode == ERROR_SUCCESS)
|
|
{
|
|
dwErrorCode = GetLastError();
|
|
}
|
|
|
|
if (dwReturn != ERROR_SUCCESS && dwErrorCode == ERROR_SUCCESS)
|
|
{
|
|
dwErrorCode = dwReturn;
|
|
}
|
|
}
|
|
}
|
|
|
|
// qm filters
|
|
if (pFilterHandles)
|
|
{
|
|
for (i = 0; i < (int) pIPSecIkePol->dwNumFilters; i++)
|
|
{
|
|
if (pIPSecIkePol->QMFilterType == QM_TRANSPORT_FILTER)
|
|
{
|
|
if (!UuidIsNil(&(pIPSecIkePol->pTransportFilters[i].gFilterID), &RpcStat))
|
|
{
|
|
dwReturn = DeleteTransportFilter(pFilterHandles[i]);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// tunnel
|
|
if (!UuidIsNil(&(pIPSecIkePol->pTunnelFilters[i].gFilterID), &RpcStat))
|
|
{
|
|
dwReturn = DeleteTunnelFilter(pFilterHandles[i]);
|
|
}
|
|
}
|
|
|
|
if (RpcStat != RPC_S_OK && dwErrorCode == ERROR_SUCCESS)
|
|
{
|
|
dwErrorCode = GetLastError();
|
|
}
|
|
|
|
if (dwReturn != ERROR_SUCCESS && dwErrorCode == ERROR_SUCCESS)
|
|
{
|
|
dwErrorCode = dwReturn;
|
|
}
|
|
}
|
|
}
|
|
|
|
// mm auth methods
|
|
if (!UuidIsNil(&(pIPSecIkePol->AuthInfos.gMMAuthID), &RpcStat))
|
|
{
|
|
dwReturn = DeleteMMAuthMethods(pServerName, pIPSecIkePol->AuthInfos.gMMAuthID);
|
|
}
|
|
if (RpcStat != RPC_S_OK && dwErrorCode == ERROR_SUCCESS)
|
|
{
|
|
dwErrorCode = GetLastError();
|
|
}
|
|
|
|
if (dwReturn != ERROR_SUCCESS && dwErrorCode == ERROR_SUCCESS)
|
|
{
|
|
dwErrorCode = dwReturn;
|
|
}
|
|
|
|
// mm policy
|
|
if (!UuidIsNil(&(pIPSecIkePol->IkePol.gPolicyID), &RpcStat))
|
|
{
|
|
dwReturn = DeleteMMPolicy(pServerName, pIPSecIkePol->IkePol.pszPolicyName);
|
|
}
|
|
if (RpcStat != RPC_S_OK && dwErrorCode == ERROR_SUCCESS)
|
|
{
|
|
dwErrorCode = GetLastError();
|
|
}
|
|
|
|
if (dwReturn != ERROR_SUCCESS && dwErrorCode == ERROR_SUCCESS)
|
|
{
|
|
dwErrorCode = dwReturn;
|
|
}
|
|
|
|
// qm policy
|
|
if (!UuidIsNil(&(pIPSecIkePol->IpsPol.gPolicyID), &RpcStat))
|
|
{
|
|
dwReturn = DeleteQMPolicy(pServerName, pIPSecIkePol->IpsPol.pszPolicyName);
|
|
}
|
|
if (RpcStat != RPC_S_OK && dwErrorCode == ERROR_SUCCESS)
|
|
{
|
|
dwErrorCode = GetLastError();
|
|
}
|
|
|
|
if (dwReturn != ERROR_SUCCESS && dwErrorCode == ERROR_SUCCESS)
|
|
{
|
|
dwErrorCode = dwReturn;
|
|
}
|
|
|
|
return dwErrorCode;
|
|
|
|
} /* DeleteIPSecPolicy */
|
|
|
|
/*********************************************************************
|
|
FUNCTION: DeletePersistedIPSecPolicy
|
|
PURPOSE: Complementary to PlumbIPSecPolicy with persistent flag on,
|
|
removes persisted policy
|
|
PARAMS:
|
|
pszServerName - machine name or NULL for local
|
|
pPolicyName - policy name prefix, if empty string of NULL,
|
|
all persisted policy settings will be removed
|
|
RETURNS: ERROR_SUCCESS or win32 error code
|
|
COMMENTS: Function will try to
|
|
remove everything specified.
|
|
It is possible that one or several errors will be encountered.
|
|
Function will continue, but later first error will be returned.
|
|
*********************************************************************/
|
|
DWORD
|
|
DeletePersistedIPSecPolicy(
|
|
IN LPWSTR pServerName,
|
|
IN LPWSTR pPolicyName
|
|
)
|
|
{
|
|
DWORD dwErrorCode, dwReturn;
|
|
int i, j;
|
|
PMM_FILTER pmmf; // for MM filter calls
|
|
PIPSEC_QM_POLICY pipsqmp; // for QM policy calls
|
|
PTRANSPORT_FILTER ptf; // for transport filter calls
|
|
PTUNNEL_FILTER ptunf; // for tunnel filter calls
|
|
PMM_AUTH_METHODS pam; // for auth method calls
|
|
PIPSEC_MM_POLICY pipsmmp; // for MM policy calls
|
|
DWORD dwCount; // counting objects here
|
|
DWORD dwResumeHandle; // handle for continuation calls
|
|
DWORD dwReserved; // reserved container
|
|
GUID gDefaultGUID = {0}; // NULL GUID value
|
|
int iPolNameLen = 0;
|
|
HANDLE hFilter;
|
|
BOOL bRemoveDefault = FALSE;
|
|
|
|
dwErrorCode = dwReturn = ERROR_SUCCESS;
|
|
if (pPolicyName && *pPolicyName)
|
|
{
|
|
iPolNameLen = wcslen(pPolicyName);
|
|
}
|
|
|
|
// start with mm filters, enum all
|
|
pmmf=NULL;
|
|
dwResumeHandle=0;
|
|
// make the call(s)
|
|
for (i = 0; ;i+=dwCount)
|
|
{
|
|
BOOL bRemoved = FALSE;
|
|
DWORD dwOldResumeHandle = dwResumeHandle;
|
|
|
|
dwReturn = EnumMMFilters(pServerName, ENUM_GENERIC_FILTERS, gDefaultGUID, &pmmf, 0, &dwCount, &dwResumeHandle);
|
|
if (dwReturn == ERROR_NO_DATA || dwCount == 0)
|
|
{
|
|
dwReturn = ERROR_SUCCESS;
|
|
// no more filters
|
|
break;
|
|
}
|
|
if (dwReturn != ERROR_SUCCESS)
|
|
{
|
|
break;
|
|
}
|
|
for (j = 0; j < (int) dwCount; j++)
|
|
{
|
|
// check if it's our filter
|
|
if (iPolNameLen == 0|| wcsncmp(pPolicyName, pmmf[j].pszFilterName, iPolNameLen) == 0)
|
|
{
|
|
dwReturn = OpenMMFilterHandle(pServerName, &(pmmf[j]), &hFilter);
|
|
if (dwReturn == ERROR_SUCCESS)
|
|
{
|
|
dwReturn = DeleteMMFilter(hFilter);
|
|
if (dwReturn == ERROR_SUCCESS)
|
|
{
|
|
bRemoved = TRUE;
|
|
}
|
|
if (dwReturn != ERROR_SUCCESS && dwErrorCode == ERROR_SUCCESS)
|
|
{
|
|
dwErrorCode = dwReturn;
|
|
}
|
|
dwReturn = CloseMMFilterHandle(hFilter);
|
|
}
|
|
if (dwReturn != ERROR_SUCCESS && dwErrorCode == ERROR_SUCCESS)
|
|
{
|
|
dwErrorCode = dwReturn;
|
|
}
|
|
}
|
|
}
|
|
SPDApiBufferFree(pmmf);
|
|
pmmf=NULL;
|
|
if (dwReturn != ERROR_SUCCESS && dwErrorCode == ERROR_SUCCESS)
|
|
{
|
|
dwErrorCode = dwReturn;
|
|
}
|
|
if (bRemoved)
|
|
{
|
|
dwResumeHandle = dwOldResumeHandle; // need to restart enumeration!
|
|
}
|
|
}
|
|
if (dwReturn != ERROR_SUCCESS && dwErrorCode == ERROR_SUCCESS)
|
|
{
|
|
dwErrorCode = dwReturn;
|
|
}
|
|
|
|
// transport filters - the routine is similar
|
|
ptf=NULL;
|
|
dwResumeHandle=0;
|
|
// make the call(s)
|
|
for (i = 0; ;i+=dwCount)
|
|
{
|
|
BOOL bRemoved = FALSE;
|
|
DWORD dwOldResumeHandle = dwResumeHandle;
|
|
|
|
dwReturn = EnumTransportFilters(pServerName, ENUM_GENERIC_FILTERS, gDefaultGUID, &ptf, 0, &dwCount, &dwResumeHandle);
|
|
if (dwReturn == ERROR_NO_DATA || dwCount == 0)
|
|
{
|
|
dwReturn = ERROR_SUCCESS;
|
|
// no more filters
|
|
break;
|
|
}
|
|
if (dwReturn != ERROR_SUCCESS)
|
|
{
|
|
break;
|
|
}
|
|
for (j = 0; j < (int) dwCount; j++)
|
|
{
|
|
// check if it's our filter
|
|
if (iPolNameLen == 0|| wcsncmp(pPolicyName, ptf[j].pszFilterName, iPolNameLen) == 0)
|
|
{
|
|
dwReturn = OpenTransportFilterHandle(pServerName, &(ptf[j]), &hFilter);
|
|
if (dwReturn == ERROR_SUCCESS)
|
|
{
|
|
dwReturn = DeleteTransportFilter(hFilter);
|
|
if (dwReturn == ERROR_SUCCESS)
|
|
{
|
|
bRemoved = TRUE;
|
|
}
|
|
if (dwReturn != ERROR_SUCCESS && dwErrorCode == ERROR_SUCCESS)
|
|
{
|
|
dwErrorCode = dwReturn;
|
|
}
|
|
dwReturn = CloseTransportFilterHandle(hFilter);
|
|
}
|
|
if (dwReturn != ERROR_SUCCESS && dwErrorCode == ERROR_SUCCESS)
|
|
{
|
|
dwErrorCode = dwReturn;
|
|
}
|
|
}
|
|
}
|
|
SPDApiBufferFree(ptf);
|
|
ptf=NULL;
|
|
if (dwReturn != ERROR_SUCCESS && dwErrorCode == ERROR_SUCCESS)
|
|
{
|
|
dwErrorCode = dwReturn;
|
|
}
|
|
if (bRemoved)
|
|
{
|
|
dwResumeHandle = dwOldResumeHandle; // need to restart enumeration!
|
|
}
|
|
}
|
|
if (dwReturn != ERROR_SUCCESS && dwErrorCode == ERROR_SUCCESS)
|
|
{
|
|
dwErrorCode = dwReturn;
|
|
}
|
|
|
|
// tunnel filters
|
|
ptunf=NULL;
|
|
dwResumeHandle=0;
|
|
// make the call(s)
|
|
for (i = 0; ;i+=dwCount)
|
|
{
|
|
BOOL bRemoved = FALSE;
|
|
DWORD dwOldResumeHandle = dwResumeHandle;
|
|
|
|
dwReturn = EnumTunnelFilters(pServerName, ENUM_GENERIC_FILTERS, gDefaultGUID, &ptunf, 0, &dwCount, &dwResumeHandle);
|
|
if (dwReturn == ERROR_NO_DATA || dwCount == 0)
|
|
{
|
|
dwReturn = ERROR_SUCCESS;
|
|
// no more filters
|
|
break;
|
|
}
|
|
if (dwReturn != ERROR_SUCCESS)
|
|
{
|
|
break;
|
|
}
|
|
for (j = 0; j < (int) dwCount; j++)
|
|
{
|
|
// check if it's our filter
|
|
if (iPolNameLen == 0|| wcsncmp(pPolicyName, ptunf[j].pszFilterName, iPolNameLen) == 0)
|
|
{
|
|
dwReturn = OpenTunnelFilterHandle(pServerName, &(ptunf[j]), &hFilter);
|
|
if (dwReturn == ERROR_SUCCESS)
|
|
{
|
|
dwReturn = DeleteTunnelFilter(hFilter);
|
|
if (dwReturn == ERROR_SUCCESS)
|
|
{
|
|
bRemoved = TRUE;
|
|
}
|
|
if (dwReturn != ERROR_SUCCESS && dwErrorCode == ERROR_SUCCESS)
|
|
{
|
|
dwErrorCode = dwReturn;
|
|
}
|
|
dwReturn = CloseTunnelFilterHandle(hFilter);
|
|
}
|
|
if (dwReturn != ERROR_SUCCESS && dwErrorCode == ERROR_SUCCESS)
|
|
{
|
|
dwErrorCode = dwReturn;
|
|
}
|
|
}
|
|
}
|
|
SPDApiBufferFree(ptunf);
|
|
ptunf=NULL;
|
|
if (dwReturn != ERROR_SUCCESS && dwErrorCode == ERROR_SUCCESS)
|
|
{
|
|
dwErrorCode = dwReturn;
|
|
}
|
|
if (bRemoved)
|
|
{
|
|
dwResumeHandle = dwOldResumeHandle; // need to restart enumeration!
|
|
}
|
|
}
|
|
if (dwReturn != ERROR_SUCCESS && dwErrorCode == ERROR_SUCCESS)
|
|
{
|
|
dwErrorCode = dwReturn;
|
|
}
|
|
|
|
// mm policies
|
|
pipsmmp=NULL;
|
|
dwResumeHandle=0;
|
|
// make the call(s)
|
|
for (i = 0; ;i+=dwCount)
|
|
{
|
|
BOOL bRemoved = FALSE;
|
|
DWORD dwOldResumeHandle = dwResumeHandle;
|
|
|
|
dwReturn = EnumMMPolicies(pServerName, &pipsmmp, 0, &dwCount, &dwResumeHandle);
|
|
if (dwReturn == ERROR_NO_DATA || dwCount == 0)
|
|
{
|
|
dwReturn = ERROR_SUCCESS;
|
|
// no more filters
|
|
break;
|
|
}
|
|
if (dwReturn != ERROR_SUCCESS)
|
|
{
|
|
break;
|
|
}
|
|
for (j = 0; j < (int) dwCount; j++)
|
|
{
|
|
// check if it's our mm policy
|
|
if (iPolNameLen == 0|| wcsncmp(pPolicyName, pipsmmp[j].pszPolicyName, iPolNameLen) == 0)
|
|
{
|
|
dwReturn = DeleteMMPolicy(pServerName, pipsmmp[j].pszPolicyName);
|
|
if (dwReturn == ERROR_SUCCESS)
|
|
{
|
|
bRemoved = TRUE;
|
|
}
|
|
if (dwReturn == ERROR_SUCCESS && (pipsmmp[j].dwFlags & IPSEC_QM_POLICY_DEFAULT_POLICY))
|
|
{ // got to remove other defaults too
|
|
bRemoveDefault = TRUE;
|
|
}
|
|
if (dwReturn != ERROR_SUCCESS && dwErrorCode == ERROR_SUCCESS)
|
|
{
|
|
dwErrorCode = dwReturn;
|
|
}
|
|
}
|
|
}
|
|
SPDApiBufferFree(pipsmmp);
|
|
pipsmmp=NULL;
|
|
if (dwReturn != ERROR_SUCCESS && dwErrorCode == ERROR_SUCCESS)
|
|
{
|
|
dwErrorCode = dwReturn;
|
|
}
|
|
if (bRemoved)
|
|
{
|
|
dwResumeHandle = dwOldResumeHandle; // need to restart enumeration!
|
|
}
|
|
}
|
|
if (dwReturn != ERROR_SUCCESS && dwErrorCode == ERROR_SUCCESS)
|
|
{
|
|
dwErrorCode = dwReturn;
|
|
}
|
|
|
|
// auth methods
|
|
pam=NULL;
|
|
dwResumeHandle=0;
|
|
// make the call(s)
|
|
for (i = 0; ;i+=dwCount)
|
|
{
|
|
BOOL bRemoved = FALSE;
|
|
DWORD dwOldResumeHandle = dwResumeHandle;
|
|
|
|
dwReturn = EnumMMAuthMethods(pServerName, &pam, 0, &dwCount, &dwResumeHandle);
|
|
if (dwReturn == ERROR_NO_DATA || dwCount == 0)
|
|
{
|
|
dwReturn = ERROR_SUCCESS;
|
|
// no more filters
|
|
break;
|
|
}
|
|
if (dwReturn != ERROR_SUCCESS)
|
|
{
|
|
break;
|
|
}
|
|
for (j = 0; j < (int) dwCount; j++)
|
|
{
|
|
// check if it's our auth method
|
|
if (bRemoveDefault || (pam[j].dwFlags & IPSEC_MM_AUTH_DEFAULT_AUTH) == 0)
|
|
{ // either remove default is set or this is non-default
|
|
dwReturn = DeleteMMAuthMethods(pServerName, pam[j].gMMAuthID);
|
|
if (dwReturn == ERROR_SUCCESS)
|
|
{
|
|
bRemoved = TRUE;
|
|
}
|
|
if (dwReturn != ERROR_SUCCESS && dwErrorCode == ERROR_SUCCESS)
|
|
{
|
|
dwErrorCode = dwReturn;
|
|
}
|
|
}
|
|
}
|
|
SPDApiBufferFree(pam);
|
|
pam=NULL;
|
|
if (dwReturn != ERROR_SUCCESS && dwErrorCode == ERROR_SUCCESS)
|
|
{
|
|
dwErrorCode = dwReturn;
|
|
}
|
|
if (bRemoved)
|
|
{
|
|
dwResumeHandle = dwOldResumeHandle; // need to restart enumeration!
|
|
}
|
|
}
|
|
if (dwReturn != ERROR_SUCCESS && dwErrorCode == ERROR_SUCCESS)
|
|
{
|
|
dwErrorCode = dwReturn;
|
|
}
|
|
|
|
// qm policies
|
|
pipsqmp=NULL;
|
|
dwResumeHandle=0;
|
|
// make the call(s)
|
|
for (i = 0; ;i+=dwCount)
|
|
{
|
|
BOOL bRemoved = FALSE;
|
|
DWORD dwOldResumeHandle = dwResumeHandle;
|
|
|
|
dwReturn = EnumQMPolicies(pServerName, &pipsqmp, 0, &dwCount, &dwResumeHandle);
|
|
if (dwReturn == ERROR_NO_DATA || dwCount == 0)
|
|
{
|
|
dwReturn = ERROR_SUCCESS;
|
|
// no more filters
|
|
break;
|
|
}
|
|
if (dwReturn != ERROR_SUCCESS)
|
|
{
|
|
break;
|
|
}
|
|
for (j = 0; j < (int) dwCount; j++)
|
|
{
|
|
// check if it's our qm policy
|
|
if (iPolNameLen == 0|| wcsncmp(pPolicyName, pipsqmp[j].pszPolicyName, iPolNameLen) == 0)
|
|
{
|
|
dwReturn = DeleteQMPolicy(pServerName, pipsqmp[j].pszPolicyName);
|
|
if (dwReturn == ERROR_SUCCESS)
|
|
{
|
|
bRemoved = TRUE;
|
|
}
|
|
if (dwReturn != ERROR_SUCCESS && dwErrorCode == ERROR_SUCCESS)
|
|
{
|
|
dwErrorCode = dwReturn;
|
|
}
|
|
}
|
|
}
|
|
SPDApiBufferFree(pipsqmp);
|
|
pipsqmp=NULL;
|
|
if (dwReturn != ERROR_SUCCESS && dwErrorCode == ERROR_SUCCESS)
|
|
{
|
|
dwErrorCode = dwReturn;
|
|
}
|
|
if (bRemoved)
|
|
{
|
|
dwResumeHandle = dwOldResumeHandle; // need to restart enumeration!
|
|
}
|
|
}
|
|
if (dwReturn != ERROR_SUCCESS && dwErrorCode == ERROR_SUCCESS)
|
|
{
|
|
dwErrorCode = dwReturn;
|
|
}
|
|
|
|
return dwErrorCode;
|
|
} /* DeletePersistedIPSecPolicy */
|