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.

493 lines
12 KiB

  1. // Policy.cpp: implementation for the CPolicy base class for main mode
  2. // and quick mode policies
  3. //
  4. // Copyright (c)1997-2001 Microsoft Corporation
  5. //
  6. //////////////////////////////////////////////////////////////////////
  7. #include "precomp.h"
  8. #include "NetSecProv.h"
  9. #include "Policy.h"
  10. #include "PolicyMM.h"
  11. #include "PolicyQM.h"
  12. //extern CCriticalSection g_CS;
  13. /*
  14. Routine Description:
  15. Name:
  16. CIPSecPolicy::Rollback
  17. Functionality:
  18. Static function to rollback those policies added by us with the given token.
  19. Virtual:
  20. No.
  21. Arguments:
  22. pNamespace - The namespace for ourselves.
  23. pszRollbackToken - The token used to record our the action when we add
  24. the policies.
  25. bClearAll - Flag whether we should clear all policies. If it's true,
  26. then we will delete all the policies regardless whether they
  27. are added by us or not. This is a dangerous flag.
  28. Return Value:
  29. Success:
  30. (1) WBEM_NO_ERROR: rollback objects are found and they are deleted.
  31. (2) WBEM_S_FALSE: no rollback objects are found.
  32. Failure:
  33. Various error codes indicating the cause of the failure.
  34. Notes:
  35. We will continue the deletion even if some failure happens. That failure will be
  36. returned, though.
  37. $undone:shawnwu, should we really support ClearAll?
  38. */
  39. HRESULT
  40. CIPSecPolicy::Rollback (
  41. IN IWbemServices * pNamespace,
  42. IN LPCWSTR pszRollbackToken,
  43. IN bool bClearAll
  44. )
  45. {
  46. if (pNamespace == NULL || pszRollbackToken == NULL)
  47. {
  48. return WBEM_E_INVALID_PARAMETER;
  49. }
  50. //if (bClearAll)
  51. //{
  52. // return ClearAllPolicies(pNamespace);
  53. //}
  54. CComPtr<IEnumWbemClassObject> srpEnum;
  55. //
  56. // this will only enumerate all rollback filter object without testing the
  57. // the token guid. This limitation is due to a mysterious error
  58. // for any queries containing the where clause. That might be a limitation
  59. // of non-dynamic classes of WMI
  60. //
  61. HRESULT hr = ::GetClassEnum(pNamespace, pszNspRollbackPolicy, &srpEnum);
  62. //
  63. // go through all found classes. srpEnum->Next will return WBEM_S_FALSE if instance
  64. // is not found.
  65. //
  66. CComPtr<IWbemClassObject> srpObj;
  67. ULONG nEnum = 0;
  68. HRESULT hrError = WBEM_NO_ERROR;
  69. hr = srpEnum->Next(WBEM_INFINITE, 1, &srpObj, &nEnum);
  70. bool bHasInst = (SUCCEEDED(hr) && hr != WBEM_S_FALSE && srpObj != NULL);
  71. while (SUCCEEDED(hr) && hr != WBEM_S_FALSE && srpObj)
  72. {
  73. CComVariant varTokenGuid;
  74. hr = srpObj->Get(g_pszTokenGuid, 0, &varTokenGuid, NULL, NULL);
  75. //
  76. // need to compare the token guid ourselves
  77. //
  78. if (SUCCEEDED(hr) &&
  79. varTokenGuid.vt == VT_BSTR &&
  80. varTokenGuid.bstrVal != NULL &&
  81. (_wcsicmp(pszRollbackToken, pszRollbackAll) == 0 || _wcsicmp(pszRollbackToken, varTokenGuid.bstrVal) == 0 )
  82. )
  83. {
  84. //
  85. // get the policy name and find the policy by the name
  86. //
  87. CComVariant varPolicyName;
  88. CComVariant varPolicyType;
  89. hr = srpObj->Get(g_pszPolicyName, 0, &varPolicyName, NULL, NULL);
  90. GUID guidFilter = GUID_NULL;
  91. //
  92. // different types of policy has different
  93. //
  94. if (SUCCEEDED(hr))
  95. {
  96. hr = srpObj->Get(g_pszPolicyType, 0, &varPolicyType, NULL, NULL);
  97. if (SUCCEEDED(hr) && varPolicyType.vt != VT_I4)
  98. {
  99. hr = WBEM_E_INVALID_OBJECT;
  100. }
  101. }
  102. if (SUCCEEDED(hr) && varPolicyName.vt == VT_BSTR)
  103. {
  104. DWORD dwResumeHandle = 0;
  105. DWORD dwReturned = 0;
  106. DWORD dwStatus;
  107. if (varPolicyType.lVal == MainMode_Policy)
  108. {
  109. //
  110. // main mode policy
  111. //
  112. hr = CMMPolicy::DeletePolicy(varPolicyName.bstrVal);
  113. }
  114. else if (varPolicyType.lVal == QuickMode_Policy)
  115. {
  116. //
  117. // quick mode policy
  118. //
  119. hr = CQMPolicy::DeletePolicy(varPolicyName.bstrVal);
  120. }
  121. }
  122. if (SUCCEEDED(hr))
  123. {
  124. CComVariant varPath;
  125. if (SUCCEEDED(srpObj->Get(L"__RelPath", 0, &varPath, NULL, NULL)) && varPath.vt == VT_BSTR)
  126. {
  127. hr = pNamespace->DeleteInstance(varPath.bstrVal, 0, NULL, NULL);
  128. }
  129. }
  130. //
  131. // we are tracking the first error
  132. //
  133. if (FAILED(hr) && SUCCEEDED(hrError))
  134. {
  135. hrError = hr;
  136. }
  137. }
  138. //
  139. // ready it for re-use
  140. //
  141. srpObj.Release();
  142. hr = srpEnum->Next(WBEM_INFINITE, 1, &srpObj, &nEnum);
  143. }
  144. if (SUCCEEDED(hr))
  145. {
  146. hr = CQMPolicy::DeleteDefaultPolicies();
  147. }
  148. if (!bHasInst)
  149. {
  150. return WBEM_S_FALSE;
  151. }
  152. else
  153. {
  154. //
  155. // any failure code will be returned regardless of the final hr
  156. //
  157. if (FAILED(hrError))
  158. {
  159. return hrError;
  160. }
  161. else
  162. {
  163. return SUCCEEDED(hr) ? WBEM_NO_ERROR : hr;
  164. }
  165. }
  166. }
  167. /*
  168. Routine Description:
  169. Name:
  170. CIPSecPolicy::ClearAllPolicies
  171. Functionality:
  172. Static function to delete all policies in SPD. This is a very dangerous action!
  173. Virtual:
  174. No.
  175. Arguments:
  176. pNamespace - The namespace for ourselves.
  177. Return Value:
  178. Success:
  179. WBEM_NO_ERROR.
  180. Failure:
  181. Various error codes indicating the cause of the failure.
  182. Notes:
  183. We will continue the deletion even if some failure happens. That failure will be
  184. returned, though.
  185. $undone:shawnwu, should we really support this?
  186. */
  187. HRESULT
  188. CIPSecPolicy::ClearAllPolicies (
  189. IN IWbemServices * pNamespace
  190. )
  191. {
  192. DWORD dwResumeHandle = 0;
  193. DWORD dwReturned = 0;
  194. DWORD dwStatus;
  195. HRESULT hr = WBEM_NO_ERROR;
  196. HRESULT hrError = WBEM_NO_ERROR;
  197. //
  198. // SPD doesn't have a similar API.
  199. // We have to do one by one. For that purpose, we need the name.
  200. //
  201. //
  202. // Delete main mode policies.
  203. //
  204. PIPSEC_MM_POLICY *ppMMPolicy = NULL;
  205. dwStatus = ::EnumMMPolicies(NULL, ppMMPolicy, 1, &dwReturned, &dwResumeHandle);
  206. while (ERROR_SUCCESS == dwStatus && dwReturned > 0)
  207. {
  208. hr = CMMPolicy::DeletePolicy((*ppMMPolicy)->pszPolicyName);
  209. //
  210. // we will track the first error
  211. //
  212. if (FAILED(hr) && SUCCEEDED(hrError))
  213. {
  214. hrError = hr;
  215. }
  216. FreePolicy(ppMMPolicy, true);
  217. *ppMMPolicy = NULL;
  218. dwReturned = 0;
  219. dwStatus = ::EnumMMPolicies(NULL, ppMMPolicy, 1, &dwReturned, &dwResumeHandle);
  220. }
  221. //
  222. // Delete quick mode policies.
  223. //
  224. PIPSEC_QM_POLICY *ppQMPolicy = NULL;
  225. dwResumeHandle = 0;
  226. dwReturned = 0;
  227. dwStatus = ::EnumQMPolicies(NULL, ppQMPolicy, 1, &dwReturned, &dwResumeHandle);
  228. while (ERROR_SUCCESS == dwStatus && dwReturned > 0)
  229. {
  230. hr = CQMPolicy::DeletePolicy((*ppQMPolicy)->pszPolicyName);
  231. //
  232. // we will track the first error
  233. //
  234. if (FAILED(hr) && SUCCEEDED(hrError))
  235. {
  236. hrError = hr;
  237. }
  238. FreePolicy(ppQMPolicy, true);
  239. *ppQMPolicy = NULL;
  240. dwReturned = 0;
  241. dwStatus = ::EnumQMPolicies(NULL, ppQMPolicy, 1, &dwReturned, &dwResumeHandle);
  242. }
  243. //
  244. // now, let's clear up all past action information for policies deposited in the
  245. // WMI depository
  246. //
  247. hr = ::DeleteRollbackObjects(pNamespace, pszNspRollbackPolicy);
  248. if (FAILED(hr) && SUCCEEDED(hrError))
  249. {
  250. hrError = hr;
  251. }
  252. return SUCCEEDED(hrError) ? WBEM_NO_ERROR : hrError;
  253. }
  254. /*
  255. Routine Description:
  256. Name:
  257. CIPSecPolicy::OnAfterAddPolicy
  258. Functionality:
  259. Post-adding handler to be called after successfully added a policy to SPD.
  260. Virtual:
  261. No.
  262. Arguments:
  263. pszPolicyName - The name of the filter.
  264. eType - The type of the policy (main mode or quick mode).
  265. Return Value:
  266. Success:
  267. (1) WBEM_NO_ERROR: if rollback object is successfully created.
  268. (2) WBEM_S_FALSE: if there is no rollback guid information.
  269. Failure:
  270. (1) various errors indicated by the returned error codes.
  271. Notes:
  272. (1) Currently, we don't require a rollback object to be created for each
  273. object added to SPD. Only a host that support rollback will deposit
  274. rollback guid information and only then can we create a rollback object.
  275. */
  276. HRESULT
  277. CIPSecPolicy::OnAfterAddPolicy (
  278. IN LPCWSTR pszPolicyName,
  279. IN EnumPolicyType eType
  280. )
  281. {
  282. //
  283. // will create an Nsp_RollbackPolicy
  284. //
  285. CComPtr<IWbemClassObject> srpObj;
  286. HRESULT hr = SpawnRollbackInstance(pszNspRollbackPolicy, &srpObj);
  287. if (FAILED(hr))
  288. {
  289. return hr;
  290. }
  291. //
  292. // won't consider a failure if there is no rollback guid, i.e., this action is not
  293. // part of a transaction block
  294. //
  295. if (SUCCEEDED(hr))
  296. {
  297. //
  298. // $undone:shawnwu, this approach to pulling the globals are not good.
  299. // Instead, we should implement it as an event handler.
  300. //
  301. //::UpdateGlobals(m_srpNamespace, m_srpCtx);
  302. //if (g_varRollbackGuid.vt != VT_NULL && g_varRollbackGuid.vt != VT_EMPTY)
  303. //{
  304. // hr = srpObj->Put(g_pszTokenGuid, 0, &g_varRollbackGuid, CIM_EMPTY);
  305. //}
  306. //else
  307. //{
  308. CComVariant varRollbackNull = pszEmptyRollbackToken;
  309. hr = srpObj->Put(g_pszTokenGuid, 0, &varRollbackNull, CIM_EMPTY);
  310. //}
  311. //
  312. // we can create a rollback object
  313. //
  314. if (SUCCEEDED(hr))
  315. {
  316. //
  317. // $undone:shawnwu, Currently, we only support rolling back added objects, not removed objects
  318. // Also, we don't cache the previous instance data yet.
  319. //
  320. VARIANT varAction;
  321. //
  322. // This is to record a PutInstance action
  323. //
  324. varAction.vt = VT_I4;
  325. varAction.lVal = Action_Add;
  326. hr = srpObj->Put(g_pszAction, 0, &varAction, CIM_EMPTY);
  327. if (SUCCEEDED(hr))
  328. {
  329. //
  330. // need to remember the policy's name
  331. //
  332. CComVariant var = pszPolicyName;
  333. hr = srpObj->Put(g_pszPolicyName, 0, &var, CIM_EMPTY);
  334. if (SUCCEEDED(hr))
  335. {
  336. var.Clear();
  337. var.vt = VT_I4;
  338. var.lVal = eType;
  339. hr = srpObj->Put(g_pszPolicyType, 0, &var, CIM_EMPTY);
  340. }
  341. }
  342. }
  343. }
  344. if (SUCCEEDED(hr))
  345. {
  346. hr = m_srpNamespace->PutInstance(srpObj, WBEM_FLAG_CREATE_OR_UPDATE, m_srpCtx, NULL);
  347. if (SUCCEEDED(hr))
  348. {
  349. hr = WBEM_NO_ERROR;
  350. }
  351. }
  352. else if (SUCCEEDED(hr))
  353. {
  354. //
  355. // we don't have rollback guid
  356. //
  357. hr = WBEM_S_FALSE;
  358. }
  359. return hr;
  360. }