windows-nt/Source/XPSP1/NT/ds/security/services/ca/include/certsd.h
2020-09-26 16:20:57 +08:00

265 lines
7.6 KiB
C++

//+--------------------------------------------------------------------------
// File: certsd.h
// Contents: CA's security descriptor class declaration
//---------------------------------------------------------------------------
#ifndef __CERTSD_H__
#define __CERTSD_H__
namespace CertSrv
{
typedef struct _SID_LIST
{
DWORD dwSidCount;
DWORD SidListStart[ANYSIZE_ARRAY];
} SID_LIST, *PSID_LIST;
HRESULT GetWellKnownSID(
PSID *ppSid,
SID_IDENTIFIER_AUTHORITY *pAuth,
BYTE SubauthorityCount,
DWORD SubAuthority1,
DWORD SubAuthority2=0,
DWORD SubAuthority3=0,
DWORD SubAuthority4=0,
DWORD SubAuthority5=0,
DWORD SubAuthority6=0,
DWORD SubAuthority7=0,
DWORD SubAuthority8=0);
// caller is responsible for LocalFree'ing PSID
HRESULT GetEveryoneSID(PSID *ppSid);
HRESULT GetLocalSystemSID(PSID *ppSid);
HRESULT GetBuiltinAdministratorsSID(PSID *ppSid);
// This class wraps a SD with single writer multiple reader access control on
// it. Allows any number of threads to LockGet() the pointer to the SD if no
// thread is in the middle of a Set(). Set() is blocked until all threads
// that already retrieved the SD released it (calling Unlock)
//
// Also provides the support for persistently saving/loading the SD to registy
class CProtectedSecurityDescriptor
{
public:
CProtectedSecurityDescriptor() :
m_pSD(NULL),
m_fInitialized(false),
m_cReaders(0),
m_hevtNoReaders(NULL),
m_pcwszSanitizedName(NULL),
m_pcwszPersistRegVal(NULL)
{};
~CProtectedSecurityDescriptor()
{
Uninitialize();
}
void Uninitialize()
{
if(m_pSD)
{
LocalFree(m_pSD);
m_pSD = NULL;
}
if(m_hevtNoReaders)
{
CloseHandle(m_hevtNoReaders);
m_hevtNoReaders = NULL;
}
m_pcwszSanitizedName = NULL;
m_fInitialized = false;
m_cReaders = 0;
if(IsInitialized())
{
DeleteCriticalSection(&m_csWrite);
}
}
BOOL IsInitialized() const { return m_fInitialized;}
// init, loading SD from the registry
HRESULT Initialize(LPCWSTR pwszSanitizedName);
// init from supplied SD
HRESULT Initialize(const PSECURITY_DESCRIPTOR pSD, LPCWSTR pwszSanitizedName);
HRESULT InitializeFromTemplate(LPCWSTR pcwszTemplate, LPCWSTR pwszSanitizedName);
HRESULT Set(const PSECURITY_DESCRIPTOR pSD);
HRESULT LockGet(PSECURITY_DESCRIPTOR *ppSD);
HRESULT Unlock();
PSECURITY_DESCRIPTOR Get() { return m_pSD; };
// load SD from registry
HRESULT Load();
// save SD to registry
HRESULT Save();
// delete SD from registry
HRESULT Delete();
LPCWSTR GetPersistRegistryVal() { return m_pcwszPersistRegVal;}
void ImportResourceStrings(LPCWSTR *pcwszStrings)
{m_pcwszResources = pcwszStrings;};
protected:
HRESULT Init(LPCWSTR pwszSanitizedName);
HRESULT SetSD(PSECURITY_DESCRIPTOR pSD);
PSECURITY_DESCRIPTOR m_pSD;
bool m_fInitialized;
LONG m_cReaders;
HANDLE m_hevtNoReaders;
CRITICAL_SECTION m_csWrite;
LPCWSTR m_pcwszSanitizedName; // no free
LPCWSTR m_pcwszPersistRegVal; // no free
static LPCWSTR const *m_pcwszResources; // no free
}; //class CProtectedSecurityDescriptor
// The class stores a list of officers/groups and the principals they are
// allowed to manage certificates for:
//
// officerSID1 -> clientSID1, clientSID2...
// officerSID2 -> clientSID3, clientSID4...
//
// The information is stored as a DACL containing callback ACEs .
// The officer SID is stored as in the ACE's SID and the list of client
// SIDs are stored in the custom data space following the officer SID
// (see definition of _ACCESS_*_CALLBACK_ACE)
//
// The DACL will be used to AccessCheck if an officer is allowed to perform
// an action over a certificate.
//
// The SD contains only the officer DACL, SACL or other data is not used.
class COfficerRightsSD : public CProtectedSecurityDescriptor
{
public:
COfficerRightsSD() : m_fEnabled(FALSE)
{ m_pcwszPersistRegVal = wszREGOFFICERRIGHTS; }
HRESULT InitializeEmpty();
HRESULT Initialize(LPCWSTR pwszSanitizedName);
// The officer rights have to be in sync with the CA security descriptor.
// An officer ACE for a certain SID can exist only if the principal is
// an officer as defined by the CA SD.
// Merge sets the internal officer DACL making sure it's in sync
// with the CA SD:
// - removes any ACE found in the officer DACL which is not present as an
// allow ACE in the CA DACL
// - add an Everyone ACE in the officer DACL for each allow ACE in CA DACL
// that is not already present
HRESULT Merge(
PSECURITY_DESCRIPTOR pOfficerSD,
PSECURITY_DESCRIPTOR pCASD);
// Same as above but using the internal officer SD. Used to generate the
// initial officer SD and to update it when CA SD changes
HRESULT Adjust(
PSECURITY_DESCRIPTOR pCASD);
BOOL IsEnabled() { return m_fEnabled; }
void SetEnable(BOOL fEnable) { m_fEnabled = fEnable;}
HRESULT Save();
HRESULT Load();
HRESULT Validate() { return S_OK; }
static HRESULT ConvertToString(
IN PSECURITY_DESCRIPTOR pSD,
OUT LPWSTR& rpwszSD);
protected:
static HRESULT ConvertAceToString(
IN PACCESS_ALLOWED_CALLBACK_ACE pAce,
OUT OPTIONAL PDWORD pdwSize,
IN OUT OPTIONAL LPWSTR pwszSD);
BOOL m_fEnabled;
}; // class COfficerRightsSD
class CCertificateAuthoritySD : public CProtectedSecurityDescriptor
{
public:
CCertificateAuthoritySD() :
m_pDefaultDSSD(NULL),
m_pDefaultServiceSD(NULL),
m_pDefaultDSAcl(NULL),
m_pDefaultServiceAcl(NULL),
m_pwszComputerSID(NULL)
{ m_pcwszPersistRegVal = wszREGCASECURITY; }
~CCertificateAuthoritySD()
{
if(m_pDefaultDSSD)
LocalFree(m_pDefaultDSSD);
if(m_pDefaultServiceSD)
LocalFree(m_pDefaultServiceSD);
if(m_pwszComputerSID)
LocalFree(m_pwszComputerSID);
}
// Sets a new CA SD. Uses the new DACL but keeps the old owner, group and
// SACL.
// Also rebuilds the DACL for objects CA owns (eg DS pKIEnrollmentService,
// service). The new DACL contains a default DACL plus additional aces
// depending on the object:
// DS - add an enroll ace for each enroll ace found in CA DACL
// Service - add a full control ace for each CA admin ace
HRESULT Set(const PSECURITY_DESCRIPTOR pSD, bool fSetDSSecurity);
static HRESULT Validate(const PSECURITY_DESCRIPTOR pSD);
HRESULT ResetSACL();
HRESULT MapAndSetDaclOnObjects(bool fSetDSSecurity);
// Upgrade SD from Win2k.
HRESULT UpgradeWin2k(bool fUseEnterpriseAcl);
static HRESULT ConvertToString(
IN PSECURITY_DESCRIPTOR pSD,
OUT LPWSTR& rpwszSD);
protected:
enum ObjType
{
ObjType_DS,
ObjType_Service,
};
HRESULT MapAclGetSize(PVOID pAce, ObjType type, DWORD& dwSize);
HRESULT MapAclAddAce(PACL pAcl, ObjType type, PVOID pAce);
HRESULT SetDefaultAcl(ObjType type);
HRESULT SetComputerSID();
HRESULT MapAclSetOnDS(const PACL pAcl);
HRESULT MapAclSetOnService(const PACL pAcl);
DWORD GetUpgradeAceSizeAndType(PVOID pAce, DWORD *pdwType, PSID *ppSid);
static HRESULT ConvertAceToString(
IN PACCESS_ALLOWED_ACE pAce,
OUT OPTIONAL PDWORD pdwSize,
IN OUT OPTIONAL LPWSTR pwszSD);
PSECURITY_DESCRIPTOR m_pDefaultDSSD;
PSECURITY_DESCRIPTOR m_pDefaultServiceSD;
PACL m_pDefaultDSAcl; // no free
PACL m_pDefaultServiceAcl; // no free
LPWSTR m_pwszComputerSID;
};
} // namespace CertSrv
#endif //__CERTSD_H__