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.
|
|
//=============================================================================
// session.h -- definition of session collection class.
//
// Copyright (c) 1998-2002 Microsoft Corporation, All Rights Reserved
//=============================================================================
#include "ctoken.h"
typedef NTSTATUS (NTAPI *PFN_NT_QUERY_SYSTEM_INFORMATION) ( IN SYSTEM_INFORMATION_CLASS SystemInformationClass, OUT PVOID SystemInformation, IN ULONG SystemInformationLength, OUT PULONG ReturnLength OPTIONAL );
class CProcess; class CSession; class CUser; class CUserComp; class CUserSessionCollection;
class CUser { public: CUser() : m_sidUser(NULL) {}
CUser( PSID psidUser);
CUser( const CUser& user);
virtual ~CUser();
bool IsValid();
PSID GetPSID() const { return m_sidUser; }
void GetSidString( CHString& str) const;
private: void Copy( CUser& out) const;
PSID m_sidUser; bool m_fValid; };
// Comparison class required for multimap
// costructor involving non-standard key
// type (i.e., a CUser) in the map.
class CUserComp { public: CUserComp() {} virtual ~CUserComp() {}
bool operator()( const CUser& userFirst, const CUser& userSecond) const { bool fRet; CHString chstr1, chstr2;
userFirst.GetSidString(chstr1); userSecond.GetSidString(chstr2); long lcmp = chstr1.CompareNoCase(chstr2); (lcmp < 0) ? fRet = true : fRet = false;
return fRet; } };
class CProcess { public: // Constructors and destructors
CProcess();
CProcess( DWORD dwPID, LPCWSTR wstrImageName);
CProcess( const CProcess& process);
virtual ~CProcess();
// Accessor functions
DWORD GetPID() const; CHString GetImageName() const; private: DWORD m_dwPID; CHString m_chstrImageName;
void Copy( CProcess& process) const; };
// vector and iterator for getting a session's processes...
typedef std::vector<CProcess> PROCESS_VECTOR; typedef PROCESS_VECTOR::iterator PROCESS_ITERATOR;
class CSession { public: // Constructors and destructors
CSession() {}
CSession( const LUID& luidSessionID);
CSession( const CSession& ses);
virtual ~CSession() {}
// Accessor functions
LUID GetLUID() const; __int64 GetLUIDint64() const; CHString GetAuthenticationPkg() const; ULONG GetLogonType() const; __int64 GetLogonTime() const;
// Enumerate list of processes
CProcess* GetFirstProcess( PROCESS_ITERATOR& pos);
CProcess* GetNextProcess( PROCESS_ITERATOR& pos);
// Allow easy impersonation of
// the session's first process
HANDLE Impersonate(); DWORD GetImpProcPID();
friend CUserSessionCollection;
// Checks a string representation
// of a session id for validity
bool IsSessionIDValid( LPCWSTR wstrSessionID);
private: void Copy( CSession& sesCopy) const;
CHString m_chstrAuthPkg; ULONG m_ulLogonType; __int64 i64LogonTime; LUID m_luid; PROCESS_VECTOR m_vecProcesses; };
// map and iterator for relating users and sessions...
typedef std::multimap<CUser, CSession, CUserComp> USER_SESSION_MAP; typedef USER_SESSION_MAP::iterator USER_SESSION_ITERATOR;
// Custom iterator used in enumerating processes from
// CUserSessionCollection.
struct USER_SESSION_PROCESS_ITERATOR { friend CUserSessionCollection; private: USER_SESSION_ITERATOR usIter; PROCESS_ITERATOR procIter; };
class CUserSessionCollection { public: // Constructors and destructors
CUserSessionCollection();
CUserSessionCollection( const CUserSessionCollection& sescol);
virtual ~CUserSessionCollection() {}
// Method to refresh map
DWORD Refresh();
// Methods to check whether a particular
// session is in the map
bool IsSessionMapped( LUID& luidSes);
bool CUserSessionCollection::IsSessionMapped( __int64 i64luidSes);
// Support enumeration of users
CUser* GetFirstUser( USER_SESSION_ITERATOR& pos);
CUser* GetNextUser( USER_SESSION_ITERATOR& pos);
// Support enumeration of sessions
// belonging to a particular user.
CSession* GetFirstSessionOfUser( CUser& usr, USER_SESSION_ITERATOR& pos);
CSession* GetNextSessionOfUser( USER_SESSION_ITERATOR& pos);
// Support enumeration of all sessions
CSession* GetFirstSession( USER_SESSION_ITERATOR& pos);
CSession* GetNextSession( USER_SESSION_ITERATOR& pos);
// Support finding a particular session
CSession* FindSession( LUID& luidSes);
CSession* FindSession( __int64 i64luidSes);
// Support enumeration of processes
// belonging to a particular user
CProcess* GetFirstProcessOfUser( CUser& usr, USER_SESSION_PROCESS_ITERATOR& pos);
CProcess* GetNextProcessOfUser( USER_SESSION_PROCESS_ITERATOR& pos);
// Support enumeration of all processes
CProcess* GetFirstProcess( USER_SESSION_PROCESS_ITERATOR& pos);
CProcess* GetNextProcess( USER_SESSION_PROCESS_ITERATOR& pos);
private: DWORD CollectSessions(); DWORD CollectNoProcessesSessions();
void Copy( CUserSessionCollection& out) const;
DWORD GetProcessList( std::vector<CProcess>& vecProcesses) const;
DWORD EnablePrivilegeOnCurrentThread( LPCTSTR szPriv) const;
bool FindSessionInternal( LUID& luidSes, USER_SESSION_ITERATOR& usiOut);
USER_SESSION_MAP m_usr2ses; };
// This version is a smart handle
// for use with thread tokens we
// are impersonating. On destruction,
// it reverts to the handle it
// encapsulates.
class SmartRevertTokenHANDLE { private: HANDLE m_h;
public: SmartRevertTokenHANDLE() : m_h(INVALID_HANDLE_VALUE) {}
SmartRevertTokenHANDLE( HANDLE h) : m_h(h) {}
~SmartRevertTokenHANDLE() { if ( FALSE == Revert () ) { throw CFramework_Exception(L"SetThreadToken failed", GetLastError()); } }
HANDLE operator =(HANDLE h) { if ( FALSE == Revert () ) { throw CFramework_Exception(L"SetThreadToken failed", GetLastError()); }
m_h = h; return h; }
operator HANDLE() const { return m_h; }
HANDLE* operator &() { if ( FALSE == Revert () ) { throw CFramework_Exception(L"SetThreadToken failed", GetLastError()); }
m_h = INVALID_HANDLE_VALUE; return &m_h; }
private :
BOOL Revert () { BOOL bRet = FALSE ;
if ( m_h && INVALID_HANDLE_VALUE != m_h ) { CThreadToken cpt ( m_h ); if ( cpt.IsValidToken () ) { HANDLE hCurThread = ::GetCurrentThread();
TOKEN_TYPE type; if ( cpt.GetTokenType ( type ) ) { if ( TokenPrimary == type ) { CToken ct; if ( ct.Duplicate ( cpt, FALSE ) ) { bRet = ::SetThreadToken ( &hCurThread, ct.GetTokenHandle () ); } } else { bRet = ::SetThreadToken ( &hCurThread, cpt.GetTokenHandle () ) ; }
if (!bRet) { LogMessage2( L"Failed to SetThreadToken in SmartRevertTokenHANDLE with error %d", ::GetLastError() ); } } }
CloseHandle(m_h); } else { //
// smart revert was created from invalid handle
// there is nothing we should do here !
//
bRet = TRUE ; }
return bRet ; } };
// Helper for automatic cleanup of
// pointers returned from the various
// enumeration functions.
template<class T> class SmartDelete { private: T* m_ptr;
public: SmartDelete() : m_ptr(NULL) {}
SmartDelete( T* ptr) : m_ptr(hptr) {}
virtual ~SmartDelete() { if(m_ptr != NULL) { delete m_ptr; m_ptr = NULL; } }
T* operator =(T* ptrRight) { if(m_ptr != NULL) { delete m_ptr; m_ptr = NULL; } m_ptr = ptrRight; return ptrRight; }
operator T*() const { return m_ptr; }
T* operator &() { if(m_ptr != NULL) { delete m_ptr; m_ptr = NULL; } m_ptr = NULL; return m_ptr; }
T* operator->() const { return m_ptr; } };
|