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.

480 lines
12 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. CIPSecurity::CIPSecurity()
  14. {
  15. m_pADs = NULL;
  16. m_pIPSec = NULL;
  17. }
  18. CIPSecurity::~CIPSecurity()
  19. {
  20. CloseSD();
  21. }
  22. void CIPSecurity::CloseSD()
  23. {
  24. if(m_pIPSec)
  25. {
  26. m_pIPSec->Release();
  27. m_pIPSec = NULL;
  28. }
  29. if(m_pADs)
  30. {
  31. m_pADs->Release();
  32. m_pADs = NULL;
  33. }
  34. }
  35. HRESULT CIPSecurity::GetObjectAsync(
  36. IWbemClassObject* pObj
  37. )
  38. {
  39. VARIANT vt;
  40. VARIANT vtBstrArray;
  41. HRESULT hr;
  42. // IPDeny
  43. hr = m_pIPSec->get_IPDeny(&vt);
  44. if(SUCCEEDED(hr))
  45. {
  46. hr = LoadBstrArrayFromVariantArray(vt, vtBstrArray);
  47. VariantClear(&vt);
  48. if(SUCCEEDED(hr))
  49. {
  50. hr = pObj->Put(L"IPDeny", 0, &vtBstrArray, 0);
  51. VariantClear(&vtBstrArray);
  52. }
  53. }
  54. // IPGrant
  55. if(SUCCEEDED(hr))
  56. {
  57. hr = m_pIPSec->get_IPGrant(&vt);
  58. if(SUCCEEDED(hr))
  59. {
  60. hr = LoadBstrArrayFromVariantArray(vt, vtBstrArray);
  61. VariantClear(&vt);
  62. if(SUCCEEDED(hr))
  63. {
  64. hr = pObj->Put(L"IPGrant", 0, &vtBstrArray, 0);
  65. VariantClear(&vtBstrArray);
  66. }
  67. }
  68. }
  69. // DomainDeny
  70. if(SUCCEEDED(hr))
  71. {
  72. hr = m_pIPSec->get_DomainDeny(&vt);
  73. if(SUCCEEDED(hr))
  74. {
  75. hr = LoadBstrArrayFromVariantArray(vt, vtBstrArray);
  76. VariantClear(&vt);
  77. if(SUCCEEDED(hr))
  78. {
  79. hr = pObj->Put(L"DomainDeny", 0, &vtBstrArray, 0);
  80. VariantClear(&vtBstrArray);
  81. }
  82. }
  83. }
  84. // DomainGrant
  85. if(SUCCEEDED(hr))
  86. {
  87. hr = m_pIPSec->get_DomainGrant(&vt);
  88. if(SUCCEEDED(hr))
  89. {
  90. hr = LoadBstrArrayFromVariantArray(vt, vtBstrArray);
  91. VariantClear(&vt);
  92. if(SUCCEEDED(hr))
  93. {
  94. hr = pObj->Put(L"DomainGrant", 0, &vtBstrArray, 0);
  95. VariantClear(&vtBstrArray);
  96. }
  97. }
  98. }
  99. // GrantByDefault
  100. if(SUCCEEDED(hr))
  101. hr = m_pIPSec->get_GrantByDefault(&vt.boolVal);
  102. if(SUCCEEDED(hr))
  103. {
  104. vt.vt = VT_BOOL;
  105. hr = pObj->Put(L"GrantByDefault", 0, &vt, 0);
  106. }
  107. return hr;
  108. }
  109. // Convert SAFEARRAY of BSTRs to SAFEARRAY of VARIANTs
  110. HRESULT CIPSecurity::LoadVariantArrayFromBstrArray(
  111. VARIANT& i_vtBstr,
  112. VARIANT& o_vtVariant)
  113. {
  114. SAFEARRAYBOUND aDim;
  115. SAFEARRAY* pBstrArray = NULL;
  116. SAFEARRAY* pVarArray = NULL;
  117. BSTR* paBstr = NULL;
  118. VARIANT vt;
  119. LONG i=0;
  120. HRESULT hr = ERROR_SUCCESS;
  121. try
  122. {
  123. // Verify that the input VARIANT is a BSTR array or NULL.
  124. if (i_vtBstr.vt != (VT_ARRAY | VT_BSTR) &&
  125. i_vtBstr.vt != VT_NULL) {
  126. hr = WBEM_E_INVALID_PARAMETER;
  127. THROW_ON_ERROR(hr);
  128. }
  129. // Initialize the output VARIANT (Set type to VT_EMPTY)
  130. VariantInit(&o_vtVariant);
  131. // Handle the case when there is no input array
  132. if (i_vtBstr.vt == VT_NULL) {
  133. aDim.lLbound = 0;
  134. aDim.cElements = 0;
  135. }
  136. else {
  137. // Verify that the input VARIANT contains a SAFEARRAY
  138. pBstrArray = i_vtBstr.parray;
  139. if (pBstrArray == NULL) {
  140. hr = WBEM_E_INVALID_PARAMETER;
  141. THROW_ON_ERROR(hr);
  142. }
  143. // Get the size of the BSTR SAFEARRAY.
  144. aDim.lLbound = 0;
  145. aDim.cElements = pBstrArray->rgsabound[0].cElements;
  146. }
  147. // Create the new VARIANT SAFEARRAY
  148. pVarArray = SafeArrayCreate(VT_VARIANT, 1, &aDim);
  149. if (pVarArray == NULL) {
  150. hr = E_OUTOFMEMORY;
  151. THROW_ON_ERROR(hr);
  152. }
  153. // Put the new VARIANT SAFEARRAY into our output VARIANT
  154. o_vtVariant.vt = VT_ARRAY | VT_VARIANT;
  155. o_vtVariant.parray = pVarArray;
  156. if(aDim.cElements > 0) {
  157. // Get the BSTR SAFEARRAY pointer.
  158. hr = SafeArrayAccessData(pBstrArray, (void**)&paBstr);
  159. THROW_ON_ERROR(hr);
  160. // Copy all the BSTRS to VARIANTS
  161. VariantInit(&vt);
  162. vt.vt = VT_BSTR;
  163. for(i = aDim.lLbound; i < (long) aDim.cElements; i++)
  164. {
  165. vt.bstrVal = SysAllocString(paBstr[i]);
  166. if (vt.bstrVal == NULL) {
  167. hr = E_OUTOFMEMORY;
  168. THROW_ON_ERROR(hr);
  169. }
  170. hr = SafeArrayPutElement(pVarArray, &i, &vt);
  171. THROW_ON_ERROR(hr);
  172. }
  173. hr = SafeArrayUnaccessData(pBstrArray);
  174. THROW_ON_ERROR(hr);
  175. }
  176. }
  177. catch(...)
  178. {
  179. // Destroy the VARIANT, the contained SAFEARRAY and the VARIANTs in the SAFEARRAY.
  180. // It also free the BSTRS contained in the VARIANTs
  181. VariantClear(&o_vtVariant);
  182. // Destroy temp VARIANT (It is possible this guy didn't get put into array, but has a BSTR)
  183. VariantClear(&vt);
  184. }
  185. return hr;
  186. }
  187. HRESULT CIPSecurity::LoadBstrArrayFromVariantArray(
  188. VARIANT& i_vtVariant,
  189. VARIANT& o_vtBstr
  190. )
  191. {
  192. SAFEARRAYBOUND aDim;
  193. SAFEARRAY* pVarArray = NULL;
  194. SAFEARRAY* pBstrArray = NULL;
  195. VARIANT* paVar = NULL;
  196. BSTR bstr = NULL;
  197. LONG i = 0;
  198. HRESULT hr = ERROR_SUCCESS;
  199. try
  200. {
  201. // Verify the Variant array.
  202. if (i_vtVariant.vt != (VT_ARRAY | VT_VARIANT)) {
  203. hr = WBEM_E_INVALID_PARAMETER;
  204. THROW_ON_ERROR(hr);
  205. }
  206. // Verify that the variant contains a safearray.
  207. pVarArray = i_vtVariant.parray;
  208. if (pVarArray == NULL) {
  209. hr = WBEM_E_INVALID_PARAMETER;
  210. THROW_ON_ERROR(hr);
  211. }
  212. // Initialize the out paramter.
  213. VariantInit(&o_vtBstr);
  214. // Get the size of the array.
  215. aDim.lLbound = 0;
  216. aDim.cElements = pVarArray->rgsabound[0].cElements;
  217. // Create the new BSTR array
  218. pBstrArray = SafeArrayCreate(VT_BSTR, 1, &aDim);
  219. if (pBstrArray == NULL) {
  220. hr = E_OUTOFMEMORY;
  221. THROW_ON_ERROR(hr);
  222. }
  223. // Put the array into the variant.
  224. o_vtBstr.vt = VT_ARRAY | VT_BSTR;
  225. o_vtBstr.parray = pBstrArray;
  226. // Get the variant array pointer.
  227. hr = SafeArrayAccessData(pVarArray, (void**)&paVar);
  228. THROW_ON_ERROR(hr);
  229. // Copy all the bstrs.
  230. for (i = aDim.lLbound; i < (long) aDim.cElements; i++)
  231. {
  232. if (paVar[i].vt != VT_BSTR) {
  233. hr = WBEM_E_FAILED;
  234. THROW_ON_ERROR(hr);
  235. }
  236. bstr = SysAllocString(paVar[i].bstrVal);
  237. if (bstr == NULL) {
  238. hr = E_OUTOFMEMORY;
  239. THROW_ON_ERROR(hr);
  240. }
  241. hr = SafeArrayPutElement(pBstrArray, &i, bstr);
  242. THROW_ON_ERROR(hr);
  243. bstr = NULL;
  244. }
  245. hr = SafeArrayUnaccessData(pVarArray);
  246. THROW_ON_ERROR(hr);
  247. }
  248. catch (...)
  249. {
  250. // Destroy the variant, the safearray and the bstr's in the array.
  251. VariantClear(&o_vtBstr);
  252. // bstr may not have been put into array but was still allocated
  253. SysFreeString(bstr);
  254. }
  255. return hr;
  256. }
  257. HRESULT CIPSecurity::PutObjectAsync(
  258. IWbemClassObject* pObj
  259. )
  260. {
  261. VARIANT vt;
  262. VARIANT vtVarArray;
  263. HRESULT hr;
  264. // IPDeny
  265. hr = pObj->Get(L"IPDeny", 0, &vt, NULL, NULL);
  266. if(SUCCEEDED(hr)) {
  267. hr = LoadVariantArrayFromBstrArray(vt, vtVarArray);
  268. VariantClear(&vt);
  269. if(SUCCEEDED(hr)) {
  270. hr = m_pIPSec->put_IPDeny(vtVarArray);
  271. VariantClear(&vtVarArray);
  272. }
  273. }
  274. // IPGrant
  275. if(SUCCEEDED(hr)) {
  276. hr = pObj->Get(L"IPGrant", 0, &vt, NULL, NULL);
  277. if(SUCCEEDED(hr)) {
  278. hr = LoadVariantArrayFromBstrArray(vt, vtVarArray);
  279. VariantClear(&vt);
  280. if(SUCCEEDED(hr)) {
  281. hr = m_pIPSec->put_IPGrant(vtVarArray);
  282. VariantClear(&vtVarArray);
  283. }
  284. }
  285. }
  286. // DomainDeny
  287. if(SUCCEEDED(hr)) {
  288. hr = pObj->Get(L"DomainDeny", 0, &vt, NULL, NULL);
  289. if(SUCCEEDED(hr)) {
  290. hr = LoadVariantArrayFromBstrArray(vt, vtVarArray);
  291. VariantClear(&vt);
  292. if(SUCCEEDED(hr)) {
  293. hr = m_pIPSec->put_DomainDeny(vtVarArray);
  294. VariantClear(&vtVarArray);
  295. }
  296. }
  297. }
  298. // DomainGrant
  299. if(SUCCEEDED(hr)) {
  300. hr = pObj->Get(L"DomainGrant", 0, &vt, NULL, NULL);
  301. if(SUCCEEDED(hr)) {
  302. hr = LoadVariantArrayFromBstrArray(vt, vtVarArray);
  303. VariantClear(&vt);
  304. if(SUCCEEDED(hr)) {
  305. hr = m_pIPSec->put_DomainGrant(vtVarArray);
  306. VariantClear(&vtVarArray);
  307. }
  308. }
  309. }
  310. // GrantByDefault
  311. if(SUCCEEDED(hr))
  312. hr = pObj->Get(L"GrantByDefault", 0, &vt, NULL, NULL);
  313. if(SUCCEEDED(hr))
  314. hr = m_pIPSec->put_GrantByDefault(vt.boolVal);
  315. VariantClear(&vt);
  316. // set the modified IPSecurity back into the metabase
  317. if(SUCCEEDED(hr))
  318. hr = SetSD();
  319. return hr;
  320. }
  321. HRESULT CIPSecurity::OpenSD(_bstr_t bstrAdsPath)
  322. {
  323. _variant_t var;
  324. HRESULT hr;
  325. IDispatch* pDisp = NULL;
  326. try
  327. { // close SD interface first
  328. CloseSD();
  329. hr = GetAdsPath(bstrAdsPath);
  330. if(FAILED(hr))
  331. return hr;
  332. // get m_pADs
  333. hr = ADsGetObject(
  334. bstrAdsPath,
  335. IID_IADs,
  336. (void**)&m_pADs
  337. );
  338. if(FAILED(hr))
  339. return hr;
  340. // get m_pSD
  341. hr = m_pADs->Get(L"IPSecurity",&var);
  342. if(FAILED(hr))
  343. return hr;
  344. hr = V_DISPATCH(&var)->QueryInterface(
  345. IID_IISIPSecurity,
  346. (void**)&m_pIPSec
  347. );
  348. }
  349. catch(...)
  350. {
  351. hr = E_FAIL;
  352. }
  353. return hr;
  354. }
  355. HRESULT CIPSecurity::SetSD()
  356. {
  357. _variant_t var;
  358. HRESULT hr;
  359. IDispatch* pDisp = NULL;
  360. try
  361. {
  362. // put IPSecurity
  363. hr = m_pIPSec->QueryInterface(
  364. IID_IDispatch,
  365. (void**)&pDisp
  366. );
  367. if(FAILED(hr))
  368. return hr;
  369. var.vt = VT_DISPATCH;
  370. var.pdispVal = pDisp;
  371. hr = m_pADs->Put(L"IPSecurity",var); // pDisp will be released by this call Put().
  372. if(FAILED(hr))
  373. return hr;
  374. // Commit the change to the active directory
  375. hr = m_pADs->SetInfo();
  376. }
  377. catch(...)
  378. {
  379. hr = E_FAIL;
  380. }
  381. return hr;
  382. }
  383. HRESULT CIPSecurity::GetAdsPath(_bstr_t& bstrAdsPath)
  384. {
  385. WCHAR* p = new WCHAR[bstrAdsPath.length() + 1];
  386. if(p == NULL)
  387. return E_OUTOFMEMORY;
  388. lstrcpyW(p, bstrAdsPath);
  389. bstrAdsPath = L"IIS://LocalHost";
  390. // trim first three charaters "/LM"
  391. bstrAdsPath += (p+3);
  392. delete [] p;
  393. return S_OK;
  394. }