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.

440 lines
9.1 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. adminmanagercache.cxx
  5. Abstract:
  6. A cache of IAzAuthorizationStore objects
  7. Author:
  8. Bilal Alam (balam) Nov 26, 2001
  9. --*/
  10. #include "precomp.hxx"
  11. BSTR ADMIN_MANAGER::sm_bstrUrlAuthApplication;
  12. //static
  13. HRESULT
  14. ADMIN_MANAGER::Initialize(
  15. VOID
  16. )
  17. /*++
  18. Routine Description:
  19. Global initialization for ADMIN_MANAGER
  20. Arguments:
  21. None
  22. Return Value:
  23. HRESULT
  24. --*/
  25. {
  26. //
  27. // Initialize some BSTRs once
  28. //
  29. DBG_ASSERT( sm_bstrUrlAuthApplication == NULL );
  30. sm_bstrUrlAuthApplication = SysAllocString( URL_AUTH_APPLICATION_NAME );
  31. if ( sm_bstrUrlAuthApplication == NULL )
  32. {
  33. return HRESULT_FROM_WIN32( GetLastError() );
  34. }
  35. return NO_ERROR;
  36. }
  37. //static
  38. VOID
  39. ADMIN_MANAGER::Terminate(
  40. VOID
  41. )
  42. /*++
  43. Routine Description:
  44. Global cleanup for ADMIN_MANAGER
  45. Arguments:
  46. None
  47. Return Value:
  48. None
  49. --*/
  50. {
  51. if ( sm_bstrUrlAuthApplication != NULL )
  52. {
  53. SysFreeString( sm_bstrUrlAuthApplication );
  54. sm_bstrUrlAuthApplication = NULL;
  55. }
  56. }
  57. HRESULT
  58. ADMIN_MANAGER::Create(
  59. WCHAR * pszStoreName
  60. )
  61. /*++
  62. Routine Description:
  63. Create a cache entry object. In this case, the object contains a
  64. pointer to a created IAzAuthorizationStore object
  65. Arguments:
  66. pszStoreName - Name of store to pass down to IAzAdminManager
  67. Return Value:
  68. HRESULT
  69. --*/
  70. {
  71. HRESULT hr;
  72. BSTR bstrStoreName;
  73. VARIANT vNoParam;
  74. HANDLE hToken = NULL;
  75. BOOL fRet;
  76. if ( pszStoreName == NULL )
  77. {
  78. DBG_ASSERT( FALSE );
  79. return HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER );
  80. }
  81. //
  82. // First create the object
  83. //
  84. hr = CoCreateInstance( CLSID_AzAuthorizationStore,
  85. NULL,
  86. CLSCTX_SERVER,
  87. IID_IAzAuthorizationStore,
  88. (VOID**) &_pAdminManager );
  89. if ( FAILED( hr ) )
  90. {
  91. return hr;
  92. }
  93. DBG_ASSERT( _pAdminManager != NULL );
  94. //
  95. // Is this an XML or AD URL? (incredibly lame!)
  96. //
  97. //
  98. // Do some BSTR nonsence
  99. //
  100. bstrStoreName = SysAllocString( pszStoreName );
  101. if ( bstrStoreName == NULL )
  102. {
  103. return HRESULT_FROM_WIN32( GetLastError() );
  104. }
  105. _wcsupr( (WCHAR*) bstrStoreName );
  106. //
  107. // Now initialize the AdminManager
  108. //
  109. VariantInit( &vNoParam );
  110. vNoParam.vt = VT_ERROR;
  111. vNoParam.scode = DISP_E_PARAMNOTFOUND;
  112. //
  113. // Initialize() routine must be called unimpersonated. Very lame!
  114. //
  115. fRet = OpenThreadToken( GetCurrentThread(),
  116. TOKEN_IMPERSONATE,
  117. TRUE,
  118. &hToken );
  119. if ( fRet )
  120. {
  121. DBG_ASSERT( hToken != NULL );
  122. RevertToSelf();
  123. }
  124. hr = _pAdminManager->Initialize( 0,
  125. bstrStoreName,
  126. vNoParam );
  127. if ( hToken != NULL )
  128. {
  129. if ( !SetThreadToken( NULL, hToken ) )
  130. {
  131. DBG_ASSERT( FALSE );
  132. }
  133. CloseHandle( hToken );
  134. hToken = NULL;
  135. }
  136. SysFreeString( bstrStoreName );
  137. if ( FAILED( hr ) )
  138. {
  139. return hr;
  140. }
  141. _fInitialized = TRUE;
  142. return NO_ERROR;
  143. }
  144. HRESULT
  145. ADMIN_MANAGER::GetApplication(
  146. AZ_APPLICATION ** ppAzApplication
  147. )
  148. /*++
  149. Routine Description:
  150. Retrieve the AZ_APPLICATION from the given admin maanger. In the future
  151. there may be more than one application associated with admin manager.
  152. For now there isn't.
  153. Arguments:
  154. ppApplication - Receives pointer to AZ_APPLICATION on success
  155. Return Value:
  156. HRESULT
  157. --*/
  158. {
  159. HRESULT hr;
  160. AZ_APPLICATION * pAzApplication;
  161. IAzApplication * pIApplication;
  162. VARIANT vNoParam;
  163. if ( ppAzApplication == NULL )
  164. {
  165. DBG_ASSERT( FALSE );
  166. return HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER );
  167. }
  168. *ppAzApplication = NULL;
  169. //
  170. // If we already have one associated, then we're done
  171. //
  172. if ( _pAzApplication != NULL )
  173. {
  174. *ppAzApplication = _pAzApplication;
  175. return NO_ERROR;
  176. }
  177. //
  178. // OK. We'll have to create one now
  179. //
  180. //
  181. // Get the application we're interested in (URLAuth)
  182. //
  183. DBG_ASSERT( _pAdminManager != NULL );
  184. VariantInit( &vNoParam );
  185. vNoParam.vt = VT_ERROR;
  186. vNoParam.scode = DISP_E_PARAMNOTFOUND;
  187. hr = _pAdminManager->OpenApplication( sm_bstrUrlAuthApplication,
  188. vNoParam,
  189. &pIApplication );
  190. if ( FAILED( hr ) )
  191. {
  192. return hr;
  193. }
  194. DBG_ASSERT( pIApplication != NULL );
  195. //
  196. // Create an AZ_APPLICATION object which wraps the IAzApplication. In
  197. // the future, an ADMIN_MANAGER may hold more than one application. For
  198. // now it won't
  199. //
  200. pAzApplication = new AZ_APPLICATION( pIApplication );
  201. if ( pAzApplication == NULL )
  202. {
  203. pIApplication->Release();
  204. return HRESULT_FROM_WIN32( ERROR_NOT_ENOUGH_MEMORY );
  205. }
  206. hr = pAzApplication->Create();
  207. if ( FAILED( hr ) )
  208. {
  209. delete pAzApplication;
  210. return hr;
  211. }
  212. //
  213. // Finally, set the AZ_APPLICATION
  214. //
  215. LockCacheEntry();
  216. if ( _pAzApplication == NULL )
  217. {
  218. _pAzApplication = pAzApplication;
  219. }
  220. else
  221. {
  222. delete pAzApplication;
  223. }
  224. UnlockCacheEntry();
  225. *ppAzApplication = _pAzApplication;
  226. DBG_ASSERT( *ppAzApplication != NULL );
  227. return NO_ERROR;
  228. }
  229. HRESULT
  230. ADMIN_MANAGER_CACHE::GetAdminManager(
  231. WCHAR * pszStoreName,
  232. ADMIN_MANAGER ** ppAdminManager
  233. )
  234. /*++
  235. Routine Description:
  236. Returns (and creates if necessary) an ADMIN_MANAGER object for the
  237. given store name
  238. Arguments:
  239. pszStoreName - Store name
  240. ppAdminManager - Filled with pointer to ADMIN_MANAGER if successful
  241. Return Value:
  242. HRESULT
  243. --*/
  244. {
  245. ADMIN_MANAGER_CACHE_KEY cacheKey;
  246. ADMIN_MANAGER * pAdminManager = NULL;
  247. HRESULT hr;
  248. if ( pszStoreName == NULL ||
  249. ppAdminManager == NULL )
  250. {
  251. DBG_ASSERT( FALSE );
  252. return HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER );
  253. }
  254. *ppAdminManager = NULL;
  255. //
  256. // First lookup in the cache
  257. //
  258. hr = cacheKey.SetStore( pszStoreName );
  259. if ( FAILED( hr ) )
  260. {
  261. return hr;
  262. }
  263. TryAgain:
  264. hr = FindCacheEntry( &cacheKey,
  265. (CACHE_ENTRY**) &pAdminManager );
  266. if ( FAILED( hr ) )
  267. {
  268. //
  269. // Anything but ERROR_FILE_NOT_FOUND is a bad thing
  270. //
  271. if ( hr != HRESULT_FROM_WIN32( ERROR_FILE_NOT_FOUND ) )
  272. {
  273. return hr;
  274. }
  275. //
  276. // Create an ADMIN_MANAGER
  277. //
  278. pAdminManager = new ADMIN_MANAGER( this );
  279. if ( pAdminManager == NULL )
  280. {
  281. return HRESULT_FROM_WIN32( ERROR_NOT_ENOUGH_MEMORY );
  282. }
  283. //
  284. // We'll initialize it later. We do this to avoid more than one
  285. // simulatenous call to pAdminManager->Create() because AZRoles crap
  286. // doesn't like it
  287. //
  288. //
  289. // Add it to the cache. If we couldn't because it was already
  290. // there, then try again to retrieve it
  291. //
  292. AddCacheEntry( (CACHE_ENTRY*) pAdminManager );
  293. if ( pAdminManager->QueryCached() == FALSE )
  294. {
  295. pAdminManager->DereferenceCacheEntry();
  296. pAdminManager = NULL;
  297. goto TryAgain;
  298. }
  299. }
  300. //
  301. // Initialize the entry once before use. This mechanism ensures only
  302. // one call is made to initialize for the same store name
  303. //
  304. if ( !pAdminManager->QueryIsInitialized() )
  305. {
  306. pAdminManager->LockCacheEntry();
  307. if ( !pAdminManager->QueryIsInitialized() )
  308. {
  309. hr = pAdminManager->Create( pszStoreName );
  310. }
  311. else
  312. {
  313. hr = NO_ERROR;
  314. }
  315. pAdminManager->UnlockCacheEntry();
  316. if ( FAILED( hr ) )
  317. {
  318. pAdminManager->DereferenceCacheEntry();
  319. pAdminManager = NULL;
  320. return hr;
  321. }
  322. }
  323. DBG_ASSERT( pAdminManager != NULL );
  324. *ppAdminManager = pAdminManager;
  325. return NO_ERROR;
  326. }