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

obsdata.c

Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (c) 1989 Microsoft Corporation 00004 00005 Module Name: 00006 00007 obsdata.c 00008 00009 Abstract: 00010 00011 Object Manager Security Descriptor Caching 00012 00013 Author: 00014 00015 Robert Reichel (robertre) 12-Oct-1993 00016 00017 Revision History: 00018 00019 --*/ 00020 00021 #include "obp.h" 00022 00023 00024 #if DBG 00025 #define OB_DIAGNOSTICS_ENABLED 1 00026 #endif // DBG 00027 00028 // 00029 // These definitions are useful diagnostics aids 00030 // 00031 00032 #if OB_DIAGNOSTICS_ENABLED 00033 00034 ULONG ObsDebugFlags = 0; 00035 00036 // 00037 // Test for enabled diagnostic 00038 // 00039 00040 #define IF_OB_GLOBAL( FlagName ) if (ObsDebugFlags & (OBS_DEBUG_##FlagName)) 00041 00042 // 00043 // Diagnostics print statement 00044 // 00045 00046 #define ObPrint( FlagName, _Text_ ) IF_OB_GLOBAL( FlagName ) DbgPrint _Text_ 00047 00048 #else 00049 00050 // 00051 // diagnostics not enabled - No diagnostics included in build 00052 // 00053 00054 // 00055 // Test for diagnostics enabled 00056 // 00057 00058 #define IF_OB_GLOBAL( FlagName ) if (FALSE) 00059 00060 // 00061 // Diagnostics print statement (expands to no-op) 00062 // 00063 00064 #define ObPrint( FlagName, _Text_ ) ; 00065 00066 #endif // OB_DIAGNOSTICS_ENABLED 00067 00068 00069 #if OB_DIAGNOSTICS_ENABLED 00070 00071 ULONG ObsTotalCacheEntries = 0; 00072 00073 #endif 00074 00075 // 00076 // The following flags enable or disable various diagnostic 00077 // capabilities within OB code. These flags are set in 00078 // ObGlobalFlag (only available within a DBG system). 00079 // 00080 // 00081 00082 #define OBS_DEBUG_ALLOC_TRACKING ((ULONG) 0x00000001L) 00083 #define OBS_DEBUG_CACHE_FREES ((ULONG) 0x00000002L) 00084 #define OBS_DEBUG_BREAK_ON_INIT ((ULONG) 0x00000004L) 00085 #define OBS_DEBUG_SHOW_COLLISIONS ((ULONG) 0x00000008L) 00086 #define OBS_DEBUG_SHOW_STATISTICS ((ULONG) 0x00000010L) 00087 #define OBS_DEBUG_SHOW_REFERENCES ((ULONG) 0x00000020L) 00088 #define OBS_DEBUG_SHOW_DEASSIGN ((ULONG) 0x00000040L) 00089 #define OBS_DEBUG_STOP_INVALID_DESCRIPTOR ((ULONG) 0x00000080L) 00090 #define OBS_DEBUG_SHOW_HEADER_FREE ((ULONG) 0x00000100L) 00091 00092 // 00093 // Array of pointers to security descriptor entries 00094 // 00095 00096 PLIST_ENTRY *ObsSecurityDescriptorCache = NULL; 00097 00098 00099 // 00100 // Resource used to protect the security descriptor cache 00101 // 00102 00103 ERESOURCE ObsSecurityDescriptorCacheLock; 00104 00105 #if defined (ALLOC_PRAGMA) 00106 #pragma alloc_text(PAGE,ObpDereferenceSecurityDescriptor) 00107 #pragma alloc_text(PAGE,ObpDestroySecurityDescriptorHeader) 00108 #pragma alloc_text(PAGE,ObpHashBuffer) 00109 #pragma alloc_text(PAGE,ObpHashSecurityDescriptor) 00110 #pragma alloc_text(PAGE,ObpInitSecurityDescriptorCache) 00111 #pragma alloc_text(PAGE,ObpLogSecurityDescriptor) 00112 #pragma alloc_text(PAGE,ObpReferenceSecurityDescriptor) 00113 #pragma alloc_text(PAGE,ObpCreateCacheEntry) 00114 #endif 00115 00116 00117 NTSTATUS 00118 ObpInitSecurityDescriptorCache ( 00119 VOID 00120 ) 00121 00122 /*++ 00123 00124 Routine Description: 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 } 00179 00180 00181 ULONG 00182 ObpHashSecurityDescriptor ( 00183 PSECURITY_DESCRIPTOR SecurityDescriptor 00184 ) 00185 00186 /*++ 00187 00188 Routine Description: 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 } 00250 00251 00252 ULONG 00253 ObpHashBuffer ( 00254 PVOID Data, 00255 ULONG Length 00256 ) 00257 00258 /*++ 00259 00260 Routine Description: 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 } 00294 00295 00296 NTSTATUS 00297 ObpLogSecurityDescriptor ( 00298 IN PSECURITY_DESCRIPTOR InputSecurityDescriptor, 00299 OUT PSECURITY_DESCRIPTOR *OutputSecurityDescriptor 00300 ) 00301 00302 /*++ 00303 00304 Routine Description: 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 } 00488 00489 00490 PSECURITY_DESCRIPTOR_HEADER 00491 ObpCreateCacheEntry ( 00492 PSECURITY_DESCRIPTOR InputSecurityDescriptor, 00493 ULONG FullHash 00494 ) 00495 00496 /*++ 00497 00498 Routine Description: 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 } 00556 00557 00558 PSECURITY_DESCRIPTOR 00559 ObpReferenceSecurityDescriptor ( 00560 PVOID Object 00561 ) 00562 00563 /*++ 00564 00565 Routine Description: 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 } 00634 00635 00636 NTSTATUS 00637 ObDeassignSecurity ( 00638 IN OUT PSECURITY_DESCRIPTOR *SecurityDescriptor 00639 ) 00640 00641 /*++ 00642 00643 Routine Description: 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 } 00697 00698 00699 VOID 00700 ObpDereferenceSecurityDescriptor ( 00701 PSECURITY_DESCRIPTOR SecurityDescriptor 00702 ) 00703 00704 /*++ 00705 00706 Routine Description: 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 } 00756 00757 00758 VOID 00759 ObpDestroySecurityDescriptorHeader ( 00760 IN PSECURITY_DESCRIPTOR_HEADER Header 00761 ) 00762 00763 /*++ 00764 00765 Routine Description: 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 } 00836 00837 00838 BOOLEAN 00839 ObpCompareSecurityDescriptors ( 00840 IN PSECURITY_DESCRIPTOR SD1, 00841 IN PSECURITY_DESCRIPTOR SD2 00842 ) 00843 00844 /*++ 00845 00846 Routine Description: 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 } 00883 00884 00885 VOID 00886 ObpAcquireDescriptorCacheWriteLock ( 00887 VOID 00888 ) 00889 00890 /*++ 00891 00892 Routine Description: 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 } 00912 00913 VOID 00914 ObpAcquireDescriptorCacheReadLock ( 00915 VOID 00916 ) 00917 00918 /*++ 00919 00920 Routine Description: 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 } 00940 00941 VOID 00942 ObpReleaseDescriptorCacheLock ( 00943 VOID 00944 ) 00945 00946 /*++ 00947 00948 Routine Description: 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 } 00968

Generated on Sat May 15 19:41:06 2004 for test by doxygen 1.3.7