|
|
//***************************************************************************
//
// IPSecurity.cpp
//
// Module: WBEM Instance provider
//
// Purpose: IIS IPSecurity class
//
// Copyright (c)1998 Microsoft Corporation, All Rights Reserved
//
//***************************************************************************
#include "iisprov.h"
#include "ipsecurity.h"
#define DEFAULT_TIMEOUT_VALUE 30000
#define BUFFER_SIZE 512
CIPSecurity::CIPSecurity() { m_pADs = NULL; m_pIPSec = NULL; bIsInherit = FALSE; }
CIPSecurity::~CIPSecurity() { CloseSD(); }
void CIPSecurity::CloseSD() { if(m_pIPSec) { m_pIPSec->Release(); m_pIPSec = NULL; }
if(m_pADs) { m_pADs->Release(); m_pADs = NULL; } }
HRESULT CIPSecurity::GetObjectAsync( IWbemClassObject* pObj ) { VARIANT vt; VARIANT vtBstrArray; HRESULT hr;
VARIANT vtTrue; vtTrue.boolVal = VARIANT_TRUE; vtTrue.vt = VT_BOOL;
// IPDeny
hr = m_pIPSec->get_IPDeny(&vt); if(SUCCEEDED(hr)) { hr = LoadBstrArrayFromVariantArray(vt, vtBstrArray); VariantClear(&vt);
if(SUCCEEDED(hr)) { hr = pObj->Put(L"IPDeny", 0, &vtBstrArray, 0); VariantClear(&vtBstrArray); }
if(bIsInherit && SUCCEEDED(hr)) { hr = CUtils::SetPropertyQualifiers( pObj, L"IPDeny", &g_wszIsInherit, &vtTrue, 1); } }
// IPGrant
if(SUCCEEDED(hr)) { hr = m_pIPSec->get_IPGrant(&vt);
if(SUCCEEDED(hr)) { hr = LoadBstrArrayFromVariantArray(vt, vtBstrArray); VariantClear(&vt);
if(SUCCEEDED(hr)) { hr = pObj->Put(L"IPGrant", 0, &vtBstrArray, 0); VariantClear(&vtBstrArray); } if(bIsInherit && SUCCEEDED(hr)) { hr = CUtils::SetPropertyQualifiers( pObj, L"IPGrant", &g_wszIsInherit, &vtTrue, 1); } } }
// DomainDeny
if(SUCCEEDED(hr)) { hr = m_pIPSec->get_DomainDeny(&vt);
if(SUCCEEDED(hr)) { hr = LoadBstrArrayFromVariantArray(vt, vtBstrArray); VariantClear(&vt);
if(SUCCEEDED(hr)) { hr = pObj->Put(L"DomainDeny", 0, &vtBstrArray, 0); VariantClear(&vtBstrArray); }
if(bIsInherit && SUCCEEDED(hr)) { hr = CUtils::SetPropertyQualifiers( pObj, L"DomainDeny", &g_wszIsInherit, &vtTrue, 1); } } }
// DomainGrant
if(SUCCEEDED(hr)) { hr = m_pIPSec->get_DomainGrant(&vt); if(SUCCEEDED(hr)) { hr = LoadBstrArrayFromVariantArray(vt, vtBstrArray); VariantClear(&vt);
if(SUCCEEDED(hr)) { hr = pObj->Put(L"DomainGrant", 0, &vtBstrArray, 0); VariantClear(&vtBstrArray); }
if(bIsInherit && SUCCEEDED(hr)) { hr = CUtils::SetPropertyQualifiers( pObj, L"DomainGrant", &g_wszIsInherit, &vtTrue, 1); } } }
// GrantByDefault
if(SUCCEEDED(hr)) hr = m_pIPSec->get_GrantByDefault(&vt.boolVal); if(SUCCEEDED(hr)) { vt.vt = VT_BOOL; hr = pObj->Put(L"GrantByDefault", 0, &vt, 0); if(bIsInherit && SUCCEEDED(hr)) { hr = CUtils::SetPropertyQualifiers( pObj, L"GrantByDefault", &g_wszIsInherit, &vtTrue, 1); } }
return hr; }
// Convert SAFEARRAY of BSTRs to SAFEARRAY of VARIANTs
HRESULT CIPSecurity::LoadVariantArrayFromBstrArray( VARIANT& i_vtBstr, VARIANT& o_vtVariant) { SAFEARRAYBOUND aDim; SAFEARRAY* pBstrArray = NULL; SAFEARRAY* pVarArray = NULL; BSTR* paBstr = NULL; VARIANT vt; LONG i=0; HRESULT hr = ERROR_SUCCESS;
try { // Verify that the input VARIANT is a BSTR array or NULL.
if (i_vtBstr.vt != (VT_ARRAY | VT_BSTR) && i_vtBstr.vt != VT_NULL) { hr = WBEM_E_INVALID_PARAMETER; THROW_ON_ERROR(hr); }
// Initialize the output VARIANT (Set type to VT_EMPTY)
VariantInit(&o_vtVariant);
// Handle the case when there is no input array
if (i_vtBstr.vt == VT_NULL) { aDim.lLbound = 0; aDim.cElements = 0; } else { // Verify that the input VARIANT contains a SAFEARRAY
pBstrArray = i_vtBstr.parray; if (pBstrArray == NULL) { hr = WBEM_E_INVALID_PARAMETER; THROW_ON_ERROR(hr); }
// Get the size of the BSTR SAFEARRAY.
aDim.lLbound = 0; aDim.cElements = pBstrArray->rgsabound[0].cElements; }
// Create the new VARIANT SAFEARRAY
pVarArray = SafeArrayCreate(VT_VARIANT, 1, &aDim); if (pVarArray == NULL) { hr = E_OUTOFMEMORY; THROW_ON_ERROR(hr); }
// Put the new VARIANT SAFEARRAY into our output VARIANT
o_vtVariant.vt = VT_ARRAY | VT_VARIANT; o_vtVariant.parray = pVarArray;
if(aDim.cElements > 0) { // Get the BSTR SAFEARRAY pointer.
hr = SafeArrayAccessData(pBstrArray, (void**)&paBstr); THROW_ON_ERROR(hr);
// Copy all the BSTRS to VARIANTS
VariantInit(&vt); vt.vt = VT_BSTR; for(i = aDim.lLbound; i < (long) aDim.cElements; i++) { vt.bstrVal = SysAllocString(paBstr[i]); if (vt.bstrVal == NULL) { hr = E_OUTOFMEMORY; THROW_ON_ERROR(hr); } hr = SafeArrayPutElement(pVarArray, &i, &vt); VariantClear(&vt); THROW_ON_ERROR(hr); }
hr = SafeArrayUnaccessData(pBstrArray); THROW_ON_ERROR(hr); } } catch(...) { // Destroy the VARIANT, the contained SAFEARRAY and the VARIANTs in the SAFEARRAY.
// It also free the BSTRS contained in the VARIANTs
VariantClear(&o_vtVariant); } return hr; }
HRESULT CIPSecurity::LoadBstrArrayFromVariantArray( VARIANT& i_vtVariant, VARIANT& o_vtBstr ) { SAFEARRAYBOUND aDim; SAFEARRAY* pVarArray = NULL; SAFEARRAY* pBstrArray = NULL; VARIANT* paVar = NULL; BSTR bstr = NULL; LONG i = 0; HRESULT hr = ERROR_SUCCESS;
try { // Verify the Variant array.
if (i_vtVariant.vt != (VT_ARRAY | VT_VARIANT)) { hr = WBEM_E_INVALID_PARAMETER; THROW_ON_ERROR(hr); }
// Verify that the variant contains a safearray.
pVarArray = i_vtVariant.parray; if (pVarArray == NULL) { hr = WBEM_E_INVALID_PARAMETER; THROW_ON_ERROR(hr); }
// Initialize the out paramter.
VariantInit(&o_vtBstr);
// Get the size of the array.
aDim.lLbound = 0; aDim.cElements = pVarArray->rgsabound[0].cElements;
// Create the new BSTR array
pBstrArray = SafeArrayCreate(VT_BSTR, 1, &aDim); if (pBstrArray == NULL) { hr = E_OUTOFMEMORY; THROW_ON_ERROR(hr); }
// Put the array into the variant.
o_vtBstr.vt = VT_ARRAY | VT_BSTR; o_vtBstr.parray = pBstrArray;
// Get the variant array pointer.
hr = SafeArrayAccessData(pVarArray, (void**)&paVar); THROW_ON_ERROR(hr);
// Copy all the bstrs.
for (i = aDim.lLbound; i < (long) aDim.cElements; i++) { if (paVar[i].vt != VT_BSTR) { hr = WBEM_E_FAILED; THROW_ON_ERROR(hr); } bstr = SysAllocString(paVar[i].bstrVal); if (bstr == NULL) { hr = E_OUTOFMEMORY; THROW_ON_ERROR(hr); } hr = SafeArrayPutElement(pBstrArray, &i, bstr); SysFreeString(bstr); bstr = NULL; THROW_ON_ERROR(hr); }
hr = SafeArrayUnaccessData(pVarArray); THROW_ON_ERROR(hr); } catch (...) { // Destroy the variant, the safearray and the bstr's in the array.
VariantClear(&o_vtBstr); }
return hr; }
HRESULT CIPSecurity::PutObjectAsync( IWbemClassObject* pObj ) { VARIANT vt; VARIANT vtVarArray; HRESULT hr;
// IPDeny
hr = pObj->Get(L"IPDeny", 0, &vt, NULL, NULL); if(SUCCEEDED(hr)) { hr = LoadVariantArrayFromBstrArray(vt, vtVarArray); VariantClear(&vt); if(SUCCEEDED(hr)) { hr = m_pIPSec->put_IPDeny(vtVarArray); VariantClear(&vtVarArray); } }
// IPGrant
if(SUCCEEDED(hr)) { hr = pObj->Get(L"IPGrant", 0, &vt, NULL, NULL);
if(SUCCEEDED(hr)) { hr = LoadVariantArrayFromBstrArray(vt, vtVarArray); VariantClear(&vt); if(SUCCEEDED(hr)) { hr = m_pIPSec->put_IPGrant(vtVarArray); VariantClear(&vtVarArray); } } }
// DomainDeny
if(SUCCEEDED(hr)) { hr = pObj->Get(L"DomainDeny", 0, &vt, NULL, NULL);
if(SUCCEEDED(hr)) { hr = LoadVariantArrayFromBstrArray(vt, vtVarArray); VariantClear(&vt); if(SUCCEEDED(hr)) { hr = m_pIPSec->put_DomainDeny(vtVarArray); VariantClear(&vtVarArray); } } }
// DomainGrant
if(SUCCEEDED(hr)) { hr = pObj->Get(L"DomainGrant", 0, &vt, NULL, NULL);
if(SUCCEEDED(hr)) { hr = LoadVariantArrayFromBstrArray(vt, vtVarArray); VariantClear(&vt); if(SUCCEEDED(hr)) { hr = m_pIPSec->put_DomainGrant(vtVarArray); VariantClear(&vtVarArray); } } }
// GrantByDefault
if(SUCCEEDED(hr)) hr = pObj->Get(L"GrantByDefault", 0, &vt, NULL, NULL); if(SUCCEEDED(hr)) hr = m_pIPSec->put_GrantByDefault(vt.boolVal); VariantClear(&vt);
// set the modified IPSecurity back into the metabase
if(SUCCEEDED(hr)) hr = SetSD();
return hr; }
HRESULT CIPSecurity::OpenSD( _bstr_t bstrAdsPath, IMSAdminBase2* pAdminBase) { _variant_t var; HRESULT hr; IDispatch* pDisp = NULL; METADATA_HANDLE hObjHandle = NULL; DWORD dwBufferSize = 0; METADATA_RECORD mdrMDData; BYTE pBuffer[BUFFER_SIZE]; _bstr_t oldPath;
try { // close SD interface first
CloseSD();
oldPath = bstrAdsPath.copy();
hr = GetAdsPath(bstrAdsPath); if(FAILED(hr)) return hr;
// get m_pADs
hr = ADsGetObject( bstrAdsPath, IID_IADs, (void**)&m_pADs ); if(FAILED(hr)) return hr; // get m_pSD
hr = m_pADs->Get(L"IPSecurity",&var); if(FAILED(hr)) return hr; hr = V_DISPATCH(&var)->QueryInterface( IID_IISIPSecurity, (void**)&m_pIPSec ); if(FAILED(hr)) return hr;
// set bIsInherit
hr = pAdminBase->OpenKey( METADATA_MASTER_ROOT_HANDLE, oldPath, METADATA_PERMISSION_READ, DEFAULT_TIMEOUT_VALUE, &hObjHandle ); if(FAILED(hr)) return hr;
MD_SET_DATA_RECORD(&mdrMDData, MD_IP_SEC, // ID for "IPSecurity"
METADATA_INHERIT | METADATA_ISINHERITED, ALL_METADATA, ALL_METADATA, BUFFER_SIZE, pBuffer); hr = pAdminBase->GetData( hObjHandle, L"", &mdrMDData, &dwBufferSize );
hr = S_OK;
bIsInherit = mdrMDData.dwMDAttributes & METADATA_ISINHERITED;
} catch(...) { hr = E_FAIL; }
if (hObjHandle && pAdminBase) { pAdminBase->CloseKey(hObjHandle); }
return hr; }
HRESULT CIPSecurity::SetSD() { _variant_t var; HRESULT hr; IDispatch* pDisp = NULL;
try { // put IPSecurity
hr = m_pIPSec->QueryInterface( IID_IDispatch, (void**)&pDisp ); if(FAILED(hr)) return hr;
var.vt = VT_DISPATCH; var.pdispVal = pDisp; hr = m_pADs->Put(L"IPSecurity",var); // pDisp will be released by this call Put().
if(FAILED(hr)) return hr;
// Commit the change to the active directory
hr = m_pADs->SetInfo(); } catch(...) { hr = E_FAIL; }
return hr; }
HRESULT CIPSecurity::GetAdsPath(_bstr_t& bstrAdsPath) { DBG_ASSERT(((LPWSTR)bstrAdsPath) != NULL);
WCHAR* p = new WCHAR[bstrAdsPath.length() + 1]; if(p == NULL) return E_OUTOFMEMORY;
lstrcpyW(p, bstrAdsPath);
try { bstrAdsPath = L"IIS://LocalHost";
// trim first three charaters "/LM"
bstrAdsPath += (p+3); } catch(_com_error e) { delete [] p; return e.Error(); }
delete [] p;
return S_OK; }
|