windows-nt/Source/XPSP1/NT/net/ipsec/ipseccmd/usepa.cpp
2020-09-26 16:20:57 +08:00

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 */