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

  1. /*++
  2. SDCACHE.H
  3. This file defines the interface to the Security
  4. --*/
  5. #ifndef _SDCACHE_H_
  6. #define _SDCACHE_H_
  7. typedef
  8. BOOL
  9. (WINAPI *CACHE_ACCESS_CHECK)( IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
  10. IN HANDLE hClientToken,
  11. IN DWORD dwDesiredAccess,
  12. IN PGENERIC_MAPPING GenericMapping,
  13. IN PRIVILEGE_SET* PrivilegeSet,
  14. IN LPDWORD PrivilegeSetLength,
  15. IN LPDWORD GrantedAccess,
  16. IN LPBOOL AccessStatus
  17. ) ;
  18. //
  19. // Define the key for the hash tables we will be using !
  20. //
  21. class CSDKey {
  22. private :
  23. //
  24. // pointer to the GENERIC_MAPPING portion of the key
  25. //
  26. PGENERIC_MAPPING m_pMapping ;
  27. //
  28. // pointer to the security descriptor portion of the key.
  29. //
  30. PSECURITY_DESCRIPTOR m_pSecDesc ;
  31. //
  32. // No use of default constructor allowed !
  33. //
  34. CSDKey() ;
  35. //
  36. // CSDObject is allowed access to our inner members !
  37. //
  38. friend class CSDObject ;
  39. public :
  40. //
  41. // the length of the security descriptor !
  42. // this is publicly available, but should be read only !
  43. //
  44. int m_cbSecDesc ;
  45. //
  46. // Can only construct a key if these are provided
  47. //
  48. inline
  49. CSDKey( PGENERIC_MAPPING pg,
  50. PSECURITY_DESCRIPTOR pSecDesc
  51. ) :
  52. m_pMapping( pg ),
  53. m_pSecDesc( pSecDesc ),
  54. m_cbSecDesc( GetSecurityDescriptorLength( pSecDesc ) ) {
  55. _ASSERT(IsValid()) ;
  56. }
  57. //
  58. // Check that we're correctly initialized !
  59. //
  60. BOOL
  61. IsValid() ;
  62. //
  63. // compare two keys for equality !
  64. //
  65. static
  66. int
  67. MatchKey( CSDKey left, CSDKey right ) ;
  68. //
  69. // compute the hash function of this key !
  70. //
  71. static
  72. DWORD
  73. HashKey( CSDKey Key ) ;
  74. } ;
  75. class CSDObjectContainer ;
  76. //
  77. // This is a variable length object that is placed within the buckets
  78. // of a hash table. Each object contains a Security Descriptor, and
  79. // the GENERIC_MAPPING relevant to evaluating that Security Descriptor.
  80. //
  81. class CSDObject {
  82. private :
  83. enum CONSTANTS {
  84. SIGNATURE = 'ODSC',
  85. DEAD_SIGNATURE = 'ODSX'
  86. } ;
  87. //
  88. // help us recognize this thing in the debugger.
  89. //
  90. DWORD m_dwSignature ;
  91. //
  92. // The refcount for this item.
  93. //
  94. volatile long m_cRefCount ;
  95. //
  96. // The item we use to chain this into a hash bucket.
  97. //
  98. DLIST_ENTRY m_list ;
  99. //
  100. // Store our Hash Value so that we have easy access to it !
  101. //
  102. DWORD m_dwHash ;
  103. //
  104. // Back pointer to the CSDContainer holding our locks !
  105. //
  106. CSDObjectContainer* m_pContainer ;
  107. //
  108. // The GENERIC_MAPPING structure the client provided and associated
  109. // with the use of this security descriptor.
  110. //
  111. GENERIC_MAPPING m_mapping ;
  112. //
  113. // This is a variable length field containing the
  114. // Security descriptor we're holding.
  115. //
  116. DWORD m_rgdwSD[1] ;
  117. //
  118. // Return the security descriptor we're holding within ourselves.
  119. //
  120. inline
  121. PSECURITY_DESCRIPTOR
  122. SecurityDescriptor() {
  123. return (PSECURITY_DESCRIPTOR)&(m_rgdwSD[0]) ;
  124. }
  125. //
  126. // Return the length of the internally held security descriptor.
  127. //
  128. inline
  129. DWORD
  130. SecurityDescriptorLength() {
  131. return GetSecurityDescriptorLength(SecurityDescriptor()) ;
  132. }
  133. //
  134. // Not available to external clients !
  135. //
  136. CSDObject() ;
  137. public :
  138. typedef DLIST_ENTRY* (*PFNDLIST)( class CSDObject* ) ;
  139. //
  140. // Construct a security descriptor object for the cache !
  141. //
  142. inline
  143. CSDObject( DWORD dwHash,
  144. CSDKey& key,
  145. CSDObjectContainer* p
  146. ) :
  147. m_dwSignature( SIGNATURE ),
  148. m_cRefCount( 2 ),
  149. m_dwHash( dwHash ),
  150. m_pContainer( p ),
  151. m_mapping( *key.m_pMapping ) {
  152. CopyMemory( m_rgdwSD, key.m_pSecDesc, GetSecurityDescriptorLength(key.m_pSecDesc) ) ;
  153. }
  154. //
  155. // Our trivial destructor just makes it easy to recognize
  156. // released objects in the debugger .
  157. //
  158. ~CSDObject( ) {
  159. m_dwSignature = DEAD_SIGNATURE ;
  160. }
  161. //
  162. // Need a special operator new to get our variable size part correct !
  163. //
  164. void*
  165. operator new( size_t size, CSDKey& key ) ;
  166. //
  167. // Handle the release correctly !
  168. //
  169. void
  170. operator delete( void* ) ;
  171. //
  172. // We don't allow just anybody to Add References to us !
  173. //
  174. inline
  175. long
  176. AddRef() {
  177. return InterlockedIncrement((long*)&m_cRefCount) ;
  178. }
  179. //
  180. // Anybody is allowed to remove a reference from us !
  181. //
  182. long
  183. Release() ;
  184. //
  185. // Check that we are a valid object !
  186. //
  187. BOOL
  188. IsValid() ;
  189. //
  190. // Determine whether the client has access or not !
  191. //
  192. BOOL
  193. AccessCheck( HANDLE hToken,
  194. ACCESS_MASK accessMask,
  195. CACHE_ACCESS_CHECK pfnAccessCheck
  196. ) ;
  197. //---------------------------
  198. //
  199. // Hash table support functions -
  200. // the following set of functions support the use of these objects
  201. // in the standard hash tables defined in fdlhash.h
  202. //
  203. //
  204. // Get the offset to the doubly linked list within the object.
  205. //
  206. inline static
  207. DLIST_ENTRY*
  208. HashDLIST( CSDObject* p ) {
  209. return &p->m_list ;
  210. }
  211. //
  212. // Get the hash value out of the object !
  213. //
  214. inline static DWORD
  215. ReHash( CSDObject* p ) {
  216. _ASSERT( p->IsValid() ) ;
  217. return p->m_dwHash ;
  218. }
  219. //
  220. // return our key to the caller !
  221. //
  222. inline CSDKey
  223. GetKey() {
  224. _ASSERT( IsValid() ) ;
  225. return CSDKey( &m_mapping, SecurityDescriptor() ) ;
  226. }
  227. } ;
  228. //
  229. // This defines a hash table containing security descriptors !
  230. //
  231. typedef TFDLHash< class CSDObject,
  232. class CSDKey,
  233. &CSDObject::HashDLIST > SDTABLE ;
  234. //
  235. // This object provides the locking and hash table for a specified set
  236. // of security descriptors !
  237. //
  238. class CSDObjectContainer {
  239. private :
  240. enum CONSTANTS {
  241. SIGNATURE = 'CDSC',
  242. DEAD_SIGNATURE = 'CDSX',
  243. INITIAL_BUCKETS = 32,
  244. INCREMENT_BUCKETS = 16,
  245. LOAD = 8
  246. } ;
  247. //
  248. // The signature of the Security Descriptor Container !
  249. //
  250. DWORD m_dwSignature ;
  251. //
  252. // The lock that protects this hash table !
  253. //
  254. CShareLockNH m_lock ;
  255. //
  256. // A hash table instance !
  257. //
  258. SDTABLE m_table ;
  259. //
  260. // our friends include CSDObject which needs to unlike
  261. // out of our hash table upon destruction.
  262. //
  263. friend class CSDObject ;
  264. public :
  265. //
  266. // construct one of these guys !
  267. //
  268. CSDObjectContainer() :
  269. m_dwSignature( SIGNATURE ) {
  270. }
  271. //
  272. // Our trivial destructor just makes it easy to recognize
  273. // released objects in the debugger .
  274. //
  275. ~CSDObjectContainer() {
  276. m_dwSignature = DEAD_SIGNATURE ;
  277. }
  278. //
  279. // Initialize this particular table
  280. //
  281. inline
  282. BOOL
  283. Init() {
  284. return
  285. m_table.Init( INITIAL_BUCKETS,
  286. INCREMENT_BUCKETS,
  287. LOAD,
  288. CSDKey::HashKey,
  289. CSDObject::GetKey,
  290. CSDKey::MatchKey,
  291. CSDObject::ReHash
  292. ) ;
  293. }
  294. //
  295. // Now - find or create a given security descriptor
  296. // item !
  297. //
  298. CSDObject*
  299. FindOrCreate( DWORD dwHash,
  300. CSDKey& key
  301. ) ;
  302. } ;
  303. typedef CRefPtr2<CSDObject> PTRCSDOBJ ;
  304. typedef CHasRef<CSDObject,FALSE> HCSDOBJ ;
  305. //
  306. // This class provides our external interface for caching security descriptors.
  307. //
  308. class CSDMultiContainer {
  309. private :
  310. enum CONSTANTS {
  311. SIGNATURE = 'ODSC',
  312. DEAD_SIGNATURE = 'ODSX',
  313. CONTAINERS=37 // pick a nice prime number !
  314. } ;
  315. //
  316. // our signature !
  317. //
  318. DWORD m_dwSignature ;
  319. //
  320. // a bunch of child containers !
  321. //
  322. CSDObjectContainer m_rgContainer[CONTAINERS] ;
  323. public :
  324. inline
  325. CSDMultiContainer() :
  326. m_dwSignature( SIGNATURE ) {
  327. }
  328. inline
  329. HCSDOBJ
  330. FindOrCreate( PGENERIC_MAPPING pMapping,
  331. PSECURITY_DESCRIPTOR pSecDesc
  332. ) {
  333. CSDKey key( pMapping, pSecDesc ) ;
  334. DWORD dwHash = CSDKey::HashKey( key ) ;
  335. DWORD i = dwHash % CONTAINERS ;
  336. return m_rgContainer[i].FindOrCreate( dwHash, key ) ;
  337. }
  338. BOOL
  339. Init() ;
  340. } ;
  341. #endif _SDCACHE_H_ // end of the security descriptor cache !