|
|
/*++
Copyright (c) 2000 Microsoft Corporation
Module Name:
dbftrust.h
Abstract:
Forest trust cache class declaration
--*/
#ifndef __FTCACHE_H
#define __FTCACHE_H
class FTCache { friend NTSTATUS LsarSetForestTrustInformation( IN LSAPR_HANDLE PolicyHandle, IN LSA_UNICODE_STRING * TrustedDomainName, IN LSA_FOREST_TRUST_RECORD_TYPE HighestRecordType, IN LSA_FOREST_TRUST_INFORMATION * ForestTrustInfo, IN BOOLEAN CheckOnly, OUT PLSA_FOREST_TRUST_COLLISION_INFORMATION * CollisionInfo );
friend NTSTATUS LsapForestTrustCacheInsert( IN UNICODE_STRING * TrustedDomainName, IN OPTIONAL PSID TrustedDomainSid, IN LSA_FOREST_TRUST_INFORMATION * ForestTrustInfo, IN BOOLEAN LocalForestEntry );
public:
FTCache(); ~FTCache();
NTSTATUS Initialize();
void SetLocalValid() { m_LocalValid = TRUE; } void SetExternalValid() { m_ExternalValid = TRUE; } void SetInvalid(); BOOLEAN IsLocalValid() { return m_LocalValid; } BOOLEAN IsExternalValid() { return m_ExternalValid; }
NTSTATUS Remove( IN UNICODE_STRING * TrustedDomainName );
NTSTATUS Retrieve( IN UNICODE_STRING * TrustedDomainName, OUT LSA_FOREST_TRUST_INFORMATION * * ForestTrustInfo );
NTSTATUS Match( IN LSA_ROUTING_MATCH_TYPE Type, IN PVOID Data, IN BOOLEAN SearchLocal, OUT OPTIONAL UNICODE_STRING * TrustedDomainName, OUT OPTIONAL PSID * TrustedDomainSid );
#if !defined(LSAEXTS) // anything in lsaexts.cxx gets full access
private: #endif
BOOLEAN m_Initialized; BOOLEAN m_LocalValid; BOOLEAN m_ExternalValid;
RTL_AVL_TABLE m_TdoTable; RTL_AVL_TABLE m_TopLevelNameTable; RTL_AVL_TABLE m_DomainSidTable; RTL_AVL_TABLE m_DnsNameTable; RTL_AVL_TABLE m_NetbiosNameTable;
//
// Every TDO the forest trust information for which is stored in the
// cache is going to have an entry like this created for it.
// This way, retrieving and setting information for a particular TDO
// can be performed efficiently.
//
struct TDO_ENTRY {
UNICODE_STRING TrustedDomainName; // name of the corresponding TDO
PSID TrustedDomainSid; // SID of the corresponding TDO
LIST_ENTRY TlnList; // list of top level name entries for this TDO list entry
LIST_ENTRY DomainInfoList; // list of domain info entries for this TDO
LIST_ENTRY BinaryList; // list of unrecognized entries for this TDO list entry
ULONG RecordCount; // combined number of records
BOOLEAN LocalForestEntry; // does this entry correspond to the local forest?
BOOLEAN Excludes( IN const UNICODE_STRING * Name );
#pragma warning(disable:4200)
WCHAR TrustedDomainNameBuffer[]; #pragma warning(default:4200)
};
//
// Top level name key for AVL tree lookups
// Contains a top level name and a list of entries matching this TLN
//
struct TLN_KEY {
UNICODE_STRING TopLevelName; // MUST be the first field
ULONG Count; // Number of entries under this key
LIST_ENTRY List; // List of entries under this key
#pragma warning(disable:4200)
WCHAR TopLevelNameBuffer[]; #pragma warning(default:4200)
};
//
// Top level name entry for AVL tree lookups
//
struct TLN_ENTRY {
//
// This 'friend' relationship is a work-around for an ia64 compiler
// bug that causes FTCache::TDO_ENTRY::Excludes to fail access control
//
friend BOOLEAN TDO_ENTRY::Excludes( IN const UNICODE_STRING * Name );
LIST_ENTRY TdoListEntry; LIST_ENTRY AvlListEntry; LARGE_INTEGER Time; BOOLEAN Excluded; ULONG Index; TDO_ENTRY * TdoEntry; union { TLN_ENTRY * SubordinateEntry; // for regular entries
TLN_ENTRY * SuperiorEntry; // for excluded entries
}; TLN_KEY * TlnKey;
BOOLEAN Enabled() {
return Excluded ? FALSE : SubordinateEntry ? SubordinateEntry->Enabled() : (( m_Flags & LSA_FTRECORD_DISABLED_REASONS ) == 0 ); }
ULONG Flags() {
return Excluded ? m_Flags : SubordinateEntry ? SubordinateEntry->Flags() : m_Flags; }
void SetFlags( IN ULONG NewValue ) {
if ( Excluded ) {
m_Flags = NewValue; // value ignored for excluded entries
} else if ( SubordinateEntry ) {
SubordinateEntry->SetFlags( NewValue );
} else {
m_Flags = NewValue; } }
static TLN_ENTRY * EntryFromTdoEntry( IN LIST_ENTRY * ListEntry ) {
return CONTAINING_RECORD( ListEntry, TLN_ENTRY, TdoListEntry ); }
static TLN_ENTRY * EntryFromAvlEntry( IN LIST_ENTRY * ListEntry ) {
return CONTAINING_RECORD( ListEntry, TLN_ENTRY, AvlListEntry ); }
#if !defined(LSAEXTS) // anything in lsaexts.cxx gets full access
private: #endif
ULONG m_Flags; };
//
// Domain SID key for AVL tree lookups
// Contains a domain SID and a list of entries matching this domain SID
//
struct DOMAIN_SID_KEY {
SID * DomainSid; // MUST be the first field
ULONG Count; // Number of entries under this key
LIST_ENTRY List; // List of entries under this key
#pragma warning(disable:4200)
ULONG SidBuffer[]; #pragma warning(default:4200)
};
//
// DNS name key for AVL tree lookups
// Contains a domain name and a list of entries matching this DNS name
//
struct DNS_NAME_KEY {
UNICODE_STRING DnsName; // MUST be the first field
ULONG Count; // Number of entries under this key
LIST_ENTRY List; // List of entries under this key
#pragma warning(disable:4200)
WCHAR DnsNameBuffer[]; #pragma warning(default:4200)
};
//
// Netbios name key for AVL tree lookups
// Contains a Netbios name and a list of entries matching this Netbios name
//
struct NETBIOS_NAME_KEY {
UNICODE_STRING NetbiosName; // MUST be the first field
ULONG Count; // Number of entries under this key
LIST_ENTRY List; // List of entries under this key
#pragma warning(disable:4200)
WCHAR NetbiosNameBuffer[]; #pragma warning(default:4200)
};
//
// Domain info entry for AVL tree lookups
//
struct DOMAIN_INFO_ENTRY {
LIST_ENTRY TdoListEntry; LIST_ENTRY SidAvlListEntry; LIST_ENTRY DnsAvlListEntry; LIST_ENTRY NetbiosAvlListEntry; LARGE_INTEGER Time; ULONG Index; SID * Sid; TDO_ENTRY * TdoEntry; TLN_ENTRY * SubordinateTo; DOMAIN_SID_KEY * SidKey; DNS_NAME_KEY * DnsKey; NETBIOS_NAME_KEY * NetbiosKey;
#define SID_DISABLED_MASK ( LSA_SID_DISABLED_ADMIN | LSA_SID_DISABLED_CONFLICT )
BOOLEAN SidEnabled() { return (( m_Flags & SID_DISABLED_MASK ) == 0 ); }
#define NETBIOS_DISABLED_MASK ( LSA_NB_DISABLED_ADMIN | LSA_NB_DISABLED_CONFLICT )
BOOLEAN NetbiosEnabled() { return (( m_Flags & ( SID_DISABLED_MASK | NETBIOS_DISABLED_MASK )) == 0 ); }
ULONG Flags() { return m_Flags; }
void SetFlags( IN ULONG NewValue ) {
m_Flags = NewValue; }
void SetSidConflict() {
SetFlags( Flags() | LSA_SID_DISABLED_CONFLICT ); }
void SetNetbiosConflict() {
SetFlags( Flags() | LSA_NB_DISABLED_CONFLICT ); }
BOOLEAN IsSidAdminDisabled() {
return ( 0 != ( Flags() && LSA_SID_DISABLED_ADMIN )); }
BOOLEAN IsNbAdminDisabled() {
return ( 0 != ( Flags() && LSA_NB_DISABLED_ADMIN )); }
static DOMAIN_INFO_ENTRY * EntryFromTdoEntry( IN LIST_ENTRY * ListEntryTdo ) {
return CONTAINING_RECORD( ListEntryTdo, DOMAIN_INFO_ENTRY, TdoListEntry ); }
static DOMAIN_INFO_ENTRY * EntryFromSidEntry( IN LIST_ENTRY * ListEntrySid ) {
return CONTAINING_RECORD( ListEntrySid, DOMAIN_INFO_ENTRY, SidAvlListEntry ); }
static DOMAIN_INFO_ENTRY * EntryFromDnsEntry( IN LIST_ENTRY * ListEntryDns ) {
return CONTAINING_RECORD( ListEntryDns, DOMAIN_INFO_ENTRY, DnsAvlListEntry ); }
static DOMAIN_INFO_ENTRY * EntryFromNetbiosEntry( IN LIST_ENTRY * ListEntryNB ) {
return CONTAINING_RECORD( ListEntryNB, DOMAIN_INFO_ENTRY, NetbiosAvlListEntry ); }
#if !defined(LSAEXTS) // anything in lsaexts.cxx gets full access
private: #endif
ULONG m_Flags; };
struct BINARY_ENTRY {
LIST_ENTRY TdoListEntry; LARGE_INTEGER Time; LSA_FOREST_TRUST_RECORD_TYPE Type; LSA_FOREST_TRUST_BINARY_DATA Data;
BOOLEAN Enabled() { return (( m_Flags & LSA_FTRECORD_DISABLED_REASONS ) == 0 ); }
ULONG Flags() { return m_Flags; }
void SetFlags( IN ULONG NewValue ) {
m_Flags = NewValue; }
static BINARY_ENTRY * EntryFromTdoEntry( IN LIST_ENTRY * ListEntry ) {
return CONTAINING_RECORD( ListEntry, BINARY_ENTRY, TdoListEntry ); }
#if !defined(LSAEXTS) // anything in lsaexts.cxx gets full access
private: #endif
ULONG m_Flags; };
struct CONFLICT_PAIR {
LSA_FOREST_TRUST_RECORD_TYPE EntryType1;
union { void * Entry1; TLN_ENTRY * TlnEntry1; DOMAIN_INFO_ENTRY * DomainInfoEntry1; };
ULONG Flag1;
LSA_FOREST_TRUST_RECORD_TYPE EntryType2;
union { void * Entry2; TLN_ENTRY * TlnEntry2; DOMAIN_INFO_ENTRY * DomainInfoEntry2; };
ULONG Flag2;
TDO_ENTRY * TdoEntry1() {
switch ( EntryType1 ) {
case ForestTrustTopLevelName: case ForestTrustTopLevelNameEx:
ASSERT( TlnEntry1 ); ASSERT( TlnEntry1->TdoEntry );
return TlnEntry1->TdoEntry;
case ForestTrustDomainInfo:
ASSERT( DomainInfoEntry1 ); ASSERT( DomainInfoEntry1->TdoEntry );
return DomainInfoEntry1->TdoEntry;
default:
ASSERT( FALSE ); // who created this entry??? it makes no sense.
return NULL; } }
TDO_ENTRY * TdoEntry2() {
switch ( EntryType2 ) {
case ForestTrustTopLevelName: case ForestTrustTopLevelNameEx:
ASSERT( TlnEntry2 ); ASSERT( TlnEntry2->TdoEntry );
return TlnEntry2->TdoEntry;
case ForestTrustDomainInfo:
ASSERT( DomainInfoEntry2 ); ASSERT( DomainInfoEntry2->TdoEntry );
return DomainInfoEntry2->TdoEntry;
default:
ASSERT( FALSE ); // who created this entry??? it makes no sense.
return NULL; } }
void DisableEntry1() {
switch ( EntryType1 ) {
case ForestTrustTopLevelName: case ForestTrustTopLevelNameEx:
TlnEntry1->SetFlags( TlnEntry1->Flags() | Flag1 ); break;
case ForestTrustDomainInfo:
DomainInfoEntry1->SetFlags( DomainInfoEntry1->Flags() | Flag1 ); break;
default: ASSERT( FALSE ); // who created this entry??? it makes no sense.
break; } }
void DisableEntry2() {
switch ( EntryType2 ) {
case ForestTrustTopLevelName: case ForestTrustTopLevelNameEx:
TlnEntry2->SetFlags( TlnEntry2->Flags() | Flag2 ); break;
case ForestTrustDomainInfo:
DomainInfoEntry2->SetFlags( DomainInfoEntry2->Flags() | Flag2 ); break;
default: ASSERT( FALSE ); // who created this entry??? it makes no sense.
break; } } };
BOOLEAN IsEmpty() { return NULL != RtlEnumerateGenericTableAvl( &m_TdoTable, TRUE ); }
NTSTATUS Insert( IN UNICODE_STRING * TrustedDomainName, IN OPTIONAL PSID TrustedDomainSid, IN LSA_FOREST_TRUST_INFORMATION * ForestTrustInfo, IN BOOLEAN LocalForestEntry, OUT TDO_ENTRY * TdoEntryOld, OUT TDO_ENTRY * * TdoEntryNew, OUT CONFLICT_PAIR * * ConflictPairs, OUT ULONG * ConflictPairsTotal );
static void ReconcileConflictPairs( IN OPTIONAL const TDO_ENTRY * TdoEntry, IN CONFLICT_PAIR * ConflictPairs, IN ULONG ConflictPairsTotal );
static NTSTATUS GenerateConflictInfo( IN CONFLICT_PAIR * ConflictPairs, IN ULONG ConflictPairsTotal, IN TDO_ENTRY * TdoEntry, OUT PLSA_FOREST_TRUST_COLLISION_INFORMATION * CollisionInfo );
static NTSTATUS MarshalBlob( IN TDO_ENTRY * TdoEntry, OUT ULONG * MarshaledSize, OUT PBYTE * MarshaledBlob );
void Purge();
void RollbackChanges( IN TDO_ENTRY * TdoEntryNew, IN TDO_ENTRY * TdoEntryOld );
void PurgeTdoEntry( IN TDO_ENTRY * TdoEntry );
void RemoveTdoEntry( IN TDO_ENTRY * TdoEntry );
static void CopyTdoEntry( IN TDO_ENTRY * Destination, IN TDO_ENTRY * Source );
LSA_FOREST_TRUST_RECORD * RecordFromTopLevelNameEntry( IN TLN_ENTRY * Entry ); LSA_FOREST_TRUST_RECORD * RecordFromDomainInfoEntry( IN DOMAIN_INFO_ENTRY * Entry ); LSA_FOREST_TRUST_RECORD * RecordFromBinaryEntry( IN BINARY_ENTRY * Entry );
NTSTATUS MatchSid( IN SID * Sid, OUT BOOLEAN * IsLocal, OUT OPTIONAL UNICODE_STRING * TrustedDomainName, OUT OPTIONAL PSID * TrustedDomainSid );
NTSTATUS MatchDnsName( IN UNICODE_STRING * String, OUT BOOLEAN * IsLocal, OUT OPTIONAL UNICODE_STRING * TrustedDomainName, OUT OPTIONAL PSID * TrustedDomainSid );
NTSTATUS MatchNetbiosName( IN UNICODE_STRING * String, OUT BOOLEAN * IsLocal, OUT OPTIONAL UNICODE_STRING * TrustedDomainName, OUT OPTIONAL PSID * TrustedDomainSid );
NTSTATUS MatchUpn( IN UNICODE_STRING * String, OUT BOOLEAN * IsLocal, OUT OPTIONAL UNICODE_STRING * TrustedDomainName, OUT OPTIONAL PSID * TrustedDomainSid );
NTSTATUS MatchSpn( IN UNICODE_STRING * String, OUT BOOLEAN * IsLocal, OUT OPTIONAL UNICODE_STRING * TrustedDomainName, OUT OPTIONAL PSID * TrustedDomainSid );
NTSTATUS MatchNamespace( IN UNICODE_STRING * String, OUT BOOLEAN * IsLocal, OUT OPTIONAL UNICODE_STRING * TrustedDomainName, OUT OPTIONAL PSID * TrustedDomainSid );
TLN_ENTRY * LongestSubstringMatchTln( OUT BOOLEAN * IsLocal, IN UNICODE_STRING * String );
static NTSTATUS AddConflictPair( IN OUT CONFLICT_PAIR * * ConflictPairs, IN OUT ULONG * ConflictPairTotal, IN LSA_FOREST_TRUST_RECORD_TYPE Type1, IN void * Conflict1, IN ULONG Flag1, IN LSA_FOREST_TRUST_RECORD_TYPE Type2, IN void * Conflict2, IN ULONG Flag2 );
void AuditChanges( IN const TDO_ENTRY * OldEntry, IN const TDO_ENTRY * NewEntry );
void AuditCollisions( IN CONFLICT_PAIR * ConflictPairs, IN ULONG ConflictPairsTotal );
#if DBG
//
// Debug-only statistics
//
static DWORD sm_TdoEntries; static DWORD sm_TlnEntries; static DWORD sm_DomainInfoEntries; static DWORD sm_BinaryEntries; static DWORD sm_TlnKeys; static DWORD sm_SidKeys; static DWORD sm_DnsNameKeys; static DWORD sm_NetbiosNameKeys;
#endif
};
#endif // __FTCACHE_H
|