Leaked source code of windows server 2003
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.
 
 
 
 
 
 

229 lines
5.5 KiB

///////////////////////////////////////////////////////////////////////////////
//
// FILE
//
// enforcer.cpp
//
// SYNOPSIS
//
// This file defines the class PolicyEnforcer.
//
///////////////////////////////////////////////////////////////////////////////
#include <ias.h>
#include <iastlutl.h>
#include <iasutil.h>
#include <sdoias.h>
#include <enforcer.h>
#include <factory.h>
#include <policylist.h>
#include <SortedSdoCollection.h>
#include <TunnelTagger.h>
#include <BuildTree.h>
#include <xprparse.h>
_COM_SMARTPTR_TYPEDEF(ISdo, __uuidof(ISdo));
_COM_SMARTPTR_TYPEDEF(ISdoCollection, __uuidof(ISdoCollection));
PolicyEnforcerBase::~PolicyEnforcerBase() throw ()
{
TunnelTagger::Free(tagger);
}
void PolicyEnforcerBase::processException(
IRequest* pRequest,
const _com_error& ce
) throw ()
{
LONG reason;
if (ce.Error() == HRESULT_FROM_WIN32(ERROR_MORE_DATA))
{
reason = IAS_MALFORMED_REQUEST;
}
else
{
reason = IAS_INTERNAL_ERROR;
}
// If there was any kind of error, discard the packet.
pRequest->SetResponse(IAS_RESPONSE_DISCARD_PACKET, reason);
}
void PolicyEnforcerBase::setPolicies(IDispatch* pDisp)
{
using _com_util::CheckError;
if (tagger == 0)
{
tagger = TunnelTagger::Alloc();
}
// Get the underlying collection.
ISdoCollectionPtr collection(pDisp);
// Get the enumerator out of the collection.
IUnknownPtr unk;
CheckError(get__NewSortedEnum(collection, &unk, PROPERTY_POLICY_MERIT));
IEnumVARIANTPtr iter(unk);
// Find out how many policies there are ...
long count;
CheckError(collection->get_Count(&count));
// ... and create a temporary list to hold them.
PolicyList temp;
temp.reserve(count);
//////////
// Iterate through each policy in the collection.
//////////
_variant_t element;
unsigned long fetched;
while (iter->Next(1, &element, &fetched) == S_OK && fetched == 1)
{
// Get an SDO out of the variant.
ISdoPtr policy(element);
element.Clear();
// Get the action and expression from the SDO.
_variant_t policyName, propAction, propExpr;
CheckError(policy->GetProperty(PROPERTY_SDO_NAME, &policyName));
CheckError(policy->GetProperty(PROPERTY_POLICY_ACTION, &propAction));
CheckError(policy->GetProperty(PROPERTY_POLICY_CONSTRAINT, &propExpr));
// Create the Action object.
ActionPtr action(
new Action(
V_BSTR(&policyName),
nameAttr,
propAction,
*tagger
)
);
// Parse the msNPConstraint strings into a token array.
_variant_t tokens;
CheckError(IASParseExpressionEx(&propExpr, &tokens));
// Convert the token array into a logic tree.
IConditionPtr expr;
CheckError(IASBuildExpression(&tokens, &expr));
// Insert the objects into our policy list.
temp.insert(expr, action);
}
//////////
// We successfully traversed the collection, so save the results.
//////////
policies.swap(temp);
}
STDMETHODIMP PolicyEnforcerBase::Shutdown()
{
policies.clear();
// We may as well clear the factory cache here.
theFactoryCache.clear();
return S_OK;
}
STDMETHODIMP PolicyEnforcerBase::PutProperty(LONG Id, VARIANT *pValue)
{
if (pValue == NULL) { return E_INVALIDARG; }
switch (Id)
{
case PROPERTY_NAP_POLICIES_COLLECTION:
{
if (V_VT(pValue) != VT_DISPATCH) { return DISP_E_TYPEMISMATCH; }
try
{
setPolicies(V_DISPATCH(pValue));
}
CATCH_AND_RETURN();
break;
}
default:
{
return DISP_E_MEMBERNOTFOUND;
}
}
return S_OK;
}
IASREQUESTSTATUS PolicyEnforcerBase::onSyncRequest(IRequest* pRequest) throw ()
{
_ASSERT(pRequest != NULL);
return IAS_REQUEST_STATUS_ABORT;
}
IASREQUESTSTATUS PolicyEnforcer::onSyncRequest(IRequest* pRequest) throw ()
{
_ASSERT(pRequest != NULL);
try
{
IASRequest request(pRequest);
if (!policies.apply(request))
{
// Access-Request: reject the user.
request.SetResponse(IAS_RESPONSE_ACCESS_REJECT,
IAS_NO_POLICY_MATCH);
}
}
catch (const _com_error& ce)
{
processException(pRequest, ce);
}
return IAS_REQUEST_STATUS_HANDLED;
}
IASREQUESTSTATUS ProxyPolicyEnforcer::onSyncRequest(IRequest* pRequest) throw ()
{
_ASSERT(pRequest != NULL);
try
{
IASRequest request(pRequest);
if (!policies.apply(request))
{
// If no policy fired, then check is that was an Accounting
// or an access request
// Accounting: discard the packet
if (request.get_Request() == IAS_REQUEST_ACCOUNTING)
{
request.SetResponse(IAS_RESPONSE_DISCARD_PACKET,
IAS_NO_CXN_REQ_POLICY_MATCH);
}
else
{
// Access-Request: reject the user.
request.SetResponse(IAS_RESPONSE_ACCESS_REJECT,
IAS_NO_CXN_REQ_POLICY_MATCH);
}
}
}
catch (const _com_error& ce)
{
processException(pRequest, ce);
}
return IAS_REQUEST_STATUS_HANDLED;
}