467 lines
11 KiB
C
467 lines
11 KiB
C
|
/*++
|
||
|
|
||
|
Copyright (C) 1997-2001 Microsoft Corporation
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
WINNTSEC.H
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
Generic wrapper classes for NT security objects.
|
||
|
|
||
|
Documention on class members is in WINNTSEC.CPP. Inline members
|
||
|
are commented in this file.
|
||
|
|
||
|
History:
|
||
|
|
||
|
raymcc 08-Jul-97 Created.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
#ifndef _WINNTSEC_H_
|
||
|
#define _WINNTSEC_H_
|
||
|
|
||
|
class POLARITY CNtSecurity;
|
||
|
|
||
|
// All ACE types are currently have the same binary layout. Rather
|
||
|
// than doing a lot of useless casts, we produce a general-purpose
|
||
|
// typedef to hold all ACEs.
|
||
|
// ================================================================
|
||
|
|
||
|
typedef ACCESS_ALLOWED_ACE GENERIC_ACE;
|
||
|
typedef GENERIC_ACE *PGENERIC_ACE;
|
||
|
|
||
|
#define FULL_CONTROL \
|
||
|
(DELETE | \
|
||
|
READ_CONTROL | \
|
||
|
WRITE_DAC | \
|
||
|
WRITE_OWNER | \
|
||
|
SYNCHRONIZE | GENERIC_ALL)
|
||
|
|
||
|
|
||
|
//***************************************************************************
|
||
|
//
|
||
|
// CNtSid
|
||
|
//
|
||
|
// Models SIDs (users/groups).
|
||
|
//
|
||
|
//***************************************************************************
|
||
|
|
||
|
class POLARITY CNtSid
|
||
|
{
|
||
|
PSID m_pSid;
|
||
|
LPWSTR m_pMachine;
|
||
|
LPWSTR m_pDomain;
|
||
|
DWORD m_dwStatus;
|
||
|
SID_NAME_USE m_snu;
|
||
|
|
||
|
public:
|
||
|
enum { NoError, Failed, NullSid, InvalidSid, InternalError, AccessDenied = 0x5 };
|
||
|
|
||
|
enum SidType {CURRENT_USER, CURRENT_THREAD};
|
||
|
|
||
|
CNtSid(SidType st);
|
||
|
CNtSid() { m_pSid = 0; m_pMachine = 0; m_dwStatus = NullSid; }
|
||
|
bool IsUser(){return m_snu == SidTypeUser;};
|
||
|
|
||
|
CNtSid(PSID pSrc);
|
||
|
// Construct based on another SID.
|
||
|
|
||
|
CNtSid(LPWSTR pUser, LPWSTR pMachine = 0);
|
||
|
// Construct based on a user (machine name is optional).
|
||
|
|
||
|
~CNtSid();
|
||
|
|
||
|
CNtSid(CNtSid &Src);
|
||
|
CNtSid &operator =(CNtSid &Src);
|
||
|
int operator ==(CNtSid &Comparand);
|
||
|
|
||
|
DWORD GetStatus() { return m_dwStatus; }
|
||
|
// Returns one of the enumerated types.
|
||
|
|
||
|
PSID GetPtr() { return m_pSid; }
|
||
|
// Returns the internal SID ptr to interface with NT APIs
|
||
|
DWORD GetSize();
|
||
|
|
||
|
BOOL CopyTo(PSID pDestination);
|
||
|
|
||
|
BOOL IsValid() { return (m_pSid && IsValidSid(m_pSid)); }
|
||
|
// Checks the validity of the internal SID.
|
||
|
|
||
|
void Dump();
|
||
|
// Dumps SID info to console for debugging.
|
||
|
|
||
|
int GetInfo(
|
||
|
LPWSTR *pRetAccount, // Account, use operator delete
|
||
|
LPWSTR *pRetDomain, // Domain, use operator delete
|
||
|
DWORD *pdwUse // See SID_NAME_USE for values
|
||
|
);
|
||
|
|
||
|
BOOL GetTextSid(LPTSTR pszSidText, LPDWORD dwBufferLen);
|
||
|
|
||
|
};
|
||
|
|
||
|
//***************************************************************************
|
||
|
//
|
||
|
// CBaseAce
|
||
|
//
|
||
|
// Base class for aces.
|
||
|
//
|
||
|
//***************************************************************************
|
||
|
|
||
|
class POLARITY CBaseAce
|
||
|
{
|
||
|
|
||
|
public:
|
||
|
|
||
|
CBaseAce(){};
|
||
|
virtual ~CBaseAce(){};
|
||
|
|
||
|
virtual int GetType() = 0;
|
||
|
virtual int GetFlags() = 0; // inheritance etc.
|
||
|
virtual ACCESS_MASK GetAccessMask() = 0;
|
||
|
virtual HRESULT GetFullUserName(WCHAR * pBuff, DWORD dwSize) = 0;
|
||
|
virtual HRESULT GetFullUserName2(WCHAR ** pBuff) = 0; // call must free
|
||
|
virtual DWORD GetStatus() = 0;
|
||
|
virtual void SetFlags(long lFlags) =0;
|
||
|
virtual DWORD GetSerializedSize() = 0;
|
||
|
virtual bool Serialize(BYTE * pData) = 0;
|
||
|
virtual bool Deserialize(BYTE * pData) = 0;
|
||
|
};
|
||
|
|
||
|
|
||
|
//***************************************************************************
|
||
|
//
|
||
|
// CNtAce
|
||
|
//
|
||
|
// Models NT ACEs.
|
||
|
//
|
||
|
//***************************************************************************
|
||
|
|
||
|
class POLARITY CNtAce : public CBaseAce
|
||
|
{
|
||
|
PGENERIC_ACE m_pAce;
|
||
|
DWORD m_dwStatus;
|
||
|
|
||
|
public:
|
||
|
enum { NoError, InvalidAce, NullAce, InternalError };
|
||
|
|
||
|
CNtAce() { m_pAce = 0; m_dwStatus = NullAce; }
|
||
|
|
||
|
CNtAce(PGENERIC_ACE pAceSrc);
|
||
|
CNtAce(CNtAce &Src);
|
||
|
CNtAce & operator =(CNtAce &Src);
|
||
|
|
||
|
~CNtAce();
|
||
|
|
||
|
CNtAce(
|
||
|
ACCESS_MASK Mask,
|
||
|
DWORD AceType,
|
||
|
DWORD dwAceFlags,
|
||
|
LPWSTR pUser,
|
||
|
LPWSTR pMachine = 0 // Defaults to local machine
|
||
|
);
|
||
|
|
||
|
CNtAce(
|
||
|
ACCESS_MASK Mask,
|
||
|
DWORD AceType,
|
||
|
DWORD dwAceFlags,
|
||
|
CNtSid & Sid
|
||
|
);
|
||
|
|
||
|
int GetType();
|
||
|
int GetFlags(); // inheritance etc.
|
||
|
void SetFlags(long lFlags){m_pAce->Header.AceFlags = (unsigned char)lFlags;};
|
||
|
|
||
|
DWORD GetStatus() { return m_dwStatus; }
|
||
|
// Returns one of the enumerated types.
|
||
|
|
||
|
int GetSubject(
|
||
|
LPWSTR *pSubject
|
||
|
);
|
||
|
|
||
|
ACCESS_MASK GetAccessMask();
|
||
|
|
||
|
CNtSid *GetSid();
|
||
|
BOOL GetSid(CNtSid &Dest);
|
||
|
|
||
|
PGENERIC_ACE GetPtr() { return m_pAce; }
|
||
|
DWORD GetSize() { return m_pAce ? m_pAce->Header.AceSize : 0; }
|
||
|
HRESULT GetFullUserName(WCHAR * pBuff, DWORD dwSize);
|
||
|
HRESULT GetFullUserName2(WCHAR ** pBuff); // call must free
|
||
|
DWORD GetSerializedSize();
|
||
|
bool Serialize(BYTE * pData);
|
||
|
bool Deserialize(BYTE * pData);
|
||
|
|
||
|
void Dump(int iAceNum = -1);
|
||
|
void DumpAccessMask();
|
||
|
};
|
||
|
|
||
|
//***************************************************************************
|
||
|
//
|
||
|
// C9XAce
|
||
|
//
|
||
|
// Simulates NT ACEs for 9X boxs.
|
||
|
//
|
||
|
//***************************************************************************
|
||
|
|
||
|
class POLARITY C9XAce : public CBaseAce
|
||
|
{
|
||
|
LPWSTR m_wszFullName;
|
||
|
DWORD m_dwAccess;
|
||
|
int m_iFlags;
|
||
|
int m_iType;
|
||
|
public:
|
||
|
|
||
|
C9XAce(){m_wszFullName = 0;};
|
||
|
C9XAce(DWORD Mask,
|
||
|
DWORD AceType,
|
||
|
DWORD dwAceFlags,
|
||
|
LPWSTR pUser);
|
||
|
~C9XAce();
|
||
|
|
||
|
int GetType(){return m_iType;};
|
||
|
int GetFlags(){return m_iFlags;}; // inheritance etc.
|
||
|
|
||
|
ACCESS_MASK GetAccessMask(){return m_dwAccess;};
|
||
|
HRESULT GetFullUserName(WCHAR * pBuff, DWORD dwSize);
|
||
|
HRESULT GetFullUserName2(WCHAR ** pBuff); // call must free
|
||
|
DWORD GetStatus(){ return CNtAce::NoError; };
|
||
|
void SetFlags(long lFlags){m_iFlags = (unsigned char)lFlags;};
|
||
|
DWORD GetSerializedSize();
|
||
|
bool Serialize(BYTE * pData);
|
||
|
bool Deserialize(BYTE * pData);
|
||
|
|
||
|
};
|
||
|
|
||
|
|
||
|
//***************************************************************************
|
||
|
//
|
||
|
// CNtAcl
|
||
|
//
|
||
|
// Models an NT ACL.
|
||
|
//
|
||
|
//***************************************************************************
|
||
|
|
||
|
class POLARITY CNtAcl
|
||
|
{
|
||
|
PACL m_pAcl;
|
||
|
DWORD m_dwStatus;
|
||
|
|
||
|
public:
|
||
|
enum { NoError, InternalError, NullAcl, InvalidAcl };
|
||
|
enum { MinimumSize = 1 };
|
||
|
|
||
|
CNtAcl(DWORD dwInitialSize = 128);
|
||
|
|
||
|
CNtAcl(CNtAcl &Src);
|
||
|
CNtAcl & operator = (CNtAcl &Src);
|
||
|
|
||
|
CNtAcl(PACL pAcl); // Makes a copy
|
||
|
~CNtAcl();
|
||
|
|
||
|
int GetNumAces();
|
||
|
|
||
|
DWORD GetStatus() { return m_dwStatus; }
|
||
|
// Returns one of the enumerated types.
|
||
|
|
||
|
BOOL ContainsSid ( CNtSid& sid, BYTE& flags ) ;
|
||
|
|
||
|
CNtAce *GetAce(int nIndex);
|
||
|
BOOL GetAce(int nIndex, CNtAce &Dest);
|
||
|
|
||
|
BOOL DeleteAce(int nIndex);
|
||
|
BOOL AddAce(CNtAce *pAce);
|
||
|
|
||
|
BOOL IsValid() { return(m_pAcl && IsValidAcl(m_pAcl)); }
|
||
|
// Checks the validity of the embedded ACL.
|
||
|
|
||
|
BOOL Resize(DWORD dwNewSize);
|
||
|
// Or use CNtAcl::MinimumSize to trim the ACL to min size.
|
||
|
// Fails if an illegal size is specified.
|
||
|
|
||
|
DWORD GetSize();
|
||
|
|
||
|
PACL GetPtr() { return m_pAcl; }
|
||
|
// Returns the internal pointer for interface with NT APIs.
|
||
|
|
||
|
BOOL GetAclSizeInfo(
|
||
|
PDWORD pdwBytesInUse,
|
||
|
PDWORD pdwBytesFree
|
||
|
);
|
||
|
|
||
|
void Dump();
|
||
|
};
|
||
|
|
||
|
//***************************************************************************
|
||
|
//
|
||
|
// SNtAbsoluteSD
|
||
|
//
|
||
|
// Helper for converting between absolute and relative SDs.
|
||
|
//
|
||
|
//***************************************************************************
|
||
|
|
||
|
struct SNtAbsoluteSD
|
||
|
{
|
||
|
PSECURITY_DESCRIPTOR m_pSD;
|
||
|
|
||
|
PACL m_pDacl;
|
||
|
PACL m_pSacl;
|
||
|
PSID m_pOwner;
|
||
|
PSID m_pPrimaryGroup;
|
||
|
|
||
|
SNtAbsoluteSD();
|
||
|
~SNtAbsoluteSD();
|
||
|
};
|
||
|
|
||
|
//***************************************************************************
|
||
|
//
|
||
|
// CNtSecurityDescriptor
|
||
|
//
|
||
|
// Models an NT Security Descriptor. Note that in order to use this for an
|
||
|
// AccessCheck, the DACL, owner sid, and group sid must be set!
|
||
|
//
|
||
|
//***************************************************************************
|
||
|
|
||
|
class POLARITY CNtSecurityDescriptor
|
||
|
{
|
||
|
PSECURITY_DESCRIPTOR m_pSD;
|
||
|
int m_dwStatus;
|
||
|
|
||
|
|
||
|
public:
|
||
|
enum { NoError, NullSD, Failed, InvalidSD, SDOwned, SDNotOwned };
|
||
|
|
||
|
CNtSecurityDescriptor();
|
||
|
|
||
|
CNtSecurityDescriptor(
|
||
|
PSECURITY_DESCRIPTOR pSD,
|
||
|
BOOL bAcquire = FALSE
|
||
|
);
|
||
|
|
||
|
CNtSecurityDescriptor(CNtSecurityDescriptor &Src);
|
||
|
CNtSecurityDescriptor & operator=(CNtSecurityDescriptor &Src);
|
||
|
|
||
|
~CNtSecurityDescriptor();
|
||
|
|
||
|
SNtAbsoluteSD* CNtSecurityDescriptor::GetAbsoluteCopy();
|
||
|
BOOL SetFromAbsoluteCopy(SNtAbsoluteSD *pSrc);
|
||
|
|
||
|
int HasOwner();
|
||
|
|
||
|
BOOL IsValid() { return(m_pSD && IsValidSecurityDescriptor(m_pSD)); }
|
||
|
// Checks the validity of the embedded security descriptor&
|
||
|
|
||
|
DWORD GetStatus() { return m_dwStatus; }
|
||
|
// Returns one of the enumerated types.
|
||
|
|
||
|
CNtAcl *GetDacl();
|
||
|
// Deallocate with operator delete
|
||
|
|
||
|
BOOL GetDacl(CNtAcl &DestAcl);
|
||
|
// Retrieve into an existing object
|
||
|
|
||
|
BOOL SetDacl(CNtAcl *pSrc);
|
||
|
|
||
|
CNtAcl *GetSacl();
|
||
|
// Deallocate with operator delete
|
||
|
|
||
|
BOOL SetSacl(CNtAcl *pSrc);
|
||
|
|
||
|
CNtSid *GetOwner();
|
||
|
BOOL SetOwner(CNtSid *pSid);
|
||
|
|
||
|
CNtSid *GetGroup();
|
||
|
BOOL SetGroup(CNtSid *pSid);
|
||
|
|
||
|
PSECURITY_DESCRIPTOR GetPtr() { return m_pSD; }
|
||
|
// Returns the internal pointer for interface with NT APIs
|
||
|
|
||
|
DWORD GetSize();
|
||
|
|
||
|
void Dump();
|
||
|
};
|
||
|
|
||
|
//***************************************************************************
|
||
|
//
|
||
|
// CNtSecurity
|
||
|
//
|
||
|
// General-purpose NT security helpers.
|
||
|
//
|
||
|
//***************************************************************************
|
||
|
|
||
|
class POLARITY CNtSecurity
|
||
|
{
|
||
|
public:
|
||
|
enum { NoError, InternalFailure, NotFound, InvalidName, AccessDenied = 5, NoSecurity,
|
||
|
Failed };
|
||
|
|
||
|
static BOOL DumpPrivileges();
|
||
|
|
||
|
static BOOL SetPrivilege(
|
||
|
IN TCHAR *pszPrivilegeName, // An SE_ value.
|
||
|
IN BOOL bEnable // TRUE=enable, FALSE=disable
|
||
|
);
|
||
|
|
||
|
static BOOL GetFileSD(
|
||
|
IN TCHAR *pszFile,
|
||
|
IN SECURITY_INFORMATION SecInfo,
|
||
|
OUT CNtSecurityDescriptor **pSD
|
||
|
);
|
||
|
|
||
|
static BOOL SetFileSD(
|
||
|
IN TCHAR *pszFile,
|
||
|
IN SECURITY_INFORMATION SecInfo,
|
||
|
IN CNtSecurityDescriptor *pSD
|
||
|
);
|
||
|
|
||
|
static int GetRegSD(
|
||
|
IN HKEY hRoot,
|
||
|
IN TCHAR *pszSubKey,
|
||
|
IN SECURITY_INFORMATION SecInfo,
|
||
|
OUT CNtSecurityDescriptor **pSD
|
||
|
);
|
||
|
|
||
|
static int SetRegSD(
|
||
|
IN HKEY hRoot,
|
||
|
IN TCHAR *pszSubKey,
|
||
|
IN SECURITY_INFORMATION SecInfo,
|
||
|
IN CNtSecurityDescriptor *pSD
|
||
|
);
|
||
|
|
||
|
|
||
|
/* static int GetDCName(
|
||
|
IN LPWSTR pszDomain,
|
||
|
OUT LPWSTR *pszDC,
|
||
|
IN LPWSTR pszServer
|
||
|
);*/
|
||
|
|
||
|
static BOOL IsUserInGroup(
|
||
|
HANDLE hClientToken,
|
||
|
CNtSid & Sid
|
||
|
);
|
||
|
|
||
|
static DWORD AccessCheck(
|
||
|
HANDLE hAccessToken,
|
||
|
ACCESS_MASK RequiredAccess,
|
||
|
CNtSecurityDescriptor *pSD
|
||
|
); // TBD
|
||
|
|
||
|
static CNtSid *GetCurrentThreadSid(); // TBD
|
||
|
|
||
|
static bool DoesLocalGroupExist(LPWSTR pwszGroup, LPWSTR pwszMachine);
|
||
|
static bool AddLocalGroup(LPWSTR pwszGroupName, LPWSTR pwszGroupDescription);
|
||
|
};
|
||
|
|
||
|
BOOL FIsRunningAsService(VOID);
|
||
|
POLARITY BOOL SetObjectAccess2(HANDLE hObj);
|
||
|
POLARITY BOOL IsAdmin(HANDLE hAccess);
|
||
|
POLARITY BOOL IsNetworkService(HANDLE hAccess);
|
||
|
POLARITY BOOL IsLocalService(HANDLE hAccess);
|
||
|
POLARITY HRESULT GetAccessToken(HANDLE &hAccessToken);
|
||
|
POLARITY BOOL IsInAdminGroup();
|
||
|
|
||
|
|
||
|
#endif
|