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

//******************************************************************************
//
// TEMPFILT.CPP
//
// Copyright (C) 1996-1999 Microsoft Corporation
//
//******************************************************************************
#include "precomp.h"
#include <stdio.h>
#include "ess.h"
#include "tempfilt.h"
#include <cominit.h>
#include <tkncache.h>
#include <callsec.h>
#include <wbemutil.h>
CTempFilter::CTempFilter(CEssNamespace* pNamespace)
: CGenericFilter(pNamespace), m_wszQueryLanguage(NULL),
m_wszQuery(NULL), m_pSecurity(NULL), m_bInternal( false )
{
}
HRESULT CTempFilter::Initialize( LPCWSTR wszQueryLanguage,
LPCWSTR wszQuery,
long lFlags,
PSID pOwnerSid,
bool bInternal,
IWbemContext* pContext,
IWbemObjectSink* pSink )
{
HRESULT hres;
_DBG_ASSERT( pSink != NULL );
m_pSink = pSink;
m_bInternal = bInternal;
hres = CGenericFilter::Create(wszQueryLanguage, wszQuery);
if(FAILED(hres))
return hres;
LPWSTR wszKey = ComputeThisKey();
if(wszKey == NULL)
return WBEM_E_OUT_OF_MEMORY;
CVectorDeleteMe<WCHAR> vdm(wszKey);
if(!(m_isKey = wszKey))
return WBEM_E_OUT_OF_MEMORY;
m_wszQueryLanguage = CloneWstr(wszQueryLanguage);
if(m_wszQueryLanguage == NULL)
return WBEM_E_OUT_OF_MEMORY;
m_wszQuery = CloneWstr(wszQuery);
if(m_wszQuery == NULL)
return WBEM_E_OUT_OF_MEMORY;
//
// if this filter is effectively permanent, that is it is being created
// on behalf of a permanent subscription ( for cross namespace purposes ),
// then we need to propagate the SID of the original subscription.
// For a normal temp filter, we save the call context and use that later
// for checking access.
//
if ( pOwnerSid == NULL )
{
//
// if this call is an on behalf of an internal call, no need to
// check security.
//
if ( !bInternal )
{
WbemCoGetCallContext( IID_IWbemCallSecurity, (void**)&m_pSecurity);
}
}
else
{
int cOwnerSid = GetLengthSid( pOwnerSid );
m_pOwnerSid = new BYTE[cOwnerSid];
if ( m_pOwnerSid == NULL )
{
return WBEM_E_OUT_OF_MEMORY;
}
memcpy( m_pOwnerSid, pOwnerSid, cOwnerSid );
}
return WBEM_S_NO_ERROR;
}
CTempFilter::~CTempFilter()
{
delete [] m_wszQuery;
delete [] m_wszQueryLanguage;
if(m_pSecurity)
m_pSecurity->Release();
}
DELETE_ME LPWSTR CTempFilter::ComputeThisKey()
{
LPWSTR wszKey = _new WCHAR[20];
if ( wszKey )
{
StringCchPrintfW( wszKey, 20, L"$%p", this);
}
return wszKey;
}
HRESULT CTempFilter::GetCoveringQuery(DELETE_ME LPWSTR& wszQueryLanguage,
DELETE_ME LPWSTR& wszQuery, BOOL& bExact,
DELETE_ME QL_LEVEL_1_RPN_EXPRESSION** ppExp)
{
bExact = TRUE;
wszQueryLanguage = CloneWstr(m_wszQueryLanguage);
if(wszQueryLanguage == NULL)
return WBEM_E_OUT_OF_MEMORY;
wszQuery = CloneWstr(m_wszQuery);
if(wszQuery== NULL)
{
delete [] wszQueryLanguage;
wszQueryLanguage = NULL;
return WBEM_E_OUT_OF_MEMORY;
}
if(ppExp)
{
CTextLexSource src((LPWSTR)wszQuery);
QL1_Parser parser(&src);
int nRes = parser.Parse(ppExp);
if (nRes)
{
delete [] wszQueryLanguage;
delete [] wszQuery;
wszQueryLanguage = NULL;
wszQuery = NULL;
ERRORTRACE((LOG_ESS, "Unable to construct event filter with "
"unparsable "
"query '%S'. The filter is not active\n", wszQuery));
return WBEM_E_UNPARSABLE_QUERY;
}
}
return WBEM_S_NO_ERROR;
}
HRESULT CTempFilter::SetThreadSecurity( IUnknown** ppNewContext )
{
*ppNewContext = NULL;
HRESULT hr;
if ( m_pSecurity != NULL )
{
//
// need to clone the security call context since it could be
// attached to multiple threads at the same time and the security
// class is not designed for this. Since the clone operation is
// also not MT safe, need to use cs here.
//
CInCritSec ics(&m_cs);
CWbemPtr<IWbemCallSecurity> pClone = CWbemCallSecurity::CreateInst();
if ( pClone == NULL )
{
return WBEM_E_OUT_OF_MEMORY;
}
//
// CreateInst() returns a object with ref count of 1. With our
// auto ref assignment operator, it is now 2. Perform a release
// to knock it back down to the desired count.
//
pClone->Release();
IUnknown* pOld;
hr = WbemCoSwitchCallContext( m_pSecurity, &pOld );
if ( FAILED(hr) )
{
return hr;
}
hr = pClone->CloneThreadContext( TRUE );
if ( FAILED(hr) )
{
return hr;
}
hr = WbemCoSwitchCallContext( pClone, &pOld );
if ( FAILED(hr) )
{
return hr;
}
*ppNewContext = pClone;
pClone->AddRef();
}
else
{
hr = WBEM_S_FALSE;
}
return hr;
}
HRESULT CTempFilter::ObtainToken(IWbemToken** ppToken)
{
HRESULT hr;
*ppToken = NULL;
//
// Construct an IWbemToken object to return.
//
if ( m_pSecurity != NULL )
{
CWmiToken* pNewToken = new CWmiToken(m_pSecurity->GetToken());
if ( pNewToken != NULL )
{
hr = pNewToken->QueryInterface(IID_IWbemToken, (void**)ppToken);
}
else
{
hr = WBEM_E_OUT_OF_MEMORY;
}
}
else if ( m_pOwnerSid != NULL )
{
hr = m_pNamespace->GetToken( m_pOwnerSid, ppToken );
}
else if ( m_bInternal )
{
hr = WBEM_S_FALSE;
}
else
{
hr = WBEM_E_FAILED;
}
return hr;
}