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.

648 lines
16 KiB

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