test: obsdata.c File Reference

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().