Source code of Windows XP (NT5)
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.

572 lines
14 KiB

  1. //***************************************************************************
  2. //
  3. // IPSecurity.cpp
  4. //
  5. // Module: WBEM Instance provider
  6. //
  7. // Purpose: IIS IPSecurity class
  8. //
  9. // Copyright (c)1998 Microsoft Corporation, All Rights Reserved
  10. //
  11. //***************************************************************************
  12. #include "iisprov.h"
  13. #include "ipsecurity.h"
  14. #define DEFAULT_TIMEOUT_VALUE 30000
  15. #define BUFFER_SIZE 512
  16. CIPSecurity::CIPSecurity()
  17. {
  18. m_pADs = NULL;
  19. m_pIPSec = NULL;
  20. bIsInherit = FALSE;
  21. }
  22. CIPSecurity::~CIPSecurity()
  23. {
  24. CloseSD();
  25. }
  26. void CIPSecurity::CloseSD()
  27. {
  28. if(m_pIPSec)
  29. {
  30. m_pIPSec->Release();
  31. m_pIPSec = NULL;
  32. }
  33. if(m_pADs)
  34. {
  35. m_pADs->Release();
  36. m_pADs = NULL;
  37. }
  38. }
  39. HRESULT CIPSecurity::GetObjectAsync(
  40. IWbemClassObject* pObj
  41. )
  42. {
  43. VARIANT vt;
  44. VARIANT vtBstrArray;
  45. HRESULT hr;
  46. VARIANT vtTrue;
  47. vtTrue.boolVal = VARIANT_TRUE;
  48. vtTrue.vt = VT_BOOL;
  49. // IPDeny
  50. hr = m_pIPSec->get_IPDeny(&vt);
  51. if(SUCCEEDED(hr))
  52. {
  53. hr = LoadBstrArrayFromVariantArray(vt, vtBstrArray);
  54. VariantClear(&vt);
  55. if(SUCCEEDED(hr))
  56. {
  57. hr = pObj->Put(L"IPDeny", 0, &vtBstrArray, 0);
  58. VariantClear(&vtBstrArray);
  59. }
  60. if(bIsInherit && SUCCEEDED(hr))
  61. {
  62. hr = CUtils::SetPropertyQualifiers(
  63. pObj, L"IPDeny", &g_wszIsInherit, &vtTrue, 1);
  64. }
  65. }
  66. // IPGrant
  67. if(SUCCEEDED(hr))
  68. {
  69. hr = m_pIPSec->get_IPGrant(&vt);
  70. if(SUCCEEDED(hr))
  71. {
  72. hr = LoadBstrArrayFromVariantArray(vt, vtBstrArray);
  73. VariantClear(&vt);
  74. if(SUCCEEDED(hr))
  75. {
  76. hr = pObj->Put(L"IPGrant", 0, &vtBstrArray, 0);
  77. VariantClear(&vtBstrArray);
  78. }
  79. if(bIsInherit && SUCCEEDED(hr))
  80. {
  81. hr = CUtils::SetPropertyQualifiers(
  82. pObj, L"IPGrant", &g_wszIsInherit, &vtTrue, 1);
  83. }
  84. }
  85. }
  86. // DomainDeny
  87. if(SUCCEEDED(hr))
  88. {
  89. hr = m_pIPSec->get_DomainDeny(&vt);
  90. if(SUCCEEDED(hr))
  91. {
  92. hr = LoadBstrArrayFromVariantArray(vt, vtBstrArray);
  93. VariantClear(&vt);
  94. if(SUCCEEDED(hr))
  95. {
  96. hr = pObj->Put(L"DomainDeny", 0, &vtBstrArray, 0);
  97. VariantClear(&vtBstrArray);
  98. }
  99. if(bIsInherit && SUCCEEDED(hr))
  100. {
  101. hr = CUtils::SetPropertyQualifiers(
  102. pObj, L"DomainDeny", &g_wszIsInherit, &vtTrue, 1);
  103. }
  104. }
  105. }
  106. // DomainGrant
  107. if(SUCCEEDED(hr))
  108. {
  109. hr = m_pIPSec->get_DomainGrant(&vt);
  110. if(SUCCEEDED(hr))
  111. {
  112. hr = LoadBstrArrayFromVariantArray(vt, vtBstrArray);
  113. VariantClear(&vt);
  114. if(SUCCEEDED(hr))
  115. {
  116. hr = pObj->Put(L"DomainGrant", 0, &vtBstrArray, 0);
  117. VariantClear(&vtBstrArray);
  118. }
  119. if(bIsInherit && SUCCEEDED(hr))
  120. {
  121. hr = CUtils::SetPropertyQualifiers(
  122. pObj, L"DomainGrant", &g_wszIsInherit, &vtTrue, 1);
  123. }
  124. }
  125. }
  126. // GrantByDefault
  127. if(SUCCEEDED(hr))
  128. hr = m_pIPSec->get_GrantByDefault(&vt.boolVal);
  129. if(SUCCEEDED(hr))
  130. {
  131. vt.vt = VT_BOOL;
  132. hr = pObj->Put(L"GrantByDefault", 0, &vt, 0);
  133. if(bIsInherit && SUCCEEDED(hr))
  134. {
  135. hr = CUtils::SetPropertyQualifiers(
  136. pObj, L"GrantByDefault", &g_wszIsInherit, &vtTrue, 1);
  137. }
  138. }
  139. return hr;
  140. }
  141. // Convert SAFEARRAY of BSTRs to SAFEARRAY of VARIANTs
  142. HRESULT CIPSecurity::LoadVariantArrayFromBstrArray(
  143. VARIANT& i_vtBstr,
  144. VARIANT& o_vtVariant)
  145. {
  146. SAFEARRAYBOUND aDim;
  147. SAFEARRAY* pBstrArray = NULL;
  148. SAFEARRAY* pVarArray = NULL;
  149. BSTR* paBstr = NULL;
  150. VARIANT vt;
  151. LONG i=0;
  152. HRESULT hr = ERROR_SUCCESS;
  153. try
  154. {
  155. // Verify that the input VARIANT is a BSTR array or NULL.
  156. if (i_vtBstr.vt != (VT_ARRAY | VT_BSTR) &&
  157. i_vtBstr.vt != VT_NULL) {
  158. hr = WBEM_E_INVALID_PARAMETER;
  159. THROW_ON_ERROR(hr);
  160. }
  161. // Initialize the output VARIANT (Set type to VT_EMPTY)
  162. VariantInit(&o_vtVariant);
  163. // Handle the case when there is no input array
  164. if (i_vtBstr.vt == VT_NULL) {
  165. aDim.lLbound = 0;
  166. aDim.cElements = 0;
  167. }
  168. else {
  169. // Verify that the input VARIANT contains a SAFEARRAY
  170. pBstrArray = i_vtBstr.parray;
  171. if (pBstrArray == NULL) {
  172. hr = WBEM_E_INVALID_PARAMETER;
  173. THROW_ON_ERROR(hr);
  174. }
  175. // Get the size of the BSTR SAFEARRAY.
  176. aDim.lLbound = 0;
  177. aDim.cElements = pBstrArray->rgsabound[0].cElements;
  178. }
  179. // Create the new VARIANT SAFEARRAY
  180. pVarArray = SafeArrayCreate(VT_VARIANT, 1, &aDim);
  181. if (pVarArray == NULL) {
  182. hr = E_OUTOFMEMORY;
  183. THROW_ON_ERROR(hr);
  184. }
  185. // Put the new VARIANT SAFEARRAY into our output VARIANT
  186. o_vtVariant.vt = VT_ARRAY | VT_VARIANT;
  187. o_vtVariant.parray = pVarArray;
  188. if(aDim.cElements > 0) {
  189. // Get the BSTR SAFEARRAY pointer.
  190. hr = SafeArrayAccessData(pBstrArray, (void**)&paBstr);
  191. THROW_ON_ERROR(hr);
  192. // Copy all the BSTRS to VARIANTS
  193. VariantInit(&vt);
  194. vt.vt = VT_BSTR;
  195. for(i = aDim.lLbound; i < (long) aDim.cElements; i++)
  196. {
  197. vt.bstrVal = SysAllocString(paBstr[i]);
  198. if (vt.bstrVal == NULL) {
  199. hr = E_OUTOFMEMORY;
  200. THROW_ON_ERROR(hr);
  201. }
  202. hr = SafeArrayPutElement(pVarArray, &i, &vt);
  203. VariantClear(&vt);
  204. THROW_ON_ERROR(hr);
  205. }
  206. hr = SafeArrayUnaccessData(pBstrArray);
  207. THROW_ON_ERROR(hr);
  208. }
  209. }
  210. catch(...)
  211. {
  212. // Destroy the VARIANT, the contained SAFEARRAY and the VARIANTs in the SAFEARRAY.
  213. // It also free the BSTRS contained in the VARIANTs
  214. VariantClear(&o_vtVariant);
  215. }
  216. return hr;
  217. }
  218. HRESULT CIPSecurity::LoadBstrArrayFromVariantArray(
  219. VARIANT& i_vtVariant,
  220. VARIANT& o_vtBstr
  221. )
  222. {
  223. SAFEARRAYBOUND aDim;
  224. SAFEARRAY* pVarArray = NULL;
  225. SAFEARRAY* pBstrArray = NULL;
  226. VARIANT* paVar = NULL;
  227. BSTR bstr = NULL;
  228. LONG i = 0;
  229. HRESULT hr = ERROR_SUCCESS;
  230. try
  231. {
  232. // Verify the Variant array.
  233. if (i_vtVariant.vt != (VT_ARRAY | VT_VARIANT)) {
  234. hr = WBEM_E_INVALID_PARAMETER;
  235. THROW_ON_ERROR(hr);
  236. }
  237. // Verify that the variant contains a safearray.
  238. pVarArray = i_vtVariant.parray;
  239. if (pVarArray == NULL) {
  240. hr = WBEM_E_INVALID_PARAMETER;
  241. THROW_ON_ERROR(hr);
  242. }
  243. // Initialize the out paramter.
  244. VariantInit(&o_vtBstr);
  245. // Get the size of the array.
  246. aDim.lLbound = 0;
  247. aDim.cElements = pVarArray->rgsabound[0].cElements;
  248. // Create the new BSTR array
  249. pBstrArray = SafeArrayCreate(VT_BSTR, 1, &aDim);
  250. if (pBstrArray == NULL) {
  251. hr = E_OUTOFMEMORY;
  252. THROW_ON_ERROR(hr);
  253. }
  254. // Put the array into the variant.
  255. o_vtBstr.vt = VT_ARRAY | VT_BSTR;
  256. o_vtBstr.parray = pBstrArray;
  257. // Get the variant array pointer.
  258. hr = SafeArrayAccessData(pVarArray, (void**)&paVar);
  259. THROW_ON_ERROR(hr);
  260. // Copy all the bstrs.
  261. for (i = aDim.lLbound; i < (long) aDim.cElements; i++)
  262. {
  263. if (paVar[i].vt != VT_BSTR) {
  264. hr = WBEM_E_FAILED;
  265. THROW_ON_ERROR(hr);
  266. }
  267. bstr = SysAllocString(paVar[i].bstrVal);
  268. if (bstr == NULL) {
  269. hr = E_OUTOFMEMORY;
  270. THROW_ON_ERROR(hr);
  271. }
  272. hr = SafeArrayPutElement(pBstrArray, &i, bstr);
  273. SysFreeString(bstr);
  274. bstr = NULL;
  275. THROW_ON_ERROR(hr);
  276. }
  277. hr = SafeArrayUnaccessData(pVarArray);
  278. THROW_ON_ERROR(hr);
  279. }
  280. catch (...)
  281. {
  282. // Destroy the variant, the safearray and the bstr's in the array.
  283. VariantClear(&o_vtBstr);
  284. }
  285. return hr;
  286. }
  287. HRESULT CIPSecurity::PutObjectAsync(
  288. IWbemClassObject* pObj
  289. )
  290. {
  291. VARIANT vt;
  292. VARIANT vtVarArray;
  293. HRESULT hr;
  294. // IPDeny
  295. hr = pObj->Get(L"IPDeny", 0, &vt, NULL, NULL);
  296. if(SUCCEEDED(hr)) {
  297. hr = LoadVariantArrayFromBstrArray(vt, vtVarArray);
  298. VariantClear(&vt);
  299. if(SUCCEEDED(hr)) {
  300. hr = m_pIPSec->put_IPDeny(vtVarArray);
  301. VariantClear(&vtVarArray);
  302. }
  303. }
  304. // IPGrant
  305. if(SUCCEEDED(hr)) {
  306. hr = pObj->Get(L"IPGrant", 0, &vt, NULL, NULL);
  307. if(SUCCEEDED(hr)) {
  308. hr = LoadVariantArrayFromBstrArray(vt, vtVarArray);
  309. VariantClear(&vt);
  310. if(SUCCEEDED(hr)) {
  311. hr = m_pIPSec->put_IPGrant(vtVarArray);
  312. VariantClear(&vtVarArray);
  313. }
  314. }
  315. }
  316. // DomainDeny
  317. if(SUCCEEDED(hr)) {
  318. hr = pObj->Get(L"DomainDeny", 0, &vt, NULL, NULL);
  319. if(SUCCEEDED(hr)) {
  320. hr = LoadVariantArrayFromBstrArray(vt, vtVarArray);
  321. VariantClear(&vt);
  322. if(SUCCEEDED(hr)) {
  323. hr = m_pIPSec->put_DomainDeny(vtVarArray);
  324. VariantClear(&vtVarArray);
  325. }
  326. }
  327. }
  328. // DomainGrant
  329. if(SUCCEEDED(hr)) {
  330. hr = pObj->Get(L"DomainGrant", 0, &vt, NULL, NULL);
  331. if(SUCCEEDED(hr)) {
  332. hr = LoadVariantArrayFromBstrArray(vt, vtVarArray);
  333. VariantClear(&vt);
  334. if(SUCCEEDED(hr)) {
  335. hr = m_pIPSec->put_DomainGrant(vtVarArray);
  336. VariantClear(&vtVarArray);
  337. }
  338. }
  339. }
  340. // GrantByDefault
  341. if(SUCCEEDED(hr))
  342. hr = pObj->Get(L"GrantByDefault", 0, &vt, NULL, NULL);
  343. if(SUCCEEDED(hr))
  344. hr = m_pIPSec->put_GrantByDefault(vt.boolVal);
  345. VariantClear(&vt);
  346. // set the modified IPSecurity back into the metabase
  347. if(SUCCEEDED(hr))
  348. hr = SetSD();
  349. return hr;
  350. }
  351. HRESULT CIPSecurity::OpenSD(
  352. _bstr_t bstrAdsPath,
  353. IMSAdminBase2* pAdminBase)
  354. {
  355. _variant_t var;
  356. HRESULT hr;
  357. IDispatch* pDisp = NULL;
  358. METADATA_HANDLE hObjHandle = NULL;
  359. DWORD dwBufferSize = 0;
  360. METADATA_RECORD mdrMDData;
  361. BYTE pBuffer[BUFFER_SIZE];
  362. _bstr_t oldPath;
  363. try
  364. { // close SD interface first
  365. CloseSD();
  366. oldPath = bstrAdsPath.copy();
  367. hr = GetAdsPath(bstrAdsPath);
  368. if(FAILED(hr))
  369. return hr;
  370. // get m_pADs
  371. hr = ADsGetObject(
  372. bstrAdsPath,
  373. IID_IADs,
  374. (void**)&m_pADs
  375. );
  376. if(FAILED(hr))
  377. return hr;
  378. // get m_pSD
  379. hr = m_pADs->Get(L"IPSecurity",&var);
  380. if(FAILED(hr))
  381. return hr;
  382. hr = V_DISPATCH(&var)->QueryInterface(
  383. IID_IISIPSecurity,
  384. (void**)&m_pIPSec
  385. );
  386. if(FAILED(hr))
  387. return hr;
  388. // set bIsInherit
  389. hr = pAdminBase->OpenKey(
  390. METADATA_MASTER_ROOT_HANDLE,
  391. oldPath,
  392. METADATA_PERMISSION_READ,
  393. DEFAULT_TIMEOUT_VALUE,
  394. &hObjHandle
  395. );
  396. if(FAILED(hr))
  397. return hr;
  398. MD_SET_DATA_RECORD(&mdrMDData,
  399. MD_IP_SEC, // ID for "IPSecurity"
  400. METADATA_INHERIT | METADATA_ISINHERITED,
  401. ALL_METADATA,
  402. ALL_METADATA,
  403. BUFFER_SIZE,
  404. pBuffer);
  405. hr = pAdminBase->GetData(
  406. hObjHandle,
  407. L"",
  408. &mdrMDData,
  409. &dwBufferSize
  410. );
  411. hr = S_OK;
  412. bIsInherit = mdrMDData.dwMDAttributes & METADATA_ISINHERITED;
  413. }
  414. catch(...)
  415. {
  416. hr = E_FAIL;
  417. }
  418. if (hObjHandle && pAdminBase) {
  419. pAdminBase->CloseKey(hObjHandle);
  420. }
  421. return hr;
  422. }
  423. HRESULT CIPSecurity::SetSD()
  424. {
  425. _variant_t var;
  426. HRESULT hr;
  427. IDispatch* pDisp = NULL;
  428. try
  429. {
  430. // put IPSecurity
  431. hr = m_pIPSec->QueryInterface(
  432. IID_IDispatch,
  433. (void**)&pDisp
  434. );
  435. if(FAILED(hr))
  436. return hr;
  437. var.vt = VT_DISPATCH;
  438. var.pdispVal = pDisp;
  439. hr = m_pADs->Put(L"IPSecurity",var); // pDisp will be released by this call Put().
  440. if(FAILED(hr))
  441. return hr;
  442. // Commit the change to the active directory
  443. hr = m_pADs->SetInfo();
  444. }
  445. catch(...)
  446. {
  447. hr = E_FAIL;
  448. }
  449. return hr;
  450. }
  451. HRESULT CIPSecurity::GetAdsPath(_bstr_t& bstrAdsPath)
  452. {
  453. DBG_ASSERT(((LPWSTR)bstrAdsPath) != NULL);
  454. WCHAR* p = new WCHAR[bstrAdsPath.length() + 1];
  455. if(p == NULL)
  456. return E_OUTOFMEMORY;
  457. lstrcpyW(p, bstrAdsPath);
  458. try
  459. {
  460. bstrAdsPath = L"IIS://LocalHost";
  461. // trim first three charaters "/LM"
  462. bstrAdsPath += (p+3);
  463. }
  464. catch(_com_error e)
  465. {
  466. delete [] p;
  467. return e.Error();
  468. }
  469. delete [] p;
  470. return S_OK;
  471. }