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.

1780 lines
51 KiB

  1. //#--------------------------------------------------------------
  2. //
  3. // File: crascom.cpp
  4. //
  5. // Synopsis: Implementation of CRasCom class methods
  6. //
  7. //
  8. // History: 2/10/98 MKarki Created
  9. // 5/15/98 SBens Do not consolidate VSAs.
  10. // 9/16/98 SBens Signature of VSAFilter::radiusFromIAS changed.
  11. // 11/17/99 TPerraut Split code for MS-Filter Attribute added
  12. // 428843
  13. //
  14. //
  15. // Copyright (C) Microsoft Corporation
  16. // All rights reserved.
  17. //
  18. //----------------------------------------------------------------
  19. #include "rascominclude.h"
  20. #include "crascom.h"
  21. #include <iastlutl.h>
  22. const DWORD MAX_SLEEP_TIME = 50; //milli-seconds
  23. //
  24. // const and defines below added for the split functions. 428843
  25. //
  26. const CHAR NUL = '\0';
  27. //
  28. // these are the largest values that the attribute type
  29. // packet type have
  30. //
  31. #define MAX_ATTRIBUTE_TYPE 255
  32. //
  33. // these are the related constants
  34. //
  35. #define MAX_ATTRIBUTE_LENGTH 253
  36. #define MAX_VSA_ATTRIBUTE_LENGTH 247
  37. //++--------------------------------------------------------------
  38. //
  39. // Function: SplitAndAdd
  40. //
  41. // Synopsis: This method is used to remove the original attribute
  42. // and add new ones
  43. // Arguments:
  44. // [in] IAttributesRaw*
  45. // [in] PIASATTRIBUTE
  46. // [in] IASTYPE
  47. // [in] DWORD - attribute length
  48. // [in] DWORD - max attribute length
  49. //
  50. // Returns: HRESULT - status
  51. //
  52. // History: MKarki Created 1/19/99
  53. // TPerraut Copied from CRecvFromPipe::SplitAndAdd 11/17/99
  54. //
  55. // Called By: SplitAttributes
  56. //
  57. //----------------------------------------------------------------
  58. HRESULT SplitAndAdd (
  59. /*[in]*/ IAttributesRaw *pIAttributesRaw,
  60. /*[in]*/ PIASATTRIBUTE pIasAttribute,
  61. /*[in]*/ IASTYPE iasType,
  62. /*[in]*/ DWORD dwAttributeLength,
  63. /*[in]*/ DWORD dwMaxLength
  64. )
  65. {
  66. HRESULT hr = S_OK;
  67. DWORD dwPacketsNeeded = 0;
  68. DWORD dwFailed = 0;
  69. PIASATTRIBUTE *ppAttribArray = NULL;
  70. PATTRIBUTEPOSITION pAttribPos = NULL;
  71. _ASSERT (pIAttributesRaw && pIasAttribute);
  72. __try
  73. {
  74. dwPacketsNeeded = dwAttributeLength / dwMaxLength;
  75. if (dwAttributeLength % dwMaxLength) {++dwPacketsNeeded;}
  76. //
  77. // allocate memory for the ATTRIBUTEPOSITION array
  78. //
  79. pAttribPos = reinterpret_cast <PATTRIBUTEPOSITION> (
  80. ::CoTaskMemAlloc (
  81. sizeof (ATTRIBUTEPOSITION)*dwPacketsNeeded));
  82. if (NULL == pAttribPos)
  83. {
  84. IASTracePrintf (
  85. "Unable to allocate memory for attribute position array "
  86. "while split and add of attributese in out-bound packet"
  87. );
  88. hr = E_OUTOFMEMORY;
  89. __leave;
  90. }
  91. //
  92. // allocate array to store the attributes in
  93. //
  94. ppAttribArray =
  95. reinterpret_cast <PIASATTRIBUTE*> (
  96. ::CoTaskMemAlloc (sizeof (PIASATTRIBUTE)*dwPacketsNeeded));
  97. if (NULL == ppAttribArray)
  98. {
  99. IASTracePrintf (
  100. "Unable to allocate memory"
  101. "while split and add of out-bound attribues"
  102. );
  103. hr = E_OUTOFMEMORY;
  104. __leave;
  105. }
  106. DWORD dwFailed =
  107. ::IASAttributeAlloc (dwPacketsNeeded, ppAttribArray);
  108. if (0 != dwFailed)
  109. {
  110. IASTracePrintf (
  111. "Unable to allocate attributes while splitting out-bound"
  112. "attributes"
  113. );
  114. hr = HRESULT_FROM_WIN32 (dwFailed);
  115. __leave;
  116. }
  117. if (IASTYPE_STRING == iasType)
  118. {
  119. PCHAR pStart = (pIasAttribute->Value).String.pszAnsi;
  120. DWORD dwCopySize = dwMaxLength;
  121. //
  122. // set value in each of the new attributes
  123. //
  124. for (DWORD dwCount1 = 0; dwCount1 < dwPacketsNeeded; dwCount1++)
  125. {
  126. (ppAttribArray[dwCount1])->Value.String.pszAnsi =
  127. reinterpret_cast <PCHAR>
  128. (::CoTaskMemAlloc ((dwCopySize + 1)*sizeof (CHAR)));
  129. if (NULL == (ppAttribArray[dwCount1])->Value.String.pszAnsi)
  130. {
  131. IASTracePrintf (
  132. "Unable to allocate memory for new attribute values"
  133. "while split and add of out-bound attribues"
  134. );
  135. hr = E_OUTOFMEMORY;
  136. __leave;
  137. }
  138. //
  139. // set the value now
  140. //
  141. ::CopyMemory (
  142. (ppAttribArray[dwCount1])->Value.String.pszAnsi,
  143. pStart,
  144. dwCopySize
  145. );
  146. //
  147. // nul terminate the values
  148. //
  149. ((ppAttribArray[dwCount1])->Value.String.pszAnsi)[dwCopySize]=NUL;
  150. (ppAttribArray[dwCount1])->Value.itType = iasType;
  151. (ppAttribArray[dwCount1])->dwId = pIasAttribute->dwId;
  152. (ppAttribArray[dwCount1])->dwFlags = pIasAttribute->dwFlags;
  153. //
  154. // calculate for next attribute
  155. //
  156. pStart = pStart + dwCopySize;
  157. dwAttributeLength -= dwCopySize;
  158. dwCopySize = (dwAttributeLength > dwMaxLength) ?
  159. dwMaxLength : dwAttributeLength;
  160. //
  161. // add attribute to position array
  162. //
  163. pAttribPos[dwCount1].pAttribute = ppAttribArray[dwCount1];
  164. }
  165. }
  166. else
  167. {
  168. PBYTE pStart = (pIasAttribute->Value).OctetString.lpValue;
  169. DWORD dwCopySize = dwMaxLength;
  170. //
  171. // fill the new attributes now
  172. //
  173. for (DWORD dwCount1 = 0; dwCount1 < dwPacketsNeeded; dwCount1++)
  174. {
  175. (ppAttribArray[dwCount1])->Value.OctetString.lpValue =
  176. reinterpret_cast <PBYTE> (::CoTaskMemAlloc (dwCopySize));
  177. if (NULL ==(ppAttribArray[dwCount1])->Value.OctetString.lpValue)
  178. {
  179. IASTracePrintf (
  180. "Unable to allocate memory for new attribute values"
  181. "while split and add of out-bound attribues"
  182. );
  183. hr = E_OUTOFMEMORY;
  184. __leave;
  185. }
  186. //
  187. // set the value now
  188. //
  189. ::CopyMemory (
  190. (ppAttribArray[dwCount1])->Value.OctetString.lpValue,
  191. pStart,
  192. dwCopySize
  193. );
  194. (ppAttribArray[dwCount1])->Value.OctetString.dwLength = dwCopySize;
  195. (ppAttribArray[dwCount1])->Value.itType = iasType;
  196. (ppAttribArray[dwCount1])->dwId = pIasAttribute->dwId;
  197. (ppAttribArray[dwCount1])->dwFlags = pIasAttribute->dwFlags;
  198. //
  199. // calculate for next attribute
  200. //
  201. pStart = pStart + dwCopySize;
  202. dwAttributeLength -= dwCopySize;
  203. dwCopySize = (dwAttributeLength > dwMaxLength) ?
  204. dwMaxLength :
  205. dwAttributeLength;
  206. //
  207. // add attribute to position array
  208. //
  209. pAttribPos[dwCount1].pAttribute = ppAttribArray[dwCount1];
  210. }
  211. }
  212. //
  213. // add the attribute to the collection
  214. //
  215. hr = pIAttributesRaw->AddAttributes (dwPacketsNeeded, pAttribPos);
  216. if (FAILED (hr))
  217. {
  218. IASTracePrintf (
  219. "Failed to add attributes to the collection"
  220. "on split and add out-bound attributes"
  221. );
  222. __leave;
  223. }
  224. }
  225. __finally
  226. {
  227. if ((FAILED (hr)) && (ppAttribArray) && (0 == dwFailed))
  228. {
  229. for (DWORD dwCount = 0; dwCount < dwPacketsNeeded; dwCount++)
  230. {
  231. ::IASAttributeRelease (ppAttribArray[dwCount]);
  232. }
  233. }
  234. if (ppAttribArray) {::CoTaskMemFree (ppAttribArray);}
  235. if (pAttribPos) {::CoTaskMemFree (pAttribPos);}
  236. }
  237. return (hr);
  238. } // end of SplitAndAdd method
  239. //++--------------------------------------------------------------
  240. //
  241. // Function: SplitAttributes
  242. //
  243. // Synopsis: This method is used to split up the following
  244. // out-bound attributes:
  245. // 1) Reply-Message attribute
  246. // 2) MS-Filter-VSA attribute
  247. // 3) MS QuarantineIpFilter attribute (VSA)
  248. //
  249. // Arguments:
  250. // [in] IAttributesRaw*
  251. //
  252. // Returns: HRESULT - status
  253. //
  254. // History: MKarki Created 1/19/99
  255. // TPerraut Copied from CRecvFromPipe::SplitAttributes
  256. // 11/17/99
  257. //
  258. // Called By: CRasCom::Process method
  259. //
  260. //----------------------------------------------------------------
  261. HRESULT SplitAttributes (
  262. /*[in]*/ IAttributesRaw *pIAttributesRaw
  263. )
  264. {
  265. const DWORD SPLIT_ATTRIBUTE_COUNT = 3;
  266. static DWORD AttribIds [] = {
  267. RADIUS_ATTRIBUTE_REPLY_MESSAGE,
  268. MS_ATTRIBUTE_FILTER,
  269. MS_ATTRIBUTE_QUARANTINE_IPFILTER
  270. };
  271. HRESULT hr = S_OK;
  272. DWORD dwAttributesFound = 0;
  273. PATTRIBUTEPOSITION pAttribPos = NULL;
  274. _ASSERT (pIAttributesRaw);
  275. __try
  276. {
  277. //
  278. // get the count of the total attributes in the collection
  279. //
  280. DWORD dwAttributeCount = 0;
  281. hr = pIAttributesRaw->GetAttributeCount (&dwAttributeCount);
  282. if (FAILED (hr))
  283. {
  284. IASTracePrintf (
  285. "Unable to obtain attribute count in request while "
  286. "splitting attributes in out-bound packet "
  287. );
  288. __leave;
  289. }
  290. else if (0 == dwAttributeCount)
  291. {
  292. __leave;
  293. }
  294. //
  295. // allocate memory for the ATTRIBUTEPOSITION array
  296. //
  297. pAttribPos = reinterpret_cast <PATTRIBUTEPOSITION> (
  298. ::CoTaskMemAlloc (
  299. sizeof (ATTRIBUTEPOSITION)*dwAttributeCount)
  300. );
  301. if (NULL == pAttribPos)
  302. {
  303. IASTracePrintf (
  304. "Unable to allocate memory for attribute position array "
  305. "while splitting attributes in out-bound packet"
  306. );
  307. hr = E_OUTOFMEMORY;
  308. __leave;
  309. }
  310. //
  311. // get the attributes we are interested in from the interface
  312. //
  313. hr = pIAttributesRaw->GetAttributes (
  314. &dwAttributeCount,
  315. pAttribPos,
  316. SPLIT_ATTRIBUTE_COUNT,
  317. static_cast <PDWORD> (AttribIds)
  318. );
  319. if (FAILED (hr))
  320. {
  321. IASTracePrintf (
  322. "Unable to obtain information about attributes"
  323. "while splitting attributes in out-bound RADIUS packet"
  324. );
  325. __leave;
  326. }
  327. else if (0 == dwAttributeCount)
  328. {
  329. __leave;
  330. }
  331. //
  332. // save the count of attributes returned
  333. //
  334. dwAttributesFound = dwAttributeCount;
  335. DWORD dwAttribLength = 0;
  336. DWORD dwMaxPossibleLength = 0;
  337. IASTYPE iasType = IASTYPE_INVALID;
  338. //
  339. // evaluate each attribute now
  340. //
  341. for (DWORD dwCount = 0; dwCount < dwAttributeCount; dwCount++)
  342. {
  343. if ((pAttribPos[dwCount].pAttribute)->dwFlags &
  344. IAS_INCLUDE_IN_RESPONSE)
  345. {
  346. //
  347. // get attribute type and length
  348. //
  349. if (
  350. (iasType = (pAttribPos[dwCount].pAttribute)->Value.itType) ==
  351. IASTYPE_STRING
  352. )
  353. {
  354. DWORD dwErr = ::IASAttributeAnsiAlloc(pAttribPos[dwCount].pAttribute);
  355. if (dwErr != NO_ERROR)
  356. {
  357. hr = (HRESULT_FROM_WIN32(dwErr));
  358. __leave;
  359. }
  360. dwAttribLength =
  361. strlen (
  362. (pAttribPos[dwCount].pAttribute)->Value.String.pszAnsi);
  363. }
  364. else if (
  365. (iasType = (pAttribPos[dwCount].pAttribute)->Value.itType) ==
  366. IASTYPE_OCTET_STRING
  367. )
  368. {
  369. dwAttribLength =
  370. (pAttribPos[dwCount].pAttribute)->Value.OctetString.dwLength;
  371. }
  372. else
  373. {
  374. //
  375. // only string values need to be split
  376. //
  377. continue;
  378. }
  379. //
  380. // get max possible attribute length
  381. //
  382. if ((pAttribPos[dwCount].pAttribute)->dwId > MAX_ATTRIBUTE_TYPE)
  383. {
  384. dwMaxPossibleLength = MAX_VSA_ATTRIBUTE_LENGTH;
  385. }
  386. else
  387. {
  388. dwMaxPossibleLength = MAX_ATTRIBUTE_LENGTH;
  389. }
  390. //
  391. // check if we need to split this attribute
  392. //
  393. if (dwAttribLength <= dwMaxPossibleLength) {continue;}
  394. //
  395. // split the attribute now
  396. //
  397. hr = SplitAndAdd (
  398. pIAttributesRaw,
  399. pAttribPos[dwCount].pAttribute,
  400. iasType,
  401. dwAttribLength,
  402. dwMaxPossibleLength
  403. );
  404. if (SUCCEEDED (hr))
  405. {
  406. //
  407. // remove this attribute from the collection now
  408. //
  409. hr = pIAttributesRaw->RemoveAttributes (
  410. 1,
  411. &(pAttribPos[dwCount])
  412. );
  413. if (FAILED (hr))
  414. {
  415. IASTracePrintf (
  416. "Unable to remove attribute from collection"
  417. "while splitting out-bound attributes"
  418. );
  419. }
  420. }
  421. }
  422. }
  423. }
  424. __finally
  425. {
  426. if (pAttribPos)
  427. {
  428. for (DWORD dwCount = 0; dwCount < dwAttributesFound; dwCount++)
  429. {
  430. ::IASAttributeRelease (pAttribPos[dwCount].pAttribute);
  431. }
  432. ::CoTaskMemFree (pAttribPos);
  433. }
  434. }
  435. return (hr);
  436. } // end of SplitAttributes method
  437. //++--------------------------------------------------------------
  438. //
  439. // Function: CRasCom
  440. //
  441. // Synopsis: This is CRasCom Class constructor
  442. //
  443. // Arguments: NONE
  444. //
  445. // Returns: NONE
  446. //
  447. // History: MKarki Created 2/10/98
  448. //
  449. //----------------------------------------------------------------
  450. CRasCom::CRasCom (
  451. VOID
  452. )
  453. :m_objCRequestSource (this),
  454. m_pIRequestHandler(NULL),
  455. m_pIClassFactory (NULL),
  456. m_bVSAFilterInitialized (FALSE),
  457. m_lRequestCount (0),
  458. m_eCompState (COMP_SHUTDOWN)
  459. {
  460. } // end of CRasCom class constructor
  461. //++--------------------------------------------------------------
  462. //
  463. // Function: ~CRasCom
  464. //
  465. // Synopsis: This is CRasCom class destructor
  466. //
  467. // Arguments: NONE
  468. //
  469. // Returns: NONE
  470. //
  471. //
  472. // History: MKarki Created 2/10/98
  473. //
  474. //----------------------------------------------------------------
  475. CRasCom::~CRasCom(
  476. VOID
  477. )
  478. {
  479. } // end of CRasCom class destructor
  480. //++--------------------------------------------------------------
  481. //
  482. // Function: InitNew
  483. //
  484. // Synopsis: This is the InitNew method exposed through the
  485. // IIasComponent COM Interface.
  486. // For the RasCom Component it is implemented for
  487. // completeness
  488. //
  489. //
  490. // Arguments: none
  491. //
  492. // Returns: HRESULT - status
  493. //
  494. // History: MKarki Created 2/10/98
  495. //
  496. // Called By: by the Component intializer through the IIasComponent
  497. // interface
  498. //
  499. //----------------------------------------------------------------
  500. STDMETHODIMP
  501. CRasCom::InitNew (
  502. VOID
  503. )
  504. {
  505. //
  506. // InitNew call can only be made from SHUTDOWN state
  507. //
  508. if (COMP_SHUTDOWN != m_eCompState)
  509. {
  510. IASTracePrintf ("The Surrogate can not be called in this state");
  511. return (E_UNEXPECTED);
  512. }
  513. //
  514. // reset the total pending request count
  515. //
  516. m_lRequestCount = 0;
  517. //
  518. // now we are initialized
  519. m_eCompState = COMP_UNINITIALIZED;
  520. return (S_OK);
  521. } // end of CRasCom::InitNew method
  522. //++--------------------------------------------------------------
  523. //
  524. // Function: Initialize
  525. //
  526. // Synopsis: This is the Initialize method exposed through the
  527. // IIasComponent COM Interface. It initializes the
  528. // Request object ClassFactory
  529. //
  530. // Arguments: none
  531. //
  532. // Returns: HRESULT - status
  533. //
  534. // History: MKarki Created 2/10/98
  535. //
  536. // Called By: by the Component intializer through the IIasComponent
  537. // interface
  538. //
  539. //----------------------------------------------------------------
  540. STDMETHODIMP
  541. CRasCom::Initialize (
  542. VOID
  543. )
  544. {
  545. HRESULT hr = S_OK;
  546. //
  547. // Initialize call can only be made from Uninitialized state
  548. //
  549. if (COMP_INITIALIZED == m_eCompState)
  550. {
  551. return (S_OK);
  552. }
  553. else if (COMP_UNINITIALIZED != m_eCompState)
  554. {
  555. IASTracePrintf ("The Surrogate can not be initialized in this state");
  556. return (E_UNEXPECTED);
  557. }
  558. //
  559. // get the IClassFactory interface to be used to create
  560. // the Request COM object
  561. //
  562. hr = ::CoGetClassObject (
  563. __uuidof (Request),
  564. CLSCTX_INPROC_SERVER,
  565. NULL,
  566. IID_IClassFactory,
  567. reinterpret_cast <PVOID*> (&m_pIClassFactory)
  568. );
  569. if (FAILED (hr))
  570. {
  571. IASTracePrintf ("The Surrogate was unable to obtain request factory");
  572. return (hr);
  573. }
  574. //
  575. // initialize the VSAFilter class object
  576. //
  577. hr = m_objVSAFilter.initialize ();
  578. if (FAILED (hr))
  579. {
  580. IASTracePrintf ("The Surrogate was unable to initializa VSA filtering");
  581. m_pIClassFactory->Release ();
  582. m_pIClassFactory = NULL;
  583. return (hr);
  584. }
  585. else
  586. {
  587. m_bVSAFilterInitialized = TRUE;
  588. }
  589. //
  590. // correctly initialized the surrogate
  591. //
  592. m_eCompState = COMP_INITIALIZED;
  593. return (S_OK);
  594. } // end of CRasCom::Initialize method
  595. //++--------------------------------------------------------------
  596. //
  597. // Function: Shutdown
  598. //
  599. // Synopsis: This is the ShutDown method exposed through the
  600. // IIasComponent COM Interface. It is used to stop
  601. // processing data
  602. //
  603. // Arguments: NONE
  604. //
  605. // Returns: HRESULT - status
  606. //
  607. // History: MKarki Created 2/10/98
  608. //
  609. // Called By: by the Component shutdown through the IIasComponent
  610. // interface
  611. //
  612. //----------------------------------------------------------------
  613. STDMETHODIMP
  614. CRasCom::Shutdown (
  615. VOID
  616. )
  617. {
  618. BOOL bStatus = FALSE;
  619. //
  620. // shutdown can only be called from the suspend state
  621. //
  622. if (COMP_SHUTDOWN == m_eCompState)
  623. {
  624. return (S_OK);
  625. }
  626. else if (
  627. (COMP_SUSPENDED != m_eCompState) &&
  628. (COMP_UNINITIALIZED != m_eCompState)
  629. )
  630. {
  631. IASTracePrintf ("The Surrogate can not be shutdown in current state");
  632. return (E_UNEXPECTED);
  633. }
  634. //
  635. // release the interfaces
  636. //
  637. if (NULL != m_pIRequestHandler)
  638. {
  639. m_pIRequestHandler->Release ();
  640. m_pIRequestHandler = NULL;
  641. }
  642. if (NULL != m_pIClassFactory)
  643. {
  644. m_pIClassFactory->Release ();
  645. m_pIClassFactory = NULL;
  646. }
  647. //
  648. // shutdown the VSAFilter
  649. //
  650. if (TRUE == m_bVSAFilterInitialized)
  651. {
  652. m_objVSAFilter.shutdown ();
  653. m_bVSAFilterInitialized = FALSE;
  654. }
  655. //
  656. // cleanly shutting down
  657. //
  658. m_eCompState = COMP_SHUTDOWN;
  659. return (S_OK);
  660. } // end of CRasCom::Shutdown method
  661. //++--------------------------------------------------------------
  662. //
  663. // Function: Suspend
  664. //
  665. // Synopsis: This is the Suspend method exposed through the
  666. // IComponent COM Interface. It is used to suspend
  667. // packet processing operations
  668. //
  669. // Arguments: NONE
  670. //
  671. // Returns: HRESULT - status
  672. //
  673. //
  674. // History: MKarki Created 10/2/97
  675. //
  676. //----------------------------------------------------------------
  677. STDMETHODIMP
  678. CRasCom::Suspend (
  679. VOID
  680. )
  681. {
  682. BOOL bStatus = FALSE;
  683. HRESULT hr = S_OK;
  684. //
  685. // suspend can only be called from the initialized state
  686. //
  687. if (COMP_SUSPENDED == m_eCompState)
  688. {
  689. return (S_OK);
  690. }
  691. else if (COMP_INITIALIZED != m_eCompState)
  692. {
  693. IASTracePrintf ("The Surrogate can not be suspended in current state");
  694. return (E_UNEXPECTED);
  695. }
  696. //
  697. // change state
  698. //
  699. m_eCompState = COMP_SUSPENDED;
  700. while (0 != m_lRequestCount) { Sleep (MAX_SLEEP_TIME); }
  701. //
  702. // we have successfully suspended RADIUS component's packet
  703. // processing operations
  704. //
  705. return (hr);
  706. } // end of CRasCom::Suspend method
  707. //++--------------------------------------------------------------
  708. //
  709. // Function: Resume
  710. //
  711. // Synopsis: This is the Resume method exposed through the
  712. // IComponent COM Interface. It is used to resume
  713. // packet processing operations which had been
  714. // stopped by a previous call to Suspend API
  715. //
  716. //
  717. // Arguments: NONE
  718. //
  719. // Returns: HRESULT - status
  720. //
  721. //
  722. // History: MKarki Created 10/2/97
  723. //
  724. //----------------------------------------------------------------
  725. STDMETHODIMP
  726. CRasCom::Resume (
  727. VOID
  728. )
  729. {
  730. if (COMP_SUSPENDED != m_eCompState)
  731. {
  732. IASTracePrintf ("The Surrogate can not resume in current state");
  733. return (E_UNEXPECTED);
  734. }
  735. //
  736. // we have successfully resumed operations in the RADIUS component
  737. //
  738. m_eCompState = COMP_INITIALIZED;
  739. return (S_OK);
  740. } // end of CRasCom::Resume method
  741. //++--------------------------------------------------------------
  742. //
  743. // Function: GetProperty
  744. //
  745. // Synopsis: This is the IIasComponent Interface method.
  746. // Only Implemented for the sake of completeness
  747. //
  748. // Arguments:
  749. // [in] LONG - id
  750. // [out] VARIANT - *pValue
  751. //
  752. // Returns: HRESULT - status
  753. //
  754. //
  755. // History: MKarki Created 2/10/98
  756. //
  757. //----------------------------------------------------------------
  758. STDMETHODIMP
  759. CRasCom::GetProperty (
  760. LONG id,
  761. VARIANT *pValue
  762. )
  763. {
  764. return (S_OK);
  765. } // end of CRasCom::GetProperty method
  766. //++--------------------------------------------------------------
  767. //
  768. // Function: PutProperty
  769. //
  770. // Synopsis: This is the IIasComponent Interface method.
  771. // Only Implemented for the sake of completeness
  772. // Arguments:
  773. // [in] LONG - id
  774. // [out] VARIANT - *pValue
  775. //
  776. // Returns: HRESULT - status
  777. //
  778. // History: MKarki Created 2/10/98
  779. //
  780. //----------------------------------------------------------------
  781. STDMETHODIMP
  782. CRasCom::PutProperty (
  783. LONG id,
  784. VARIANT *pValue
  785. )
  786. {
  787. HRESULT hr = S_OK;
  788. //
  789. // PutProperty method can only be called from
  790. // Uninitialized, Initialized or Suspended state
  791. //
  792. if (
  793. (COMP_UNINITIALIZED != m_eCompState) &&
  794. (COMP_INITIALIZED != m_eCompState) &&
  795. (COMP_SUSPENDED == m_eCompState)
  796. )
  797. {
  798. IASTracePrintf ("Surrogate can not put property in current state");
  799. return (E_UNEXPECTED);
  800. }
  801. //
  802. // check if valid arguments where passed in
  803. //
  804. if (NULL == pValue) { return (E_POINTER); }
  805. //
  806. // carry out the property intialization now
  807. //
  808. switch (id)
  809. {
  810. case PROPERTY_PROTOCOL_REQUEST_HANDLER:
  811. if (NULL != m_pIRequestHandler)
  812. {
  813. //
  814. // clients can not be updated in INITIALIZED or
  815. // SUSPENDED state
  816. //
  817. hr = HRESULT_FROM_WIN32 (ERROR_ALREADY_INITIALIZED);
  818. }
  819. else if (VT_DISPATCH != pValue->vt)
  820. {
  821. hr = DISP_E_TYPEMISMATCH;
  822. }
  823. else if (NULL == pValue->punkVal)
  824. {
  825. hr = E_INVALIDARG;
  826. }
  827. else
  828. {
  829. //
  830. // initialize the providers
  831. //
  832. m_pIRequestHandler = reinterpret_cast <IRequestHandler*>
  833. (pValue->punkVal);
  834. m_pIRequestHandler->AddRef ();
  835. }
  836. break;
  837. default:
  838. hr = DISP_E_MEMBERNOTFOUND;
  839. break;
  840. }
  841. return (hr);
  842. } // end of CRasCom::PutProperty method
  843. //++--------------------------------------------------------------
  844. //
  845. // Function: QueryInterfaceReqSrc
  846. //
  847. // Synopsis: This is the function called when this Component
  848. // is called and queried for its IRequestSource
  849. // interface
  850. //
  851. // Arguments:
  852. // [in] PVOID - this object refrence
  853. // [in] REFIID - IID of interface requested
  854. // [out] LPVOID - return appropriate interface
  855. // [in] DWORD
  856. //
  857. //
  858. // Returns: HRESULT - status
  859. //
  860. // History: MKarki Created 2/10/98
  861. //
  862. //----------------------------------------------------------------
  863. HRESULT WINAPI
  864. CRasCom::QueryInterfaceReqSrc (
  865. PVOID pThis,
  866. REFIID riid,
  867. LPVOID *ppv,
  868. DWORD_PTR dwValue
  869. )
  870. {
  871. if ((NULL == pThis) || (NULL == ppv))
  872. return (E_FAIL);
  873. //
  874. // get a reference to the nested CRequestSource object
  875. //
  876. *ppv =
  877. &(static_cast<CRasCom*>(pThis))->m_objCRequestSource;
  878. //
  879. // increment count
  880. //
  881. ((LPUNKNOWN)*ppv)->AddRef();
  882. return (S_OK);
  883. } // end of CRasCom::QueryInterfaceReqSrc method
  884. //++--------------------------------------------------------------
  885. //
  886. // Function: CRequestSource
  887. //
  888. // Synopsis: This is the constructor of the CRequestSource
  889. // nested class
  890. //
  891. // Arguments:
  892. // [in] CRasCom*
  893. //
  894. // Returns: none
  895. //
  896. // History: MKarki Created 2/10/98
  897. //
  898. //----------------------------------------------------------------
  899. CRasCom::CRequestSource::CRequestSource(
  900. CRasCom *pCRasCom
  901. )
  902. :m_pCRasCom (pCRasCom)
  903. {
  904. _ASSERT (NULL != pCRasCom);
  905. } // end of CRequestSource class constructor
  906. //++--------------------------------------------------------------
  907. //
  908. // Function: ~CRequestSource
  909. //
  910. // Synopsis: This is the destructor of the CRequestSource
  911. // nested class
  912. //
  913. // Arguments:
  914. //
  915. // Returns: HRESULT - status
  916. //
  917. //
  918. // History: MKarki Created 11/21/97
  919. //
  920. //----------------------------------------------------------------
  921. CRasCom::CRequestSource::~CRequestSource()
  922. {
  923. } // end of CRequestSource destructor
  924. //++--------------------------------------------------------------
  925. //
  926. // Function: OnRequestComplete
  927. //
  928. // Synopsis: This is a method of IRequestHandler COM interface
  929. // This is the function called when a request is
  930. // is being pushed back after backend processing
  931. // we just return here as we are only be doing
  932. // synchronous processing
  933. //
  934. // Arguments:
  935. // [in] IRequest*
  936. // [in] IASREQUESTSTATUS
  937. //
  938. // Returns: HRESULT - status
  939. //
  940. // History: MKarki Created 2/10/98
  941. //
  942. // Called By: Pipeline through the IRequestHandler interface
  943. //
  944. //----------------------------------------------------------------
  945. STDMETHODIMP CRasCom::CRequestSource::OnRequestComplete (
  946. IRequest *pIRequest,
  947. IASREQUESTSTATUS eStatus
  948. )
  949. {
  950. BOOL bStatus = FALSE;
  951. HANDLE hEvent = NULL;
  952. HRESULT hr = S_OK;
  953. unsigned hyper uhyState = 0;
  954. CComPtr <IRequestState> pIRequestState;
  955. if (NULL == pIRequest)
  956. {
  957. IASTracePrintf (
  958. "Surrogate passed invalid argumen in OnRequestComplete method"
  959. );
  960. return (E_POINTER);
  961. }
  962. //
  963. // get the IRequestState interface now
  964. //
  965. hr = pIRequest->QueryInterface (
  966. __uuidof(IRequestState),
  967. reinterpret_cast <PVOID*> (&pIRequestState)
  968. );
  969. if (FAILED (hr))
  970. {
  971. IASTracePrintf (
  972. "Surrogate unable to obtain IRequestState interface in"
  973. " OnRequestComplete method"
  974. );
  975. return (hr);
  976. }
  977. //
  978. // get the CPacketRadius class object
  979. //
  980. hr = pIRequestState->Pop (
  981. reinterpret_cast <unsigned hyper*> (&uhyState)
  982. );
  983. if (FAILED (hr))
  984. {
  985. IASTracePrintf (
  986. "Surrogate unable to obtain information from Request State"
  987. " in OnRequestComplete method"
  988. );
  989. return (hr);
  990. }
  991. //
  992. // get the hEvent;
  993. //
  994. hEvent = reinterpret_cast <HANDLE> (uhyState);
  995. //
  996. // set the event now
  997. //
  998. bStatus = ::SetEvent (hEvent);
  999. if (FALSE == bStatus)
  1000. {
  1001. IASTracePrintf (
  1002. "Surrogate unable to send notification that request is"
  1003. " processed in OnRequestComplete method"
  1004. );
  1005. return (E_FAIL);
  1006. }
  1007. return (S_OK);
  1008. } // end of CRasCom::CRequestSource::OnRequestComplete method
  1009. //++--------------------------------------------------------------
  1010. //
  1011. // Function: Process
  1012. //
  1013. // Synopsis: This is the method of the IRecvRequest COM interface
  1014. // It is called to generate and send request to the
  1015. // pipeline
  1016. //
  1017. // Arguments:
  1018. // [in] DWORD - number of in attributes
  1019. // [in] PIASATTRIBUTE* - array of pointer to attribs
  1020. // [out] PDWORD - number of out attributes
  1021. // [out] PIASATTRIBUTE** - pointer
  1022. // [in] LONG
  1023. // [in/out]LONG*
  1024. // [in] IASPROTCOL
  1025. //
  1026. // Returns: HRESULT - status
  1027. //
  1028. // History: MKarki Created 2/10/98
  1029. //
  1030. // Called By: Called by DoRequest C style API
  1031. //
  1032. //----------------------------------------------------------------
  1033. STDMETHODIMP
  1034. CRasCom::Process (
  1035. /*[in]*/ DWORD dwInAttributeCount,
  1036. /*[in]*/ PIASATTRIBUTE *ppInIasAttribute,
  1037. /*[out]*/ PDWORD pdwOutAttributeCount,
  1038. /*[out]*/ PIASATTRIBUTE **pppOutIasAttribute,
  1039. /*[in]*/ LONG IasRequest,
  1040. /*[in/out]*/ LONG *pIasResponse,
  1041. /*[in]*/ IASPROTOCOL IasProtocol,
  1042. /*[out]*/ PLONG plReason,
  1043. /*[in]*/ BOOL bProcessVSA
  1044. )
  1045. {
  1046. DWORD dwCount = 0;
  1047. HRESULT hr = S_OK;
  1048. HANDLE hEvent = NULL;
  1049. DWORD dwRetVal = 0;
  1050. IRequest *pIRequest = NULL;
  1051. IAttributesRaw *pIAttributesRaw = NULL;
  1052. IRequestState *pIRequestState = NULL;
  1053. PATTRIBUTEPOSITION pIasAttribPos = NULL;
  1054. static DWORD dwRequestCount = 0;
  1055. //
  1056. // check if processing is enabled
  1057. //
  1058. if ((COMP_INITIALIZED != m_eCompState) || (NULL == m_pIRequestHandler))
  1059. {
  1060. IASTracePrintf (
  1061. "Surrogate passed invalid argument for request processing"
  1062. );
  1063. return (E_FAIL);
  1064. }
  1065. __try
  1066. {
  1067. //
  1068. // increment the request count
  1069. //
  1070. InterlockedIncrement (&m_lRequestCount);
  1071. // check if we are processing requests at this time
  1072. //
  1073. if ((COMP_INITIALIZED != m_eCompState) || (NULL == m_pIRequestHandler))
  1074. {
  1075. IASTracePrintf (
  1076. "Surrogate unable to process request in the current state"
  1077. );
  1078. hr = E_FAIL;
  1079. __leave;
  1080. }
  1081. if (
  1082. (0 == dwInAttributeCount) ||
  1083. (NULL == ppInIasAttribute) ||
  1084. (NULL == pdwOutAttributeCount) ||
  1085. (NULL == pppOutIasAttribute) ||
  1086. (NULL == pIasResponse) ||
  1087. (NULL == plReason)
  1088. )
  1089. {
  1090. IASTracePrintf (
  1091. "Surrogate passed invalid argument for processing request"
  1092. );
  1093. hr = E_INVALIDARG;
  1094. __leave;
  1095. }
  1096. _ASSERT (NULL != m_pIClassFactory);
  1097. //
  1098. // create the request object
  1099. //
  1100. HRESULT hr = m_pIClassFactory->CreateInstance (
  1101. NULL,
  1102. __uuidof (IRequest),
  1103. reinterpret_cast <PVOID*> (&pIRequest)
  1104. );
  1105. if (FAILED (hr))
  1106. {
  1107. IASTracePrintf (
  1108. "Surrogate failed in creation of a new request object"
  1109. );
  1110. __leave;
  1111. }
  1112. //
  1113. // get IAttributesRaw interface
  1114. //
  1115. hr = pIRequest->QueryInterface (
  1116. __uuidof (IAttributesRaw),
  1117. reinterpret_cast <PVOID*> (&pIAttributesRaw)
  1118. );
  1119. if (FAILED (hr))
  1120. {
  1121. IASTracePrintf (
  1122. "Surrogate unable to obtain Attribute interface while"
  1123. " processing request"
  1124. );
  1125. __leave;
  1126. }
  1127. //
  1128. // allocate memory for the ATTRIBUTEPOSITION array
  1129. //
  1130. pIasAttribPos = reinterpret_cast <PATTRIBUTEPOSITION>(
  1131. ::CoTaskMemAlloc (
  1132. sizeof (ATTRIBUTEPOSITION)*dwInAttributeCount)
  1133. );
  1134. if (NULL == pIasAttribPos)
  1135. {
  1136. IASTracePrintf (
  1137. "Surrogate unable to allocate memory while processing request"
  1138. );
  1139. hr = E_OUTOFMEMORY;
  1140. __leave;
  1141. }
  1142. //
  1143. // put the attributes in the ATTRIBUTEPOSITION structs
  1144. //
  1145. for (dwCount = 0; dwCount < dwInAttributeCount; dwCount++)
  1146. {
  1147. //
  1148. // mark the attribute as having been received from client
  1149. //
  1150. ppInIasAttribute[dwCount]->dwFlags |= IAS_RECVD_FROM_CLIENT;
  1151. pIasAttribPos[dwCount].pAttribute = ppInIasAttribute[dwCount];
  1152. }
  1153. //
  1154. // put the attributes collection that we are holding into the
  1155. // Request object through the IAttributesRaw interface
  1156. //
  1157. hr = pIAttributesRaw->AddAttributes (
  1158. dwInAttributeCount,
  1159. pIasAttribPos
  1160. );
  1161. if (FAILED (hr))
  1162. {
  1163. IASTracePrintf (
  1164. "Surrogate failed to add attributes to request being processed"
  1165. );
  1166. __leave;
  1167. }
  1168. //
  1169. // set the request type now
  1170. //
  1171. hr = pIRequest->put_Request (IasRequest);
  1172. if (FAILED (hr))
  1173. {
  1174. IASTracePrintf (
  1175. "Surrogate unable to set the request type for processing"
  1176. );
  1177. __leave;
  1178. }
  1179. //
  1180. // set the protocol now
  1181. //
  1182. hr = pIRequest->put_Protocol (IasProtocol);
  1183. if (FAILED (hr))
  1184. {
  1185. IASTracePrintf (
  1186. "Surrogate unable to set protocol type in request for processing"
  1187. );
  1188. __leave;
  1189. }
  1190. //
  1191. // put your IRequestSource interface in now
  1192. //
  1193. hr = pIRequest->put_Source (&m_objCRequestSource);
  1194. if (FAILED (hr))
  1195. {
  1196. IASTracePrintf (
  1197. "Surrogate unable to set source in request for processing"
  1198. );
  1199. __leave;
  1200. }
  1201. //
  1202. // convert the VSA attributes to IAS format if requested
  1203. //
  1204. if (TRUE == bProcessVSA)
  1205. {
  1206. hr = m_objVSAFilter.radiusToIAS (pIAttributesRaw);
  1207. if (FAILED (hr))
  1208. {
  1209. IASTracePrintf (
  1210. "Surrogate unable to convert VSAs to IAS format"
  1211. );
  1212. __leave;
  1213. }
  1214. }
  1215. //
  1216. // create an event which will be used to wake this thread
  1217. // when the pipeline does multithreaded processing
  1218. //
  1219. hEvent = CreateEvent (NULL, TRUE, FALSE, NULL);
  1220. if (NULL == hEvent)
  1221. {
  1222. IASTracePrintf (
  1223. "Surrogate unable to create event while processing request"
  1224. );
  1225. __leave;
  1226. }
  1227. //
  1228. // get the request state interface to put in our state now
  1229. //
  1230. //
  1231. hr = pIRequest->QueryInterface (
  1232. __uuidof (IRequestState),
  1233. reinterpret_cast <PVOID*> (&pIRequestState)
  1234. );
  1235. if (FAILED (hr))
  1236. {
  1237. IASTracePrintf (
  1238. "Surrogate unable to extract request state interface"
  1239. );
  1240. __leave;
  1241. }
  1242. //
  1243. // put in the request state - which is our event handle in
  1244. //
  1245. hr = pIRequestState->Push (
  1246. reinterpret_cast <unsigned hyper> (hEvent)
  1247. );
  1248. if (FAILED (hr))
  1249. {
  1250. IASTracePrintf (
  1251. "Surrogate unable to set event in request state"
  1252. );
  1253. __leave;
  1254. }
  1255. _ASSERT (NULL != m_pIRequestHandler);
  1256. //
  1257. // send the request to the pipeline now
  1258. //
  1259. hr = m_pIRequestHandler->OnRequest (pIRequest);
  1260. if (FAILED (hr))
  1261. {
  1262. IASTracePrintf (
  1263. "Surrogate request failed backend processing..."
  1264. );
  1265. __leave;
  1266. }
  1267. //
  1268. // now wait for the event now
  1269. //
  1270. dwRetVal = ::WaitForSingleObjectEx (hEvent, INFINITE, TRUE);
  1271. if (0XFFFFFFFF == dwRetVal)
  1272. {
  1273. IASTracePrintf (
  1274. "Surrogate failed on waiting for process completion"
  1275. );
  1276. hr = E_FAIL;
  1277. __leave;
  1278. }
  1279. //
  1280. // convert the IAS attributes to VSA format if requested
  1281. //
  1282. if (TRUE == bProcessVSA)
  1283. {
  1284. //
  1285. // TPERRAUT ADDED Bug 428843
  1286. // Always called from RAS with bProcessVSA = true
  1287. //
  1288. // split the attributes which can not fit in a radius packet
  1289. //
  1290. hr = SplitAttributes (pIAttributesRaw);
  1291. if (FAILED (hr))
  1292. {
  1293. IASTracePrintf (
  1294. "TPERRAUT: Unable to split IAS attribute received from backend"
  1295. );
  1296. __leave;
  1297. }
  1298. // TPERRAUT ADDED: END
  1299. hr = m_objVSAFilter.radiusFromIAS (pIAttributesRaw);
  1300. if (FAILED (hr))
  1301. {
  1302. IASTracePrintf (
  1303. "Surrogate failed on extracting VSAs from IAS format"
  1304. );
  1305. __leave;
  1306. }
  1307. }
  1308. //
  1309. // now its time to dismantle the request sent to find out
  1310. // what we got back
  1311. //
  1312. hr = pIRequest->get_Response (pIasResponse);
  1313. if (FAILED (hr))
  1314. {
  1315. IASTracePrintf (
  1316. "Surrogate unable to obtain response from processed request"
  1317. );
  1318. __leave;
  1319. }
  1320. hr = pIRequest->get_Reason (plReason);
  1321. if (FAILED (hr))
  1322. {
  1323. IASTracePrintf (
  1324. "Surrogate unable to obtain reason from processed request"
  1325. );
  1326. __leave;
  1327. }
  1328. //
  1329. // remove all the attributes from the request object now
  1330. //
  1331. hr = RemoveAttributesFromRequest (
  1332. *pIasResponse,
  1333. pIAttributesRaw,
  1334. pdwOutAttributeCount,
  1335. pppOutIasAttribute
  1336. );
  1337. if (FAILED (hr))
  1338. {
  1339. IASTracePrintf (
  1340. "Surrogate unable to remove attributes from processed request"
  1341. );
  1342. __leave;
  1343. }
  1344. }
  1345. __finally
  1346. {
  1347. //
  1348. // do the cleanup now
  1349. //
  1350. if (NULL != hEvent)
  1351. {
  1352. CloseHandle (hEvent);
  1353. }
  1354. if (NULL != pIasAttribPos)
  1355. {
  1356. ::CoTaskMemFree (pIasAttribPos);
  1357. }
  1358. if (NULL != pIRequestState)
  1359. {
  1360. pIRequestState->Release ();
  1361. }
  1362. if (NULL != pIAttributesRaw)
  1363. {
  1364. pIAttributesRaw->Release ();
  1365. }
  1366. if (NULL != pIRequest)
  1367. {
  1368. pIRequest->Release ();
  1369. }
  1370. //
  1371. // increment the requestreceived
  1372. //
  1373. dwRequestCount =
  1374. (0xFFFFFFFF == dwRequestCount) ? 1 : dwRequestCount+ 1;
  1375. //
  1376. // decrement the request count
  1377. //
  1378. InterlockedDecrement (&m_lRequestCount);
  1379. }
  1380. return (hr);
  1381. } // end of CRasCom::Process method
  1382. //++--------------------------------------------------------------
  1383. //
  1384. // Function: RemoveAttributesFromRequest
  1385. //
  1386. // Synopsis: This is the CRasCom class private method
  1387. // that is used to remove the attributes
  1388. // from the Request object through the
  1389. // IAttributesRaw interface
  1390. //
  1391. // Arguments:
  1392. // [in] LONG - response received from pipe
  1393. // [in] IAttributesRaw*
  1394. // [out] PIASATTRIBUTE**
  1395. // [out] PDWORD - out attribute count
  1396. //
  1397. // Returns: HRESULT - status
  1398. //
  1399. // History: MKarki Created 2/10/98
  1400. //
  1401. // Called By: CRasCom::Process method
  1402. //
  1403. //----------------------------------------------------------------
  1404. STDMETHODIMP
  1405. CRasCom::RemoveAttributesFromRequest (
  1406. LONG lResponse,
  1407. IAttributesRaw *pIasAttributesRaw,
  1408. PDWORD pdwOutAttributeCount,
  1409. PIASATTRIBUTE **pppIasAttribute
  1410. )
  1411. {
  1412. HRESULT hr = S_OK;
  1413. PATTRIBUTEPOSITION pIasOutAttributePos = NULL;
  1414. DWORD dwCount = 0;
  1415. DWORD dwAttribCount = 0;
  1416. DWORD dwOutCount = 0;
  1417. BOOL bGotAttributes = FALSE;
  1418. PIASATTRIBUTE pIasAttribute = NULL;
  1419. _ASSERT (
  1420. (NULL != pIasAttributesRaw) &&
  1421. (NULL != pppIasAttribute) &&
  1422. (NULL != pdwOutAttributeCount)
  1423. );
  1424. __try
  1425. {
  1426. //
  1427. // get the count of the attributes remaining in the collection
  1428. // these will be the OUT attributes
  1429. //
  1430. hr = pIasAttributesRaw->GetAttributeCount (&dwAttribCount);
  1431. if (FAILED (hr))
  1432. {
  1433. IASTracePrintf (
  1434. "Surrogate unable to obtain attribute count from request in"
  1435. "while removing attributes from request"
  1436. );
  1437. __leave;
  1438. }
  1439. //
  1440. // allocate memory for the ATTRIBUTEPOSITION array
  1441. //
  1442. pIasOutAttributePos = reinterpret_cast <PATTRIBUTEPOSITION> (
  1443. ::CoTaskMemAlloc (
  1444. sizeof (ATTRIBUTEPOSITION)*(dwAttribCount))
  1445. );
  1446. if (NULL == pIasOutAttributePos)
  1447. {
  1448. IASTracePrintf (
  1449. "Surrogate unable to allocate memory"
  1450. "while removing attributes from request"
  1451. );
  1452. hr = E_OUTOFMEMORY;
  1453. __leave;
  1454. }
  1455. //
  1456. // get all the attributes from the collection
  1457. //
  1458. hr = pIasAttributesRaw->GetAttributes (
  1459. &dwAttribCount,
  1460. pIasOutAttributePos,
  1461. 0,
  1462. NULL
  1463. );
  1464. if (FAILED (hr))
  1465. {
  1466. IASTracePrintf (
  1467. "Surrogate unable get attributes from request interface"
  1468. "while removing attributes"
  1469. );
  1470. __leave;
  1471. }
  1472. //
  1473. // we have obtained the attributes
  1474. //
  1475. bGotAttributes = TRUE;
  1476. //
  1477. // remove the attributes from the collection now
  1478. //
  1479. hr = pIasAttributesRaw->RemoveAttributes (
  1480. dwAttribCount,
  1481. pIasOutAttributePos
  1482. );
  1483. if (FAILED (hr))
  1484. {
  1485. IASTracePrintf (
  1486. "Surrogate unable remove attributes from request"
  1487. );
  1488. __leave;
  1489. }
  1490. //
  1491. // calculate the number of attributes not added by the client
  1492. //
  1493. *pdwOutAttributeCount = 0;
  1494. for (dwCount = 0; dwCount < dwAttribCount; dwCount++)
  1495. {
  1496. pIasAttribute = pIasOutAttributePos[dwCount].pAttribute;
  1497. //
  1498. // verify that this attributes has to be sent to client
  1499. //
  1500. if
  1501. (
  1502. ((pIasAttribute->dwFlags & IAS_INCLUDE_IN_ACCEPT) &&
  1503. (IAS_RESPONSE_ACCESS_ACCEPT == lResponse)) ||
  1504. ((pIasAttribute->dwFlags & IAS_INCLUDE_IN_REJECT) &&
  1505. (IAS_RESPONSE_ACCESS_REJECT == lResponse)) ||
  1506. ((pIasAttribute->dwFlags & IAS_INCLUDE_IN_CHALLENGE) &&
  1507. (IAS_RESPONSE_ACCESS_CHALLENGE == lResponse))
  1508. )
  1509. {
  1510. (*pdwOutAttributeCount)++;
  1511. }
  1512. }
  1513. //
  1514. // allocate memory for PIASATTRIBUTE array
  1515. //
  1516. *pppIasAttribute = reinterpret_cast <PIASATTRIBUTE*> (
  1517. ::CoTaskMemAlloc (sizeof(PIASATTRIBUTE)*(*pdwOutAttributeCount))
  1518. );
  1519. if (NULL == *pppIasAttribute)
  1520. {
  1521. IASTracePrintf (
  1522. "Surrogate unable to allocate memory for attrib pointer array"
  1523. "while removing attribute from request"
  1524. );
  1525. hr = E_OUTOFMEMORY;
  1526. __leave;
  1527. }
  1528. //
  1529. // put the attributes in the PIASATTRIBUTE array
  1530. //
  1531. for (dwCount = 0, dwOutCount = 0; dwCount < dwAttribCount; dwCount++)
  1532. {
  1533. pIasAttribute = pIasOutAttributePos[dwCount].pAttribute;
  1534. if (
  1535. (((pIasAttribute->dwFlags & IAS_INCLUDE_IN_ACCEPT) &&
  1536. (IAS_RESPONSE_ACCESS_ACCEPT == lResponse)) ||
  1537. ((pIasAttribute->dwFlags & IAS_INCLUDE_IN_REJECT) &&
  1538. (IAS_RESPONSE_ACCESS_REJECT == lResponse)) ||
  1539. ((pIasAttribute->dwFlags & IAS_INCLUDE_IN_CHALLENGE) &&
  1540. (IAS_RESPONSE_ACCESS_CHALLENGE == lResponse)))
  1541. &&
  1542. (dwOutCount < *pdwOutAttributeCount)
  1543. )
  1544. {
  1545. //
  1546. // put the out attribute in the output array
  1547. //
  1548. (*pppIasAttribute)[dwOutCount] = pIasAttribute;
  1549. dwOutCount++;
  1550. }
  1551. else
  1552. {
  1553. //
  1554. // decrement the reference count for the
  1555. // attributes we created or the ones we are
  1556. // not sending as out to client
  1557. //
  1558. ::IASAttributeRelease (pIasAttribute);
  1559. }
  1560. }
  1561. //
  1562. // now put in the number of out attribute we are actually
  1563. // giving the client
  1564. //
  1565. *pdwOutAttributeCount = dwOutCount;
  1566. }
  1567. __finally
  1568. {
  1569. //
  1570. // cleanup on failure
  1571. //
  1572. if (FAILED (hr))
  1573. {
  1574. if (NULL != *pppIasAttribute)
  1575. {
  1576. ::CoTaskMemFree (*pppIasAttribute);
  1577. pppIasAttribute = NULL;
  1578. }
  1579. //
  1580. // correct the out attribute count
  1581. //
  1582. *pdwOutAttributeCount = 0;
  1583. //
  1584. // free up all the attributes also
  1585. //
  1586. if ((TRUE == bGotAttributes) && (NULL != pIasOutAttributePos))
  1587. {
  1588. for (dwCount = 0; dwCount < dwAttribCount; dwCount++)
  1589. {
  1590. ::IASAttributeRelease (
  1591. pIasOutAttributePos[dwCount].pAttribute
  1592. );
  1593. }
  1594. }
  1595. }
  1596. //
  1597. // delete the dynamically allocated memory
  1598. //
  1599. if (NULL != pIasOutAttributePos)
  1600. {
  1601. ::CoTaskMemFree (pIasOutAttributePos);
  1602. }
  1603. }
  1604. return (hr);
  1605. } // end of CRasCom::RemoveAttributesFromRequest method