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

//#pragma title ("SidCache.hpp -- Cache, Tree of SIDs")
/*
Copyright (c) 1995-1998, Mission Critical Software, Inc. All rights reserved.
===============================================================================
Module - sidcache.hpp
System - SDResolve
Author - Christy Boles
Created - 97/06/27
Description - Cache of SIDs. Implemented using TNode derived classes, Cache is
organized as a tree, sorted by Domain B RID. Each node contains
Domain A RID, Domain B RID, Account Name, and counters for stats.
Updates -
===============================================================================
*/
#ifndef TSIDCACHE_HEADER
#define TSIDCACHE_HEADER
#ifndef TNODEINCLUDED
#include "Tnode.hpp"
#define TNODEINCLUDED
#endif
//#import "\bin\McsVarSetMin.tlb" no_namespace
//#import "VarSet.tlb" no_namespace rename("property", "aproperty")//#imported below via sdstat.hpp
#include "DCTStat.h"
#include "WorkObj.h"
#include "sdstat.hpp"
#include <map>
#include <string>
#ifndef IStatusObjPtr
_COM_SMARTPTR_TYPEDEF(IStatusObj, __uuidof(IStatusObj));
#endif
//#define ACCOUNT_NAME_LENGTH 256
#define NUM_IN_BUF 5000 /* the number of accounts to get at one time NetQueryDisplayInfo()*/
#define BUFSIZE 100000 /* preferred max size of buffer for receiving accounts NetQueryDisplayInfo()*/
#define DEFAULT_SID_SIZE 500
#define EALB_OCX_LOCAL_USER 13
#define EALB_OCX_GLOBAL_USER 14
#define EALB_OCX_LOCAL_GROUP 16
#define EALB_OCX_GLOBAL_GROUP 17
#define FST_CACHE_SOME_SOURCE 1
#define FST_CACHE_NO_TARGET 2
#define FST_CACHE_SOME_TARGET 4
#define FST_CACHE_NO_DOMAIN 8
class TAcctNode:public TNode
{
protected:
DWORD owner_changes; // Stats for each node
DWORD group_changes;
DWORD ace_changes;
DWORD sace_changes;
public:
TAcctNode();
virtual WCHAR * GetAcctName() = 0;
virtual bool IsValidOnTgt() const = 0;
virtual void AddOwnerChange(objectType type) { owner_changes++; } // Stats functions
virtual void AddGroupChange(objectType type) { group_changes++; }
virtual void AddAceChange(objectType type) { ace_changes++; }
virtual void AddSaceChange(objectType type) { sace_changes++; }
virtual void DisplayStats() const;
DWORD OwnerChanges() { return owner_changes; }
DWORD GroupChanges() { return group_changes; }
DWORD DACEChanges() { return ace_changes; }
DWORD SACEChanges() { return sace_changes; }
BOOL ReportToVarSet(IVarSet * pVarSet, DWORD n);
};
class TRidNode:public TAcctNode
{
public:
typedef enum _STATUS { DEFAULT = 0, TARGETSIDISINVALID = 1 } STATUS;
protected:
DWORD srcRid; // RID for domain A
DWORD tgtRid; // RID for domain B
DWORD status;
short acct_type;
int acct_len; // length of account name
std::wstring srcDomSid; // source domain sid
std::wstring tgtDomSid; // target domain sid
std::wstring srcDomName; // source domain name
std::wstring tgtDomName; // target domain name
WCHAR acct_name[1]; // source account name \0 target account name
public:
void * operator new(size_t sz,const LPWSTR name1,const LPWSTR name2);
TRidNode(const LPWSTR oldacctname, const LPWSTR newacctname);
~TRidNode();
WCHAR * GetAcctName() { return acct_name; } // member "Get" functions
WCHAR * GetTargetAcctName() { return acct_name + acct_len + 1; }
DWORD SrcRid() const { return srcRid; }
DWORD TgtRid() const { return tgtRid; }
DWORD GetStatus() { return status; }
void SetStatus(DWORD newStatus) { status = newStatus; }
bool IsValidOnTgt() const { return tgtRid != 0 && !(status & TARGETSIDISINVALID); }
short Type() { return acct_type; }
void Type(short newtype) { acct_type = newtype; }
void SrcRid(DWORD const val) { srcRid=val; } // member "Set" functions
void TgtRid(DWORD const val) { tgtRid=val; }
void DisplayStats() const;
void DisplaySidInfo() const;
PCWSTR GetSrcDomSid() { return srcDomSid.c_str(); } // member "Get" function
PCWSTR GetTgtDomSid() { return tgtDomSid.c_str(); } // member "Get" function
void SrcDomSid(PCWSTR sSid) { if (sSid) srcDomSid = sSid; else srcDomSid.erase(); } // member "Set" function
void TgtDomSid(PCWSTR sSid) { if (sSid) tgtDomSid = sSid; else tgtDomSid.erase(); } // member "Set" function
PCWSTR GetSrcDomName() { return srcDomName.c_str(); } // member "Get" function
PCWSTR GetTgtDomName() { return tgtDomName.c_str(); } // member "Get" function
void SrcDomName(PCWSTR sName) { if (sName) srcDomName = sName; else srcDomName.erase(); } // member "Set" function
void TgtDomName(PCWSTR sName) { if (sName) tgtDomName = sName; else tgtDomName.erase(); } // member "Set" function
protected:
};
class TGeneralSidNode:public TAcctNode
{
protected:
LPWSTR src_acct_name;
LPWSTR tgt_acct_name;
PSID src_sid;
PSID tgt_sid;
UCHAR src_nsubs;
UCHAR tgt_nsubs;
WCHAR * src_domain;
WCHAR * tgt_domain;
DWORD sizediff;
TSDFileDirCell ownerStats;
TSDFileDirCell groupStats;
TSDFileDirCell daclStats;
TSDFileDirCell saclStats;
public:
TGeneralSidNode(const LPWSTR name1, const LPWSTR name2);
TGeneralSidNode(const PSID pSid1, const PSID pSid2);
~TGeneralSidNode();
LPWSTR GetAcctName() { return src_acct_name; }
PSID SrcSid() { return src_sid; }
PSID TgtSid() { return src_sid; /* this is a hack to allow for counting all references to accounts */ }
bool IsValidOnTgt() const { return TRUE;/*tgt_sid != NULL;*/ }
void DisplaySidInfo() const;
DWORD SizeDiff() const { return 0; }
TSDFileDirCell * GetOwnerStats() { return &ownerStats; }
TSDFileDirCell * GetGroupStats() { return &groupStats; }
TSDFileDirCell * GetDaclStats() { return &daclStats; }
TSDFileDirCell * GetSaclStats() { return &saclStats; }
virtual void AddOwnerChange(objectType type)
{
switch (type)
{
case file: ownerStats.file++; break;
case directory: ownerStats.dir++; break;
case mailbox: ownerStats.mailbox++; break;
case container: ownerStats.container++; break;
case share: ownerStats.share++; break;
case groupmember: ownerStats.member++; break;
case userright: ownerStats.userright++; break;
case regkey: ownerStats.regkey++; break;
case printer: ownerStats.printer++; break;
default:
break;
};
}
virtual void AddGroupChange(objectType type)
{
switch (type)
{
case file: groupStats.file++; break;
case directory: groupStats.dir++; break;
case mailbox: groupStats.mailbox++; break;
case container: groupStats.container++; break;
case share: groupStats.share++; break;
case groupmember: groupStats.member++; break;
case userright: groupStats.userright++; break;
case regkey: groupStats.regkey++; break;
case printer: groupStats.printer++; break;
default:
break;
};
}
virtual void AddAceChange(objectType type)
{
switch (type)
{
case file: daclStats.file++; break;
case directory: daclStats.dir++; break;
case mailbox: daclStats.mailbox++; break;
case container: daclStats.container++; break;
case share: daclStats.share++; break;
case groupmember: daclStats.member++; break;
case userright: daclStats.userright++; break;
case regkey: daclStats.regkey++; break;
case printer: daclStats.printer++; break;
default:
break;
};
}
virtual void AddSaceChange(objectType type)
{
switch (type)
{
case file: saclStats.file++; break;
case directory: saclStats.dir++; break;
case mailbox: saclStats.mailbox++; break;
case container: saclStats.container++; break;
case share: saclStats.share++; break;
case groupmember: saclStats.member++; break;
case userright: saclStats.userright++; break;
case regkey: saclStats.regkey++; break;
case printer: saclStats.printer++; break;
default:
break;
};
}
};
/**************************************************************************************************/
/* TSidCache: Cache for SIDs.
The cache is filled by calling FillCache(name_of_domain_A, name_of_domain_B)
Lookup, and GetName search the tree for a domain B SID value.
Lookup returns a pointer to the node, while GetName returns the account
name for the node.
GetSidB( tsidnode *) builds and returns the domain B SID for the node (the node contains only the RID)
SizeDiff() returns the answer to "How much bigger are domain B sids than domain A sids?"
this information is needed when allocating space for ACES.
/**************************************************************************************************/
class TAccountCache: public TNodeListSortable
{
IStatusObjPtr m_pStatus;
public:
TAccountCache() { m_cancelled = false; m_bAddIfNotFound = FALSE; }
~TAccountCache() {}
virtual TAcctNode * Lookup(const PSID psid) = 0; // sid lookup functions
virtual LPWSTR GetName(const PSID psid) = 0;
//virtual BOOL Insert(const LPWSTR acctname,DWORD srcSid, DWORD tgtSid) = 0;
virtual PSID GetTgtSid(const TAcctNode* tnode) = 0;
virtual DWORD SizeDiff(const TAcctNode *tnode) const = 0; // returns max( 0 , (length(to_sid) - length(from_sid)) )
bool IsCancelled()
{
if ( m_pStatus )
{
LONG status = 0;
// HRESULT hr = m_pStatus->get_Status(&status);
m_pStatus->get_Status(&status);
return (status == DCT_STATUS_ABORTING);
}
else
{
return m_cancelled;
}
}
void Cancel() { m_cancelled = true; if ( m_pStatus ) m_pStatus->put_Status(DCT_STATUS_ABORTING); }
void UnCancel() { m_cancelled = false; }
void AddIfNotFound(BOOL val) { m_bAddIfNotFound = val; }
BOOL AddIfNotFound() { return m_bAddIfNotFound; }
void SetStatusObject(IStatusObj * pS) { m_pStatus = pS; }
protected:
bool m_cancelled;
BOOL m_bAddIfNotFound;
};
class TGeneralCache;
class TSDRidCache: public TAccountCache
{
protected:
WCHAR from_domain[MAX_PATH + 1]; // domain names
WCHAR to_domain[MAX_PATH + 1];
WCHAR from_dc[MAX_PATH + 1]; // domain controller (machine) names
WCHAR to_dc[MAX_PATH + 1];
PSID from_sid; // domain sids (dynamically allocated)
PSID to_sid;
UCHAR from_nsubs; // # subauthorities in domain sids
UCHAR to_nsubs;
DWORD accts; // statistical stuff
DWORD accts_resolved;
TGeneralCache * m_otherAccounts;
typedef std::multimap<DWORD, TRidNode*> CRidToNodeMap;
CRidToNodeMap m_mapRidToNode;
public:
TSDRidCache();
~TSDRidCache();
// filling methods
WCHAR const * GetSourceDomainName() { return from_domain; }
WCHAR const * GetTargetDomainName() { return to_domain; }
WCHAR const * GetSourceDCName() { return from_dc; }
WCHAR const * GetTargetDCName() { return to_dc; }
void InsertLast(const LPWSTR acctname,DWORD rida, const LPWSTR newname, DWORD ridb, short type = 0, DWORD status = TRidNode::DEFAULT)
{ TRidNode * tn = new (acctname,newname) TRidNode(acctname,newname); if (tn){ tn->SetStatus(status); tn->SrcRid(rida); tn->TgtRid(ridb);
tn->Type(type); if ( ridb != 0 ) accts_resolved++; accts++; TNodeListSortable::InsertBottom((TNode *)tn); }}
void InsertLastWithSid(const LPWSTR acctname, LPCWSTR srcdomainsid, LPCWSTR srcdomainname, DWORD rida, const LPWSTR newname,
LPCWSTR tgtdomainsid, LPCWSTR tgtdomainname, DWORD ridb, short type = 0, DWORD status = TRidNode::DEFAULT)
{ TRidNode * tn = new (acctname,newname) TRidNode(acctname,newname); if (tn){ tn->SetStatus(status); tn->SrcRid(rida); tn->TgtRid(ridb);
tn->SrcDomSid(srcdomainsid); tn->TgtDomSid(tgtdomainsid); tn->SrcDomName(srcdomainname); tn->TgtDomName(tgtdomainname);
tn->Type(type); if ( ridb != 0 ) accts_resolved++; accts++; TNodeListSortable::InsertBottom((TNode *)tn); }}
TAcctNode * Lookup(const PSID psid); // sid lookup functions
TAcctNode * LookupWODomain(const PSID psid); // sid lookup functions
LPWSTR GetName(const PSID psid);
// helper methods
PSID GetTgtSid(TAcctNode const * tnode) ; // "Get" functions
DWORD SizeDiff(const TAcctNode *tnode) const ; // returns max( 0 , (length(to_sid) - length(from_sid)) )
void Display(bool summary, bool detail);
void ReportToVarSet(IVarSet * pVarSet,bool summary, bool detail);
PSID GetTgtSid(const PSID psid) { return GetTgtSid(Lookup(psid)); }
void CopyDomainInfo( TSDRidCache const * other);
PSID GetTgtSidWODomain(TAcctNode const * tnode); // "Get" functions
PSID GetTgtSidWODomain(const PSID psid); // "Get" functions
DWORD GetNumAccts() const {return accts; }
DWORD GetNumResolvedAccts() const { return accts_resolved; }
void Clear();
void SetSourceAndTargetDomains(WCHAR const * src, WCHAR const * tgt) { SetDomainInfo(src,true); SetDomainInfo(tgt,false); }
void SetSourceAndTargetDomainsWithSids(WCHAR const * src, WCHAR const * srcSid, WCHAR const * tgt,WCHAR const * tgtSid)
{ SetDomainInfoWithSid(src,srcSid,true); SetDomainInfoWithSid(tgt,tgtSid,false); }
void ReportAccountReferences(WCHAR const * filename);
BOOL IsInitialized() { return from_sid!=NULL && to_sid!=NULL; }
void VerifyTargetSids();
protected:
int SetDomainInfo(WCHAR const * domname, bool firstdom);
int SetDomainInfoWithSid(WCHAR const * domainName, WCHAR const * domainSid, bool firstdom);
};
class TGeneralCache : public TAccountCache
{
protected:
DWORD accts; // statistical stuff
DWORD accts_resolved;
public:
TGeneralCache();
~TGeneralCache();
TAcctNode * Lookup(const PSID psid) ; // sid lookup functions
LPWSTR GetName(const PSID psid) ;
BOOL Insert(const LPWSTR acctname1,const LPWSTR acctname2,PSID sid1, PSID sid2);
PSID GetTgtSid(const TAcctNode* tnode) { return ((TGeneralSidNode *)tnode)->TgtSid(); }
DWORD SizeDiff(const TAcctNode *tnode) const { return ((TGeneralSidNode *)tnode)->SizeDiff(); } // returns max( 0 , (length(to_sid) - length(from_sid)) )
};
// Global Functions
struct SDRDomainInfo
{
bool valid;
PSID domain_sid;
WCHAR domain_name[80];
WCHAR dc_name[80];
UCHAR nsubs;
};
int vRidComp(const TNode * tn, const void * v1);
int vNameComp(const TNode * tn, const void * v1);
int vTargetNameComp(const TNode * tn, const void * v1);
int RidComp(const TNode * n1, const TNode * n2);
int CompN(const TNode * n1, const TNode * n2);
int CompTargetN(const TNode * n1, const TNode * n2);
void DisplaySid(const PSID); // displays the contents of a SID
void DisplaySid(const PSID,TAccountCache *); // displays the acct name if in cache, or
void
SetDomainInfoStruct(
WCHAR const * domname, // in -name of domain
SDRDomainInfo * info // in -struct to put info into
);
void
SetDomainInfoStructFromSid(
PSID pSid, // in -sid for domain
SDRDomainInfo * info // in -struct to put info into
);
PSID DomainizeSid(PSID psid,BOOL freeOldSid);
#endif