|
|
/*++
SDCACHE.H
This file defines the interface to the Security
--*/
#ifndef _SDCACHE_H_
#define _SDCACHE_H_
typedef BOOL (WINAPI *CACHE_ACCESS_CHECK)( IN PSECURITY_DESCRIPTOR pSecurityDescriptor, IN HANDLE hClientToken, IN DWORD dwDesiredAccess, IN PGENERIC_MAPPING GenericMapping, IN PRIVILEGE_SET* PrivilegeSet, IN LPDWORD PrivilegeSetLength, IN LPDWORD GrantedAccess, IN LPBOOL AccessStatus ) ;
//
// Define the key for the hash tables we will be using !
//
class CSDKey { private : //
// pointer to the GENERIC_MAPPING portion of the key
//
PGENERIC_MAPPING m_pMapping ; //
// pointer to the security descriptor portion of the key.
//
PSECURITY_DESCRIPTOR m_pSecDesc ; //
// No use of default constructor allowed !
//
CSDKey() ; //
// CSDObject is allowed access to our inner members !
//
friend class CSDObject ;
public :
//
// the length of the security descriptor !
// this is publicly available, but should be read only !
//
int m_cbSecDesc ;
//
// Can only construct a key if these are provided
//
inline CSDKey( PGENERIC_MAPPING pg, PSECURITY_DESCRIPTOR pSecDesc ) : m_pMapping( pg ), m_pSecDesc( pSecDesc ), m_cbSecDesc( GetSecurityDescriptorLength( pSecDesc ) ) { _ASSERT(IsValid()) ; }
//
// Check that we're correctly initialized !
//
BOOL IsValid() ;
//
// compare two keys for equality !
//
static int MatchKey( CSDKey left, CSDKey right ) ;
//
// compute the hash function of this key !
//
static DWORD HashKey( CSDKey Key ) ; } ;
class CSDObjectContainer ;
//
// This is a variable length object that is placed within the buckets
// of a hash table. Each object contains a Security Descriptor, and
// the GENERIC_MAPPING relevant to evaluating that Security Descriptor.
//
class CSDObject { private :
enum CONSTANTS { SIGNATURE = 'ODSC', DEAD_SIGNATURE = 'ODSX' } ;
//
// help us recognize this thing in the debugger.
//
DWORD m_dwSignature ;
//
// The refcount for this item.
//
volatile long m_cRefCount ;
//
// The item we use to chain this into a hash bucket.
//
DLIST_ENTRY m_list ;
//
// Store our Hash Value so that we have easy access to it !
//
DWORD m_dwHash ;
//
// Back pointer to the CSDContainer holding our locks !
//
CSDObjectContainer* m_pContainer ;
//
// The GENERIC_MAPPING structure the client provided and associated
// with the use of this security descriptor.
//
GENERIC_MAPPING m_mapping ;
//
// This is a variable length field containing the
// Security descriptor we're holding.
//
DWORD m_rgdwSD[1] ;
//
// Return the security descriptor we're holding within ourselves.
//
inline PSECURITY_DESCRIPTOR SecurityDescriptor() { return (PSECURITY_DESCRIPTOR)&(m_rgdwSD[0]) ; }
//
// Return the length of the internally held security descriptor.
//
inline DWORD SecurityDescriptorLength() { return GetSecurityDescriptorLength(SecurityDescriptor()) ; }
//
// Not available to external clients !
//
CSDObject() ;
public :
typedef DLIST_ENTRY* (*PFNDLIST)( class CSDObject* ) ;
//
// Construct a security descriptor object for the cache !
//
inline CSDObject( DWORD dwHash, CSDKey& key, CSDObjectContainer* p ) : m_dwSignature( SIGNATURE ), m_cRefCount( 2 ), m_dwHash( dwHash ), m_pContainer( p ), m_mapping( *key.m_pMapping ) { CopyMemory( m_rgdwSD, key.m_pSecDesc, GetSecurityDescriptorLength(key.m_pSecDesc) ) ; }
//
// Our trivial destructor just makes it easy to recognize
// released objects in the debugger .
//
~CSDObject( ) { m_dwSignature = DEAD_SIGNATURE ; }
//
// Need a special operator new to get our variable size part correct !
//
void* operator new( size_t size, CSDKey& key ) ;
//
// Handle the release correctly !
//
void operator delete( void* ) ;
//
// We don't allow just anybody to Add References to us !
//
inline long AddRef() { return InterlockedIncrement((long*)&m_cRefCount) ; }
//
// Anybody is allowed to remove a reference from us !
//
long Release() ;
//
// Check that we are a valid object !
//
BOOL IsValid() ;
//
// Determine whether the client has access or not !
//
BOOL AccessCheck( HANDLE hToken, ACCESS_MASK accessMask, CACHE_ACCESS_CHECK pfnAccessCheck ) ;
//---------------------------
//
// Hash table support functions -
// the following set of functions support the use of these objects
// in the standard hash tables defined in fdlhash.h
//
//
// Get the offset to the doubly linked list within the object.
//
inline static DLIST_ENTRY* HashDLIST( CSDObject* p ) { return &p->m_list ; }
//
// Get the hash value out of the object !
//
inline static DWORD ReHash( CSDObject* p ) { _ASSERT( p->IsValid() ) ; return p->m_dwHash ; }
//
// return our key to the caller !
//
inline CSDKey GetKey() { _ASSERT( IsValid() ) ; return CSDKey( &m_mapping, SecurityDescriptor() ) ; } } ;
//
// This defines a hash table containing security descriptors !
//
typedef TFDLHash< class CSDObject, class CSDKey, &CSDObject::HashDLIST > SDTABLE ;
//
// This object provides the locking and hash table for a specified set
// of security descriptors !
//
class CSDObjectContainer { private :
enum CONSTANTS { SIGNATURE = 'CDSC', DEAD_SIGNATURE = 'CDSX', INITIAL_BUCKETS = 32, INCREMENT_BUCKETS = 16, LOAD = 8 } ;
//
// The signature of the Security Descriptor Container !
//
DWORD m_dwSignature ;
//
// The lock that protects this hash table !
//
CShareLockNH m_lock ;
//
// A hash table instance !
//
SDTABLE m_table ;
//
// our friends include CSDObject which needs to unlike
// out of our hash table upon destruction.
//
friend class CSDObject ;
public :
//
// construct one of these guys !
//
CSDObjectContainer() : m_dwSignature( SIGNATURE ) { }
//
// Our trivial destructor just makes it easy to recognize
// released objects in the debugger .
//
~CSDObjectContainer() { m_dwSignature = DEAD_SIGNATURE ; }
//
// Initialize this particular table
//
inline BOOL Init() { return m_table.Init( INITIAL_BUCKETS, INCREMENT_BUCKETS, LOAD, CSDKey::HashKey, CSDObject::GetKey, CSDKey::MatchKey, CSDObject::ReHash ) ; }
//
// Now - find or create a given security descriptor
// item !
//
CSDObject* FindOrCreate( DWORD dwHash, CSDKey& key ) ;
} ;
typedef CRefPtr2<CSDObject> PTRCSDOBJ ; typedef CHasRef<CSDObject,FALSE> HCSDOBJ ;
//
// This class provides our external interface for caching security descriptors.
//
class CSDMultiContainer { private :
enum CONSTANTS { SIGNATURE = 'ODSC', DEAD_SIGNATURE = 'ODSX', CONTAINERS=37 // pick a nice prime number !
} ;
//
// our signature !
//
DWORD m_dwSignature ; //
// a bunch of child containers !
//
CSDObjectContainer m_rgContainer[CONTAINERS] ; public :
inline CSDMultiContainer() : m_dwSignature( SIGNATURE ) { }
inline HCSDOBJ FindOrCreate( PGENERIC_MAPPING pMapping, PSECURITY_DESCRIPTOR pSecDesc ) {
CSDKey key( pMapping, pSecDesc ) ; DWORD dwHash = CSDKey::HashKey( key ) ; DWORD i = dwHash % CONTAINERS ;
return m_rgContainer[i].FindOrCreate( dwHash, key ) ; }
BOOL Init() ;
} ;
#endif _SDCACHE_H_ // end of the security descriptor cache !
|