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.

398 lines
18 KiB

  1. //#pragma title ("SidCache.hpp -- Cache, Tree of SIDs")
  2. /*
  3. Copyright (c) 1995-1998, Mission Critical Software, Inc. All rights reserved.
  4. ===============================================================================
  5. Module - sidcache.hpp
  6. System - SDResolve
  7. Author - Christy Boles
  8. Created - 97/06/27
  9. Description - Cache of SIDs. Implemented using TNode derived classes, Cache is
  10. organized as a tree, sorted by Domain B RID. Each node contains
  11. Domain A RID, Domain B RID, Account Name, and counters for stats.
  12. Updates -
  13. ===============================================================================
  14. */
  15. #ifndef TSIDCACHE_HEADER
  16. #define TSIDCACHE_HEADER
  17. #ifndef TNODEINCLUDED
  18. #include "Tnode.hpp"
  19. #define TNODEINCLUDED
  20. #endif
  21. //#import "\bin\McsVarSetMin.tlb" no_namespace
  22. //#import "VarSet.tlb" no_namespace rename("property", "aproperty")//#imported below via sdstat.hpp
  23. #include "DCTStat.h"
  24. #include "WorkObj.h"
  25. #include "sdstat.hpp"
  26. #include <map>
  27. #include <string>
  28. #ifndef IStatusObjPtr
  29. _COM_SMARTPTR_TYPEDEF(IStatusObj, __uuidof(IStatusObj));
  30. #endif
  31. //#define ACCOUNT_NAME_LENGTH 256
  32. #define NUM_IN_BUF 5000 /* the number of accounts to get at one time NetQueryDisplayInfo()*/
  33. #define BUFSIZE 100000 /* preferred max size of buffer for receiving accounts NetQueryDisplayInfo()*/
  34. #define DEFAULT_SID_SIZE 500
  35. #define EALB_OCX_LOCAL_USER 13
  36. #define EALB_OCX_GLOBAL_USER 14
  37. #define EALB_OCX_LOCAL_GROUP 16
  38. #define EALB_OCX_GLOBAL_GROUP 17
  39. #define FST_CACHE_SOME_SOURCE 1
  40. #define FST_CACHE_NO_TARGET 2
  41. #define FST_CACHE_SOME_TARGET 4
  42. #define FST_CACHE_NO_DOMAIN 8
  43. class TAcctNode:public TNode
  44. {
  45. protected:
  46. DWORD owner_changes; // Stats for each node
  47. DWORD group_changes;
  48. DWORD ace_changes;
  49. DWORD sace_changes;
  50. public:
  51. TAcctNode();
  52. virtual WCHAR * GetAcctName() = 0;
  53. virtual bool IsValidOnTgt() const = 0;
  54. virtual void AddOwnerChange(objectType type) { owner_changes++; } // Stats functions
  55. virtual void AddGroupChange(objectType type) { group_changes++; }
  56. virtual void AddAceChange(objectType type) { ace_changes++; }
  57. virtual void AddSaceChange(objectType type) { sace_changes++; }
  58. virtual void DisplayStats() const;
  59. DWORD OwnerChanges() { return owner_changes; }
  60. DWORD GroupChanges() { return group_changes; }
  61. DWORD DACEChanges() { return ace_changes; }
  62. DWORD SACEChanges() { return sace_changes; }
  63. BOOL ReportToVarSet(IVarSet * pVarSet, DWORD n);
  64. };
  65. class TRidNode:public TAcctNode
  66. {
  67. public:
  68. typedef enum _STATUS { DEFAULT = 0, TARGETSIDISINVALID = 1 } STATUS;
  69. protected:
  70. DWORD srcRid; // RID for domain A
  71. DWORD tgtRid; // RID for domain B
  72. DWORD status;
  73. short acct_type;
  74. int acct_len; // length of account name
  75. std::wstring srcDomSid; // source domain sid
  76. std::wstring tgtDomSid; // target domain sid
  77. std::wstring srcDomName; // source domain name
  78. std::wstring tgtDomName; // target domain name
  79. WCHAR acct_name[1]; // source account name \0 target account name
  80. public:
  81. void * operator new(size_t sz,const LPWSTR name1,const LPWSTR name2);
  82. TRidNode(const LPWSTR oldacctname, const LPWSTR newacctname);
  83. ~TRidNode();
  84. WCHAR * GetAcctName() { return acct_name; } // member "Get" functions
  85. WCHAR * GetTargetAcctName() { return acct_name + acct_len + 1; }
  86. DWORD SrcRid() const { return srcRid; }
  87. DWORD TgtRid() const { return tgtRid; }
  88. DWORD GetStatus() { return status; }
  89. void SetStatus(DWORD newStatus) { status = newStatus; }
  90. bool IsValidOnTgt() const { return tgtRid != 0 && !(status & TARGETSIDISINVALID); }
  91. short Type() { return acct_type; }
  92. void Type(short newtype) { acct_type = newtype; }
  93. void SrcRid(DWORD const val) { srcRid=val; } // member "Set" functions
  94. void TgtRid(DWORD const val) { tgtRid=val; }
  95. void DisplayStats() const;
  96. void DisplaySidInfo() const;
  97. PCWSTR GetSrcDomSid() { return srcDomSid.c_str(); } // member "Get" function
  98. PCWSTR GetTgtDomSid() { return tgtDomSid.c_str(); } // member "Get" function
  99. void SrcDomSid(PCWSTR sSid) { if (sSid) srcDomSid = sSid; else srcDomSid.erase(); } // member "Set" function
  100. void TgtDomSid(PCWSTR sSid) { if (sSid) tgtDomSid = sSid; else tgtDomSid.erase(); } // member "Set" function
  101. PCWSTR GetSrcDomName() { return srcDomName.c_str(); } // member "Get" function
  102. PCWSTR GetTgtDomName() { return tgtDomName.c_str(); } // member "Get" function
  103. void SrcDomName(PCWSTR sName) { if (sName) srcDomName = sName; else srcDomName.erase(); } // member "Set" function
  104. void TgtDomName(PCWSTR sName) { if (sName) tgtDomName = sName; else tgtDomName.erase(); } // member "Set" function
  105. protected:
  106. };
  107. class TGeneralSidNode:public TAcctNode
  108. {
  109. protected:
  110. LPWSTR src_acct_name;
  111. LPWSTR tgt_acct_name;
  112. PSID src_sid;
  113. PSID tgt_sid;
  114. UCHAR src_nsubs;
  115. UCHAR tgt_nsubs;
  116. WCHAR * src_domain;
  117. WCHAR * tgt_domain;
  118. DWORD sizediff;
  119. TSDFileDirCell ownerStats;
  120. TSDFileDirCell groupStats;
  121. TSDFileDirCell daclStats;
  122. TSDFileDirCell saclStats;
  123. public:
  124. TGeneralSidNode(const LPWSTR name1, const LPWSTR name2);
  125. TGeneralSidNode(const PSID pSid1, const PSID pSid2);
  126. ~TGeneralSidNode();
  127. LPWSTR GetAcctName() { return src_acct_name; }
  128. PSID SrcSid() { return src_sid; }
  129. PSID TgtSid() { return src_sid; /* this is a hack to allow for counting all references to accounts */ }
  130. bool IsValidOnTgt() const { return TRUE;/*tgt_sid != NULL;*/ }
  131. void DisplaySidInfo() const;
  132. DWORD SizeDiff() const { return 0; }
  133. TSDFileDirCell * GetOwnerStats() { return &ownerStats; }
  134. TSDFileDirCell * GetGroupStats() { return &groupStats; }
  135. TSDFileDirCell * GetDaclStats() { return &daclStats; }
  136. TSDFileDirCell * GetSaclStats() { return &saclStats; }
  137. virtual void AddOwnerChange(objectType type)
  138. {
  139. switch (type)
  140. {
  141. case file: ownerStats.file++; break;
  142. case directory: ownerStats.dir++; break;
  143. case mailbox: ownerStats.mailbox++; break;
  144. case container: ownerStats.container++; break;
  145. case share: ownerStats.share++; break;
  146. case groupmember: ownerStats.member++; break;
  147. case userright: ownerStats.userright++; break;
  148. case regkey: ownerStats.regkey++; break;
  149. case printer: ownerStats.printer++; break;
  150. default:
  151. break;
  152. };
  153. }
  154. virtual void AddGroupChange(objectType type)
  155. {
  156. switch (type)
  157. {
  158. case file: groupStats.file++; break;
  159. case directory: groupStats.dir++; break;
  160. case mailbox: groupStats.mailbox++; break;
  161. case container: groupStats.container++; break;
  162. case share: groupStats.share++; break;
  163. case groupmember: groupStats.member++; break;
  164. case userright: groupStats.userright++; break;
  165. case regkey: groupStats.regkey++; break;
  166. case printer: groupStats.printer++; break;
  167. default:
  168. break;
  169. };
  170. }
  171. virtual void AddAceChange(objectType type)
  172. {
  173. switch (type)
  174. {
  175. case file: daclStats.file++; break;
  176. case directory: daclStats.dir++; break;
  177. case mailbox: daclStats.mailbox++; break;
  178. case container: daclStats.container++; break;
  179. case share: daclStats.share++; break;
  180. case groupmember: daclStats.member++; break;
  181. case userright: daclStats.userright++; break;
  182. case regkey: daclStats.regkey++; break;
  183. case printer: daclStats.printer++; break;
  184. default:
  185. break;
  186. };
  187. }
  188. virtual void AddSaceChange(objectType type)
  189. {
  190. switch (type)
  191. {
  192. case file: saclStats.file++; break;
  193. case directory: saclStats.dir++; break;
  194. case mailbox: saclStats.mailbox++; break;
  195. case container: saclStats.container++; break;
  196. case share: saclStats.share++; break;
  197. case groupmember: saclStats.member++; break;
  198. case userright: saclStats.userright++; break;
  199. case regkey: saclStats.regkey++; break;
  200. case printer: saclStats.printer++; break;
  201. default:
  202. break;
  203. };
  204. }
  205. };
  206. /**************************************************************************************************/
  207. /* TSidCache: Cache for SIDs.
  208. The cache is filled by calling FillCache(name_of_domain_A, name_of_domain_B)
  209. Lookup, and GetName search the tree for a domain B SID value.
  210. Lookup returns a pointer to the node, while GetName returns the account
  211. name for the node.
  212. GetSidB( tsidnode *) builds and returns the domain B SID for the node (the node contains only the RID)
  213. SizeDiff() returns the answer to "How much bigger are domain B sids than domain A sids?"
  214. this information is needed when allocating space for ACES.
  215. /**************************************************************************************************/
  216. class TAccountCache: public TNodeListSortable
  217. {
  218. IStatusObjPtr m_pStatus;
  219. public:
  220. TAccountCache() { m_cancelled = false; m_bAddIfNotFound = FALSE; }
  221. ~TAccountCache() {}
  222. virtual TAcctNode * Lookup(const PSID psid) = 0; // sid lookup functions
  223. virtual LPWSTR GetName(const PSID psid) = 0;
  224. //virtual BOOL Insert(const LPWSTR acctname,DWORD srcSid, DWORD tgtSid) = 0;
  225. virtual PSID GetTgtSid(const TAcctNode* tnode) = 0;
  226. virtual DWORD SizeDiff(const TAcctNode *tnode) const = 0; // returns max( 0 , (length(to_sid) - length(from_sid)) )
  227. bool IsCancelled()
  228. {
  229. if ( m_pStatus )
  230. {
  231. LONG status = 0;
  232. // HRESULT hr = m_pStatus->get_Status(&status);
  233. m_pStatus->get_Status(&status);
  234. return (status == DCT_STATUS_ABORTING);
  235. }
  236. else
  237. {
  238. return m_cancelled;
  239. }
  240. }
  241. void Cancel() { m_cancelled = true; if ( m_pStatus ) m_pStatus->put_Status(DCT_STATUS_ABORTING); }
  242. void UnCancel() { m_cancelled = false; }
  243. void AddIfNotFound(BOOL val) { m_bAddIfNotFound = val; }
  244. BOOL AddIfNotFound() { return m_bAddIfNotFound; }
  245. void SetStatusObject(IStatusObj * pS) { m_pStatus = pS; }
  246. protected:
  247. bool m_cancelled;
  248. BOOL m_bAddIfNotFound;
  249. };
  250. class TGeneralCache;
  251. class TSDRidCache: public TAccountCache
  252. {
  253. protected:
  254. WCHAR from_domain[MAX_PATH + 1]; // domain names
  255. WCHAR to_domain[MAX_PATH + 1];
  256. WCHAR from_dc[MAX_PATH + 1]; // domain controller (machine) names
  257. WCHAR to_dc[MAX_PATH + 1];
  258. PSID from_sid; // domain sids (dynamically allocated)
  259. PSID to_sid;
  260. UCHAR from_nsubs; // # subauthorities in domain sids
  261. UCHAR to_nsubs;
  262. DWORD accts; // statistical stuff
  263. DWORD accts_resolved;
  264. TGeneralCache * m_otherAccounts;
  265. typedef std::multimap<DWORD, TRidNode*> CRidToNodeMap;
  266. CRidToNodeMap m_mapRidToNode;
  267. public:
  268. TSDRidCache();
  269. ~TSDRidCache();
  270. // filling methods
  271. WCHAR const * GetSourceDomainName() { return from_domain; }
  272. WCHAR const * GetTargetDomainName() { return to_domain; }
  273. WCHAR const * GetSourceDCName() { return from_dc; }
  274. WCHAR const * GetTargetDCName() { return to_dc; }
  275. void InsertLast(const LPWSTR acctname,DWORD rida, const LPWSTR newname, DWORD ridb, short type = 0, DWORD status = TRidNode::DEFAULT)
  276. { TRidNode * tn = new (acctname,newname) TRidNode(acctname,newname); if (tn){ tn->SetStatus(status); tn->SrcRid(rida); tn->TgtRid(ridb);
  277. tn->Type(type); if ( ridb != 0 ) accts_resolved++; accts++; TNodeListSortable::InsertBottom((TNode *)tn); }}
  278. void InsertLastWithSid(const LPWSTR acctname, LPCWSTR srcdomainsid, LPCWSTR srcdomainname, DWORD rida, const LPWSTR newname,
  279. LPCWSTR tgtdomainsid, LPCWSTR tgtdomainname, DWORD ridb, short type = 0, DWORD status = TRidNode::DEFAULT)
  280. { TRidNode * tn = new (acctname,newname) TRidNode(acctname,newname); if (tn){ tn->SetStatus(status); tn->SrcRid(rida); tn->TgtRid(ridb);
  281. tn->SrcDomSid(srcdomainsid); tn->TgtDomSid(tgtdomainsid); tn->SrcDomName(srcdomainname); tn->TgtDomName(tgtdomainname);
  282. tn->Type(type); if ( ridb != 0 ) accts_resolved++; accts++; TNodeListSortable::InsertBottom((TNode *)tn); }}
  283. TAcctNode * Lookup(const PSID psid); // sid lookup functions
  284. TAcctNode * LookupWODomain(const PSID psid); // sid lookup functions
  285. LPWSTR GetName(const PSID psid);
  286. // helper methods
  287. PSID GetTgtSid(TAcctNode const * tnode) ; // "Get" functions
  288. DWORD SizeDiff(const TAcctNode *tnode) const ; // returns max( 0 , (length(to_sid) - length(from_sid)) )
  289. void Display(bool summary, bool detail);
  290. void ReportToVarSet(IVarSet * pVarSet,bool summary, bool detail);
  291. PSID GetTgtSid(const PSID psid) { return GetTgtSid(Lookup(psid)); }
  292. void CopyDomainInfo( TSDRidCache const * other);
  293. PSID GetTgtSidWODomain(TAcctNode const * tnode); // "Get" functions
  294. PSID GetTgtSidWODomain(const PSID psid); // "Get" functions
  295. DWORD GetNumAccts() const {return accts; }
  296. DWORD GetNumResolvedAccts() const { return accts_resolved; }
  297. void Clear();
  298. void SetSourceAndTargetDomains(WCHAR const * src, WCHAR const * tgt) { SetDomainInfo(src,true); SetDomainInfo(tgt,false); }
  299. void SetSourceAndTargetDomainsWithSids(WCHAR const * src, WCHAR const * srcSid, WCHAR const * tgt,WCHAR const * tgtSid)
  300. { SetDomainInfoWithSid(src,srcSid,true); SetDomainInfoWithSid(tgt,tgtSid,false); }
  301. void ReportAccountReferences(WCHAR const * filename);
  302. BOOL IsInitialized() { return from_sid!=NULL && to_sid!=NULL; }
  303. void VerifyTargetSids();
  304. protected:
  305. int SetDomainInfo(WCHAR const * domname, bool firstdom);
  306. int SetDomainInfoWithSid(WCHAR const * domainName, WCHAR const * domainSid, bool firstdom);
  307. };
  308. class TGeneralCache : public TAccountCache
  309. {
  310. protected:
  311. DWORD accts; // statistical stuff
  312. DWORD accts_resolved;
  313. public:
  314. TGeneralCache();
  315. ~TGeneralCache();
  316. TAcctNode * Lookup(const PSID psid) ; // sid lookup functions
  317. LPWSTR GetName(const PSID psid) ;
  318. BOOL Insert(const LPWSTR acctname1,const LPWSTR acctname2,PSID sid1, PSID sid2);
  319. PSID GetTgtSid(const TAcctNode* tnode) { return ((TGeneralSidNode *)tnode)->TgtSid(); }
  320. DWORD SizeDiff(const TAcctNode *tnode) const { return ((TGeneralSidNode *)tnode)->SizeDiff(); } // returns max( 0 , (length(to_sid) - length(from_sid)) )
  321. };
  322. // Global Functions
  323. struct SDRDomainInfo
  324. {
  325. bool valid;
  326. PSID domain_sid;
  327. WCHAR domain_name[80];
  328. WCHAR dc_name[80];
  329. UCHAR nsubs;
  330. };
  331. int vRidComp(const TNode * tn, const void * v1);
  332. int vNameComp(const TNode * tn, const void * v1);
  333. int vTargetNameComp(const TNode * tn, const void * v1);
  334. int RidComp(const TNode * n1, const TNode * n2);
  335. int CompN(const TNode * n1, const TNode * n2);
  336. int CompTargetN(const TNode * n1, const TNode * n2);
  337. void DisplaySid(const PSID); // displays the contents of a SID
  338. void DisplaySid(const PSID,TAccountCache *); // displays the acct name if in cache, or
  339. void
  340. SetDomainInfoStruct(
  341. WCHAR const * domname, // in -name of domain
  342. SDRDomainInfo * info // in -struct to put info into
  343. );
  344. void
  345. SetDomainInfoStructFromSid(
  346. PSID pSid, // in -sid for domain
  347. SDRDomainInfo * info // in -struct to put info into
  348. );
  349. PSID DomainizeSid(PSID psid,BOOL freeOldSid);
  350. #endif