Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

obsdata.c File Reference

#include "obp.h"

Go to the source code of this file.

Defines

#define IF_OB_GLOBAL(FlagName)   if (FALSE)
#define ObPrint(FlagName, _Text_)   ;
#define OBS_DEBUG_ALLOC_TRACKING   ((ULONG) 0x00000001L)
#define OBS_DEBUG_CACHE_FREES   ((ULONG) 0x00000002L)
#define OBS_DEBUG_BREAK_ON_INIT   ((ULONG) 0x00000004L)
#define OBS_DEBUG_SHOW_COLLISIONS   ((ULONG) 0x00000008L)
#define OBS_DEBUG_SHOW_STATISTICS   ((ULONG) 0x00000010L)
#define OBS_DEBUG_SHOW_REFERENCES   ((ULONG) 0x00000020L)
#define OBS_DEBUG_SHOW_DEASSIGN   ((ULONG) 0x00000040L)
#define OBS_DEBUG_STOP_INVALID_DESCRIPTOR   ((ULONG) 0x00000080L)
#define OBS_DEBUG_SHOW_HEADER_FREE   ((ULONG) 0x00000100L)

Functions

NTSTATUS ObpInitSecurityDescriptorCache (VOID)
ULONG ObpHashSecurityDescriptor (PSECURITY_DESCRIPTOR SecurityDescriptor)
ULONG ObpHashBuffer (PVOID Data, ULONG Length)
NTSTATUS ObpLogSecurityDescriptor (IN PSECURITY_DESCRIPTOR InputSecurityDescriptor, OUT PSECURITY_DESCRIPTOR *OutputSecurityDescriptor)
PSECURITY_DESCRIPTOR_HEADER ObpCreateCacheEntry (PSECURITY_DESCRIPTOR InputSecurityDescriptor, ULONG FullHash)
PSECURITY_DESCRIPTOR ObpReferenceSecurityDescriptor (PVOID Object)
NTSTATUS ObDeassignSecurity (IN OUT PSECURITY_DESCRIPTOR *SecurityDescriptor)
VOID ObpDereferenceSecurityDescriptor (PSECURITY_DESCRIPTOR SecurityDescriptor)
VOID ObpDestroySecurityDescriptorHeader (IN PSECURITY_DESCRIPTOR_HEADER Header)
BOOLEAN ObpCompareSecurityDescriptors (IN PSECURITY_DESCRIPTOR SD1, IN PSECURITY_DESCRIPTOR SD2)
VOID ObpAcquireDescriptorCacheWriteLock (VOID)
VOID ObpAcquireDescriptorCacheReadLock (VOID)
VOID ObpReleaseDescriptorCacheLock (VOID)

Variables

PLIST_ENTRY * ObsSecurityDescriptorCache = NULL
ERESOURCE ObsSecurityDescriptorCacheLock


Define Documentation

#define IF_OB_GLOBAL FlagName   )     if (FALSE)
 

Definition at line 58 of file obsdata.c.

Referenced by ObpInitSecurityDescriptorCache(), and ObpReferenceSecurityDescriptor().

#define ObPrint FlagName,
_Text_   )     ;
 

Definition at line 64 of file obsdata.c.

Referenced by ObDeassignSecurity(), ObpDereferenceSecurityDescriptor(), ObpDestroySecurityDescriptorHeader(), ObpLogSecurityDescriptor(), and ObpReferenceSecurityDescriptor().

#define OBS_DEBUG_ALLOC_TRACKING   ((ULONG) 0x00000001L)
 

Definition at line 82 of file obsdata.c.

#define OBS_DEBUG_BREAK_ON_INIT   ((ULONG) 0x00000004L)
 

Definition at line 84 of file obsdata.c.

#define OBS_DEBUG_CACHE_FREES   ((ULONG) 0x00000002L)
 

Definition at line 83 of file obsdata.c.

#define OBS_DEBUG_SHOW_COLLISIONS   ((ULONG) 0x00000008L)
 

Definition at line 85 of file obsdata.c.

#define OBS_DEBUG_SHOW_DEASSIGN   ((ULONG) 0x00000040L)
 

Definition at line 88 of file obsdata.c.

#define OBS_DEBUG_SHOW_HEADER_FREE   ((ULONG) 0x00000100L)
 

Definition at line 90 of file obsdata.c.

#define OBS_DEBUG_SHOW_REFERENCES   ((ULONG) 0x00000020L)
 

Definition at line 87 of file obsdata.c.

#define OBS_DEBUG_SHOW_STATISTICS   ((ULONG) 0x00000010L)
 

Definition at line 86 of file obsdata.c.

#define OBS_DEBUG_STOP_INVALID_DESCRIPTOR   ((ULONG) 0x00000080L)
 

Definition at line 89 of file obsdata.c.


Function Documentation

NTSTATUS ObDeassignSecurity IN OUT PSECURITY_DESCRIPTOR *  SecurityDescriptor  ) 
 

Definition at line 637 of file obsdata.c.

References Header, NULL, ObpAcquireDescriptorCacheWriteLock(), ObpDereferenceSecurityDescriptor(), ObpReleaseDescriptorCacheLock(), ObPrint, and SD_TO_SD_HEADER.

Referenced by SepDefaultDeleteMethod().

00643 : 00644 00645 This routine dereferences the input security descriptor 00646 00647 Arguments: 00648 00649 SecurityDescriptor - Supplies the security descriptor 00650 being modified 00651 00652 Return Value: 00653 00654 Only returns STATUS_SUCCESS 00655 00656 --*/ 00657 00658 { 00659 PSECURITY_DESCRIPTOR_HEADER Header; 00660 00661 // 00662 // Lock the security descriptor cache and get a pointer 00663 // to the security descriptor header 00664 // 00665 00666 ObpAcquireDescriptorCacheWriteLock(); 00667 00668 // 00669 // **** the following diagnostic code should really be done only on 00670 // a checked build 00671 // 00672 00673 Header = SD_TO_SD_HEADER( *SecurityDescriptor ); 00674 ObPrint( SHOW_DEASSIGN,("Deassigning security descriptor %x, hash = %lX\n",*SecurityDescriptor, Header->FullHash)); 00675 00676 // 00677 // Call the actual routine to dereference the security descriptor 00678 // 00679 00680 ObpDereferenceSecurityDescriptor( *SecurityDescriptor ); 00681 00682 // 00683 // NULL out the SecurityDescriptor in the object's 00684 // header so we don't try to free it again. 00685 // 00686 00687 *SecurityDescriptor = NULL; 00688 00689 // 00690 // Unlock the security descriptor cache and return to our caller 00691 // 00692 00693 ObpReleaseDescriptorCacheLock(); 00694 00695 return( STATUS_SUCCESS ); 00696 }

VOID ObpAcquireDescriptorCacheReadLock VOID   ) 
 

Definition at line 914 of file obsdata.c.

References ExAcquireResourceShared, KeEnterCriticalRegion, ObsSecurityDescriptorCacheLock, TRUE, and VOID().

Referenced by NtQueryObject(), and ObQuerySecurityDescriptorInfo().

00920 : 00921 00922 Takes a read lock on the security descriptor cache. 00923 00924 Arguments: 00925 00926 none 00927 00928 Return Value: 00929 00930 None. 00931 00932 --*/ 00933 00934 { 00935 KeEnterCriticalRegion(); 00936 (VOID)ExAcquireResourceShared( &ObsSecurityDescriptorCacheLock,TRUE ); 00937 00938 return; 00939 }

VOID ObpAcquireDescriptorCacheWriteLock VOID   ) 
 

Definition at line 886 of file obsdata.c.

References ExAcquireResourceExclusive, KeEnterCriticalRegion, ObsSecurityDescriptorCacheLock, TRUE, and VOID().

Referenced by ObDeassignSecurity(), ObpDereferenceSecurityDescriptor(), ObpLogSecurityDescriptor(), ObpReferenceSecurityDescriptor(), and ObSetSecurityDescriptorInfo().

00892 : 00893 00894 Takes a write lock on the security descriptor cache. 00895 00896 Arguments: 00897 00898 none 00899 00900 Return Value: 00901 00902 None. 00903 00904 --*/ 00905 00906 { 00907 KeEnterCriticalRegion(); 00908 (VOID)ExAcquireResourceExclusive( &ObsSecurityDescriptorCacheLock, TRUE ); 00909 00910 return; 00911 }

BOOLEAN ObpCompareSecurityDescriptors IN PSECURITY_DESCRIPTOR  SD1,
IN PSECURITY_DESCRIPTOR  SD2
 

Definition at line 839 of file obsdata.c.

References Compare(), FALSE, and RtlLengthSecurityDescriptor().

Referenced by ObpLogSecurityDescriptor().

00846 : 00847 00848 Performs a byte by byte comparison of two self relative security 00849 descriptors to determine if they are identical. 00850 00851 Arguments: 00852 00853 SD1, SD2 - Security descriptors to be compared. 00854 00855 Return Value: 00856 00857 TRUE - They are the same. 00858 00859 FALSE - They are different. 00860 00861 --*/ 00862 00863 { 00864 ULONG Length1; 00865 ULONG Length2; 00866 ULONG Compare; 00867 00868 // 00869 // Calculating the length is pretty fast, see if we 00870 // can get away with doing only that. 00871 // 00872 00873 Length1 = RtlLengthSecurityDescriptor ( SD1 ); 00874 Length2 = RtlLengthSecurityDescriptor ( SD2 ); 00875 00876 if (Length1 != Length2) { 00877 00878 return( FALSE ); 00879 } 00880 00881 return (BOOLEAN)RtlEqualMemory ( SD1, SD2, Length1 ); 00882 }

PSECURITY_DESCRIPTOR_HEADER ObpCreateCacheEntry PSECURITY_DESCRIPTOR  InputSecurityDescriptor,
ULONG  FullHash
 

Definition at line 491 of file obsdata.c.

References ExAllocatePoolWithTag, _SECURITY_DESCRIPTOR_HEADER::FullHash, _SECURITY_DESCRIPTOR_HEADER::Link, NULL, PagedPool, _SECURITY_DESCRIPTOR_HEADER::RefCount, RtlLengthSecurityDescriptor(), and _SECURITY_DESCRIPTOR_HEADER::SecurityDescriptor.

Referenced by ObpLogSecurityDescriptor().

00498 : 00499 00500 Allocates and initializes a new cache entry. 00501 00502 Arguments: 00503 00504 InputSecurityDescriptor - The security descriptor to be cached. 00505 00506 FullHash - Full 32 bit hash of the security descriptor. 00507 00508 Return Value: 00509 00510 A pointer to the newly allocated cache entry, or NULL 00511 00512 --*/ 00513 00514 { 00515 00516 ULONG SecurityDescriptorLength; 00517 ULONG CacheEntrySize; 00518 PSECURITY_DESCRIPTOR_HEADER NewDescriptor; 00519 00520 // 00521 // Compute the size that we'll need to allocate. We need space for 00522 // the security descriptor cache minus the funny quad at the end and the 00523 // security descriptor itself. 00524 // 00525 00526 SecurityDescriptorLength = RtlLengthSecurityDescriptor ( InputSecurityDescriptor ); 00527 CacheEntrySize = SecurityDescriptorLength + (sizeof(SECURITY_DESCRIPTOR_HEADER) - sizeof( QUAD )); 00528 00529 // 00530 // Now allocate space for the cached entry 00531 // 00532 00533 NewDescriptor = ExAllocatePoolWithTag( PagedPool, CacheEntrySize, 'dSeS'); 00534 00535 if ( NewDescriptor == NULL ) { 00536 00537 return( NULL ); 00538 } 00539 00540 // 00541 // Fill the header, copy over the descriptor data, and return to our 00542 // caller 00543 // 00544 00545 NewDescriptor->RefCount = 1; 00546 NewDescriptor->FullHash = FullHash; 00547 NewDescriptor->Link.Flink = NULL; 00548 NewDescriptor->Link.Blink = NULL; 00549 00550 RtlCopyMemory( &NewDescriptor->SecurityDescriptor, 00551 InputSecurityDescriptor, 00552 SecurityDescriptorLength ); 00553 00554 return( NewDescriptor ); 00555 }

VOID ObpDereferenceSecurityDescriptor PSECURITY_DESCRIPTOR  SecurityDescriptor  ) 
 

Definition at line 700 of file obsdata.c.

References ASSERT, _SECURITY_DESCRIPTOR_HEADER::FullHash, ObpAcquireDescriptorCacheWriteLock(), ObpDestroySecurityDescriptorHeader(), ObpReleaseDescriptorCacheLock(), ObPrint, _SECURITY_DESCRIPTOR_HEADER::RefCount, and SD_TO_SD_HEADER.

Referenced by ObDeassignSecurity(), ObReleaseObjectSecurity(), and ObSetSecurityDescriptorInfo().

00706 : 00707 00708 Decrements the refcount of a cached security descriptor 00709 00710 Arguments: 00711 00712 SecurityDescriptor - Points to a cached security descriptor 00713 00714 Return Value: 00715 00716 None. 00717 00718 --*/ 00719 00720 { 00721 PSECURITY_DESCRIPTOR_HEADER SecurityDescriptorHeader; 00722 00723 // 00724 // Lock the security descriptor cache and get a pointer 00725 // to the security descriptor header 00726 // 00727 00728 ObpAcquireDescriptorCacheWriteLock(); 00729 00730 SecurityDescriptorHeader = SD_TO_SD_HEADER( SecurityDescriptor ); 00731 00732 // 00733 // Do some debug work 00734 // 00735 00736 ObPrint( SHOW_REFERENCES, ("Dereferencing SecurityDescriptor %x, hash %lx, refcount = %d \n", SecurityDescriptor, SecurityDescriptorHeader->FullHash,SecurityDescriptorHeader->RefCount)); 00737 00738 ASSERT(SecurityDescriptorHeader->RefCount != 0); 00739 00740 // 00741 // Decrement the ref count and if it is now zero then 00742 // we can completely remove this entry from the cache 00743 // 00744 00745 if (--SecurityDescriptorHeader->RefCount == 0) { 00746 00747 ObpDestroySecurityDescriptorHeader( SecurityDescriptorHeader ); 00748 } 00749 00750 // 00751 // Unlock the security descriptor cache and return to our caller 00752 // 00753 00754 ObpReleaseDescriptorCacheLock(); 00755 }

VOID ObpDestroySecurityDescriptorHeader IN PSECURITY_DESCRIPTOR_HEADER  Header  ) 
 

Definition at line 759 of file obsdata.c.

References ASSERT, ExFreePool(), Header, NULL, ObPrint, and ObsSecurityDescriptorCache.

Referenced by ObpDereferenceSecurityDescriptor().

00765 : 00766 00767 Frees a cached security descriptor and unlinks it from the chain. 00768 00769 Arguments: 00770 00771 Header - Pointer to a security descriptor header (cached security 00772 descriptor) 00773 00774 Return Value: 00775 00776 None. 00777 00778 --*/ 00779 00780 { 00781 PLIST_ENTRY Forward; 00782 PLIST_ENTRY Rear; 00783 UCHAR SmallHash; 00784 00785 ASSERT ( Header->RefCount == 0 ); 00786 00787 #if OB_DIAGNOSTICS_ENABLED 00788 00789 ObsTotalCacheEntries--; 00790 00791 #endif 00792 00793 ObPrint( SHOW_STATISTICS, ("ObsTotalCacheEntries = %d \n",ObsTotalCacheEntries)); 00794 00795 // 00796 // Unlink the cached security descriptor from its linked list and 00797 // from the small hash table if it was at the head of the list 00798 // 00799 // **** this should all be rewritten to use the regular set of 00800 // link list macros 00801 // 00802 00803 SmallHash = (UCHAR)Header->FullHash; 00804 00805 Forward = Header->Link.Flink; 00806 Rear = Header->Link.Blink; 00807 00808 if ( Forward != NULL ) { 00809 00810 Forward->Blink = Rear; 00811 } 00812 00813 if ( Rear != NULL ) { 00814 00815 Rear->Flink = Forward; 00816 00817 } else { 00818 00819 // 00820 // if Rear is NULL, we're deleting the head of the list 00821 // 00822 00823 ObsSecurityDescriptorCache[SmallHash] = Forward; 00824 } 00825 00826 ObPrint( SHOW_HEADER_FREE, ("Freeing memory at %x \n",Header)); 00827 00828 // 00829 // Now return the cached descriptor to pool and return to our caller 00830 // 00831 00832 ExFreePool( Header ); 00833 00834 return; 00835 }

ULONG ObpHashBuffer PVOID  Data,
ULONG  Length
 

Definition at line 253 of file obsdata.c.

References Buffer.

Referenced by ObpHashSecurityDescriptor().

00260 : 00261 00262 Hashes a buffer into a 32 bit value 00263 00264 Arguments: 00265 00266 Data - Buffer containing the data to be hashed. 00267 00268 Length - The length in bytes of the buffer 00269 00270 00271 Return Value: 00272 00273 ULONG - a 32 bit hash value. 00274 00275 --*/ 00276 00277 { 00278 PCHAR Buffer; 00279 ULONG Result = 0; 00280 LONG i; 00281 00282 Buffer = (PCHAR)Data; 00283 00284 for (i = 0; i <= (LONG)((Length-3)-sizeof(ULONG)); i++) { 00285 00286 ULONG Tmp; 00287 00288 Tmp = *((ULONG UNALIGNED *)(Buffer + i)); 00289 Result += Tmp; 00290 } 00291 00292 return( Result ); 00293 }

ULONG ObpHashSecurityDescriptor PSECURITY_DESCRIPTOR  SecurityDescriptor  ) 
 

Definition at line 182 of file obsdata.c.

References Dacl, FALSE, Group, NTSTATUS(), NULL, ObpHashBuffer(), Owner, RtlGetDaclSecurityDescriptor(), RtlGetGroupSecurityDescriptor(), RtlGetOwnerSecurityDescriptor(), RtlGetSaclSecurityDescriptor(), RtlLengthSid(), and Status.

Referenced by ObpLogSecurityDescriptor().

00188 : 00189 00190 Hashes a security descriptor to a 32 bit value 00191 00192 Arguments: 00193 00194 SecurityDescriptor - Provides the security descriptor to be hashed 00195 00196 Return Value: 00197 00198 ULONG - a 32 bit hash value. 00199 00200 --*/ 00201 00202 { 00203 PSID Owner = NULL; 00204 PSID Group = NULL; 00205 00206 PACL Dacl; 00207 PACL Sacl; 00208 00209 ULONG Hash = 0; 00210 BOOLEAN Junk; 00211 NTSTATUS Status; 00212 BOOLEAN DaclPresent = FALSE; 00213 BOOLEAN SaclPresent = FALSE; 00214 PISECURITY_DESCRIPTOR sd; 00215 00216 // 00217 // Cast the actually opaque security descriptor into something 00218 // that we can decipher 00219 // 00220 00221 sd = (PISECURITY_DESCRIPTOR)SecurityDescriptor; 00222 00223 Status = RtlGetOwnerSecurityDescriptor( sd, &Owner, &Junk ); 00224 Status = RtlGetGroupSecurityDescriptor( sd, &Group, &Junk ); 00225 Status = RtlGetDaclSecurityDescriptor( sd, &DaclPresent, &Dacl, &Junk ); 00226 Status = RtlGetSaclSecurityDescriptor( sd, &SaclPresent, &Sacl, &Junk ); 00227 00228 if ( Owner != NULL ) { 00229 00230 Hash = ObpHashBuffer( Owner, RtlLengthSid( Owner )); 00231 } 00232 00233 if ( Group != NULL ) { 00234 00235 Hash += ObpHashBuffer( Group, RtlLengthSid( Group)); 00236 } 00237 00238 if ( DaclPresent && (Dacl != NULL)) { 00239 00240 Hash += ObpHashBuffer( Dacl, Dacl->AclSize); 00241 } 00242 00243 if ( SaclPresent && (Sacl != NULL)) { 00244 00245 Hash += ObpHashBuffer( Sacl, Sacl->AclSize); 00246 } 00247 00248 return( Hash ); 00249 }

NTSTATUS ObpInitSecurityDescriptorCache VOID   ) 
 

Definition at line 118 of file obsdata.c.

References ExAllocatePoolWithTag, ExFreePool(), ExInitializeResource, IF_OB_GLOBAL, NT_SUCCESS, NTSTATUS(), NULL, ObsSecurityDescriptorCache, ObsSecurityDescriptorCacheLock, PagedPool, SECURITY_DESCRIPTOR_CACHE_ENTRIES, Size, and Status.

Referenced by ObInitSystem().

00124 : 00125 00126 Allocates and initializes the globalSecurity Descriptor Cache 00127 00128 Arguments: 00129 00130 None 00131 00132 Return Value: 00133 00134 STATUS_SUCCESS on success, NTSTATUS on failure. 00135 00136 --*/ 00137 00138 { 00139 ULONG Size; 00140 NTSTATUS Status; 00141 00142 IF_OB_GLOBAL( BREAK_ON_INIT ) { 00143 00144 DbgBreakPoint(); 00145 } 00146 00147 // 00148 // Allocate the cache of pointers and zero it out 00149 // 00150 00151 Size = SECURITY_DESCRIPTOR_CACHE_ENTRIES * sizeof(PLIST_ENTRY); 00152 ObsSecurityDescriptorCache = ExAllocatePoolWithTag( PagedPool, Size, 'cCdS' ); 00153 00154 if (ObsSecurityDescriptorCache == NULL ) { 00155 00156 return( STATUS_INSUFFICIENT_RESOURCES ); 00157 } 00158 00159 RtlZeroMemory( ObsSecurityDescriptorCache, Size ); 00160 00161 // 00162 // Initialize the resource used to protect the security cache 00163 // 00164 00165 Status = ExInitializeResource ( &ObsSecurityDescriptorCacheLock ); 00166 00167 if ( !NT_SUCCESS(Status) ) { 00168 00169 ExFreePool( ObsSecurityDescriptorCache ); 00170 return( Status ); 00171 } 00172 00173 // 00174 // And return to our caller 00175 // 00176 00177 return( STATUS_SUCCESS ); 00178 }

NTSTATUS ObpLogSecurityDescriptor IN PSECURITY_DESCRIPTOR  InputSecurityDescriptor,
OUT PSECURITY_DESCRIPTOR *  OutputSecurityDescriptor
 

Definition at line 297 of file obsdata.c.

References ExFreePool(), FALSE, Header, _SECURITY_DESCRIPTOR_HEADER::Link, LINK_TO_SD_HEADER, NULL, ObpAcquireDescriptorCacheWriteLock(), ObpCompareSecurityDescriptors(), ObpCreateCacheEntry(), ObpHashSecurityDescriptor(), ObpReleaseDescriptorCacheLock(), ObPrint, ObsSecurityDescriptorCache, and _SECURITY_DESCRIPTOR_HEADER::SecurityDescriptor.

Referenced by ObAssignObjectSecurityDescriptor(), and ObSetSecurityDescriptorInfo().

00304 : 00305 00306 Takes a passed security descriptor and registers it into the 00307 security descriptor database. 00308 00309 Arguments: 00310 00311 InputSecurityDescriptor - The new security descriptor to be logged into 00312 the database. On a successful return this memory will have been 00313 freed back to pool. 00314 00315 OutputSecurityDescriptor - Output security descriptor to be used by the 00316 caller. 00317 00318 Return Value: 00319 00320 An appropriate status value 00321 00322 --*/ 00323 00324 { 00325 ULONG FullHash; 00326 UCHAR SmallHash; 00327 PSECURITY_DESCRIPTOR_HEADER NewDescriptor; 00328 PLIST_ENTRY Front; 00329 PLIST_ENTRY Back; 00330 PSECURITY_DESCRIPTOR_HEADER Header; 00331 BOOLEAN Match; 00332 00333 FullHash = ObpHashSecurityDescriptor( InputSecurityDescriptor ); 00334 SmallHash = (UCHAR)FullHash; 00335 00336 // 00337 // See if the entry matching SmallHash is in use. 00338 // Lock the table first, unlock if if we don't need it. 00339 // 00340 00341 ObpAcquireDescriptorCacheWriteLock(); 00342 00343 Front = ObsSecurityDescriptorCache[SmallHash]; 00344 Back = NULL; 00345 Match = FALSE; 00346 00347 // 00348 // Zoom down the hash bucket looking for a full hash match 00349 // 00350 00351 while ( Front != NULL ) { 00352 00353 Header = LINK_TO_SD_HEADER( Front ); 00354 00355 // 00356 // **** is this test really right? Is the full hash value really 00357 // ordered like this? 00358 // 00359 00360 if ( Header->FullHash > FullHash ) { 00361 00362 break; 00363 } 00364 00365 if ( Header->FullHash == FullHash ) { 00366 00367 Match = ObpCompareSecurityDescriptors( InputSecurityDescriptor, 00368 &Header->SecurityDescriptor ); 00369 00370 if ( Match ) { 00371 00372 break; 00373 } 00374 00375 ObPrint( SHOW_COLLISIONS,("Got a collision on %d, no match\n",SmallHash)); 00376 } 00377 00378 Back = Front; 00379 Front = Front->Flink; 00380 } 00381 00382 // 00383 // If we have a match then we'll get the caller to use the old 00384 // cached descriptor, but bumping its ref count, freeing what 00385 // the caller supplied and returning the old one to our caller 00386 // 00387 00388 if ( Match ) { 00389 00390 Header->RefCount++; 00391 00392 ObPrint( SHOW_REFERENCES, ("Reference Hash = 0x%lX, New RefCount = %d\n",Header->FullHash,Header->RefCount)); 00393 00394 *OutputSecurityDescriptor = &Header->SecurityDescriptor; 00395 00396 ExFreePool( InputSecurityDescriptor ); 00397 00398 ObpReleaseDescriptorCacheLock(); 00399 00400 return( STATUS_SUCCESS ); 00401 } 00402 00403 // 00404 // Can't use an existing one, create a new entry 00405 // and insert it into the list. 00406 // 00407 00408 NewDescriptor = ObpCreateCacheEntry( InputSecurityDescriptor, 00409 FullHash ); 00410 00411 if ( NewDescriptor == NULL ) { 00412 00413 ObpReleaseDescriptorCacheLock(); 00414 00415 return( STATUS_INSUFFICIENT_RESOURCES ); 00416 } 00417 00418 #if OB_DIAGNOSTICS_ENABLED 00419 00420 ObsTotalCacheEntries++; 00421 00422 #endif 00423 00424 ObPrint( SHOW_STATISTICS, ("ObsTotalCacheEntries = %d \n",ObsTotalCacheEntries)); 00425 ObPrint( SHOW_COLLISIONS, ("Adding new entry for index #%d \n",SmallHash)); 00426 00427 // 00428 // We don't need the old security descriptor any more. 00429 // 00430 00431 ExFreePool( InputSecurityDescriptor ); 00432 00433 // 00434 // The following logic inserts the new security descriptor into the 00435 // small hash list. We need to first decide if the we're adding 00436 // the entry to the beginning of the list (back is null) or if we're 00437 // further in the list. 00438 // 00439 // **** This logic is plain bizzare because (1) the small hash 00440 // should probably just be an array of list heads and not single 00441 // pointer value and (2) the doubly linked list of security descriptors 00442 // is not circular! This should be fixed to use the regular set 00443 // of link list macros 00444 // 00445 00446 if ( Back == NULL ) { 00447 00448 // 00449 // We're inserting at the beginning of the list for this 00450 // minor index 00451 // 00452 00453 NewDescriptor->Link.Flink = ObsSecurityDescriptorCache[SmallHash]; 00454 ObsSecurityDescriptorCache[SmallHash] = &NewDescriptor->Link; 00455 00456 if ( NewDescriptor->Link.Flink != NULL ) { 00457 00458 NewDescriptor->Link.Flink->Blink = &NewDescriptor->Link; 00459 } 00460 00461 } else { 00462 00463 // 00464 // Hook new descriptor entry into list. 00465 // 00466 00467 NewDescriptor->Link.Flink = Front; 00468 00469 NewDescriptor->Link.Blink = Back; 00470 00471 Back->Flink = &NewDescriptor->Link; 00472 00473 if (Front != NULL) { 00474 00475 Front->Blink = &NewDescriptor->Link; 00476 } 00477 } 00478 00479 // 00480 // Set the output security descriptor and return to our caller 00481 // 00482 00483 *OutputSecurityDescriptor = &NewDescriptor->SecurityDescriptor; 00484 ObpReleaseDescriptorCacheLock(); 00485 00486 return( STATUS_SUCCESS ); 00487 }

PSECURITY_DESCRIPTOR ObpReferenceSecurityDescriptor PVOID  Object  ) 
 

Definition at line 559 of file obsdata.c.

References ASSERT, _SECURITY_DESCRIPTOR_HEADER::FullHash, IF_OB_GLOBAL, NULL, OBJECT_TO_OBJECT_HEADER, ObpAcquireDescriptorCacheWriteLock(), ObpCentralizedSecurity, ObpReleaseDescriptorCacheLock(), ObPrint, _SECURITY_DESCRIPTOR_HEADER::RefCount, RtlValidSecurityDescriptor(), SD_TO_SD_HEADER, and _OBJECT_HEADER::Type.

Referenced by ObGetObjectSecurity().

00565 : 00566 00567 References the security descriptor of the passed object. 00568 00569 Arguments: 00570 00571 Object - Object being access validated. 00572 00573 Return Value: 00574 00575 The security descriptor of the object. 00576 00577 --*/ 00578 00579 { 00580 PSECURITY_DESCRIPTOR_HEADER SecurityDescriptorHeader; 00581 POBJECT_HEADER ObjectHeader; 00582 POBJECT_TYPE ObjectType; 00583 PSECURITY_DESCRIPTOR SecurityDescriptor; 00584 00585 // 00586 // Make sure the sure that the object in question is being 00587 // maintained by the system and doesn't have it own security 00588 // management routines. 00589 // 00590 // **** the first two lines should probably be only done on 00591 // a checked build 00592 // 00593 00594 ObjectHeader = OBJECT_TO_OBJECT_HEADER( Object ); 00595 ObjectType = ObjectHeader->Type; 00596 ASSERT( ObpCentralizedSecurity(ObjectType) ); 00597 00598 // 00599 // Lock the security descriptor cache and get the objects 00600 // security descriptor 00601 // 00602 00603 ObpAcquireDescriptorCacheWriteLock(); 00604 00605 SecurityDescriptor = OBJECT_TO_OBJECT_HEADER( Object )->SecurityDescriptor; 00606 00607 IF_OB_GLOBAL( STOP_INVALID_DESCRIPTOR ) { 00608 00609 if((SecurityDescriptor != NULL) && 00610 (!RtlValidSecurityDescriptor ( SecurityDescriptor ))) { 00611 00612 DbgBreakPoint(); 00613 } 00614 } 00615 00616 // 00617 // If the object has a security descriptor then we need to 00618 // get the security descriptor header and increment its 00619 // ref count before releasing the lock and returning to 00620 // our caller 00621 // 00622 00623 if ( SecurityDescriptor != NULL ) { 00624 00625 SecurityDescriptorHeader = SD_TO_SD_HEADER( SecurityDescriptor ); 00626 ObPrint( SHOW_REFERENCES, ("Referencing Hash %lX, Refcount = %d \n",SecurityDescriptorHeader->FullHash,SecurityDescriptorHeader->RefCount)); 00627 SecurityDescriptorHeader->RefCount++; 00628 } 00629 00630 ObpReleaseDescriptorCacheLock(); 00631 00632 return( SecurityDescriptor ); 00633 }

VOID ObpReleaseDescriptorCacheLock VOID   ) 
 

Definition at line 942 of file obsdata.c.

References ExReleaseResource, KeLeaveCriticalRegion, ObsSecurityDescriptorCacheLock, and VOID().

Referenced by NtQueryObject(), ObDeassignSecurity(), ObpDereferenceSecurityDescriptor(), ObpLogSecurityDescriptor(), ObpReferenceSecurityDescriptor(), ObQuerySecurityDescriptorInfo(), and ObSetSecurityDescriptorInfo().

00948 : 00949 00950 Releases a lock on the security descriptor cache. 00951 00952 Arguments: 00953 00954 none 00955 00956 Return Value: 00957 00958 None. 00959 00960 --*/ 00961 00962 { 00963 (VOID)ExReleaseResource( &ObsSecurityDescriptorCacheLock ); 00964 KeLeaveCriticalRegion (); 00965 00966 return; 00967 }


Variable Documentation

PLIST_ENTRY* ObsSecurityDescriptorCache = NULL
 

Definition at line 96 of file obsdata.c.

Referenced by ObpDestroySecurityDescriptorHeader(), ObpInitSecurityDescriptorCache(), and ObpLogSecurityDescriptor().

ERESOURCE ObsSecurityDescriptorCacheLock
 

Definition at line 103 of file obsdata.c.

Referenced by ObpAcquireDescriptorCacheReadLock(), ObpAcquireDescriptorCacheWriteLock(), ObpInitSecurityDescriptorCache(), and ObpReleaseDescriptorCacheLock().


Generated on Sat May 15 19:44:59 2004 for test by doxygen 1.3.7