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.

501 lines
12 KiB

  1. /******************************************************************************
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. AccessControlList.cpp
  5. Abstract:
  6. This file contains the implementation of the CPCHAccessControlList class,
  7. which is used to represent a security descriptor.
  8. Revision History:
  9. Davide Massarenti (Dmassare) 03/22/2000
  10. created
  11. ******************************************************************************/
  12. #include "StdAfx.h"
  13. ////////////////////////////////////////////////////////////////////////////////
  14. //
  15. // AccessControlList [@AclRevision]
  16. //
  17. // Entries
  18. //
  19. ////////////////////////////////////////////////////////////////////////////////
  20. static const CComBSTR s_TAG_ACL ( L"AccessControlList" );
  21. static const CComBSTR s_ATTR_ACL_AclRevision( L"AclRevision" );
  22. static const CComBSTR s_TAG_Entries ( L"Entries" );
  23. static const CComBSTR s_TAG_ACE ( L"AccessControlEntry" );
  24. ////////////////////////////////////////////////////////////////////////////////
  25. CPCHAccessControlList::CPCHAccessControlList()
  26. {
  27. m_dwAclRevision = 0; // DWORD m_dwAclRevision;
  28. }
  29. CPCHAccessControlList::~CPCHAccessControlList()
  30. {
  31. }
  32. ////////////////////////////////////////////////////////////////////////////////
  33. STDMETHODIMP CPCHAccessControlList::get_AclRevision( /*[out, retval]*/ long *pVal )
  34. {
  35. __HCP_BEGIN_PROPERTY_GET("CPCHAccessControlList::get_AclRevision",hr,pVal);
  36. *pVal = m_dwAclRevision;
  37. __HCP_END_PROPERTY(hr);
  38. }
  39. STDMETHODIMP CPCHAccessControlList::put_AclRevision( /*[in]*/ long newVal )
  40. {
  41. __HCP_BEGIN_PROPERTY_PUT("CPCHAccessControlList::put_AclRevision",hr);
  42. m_dwAclRevision = newVal;
  43. __HCP_END_PROPERTY(hr);
  44. }
  45. ////////////////////////////////////////////////////////////////////////////////
  46. HRESULT CPCHAccessControlList::CreateItem( /*[out]*/ CPCHAccessControlEntry* *entry )
  47. {
  48. __HCP_FUNC_ENTRY( "CPCHAccessControlList::CreateItem" );
  49. HRESULT hr;
  50. MPC::SmartLock<_ThreadModel> lock( this );
  51. CComPtr<CPCHAccessControlEntry> pACE;
  52. __MPC_PARAMCHECK_BEGIN(hr)
  53. __MPC_PARAMCHECK_POINTER_AND_SET(entry,NULL);
  54. __MPC_PARAMCHECK_END();
  55. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CreateInstance( &pACE ));
  56. __MPC_EXIT_IF_METHOD_FAILS(hr, AddItem( pACE ));
  57. *entry = pACE.Detach();
  58. hr = S_OK;
  59. __HCP_FUNC_CLEANUP;
  60. __HCP_FUNC_EXIT(hr);
  61. }
  62. STDMETHODIMP CPCHAccessControlList::AddAce( /*[in]*/ IPCHAccessControlEntry* pAccessControlEntry )
  63. {
  64. __HCP_FUNC_ENTRY( "CPCHAccessControlList::AddAce" );
  65. HRESULT hr;
  66. MPC::SmartLock<_ThreadModel> lock( this );
  67. CollectionIter it;
  68. __MPC_PARAMCHECK_BEGIN(hr)
  69. __MPC_PARAMCHECK_NOTNULL(pAccessControlEntry);
  70. __MPC_PARAMCHECK_END();
  71. //
  72. // Verify that there's no duplicate ACE.
  73. //
  74. for(it = m_coll.begin(); it != m_coll.end(); it++)
  75. {
  76. VARIANT_BOOL fSame;
  77. if(it->pdispVal)
  78. {
  79. CComPtr<IPCHAccessControlEntry> ace;
  80. __MPC_EXIT_IF_METHOD_FAILS(hr, it->pdispVal->QueryInterface( IID_IPCHAccessControlEntry, (void**)&ace ));
  81. __MPC_EXIT_IF_METHOD_FAILS(hr, ace->IsEquivalent( pAccessControlEntry, &fSame ));
  82. if(fSame == VARIANT_TRUE)
  83. {
  84. __MPC_SET_ERROR_AND_EXIT(hr, S_FALSE); // Duplicate, don't add.
  85. }
  86. }
  87. }
  88. __MPC_EXIT_IF_METHOD_FAILS(hr, AddItem( pAccessControlEntry ));
  89. hr = S_OK;
  90. __HCP_FUNC_CLEANUP;
  91. __HCP_FUNC_EXIT(hr);
  92. }
  93. STDMETHODIMP CPCHAccessControlList::RemoveAce( /*[in]*/ IPCHAccessControlEntry* pAccessControlEntry )
  94. {
  95. __HCP_FUNC_ENTRY( "CPCHAccessControlList::RemoveAce" );
  96. HRESULT hr;
  97. MPC::SmartLock<_ThreadModel> lock( this );
  98. CollectionIter it;
  99. __MPC_PARAMCHECK_BEGIN(hr)
  100. __MPC_PARAMCHECK_NOTNULL(pAccessControlEntry);
  101. __MPC_PARAMCHECK_END();
  102. //
  103. // Find and remove the entry.
  104. //
  105. for(it = m_coll.begin(); it != m_coll.end(); it++)
  106. {
  107. VARIANT_BOOL fSame;
  108. if(it->pdispVal)
  109. {
  110. CComPtr<IPCHAccessControlEntry> ace;
  111. __MPC_EXIT_IF_METHOD_FAILS(hr, it->pdispVal->QueryInterface( IID_IPCHAccessControlEntry, (void**)&ace ));
  112. __MPC_EXIT_IF_METHOD_FAILS(hr, ace->IsEquivalent( pAccessControlEntry, &fSame ));
  113. if(fSame == VARIANT_TRUE)
  114. {
  115. m_coll.erase( it );
  116. __MPC_SET_ERROR_AND_EXIT(hr, S_OK); // Found, exit.
  117. }
  118. }
  119. }
  120. hr = S_FALSE; // Entry not found.
  121. __HCP_FUNC_CLEANUP;
  122. __HCP_FUNC_EXIT(hr);
  123. }
  124. ////////////////////////////////////////////////////////////////////////////////
  125. STDMETHODIMP CPCHAccessControlList::Clone( /*[out, retval]*/ IPCHAccessControlList* *pVal )
  126. {
  127. __HCP_FUNC_ENTRY( "CPCHAccessControlList::Clone" );
  128. HRESULT hr;
  129. MPC::SmartLock<_ThreadModel> lock( this );
  130. CComPtr<CPCHAccessControlList> pNew;
  131. CPCHAccessControlList* pPtr;
  132. CollectionIter it;
  133. __MPC_PARAMCHECK_BEGIN(hr)
  134. __MPC_PARAMCHECK_POINTER_AND_SET(pVal,NULL);
  135. __MPC_PARAMCHECK_END();
  136. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CreateInstance( &pNew ));
  137. pPtr = pNew;
  138. pPtr->m_dwAclRevision = m_dwAclRevision;
  139. for(it = m_coll.begin(); it != m_coll.end(); it++)
  140. {
  141. if(it->pdispVal)
  142. {
  143. CComPtr<IPCHAccessControlEntry> aceSrc;
  144. CComPtr<IPCHAccessControlEntry> aceDst;
  145. __MPC_EXIT_IF_METHOD_FAILS(hr, it->pdispVal->QueryInterface( IID_IPCHAccessControlEntry, (void**)&aceSrc ));
  146. __MPC_EXIT_IF_METHOD_FAILS(hr, aceSrc->Clone( &aceDst ));
  147. __MPC_EXIT_IF_METHOD_FAILS(hr, pPtr->AddItem( aceDst ));
  148. }
  149. }
  150. __MPC_EXIT_IF_METHOD_FAILS(hr, pNew.QueryInterface( pVal ));
  151. hr = S_OK;
  152. __HCP_FUNC_CLEANUP;
  153. __HCP_FUNC_EXIT(hr);
  154. }
  155. ////////////////////////////////////////////////////////////////////////////////
  156. HRESULT CPCHAccessControlList::LoadPost( /*[in]*/ MPC::XmlUtil& xml )
  157. {
  158. __HCP_FUNC_ENTRY( "CPCHAccessControlList::LoadPost" );
  159. HRESULT hr;
  160. MPC::SmartLock<_ThreadModel> lock( this );
  161. CComPtr<IXMLDOMNode> xdnNode;
  162. CComBSTR bstrValue;
  163. LONG lValue;
  164. bool fFound;
  165. //
  166. // Make sure we have something to parse....
  167. //
  168. __MPC_EXIT_IF_METHOD_FAILS(hr, xml.GetRoot( &xdnNode )); xdnNode.Release();
  169. //
  170. // Clean up before loading.
  171. //
  172. m_dwAclRevision = 0;
  173. Erase();
  174. //
  175. // Read attributes.
  176. //
  177. __MPC_EXIT_IF_METHOD_FAILS(hr, xml.GetAttribute( NULL, s_ATTR_ACL_AclRevision, lValue, fFound )); if(fFound) m_dwAclRevision = lValue;
  178. //
  179. // Read ACES.
  180. //
  181. __MPC_EXIT_IF_METHOD_FAILS(hr, xml.GetNode( s_TAG_Entries, &xdnNode ));
  182. if(xdnNode)
  183. {
  184. MPC::XmlUtil subxml( xdnNode );
  185. CComPtr<IXMLDOMNodeList> xdnlList;
  186. CComPtr<IXMLDOMNode> xdnSubNode;
  187. //
  188. // Enumerate all the ACE elements.
  189. //
  190. __MPC_EXIT_IF_METHOD_FAILS(hr, subxml.GetNodes( s_TAG_ACE, &xdnlList ));
  191. for(;SUCCEEDED(hr = xdnlList->nextNode( &xdnSubNode )) && xdnSubNode != NULL; xdnSubNode = NULL)
  192. {
  193. CComPtr<CPCHAccessControlEntry> ace;
  194. __MPC_EXIT_IF_METHOD_FAILS(hr, CreateItem( &ace ));
  195. __MPC_EXIT_IF_METHOD_FAILS(hr, ace->LoadXML( xdnSubNode ));
  196. }
  197. }
  198. hr = S_OK;
  199. __HCP_FUNC_CLEANUP;
  200. __HCP_FUNC_EXIT(hr);
  201. }
  202. STDMETHODIMP CPCHAccessControlList::LoadXML( /*[in]*/ IXMLDOMNode* xdnNode )
  203. {
  204. __HCP_FUNC_ENTRY( "CPCHAccessControlList::LoadXML" );
  205. HRESULT hr;
  206. MPC::XmlUtil xml( xdnNode );
  207. __MPC_PARAMCHECK_BEGIN(hr)
  208. __MPC_PARAMCHECK_NOTNULL(xdnNode);
  209. __MPC_PARAMCHECK_END();
  210. __MPC_EXIT_IF_METHOD_FAILS(hr, LoadPost( xml ));
  211. hr = S_OK;
  212. __HCP_FUNC_CLEANUP;
  213. __HCP_FUNC_EXIT(hr);
  214. }
  215. STDMETHODIMP CPCHAccessControlList::LoadXMLAsString( /*[in]*/ BSTR bstrVal )
  216. {
  217. __HCP_FUNC_ENTRY( "CPCHAccessControlList::LoadXMLAsString" );
  218. HRESULT hr;
  219. MPC::XmlUtil xml;
  220. bool fLoaded;
  221. bool fFound;
  222. __MPC_PARAMCHECK_BEGIN(hr)
  223. __MPC_PARAMCHECK_NOTNULL(bstrVal);
  224. __MPC_PARAMCHECK_END();
  225. __MPC_EXIT_IF_METHOD_FAILS(hr, xml.LoadAsString( bstrVal, s_TAG_ACL, fLoaded, &fFound ));
  226. if(fLoaded == false || fFound == false)
  227. {
  228. __MPC_SET_WIN32_ERROR_AND_EXIT(hr, ERROR_BAD_FORMAT);
  229. }
  230. __MPC_EXIT_IF_METHOD_FAILS(hr, LoadPost( xml ));
  231. hr = S_OK;
  232. __HCP_FUNC_CLEANUP;
  233. __HCP_FUNC_EXIT(hr);
  234. }
  235. STDMETHODIMP CPCHAccessControlList::LoadXMLAsStream( /*[in]*/ IUnknown* pStream )
  236. {
  237. __HCP_FUNC_ENTRY( "CPCHAccessControlList::LoadXMLAsStream" );
  238. HRESULT hr;
  239. MPC::XmlUtil xml;
  240. bool fLoaded;
  241. bool fFound;
  242. __MPC_PARAMCHECK_BEGIN(hr)
  243. __MPC_PARAMCHECK_NOTNULL(pStream);
  244. __MPC_PARAMCHECK_END();
  245. __MPC_EXIT_IF_METHOD_FAILS(hr, xml.LoadAsStream( pStream, s_TAG_ACL, fLoaded, &fFound ));
  246. if(fLoaded == false || fFound == false)
  247. {
  248. __MPC_SET_WIN32_ERROR_AND_EXIT(hr, ERROR_BAD_FORMAT);
  249. }
  250. __MPC_EXIT_IF_METHOD_FAILS(hr, LoadPost( xml ));
  251. hr = S_OK;
  252. __HCP_FUNC_CLEANUP;
  253. __HCP_FUNC_EXIT(hr);
  254. }
  255. ////////////////////////////////////////////////////////////////////////////////
  256. HRESULT CPCHAccessControlList::SavePre( /*[in]*/ MPC::XmlUtil& xml )
  257. {
  258. __HCP_FUNC_ENTRY( "CPCHAccessControlList::SavePre" );
  259. HRESULT hr;
  260. MPC::SmartLock<_ThreadModel> lock( this );
  261. CComPtr<IXMLDOMNode> xdnNode;
  262. bool fFound;
  263. __MPC_EXIT_IF_METHOD_FAILS(hr, xml.CreateNode( s_TAG_ACL, &xdnNode ));
  264. //
  265. // Write attributes.
  266. //
  267. __MPC_EXIT_IF_METHOD_FAILS(hr, xml.PutAttribute( NULL, s_ATTR_ACL_AclRevision, m_dwAclRevision, fFound, xdnNode ));
  268. //
  269. // Write ACES.
  270. //
  271. if(m_coll.size())
  272. {
  273. CComPtr<IXMLDOMNode> xdnSubNode;
  274. CComPtr<IXMLDOMNode> xdnSubSubNode;
  275. CollectionIter it;
  276. __MPC_EXIT_IF_METHOD_FAILS(hr, xml.CreateNode( s_TAG_Entries, &xdnSubNode, xdnNode ));
  277. for(it = m_coll.begin(); it != m_coll.end(); it++)
  278. {
  279. if(it->pdispVal)
  280. {
  281. CComPtr<IPCHAccessControlEntry> ace;
  282. __MPC_EXIT_IF_METHOD_FAILS(hr, it->pdispVal->QueryInterface( IID_IPCHAccessControlEntry, (void**)&ace ));
  283. __MPC_EXIT_IF_METHOD_FAILS(hr, ace->SaveXML( xdnSubNode, &xdnSubSubNode ));
  284. }
  285. }
  286. }
  287. hr = S_OK;
  288. __HCP_FUNC_CLEANUP;
  289. __HCP_FUNC_EXIT(hr);
  290. }
  291. STDMETHODIMP CPCHAccessControlList::SaveXML( /*[in ]*/ IXMLDOMNode* xdnRoot ,
  292. /*[out, retval]*/ IXMLDOMNode* *pxdnNode )
  293. {
  294. __HCP_FUNC_ENTRY( "CPCHAccessControlList::SaveXML" );
  295. HRESULT hr;
  296. MPC::XmlUtil xml( xdnRoot );
  297. __MPC_PARAMCHECK_BEGIN(hr)
  298. __MPC_PARAMCHECK_NOTNULL(xdnRoot);
  299. __MPC_PARAMCHECK_POINTER_AND_SET(pxdnNode,NULL);
  300. __MPC_PARAMCHECK_END();
  301. __MPC_EXIT_IF_METHOD_FAILS(hr, SavePre( xml ));
  302. hr = S_OK;
  303. __HCP_FUNC_CLEANUP;
  304. __HCP_FUNC_EXIT(hr);
  305. }
  306. STDMETHODIMP CPCHAccessControlList::SaveXMLAsString( /*[out, retval]*/ BSTR *bstrVal )
  307. {
  308. __HCP_FUNC_ENTRY( "CPCHAccessControlList::SaveXMLAsString" );
  309. HRESULT hr;
  310. MPC::XmlUtil xml;
  311. __MPC_PARAMCHECK_BEGIN(hr)
  312. __MPC_PARAMCHECK_POINTER_AND_SET(bstrVal,NULL);
  313. __MPC_PARAMCHECK_END();
  314. __MPC_EXIT_IF_METHOD_FAILS(hr, SavePre( xml ));
  315. __MPC_EXIT_IF_METHOD_FAILS(hr, xml.SaveAsString( bstrVal ));
  316. hr = S_OK;
  317. __HCP_FUNC_CLEANUP;
  318. __HCP_FUNC_EXIT(hr);
  319. }
  320. STDMETHODIMP CPCHAccessControlList::SaveXMLAsStream( /*[out, retval]*/ IUnknown* *pStream )
  321. {
  322. __HCP_FUNC_ENTRY( "CPCHAccessControlList::SaveXMLAsStream" );
  323. HRESULT hr;
  324. MPC::XmlUtil xml;
  325. __MPC_PARAMCHECK_BEGIN(hr)
  326. __MPC_PARAMCHECK_POINTER_AND_SET(pStream,NULL);
  327. __MPC_PARAMCHECK_END();
  328. __MPC_EXIT_IF_METHOD_FAILS(hr, SavePre( xml ));
  329. __MPC_EXIT_IF_METHOD_FAILS(hr, xml.SaveAsStream( pStream ));
  330. hr = S_OK;
  331. __HCP_FUNC_CLEANUP;
  332. __HCP_FUNC_EXIT(hr);
  333. }