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

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. dbftrust.h
  5. Abstract:
  6. Forest trust cache class declaration
  7. --*/
  8. #ifndef __FTCACHE_H
  9. #define __FTCACHE_H
  10. class FTCache
  11. {
  12. friend NTSTATUS
  13. LsarSetForestTrustInformation(
  14. IN LSAPR_HANDLE PolicyHandle,
  15. IN LSA_UNICODE_STRING * TrustedDomainName,
  16. IN LSA_FOREST_TRUST_RECORD_TYPE HighestRecordType,
  17. IN LSA_FOREST_TRUST_INFORMATION * ForestTrustInfo,
  18. IN BOOLEAN CheckOnly,
  19. OUT PLSA_FOREST_TRUST_COLLISION_INFORMATION * CollisionInfo );
  20. friend NTSTATUS
  21. LsapForestTrustCacheInsert(
  22. IN UNICODE_STRING * TrustedDomainName,
  23. IN OPTIONAL PSID TrustedDomainSid,
  24. IN LSA_FOREST_TRUST_INFORMATION * ForestTrustInfo,
  25. IN BOOLEAN LocalForestEntry );
  26. public:
  27. FTCache();
  28. ~FTCache();
  29. NTSTATUS Initialize();
  30. void SetLocalValid() { m_LocalValid = TRUE; }
  31. void SetExternalValid() { m_ExternalValid = TRUE; }
  32. void SetInvalid();
  33. BOOLEAN IsLocalValid() { return m_LocalValid; }
  34. BOOLEAN IsExternalValid() { return m_ExternalValid; }
  35. NTSTATUS
  36. Remove(
  37. IN UNICODE_STRING * TrustedDomainName );
  38. NTSTATUS
  39. Retrieve(
  40. IN UNICODE_STRING * TrustedDomainName,
  41. OUT LSA_FOREST_TRUST_INFORMATION * * ForestTrustInfo );
  42. NTSTATUS
  43. Match(
  44. IN LSA_ROUTING_MATCH_TYPE Type,
  45. IN PVOID Data,
  46. IN BOOLEAN SearchLocal,
  47. OUT OPTIONAL UNICODE_STRING * TrustedDomainName,
  48. OUT OPTIONAL PSID * TrustedDomainSid );
  49. #if !defined(LSAEXTS) // anything in lsaexts.cxx gets full access
  50. private:
  51. #endif
  52. BOOLEAN m_Initialized;
  53. BOOLEAN m_LocalValid;
  54. BOOLEAN m_ExternalValid;
  55. RTL_AVL_TABLE m_TdoTable;
  56. RTL_AVL_TABLE m_TopLevelNameTable;
  57. RTL_AVL_TABLE m_DomainSidTable;
  58. RTL_AVL_TABLE m_DnsNameTable;
  59. RTL_AVL_TABLE m_NetbiosNameTable;
  60. //
  61. // Every TDO the forest trust information for which is stored in the
  62. // cache is going to have an entry like this created for it.
  63. // This way, retrieving and setting information for a particular TDO
  64. // can be performed efficiently.
  65. //
  66. struct TDO_ENTRY {
  67. UNICODE_STRING TrustedDomainName; // name of the corresponding TDO
  68. PSID TrustedDomainSid; // SID of the corresponding TDO
  69. LIST_ENTRY TlnList; // list of top level name entries for this TDO list entry
  70. LIST_ENTRY DomainInfoList; // list of domain info entries for this TDO
  71. LIST_ENTRY BinaryList; // list of unrecognized entries for this TDO list entry
  72. ULONG RecordCount; // combined number of records
  73. BOOLEAN LocalForestEntry; // does this entry correspond to the local forest?
  74. BOOLEAN Excludes( IN const UNICODE_STRING * Name );
  75. #pragma warning(disable:4200)
  76. WCHAR TrustedDomainNameBuffer[];
  77. #pragma warning(default:4200)
  78. };
  79. //
  80. // Top level name key for AVL tree lookups
  81. // Contains a top level name and a list of entries matching this TLN
  82. //
  83. struct TLN_KEY {
  84. UNICODE_STRING TopLevelName; // MUST be the first field
  85. ULONG Count; // Number of entries under this key
  86. LIST_ENTRY List; // List of entries under this key
  87. #pragma warning(disable:4200)
  88. WCHAR TopLevelNameBuffer[];
  89. #pragma warning(default:4200)
  90. };
  91. //
  92. // Top level name entry for AVL tree lookups
  93. //
  94. struct TLN_ENTRY {
  95. //
  96. // This 'friend' relationship is a work-around for an ia64 compiler
  97. // bug that causes FTCache::TDO_ENTRY::Excludes to fail access control
  98. //
  99. friend BOOLEAN
  100. TDO_ENTRY::Excludes( IN const UNICODE_STRING * Name );
  101. LIST_ENTRY TdoListEntry;
  102. LIST_ENTRY AvlListEntry;
  103. LARGE_INTEGER Time;
  104. BOOLEAN Excluded;
  105. ULONG Index;
  106. TDO_ENTRY * TdoEntry;
  107. union {
  108. TLN_ENTRY * SubordinateEntry; // for regular entries
  109. TLN_ENTRY * SuperiorEntry; // for excluded entries
  110. };
  111. TLN_KEY * TlnKey;
  112. BOOLEAN Enabled() {
  113. return Excluded ?
  114. FALSE :
  115. SubordinateEntry ?
  116. SubordinateEntry->Enabled() :
  117. (( m_Flags & LSA_FTRECORD_DISABLED_REASONS ) == 0 );
  118. }
  119. ULONG Flags() {
  120. return Excluded ?
  121. m_Flags :
  122. SubordinateEntry ?
  123. SubordinateEntry->Flags() :
  124. m_Flags;
  125. }
  126. void SetFlags( IN ULONG NewValue ) {
  127. if ( Excluded ) {
  128. m_Flags = NewValue; // value ignored for excluded entries
  129. } else if ( SubordinateEntry ) {
  130. SubordinateEntry->SetFlags( NewValue );
  131. } else {
  132. m_Flags = NewValue;
  133. }
  134. }
  135. static TLN_ENTRY *
  136. EntryFromTdoEntry( IN LIST_ENTRY * ListEntry ) {
  137. return CONTAINING_RECORD(
  138. ListEntry,
  139. TLN_ENTRY,
  140. TdoListEntry
  141. );
  142. }
  143. static TLN_ENTRY *
  144. EntryFromAvlEntry( IN LIST_ENTRY * ListEntry ) {
  145. return CONTAINING_RECORD(
  146. ListEntry,
  147. TLN_ENTRY,
  148. AvlListEntry
  149. );
  150. }
  151. #if !defined(LSAEXTS) // anything in lsaexts.cxx gets full access
  152. private:
  153. #endif
  154. ULONG m_Flags;
  155. };
  156. //
  157. // Domain SID key for AVL tree lookups
  158. // Contains a domain SID and a list of entries matching this domain SID
  159. //
  160. struct DOMAIN_SID_KEY {
  161. SID * DomainSid; // MUST be the first field
  162. ULONG Count; // Number of entries under this key
  163. LIST_ENTRY List; // List of entries under this key
  164. #pragma warning(disable:4200)
  165. ULONG SidBuffer[];
  166. #pragma warning(default:4200)
  167. };
  168. //
  169. // DNS name key for AVL tree lookups
  170. // Contains a domain name and a list of entries matching this DNS name
  171. //
  172. struct DNS_NAME_KEY {
  173. UNICODE_STRING DnsName; // MUST be the first field
  174. ULONG Count; // Number of entries under this key
  175. LIST_ENTRY List; // List of entries under this key
  176. #pragma warning(disable:4200)
  177. WCHAR DnsNameBuffer[];
  178. #pragma warning(default:4200)
  179. };
  180. //
  181. // Netbios name key for AVL tree lookups
  182. // Contains a Netbios name and a list of entries matching this Netbios name
  183. //
  184. struct NETBIOS_NAME_KEY {
  185. UNICODE_STRING NetbiosName; // MUST be the first field
  186. ULONG Count; // Number of entries under this key
  187. LIST_ENTRY List; // List of entries under this key
  188. #pragma warning(disable:4200)
  189. WCHAR NetbiosNameBuffer[];
  190. #pragma warning(default:4200)
  191. };
  192. //
  193. // Domain info entry for AVL tree lookups
  194. //
  195. struct DOMAIN_INFO_ENTRY {
  196. LIST_ENTRY TdoListEntry;
  197. LIST_ENTRY SidAvlListEntry;
  198. LIST_ENTRY DnsAvlListEntry;
  199. LIST_ENTRY NetbiosAvlListEntry;
  200. LARGE_INTEGER Time;
  201. ULONG Index;
  202. SID * Sid;
  203. TDO_ENTRY * TdoEntry;
  204. TLN_ENTRY * SubordinateTo;
  205. DOMAIN_SID_KEY * SidKey;
  206. DNS_NAME_KEY * DnsKey;
  207. NETBIOS_NAME_KEY * NetbiosKey;
  208. #define SID_DISABLED_MASK ( LSA_SID_DISABLED_ADMIN | LSA_SID_DISABLED_CONFLICT )
  209. BOOLEAN SidEnabled() { return (( m_Flags & SID_DISABLED_MASK ) == 0 ); }
  210. #define NETBIOS_DISABLED_MASK ( LSA_NB_DISABLED_ADMIN | LSA_NB_DISABLED_CONFLICT )
  211. BOOLEAN NetbiosEnabled() { return (( m_Flags & ( SID_DISABLED_MASK | NETBIOS_DISABLED_MASK )) == 0 ); }
  212. ULONG Flags() { return m_Flags; }
  213. void SetFlags( IN ULONG NewValue ) {
  214. m_Flags = NewValue;
  215. }
  216. void SetSidConflict() {
  217. SetFlags( Flags() | LSA_SID_DISABLED_CONFLICT );
  218. }
  219. void SetNetbiosConflict() {
  220. SetFlags( Flags() | LSA_NB_DISABLED_CONFLICT );
  221. }
  222. BOOLEAN IsSidAdminDisabled() {
  223. return ( 0 != ( Flags() && LSA_SID_DISABLED_ADMIN ));
  224. }
  225. BOOLEAN IsNbAdminDisabled() {
  226. return ( 0 != ( Flags() && LSA_NB_DISABLED_ADMIN ));
  227. }
  228. static DOMAIN_INFO_ENTRY *
  229. EntryFromTdoEntry( IN LIST_ENTRY * ListEntryTdo ) {
  230. return CONTAINING_RECORD(
  231. ListEntryTdo,
  232. DOMAIN_INFO_ENTRY,
  233. TdoListEntry
  234. );
  235. }
  236. static DOMAIN_INFO_ENTRY *
  237. EntryFromSidEntry( IN LIST_ENTRY * ListEntrySid ) {
  238. return CONTAINING_RECORD(
  239. ListEntrySid,
  240. DOMAIN_INFO_ENTRY,
  241. SidAvlListEntry
  242. );
  243. }
  244. static DOMAIN_INFO_ENTRY *
  245. EntryFromDnsEntry( IN LIST_ENTRY * ListEntryDns ) {
  246. return CONTAINING_RECORD(
  247. ListEntryDns,
  248. DOMAIN_INFO_ENTRY,
  249. DnsAvlListEntry
  250. );
  251. }
  252. static DOMAIN_INFO_ENTRY *
  253. EntryFromNetbiosEntry( IN LIST_ENTRY * ListEntryNB ) {
  254. return CONTAINING_RECORD(
  255. ListEntryNB,
  256. DOMAIN_INFO_ENTRY,
  257. NetbiosAvlListEntry
  258. );
  259. }
  260. #if !defined(LSAEXTS) // anything in lsaexts.cxx gets full access
  261. private:
  262. #endif
  263. ULONG m_Flags;
  264. };
  265. struct BINARY_ENTRY {
  266. LIST_ENTRY TdoListEntry;
  267. LARGE_INTEGER Time;
  268. LSA_FOREST_TRUST_RECORD_TYPE Type;
  269. LSA_FOREST_TRUST_BINARY_DATA Data;
  270. BOOLEAN Enabled() { return (( m_Flags & LSA_FTRECORD_DISABLED_REASONS ) == 0 ); }
  271. ULONG Flags() { return m_Flags; }
  272. void SetFlags( IN ULONG NewValue ) {
  273. m_Flags = NewValue;
  274. }
  275. static BINARY_ENTRY *
  276. EntryFromTdoEntry( IN LIST_ENTRY * ListEntry ) {
  277. return CONTAINING_RECORD(
  278. ListEntry,
  279. BINARY_ENTRY,
  280. TdoListEntry
  281. );
  282. }
  283. #if !defined(LSAEXTS) // anything in lsaexts.cxx gets full access
  284. private:
  285. #endif
  286. ULONG m_Flags;
  287. };
  288. struct CONFLICT_PAIR {
  289. LSA_FOREST_TRUST_RECORD_TYPE EntryType1;
  290. union {
  291. void * Entry1;
  292. TLN_ENTRY * TlnEntry1;
  293. DOMAIN_INFO_ENTRY * DomainInfoEntry1;
  294. };
  295. ULONG Flag1;
  296. LSA_FOREST_TRUST_RECORD_TYPE EntryType2;
  297. union {
  298. void * Entry2;
  299. TLN_ENTRY * TlnEntry2;
  300. DOMAIN_INFO_ENTRY * DomainInfoEntry2;
  301. };
  302. ULONG Flag2;
  303. TDO_ENTRY * TdoEntry1() {
  304. switch ( EntryType1 ) {
  305. case ForestTrustTopLevelName:
  306. case ForestTrustTopLevelNameEx:
  307. ASSERT( TlnEntry1 );
  308. ASSERT( TlnEntry1->TdoEntry );
  309. return TlnEntry1->TdoEntry;
  310. case ForestTrustDomainInfo:
  311. ASSERT( DomainInfoEntry1 );
  312. ASSERT( DomainInfoEntry1->TdoEntry );
  313. return DomainInfoEntry1->TdoEntry;
  314. default:
  315. ASSERT( FALSE ); // who created this entry??? it makes no sense.
  316. return NULL;
  317. }
  318. }
  319. TDO_ENTRY * TdoEntry2() {
  320. switch ( EntryType2 ) {
  321. case ForestTrustTopLevelName:
  322. case ForestTrustTopLevelNameEx:
  323. ASSERT( TlnEntry2 );
  324. ASSERT( TlnEntry2->TdoEntry );
  325. return TlnEntry2->TdoEntry;
  326. case ForestTrustDomainInfo:
  327. ASSERT( DomainInfoEntry2 );
  328. ASSERT( DomainInfoEntry2->TdoEntry );
  329. return DomainInfoEntry2->TdoEntry;
  330. default:
  331. ASSERT( FALSE ); // who created this entry??? it makes no sense.
  332. return NULL;
  333. }
  334. }
  335. void DisableEntry1() {
  336. switch ( EntryType1 ) {
  337. case ForestTrustTopLevelName:
  338. case ForestTrustTopLevelNameEx:
  339. TlnEntry1->SetFlags( TlnEntry1->Flags() | Flag1 );
  340. break;
  341. case ForestTrustDomainInfo:
  342. DomainInfoEntry1->SetFlags( DomainInfoEntry1->Flags() | Flag1 );
  343. break;
  344. default:
  345. ASSERT( FALSE ); // who created this entry??? it makes no sense.
  346. break;
  347. }
  348. }
  349. void DisableEntry2() {
  350. switch ( EntryType2 ) {
  351. case ForestTrustTopLevelName:
  352. case ForestTrustTopLevelNameEx:
  353. TlnEntry2->SetFlags( TlnEntry2->Flags() | Flag2 );
  354. break;
  355. case ForestTrustDomainInfo:
  356. DomainInfoEntry2->SetFlags( DomainInfoEntry2->Flags() | Flag2 );
  357. break;
  358. default:
  359. ASSERT( FALSE ); // who created this entry??? it makes no sense.
  360. break;
  361. }
  362. }
  363. };
  364. BOOLEAN
  365. IsEmpty() { return NULL != RtlEnumerateGenericTableAvl( &m_TdoTable, TRUE ); }
  366. NTSTATUS
  367. Insert(
  368. IN UNICODE_STRING * TrustedDomainName,
  369. IN OPTIONAL PSID TrustedDomainSid,
  370. IN LSA_FOREST_TRUST_INFORMATION * ForestTrustInfo,
  371. IN BOOLEAN LocalForestEntry,
  372. OUT TDO_ENTRY * TdoEntryOld,
  373. OUT TDO_ENTRY * * TdoEntryNew,
  374. OUT CONFLICT_PAIR * * ConflictPairs,
  375. OUT ULONG * ConflictPairsTotal );
  376. static
  377. void
  378. ReconcileConflictPairs(
  379. IN OPTIONAL const TDO_ENTRY * TdoEntry,
  380. IN CONFLICT_PAIR * ConflictPairs,
  381. IN ULONG ConflictPairsTotal );
  382. static
  383. NTSTATUS
  384. GenerateConflictInfo(
  385. IN CONFLICT_PAIR * ConflictPairs,
  386. IN ULONG ConflictPairsTotal,
  387. IN TDO_ENTRY * TdoEntry,
  388. OUT PLSA_FOREST_TRUST_COLLISION_INFORMATION * CollisionInfo );
  389. static
  390. NTSTATUS
  391. MarshalBlob(
  392. IN TDO_ENTRY * TdoEntry,
  393. OUT ULONG * MarshaledSize,
  394. OUT PBYTE * MarshaledBlob );
  395. void Purge();
  396. void
  397. RollbackChanges(
  398. IN TDO_ENTRY * TdoEntryNew,
  399. IN TDO_ENTRY * TdoEntryOld );
  400. void
  401. PurgeTdoEntry( IN TDO_ENTRY * TdoEntry );
  402. void
  403. RemoveTdoEntry( IN TDO_ENTRY * TdoEntry );
  404. static
  405. void
  406. CopyTdoEntry(
  407. IN TDO_ENTRY * Destination,
  408. IN TDO_ENTRY * Source );
  409. LSA_FOREST_TRUST_RECORD * RecordFromTopLevelNameEntry( IN TLN_ENTRY * Entry );
  410. LSA_FOREST_TRUST_RECORD * RecordFromDomainInfoEntry( IN DOMAIN_INFO_ENTRY * Entry );
  411. LSA_FOREST_TRUST_RECORD * RecordFromBinaryEntry( IN BINARY_ENTRY * Entry );
  412. NTSTATUS
  413. MatchSid(
  414. IN SID * Sid,
  415. OUT BOOLEAN * IsLocal,
  416. OUT OPTIONAL UNICODE_STRING * TrustedDomainName,
  417. OUT OPTIONAL PSID * TrustedDomainSid );
  418. NTSTATUS
  419. MatchDnsName(
  420. IN UNICODE_STRING * String,
  421. OUT BOOLEAN * IsLocal,
  422. OUT OPTIONAL UNICODE_STRING * TrustedDomainName,
  423. OUT OPTIONAL PSID * TrustedDomainSid );
  424. NTSTATUS
  425. MatchNetbiosName(
  426. IN UNICODE_STRING * String,
  427. OUT BOOLEAN * IsLocal,
  428. OUT OPTIONAL UNICODE_STRING * TrustedDomainName,
  429. OUT OPTIONAL PSID * TrustedDomainSid );
  430. NTSTATUS
  431. MatchUpn(
  432. IN UNICODE_STRING * String,
  433. OUT BOOLEAN * IsLocal,
  434. OUT OPTIONAL UNICODE_STRING * TrustedDomainName,
  435. OUT OPTIONAL PSID * TrustedDomainSid );
  436. NTSTATUS
  437. MatchSpn(
  438. IN UNICODE_STRING * String,
  439. OUT BOOLEAN * IsLocal,
  440. OUT OPTIONAL UNICODE_STRING * TrustedDomainName,
  441. OUT OPTIONAL PSID * TrustedDomainSid );
  442. NTSTATUS
  443. MatchNamespace(
  444. IN UNICODE_STRING * String,
  445. OUT BOOLEAN * IsLocal,
  446. OUT OPTIONAL UNICODE_STRING * TrustedDomainName,
  447. OUT OPTIONAL PSID * TrustedDomainSid );
  448. TLN_ENTRY *
  449. LongestSubstringMatchTln(
  450. OUT BOOLEAN * IsLocal,
  451. IN UNICODE_STRING * String );
  452. static
  453. NTSTATUS
  454. AddConflictPair(
  455. IN OUT CONFLICT_PAIR * * ConflictPairs,
  456. IN OUT ULONG * ConflictPairTotal,
  457. IN LSA_FOREST_TRUST_RECORD_TYPE Type1,
  458. IN void * Conflict1,
  459. IN ULONG Flag1,
  460. IN LSA_FOREST_TRUST_RECORD_TYPE Type2,
  461. IN void * Conflict2,
  462. IN ULONG Flag2 );
  463. void
  464. AuditChanges(
  465. IN const TDO_ENTRY * OldEntry,
  466. IN const TDO_ENTRY * NewEntry );
  467. void
  468. AuditCollisions(
  469. IN CONFLICT_PAIR * ConflictPairs,
  470. IN ULONG ConflictPairsTotal );
  471. #if DBG
  472. //
  473. // Debug-only statistics
  474. //
  475. static DWORD sm_TdoEntries;
  476. static DWORD sm_TlnEntries;
  477. static DWORD sm_DomainInfoEntries;
  478. static DWORD sm_BinaryEntries;
  479. static DWORD sm_TlnKeys;
  480. static DWORD sm_SidKeys;
  481. static DWORD sm_DnsNameKeys;
  482. static DWORD sm_NetbiosNameKeys;
  483. #endif
  484. };
  485. #endif // __FTCACHE_H