You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
493 lines
12 KiB
493 lines
12 KiB
// Policy.cpp: implementation for the CPolicy base class for main mode
|
|
// and quick mode policies
|
|
//
|
|
// Copyright (c)1997-2001 Microsoft Corporation
|
|
//
|
|
//////////////////////////////////////////////////////////////////////
|
|
#include "precomp.h"
|
|
#include "NetSecProv.h"
|
|
#include "Policy.h"
|
|
#include "PolicyMM.h"
|
|
#include "PolicyQM.h"
|
|
|
|
//extern CCriticalSection g_CS;
|
|
|
|
|
|
/*
|
|
Routine Description:
|
|
|
|
Name:
|
|
|
|
CIPSecPolicy::Rollback
|
|
|
|
Functionality:
|
|
|
|
Static function to rollback those policies added by us with the given token.
|
|
|
|
Virtual:
|
|
|
|
No.
|
|
|
|
Arguments:
|
|
|
|
pNamespace - The namespace for ourselves.
|
|
|
|
pszRollbackToken - The token used to record our the action when we add
|
|
the policies.
|
|
|
|
bClearAll - Flag whether we should clear all policies. If it's true,
|
|
then we will delete all the policies regardless whether they
|
|
are added by us or not. This is a dangerous flag.
|
|
|
|
Return Value:
|
|
|
|
Success:
|
|
|
|
(1) WBEM_NO_ERROR: rollback objects are found and they are deleted.
|
|
|
|
(2) WBEM_S_FALSE: no rollback objects are found.
|
|
|
|
Failure:
|
|
|
|
Various error codes indicating the cause of the failure.
|
|
|
|
|
|
Notes:
|
|
|
|
We will continue the deletion even if some failure happens. That failure will be
|
|
returned, though.
|
|
|
|
$undone:shawnwu, should we really support ClearAll?
|
|
|
|
*/
|
|
|
|
HRESULT
|
|
CIPSecPolicy::Rollback (
|
|
IN IWbemServices * pNamespace,
|
|
IN LPCWSTR pszRollbackToken,
|
|
IN bool bClearAll
|
|
)
|
|
{
|
|
if (pNamespace == NULL || pszRollbackToken == NULL)
|
|
{
|
|
return WBEM_E_INVALID_PARAMETER;
|
|
}
|
|
|
|
//if (bClearAll)
|
|
//{
|
|
// return ClearAllPolicies(pNamespace);
|
|
//}
|
|
|
|
CComPtr<IEnumWbemClassObject> srpEnum;
|
|
|
|
//
|
|
// this will only enumerate all rollback filter object without testing the
|
|
// the token guid. This limitation is due to a mysterious error
|
|
// for any queries containing the where clause. That might be a limitation
|
|
// of non-dynamic classes of WMI
|
|
//
|
|
|
|
HRESULT hr = ::GetClassEnum(pNamespace, pszNspRollbackPolicy, &srpEnum);
|
|
|
|
//
|
|
// go through all found classes. srpEnum->Next will return WBEM_S_FALSE if instance
|
|
// is not found.
|
|
//
|
|
|
|
CComPtr<IWbemClassObject> srpObj;
|
|
ULONG nEnum = 0;
|
|
HRESULT hrError = WBEM_NO_ERROR;
|
|
|
|
hr = srpEnum->Next(WBEM_INFINITE, 1, &srpObj, &nEnum);
|
|
bool bHasInst = (SUCCEEDED(hr) && hr != WBEM_S_FALSE && srpObj != NULL);
|
|
|
|
while (SUCCEEDED(hr) && hr != WBEM_S_FALSE && srpObj)
|
|
{
|
|
CComVariant varTokenGuid;
|
|
hr = srpObj->Get(g_pszTokenGuid, 0, &varTokenGuid, NULL, NULL);
|
|
|
|
//
|
|
// need to compare the token guid ourselves
|
|
//
|
|
|
|
if (SUCCEEDED(hr) &&
|
|
varTokenGuid.vt == VT_BSTR &&
|
|
varTokenGuid.bstrVal != NULL &&
|
|
(_wcsicmp(pszRollbackToken, pszRollbackAll) == 0 || _wcsicmp(pszRollbackToken, varTokenGuid.bstrVal) == 0 )
|
|
)
|
|
{
|
|
//
|
|
// get the policy name and find the policy by the name
|
|
//
|
|
|
|
CComVariant varPolicyName;
|
|
CComVariant varPolicyType;
|
|
hr = srpObj->Get(g_pszPolicyName, 0, &varPolicyName, NULL, NULL);
|
|
|
|
GUID guidFilter = GUID_NULL;
|
|
|
|
//
|
|
// different types of policy has different
|
|
//
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = srpObj->Get(g_pszPolicyType, 0, &varPolicyType, NULL, NULL);
|
|
|
|
if (SUCCEEDED(hr) && varPolicyType.vt != VT_I4)
|
|
{
|
|
hr = WBEM_E_INVALID_OBJECT;
|
|
}
|
|
}
|
|
|
|
if (SUCCEEDED(hr) && varPolicyName.vt == VT_BSTR)
|
|
{
|
|
DWORD dwResumeHandle = 0;
|
|
DWORD dwReturned = 0;
|
|
DWORD dwStatus;
|
|
|
|
if (varPolicyType.lVal == MainMode_Policy)
|
|
{
|
|
//
|
|
// main mode policy
|
|
//
|
|
|
|
hr = CMMPolicy::DeletePolicy(varPolicyName.bstrVal);
|
|
}
|
|
else if (varPolicyType.lVal == QuickMode_Policy)
|
|
{
|
|
//
|
|
// quick mode policy
|
|
//
|
|
|
|
hr = CQMPolicy::DeletePolicy(varPolicyName.bstrVal);
|
|
}
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
CComVariant varPath;
|
|
if (SUCCEEDED(srpObj->Get(L"__RelPath", 0, &varPath, NULL, NULL)) && varPath.vt == VT_BSTR)
|
|
{
|
|
hr = pNamespace->DeleteInstance(varPath.bstrVal, 0, NULL, NULL);
|
|
}
|
|
}
|
|
|
|
//
|
|
// we are tracking the first error
|
|
//
|
|
|
|
if (FAILED(hr) && SUCCEEDED(hrError))
|
|
{
|
|
hrError = hr;
|
|
}
|
|
}
|
|
|
|
//
|
|
// ready it for re-use
|
|
//
|
|
|
|
srpObj.Release();
|
|
hr = srpEnum->Next(WBEM_INFINITE, 1, &srpObj, &nEnum);
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = CQMPolicy::DeleteDefaultPolicies();
|
|
}
|
|
|
|
if (!bHasInst)
|
|
{
|
|
return WBEM_S_FALSE;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// any failure code will be returned regardless of the final hr
|
|
//
|
|
|
|
if (FAILED(hrError))
|
|
{
|
|
return hrError;
|
|
}
|
|
else
|
|
{
|
|
return SUCCEEDED(hr) ? WBEM_NO_ERROR : hr;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
Routine Description:
|
|
|
|
Name:
|
|
|
|
CIPSecPolicy::ClearAllPolicies
|
|
|
|
Functionality:
|
|
|
|
Static function to delete all policies in SPD. This is a very dangerous action!
|
|
|
|
Virtual:
|
|
|
|
No.
|
|
|
|
Arguments:
|
|
|
|
pNamespace - The namespace for ourselves.
|
|
|
|
Return Value:
|
|
|
|
Success:
|
|
|
|
WBEM_NO_ERROR.
|
|
|
|
Failure:
|
|
|
|
Various error codes indicating the cause of the failure.
|
|
|
|
|
|
Notes:
|
|
|
|
We will continue the deletion even if some failure happens. That failure will be
|
|
returned, though.
|
|
|
|
$undone:shawnwu, should we really support this?
|
|
|
|
*/
|
|
|
|
HRESULT
|
|
CIPSecPolicy::ClearAllPolicies (
|
|
IN IWbemServices * pNamespace
|
|
)
|
|
{
|
|
DWORD dwResumeHandle = 0;
|
|
DWORD dwReturned = 0;
|
|
DWORD dwStatus;
|
|
|
|
HRESULT hr = WBEM_NO_ERROR;
|
|
HRESULT hrError = WBEM_NO_ERROR;
|
|
|
|
//
|
|
// SPD doesn't have a similar API.
|
|
// We have to do one by one. For that purpose, we need the name.
|
|
//
|
|
|
|
//
|
|
// Delete main mode policies.
|
|
//
|
|
|
|
PIPSEC_MM_POLICY *ppMMPolicy = NULL;
|
|
dwStatus = ::EnumMMPolicies(NULL, ppMMPolicy, 1, &dwReturned, &dwResumeHandle);
|
|
while (ERROR_SUCCESS == dwStatus && dwReturned > 0)
|
|
{
|
|
hr = CMMPolicy::DeletePolicy((*ppMMPolicy)->pszPolicyName);
|
|
|
|
//
|
|
// we will track the first error
|
|
//
|
|
|
|
if (FAILED(hr) && SUCCEEDED(hrError))
|
|
{
|
|
hrError = hr;
|
|
}
|
|
|
|
FreePolicy(ppMMPolicy, true);
|
|
*ppMMPolicy = NULL;
|
|
|
|
dwReturned = 0;
|
|
dwStatus = ::EnumMMPolicies(NULL, ppMMPolicy, 1, &dwReturned, &dwResumeHandle);
|
|
}
|
|
|
|
//
|
|
// Delete quick mode policies.
|
|
//
|
|
|
|
PIPSEC_QM_POLICY *ppQMPolicy = NULL;
|
|
|
|
dwResumeHandle = 0;
|
|
dwReturned = 0;
|
|
dwStatus = ::EnumQMPolicies(NULL, ppQMPolicy, 1, &dwReturned, &dwResumeHandle);
|
|
while (ERROR_SUCCESS == dwStatus && dwReturned > 0)
|
|
{
|
|
hr = CQMPolicy::DeletePolicy((*ppQMPolicy)->pszPolicyName);
|
|
|
|
//
|
|
// we will track the first error
|
|
//
|
|
|
|
if (FAILED(hr) && SUCCEEDED(hrError))
|
|
{
|
|
hrError = hr;
|
|
}
|
|
|
|
FreePolicy(ppQMPolicy, true);
|
|
*ppQMPolicy = NULL;
|
|
|
|
dwReturned = 0;
|
|
dwStatus = ::EnumQMPolicies(NULL, ppQMPolicy, 1, &dwReturned, &dwResumeHandle);
|
|
}
|
|
|
|
//
|
|
// now, let's clear up all past action information for policies deposited in the
|
|
// WMI depository
|
|
//
|
|
|
|
hr = ::DeleteRollbackObjects(pNamespace, pszNspRollbackPolicy);
|
|
|
|
if (FAILED(hr) && SUCCEEDED(hrError))
|
|
{
|
|
hrError = hr;
|
|
}
|
|
|
|
return SUCCEEDED(hrError) ? WBEM_NO_ERROR : hrError;
|
|
}
|
|
|
|
|
|
/*
|
|
Routine Description:
|
|
|
|
Name:
|
|
|
|
CIPSecPolicy::OnAfterAddPolicy
|
|
|
|
Functionality:
|
|
|
|
Post-adding handler to be called after successfully added a policy to SPD.
|
|
|
|
Virtual:
|
|
|
|
No.
|
|
|
|
Arguments:
|
|
|
|
pszPolicyName - The name of the filter.
|
|
|
|
eType - The type of the policy (main mode or quick mode).
|
|
|
|
Return Value:
|
|
|
|
Success:
|
|
|
|
(1) WBEM_NO_ERROR: if rollback object is successfully created.
|
|
|
|
(2) WBEM_S_FALSE: if there is no rollback guid information.
|
|
|
|
Failure:
|
|
|
|
(1) various errors indicated by the returned error codes.
|
|
|
|
|
|
Notes:
|
|
|
|
(1) Currently, we don't require a rollback object to be created for each
|
|
object added to SPD. Only a host that support rollback will deposit
|
|
rollback guid information and only then can we create a rollback object.
|
|
|
|
*/
|
|
|
|
HRESULT
|
|
CIPSecPolicy::OnAfterAddPolicy (
|
|
IN LPCWSTR pszPolicyName,
|
|
IN EnumPolicyType eType
|
|
)
|
|
{
|
|
//
|
|
// will create an Nsp_RollbackPolicy
|
|
//
|
|
|
|
CComPtr<IWbemClassObject> srpObj;
|
|
HRESULT hr = SpawnRollbackInstance(pszNspRollbackPolicy, &srpObj);
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
return hr;
|
|
}
|
|
|
|
//
|
|
// won't consider a failure if there is no rollback guid, i.e., this action is not
|
|
// part of a transaction block
|
|
//
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
//
|
|
// $undone:shawnwu, this approach to pulling the globals are not good.
|
|
// Instead, we should implement it as an event handler.
|
|
//
|
|
|
|
//::UpdateGlobals(m_srpNamespace, m_srpCtx);
|
|
//if (g_varRollbackGuid.vt != VT_NULL && g_varRollbackGuid.vt != VT_EMPTY)
|
|
//{
|
|
// hr = srpObj->Put(g_pszTokenGuid, 0, &g_varRollbackGuid, CIM_EMPTY);
|
|
//}
|
|
//else
|
|
//{
|
|
|
|
CComVariant varRollbackNull = pszEmptyRollbackToken;
|
|
hr = srpObj->Put(g_pszTokenGuid, 0, &varRollbackNull, CIM_EMPTY);
|
|
|
|
//}
|
|
|
|
//
|
|
// we can create a rollback object
|
|
//
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
|
|
//
|
|
// $undone:shawnwu, Currently, we only support rolling back added objects, not removed objects
|
|
// Also, we don't cache the previous instance data yet.
|
|
//
|
|
|
|
VARIANT varAction;
|
|
|
|
//
|
|
// This is to record a PutInstance action
|
|
//
|
|
|
|
varAction.vt = VT_I4;
|
|
varAction.lVal = Action_Add;
|
|
|
|
hr = srpObj->Put(g_pszAction, 0, &varAction, CIM_EMPTY);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
//
|
|
// need to remember the policy's name
|
|
//
|
|
|
|
CComVariant var = pszPolicyName;
|
|
hr = srpObj->Put(g_pszPolicyName, 0, &var, CIM_EMPTY);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
var.Clear();
|
|
var.vt = VT_I4;
|
|
var.lVal = eType;
|
|
hr = srpObj->Put(g_pszPolicyType, 0, &var, CIM_EMPTY);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = m_srpNamespace->PutInstance(srpObj, WBEM_FLAG_CREATE_OR_UPDATE, m_srpCtx, NULL);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = WBEM_NO_ERROR;
|
|
}
|
|
}
|
|
else if (SUCCEEDED(hr))
|
|
{
|
|
//
|
|
// we don't have rollback guid
|
|
//
|
|
|
|
hr = WBEM_S_FALSE;
|
|
}
|
|
|
|
return hr;
|
|
}
|