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

  1. //***************************************************************************
  2. //
  3. // adminacl.cpp
  4. //
  5. // Module: WBEM Instance provider
  6. //
  7. // Purpose: IIS AdminACL class
  8. //
  9. // Copyright (c)1998 Microsoft Corporation, All Rights Reserved
  10. //
  11. //***************************************************************************
  12. #include "iisprov.h"
  13. CAdminACL::CAdminACL()
  14. {
  15. m_pADs = NULL;
  16. m_pSD = NULL;
  17. m_pDACL = NULL;
  18. }
  19. CAdminACL::~CAdminACL()
  20. {
  21. CloseSD();
  22. }
  23. void CAdminACL::CloseSD()
  24. {
  25. if(m_pDACL)
  26. {
  27. m_pDACL->Release();
  28. m_pDACL = NULL;
  29. }
  30. if(m_pSD)
  31. {
  32. m_pSD->Release();
  33. m_pSD = NULL;
  34. }
  35. if(m_pADs)
  36. {
  37. m_pADs->Release();
  38. m_pADs = NULL;
  39. }
  40. }
  41. HRESULT CAdminACL::GetObjectAsync(
  42. IWbemClassObject* pObj,
  43. ParsedObjectPath* pParsedObject,
  44. WMI_CLASS* pWMIClass
  45. )
  46. {
  47. if(!m_pSD || !m_pSD || !m_pDACL)
  48. return E_UNEXPECTED;
  49. HRESULT hr = S_OK;
  50. if( pWMIClass->eKeyType == TYPE_AdminACL )
  51. {
  52. hr = PingAdminACL(pObj);
  53. }
  54. else if( pWMIClass->eKeyType == TYPE_AdminACE )
  55. {
  56. _bstr_t bstrTrustee;
  57. GetTrustee(pObj, pParsedObject, bstrTrustee);
  58. hr = GetACE(pObj, bstrTrustee);
  59. }
  60. else
  61. hr = E_INVALIDARG;
  62. return hr;
  63. }
  64. HRESULT CAdminACL::DeleteObjectAsync(ParsedObjectPath* pParsedObject)
  65. {
  66. HRESULT hr = S_OK;
  67. _bstr_t bstrTrustee;
  68. // get the trustee from key
  69. GetTrustee(NULL, pParsedObject, bstrTrustee);
  70. // remove the ACE
  71. hr = RemoveACE(bstrTrustee);
  72. // set the modified AdminACL back into the metabase
  73. if(SUCCEEDED(hr))
  74. hr = SetSD();
  75. return hr;
  76. }
  77. HRESULT CAdminACL::PutObjectAsync(
  78. IWbemClassObject* pObj,
  79. ParsedObjectPath* pParsedObject,
  80. WMI_CLASS* pWMIClass
  81. )
  82. {
  83. if(!m_pSD || !m_pSD || !m_pDACL)
  84. return E_UNEXPECTED;
  85. HRESULT hr;
  86. if( pWMIClass->eKeyType == TYPE_AdminACL )
  87. {
  88. hr = SetAdminACL(pObj);
  89. }
  90. else if( pWMIClass->eKeyType == TYPE_AdminACE )
  91. {
  92. _bstr_t bstrTrustee;
  93. GetTrustee(NULL, pParsedObject, bstrTrustee);
  94. BOOL fAceExisted = FALSE;
  95. hr = UpdateACE(pObj, bstrTrustee, fAceExisted);
  96. if(fAceExisted == FALSE)
  97. hr = AddACE(pObj, bstrTrustee);
  98. }
  99. else
  100. hr = E_INVALIDARG;
  101. // set the modified AdminACL back into the metabase
  102. if(SUCCEEDED(hr))
  103. hr = SetSD();
  104. return hr;
  105. }
  106. HRESULT CAdminACL::PingAdminACL(
  107. IWbemClassObject* pObj
  108. )
  109. {
  110. _variant_t vt;
  111. BSTR bstr;
  112. long lVal;
  113. HRESULT hr;
  114. // Owner
  115. hr = m_pSD->get_Owner(&bstr);
  116. if(SUCCEEDED(hr))
  117. {
  118. vt = bstr;
  119. hr = pObj->Put(L"Owner", 0, &vt, 0);
  120. SysFreeString(bstr);
  121. }
  122. // Group
  123. if(SUCCEEDED(hr))
  124. hr = m_pSD->get_Group(&bstr);
  125. if(SUCCEEDED(hr))
  126. {
  127. vt = bstr;
  128. hr = pObj->Put(L"Group", 0, &vt, 0);
  129. SysFreeString(bstr);
  130. }
  131. // ControlFlags
  132. if(SUCCEEDED(hr))
  133. hr = m_pSD->get_Control(&lVal);
  134. if(SUCCEEDED(hr))
  135. {
  136. vt.vt = VT_I4;
  137. vt.lVal = lVal;
  138. hr = pObj->Put(L"ControlFlags", 0, &vt, 0);
  139. }
  140. return hr;
  141. }
  142. HRESULT CAdminACL::SetAdminACL(
  143. IWbemClassObject* pObj
  144. )
  145. {
  146. _variant_t vt;
  147. HRESULT hr;
  148. // Owner
  149. hr = pObj->Get(L"Owner", 0, &vt, NULL, NULL);
  150. if(SUCCEEDED(hr) && vt.vt == VT_BSTR)
  151. hr = m_pSD->put_Owner(vt.bstrVal);
  152. // Owner
  153. if(SUCCEEDED(hr))
  154. hr = pObj->Get(L"Group", 0, &vt, NULL, NULL);
  155. if(SUCCEEDED(hr) && vt.vt == VT_BSTR)
  156. hr = m_pSD->put_Group(vt.bstrVal);
  157. // ControlFlags
  158. if(SUCCEEDED(hr))
  159. hr = pObj->Get(L"ControlFlags", 0, &vt, NULL, NULL);
  160. if(SUCCEEDED(hr) && vt.vt == VT_I4)
  161. hr = m_pSD->put_Control(vt.lVal);
  162. return hr;
  163. }
  164. HRESULT CAdminACL::OpenSD(_bstr_t bstrAdsPath)
  165. {
  166. _variant_t var;
  167. HRESULT hr;
  168. IDispatch* pDisp = NULL;
  169. // close SD interface first
  170. CloseSD();
  171. hr = GetAdsPath(bstrAdsPath);
  172. if(FAILED(hr))
  173. return hr;
  174. // get m_pADs
  175. hr = ADsGetObject(
  176. bstrAdsPath,
  177. IID_IADs,
  178. (void**)&m_pADs
  179. );
  180. if(FAILED(hr))
  181. return hr;
  182. // get m_pSD
  183. hr = m_pADs->Get(L"AdminACL",&var);
  184. if(FAILED(hr))
  185. return hr;
  186. hr = V_DISPATCH(&var)->QueryInterface(
  187. IID_IADsSecurityDescriptor,
  188. (void**)&m_pSD
  189. );
  190. if(FAILED(hr))
  191. return hr;
  192. // get m_pDACL
  193. hr = m_pSD->get_DiscretionaryAcl(&pDisp);
  194. if(FAILED(hr))
  195. return hr;
  196. hr = pDisp->QueryInterface(
  197. IID_IADsAccessControlList,
  198. (void**)&m_pDACL
  199. );
  200. pDisp->Release();
  201. return hr;
  202. }
  203. HRESULT CAdminACL::SetSD()
  204. {
  205. _variant_t var;
  206. HRESULT hr;
  207. IDispatch* pDisp = NULL;
  208. // put m_pDACL
  209. hr = m_pDACL->QueryInterface(
  210. IID_IDispatch,
  211. (void**)&pDisp
  212. );
  213. if(FAILED(hr))
  214. return hr;
  215. hr = m_pSD->put_DiscretionaryAcl(pDisp);
  216. pDisp->Release();
  217. if(FAILED(hr))
  218. return hr;
  219. // put AdminACL
  220. hr = m_pSD->QueryInterface(
  221. IID_IDispatch,
  222. (void**)&pDisp
  223. );
  224. if(FAILED(hr))
  225. return hr;
  226. var.vt = VT_DISPATCH;
  227. var.pdispVal = pDisp;
  228. hr = m_pADs->Put(L"AdminACL",var); // pDisp will be released by this call Put().
  229. if(FAILED(hr))
  230. return hr;
  231. // Commit the change to the active directory
  232. hr = m_pADs->SetInfo();
  233. return hr;
  234. }
  235. HRESULT CAdminACL::GetAdsPath(_bstr_t& bstrAdsPath)
  236. {
  237. WCHAR* p = new WCHAR[bstrAdsPath.length() + 1];
  238. if(p == NULL)
  239. return E_OUTOFMEMORY;
  240. lstrcpyW(p, bstrAdsPath);
  241. bstrAdsPath = L"IIS://LocalHost";
  242. // trim first three charaters "/LM"
  243. bstrAdsPath += (p+3);
  244. delete [] p;
  245. return S_OK;
  246. }
  247. HRESULT CAdminACL::PingACE(
  248. IWbemClassObject* pObj,
  249. IADsAccessControlEntry* pACE
  250. )
  251. {
  252. _variant_t vt;
  253. BSTR bstr;
  254. long lVal;
  255. HRESULT hr;
  256. // AccessMask
  257. hr = pACE->get_AccessMask(&lVal);
  258. if(SUCCEEDED(hr))
  259. {
  260. vt.vt = VT_I4;
  261. vt.lVal = lVal;
  262. hr = pObj->Put(L"AccessMask", 0, &vt, 0);
  263. }
  264. // AceType
  265. if(SUCCEEDED(hr))
  266. hr = pACE->get_AceType(&lVal);
  267. if(SUCCEEDED(hr))
  268. {
  269. vt.vt = VT_I4;
  270. vt.lVal = lVal;
  271. hr = pObj->Put(L"AceType", 0, &vt, 0);
  272. }
  273. // AceFlags
  274. if(SUCCEEDED(hr))
  275. hr = pACE->get_AceFlags(&lVal);
  276. if(SUCCEEDED(hr))
  277. {
  278. vt.vt = VT_I4;
  279. vt.lVal = lVal;
  280. hr = pObj->Put(L"AceFlags", 0, &vt, 0);
  281. }
  282. // Flags
  283. if(SUCCEEDED(hr))
  284. hr = pACE->get_Flags(&lVal);
  285. if(SUCCEEDED(hr))
  286. {
  287. vt.vt = VT_I4;
  288. vt.lVal = lVal;
  289. hr = pObj->Put(L"Flags", 0, &vt, 0);
  290. }
  291. // ObjectType
  292. if(SUCCEEDED(hr))
  293. hr = pACE->get_ObjectType(&bstr);
  294. if(SUCCEEDED(hr))
  295. {
  296. vt = bstr;
  297. hr = pObj->Put(L"ObjectType", 0, &vt, 0);
  298. SysFreeString(bstr);
  299. }
  300. // InheritedObjectType
  301. if(SUCCEEDED(hr))
  302. hr = pACE->get_InheritedObjectType(&bstr);
  303. if(SUCCEEDED(hr))
  304. {
  305. vt = bstr;
  306. hr = pObj->Put(L"InheritedObjectType", 0, &vt, 0);
  307. SysFreeString(bstr);
  308. }
  309. return hr;
  310. }
  311. HRESULT CAdminACL::GetACE(
  312. IWbemClassObject* pObj,
  313. _bstr_t& bstrTrustee
  314. )
  315. {
  316. HRESULT hr = S_OK;
  317. _variant_t var;
  318. IEnumVARIANT* pEnum = NULL;
  319. ULONG lFetch;
  320. BSTR bstr;
  321. IDispatch *pDisp = NULL;
  322. IADsAccessControlEntry *pACE = NULL;
  323. hr = GetACEEnum(&pEnum);
  324. if ( FAILED(hr) )
  325. return hr;
  326. //////////////////////////////////////////////
  327. // Enumerate ACEs
  328. //////////////////////////////////////////////
  329. hr = pEnum->Next( 1, &var, &lFetch );
  330. while( hr == S_OK )
  331. {
  332. if ( lFetch == 1 )
  333. {
  334. if ( VT_DISPATCH != V_VT(&var) )
  335. {
  336. hr = E_UNEXPECTED;
  337. break;
  338. }
  339. pDisp = V_DISPATCH(&var);
  340. /////////////////////////////
  341. // Get the individual ACE
  342. /////////////////////////////
  343. hr = pDisp->QueryInterface(
  344. IID_IADsAccessControlEntry,
  345. (void**)&pACE
  346. );
  347. if ( SUCCEEDED(hr) )
  348. {
  349. hr = pACE->get_Trustee(&bstr);
  350. if( SUCCEEDED(hr) && !lstrcmpiW(bstr, bstrTrustee) )
  351. {
  352. hr = PingACE(pObj, pACE);
  353. SysFreeString(bstr);
  354. pACE->Release();
  355. break;
  356. }
  357. SysFreeString(bstr);
  358. pACE->Release();
  359. }
  360. }
  361. hr = pEnum->Next( 1, &var, &lFetch );
  362. }
  363. pEnum->Release();
  364. return hr;
  365. }
  366. HRESULT CAdminACL::RemoveACE(
  367. _bstr_t& bstrTrustee
  368. )
  369. {
  370. HRESULT hRemoved = WBEM_E_INVALID_PARAMETER;
  371. HRESULT hr = S_OK;
  372. _variant_t var;
  373. IEnumVARIANT* pEnum = NULL;
  374. ULONG lFetch;
  375. BSTR bstr;
  376. IDispatch *pDisp = NULL;
  377. IADsAccessControlEntry *pACE = NULL;
  378. hr = GetACEEnum(&pEnum);
  379. if ( FAILED(hr) )
  380. return hr;
  381. //////////////////////////////////////////////
  382. // Enumerate ACEs
  383. //////////////////////////////////////////////
  384. hr = pEnum->Next( 1, &var, &lFetch );
  385. while( hr == S_OK )
  386. {
  387. if ( lFetch == 1 )
  388. {
  389. if ( VT_DISPATCH != V_VT(&var) )
  390. {
  391. hr = E_UNEXPECTED;
  392. break;
  393. }
  394. pDisp = V_DISPATCH(&var);
  395. /////////////////////////////
  396. // Get the individual ACE
  397. /////////////////////////////
  398. hr = pDisp->QueryInterface(
  399. IID_IADsAccessControlEntry,
  400. (void**)&pACE
  401. );
  402. if ( SUCCEEDED(hr) )
  403. {
  404. hr = pACE->get_Trustee(&bstr);
  405. if( SUCCEEDED(hr) && !lstrcmpiW(bstr, bstrTrustee) )
  406. {
  407. // remove ACE
  408. hr = pACE->QueryInterface(IID_IDispatch,(void**)&pDisp);
  409. if ( SUCCEEDED(hr) )
  410. {
  411. hRemoved = m_pDACL->RemoveAce(pDisp);
  412. pDisp->Release();
  413. }
  414. SysFreeString(bstr);
  415. pACE->Release();
  416. break;
  417. }
  418. SysFreeString(bstr);
  419. pACE->Release();
  420. }
  421. }
  422. hr = pEnum->Next( 1, &var, &lFetch );
  423. }
  424. pEnum->Release();
  425. return hRemoved;
  426. }
  427. // parse ParsedObjectPath to get the Trustee key
  428. void CAdminACL::GetTrustee(
  429. IWbemClassObject* pObj,
  430. ParsedObjectPath* pPath,
  431. _bstr_t& bstrTrustee
  432. )
  433. {
  434. KeyRef* pkr;
  435. WCHAR* pszKey = L"Trustee";
  436. pkr = CUtils::GetKey(pPath, pszKey);
  437. if(pkr == NULL)
  438. throw WBEM_E_INVALID_OBJECT;
  439. bstrTrustee = pkr->m_vValue;
  440. if (pObj)
  441. {
  442. _bstr_t bstr = pkr->m_pName;
  443. HRESULT hr = pObj->Put(bstr, 0, &pkr->m_vValue, 0);
  444. THROW_ON_ERROR(hr);
  445. }
  446. }
  447. HRESULT CAdminACL::GetACEEnum(
  448. IEnumVARIANT** pEnum
  449. )
  450. {
  451. HRESULT hr = S_OK;
  452. LPUNKNOWN pUnk = NULL;
  453. if(!pEnum)
  454. return E_INVALIDARG;
  455. if(*pEnum)
  456. (*pEnum)->Release();
  457. hr = m_pDACL->get__NewEnum( &pUnk );
  458. if ( SUCCEEDED(hr) )
  459. {
  460. hr = pUnk->QueryInterface( IID_IEnumVARIANT, (void**) pEnum );
  461. }
  462. return hr;
  463. }
  464. // addd a ACE
  465. HRESULT CAdminACL::AddACE(
  466. IWbemClassObject* pObj,
  467. _bstr_t& bstrTrustee
  468. )
  469. {
  470. HRESULT hr = m_pDACL->put_AclRevision(ADS_SD_REVISION_DS);
  471. if(FAILED(hr))
  472. return hr;
  473. // create a ACE
  474. IADsAccessControlEntry* pACE = NULL;
  475. hr = NewACE(
  476. pObj,
  477. bstrTrustee,
  478. &pACE
  479. );
  480. if(FAILED(hr))
  481. return hr;
  482. // add the ACE
  483. IDispatch* pDisp = NULL;
  484. hr = pACE->QueryInterface(IID_IDispatch,(void**)&pDisp);
  485. if(SUCCEEDED(hr))
  486. {
  487. hr = m_pDACL->AddAce(pDisp);
  488. pDisp->Release();
  489. }
  490. pACE->Release();
  491. return hr;
  492. }
  493. ////////////////////////////////////
  494. // function to create an ACE
  495. ////////////////////////////////////
  496. HRESULT CAdminACL::NewACE(
  497. IWbemClassObject* pObj,
  498. _bstr_t& bstrTrustee,
  499. IADsAccessControlEntry** ppACE
  500. )
  501. {
  502. if(!ppACE)
  503. return E_INVALIDARG;
  504. HRESULT hr;
  505. hr = CoCreateInstance(
  506. CLSID_AccessControlEntry,
  507. NULL,
  508. CLSCTX_INPROC_SERVER,
  509. IID_IADsAccessControlEntry,
  510. (void**)ppACE
  511. );
  512. // Trustee
  513. _variant_t vt;
  514. if(SUCCEEDED(hr))
  515. hr = (*ppACE)->put_Trustee(bstrTrustee);
  516. if(SUCCEEDED(hr))
  517. hr = SetDataOfACE(pObj, *ppACE);
  518. return hr;
  519. }
  520. HRESULT CAdminACL::SetDataOfACE(
  521. IWbemClassObject* pObj,
  522. IADsAccessControlEntry* pACE
  523. )
  524. {
  525. HRESULT hr;
  526. _variant_t vt;
  527. // AccessMask
  528. hr = pObj->Get(L"AccessMask", 0, &vt, NULL, NULL);
  529. if(SUCCEEDED(hr) && vt.vt == VT_I4)
  530. hr = pACE->put_AccessMask(vt.lVal);
  531. // AceType
  532. if(SUCCEEDED(hr))
  533. hr = pObj->Get(L"AceType", 0, &vt, NULL, NULL);
  534. if(SUCCEEDED(hr) && vt.vt == VT_I4)
  535. hr = pACE->put_AceType(vt.lVal);
  536. // AceFlags
  537. if(SUCCEEDED(hr))
  538. hr = pObj->Get(L"AceFlags", 0, &vt, NULL, NULL);
  539. if(SUCCEEDED(hr) && vt.vt == VT_I4)
  540. hr = pACE->put_AceFlags(vt.lVal);
  541. // Flags
  542. if(SUCCEEDED(hr))
  543. hr = pObj->Get(L"Flags", 0, &vt, NULL, NULL);
  544. if(SUCCEEDED(hr) && vt.vt == VT_I4)
  545. hr = pACE->put_Flags(vt.lVal);
  546. // ObjectType
  547. if(SUCCEEDED(hr))
  548. hr = pObj->Get(L"ObjectType", 0, &vt, NULL, NULL);
  549. if(SUCCEEDED(hr) && vt.vt == VT_BSTR)
  550. hr = pACE->put_ObjectType(vt.bstrVal);
  551. // InheritedObjectType
  552. if(SUCCEEDED(hr))
  553. hr = pObj->Get(L"InheritedObjectType", 0, &vt, NULL, NULL);
  554. if(SUCCEEDED(hr) && vt.vt == VT_BSTR)
  555. hr = pACE->put_InheritedObjectType(vt.bstrVal);
  556. return hr;
  557. }
  558. HRESULT CAdminACL::UpdateACE(
  559. IWbemClassObject* pObj,
  560. _bstr_t& bstrTrustee,
  561. BOOL& fAceExisted
  562. )
  563. {
  564. HRESULT hr = S_OK;
  565. _variant_t var;
  566. IEnumVARIANT* pEnum = NULL;
  567. ULONG lFetch;
  568. BSTR bstr;
  569. IDispatch *pDisp = NULL;
  570. IADsAccessControlEntry *pACE = NULL;
  571. fAceExisted = FALSE;
  572. hr = GetACEEnum(&pEnum);
  573. if ( FAILED(hr) )
  574. return hr;
  575. //////////////////////////////////////////////
  576. // Enumerate ACEs
  577. //////////////////////////////////////////////
  578. hr = pEnum->Next( 1, &var, &lFetch );
  579. while( hr == S_OK )
  580. {
  581. if ( lFetch == 1 )
  582. {
  583. if ( VT_DISPATCH != V_VT(&var) )
  584. {
  585. hr = E_UNEXPECTED;
  586. break;
  587. }
  588. pDisp = V_DISPATCH(&var);
  589. /////////////////////////////
  590. // Get the individual ACE
  591. /////////////////////////////
  592. hr = pDisp->QueryInterface(
  593. IID_IADsAccessControlEntry,
  594. (void**)&pACE
  595. );
  596. if ( SUCCEEDED(hr) )
  597. {
  598. hr = pACE->get_Trustee(&bstr);
  599. if( SUCCEEDED(hr) && !lstrcmpiW(bstr, bstrTrustee) )
  600. {
  601. fAceExisted = TRUE;
  602. // Update the data of the ACE
  603. hr = SetDataOfACE(pObj, pACE);
  604. SysFreeString(bstr);
  605. pACE->Release();
  606. break;
  607. }
  608. SysFreeString(bstr);
  609. pACE->Release();
  610. }
  611. }
  612. hr = pEnum->Next( 1, &var, &lFetch );
  613. }
  614. pEnum->Release();
  615. return hr;
  616. }