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.
 
 
 
 
 
 

414 lines
7.8 KiB

/*++
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 !