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.
 
 
 
 
 
 

757 lines
16 KiB

//***************************************************************************
//
// adminacl.cpp
//
// Module: WBEM Instance provider
//
// Purpose: IIS AdminACL class
//
// Copyright (c)1998 Microsoft Corporation, All Rights Reserved
//
//***************************************************************************
#include "iisprov.h"
CAdminACL::CAdminACL()
{
m_pADs = NULL;
m_pSD = NULL;
m_pDACL = NULL;
}
CAdminACL::~CAdminACL()
{
CloseSD();
}
void CAdminACL::CloseSD()
{
if(m_pDACL)
{
m_pDACL->Release();
m_pDACL = NULL;
}
if(m_pSD)
{
m_pSD->Release();
m_pSD = NULL;
}
if(m_pADs)
{
m_pADs->Release();
m_pADs = NULL;
}
}
HRESULT CAdminACL::GetObjectAsync(
IWbemClassObject* pObj,
ParsedObjectPath* pParsedObject,
WMI_CLASS* pWMIClass
)
{
if(!m_pSD || !m_pSD || !m_pDACL)
return E_UNEXPECTED;
HRESULT hr = S_OK;
if( pWMIClass->eKeyType == TYPE_AdminACL )
{
hr = PingAdminACL(pObj);
}
else if( pWMIClass->eKeyType == TYPE_AdminACE )
{
_bstr_t bstrTrustee;
GetTrustee(pObj, pParsedObject, bstrTrustee);
hr = GetACE(pObj, bstrTrustee);
}
else
hr = E_INVALIDARG;
return hr;
}
HRESULT CAdminACL::DeleteObjectAsync(ParsedObjectPath* pParsedObject)
{
HRESULT hr = S_OK;
_bstr_t bstrTrustee;
// get the trustee from key
GetTrustee(NULL, pParsedObject, bstrTrustee);
// remove the ACE
hr = RemoveACE(bstrTrustee);
// set the modified AdminACL back into the metabase
if(SUCCEEDED(hr))
hr = SetSD();
return hr;
}
HRESULT CAdminACL::PutObjectAsync(
IWbemClassObject* pObj,
ParsedObjectPath* pParsedObject,
WMI_CLASS* pWMIClass
)
{
if(!m_pSD || !m_pSD || !m_pDACL)
return E_UNEXPECTED;
HRESULT hr;
if( pWMIClass->eKeyType == TYPE_AdminACL )
{
hr = SetAdminACL(pObj);
}
else if( pWMIClass->eKeyType == TYPE_AdminACE )
{
_bstr_t bstrTrustee;
GetTrustee(NULL, pParsedObject, bstrTrustee);
BOOL fAceExisted = FALSE;
hr = UpdateACE(pObj, bstrTrustee, fAceExisted);
if(fAceExisted == FALSE)
hr = AddACE(pObj, bstrTrustee);
}
else
hr = E_INVALIDARG;
// set the modified AdminACL back into the metabase
if(SUCCEEDED(hr))
hr = SetSD();
return hr;
}
HRESULT CAdminACL::PingAdminACL(
IWbemClassObject* pObj
)
{
_variant_t vt;
BSTR bstr;
long lVal;
HRESULT hr;
// Owner
hr = m_pSD->get_Owner(&bstr);
if(SUCCEEDED(hr))
{
vt = bstr;
hr = pObj->Put(L"Owner", 0, &vt, 0);
SysFreeString(bstr);
}
// Group
if(SUCCEEDED(hr))
hr = m_pSD->get_Group(&bstr);
if(SUCCEEDED(hr))
{
vt = bstr;
hr = pObj->Put(L"Group", 0, &vt, 0);
SysFreeString(bstr);
}
// ControlFlags
if(SUCCEEDED(hr))
hr = m_pSD->get_Control(&lVal);
if(SUCCEEDED(hr))
{
vt.vt = VT_I4;
vt.lVal = lVal;
hr = pObj->Put(L"ControlFlags", 0, &vt, 0);
}
return hr;
}
HRESULT CAdminACL::SetAdminACL(
IWbemClassObject* pObj
)
{
_variant_t vt;
HRESULT hr;
// Owner
hr = pObj->Get(L"Owner", 0, &vt, NULL, NULL);
if(SUCCEEDED(hr) && vt.vt == VT_BSTR)
hr = m_pSD->put_Owner(vt.bstrVal);
// Owner
if(SUCCEEDED(hr))
hr = pObj->Get(L"Group", 0, &vt, NULL, NULL);
if(SUCCEEDED(hr) && vt.vt == VT_BSTR)
hr = m_pSD->put_Group(vt.bstrVal);
// ControlFlags
if(SUCCEEDED(hr))
hr = pObj->Get(L"ControlFlags", 0, &vt, NULL, NULL);
if(SUCCEEDED(hr) && vt.vt == VT_I4)
hr = m_pSD->put_Control(vt.lVal);
return hr;
}
HRESULT CAdminACL::OpenSD(_bstr_t bstrAdsPath)
{
_variant_t var;
HRESULT hr;
IDispatch* pDisp = NULL;
// close SD interface first
CloseSD();
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"AdminACL",&var);
if(FAILED(hr))
return hr;
hr = V_DISPATCH(&var)->QueryInterface(
IID_IADsSecurityDescriptor,
(void**)&m_pSD
);
if(FAILED(hr))
return hr;
// get m_pDACL
hr = m_pSD->get_DiscretionaryAcl(&pDisp);
if(FAILED(hr))
return hr;
hr = pDisp->QueryInterface(
IID_IADsAccessControlList,
(void**)&m_pDACL
);
pDisp->Release();
return hr;
}
HRESULT CAdminACL::SetSD()
{
_variant_t var;
HRESULT hr;
IDispatch* pDisp = NULL;
// put m_pDACL
hr = m_pDACL->QueryInterface(
IID_IDispatch,
(void**)&pDisp
);
if(FAILED(hr))
return hr;
hr = m_pSD->put_DiscretionaryAcl(pDisp);
pDisp->Release();
if(FAILED(hr))
return hr;
// put AdminACL
hr = m_pSD->QueryInterface(
IID_IDispatch,
(void**)&pDisp
);
if(FAILED(hr))
return hr;
var.vt = VT_DISPATCH;
var.pdispVal = pDisp;
hr = m_pADs->Put(L"AdminACL",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();
return hr;
}
HRESULT CAdminACL::GetAdsPath(_bstr_t& bstrAdsPath)
{
WCHAR* p = new WCHAR[bstrAdsPath.length() + 1];
if(p == NULL)
return E_OUTOFMEMORY;
lstrcpyW(p, bstrAdsPath);
bstrAdsPath = L"IIS://LocalHost";
// trim first three charaters "/LM"
bstrAdsPath += (p+3);
delete [] p;
return S_OK;
}
HRESULT CAdminACL::PingACE(
IWbemClassObject* pObj,
IADsAccessControlEntry* pACE
)
{
_variant_t vt;
BSTR bstr;
long lVal;
HRESULT hr;
// AccessMask
hr = pACE->get_AccessMask(&lVal);
if(SUCCEEDED(hr))
{
vt.vt = VT_I4;
vt.lVal = lVal;
hr = pObj->Put(L"AccessMask", 0, &vt, 0);
}
// AceType
if(SUCCEEDED(hr))
hr = pACE->get_AceType(&lVal);
if(SUCCEEDED(hr))
{
vt.vt = VT_I4;
vt.lVal = lVal;
hr = pObj->Put(L"AceType", 0, &vt, 0);
}
// AceFlags
if(SUCCEEDED(hr))
hr = pACE->get_AceFlags(&lVal);
if(SUCCEEDED(hr))
{
vt.vt = VT_I4;
vt.lVal = lVal;
hr = pObj->Put(L"AceFlags", 0, &vt, 0);
}
// Flags
if(SUCCEEDED(hr))
hr = pACE->get_Flags(&lVal);
if(SUCCEEDED(hr))
{
vt.vt = VT_I4;
vt.lVal = lVal;
hr = pObj->Put(L"Flags", 0, &vt, 0);
}
// ObjectType
if(SUCCEEDED(hr))
hr = pACE->get_ObjectType(&bstr);
if(SUCCEEDED(hr))
{
vt = bstr;
hr = pObj->Put(L"ObjectType", 0, &vt, 0);
SysFreeString(bstr);
}
// InheritedObjectType
if(SUCCEEDED(hr))
hr = pACE->get_InheritedObjectType(&bstr);
if(SUCCEEDED(hr))
{
vt = bstr;
hr = pObj->Put(L"InheritedObjectType", 0, &vt, 0);
SysFreeString(bstr);
}
return hr;
}
HRESULT CAdminACL::GetACE(
IWbemClassObject* pObj,
_bstr_t& bstrTrustee
)
{
HRESULT hr = S_OK;
_variant_t var;
IEnumVARIANT* pEnum = NULL;
ULONG lFetch;
BSTR bstr;
IDispatch *pDisp = NULL;
IADsAccessControlEntry *pACE = NULL;
hr = GetACEEnum(&pEnum);
if ( FAILED(hr) )
return hr;
//////////////////////////////////////////////
// Enumerate ACEs
//////////////////////////////////////////////
hr = pEnum->Next( 1, &var, &lFetch );
while( hr == S_OK )
{
if ( lFetch == 1 )
{
if ( VT_DISPATCH != V_VT(&var) )
{
hr = E_UNEXPECTED;
break;
}
pDisp = V_DISPATCH(&var);
/////////////////////////////
// Get the individual ACE
/////////////////////////////
hr = pDisp->QueryInterface(
IID_IADsAccessControlEntry,
(void**)&pACE
);
if ( SUCCEEDED(hr) )
{
hr = pACE->get_Trustee(&bstr);
if( SUCCEEDED(hr) && !lstrcmpiW(bstr, bstrTrustee) )
{
hr = PingACE(pObj, pACE);
SysFreeString(bstr);
pACE->Release();
break;
}
SysFreeString(bstr);
pACE->Release();
}
}
hr = pEnum->Next( 1, &var, &lFetch );
}
pEnum->Release();
return hr;
}
HRESULT CAdminACL::RemoveACE(
_bstr_t& bstrTrustee
)
{
HRESULT hRemoved = WBEM_E_INVALID_PARAMETER;
HRESULT hr = S_OK;
_variant_t var;
IEnumVARIANT* pEnum = NULL;
ULONG lFetch;
BSTR bstr;
IDispatch *pDisp = NULL;
IADsAccessControlEntry *pACE = NULL;
hr = GetACEEnum(&pEnum);
if ( FAILED(hr) )
return hr;
//////////////////////////////////////////////
// Enumerate ACEs
//////////////////////////////////////////////
hr = pEnum->Next( 1, &var, &lFetch );
while( hr == S_OK )
{
if ( lFetch == 1 )
{
if ( VT_DISPATCH != V_VT(&var) )
{
hr = E_UNEXPECTED;
break;
}
pDisp = V_DISPATCH(&var);
/////////////////////////////
// Get the individual ACE
/////////////////////////////
hr = pDisp->QueryInterface(
IID_IADsAccessControlEntry,
(void**)&pACE
);
if ( SUCCEEDED(hr) )
{
hr = pACE->get_Trustee(&bstr);
if( SUCCEEDED(hr) && !lstrcmpiW(bstr, bstrTrustee) )
{
// remove ACE
hr = pACE->QueryInterface(IID_IDispatch,(void**)&pDisp);
if ( SUCCEEDED(hr) )
{
hRemoved = m_pDACL->RemoveAce(pDisp);
pDisp->Release();
}
SysFreeString(bstr);
pACE->Release();
break;
}
SysFreeString(bstr);
pACE->Release();
}
}
hr = pEnum->Next( 1, &var, &lFetch );
}
pEnum->Release();
return hRemoved;
}
// parse ParsedObjectPath to get the Trustee key
void CAdminACL::GetTrustee(
IWbemClassObject* pObj,
ParsedObjectPath* pPath,
_bstr_t& bstrTrustee
)
{
KeyRef* pkr;
WCHAR* pszKey = L"Trustee";
pkr = CUtils::GetKey(pPath, pszKey);
if(pkr == NULL)
throw WBEM_E_INVALID_OBJECT;
bstrTrustee = pkr->m_vValue;
if (pObj)
{
_bstr_t bstr = pkr->m_pName;
HRESULT hr = pObj->Put(bstr, 0, &pkr->m_vValue, 0);
THROW_ON_ERROR(hr);
}
}
HRESULT CAdminACL::GetACEEnum(
IEnumVARIANT** pEnum
)
{
HRESULT hr = S_OK;
LPUNKNOWN pUnk = NULL;
if(!pEnum)
return E_INVALIDARG;
if(*pEnum)
(*pEnum)->Release();
hr = m_pDACL->get__NewEnum( &pUnk );
if ( SUCCEEDED(hr) )
{
hr = pUnk->QueryInterface( IID_IEnumVARIANT, (void**) pEnum );
}
return hr;
}
// addd a ACE
HRESULT CAdminACL::AddACE(
IWbemClassObject* pObj,
_bstr_t& bstrTrustee
)
{
HRESULT hr = m_pDACL->put_AclRevision(ADS_SD_REVISION_DS);
if(FAILED(hr))
return hr;
// create a ACE
IADsAccessControlEntry* pACE = NULL;
hr = NewACE(
pObj,
bstrTrustee,
&pACE
);
if(FAILED(hr))
return hr;
// add the ACE
IDispatch* pDisp = NULL;
hr = pACE->QueryInterface(IID_IDispatch,(void**)&pDisp);
if(SUCCEEDED(hr))
{
hr = m_pDACL->AddAce(pDisp);
pDisp->Release();
}
pACE->Release();
return hr;
}
////////////////////////////////////
// function to create an ACE
////////////////////////////////////
HRESULT CAdminACL::NewACE(
IWbemClassObject* pObj,
_bstr_t& bstrTrustee,
IADsAccessControlEntry** ppACE
)
{
if(!ppACE)
return E_INVALIDARG;
HRESULT hr;
hr = CoCreateInstance(
CLSID_AccessControlEntry,
NULL,
CLSCTX_INPROC_SERVER,
IID_IADsAccessControlEntry,
(void**)ppACE
);
// Trustee
_variant_t vt;
if(SUCCEEDED(hr))
hr = (*ppACE)->put_Trustee(bstrTrustee);
if(SUCCEEDED(hr))
hr = SetDataOfACE(pObj, *ppACE);
return hr;
}
HRESULT CAdminACL::SetDataOfACE(
IWbemClassObject* pObj,
IADsAccessControlEntry* pACE
)
{
HRESULT hr;
_variant_t vt;
// AccessMask
hr = pObj->Get(L"AccessMask", 0, &vt, NULL, NULL);
if(SUCCEEDED(hr) && vt.vt == VT_I4)
hr = pACE->put_AccessMask(vt.lVal);
// AceType
if(SUCCEEDED(hr))
hr = pObj->Get(L"AceType", 0, &vt, NULL, NULL);
if(SUCCEEDED(hr) && vt.vt == VT_I4)
hr = pACE->put_AceType(vt.lVal);
// AceFlags
if(SUCCEEDED(hr))
hr = pObj->Get(L"AceFlags", 0, &vt, NULL, NULL);
if(SUCCEEDED(hr) && vt.vt == VT_I4)
hr = pACE->put_AceFlags(vt.lVal);
// Flags
if(SUCCEEDED(hr))
hr = pObj->Get(L"Flags", 0, &vt, NULL, NULL);
if(SUCCEEDED(hr) && vt.vt == VT_I4)
hr = pACE->put_Flags(vt.lVal);
// ObjectType
if(SUCCEEDED(hr))
hr = pObj->Get(L"ObjectType", 0, &vt, NULL, NULL);
if(SUCCEEDED(hr) && vt.vt == VT_BSTR)
hr = pACE->put_ObjectType(vt.bstrVal);
// InheritedObjectType
if(SUCCEEDED(hr))
hr = pObj->Get(L"InheritedObjectType", 0, &vt, NULL, NULL);
if(SUCCEEDED(hr) && vt.vt == VT_BSTR)
hr = pACE->put_InheritedObjectType(vt.bstrVal);
return hr;
}
HRESULT CAdminACL::UpdateACE(
IWbemClassObject* pObj,
_bstr_t& bstrTrustee,
BOOL& fAceExisted
)
{
HRESULT hr = S_OK;
_variant_t var;
IEnumVARIANT* pEnum = NULL;
ULONG lFetch;
BSTR bstr;
IDispatch *pDisp = NULL;
IADsAccessControlEntry *pACE = NULL;
fAceExisted = FALSE;
hr = GetACEEnum(&pEnum);
if ( FAILED(hr) )
return hr;
//////////////////////////////////////////////
// Enumerate ACEs
//////////////////////////////////////////////
hr = pEnum->Next( 1, &var, &lFetch );
while( hr == S_OK )
{
if ( lFetch == 1 )
{
if ( VT_DISPATCH != V_VT(&var) )
{
hr = E_UNEXPECTED;
break;
}
pDisp = V_DISPATCH(&var);
/////////////////////////////
// Get the individual ACE
/////////////////////////////
hr = pDisp->QueryInterface(
IID_IADsAccessControlEntry,
(void**)&pACE
);
if ( SUCCEEDED(hr) )
{
hr = pACE->get_Trustee(&bstr);
if( SUCCEEDED(hr) && !lstrcmpiW(bstr, bstrTrustee) )
{
fAceExisted = TRUE;
// Update the data of the ACE
hr = SetDataOfACE(pObj, pACE);
SysFreeString(bstr);
pACE->Release();
break;
}
SysFreeString(bstr);
pACE->Release();
}
}
hr = pEnum->Next( 1, &var, &lFetch );
}
pEnum->Release();
return hr;
}