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.
501 lines
12 KiB
501 lines
12 KiB
/******************************************************************************
|
|
|
|
Copyright (c) 2000 Microsoft Corporation
|
|
|
|
Module Name:
|
|
AccessControlList.cpp
|
|
|
|
Abstract:
|
|
This file contains the implementation of the CPCHAccessControlList class,
|
|
which is used to represent a security descriptor.
|
|
|
|
Revision History:
|
|
Davide Massarenti (Dmassare) 03/22/2000
|
|
created
|
|
|
|
******************************************************************************/
|
|
|
|
#include "StdAfx.h"
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// AccessControlList [@AclRevision]
|
|
//
|
|
// Entries
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
static const CComBSTR s_TAG_ACL ( L"AccessControlList" );
|
|
static const CComBSTR s_ATTR_ACL_AclRevision( L"AclRevision" );
|
|
|
|
static const CComBSTR s_TAG_Entries ( L"Entries" );
|
|
static const CComBSTR s_TAG_ACE ( L"AccessControlEntry" );
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
CPCHAccessControlList::CPCHAccessControlList()
|
|
{
|
|
m_dwAclRevision = 0; // DWORD m_dwAclRevision;
|
|
}
|
|
|
|
CPCHAccessControlList::~CPCHAccessControlList()
|
|
{
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
STDMETHODIMP CPCHAccessControlList::get_AclRevision( /*[out, retval]*/ long *pVal )
|
|
{
|
|
__HCP_BEGIN_PROPERTY_GET("CPCHAccessControlList::get_AclRevision",hr,pVal);
|
|
|
|
*pVal = m_dwAclRevision;
|
|
|
|
__HCP_END_PROPERTY(hr);
|
|
}
|
|
|
|
STDMETHODIMP CPCHAccessControlList::put_AclRevision( /*[in]*/ long newVal )
|
|
{
|
|
__HCP_BEGIN_PROPERTY_PUT("CPCHAccessControlList::put_AclRevision",hr);
|
|
|
|
m_dwAclRevision = newVal;
|
|
|
|
__HCP_END_PROPERTY(hr);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
HRESULT CPCHAccessControlList::CreateItem( /*[out]*/ CPCHAccessControlEntry* *entry )
|
|
{
|
|
__HCP_FUNC_ENTRY( "CPCHAccessControlList::CreateItem" );
|
|
|
|
HRESULT hr;
|
|
MPC::SmartLock<_ThreadModel> lock( this );
|
|
CComPtr<CPCHAccessControlEntry> pACE;
|
|
|
|
__MPC_PARAMCHECK_BEGIN(hr)
|
|
__MPC_PARAMCHECK_POINTER_AND_SET(entry,NULL);
|
|
__MPC_PARAMCHECK_END();
|
|
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CreateInstance( &pACE ));
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, AddItem( pACE ));
|
|
|
|
*entry = pACE.Detach();
|
|
|
|
hr = S_OK;
|
|
|
|
|
|
__HCP_FUNC_CLEANUP;
|
|
|
|
__HCP_FUNC_EXIT(hr);
|
|
}
|
|
|
|
STDMETHODIMP CPCHAccessControlList::AddAce( /*[in]*/ IPCHAccessControlEntry* pAccessControlEntry )
|
|
{
|
|
__HCP_FUNC_ENTRY( "CPCHAccessControlList::AddAce" );
|
|
|
|
HRESULT hr;
|
|
MPC::SmartLock<_ThreadModel> lock( this );
|
|
CollectionIter it;
|
|
|
|
__MPC_PARAMCHECK_BEGIN(hr)
|
|
__MPC_PARAMCHECK_NOTNULL(pAccessControlEntry);
|
|
__MPC_PARAMCHECK_END();
|
|
|
|
|
|
//
|
|
// Verify that there's no duplicate ACE.
|
|
//
|
|
for(it = m_coll.begin(); it != m_coll.end(); it++)
|
|
{
|
|
VARIANT_BOOL fSame;
|
|
|
|
if(it->pdispVal)
|
|
{
|
|
CComPtr<IPCHAccessControlEntry> ace;
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, it->pdispVal->QueryInterface( IID_IPCHAccessControlEntry, (void**)&ace ));
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, ace->IsEquivalent( pAccessControlEntry, &fSame ));
|
|
if(fSame == VARIANT_TRUE)
|
|
{
|
|
__MPC_SET_ERROR_AND_EXIT(hr, S_FALSE); // Duplicate, don't add.
|
|
}
|
|
}
|
|
}
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, AddItem( pAccessControlEntry ));
|
|
|
|
hr = S_OK;
|
|
|
|
|
|
__HCP_FUNC_CLEANUP;
|
|
|
|
__HCP_FUNC_EXIT(hr);
|
|
}
|
|
|
|
STDMETHODIMP CPCHAccessControlList::RemoveAce( /*[in]*/ IPCHAccessControlEntry* pAccessControlEntry )
|
|
{
|
|
__HCP_FUNC_ENTRY( "CPCHAccessControlList::RemoveAce" );
|
|
|
|
HRESULT hr;
|
|
MPC::SmartLock<_ThreadModel> lock( this );
|
|
CollectionIter it;
|
|
|
|
__MPC_PARAMCHECK_BEGIN(hr)
|
|
__MPC_PARAMCHECK_NOTNULL(pAccessControlEntry);
|
|
__MPC_PARAMCHECK_END();
|
|
|
|
|
|
|
|
//
|
|
// Find and remove the entry.
|
|
//
|
|
for(it = m_coll.begin(); it != m_coll.end(); it++)
|
|
{
|
|
VARIANT_BOOL fSame;
|
|
|
|
if(it->pdispVal)
|
|
{
|
|
CComPtr<IPCHAccessControlEntry> ace;
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, it->pdispVal->QueryInterface( IID_IPCHAccessControlEntry, (void**)&ace ));
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, ace->IsEquivalent( pAccessControlEntry, &fSame ));
|
|
if(fSame == VARIANT_TRUE)
|
|
{
|
|
m_coll.erase( it );
|
|
__MPC_SET_ERROR_AND_EXIT(hr, S_OK); // Found, exit.
|
|
}
|
|
}
|
|
}
|
|
|
|
hr = S_FALSE; // Entry not found.
|
|
|
|
|
|
__HCP_FUNC_CLEANUP;
|
|
|
|
__HCP_FUNC_EXIT(hr);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
STDMETHODIMP CPCHAccessControlList::Clone( /*[out, retval]*/ IPCHAccessControlList* *pVal )
|
|
{
|
|
__HCP_FUNC_ENTRY( "CPCHAccessControlList::Clone" );
|
|
|
|
HRESULT hr;
|
|
MPC::SmartLock<_ThreadModel> lock( this );
|
|
CComPtr<CPCHAccessControlList> pNew;
|
|
CPCHAccessControlList* pPtr;
|
|
CollectionIter it;
|
|
|
|
__MPC_PARAMCHECK_BEGIN(hr)
|
|
__MPC_PARAMCHECK_POINTER_AND_SET(pVal,NULL);
|
|
__MPC_PARAMCHECK_END();
|
|
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CreateInstance( &pNew ));
|
|
|
|
pPtr = pNew;
|
|
|
|
pPtr->m_dwAclRevision = m_dwAclRevision;
|
|
|
|
for(it = m_coll.begin(); it != m_coll.end(); it++)
|
|
{
|
|
if(it->pdispVal)
|
|
{
|
|
CComPtr<IPCHAccessControlEntry> aceSrc;
|
|
CComPtr<IPCHAccessControlEntry> aceDst;
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, it->pdispVal->QueryInterface( IID_IPCHAccessControlEntry, (void**)&aceSrc ));
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, aceSrc->Clone( &aceDst ));
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, pPtr->AddItem( aceDst ));
|
|
}
|
|
}
|
|
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, pNew.QueryInterface( pVal ));
|
|
|
|
hr = S_OK;
|
|
|
|
|
|
__HCP_FUNC_CLEANUP;
|
|
|
|
__HCP_FUNC_EXIT(hr);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
HRESULT CPCHAccessControlList::LoadPost( /*[in]*/ MPC::XmlUtil& xml )
|
|
{
|
|
__HCP_FUNC_ENTRY( "CPCHAccessControlList::LoadPost" );
|
|
|
|
HRESULT hr;
|
|
MPC::SmartLock<_ThreadModel> lock( this );
|
|
CComPtr<IXMLDOMNode> xdnNode;
|
|
CComBSTR bstrValue;
|
|
LONG lValue;
|
|
bool fFound;
|
|
|
|
|
|
//
|
|
// Make sure we have something to parse....
|
|
//
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, xml.GetRoot( &xdnNode )); xdnNode.Release();
|
|
|
|
|
|
//
|
|
// Clean up before loading.
|
|
//
|
|
m_dwAclRevision = 0;
|
|
|
|
Erase();
|
|
|
|
|
|
//
|
|
// Read attributes.
|
|
//
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, xml.GetAttribute( NULL, s_ATTR_ACL_AclRevision, lValue, fFound )); if(fFound) m_dwAclRevision = lValue;
|
|
|
|
//
|
|
// Read ACES.
|
|
//
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, xml.GetNode( s_TAG_Entries, &xdnNode ));
|
|
if(xdnNode)
|
|
{
|
|
MPC::XmlUtil subxml( xdnNode );
|
|
CComPtr<IXMLDOMNodeList> xdnlList;
|
|
CComPtr<IXMLDOMNode> xdnSubNode;
|
|
|
|
//
|
|
// Enumerate all the ACE elements.
|
|
//
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, subxml.GetNodes( s_TAG_ACE, &xdnlList ));
|
|
for(;SUCCEEDED(hr = xdnlList->nextNode( &xdnSubNode )) && xdnSubNode != NULL; xdnSubNode = NULL)
|
|
{
|
|
CComPtr<CPCHAccessControlEntry> ace;
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, CreateItem( &ace ));
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, ace->LoadXML( xdnSubNode ));
|
|
}
|
|
}
|
|
|
|
hr = S_OK;
|
|
|
|
|
|
__HCP_FUNC_CLEANUP;
|
|
|
|
__HCP_FUNC_EXIT(hr);
|
|
}
|
|
|
|
STDMETHODIMP CPCHAccessControlList::LoadXML( /*[in]*/ IXMLDOMNode* xdnNode )
|
|
{
|
|
__HCP_FUNC_ENTRY( "CPCHAccessControlList::LoadXML" );
|
|
|
|
HRESULT hr;
|
|
MPC::XmlUtil xml( xdnNode );
|
|
|
|
__MPC_PARAMCHECK_BEGIN(hr)
|
|
__MPC_PARAMCHECK_NOTNULL(xdnNode);
|
|
__MPC_PARAMCHECK_END();
|
|
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, LoadPost( xml ));
|
|
|
|
hr = S_OK;
|
|
|
|
|
|
__HCP_FUNC_CLEANUP;
|
|
|
|
__HCP_FUNC_EXIT(hr);
|
|
}
|
|
|
|
STDMETHODIMP CPCHAccessControlList::LoadXMLAsString( /*[in]*/ BSTR bstrVal )
|
|
{
|
|
__HCP_FUNC_ENTRY( "CPCHAccessControlList::LoadXMLAsString" );
|
|
|
|
HRESULT hr;
|
|
MPC::XmlUtil xml;
|
|
bool fLoaded;
|
|
bool fFound;
|
|
|
|
__MPC_PARAMCHECK_BEGIN(hr)
|
|
__MPC_PARAMCHECK_NOTNULL(bstrVal);
|
|
__MPC_PARAMCHECK_END();
|
|
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, xml.LoadAsString( bstrVal, s_TAG_ACL, fLoaded, &fFound ));
|
|
if(fLoaded == false || fFound == false)
|
|
{
|
|
__MPC_SET_WIN32_ERROR_AND_EXIT(hr, ERROR_BAD_FORMAT);
|
|
}
|
|
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, LoadPost( xml ));
|
|
|
|
hr = S_OK;
|
|
|
|
|
|
__HCP_FUNC_CLEANUP;
|
|
|
|
__HCP_FUNC_EXIT(hr);
|
|
}
|
|
|
|
STDMETHODIMP CPCHAccessControlList::LoadXMLAsStream( /*[in]*/ IUnknown* pStream )
|
|
{
|
|
__HCP_FUNC_ENTRY( "CPCHAccessControlList::LoadXMLAsStream" );
|
|
|
|
HRESULT hr;
|
|
MPC::XmlUtil xml;
|
|
bool fLoaded;
|
|
bool fFound;
|
|
|
|
__MPC_PARAMCHECK_BEGIN(hr)
|
|
__MPC_PARAMCHECK_NOTNULL(pStream);
|
|
__MPC_PARAMCHECK_END();
|
|
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, xml.LoadAsStream( pStream, s_TAG_ACL, fLoaded, &fFound ));
|
|
if(fLoaded == false || fFound == false)
|
|
{
|
|
__MPC_SET_WIN32_ERROR_AND_EXIT(hr, ERROR_BAD_FORMAT);
|
|
}
|
|
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, LoadPost( xml ));
|
|
|
|
hr = S_OK;
|
|
|
|
|
|
__HCP_FUNC_CLEANUP;
|
|
|
|
__HCP_FUNC_EXIT(hr);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
HRESULT CPCHAccessControlList::SavePre( /*[in]*/ MPC::XmlUtil& xml )
|
|
{
|
|
__HCP_FUNC_ENTRY( "CPCHAccessControlList::SavePre" );
|
|
|
|
HRESULT hr;
|
|
MPC::SmartLock<_ThreadModel> lock( this );
|
|
CComPtr<IXMLDOMNode> xdnNode;
|
|
bool fFound;
|
|
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, xml.CreateNode( s_TAG_ACL, &xdnNode ));
|
|
|
|
//
|
|
// Write attributes.
|
|
//
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, xml.PutAttribute( NULL, s_ATTR_ACL_AclRevision, m_dwAclRevision, fFound, xdnNode ));
|
|
|
|
//
|
|
// Write ACES.
|
|
//
|
|
if(m_coll.size())
|
|
{
|
|
CComPtr<IXMLDOMNode> xdnSubNode;
|
|
CComPtr<IXMLDOMNode> xdnSubSubNode;
|
|
CollectionIter it;
|
|
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, xml.CreateNode( s_TAG_Entries, &xdnSubNode, xdnNode ));
|
|
|
|
for(it = m_coll.begin(); it != m_coll.end(); it++)
|
|
{
|
|
if(it->pdispVal)
|
|
{
|
|
CComPtr<IPCHAccessControlEntry> ace;
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, it->pdispVal->QueryInterface( IID_IPCHAccessControlEntry, (void**)&ace ));
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, ace->SaveXML( xdnSubNode, &xdnSubSubNode ));
|
|
}
|
|
}
|
|
}
|
|
|
|
hr = S_OK;
|
|
|
|
|
|
__HCP_FUNC_CLEANUP;
|
|
|
|
__HCP_FUNC_EXIT(hr);
|
|
}
|
|
|
|
STDMETHODIMP CPCHAccessControlList::SaveXML( /*[in ]*/ IXMLDOMNode* xdnRoot ,
|
|
/*[out, retval]*/ IXMLDOMNode* *pxdnNode )
|
|
{
|
|
__HCP_FUNC_ENTRY( "CPCHAccessControlList::SaveXML" );
|
|
|
|
HRESULT hr;
|
|
MPC::XmlUtil xml( xdnRoot );
|
|
|
|
__MPC_PARAMCHECK_BEGIN(hr)
|
|
__MPC_PARAMCHECK_NOTNULL(xdnRoot);
|
|
__MPC_PARAMCHECK_POINTER_AND_SET(pxdnNode,NULL);
|
|
__MPC_PARAMCHECK_END();
|
|
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, SavePre( xml ));
|
|
|
|
hr = S_OK;
|
|
|
|
|
|
__HCP_FUNC_CLEANUP;
|
|
|
|
__HCP_FUNC_EXIT(hr);
|
|
}
|
|
|
|
STDMETHODIMP CPCHAccessControlList::SaveXMLAsString( /*[out, retval]*/ BSTR *bstrVal )
|
|
{
|
|
__HCP_FUNC_ENTRY( "CPCHAccessControlList::SaveXMLAsString" );
|
|
|
|
HRESULT hr;
|
|
MPC::XmlUtil xml;
|
|
|
|
__MPC_PARAMCHECK_BEGIN(hr)
|
|
__MPC_PARAMCHECK_POINTER_AND_SET(bstrVal,NULL);
|
|
__MPC_PARAMCHECK_END();
|
|
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, SavePre( xml ));
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, xml.SaveAsString( bstrVal ));
|
|
|
|
hr = S_OK;
|
|
|
|
|
|
__HCP_FUNC_CLEANUP;
|
|
|
|
__HCP_FUNC_EXIT(hr);
|
|
}
|
|
|
|
STDMETHODIMP CPCHAccessControlList::SaveXMLAsStream( /*[out, retval]*/ IUnknown* *pStream )
|
|
{
|
|
__HCP_FUNC_ENTRY( "CPCHAccessControlList::SaveXMLAsStream" );
|
|
|
|
HRESULT hr;
|
|
MPC::XmlUtil xml;
|
|
|
|
__MPC_PARAMCHECK_BEGIN(hr)
|
|
__MPC_PARAMCHECK_POINTER_AND_SET(pStream,NULL);
|
|
__MPC_PARAMCHECK_END();
|
|
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, SavePre( xml ));
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, xml.SaveAsStream( pStream ));
|
|
|
|
hr = S_OK;
|
|
|
|
|
|
__HCP_FUNC_CLEANUP;
|
|
|
|
__HCP_FUNC_EXIT(hr);
|
|
}
|