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

/*++
Copyright (c) 2000 Microsoft Corporation
Module Name:
adminmanagercache.cxx
Abstract:
A cache of IAzAuthorizationStore objects
Author:
Bilal Alam (balam) Nov 26, 2001
--*/
#include "precomp.hxx"
BSTR ADMIN_MANAGER::sm_bstrUrlAuthApplication;
//static
HRESULT
ADMIN_MANAGER::Initialize(
VOID
)
/*++
Routine Description:
Global initialization for ADMIN_MANAGER
Arguments:
None
Return Value:
HRESULT
--*/
{
//
// Initialize some BSTRs once
//
DBG_ASSERT( sm_bstrUrlAuthApplication == NULL );
sm_bstrUrlAuthApplication = SysAllocString( URL_AUTH_APPLICATION_NAME );
if ( sm_bstrUrlAuthApplication == NULL )
{
return HRESULT_FROM_WIN32( GetLastError() );
}
return NO_ERROR;
}
//static
VOID
ADMIN_MANAGER::Terminate(
VOID
)
/*++
Routine Description:
Global cleanup for ADMIN_MANAGER
Arguments:
None
Return Value:
None
--*/
{
if ( sm_bstrUrlAuthApplication != NULL )
{
SysFreeString( sm_bstrUrlAuthApplication );
sm_bstrUrlAuthApplication = NULL;
}
}
HRESULT
ADMIN_MANAGER::Create(
WCHAR * pszStoreName
)
/*++
Routine Description:
Create a cache entry object. In this case, the object contains a
pointer to a created IAzAuthorizationStore object
Arguments:
pszStoreName - Name of store to pass down to IAzAdminManager
Return Value:
HRESULT
--*/
{
HRESULT hr;
BSTR bstrStoreName;
VARIANT vNoParam;
HANDLE hToken = NULL;
BOOL fRet;
if ( pszStoreName == NULL )
{
DBG_ASSERT( FALSE );
return HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER );
}
//
// First create the object
//
hr = CoCreateInstance( CLSID_AzAuthorizationStore,
NULL,
CLSCTX_SERVER,
IID_IAzAuthorizationStore,
(VOID**) &_pAdminManager );
if ( FAILED( hr ) )
{
return hr;
}
DBG_ASSERT( _pAdminManager != NULL );
//
// Is this an XML or AD URL? (incredibly lame!)
//
//
// Do some BSTR nonsence
//
bstrStoreName = SysAllocString( pszStoreName );
if ( bstrStoreName == NULL )
{
return HRESULT_FROM_WIN32( GetLastError() );
}
_wcsupr( (WCHAR*) bstrStoreName );
//
// Now initialize the AdminManager
//
VariantInit( &vNoParam );
vNoParam.vt = VT_ERROR;
vNoParam.scode = DISP_E_PARAMNOTFOUND;
//
// Initialize() routine must be called unimpersonated. Very lame!
//
fRet = OpenThreadToken( GetCurrentThread(),
TOKEN_IMPERSONATE,
TRUE,
&hToken );
if ( fRet )
{
DBG_ASSERT( hToken != NULL );
RevertToSelf();
}
hr = _pAdminManager->Initialize( 0,
bstrStoreName,
vNoParam );
if ( hToken != NULL )
{
if ( !SetThreadToken( NULL, hToken ) )
{
DBG_ASSERT( FALSE );
}
CloseHandle( hToken );
hToken = NULL;
}
SysFreeString( bstrStoreName );
if ( FAILED( hr ) )
{
return hr;
}
_fInitialized = TRUE;
return NO_ERROR;
}
HRESULT
ADMIN_MANAGER::GetApplication(
AZ_APPLICATION ** ppAzApplication
)
/*++
Routine Description:
Retrieve the AZ_APPLICATION from the given admin maanger. In the future
there may be more than one application associated with admin manager.
For now there isn't.
Arguments:
ppApplication - Receives pointer to AZ_APPLICATION on success
Return Value:
HRESULT
--*/
{
HRESULT hr;
AZ_APPLICATION * pAzApplication;
IAzApplication * pIApplication;
VARIANT vNoParam;
if ( ppAzApplication == NULL )
{
DBG_ASSERT( FALSE );
return HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER );
}
*ppAzApplication = NULL;
//
// If we already have one associated, then we're done
//
if ( _pAzApplication != NULL )
{
*ppAzApplication = _pAzApplication;
return NO_ERROR;
}
//
// OK. We'll have to create one now
//
//
// Get the application we're interested in (URLAuth)
//
DBG_ASSERT( _pAdminManager != NULL );
VariantInit( &vNoParam );
vNoParam.vt = VT_ERROR;
vNoParam.scode = DISP_E_PARAMNOTFOUND;
hr = _pAdminManager->OpenApplication( sm_bstrUrlAuthApplication,
vNoParam,
&pIApplication );
if ( FAILED( hr ) )
{
return hr;
}
DBG_ASSERT( pIApplication != NULL );
//
// Create an AZ_APPLICATION object which wraps the IAzApplication. In
// the future, an ADMIN_MANAGER may hold more than one application. For
// now it won't
//
pAzApplication = new AZ_APPLICATION( pIApplication );
if ( pAzApplication == NULL )
{
pIApplication->Release();
return HRESULT_FROM_WIN32( ERROR_NOT_ENOUGH_MEMORY );
}
hr = pAzApplication->Create();
if ( FAILED( hr ) )
{
delete pAzApplication;
return hr;
}
//
// Finally, set the AZ_APPLICATION
//
LockCacheEntry();
if ( _pAzApplication == NULL )
{
_pAzApplication = pAzApplication;
}
else
{
delete pAzApplication;
}
UnlockCacheEntry();
*ppAzApplication = _pAzApplication;
DBG_ASSERT( *ppAzApplication != NULL );
return NO_ERROR;
}
HRESULT
ADMIN_MANAGER_CACHE::GetAdminManager(
WCHAR * pszStoreName,
ADMIN_MANAGER ** ppAdminManager
)
/*++
Routine Description:
Returns (and creates if necessary) an ADMIN_MANAGER object for the
given store name
Arguments:
pszStoreName - Store name
ppAdminManager - Filled with pointer to ADMIN_MANAGER if successful
Return Value:
HRESULT
--*/
{
ADMIN_MANAGER_CACHE_KEY cacheKey;
ADMIN_MANAGER * pAdminManager = NULL;
HRESULT hr;
if ( pszStoreName == NULL ||
ppAdminManager == NULL )
{
DBG_ASSERT( FALSE );
return HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER );
}
*ppAdminManager = NULL;
//
// First lookup in the cache
//
hr = cacheKey.SetStore( pszStoreName );
if ( FAILED( hr ) )
{
return hr;
}
TryAgain:
hr = FindCacheEntry( &cacheKey,
(CACHE_ENTRY**) &pAdminManager );
if ( FAILED( hr ) )
{
//
// Anything but ERROR_FILE_NOT_FOUND is a bad thing
//
if ( hr != HRESULT_FROM_WIN32( ERROR_FILE_NOT_FOUND ) )
{
return hr;
}
//
// Create an ADMIN_MANAGER
//
pAdminManager = new ADMIN_MANAGER( this );
if ( pAdminManager == NULL )
{
return HRESULT_FROM_WIN32( ERROR_NOT_ENOUGH_MEMORY );
}
//
// We'll initialize it later. We do this to avoid more than one
// simulatenous call to pAdminManager->Create() because AZRoles crap
// doesn't like it
//
//
// Add it to the cache. If we couldn't because it was already
// there, then try again to retrieve it
//
AddCacheEntry( (CACHE_ENTRY*) pAdminManager );
if ( pAdminManager->QueryCached() == FALSE )
{
pAdminManager->DereferenceCacheEntry();
pAdminManager = NULL;
goto TryAgain;
}
}
//
// Initialize the entry once before use. This mechanism ensures only
// one call is made to initialize for the same store name
//
if ( !pAdminManager->QueryIsInitialized() )
{
pAdminManager->LockCacheEntry();
if ( !pAdminManager->QueryIsInitialized() )
{
hr = pAdminManager->Create( pszStoreName );
}
else
{
hr = NO_ERROR;
}
pAdminManager->UnlockCacheEntry();
if ( FAILED( hr ) )
{
pAdminManager->DereferenceCacheEntry();
pAdminManager = NULL;
return hr;
}
}
DBG_ASSERT( pAdminManager != NULL );
*ppAdminManager = pAdminManager;
return NO_ERROR;
}