Leaked source code of windows server 2003
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.
 
 
 
 
 
 

650 lines
17 KiB

/*++
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