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.

701 lines
18 KiB

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