|
|
/*++
Copyright (c) 2001 Microsoft Corporation
Module Name:
adminmgr.cxx
Abstract:
Routines implementing the Admin Manager object
Author:
Cliff Van Dyke (cliffv) 11-Apr-2001
--*/
#include "pch.hxx"
//
// Global Data
//
//
// Global list of all admin manager for this process
// Access serialized by AzGlResource
//
GENERIC_OBJECT_HEAD AzGlAdminManagers;
RTL_RESOURCE AzGlResource;
BOOL ResourceInitialized = FALSE;
GUID AzGlZeroGuid;
#if DBG
BOOL CritSectInitialized = FALSE; #endif // DBG
BOOL AzDllInitialize(VOID) /*++
Routine Description
This initializes global events and variables for the DLL.
Arguments
none
Return Value
Boolean: TRUE on success, FALSE on fail.
--*/ { BOOL RetVal = TRUE;
//
// Don't call back on thread start/stop
// ???
RtlZeroMemory( &AzGlZeroGuid, sizeof(AzGlZeroGuid) );
// Initialize the resource
//
__try {
RtlInitializeResource( &AzGlResource );
} __except( EXCEPTION_EXECUTE_HANDLER ) { RetVal = FALSE; KdPrint(("AzRoles.dll: RtlInitializeResource failed: 0x%lx\n", GetExceptionCode() )); }
ResourceInitialized = TRUE;
//
// Initialize the root of the tree of objects
//
AzpLockResourceExclusive( &AzGlResource ); ObInitGenericHead( &AzGlAdminManagers, OBJECT_TYPE_ADMIN_MANAGER, NULL, NULL, NULL ); AzpUnlockResource( &AzGlResource );
//
// Initialize the stack allocator
//
SafeAllocaInitialize( SAFEALLOCA_USE_DEFAULT, SAFEALLOCA_USE_DEFAULT, AzpAllocateHeap, AzpFreeHeap );
#if DBG
//
// Initialize the allocator
//
InitializeListHead ( &AzGlAllocatedBlocks ); __try { InitializeCriticalSection ( &AzGlAllocatorCritSect ); } __except( EXCEPTION_EXECUTE_HANDLER ) { RetVal = FALSE; KdPrint(("AzRoles.dll: InitializCriticalSection (AzGlAllocatorCritSect) failed: 0x%lx\n", GetExceptionCode() )); }
CritSectInitialized = TRUE; #endif // DBG
#ifdef AZROLESDBG
//
// Initialize debugging
//
__try { InitializeCriticalSection ( &AzGlLogFileCritSect ); } __except( EXCEPTION_EXECUTE_HANDLER ) { RetVal = FALSE; KdPrint(("AzRoles.dll: InitializCriticalSection (AzGlLogFileCritSect) failed: 0x%lx\n", GetExceptionCode() )); }
// AzGlDbFlag = AZD_ALL;
AzGlDbFlag = AZD_INVPARM; // | AZD_PERSIST | AZD_PERSIST_MORE;
// AzGlLogFile = INVALID_HANDLE_VALUE;
#endif // AZROLESDBG
return RetVal;
}
BOOL AzDllUnInitialize(VOID) /*++
Routine Description
This uninitializes global events and variables for the DLL.
Arguments
none
Return Value
Boolean: TRUE on success, FALSE on fail.
--*/ { BOOL RetVal = TRUE;
//
// Don't call back on thread start/stop
//
// Handle detaching from a process.
//
//
// Delete the resource
//
if ( ResourceInitialized ) { RtlDeleteResource( &AzGlResource ); ResourceInitialized = FALSE; }
#if DBG
//
// Done with the allocator
//
if ( CritSectInitialized ) { ASSERT( IsListEmpty( &AzGlAllocatedBlocks )); DeleteCriticalSection ( &AzGlAllocatorCritSect ); CritSectInitialized = FALSE; } #endif // DBG
return RetVal;
}
VOID AzpUnload( VOID ) /*++
Routine Description
Force the DLL unload routine to execute
Arguments
NONE
Return Value
NONE
--*/
{
#if DBG // Don't check this in ???
AzDllUnInitialize(); ASSERT( IsListEmpty( &AzGlAllocatedBlocks )); #endif // DBG
}
DWORD AzpAdminManagerInit( IN PGENERIC_OBJECT ParentGenericObject, IN PGENERIC_OBJECT ChildGenericObject ) /*++
Routine Description:
This routine is a worker routine for AzInitialize. It does any object specific initialization that needs to be done.
On entry, AzGlResource must be locked exclusively.
Arguments:
ParentGenericObject - Specifies the parent object to add the child object onto. The reference count has been incremented on this object.
ChildGenericObject - Specifies the newly allocated child object. The reference count has been incremented on this object.
Return Value:
NO_ERROR - The operation was successful ERROR_NOT_ENOUGH_MEMORY - not enough memory Other exception status codes
--*/ { PAZP_ADMIN_MANAGER AdminManager = (PAZP_ADMIN_MANAGER) ChildGenericObject;
//
// Initialization
//
ASSERT( AzpIsLockedExclusive( &AzGlResource ) );
//
// Initialize the lists of child objects
// Let the generic object manager know all of the types of children we support
//
ASSERT( ParentGenericObject == NULL ); UNREFERENCED_PARAMETER( ParentGenericObject );
ChildGenericObject->ChildGenericObjectHead = &AdminManager->Applications;
// List of child applications
ObInitGenericHead( &AdminManager->Applications, OBJECT_TYPE_APPLICATION, ChildGenericObject, &AdminManager->Groups, NULL ); // Doesn't share namespace
// List of child groups
ObInitGenericHead( &AdminManager->Groups, OBJECT_TYPE_GROUP, ChildGenericObject, &AdminManager->AzpSids, NULL ); // Doesn't share namespace (YET)
// List of child AzpSids
ObInitGenericHead( &AdminManager->AzpSids, OBJECT_TYPE_SID, ChildGenericObject, NULL, NULL ); // Doesn't share namespace
return NO_ERROR; }
VOID AzpAdminManagerFree( IN PGENERIC_OBJECT GenericObject ) /*++
Routine Description:
This routine is a worker routine for AdminManager object free. It does any object specific cleanup that needs to be done.
On entry, AzGlResource must be locked exclusively.
Arguments:
GenericObject - Specifies a pointer to the object to be deleted.
Return Value:
None
--*/ { PAZP_ADMIN_MANAGER AdminManager = (PAZP_ADMIN_MANAGER) GenericObject;
//
// Initialization
//
ASSERT( AzpIsLockedExclusive( &AzGlResource ) );
//
// Free any local strings
//
AzpFreeString( &AdminManager->PolicyUrl );
}
DWORD WINAPI AzInitialize( IN DWORD StoreType, IN LPCWSTR PolicyUrl, IN DWORD Flags, IN DWORD Reserved, OUT PAZ_HANDLE AdminManagerHandle ) /*++
Routine Description:
This routine initializes admin manager. This routine must be called before any other routine.
Arguments:
StoreType - Takes one of the AZ_ADMIN_STORE_* defines
PolicyUrl - Specifies the location of the policy store
Flags - Specifies flags that control the behavior of AzInitialize AZ_ADMIN_FLAG_CREATE: Create the policy database
Reserved - Reserved. Must by zero.
AdminManagerHandle - Return a handle to the AdminManager. The caller must close this handle by calling AzCloseHandle.
Return Value:
NO_ERROR - The operation was successful
ERROR_ALREADY_EXISTS - AZ_ADMIN_FLAG_CREATE flag was specified and the policy already exists ERROR_FILE_NOT_FOUND - AZ_ADMIN_FLAG_CREATE flag was not specified and the policy does not already exist
--*/ { DWORD WinStatus;
PGENERIC_OBJECT AdminManager = NULL; AZP_STRING AdminManagerName; AZP_STRING CapturedString;
//
// Grab the global lock
//
AzpLockResourceExclusive( &AzGlResource ); AzpInitString( &AdminManagerName, NULL ); AzpInitString( &CapturedString, NULL );
//
// Initialization
//
__try { *AdminManagerHandle = NULL; } __except( EXCEPTION_EXECUTE_HANDLER ) {
WinStatus = RtlNtStatusToDosError( GetExceptionCode()); goto Cleanup; }
//
// Validate the input parameters
//
if ( Reserved != 0 ) { AzPrint(( AZD_INVPARM, "AzInitialize: Reserved != 0\n" )); WinStatus = ERROR_INVALID_PARAMETER; goto Cleanup; }
switch ( StoreType ) { case AZ_ADMIN_STORE_SAMPLE: break;
case AZ_ADMIN_STORE_UNKNOWN: case AZ_ADMIN_STORE_AD: case AZ_ADMIN_STORE_XML: default: AzPrint(( AZD_INVPARM, "AzInitialize: StoreType invalid %ld\n", StoreType )); WinStatus = ERROR_INVALID_PARAMETER; goto Cleanup; }
if ( Flags & ~AZ_ADMIN_FLAG_VALID ) { AzPrint(( AZD_INVPARM, "AzInitialize: Invalid flags 0x%lx\n", Flags )); WinStatus = ERROR_INVALID_FLAGS; goto Cleanup; }
//
// Capture the Policy URL
//
WinStatus = AzpCaptureString( &CapturedString, (LPWSTR) PolicyUrl, AZ_MAX_POLICY_URL_LENGTH, TRUE ); // NULL is OK
if ( WinStatus != NO_ERROR ) { goto Cleanup; }
//
// Create the object
//
WinStatus = ObCreateObject( NULL, // There is no parent object
&AzGlAdminManagers, OBJECT_TYPE_ADMIN_MANAGER, &AdminManagerName, &AdminManager );
if ( WinStatus != NO_ERROR ) { goto Cleanup; }
//
// Set admin manager specific fields
//
AzpSwapStrings( &CapturedString, &((PAZP_ADMIN_MANAGER)AdminManager)->PolicyUrl ); ((PAZP_ADMIN_MANAGER)AdminManager)->StoreType = StoreType;
//
// Load the objects for the database store
//
WinStatus = AzpPersistOpen( (PAZP_ADMIN_MANAGER)AdminManager, (Flags & AZ_ADMIN_FLAG_CREATE) != 0 );
if ( WinStatus != NO_ERROR ) { goto Cleanup; }
//
// Return the handle to the caller
//
ObIncrHandleRefCount( AdminManager ); *AdminManagerHandle = AdminManager;
WinStatus = NO_ERROR;
//
// Free locally used resources
//
Cleanup: if ( AdminManager != NULL ) { ObDereferenceObject( AdminManager ); }
AzpFreeString( &CapturedString );
//
// Drop the global lock
//
AzpUnlockResource( &AzGlResource );
return WinStatus;
}
DWORD WINAPI AzCloseHandle( IN AZ_HANDLE AzHandle, IN DWORD Reserved ) /*++
Routine Description:
Close a handle returned from any of the Az* routines
Arguments:
AzHandle - Passes in the handle to be closed.
Reserved - Reserved. Must by zero.
Return Value:
NO_ERROR - The operation was successful.
ERROR_INVALID_HANDLE - The passed in handle was invalid
ERROR_SERVER_HAS_OPEN_HANDLES - That passed in handle is an AdminManager handle and the caller open handles to child objects.
--*/ { DWORD WinStatus;
PGENERIC_OBJECT ReferencedGenericObject = NULL; PGENERIC_OBJECT GenericObject = (PGENERIC_OBJECT) AzHandle; DWORD ObjectType;
//
// Grab the global lock
// Only for the admin manager case do we modify anything.
//
AzpLockResourceShared( &AzGlResource );
//
// Validate the input parameters
//
if ( Reserved != 0 ) { AzPrint(( AZD_INVPARM, "AzCloseHandle: Reserved != 0\n" )); WinStatus = ERROR_INVALID_PARAMETER; goto Cleanup; }
//
// Determine the type of the object
//
WinStatus = ObGetHandleType( GenericObject, TRUE, // Ok to close handle for deleted object
&ObjectType );
if ( WinStatus != NO_ERROR ) { goto Cleanup; }
//
// Grab the lock exclusively if we're going to change the database
//
if ( ObjectType == OBJECT_TYPE_ADMIN_MANAGER ) { AzpLockResourceSharedToExclusive( &AzGlResource ); }
//
// Validate the passed in handle
//
WinStatus = ObReferenceObjectByHandle( GenericObject, TRUE, // Allow deleted objects
FALSE, // No need to refresh cache on a close
ObjectType );
if ( WinStatus != NO_ERROR ) { goto Cleanup; }
ReferencedGenericObject = GenericObject;
//
// Handle close of AdminManager handles
//
if ( ObjectType == OBJECT_TYPE_ADMIN_MANAGER ) {
PAZP_ADMIN_MANAGER AdminManager = (PAZP_ADMIN_MANAGER) GenericObject;
//
// Fail if there are any child handles open
// Otherwise we'll have dangling references
//
if ( AdminManager->TotalHandleReferenceCount != 1 ) { WinStatus = ERROR_SERVER_HAS_OPEN_HANDLES; goto Cleanup; }
//
// Close the database store
//
AzpPersistClose( AdminManager );
//
// Remove the entry from the global list of AdminManagers
//
RemoveEntryList( &GenericObject->Next );
// One from ObReferenceObjectByHandle,
// one for being in the global list,
// one because the handle itself isn't closed yet.
ASSERT( GenericObject->ReferenceCount == 3 );
// No longer in the global list
ObDereferenceObject( GenericObject );
}
//
// Actually close the handle
//
ObDecrHandleRefCount( GenericObject );
//
// ??? This is really an overactive assert. Yank it once someone complains.
ASSERT( (GenericObject->Flags & GENOBJ_FLAGS_DIRTY) == 0 );
WinStatus = NO_ERROR;
//
// Free locally used resources
//
Cleanup:
if ( ReferencedGenericObject != NULL ) { ObDereferenceObject( ReferencedGenericObject ); }
//
// Drop the global lock
//
AzpUnlockResource( &AzGlResource );
return WinStatus;
}
VOID WINAPI AzFreeMemory( IN PVOID Buffer ) /*++
Routine Description
Free memory returned from AzXXXGetProperty
Arguments
Buffer - address of buffer to free
Return Value
None
--*/ { if ( Buffer != NULL ) { AzpFreeHeap( Buffer ); } }
|