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.

537 lines
14 KiB

  1. // option.cpp, implementation of CSecurityOptions class
  2. // Copyright (c)1997-1999 Microsoft Corporation
  3. //
  4. //////////////////////////////////////////////////////////////////////
  5. #include "precomp.h"
  6. #include "option.h"
  7. #include "persistmgr.h"
  8. #include <io.h>
  9. #include "requestobject.h"
  10. #define KeyAdmin L"NewAdministratorName"
  11. #define KeyGuest L"NewGuestName"
  12. /*
  13. Routine Description:
  14. Name:
  15. CSecurityOptions::CSecurityOptions
  16. Functionality:
  17. This is the constructor. Pass along the parameters to the base class
  18. Virtual:
  19. No (you know that, constructor won't be virtual!)
  20. Arguments:
  21. pKeyChain - Pointer to the ISceKeyChain COM interface which is prepared
  22. by the caller who constructs this instance.
  23. pNamespace - Pointer to WMI namespace of our provider (COM interface).
  24. Passed along by the caller. Must not be NULL.
  25. pCtx - Pointer to WMI context object (COM interface). Passed along
  26. by the caller. It's up to WMI whether this interface pointer is NULL or not.
  27. Return Value:
  28. None as any constructor
  29. Notes:
  30. if you create any local members, think about initialize them here
  31. */
  32. CSecurityOptions::CSecurityOptions (
  33. IN ISceKeyChain * pKeyChain,
  34. IN IWbemServices * pNamespace,
  35. IN IWbemContext * pCtx
  36. )
  37. :
  38. CGenericClass(pKeyChain, pNamespace, pCtx)
  39. {
  40. }
  41. /*
  42. Routine Description:
  43. Name:
  44. CSecurityOptions::~CSecurityOptions
  45. Functionality:
  46. Destructor. Necessary as good C++ discipline since we have virtual functions.
  47. Virtual:
  48. Yes.
  49. Arguments:
  50. none as any destructor
  51. Return Value:
  52. None as any destructor
  53. Notes:
  54. if you create any local members, think about whether
  55. there is any need for a non-trivial destructor
  56. */
  57. CSecurityOptions::~CSecurityOptions ()
  58. {
  59. }
  60. /*
  61. Routine Description:
  62. Name:
  63. CSecurityOptions::CreateObject
  64. Functionality:
  65. Create WMI objects (Sce_SecurityOptions). Depending on parameter atAction,
  66. this creation may mean:
  67. (a) Get a single instance (atAction == ACTIONTYPE_GET)
  68. (b) Get several instances satisfying some criteria (atAction == ACTIONTYPE_QUERY)
  69. (c) Delete an instance (atAction == ACTIONTYPE_DELETE)
  70. Virtual:
  71. Yes.
  72. Arguments:
  73. pHandler - COM interface pointer for notifying WMI for creation result.
  74. atAction - Get single instance ACTIONTYPE_GET
  75. Get several instances ACTIONTYPE_QUERY
  76. Delete a single instance ACTIONTYPE_DELETE
  77. Return Value:
  78. Success: it must return success code (use SUCCEEDED to test). It is
  79. not guaranteed to return WBEM_NO_ERROR. The returned objects are indicated to WMI,
  80. not directly passed back via parameters.
  81. Failure: Various errors may occurs. Except WBEM_E_NOT_FOUND, any such error should indicate
  82. the failure of getting the wanted instance. If WBEM_E_NOT_FOUND is returned in querying
  83. situations, this may not be an error depending on caller's intention.
  84. Notes:
  85. */
  86. HRESULT
  87. CSecurityOptions::CreateObject (
  88. IN IWbemObjectSink * pHandler,
  89. IN ACTIONTYPE atAction
  90. )
  91. {
  92. //
  93. // we know how to:
  94. // Get single instance ACTIONTYPE_GET
  95. // Delete a single instance ACTIONTYPE_DELETE
  96. // Get several instances ACTIONTYPE_QUERY
  97. //
  98. if ( ACTIONTYPE_GET != atAction &&
  99. ACTIONTYPE_DELETE != atAction &&
  100. ACTIONTYPE_QUERY != atAction )
  101. {
  102. return WBEM_E_NOT_SUPPORTED;
  103. }
  104. //
  105. // return WBEM_S_FALSE if the key is not recognized
  106. //
  107. CComVariant varStorePath;
  108. HRESULT hr = m_srpKeyChain->GetKeyPropertyValue(pStorePath, &varStorePath);
  109. if (SUCCEEDED(hr) && hr != WBEM_S_FALSE && varStorePath.vt == VT_BSTR)
  110. {
  111. //
  112. // Prepare a store (for persistence) for this store path (file)
  113. //
  114. CSceStore SceStore;
  115. hr = SceStore.SetPersistPath(varStorePath.bstrVal);
  116. if ( SUCCEEDED(hr) )
  117. {
  118. //
  119. // make sure the store (just a file) really exists. The raw path
  120. // may contain env variables, so we need the expanded path
  121. //
  122. DWORD dwAttrib = GetFileAttributes(SceStore.GetExpandedPath());
  123. if ( dwAttrib != -1 )
  124. {
  125. if ( ACTIONTYPE_DELETE == atAction )
  126. {
  127. hr = DeleteInstance(pHandler, &SceStore);
  128. }
  129. else
  130. {
  131. BOOL bPostFilter=TRUE;
  132. DWORD dwCount = 0;
  133. m_srpKeyChain->GetKeyPropertyCount(&dwCount);
  134. if ( ACTIONTYPE_QUERY == atAction && dwCount == 1 )
  135. {
  136. bPostFilter = FALSE;
  137. }
  138. hr = ConstructInstance(pHandler, &SceStore, varStorePath.bstrVal, bPostFilter);
  139. }
  140. }
  141. else
  142. {
  143. hr = WBEM_E_NOT_FOUND;
  144. }
  145. }
  146. }
  147. return hr;
  148. }
  149. /*
  150. Routine Description:
  151. Name:
  152. CSecurityOptions::PutInst
  153. Functionality:
  154. Put an instance as instructed by WMI. Since this class implements Sce_SecurityOptions,
  155. which is persistence oriented, this will cause the Sce_SecurityOptions object's property
  156. information to be saved in our store.
  157. Virtual:
  158. Yes.
  159. Arguments:
  160. pInst - COM interface pointer to the WMI class (Sce_SecurityOptions) object.
  161. pHandler - COM interface pointer for notifying WMI of any events.
  162. pCtx - COM interface pointer. This interface is just something we pass around.
  163. WMI may mandate it (not now) in the future. But we never construct
  164. such an interface and so, we just pass around for various WMI API's
  165. Return Value:
  166. Success: it must return success code (use SUCCEEDED to test). It is
  167. not guaranteed to return WBEM_NO_ERROR.
  168. Failure: Various errors may occurs. Any such error should indicate the failure of persisting
  169. the instance.
  170. Notes:
  171. Since GetProperty will return a success code (WBEM_S_RESET_TO_DEFAULT) when the
  172. requested property is not present, don't simply use SUCCEEDED or FAILED macros
  173. to test for the result of retrieving a property.
  174. */
  175. HRESULT
  176. CSecurityOptions::PutInst (
  177. IN IWbemClassObject * pInst,
  178. IN IWbemObjectSink * pHandler,
  179. IN IWbemContext * pCtx
  180. )
  181. {
  182. CComBSTR bstrAdmin;
  183. CComBSTR bstrGuest;
  184. //
  185. // CScePropertyMgr helps us to access WMI object's properties
  186. // create an instance and attach the WMI object to it.
  187. // This will always succeed.
  188. //
  189. CScePropertyMgr ScePropMgr;
  190. ScePropMgr.Attach(pInst);
  191. HRESULT hr = ScePropMgr.GetProperty(pAdministratorAccountName, &bstrAdmin);
  192. if (SUCCEEDED(hr))
  193. {
  194. hr = ScePropMgr.GetProperty(pGuestAccountName, &bstrGuest);
  195. }
  196. //
  197. // now save the info to file
  198. //
  199. if (SUCCEEDED(hr))
  200. {
  201. //
  202. // Attach the WMI object instance to the store and let the store know that
  203. // it's store is given by the pStorePath property of the instance.
  204. //
  205. CSceStore SceStore;
  206. hr = SceStore.SetPersistProperties(pInst, pStorePath);
  207. //
  208. // an INF template file
  209. // Write an empty buffer to the file
  210. // will creates the file with right header/signature/unicode format
  211. //
  212. if (SUCCEEDED(hr))
  213. {
  214. DWORD dwDump;
  215. //
  216. // For a new .inf file. Write an empty buffer to the file
  217. // will creates the file with right header/signature/unicode format
  218. // this is harmless for existing files.
  219. // For database store, this is a no-op.
  220. //
  221. hr = SceStore.WriteSecurityProfileInfo(
  222. AreaBogus,
  223. (PSCE_PROFILE_INFO)&dwDump,
  224. NULL,
  225. false
  226. );
  227. }
  228. if (SUCCEEDED(hr))
  229. {
  230. hr = SceStore.SavePropertyToStore(szSystemAccess, KeyAdmin, bstrAdmin);
  231. }
  232. if (SUCCEEDED(hr))
  233. {
  234. hr = SceStore.SavePropertyToStore(szSystemAccess, KeyGuest, bstrGuest);
  235. }
  236. }
  237. return hr;
  238. }
  239. /*
  240. Routine Description:
  241. Name:
  242. CSecurityOptions::ConstructInstance
  243. Functionality:
  244. This is private function to create an instance of Sce_SecurityOptions.
  245. Virtual:
  246. No.
  247. Arguments:
  248. pHandler - COM interface pointer for notifying WMI of any events.
  249. pSceStore - Pointer to our store. It must have been appropriately set up.
  250. wszLogStorePath - store path, a key property of Sce_SecurityOptions class.
  251. bPostFilter - Controls how WMI will be informed with pHandler->SetStatus.
  252. Return Value:
  253. Success: it must return success code (use SUCCEEDED to test). It is
  254. not guaranteed to return WBEM_NO_ERROR.
  255. Failure: Various errors may occurs. Any such error should indicate the creating the instance.
  256. Notes:
  257. */
  258. HRESULT CSecurityOptions::ConstructInstance (
  259. IN IWbemObjectSink * pHandler,
  260. IN CSceStore * pSceStore,
  261. IN LPCWSTR wszLogStorePath,
  262. IN BOOL bPostFilter
  263. )
  264. {
  265. //
  266. // make sure that we have a valid store
  267. //
  268. if ( pSceStore == NULL ||
  269. pSceStore->GetStoreType() < SCE_INF_FORMAT ||
  270. pSceStore->GetStoreType() > SCE_JET_ANALYSIS_REQUIRED )
  271. {
  272. return WBEM_E_INVALID_PARAMETER;
  273. }
  274. //
  275. // ask SCE to read a gigantic structure out from the store. Only SCE
  276. // knows now to release the memory. Don't just delete it! Use our CSceStore
  277. // to do the releasing (FreeSecurityProfileInfo)
  278. //
  279. PSCE_PROFILE_INFO pInfo=NULL;
  280. HRESULT hr = pSceStore->GetSecurityProfileInfo(
  281. AREA_SECURITY_POLICY,
  282. &pInfo,
  283. NULL
  284. );
  285. if (SUCCEEDED(hr) && pInfo != NULL && pInfo->NewAdministratorName == NULL && pInfo->NewGuestName == NULL )
  286. {
  287. hr = WBEM_E_NOT_FOUND;
  288. }
  289. if (SUCCEEDED(hr))
  290. {
  291. CComBSTR bstrLogOut;
  292. //
  293. // the use of the macro SCE_PROV_IfErrorGotoCleanup cause
  294. // a "goto CleanUp;" with hr set to the return value from
  295. // the function (macro parameter)
  296. //
  297. SCE_PROV_IfErrorGotoCleanup(MakeSingleBackSlashPath(wszLogStorePath, L'\\', &bstrLogOut));
  298. CComPtr<IWbemClassObject> srpObj;
  299. SCE_PROV_IfErrorGotoCleanup(SpawnAnInstance(&srpObj));
  300. //
  301. // CScePropertyMgr helps us to access WMI object's properties
  302. // create an instance and attach the WMI object to it.
  303. // This will always succeed.
  304. //
  305. CScePropertyMgr ScePropMgr;
  306. ScePropMgr.Attach(srpObj);
  307. SCE_PROV_IfErrorGotoCleanup(ScePropMgr.PutProperty(pStorePath, bstrLogOut));
  308. if (pInfo->NewAdministratorName != NULL )
  309. {
  310. SCE_PROV_IfErrorGotoCleanup(ScePropMgr.PutProperty(pAdministratorAccountName, pInfo->NewAdministratorName));
  311. }
  312. if (pInfo->NewGuestName != NULL )
  313. {
  314. SCE_PROV_IfErrorGotoCleanup(ScePropMgr.PutProperty(pGuestAccountName, pInfo->NewGuestName));
  315. }
  316. //
  317. // do the necessary gestures to WMI.
  318. // the use of WBEM_STATUS_REQUIREMENTS in SetStatus is not documented by WMI
  319. // at this point. Consult WMI team for detail if you suspect problems with
  320. // the use of WBEM_STATUS_REQUIREMENTS
  321. //
  322. if ( !bPostFilter )
  323. {
  324. pHandler->SetStatus(WBEM_STATUS_REQUIREMENTS, S_FALSE, NULL, NULL);
  325. }
  326. else
  327. {
  328. pHandler->SetStatus(WBEM_STATUS_REQUIREMENTS, S_OK, NULL, NULL);
  329. }
  330. //
  331. // everything alright, pass to WMI the newly created instance!
  332. //
  333. hr = pHandler->Indicate(1, &srpObj);
  334. }
  335. CleanUp:
  336. pSceStore->FreeSecurityProfileInfo(pInfo);
  337. return hr;
  338. }
  339. /*
  340. Routine Description:
  341. Name:
  342. CSecurityOptions::DeleteInstance
  343. Functionality:
  344. remove an instance of Sce_SecurityOptions from the specified store.
  345. Virtual:
  346. No.
  347. Arguments:
  348. pHandler - COM interface pointer for notifying WMI of any events.
  349. pSceStore - Pointer to our store. It must have been appropriately set up.
  350. Return Value:
  351. Success: WBEM_NO_ERROR.
  352. Failure: WBEM_E_INVALID_PARAMETER.
  353. Notes:
  354. */
  355. HRESULT
  356. CSecurityOptions::DeleteInstance (
  357. IWbemObjectSink *pHandler,
  358. CSceStore* pSceStore
  359. )
  360. {
  361. //
  362. // make sure that we have a valid store
  363. //
  364. if ( pSceStore == NULL ||
  365. pSceStore->GetStoreType() < SCE_INF_FORMAT ||
  366. pSceStore->GetStoreType() > SCE_JET_ANALYSIS_REQUIRED )
  367. {
  368. return WBEM_E_INVALID_PARAMETER;
  369. }
  370. //
  371. // this shouldn't fail unless parameter is not valid.
  372. // If it fails, then we don't bother to delete the second property
  373. //
  374. HRESULT hr = pSceStore->SavePropertyToStore(szSystemAccess, KeyAdmin, (LPCWSTR)NULL);
  375. if (SUCCEEDED(hr))
  376. {
  377. hr = pSceStore->SavePropertyToStore(szSystemAccess, KeyGuest, (LPCWSTR)NULL);
  378. }
  379. return hr;
  380. }