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.

251 lines
6.3 KiB

  1. //******************************************************************************
  2. //
  3. // TEMPFILT.CPP
  4. //
  5. // Copyright (C) 1996-1999 Microsoft Corporation
  6. //
  7. //******************************************************************************
  8. #include "precomp.h"
  9. #include <stdio.h>
  10. #include "ess.h"
  11. #include "tempfilt.h"
  12. #include <cominit.h>
  13. #include <tkncache.h>
  14. #include <callsec.h>
  15. #include <wbemutil.h>
  16. CTempFilter::CTempFilter(CEssNamespace* pNamespace)
  17. : CGenericFilter(pNamespace), m_wszQueryLanguage(NULL),
  18. m_wszQuery(NULL), m_pSecurity(NULL), m_bInternal( false )
  19. {
  20. }
  21. HRESULT CTempFilter::Initialize( LPCWSTR wszQueryLanguage,
  22. LPCWSTR wszQuery,
  23. long lFlags,
  24. PSID pOwnerSid,
  25. bool bInternal,
  26. IWbemContext* pContext,
  27. IWbemObjectSink* pSink )
  28. {
  29. HRESULT hres;
  30. _DBG_ASSERT( pSink != NULL );
  31. m_pSink = pSink;
  32. m_bInternal = bInternal;
  33. hres = CGenericFilter::Create(wszQueryLanguage, wszQuery);
  34. if(FAILED(hres))
  35. return hres;
  36. LPWSTR wszKey = ComputeThisKey();
  37. if(wszKey == NULL)
  38. return WBEM_E_OUT_OF_MEMORY;
  39. CVectorDeleteMe<WCHAR> vdm(wszKey);
  40. if(!(m_isKey = wszKey))
  41. return WBEM_E_OUT_OF_MEMORY;
  42. m_wszQueryLanguage = CloneWstr(wszQueryLanguage);
  43. if(m_wszQueryLanguage == NULL)
  44. return WBEM_E_OUT_OF_MEMORY;
  45. m_wszQuery = CloneWstr(wszQuery);
  46. if(m_wszQuery == NULL)
  47. return WBEM_E_OUT_OF_MEMORY;
  48. //
  49. // if this filter is effectively permanent, that is it is being created
  50. // on behalf of a permanent subscription ( for cross namespace purposes ),
  51. // then we need to propagate the SID of the original subscription.
  52. // For a normal temp filter, we save the call context and use that later
  53. // for checking access.
  54. //
  55. if ( pOwnerSid == NULL )
  56. {
  57. //
  58. // if this call is an on behalf of an internal call, no need to
  59. // check security.
  60. //
  61. if ( !bInternal )
  62. {
  63. WbemCoGetCallContext( IID_IWbemCallSecurity, (void**)&m_pSecurity);
  64. }
  65. }
  66. else
  67. {
  68. int cOwnerSid = GetLengthSid( pOwnerSid );
  69. m_pOwnerSid = new BYTE[cOwnerSid];
  70. if ( m_pOwnerSid == NULL )
  71. {
  72. return WBEM_E_OUT_OF_MEMORY;
  73. }
  74. memcpy( m_pOwnerSid, pOwnerSid, cOwnerSid );
  75. }
  76. return WBEM_S_NO_ERROR;
  77. }
  78. CTempFilter::~CTempFilter()
  79. {
  80. delete [] m_wszQuery;
  81. delete [] m_wszQueryLanguage;
  82. if(m_pSecurity)
  83. m_pSecurity->Release();
  84. }
  85. DELETE_ME LPWSTR CTempFilter::ComputeThisKey()
  86. {
  87. LPWSTR wszKey = _new WCHAR[20];
  88. if ( wszKey )
  89. {
  90. StringCchPrintfW( wszKey, 20, L"$%p", this);
  91. }
  92. return wszKey;
  93. }
  94. HRESULT CTempFilter::GetCoveringQuery(DELETE_ME LPWSTR& wszQueryLanguage,
  95. DELETE_ME LPWSTR& wszQuery, BOOL& bExact,
  96. DELETE_ME QL_LEVEL_1_RPN_EXPRESSION** ppExp)
  97. {
  98. bExact = TRUE;
  99. wszQueryLanguage = CloneWstr(m_wszQueryLanguage);
  100. if(wszQueryLanguage == NULL)
  101. return WBEM_E_OUT_OF_MEMORY;
  102. wszQuery = CloneWstr(m_wszQuery);
  103. if(wszQuery== NULL)
  104. {
  105. delete [] wszQueryLanguage;
  106. wszQueryLanguage = NULL;
  107. return WBEM_E_OUT_OF_MEMORY;
  108. }
  109. if(ppExp)
  110. {
  111. CTextLexSource src((LPWSTR)wszQuery);
  112. QL1_Parser parser(&src);
  113. int nRes = parser.Parse(ppExp);
  114. if (nRes)
  115. {
  116. delete [] wszQueryLanguage;
  117. delete [] wszQuery;
  118. wszQueryLanguage = NULL;
  119. wszQuery = NULL;
  120. ERRORTRACE((LOG_ESS, "Unable to construct event filter with "
  121. "unparsable "
  122. "query '%S'. The filter is not active\n", wszQuery));
  123. return WBEM_E_UNPARSABLE_QUERY;
  124. }
  125. }
  126. return WBEM_S_NO_ERROR;
  127. }
  128. HRESULT CTempFilter::SetThreadSecurity( IUnknown** ppNewContext )
  129. {
  130. *ppNewContext = NULL;
  131. HRESULT hr;
  132. if ( m_pSecurity != NULL )
  133. {
  134. //
  135. // need to clone the security call context since it could be
  136. // attached to multiple threads at the same time and the security
  137. // class is not designed for this. Since the clone operation is
  138. // also not MT safe, need to use cs here.
  139. //
  140. CInCritSec ics(&m_cs);
  141. CWbemPtr<IWbemCallSecurity> pClone = CWbemCallSecurity::CreateInst();
  142. if ( pClone == NULL )
  143. {
  144. return WBEM_E_OUT_OF_MEMORY;
  145. }
  146. //
  147. // CreateInst() returns a object with ref count of 1. With our
  148. // auto ref assignment operator, it is now 2. Perform a release
  149. // to knock it back down to the desired count.
  150. //
  151. pClone->Release();
  152. IUnknown* pOld;
  153. hr = WbemCoSwitchCallContext( m_pSecurity, &pOld );
  154. if ( FAILED(hr) )
  155. {
  156. return hr;
  157. }
  158. hr = pClone->CloneThreadContext( TRUE );
  159. if ( FAILED(hr) )
  160. {
  161. return hr;
  162. }
  163. hr = WbemCoSwitchCallContext( pClone, &pOld );
  164. if ( FAILED(hr) )
  165. {
  166. return hr;
  167. }
  168. *ppNewContext = pClone;
  169. pClone->AddRef();
  170. }
  171. else
  172. {
  173. hr = WBEM_S_FALSE;
  174. }
  175. return hr;
  176. }
  177. HRESULT CTempFilter::ObtainToken(IWbemToken** ppToken)
  178. {
  179. HRESULT hr;
  180. *ppToken = NULL;
  181. //
  182. // Construct an IWbemToken object to return.
  183. //
  184. if ( m_pSecurity != NULL )
  185. {
  186. CWmiToken* pNewToken = new CWmiToken(m_pSecurity->GetToken());
  187. if ( pNewToken != NULL )
  188. {
  189. hr = pNewToken->QueryInterface(IID_IWbemToken, (void**)ppToken);
  190. }
  191. else
  192. {
  193. hr = WBEM_E_OUT_OF_MEMORY;
  194. }
  195. }
  196. else if ( m_pOwnerSid != NULL )
  197. {
  198. hr = m_pNamespace->GetToken( m_pOwnerSid, ppToken );
  199. }
  200. else if ( m_bInternal )
  201. {
  202. hr = WBEM_S_FALSE;
  203. }
  204. else
  205. {
  206. hr = WBEM_E_FAILED;
  207. }
  208. return hr;
  209. }