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

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // FILE
  4. //
  5. // enforcer.cpp
  6. //
  7. // SYNOPSIS
  8. //
  9. // This file defines the class PolicyEnforcer.
  10. //
  11. ///////////////////////////////////////////////////////////////////////////////
  12. #include <ias.h>
  13. #include <iastlutl.h>
  14. #include <iasutil.h>
  15. #include <sdoias.h>
  16. #include <enforcer.h>
  17. #include <factory.h>
  18. #include <policylist.h>
  19. #include <SortedSdoCollection.h>
  20. #include <TunnelTagger.h>
  21. #include <BuildTree.h>
  22. #include <xprparse.h>
  23. _COM_SMARTPTR_TYPEDEF(ISdo, __uuidof(ISdo));
  24. _COM_SMARTPTR_TYPEDEF(ISdoCollection, __uuidof(ISdoCollection));
  25. PolicyEnforcerBase::~PolicyEnforcerBase() throw ()
  26. {
  27. TunnelTagger::Free(tagger);
  28. }
  29. void PolicyEnforcerBase::processException(
  30. IRequest* pRequest,
  31. const _com_error& ce
  32. ) throw ()
  33. {
  34. LONG reason;
  35. if (ce.Error() == HRESULT_FROM_WIN32(ERROR_MORE_DATA))
  36. {
  37. reason = IAS_MALFORMED_REQUEST;
  38. }
  39. else
  40. {
  41. reason = IAS_INTERNAL_ERROR;
  42. }
  43. // If there was any kind of error, discard the packet.
  44. pRequest->SetResponse(IAS_RESPONSE_DISCARD_PACKET, reason);
  45. }
  46. void PolicyEnforcerBase::setPolicies(IDispatch* pDisp)
  47. {
  48. using _com_util::CheckError;
  49. if (tagger == 0)
  50. {
  51. tagger = TunnelTagger::Alloc();
  52. }
  53. // Get the underlying collection.
  54. ISdoCollectionPtr collection(pDisp);
  55. // Get the enumerator out of the collection.
  56. IUnknownPtr unk;
  57. CheckError(get__NewSortedEnum(collection, &unk, PROPERTY_POLICY_MERIT));
  58. IEnumVARIANTPtr iter(unk);
  59. // Find out how many policies there are ...
  60. long count;
  61. CheckError(collection->get_Count(&count));
  62. // ... and create a temporary list to hold them.
  63. PolicyList temp;
  64. temp.reserve(count);
  65. //////////
  66. // Iterate through each policy in the collection.
  67. //////////
  68. _variant_t element;
  69. unsigned long fetched;
  70. while (iter->Next(1, &element, &fetched) == S_OK && fetched == 1)
  71. {
  72. // Get an SDO out of the variant.
  73. ISdoPtr policy(element);
  74. element.Clear();
  75. // Get the action and expression from the SDO.
  76. _variant_t policyName, propAction, propExpr;
  77. CheckError(policy->GetProperty(PROPERTY_SDO_NAME, &policyName));
  78. CheckError(policy->GetProperty(PROPERTY_POLICY_ACTION, &propAction));
  79. CheckError(policy->GetProperty(PROPERTY_POLICY_CONSTRAINT, &propExpr));
  80. // Create the Action object.
  81. ActionPtr action(
  82. new Action(
  83. V_BSTR(&policyName),
  84. nameAttr,
  85. propAction,
  86. *tagger
  87. )
  88. );
  89. // Parse the msNPConstraint strings into a token array.
  90. _variant_t tokens;
  91. CheckError(IASParseExpressionEx(&propExpr, &tokens));
  92. // Convert the token array into a logic tree.
  93. IConditionPtr expr;
  94. CheckError(IASBuildExpression(&tokens, &expr));
  95. // Insert the objects into our policy list.
  96. temp.insert(expr, action);
  97. }
  98. //////////
  99. // We successfully traversed the collection, so save the results.
  100. //////////
  101. policies.swap(temp);
  102. }
  103. STDMETHODIMP PolicyEnforcerBase::Shutdown()
  104. {
  105. policies.clear();
  106. // We may as well clear the factory cache here.
  107. theFactoryCache.clear();
  108. return S_OK;
  109. }
  110. STDMETHODIMP PolicyEnforcerBase::PutProperty(LONG Id, VARIANT *pValue)
  111. {
  112. if (pValue == NULL) { return E_INVALIDARG; }
  113. switch (Id)
  114. {
  115. case PROPERTY_NAP_POLICIES_COLLECTION:
  116. {
  117. if (V_VT(pValue) != VT_DISPATCH) { return DISP_E_TYPEMISMATCH; }
  118. try
  119. {
  120. setPolicies(V_DISPATCH(pValue));
  121. }
  122. CATCH_AND_RETURN();
  123. break;
  124. }
  125. default:
  126. {
  127. return DISP_E_MEMBERNOTFOUND;
  128. }
  129. }
  130. return S_OK;
  131. }
  132. IASREQUESTSTATUS PolicyEnforcerBase::onSyncRequest(IRequest* pRequest) throw ()
  133. {
  134. _ASSERT(pRequest != NULL);
  135. return IAS_REQUEST_STATUS_ABORT;
  136. }
  137. IASREQUESTSTATUS PolicyEnforcer::onSyncRequest(IRequest* pRequest) throw ()
  138. {
  139. _ASSERT(pRequest != NULL);
  140. try
  141. {
  142. IASRequest request(pRequest);
  143. if (!policies.apply(request))
  144. {
  145. // Access-Request: reject the user.
  146. request.SetResponse(IAS_RESPONSE_ACCESS_REJECT,
  147. IAS_NO_POLICY_MATCH);
  148. }
  149. }
  150. catch (const _com_error& ce)
  151. {
  152. processException(pRequest, ce);
  153. }
  154. return IAS_REQUEST_STATUS_HANDLED;
  155. }
  156. IASREQUESTSTATUS ProxyPolicyEnforcer::onSyncRequest(IRequest* pRequest) throw ()
  157. {
  158. _ASSERT(pRequest != NULL);
  159. try
  160. {
  161. IASRequest request(pRequest);
  162. if (!policies.apply(request))
  163. {
  164. // If no policy fired, then check is that was an Accounting
  165. // or an access request
  166. // Accounting: discard the packet
  167. if (request.get_Request() == IAS_REQUEST_ACCOUNTING)
  168. {
  169. request.SetResponse(IAS_RESPONSE_DISCARD_PACKET,
  170. IAS_NO_CXN_REQ_POLICY_MATCH);
  171. }
  172. else
  173. {
  174. // Access-Request: reject the user.
  175. request.SetResponse(IAS_RESPONSE_ACCESS_REJECT,
  176. IAS_NO_CXN_REQ_POLICY_MATCH);
  177. }
  178. }
  179. }
  180. catch (const _com_error& ce)
  181. {
  182. processException(pRequest, ce);
  183. }
  184. return IAS_REQUEST_STATUS_HANDLED;
  185. }