mirror of https://github.com/lianthony/NT4.0
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.
355 lines
6.8 KiB
355 lines
6.8 KiB
/*++
|
|
|
|
Copyright (c) 1993 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
sidcache.hxx
|
|
|
|
Abstract:
|
|
|
|
This module contains definitions for the SID_CACHE class,
|
|
which models a simple cache of SID's for ACLCONV.
|
|
|
|
Author:
|
|
|
|
Bill McJohn (billmc) 06-Nov-1993
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
#include "ulib.hxx"
|
|
#include "sidcache.hxx"
|
|
|
|
DEFINE_CONSTRUCTOR( SID_CACHE, OBJECT );
|
|
|
|
SID_CACHE::~SID_CACHE(
|
|
)
|
|
{
|
|
Destroy();
|
|
}
|
|
|
|
VOID
|
|
SID_CACHE::Construct(
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This method is a helper function for object construction.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
{
|
|
_NumberOfEntries = 0;
|
|
_NextSlot = 0;
|
|
_Cache = NULL;
|
|
}
|
|
|
|
VOID
|
|
SID_CACHE::Destroy(
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This method is a helper function for object destruction.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
{
|
|
ULONG i;
|
|
|
|
for( i = 0; i < _NumberOfEntries; i++ ) {
|
|
|
|
if( _Cache[i].Sid ) {
|
|
|
|
FREE( _Cache[i].Sid );
|
|
_Cache[i].Sid = NULL;
|
|
}
|
|
}
|
|
|
|
_NumberOfEntries = 0;
|
|
_NextSlot = 0;
|
|
delete[] _Cache;
|
|
}
|
|
|
|
|
|
BOOLEAN
|
|
SID_CACHE::Initialize(
|
|
IN ULONG NumberOfEntries
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This method initializes the cache--it allocates the array
|
|
of CACHED_SID's and initializes each one.
|
|
|
|
Arguments:
|
|
|
|
NumberOfEntries -- Supplies the size of the cache.
|
|
|
|
Return Value:
|
|
|
|
TRUE upon successful completion.
|
|
|
|
--*/
|
|
{
|
|
ULONG i;
|
|
|
|
Destroy();
|
|
|
|
if( NumberOfEntries == 0 ) {
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
_NumberOfEntries = NumberOfEntries;
|
|
_NextSlot = 0;
|
|
|
|
if( (_Cache = NEW CACHED_SID[NumberOfEntries]) == NULL ) {
|
|
|
|
Destroy();
|
|
return FALSE;
|
|
}
|
|
|
|
for( i = 0; i < NumberOfEntries; i++ ) {
|
|
|
|
_Cache[i].InUse = FALSE;
|
|
_Cache[i].Sid = NULL;
|
|
_Cache[i].SidLength = 0;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOLEAN
|
|
SID_CACHE::IsNamePresent(
|
|
IN PCWSTRING Domain,
|
|
IN PCWSTRING Name,
|
|
OUT PULONG SidLength
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This method determines whether a particular account name
|
|
is in the cache.
|
|
|
|
Arguments:
|
|
|
|
Domain -- Supplies the domain to search. May be NULL, indicating
|
|
that the client will accept a positive match from any
|
|
domain.
|
|
Name -- Supplies the account name.
|
|
SidLength -- Receives the length of the SID for the specified
|
|
name. A value of 0 indicates that the name has
|
|
been previously sought and not found.
|
|
|
|
Return Value:
|
|
|
|
TRUE if a match is found.
|
|
|
|
--*/
|
|
{
|
|
ULONG Index;
|
|
|
|
if( !LocateName( Domain, Name, &Index ) ) {
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
*SidLength = _Cache[Index].SidLength;
|
|
return TRUE;
|
|
}
|
|
|
|
NONVIRTUAL
|
|
BOOLEAN
|
|
SID_CACHE::QueryCachedSid(
|
|
IN PCWSTRING Domain,
|
|
IN PCWSTRING Name,
|
|
OUT PSID Sid,
|
|
IN OUT PULONG SidLength
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This method fetches a SID from the cache.
|
|
|
|
Arguments:
|
|
|
|
Domain -- Supplies the domain to search. May be NULL, indicating
|
|
that the client will accept a positive match from any
|
|
domain.
|
|
Name -- Supplies the account name.
|
|
Sid -- Receives the SID.
|
|
SidLength -- Supplies the length in bytes of the client's
|
|
buffer; receives the length in bytes of the SID.
|
|
A length of zero means that the name has previously
|
|
been searched for and not found.
|
|
--*/
|
|
{
|
|
ULONG Index;
|
|
|
|
if( !LocateName( Domain, Name, &Index ) ) {
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
if( *SidLength < _Cache[Index].SidLength ) {
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
memcpy( Sid, _Cache[Index].Sid, _Cache[Index].SidLength );
|
|
*SidLength = _Cache[Index].SidLength;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOLEAN
|
|
SID_CACHE::CacheSid(
|
|
IN PCWSTRING Domain,
|
|
IN PCWSTRING Name,
|
|
IN PSID Sid,
|
|
IN ULONG SidLength
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This method adds a SID to the cache.
|
|
|
|
Arguments:
|
|
|
|
Domain -- Supplies the domain in which the name was found.
|
|
May be NULL if the SID is also NULL, to indicate
|
|
that the specified account name was not found in
|
|
any trusted domain.
|
|
Name -- Supplies the name associated with this SID.
|
|
Sid -- Supplies the SID. A NULL SID indicates that the
|
|
user does not exist.
|
|
SidLength -- Supplies the length in bytes of the SID.
|
|
|
|
--*/
|
|
{
|
|
|
|
DebugAssert( _NextSlot < _NumberOfEntries );
|
|
|
|
_Cache[_NextSlot].InUse = FALSE;
|
|
|
|
if( _Cache[_NextSlot].Sid ) {
|
|
|
|
FREE( _Cache[_NextSlot].Sid );
|
|
_Cache[_NextSlot].Sid = NULL;
|
|
}
|
|
|
|
if( (!Domain && !_Cache[_NextSlot].Domain.Initialize( "" )) ||
|
|
( Domain && !_Cache[_NextSlot].Domain.Initialize( Domain )) ||
|
|
!_Cache[_NextSlot].Name.Initialize( Name ) ) {
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
if( !(_Cache[_NextSlot].Sid = (PSID)MALLOC( SidLength )) ) {
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
memcpy( _Cache[_NextSlot].Sid, Sid, SidLength );
|
|
|
|
_Cache[_NextSlot].SidLength = SidLength;
|
|
_Cache[_NextSlot].InUse = TRUE;
|
|
|
|
_NextSlot++;
|
|
_NextSlot %= _NumberOfEntries;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
BOOLEAN
|
|
SID_CACHE::LocateName(
|
|
IN PCWSTRING Domain,
|
|
IN PCWSTRING Name,
|
|
OUT PULONG Index
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This method locates a name in the cache.
|
|
|
|
Note that matching rules are different for positive matches
|
|
(cache entries with a non-NULL SID) and negative matches
|
|
(entries with a NULL SID). A negative entry only matches
|
|
if both the domain and account name are identical, whereas
|
|
a positive entry also matches if the names are equal and
|
|
the search domain is the empty string.
|
|
|
|
Arguments:
|
|
|
|
Domain -- Supplies the domain to search. May be NULL, indicating
|
|
that the client will accept a positive match from any
|
|
domain.
|
|
Name -- Supplies the account name to find.
|
|
Index -- Receives the index of the matching cache entry, if
|
|
found.
|
|
|
|
Return Value:
|
|
|
|
TRUE if a match is found.
|
|
|
|
|
|
|
|
--*/
|
|
{
|
|
ULONG i;
|
|
|
|
for( i = 0; i < _NumberOfEntries; i++ ) {
|
|
|
|
if( _Cache[i].InUse && !_Cache[i].Name.Strcmp( Name ) ) {
|
|
|
|
if( (Domain && !_Cache[i].Domain.Strcmp( Domain )) ||
|
|
(!Domain && _Cache[i].Domain.QueryChCount() == 0) ) {
|
|
|
|
// It's an exact match--return it.
|
|
//
|
|
*Index = i;
|
|
return TRUE;
|
|
}
|
|
|
|
// It's not an exact match. If this is a positive
|
|
// entry (i.e. the SID is non-NULL), and the search
|
|
// domain is NULL, then this is an acceptable match.
|
|
//
|
|
if( _Cache[i].Sid && !Domain ) {
|
|
|
|
*Index = i;
|
|
return TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|