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.
689 lines
17 KiB
689 lines
17 KiB
//+-------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
//
|
|
// Copyright (C) Microsoft Corporation, 1998 - 1999
|
|
//
|
|
// File: casec.cpp
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// casec.cpp
|
|
//
|
|
// ISecurityInformation implementation for CA objects
|
|
// and the new acl editor
|
|
//
|
|
// PURPOSE
|
|
|
|
//
|
|
//
|
|
// DYNALOADED LIBRARIES
|
|
//
|
|
// HISTORY
|
|
// 5-Nov-1998 petesk Copied template from privobsi.cpp sample.
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
#include <stdafx.h>
|
|
#include <accctrl.h>
|
|
#include <certca.h>
|
|
#include <sddl.h>
|
|
#include "certsrvd.h"
|
|
#include "certacl.h"
|
|
|
|
#define __dwFILE__ __dwFILE_CERTMMC_CASEC_CPP__
|
|
|
|
|
|
//
|
|
// defined in Security.cpp
|
|
//
|
|
// // define our generic mapping structure for our private objects //
|
|
|
|
|
|
#define INHERIT_FULL (CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE)
|
|
|
|
|
|
GENERIC_MAPPING ObjMap =
|
|
{
|
|
ACTRL_CERTSRV_READ,
|
|
DELETE | WRITE_DAC | WRITE_OWNER | ACTRL_DS_WRITE_PROP,
|
|
0,
|
|
ACTRL_CERTSRV_MANAGE
|
|
};
|
|
|
|
|
|
//
|
|
// DESCRIPTION OF ACCESS FLAG AFFECTS
|
|
//
|
|
// SI_ACCESS_GENERAL shows up on general properties page
|
|
// SI_ACCESS_SPECIFIC shows up on advanced page
|
|
// SI_ACCESS_CONTAINER shows on general page IF object is a container
|
|
//
|
|
|
|
SI_ACCESS g_siObjAccesses[] = {CERTSRV_SI_ACCESS_LIST};
|
|
|
|
#define g_iObjDefAccess 3 // ENROLL enabled by default
|
|
|
|
// The following array defines the inheritance types for my containers.
|
|
SI_INHERIT_TYPE g_siObjInheritTypes[] =
|
|
{
|
|
&GUID_NULL, 0, MAKEINTRESOURCE(IDS_INH_NONE),
|
|
};
|
|
|
|
|
|
HRESULT
|
|
LocalAllocString(LPWSTR* ppResult, LPCWSTR pString)
|
|
{
|
|
if (!ppResult || !pString)
|
|
return E_INVALIDARG;
|
|
|
|
*ppResult = (LPWSTR)LocalAlloc(LPTR, (lstrlen(pString) + 1) * sizeof(WCHAR));
|
|
|
|
if (!*ppResult)
|
|
return E_OUTOFMEMORY;
|
|
|
|
lstrcpy(*ppResult, pString);
|
|
return S_OK;
|
|
}
|
|
|
|
void
|
|
LocalFreeString(LPWSTR* ppString)
|
|
{
|
|
if (ppString)
|
|
{
|
|
if (*ppString)
|
|
LocalFree(*ppString);
|
|
*ppString = NULL;
|
|
}
|
|
}
|
|
|
|
class CCASecurityObject : public ISecurityInformation
|
|
{
|
|
protected:
|
|
ULONG m_cRef;
|
|
CertSvrCA * m_pSvrCA;
|
|
// PSECURITY_DESCRIPTOR m_pSD;
|
|
|
|
public:
|
|
CCASecurityObject() : m_cRef(1)
|
|
{
|
|
m_pSvrCA = NULL;
|
|
// m_pSD = NULL;
|
|
}
|
|
virtual ~CCASecurityObject();
|
|
|
|
STDMETHOD(Initialize)(CertSvrCA *pCA);
|
|
|
|
// IUnknown methods
|
|
STDMETHOD(QueryInterface)(REFIID, LPVOID *);
|
|
STDMETHOD_(ULONG, AddRef)();
|
|
STDMETHOD_(ULONG, Release)();
|
|
|
|
// ISecurityInformation methods
|
|
STDMETHOD(GetObjectInformation)(PSI_OBJECT_INFO pObjectInfo);
|
|
STDMETHOD(GetSecurity)(SECURITY_INFORMATION si,
|
|
PSECURITY_DESCRIPTOR *ppSD,
|
|
BOOL fDefault);
|
|
STDMETHOD(SetSecurity)(SECURITY_INFORMATION si,
|
|
PSECURITY_DESCRIPTOR pSD);
|
|
STDMETHOD(GetAccessRights)(const GUID* pguidObjectType,
|
|
DWORD dwFlags,
|
|
PSI_ACCESS *ppAccess,
|
|
ULONG *pcAccesses,
|
|
ULONG *piDefaultAccess);
|
|
STDMETHOD(MapGeneric)(const GUID *pguidObjectType,
|
|
UCHAR *pAceFlags,
|
|
ACCESS_MASK *pmask);
|
|
STDMETHOD(GetInheritTypes)(PSI_INHERIT_TYPE *ppInheritTypes,
|
|
ULONG *pcInheritTypes);
|
|
STDMETHOD(PropertySheetPageCallback)(HWND hwnd,
|
|
UINT uMsg,
|
|
SI_PAGE_TYPE uPage);
|
|
|
|
protected:
|
|
HRESULT GetSecurityDCOM(PSECURITY_DESCRIPTOR *ppSD);
|
|
HRESULT GetSecurityRegistry(PSECURITY_DESCRIPTOR *ppSD);
|
|
HRESULT SetSecurityDCOM(PSECURITY_DESCRIPTOR pSD);
|
|
HRESULT SetSecurityRegistry(PSECURITY_DESCRIPTOR pSD);
|
|
};
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// This is the entry point function called from our code that establishes
|
|
// what the ACLUI interface is going to need to know.
|
|
//
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
extern "C"
|
|
HRESULT
|
|
CreateCASecurityInfo( CertSvrCA *pCA,
|
|
LPSECURITYINFO *ppObjSI)
|
|
{
|
|
HRESULT hr;
|
|
CCASecurityObject *psi;
|
|
|
|
*ppObjSI = NULL;
|
|
|
|
psi = new CCASecurityObject;
|
|
if (!psi)
|
|
return E_OUTOFMEMORY;
|
|
|
|
hr = psi->Initialize(pCA);
|
|
|
|
if (SUCCEEDED(hr))
|
|
*ppObjSI = psi;
|
|
else
|
|
delete psi;
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
CCASecurityObject::~CCASecurityObject()
|
|
{
|
|
}
|
|
|
|
STDMETHODIMP
|
|
CCASecurityObject::Initialize(CertSvrCA *pCA)
|
|
{
|
|
m_pSvrCA = pCA;
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////
|
|
//
|
|
// IUnknown methods
|
|
//
|
|
///////////////////////////////////////////////////////////
|
|
|
|
STDMETHODIMP_(ULONG)
|
|
CCASecurityObject::AddRef()
|
|
{
|
|
return ++m_cRef;
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG)
|
|
CCASecurityObject::Release()
|
|
{
|
|
if (--m_cRef == 0)
|
|
{
|
|
delete this;
|
|
return 0;
|
|
}
|
|
|
|
return m_cRef;
|
|
}
|
|
|
|
STDMETHODIMP
|
|
CCASecurityObject::QueryInterface(REFIID riid, LPVOID FAR* ppv)
|
|
{
|
|
if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_ISecurityInformation))
|
|
{
|
|
*ppv = (LPSECURITYINFO)this;
|
|
m_cRef++;
|
|
return S_OK;
|
|
}
|
|
else
|
|
{
|
|
*ppv = NULL;
|
|
return E_NOINTERFACE;
|
|
}
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////
|
|
//
|
|
// ISecurityInformation methods
|
|
//
|
|
///////////////////////////////////////////////////////////
|
|
|
|
STDMETHODIMP
|
|
CCASecurityObject::GetObjectInformation(PSI_OBJECT_INFO pObjectInfo)
|
|
{
|
|
|
|
|
|
if(pObjectInfo == NULL)
|
|
{
|
|
return E_POINTER;
|
|
}
|
|
if(m_pSvrCA == NULL)
|
|
{
|
|
return E_POINTER;
|
|
}
|
|
|
|
ZeroMemory(pObjectInfo, sizeof(SI_OBJECT_INFO));
|
|
pObjectInfo->dwFlags = SI_EDIT_PERMS |
|
|
SI_NO_TREE_APPLY |
|
|
SI_EDIT_AUDITS |
|
|
SI_NO_ACL_PROTECT |
|
|
SI_NO_ADDITIONAL_PERMISSION;
|
|
|
|
if(!m_pSvrCA->AccessAllowed(CA_ACCESS_ADMIN))
|
|
pObjectInfo->dwFlags |= SI_READONLY;
|
|
|
|
pObjectInfo->hInstance = g_hInstance;
|
|
|
|
if(m_pSvrCA->m_pParentMachine)
|
|
{
|
|
pObjectInfo->pszServerName = const_cast<WCHAR *>((LPCTSTR)m_pSvrCA->m_pParentMachine->m_strMachineName);
|
|
}
|
|
|
|
pObjectInfo->pszObjectName = const_cast<WCHAR *>((LPCTSTR)m_pSvrCA->m_strCommonName);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CCASecurityObject::GetSecurityDCOM(PSECURITY_DESCRIPTOR *ppSD)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
ICertAdminD2 *pICertAdminD = NULL;
|
|
DWORD dwServerVersion = 0; // 0 required by myOpenAdminDComConnection
|
|
WCHAR const *pwszAuthority;
|
|
CERTTRANSBLOB ctbSD;
|
|
ZeroMemory(&ctbSD, sizeof(CERTTRANSBLOB));
|
|
|
|
CSASSERT(m_pSvrCA);
|
|
|
|
hr = myOpenAdminDComConnection(
|
|
m_pSvrCA->m_bstrConfig,
|
|
&pwszAuthority,
|
|
NULL,
|
|
&dwServerVersion,
|
|
&pICertAdminD);
|
|
_JumpIfError(hr, error, "myOpenAdminDComConnection");
|
|
|
|
if (2 > dwServerVersion)
|
|
{
|
|
hr = RPC_E_VERSION_MISMATCH;
|
|
_JumpError(hr, error, "old server");
|
|
}
|
|
|
|
__try
|
|
{
|
|
hr = pICertAdminD->GetCASecurity(
|
|
pwszAuthority,
|
|
&ctbSD);
|
|
}
|
|
__except(hr = myHEXCEPTIONCODE(), EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
}
|
|
_JumpIfError(hr, error, "pICertAdminD->GetCASecurity");
|
|
|
|
myRegisterMemAlloc(ctbSD.pb, ctbSD.cb, CSM_COTASKALLOC);
|
|
|
|
// take the return
|
|
*ppSD = (PSECURITY_DESCRIPTOR)LocalAlloc(LMEM_FIXED, ctbSD.cb);
|
|
if (NULL == *ppSD)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
_JumpError(hr, error, "LocalAlloc");
|
|
}
|
|
MoveMemory(*ppSD, ctbSD.pb, ctbSD.cb);
|
|
|
|
error:
|
|
myCloseDComConnection((IUnknown **) &pICertAdminD, NULL);
|
|
if (NULL != ctbSD.pb)
|
|
{
|
|
CoTaskMemFree(ctbSD.pb);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CCASecurityObject::GetSecurityRegistry(PSECURITY_DESCRIPTOR *ppSD)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
variant_t var;
|
|
DWORD dwType;
|
|
DWORD dwSize;
|
|
BYTE* pbTmp;
|
|
|
|
hr = m_pSvrCA->GetConfigEntry(
|
|
NULL,
|
|
wszREGCASECURITY,
|
|
&var);
|
|
_JumpIfError(hr, error, "GetConfigEntry");
|
|
|
|
hr = myVariantToRegValue(
|
|
&var,
|
|
&dwType,
|
|
&dwSize,
|
|
&pbTmp);
|
|
_JumpIfError(hr, error, "myVariantToRegValue");
|
|
|
|
*ppSD = pbTmp;
|
|
|
|
error:
|
|
return hr;
|
|
}
|
|
|
|
|
|
STDMETHODIMP
|
|
CCASecurityObject::GetSecurity(
|
|
SECURITY_INFORMATION, // si
|
|
PSECURITY_DESCRIPTOR *ppSD,
|
|
BOOL /* fDefault */ )
|
|
{
|
|
HRESULT hr = S_OK;
|
|
SECURITY_DESCRIPTOR_CONTROL Control = SE_DACL_PROTECTED;
|
|
DWORD dwRevision;
|
|
|
|
hr = GetSecurityDCOM(ppSD);
|
|
_PrintIfError(hr, "GetSecurityDCOM");
|
|
if(S_OK!=hr)
|
|
{
|
|
hr = GetSecurityRegistry(ppSD);
|
|
_JumpIfError(hr, error, "GetSecurityRegistry");
|
|
}
|
|
|
|
CSASSERT(*ppSD);
|
|
|
|
if(GetSecurityDescriptorControl(*ppSD, &Control, &dwRevision))
|
|
{
|
|
Control &= SE_DACL_PROTECTED | SE_DACL_AUTO_INHERIT_REQ | SE_DACL_AUTO_INHERITED;
|
|
SetSecurityDescriptorControl(*ppSD,
|
|
SE_DACL_PROTECTED | SE_DACL_AUTO_INHERIT_REQ | SE_DACL_AUTO_INHERITED,
|
|
Control);
|
|
}
|
|
|
|
error:
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT CCASecurityObject::SetSecurityDCOM(PSECURITY_DESCRIPTOR pSD)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
HANDLE hClientToken = NULL;
|
|
HANDLE hHandle = NULL;
|
|
ICertAdminD2 *pICertAdminD = NULL;
|
|
DWORD dwServerVersion = 0;
|
|
CERTTRANSBLOB ctbSD;
|
|
WCHAR const *pwszAuthority;
|
|
|
|
hHandle = GetCurrentThread();
|
|
if (NULL == hHandle)
|
|
{
|
|
hr = myHLastError();
|
|
}
|
|
else
|
|
{
|
|
if (!OpenThreadToken(hHandle,
|
|
TOKEN_QUERY,
|
|
TRUE, // open as self
|
|
&hClientToken))
|
|
{
|
|
hr = myHLastError();
|
|
CloseHandle(hHandle);
|
|
hHandle = NULL;
|
|
}
|
|
}
|
|
|
|
if(hr != S_OK)
|
|
{
|
|
hHandle = GetCurrentProcess();
|
|
if (NULL == hHandle)
|
|
{
|
|
hr = myHLastError();
|
|
}
|
|
else
|
|
{
|
|
HANDLE hProcessToken = NULL;
|
|
hr = S_OK;
|
|
|
|
if (!OpenProcessToken(hHandle,
|
|
TOKEN_DUPLICATE,
|
|
&hProcessToken))
|
|
{
|
|
hr = myHLastError();
|
|
CloseHandle(hHandle);
|
|
hHandle = NULL;
|
|
}
|
|
else
|
|
{
|
|
if(!DuplicateToken(hProcessToken,
|
|
SecurityImpersonation,
|
|
&hClientToken))
|
|
{
|
|
hr = myHLastError();
|
|
CloseHandle(hHandle);
|
|
hHandle = NULL;
|
|
}
|
|
CloseHandle(hProcessToken);
|
|
}
|
|
}
|
|
}
|
|
|
|
if(hr != S_OK)
|
|
{
|
|
goto error;
|
|
}
|
|
|
|
hr = myOpenAdminDComConnection(
|
|
m_pSvrCA->m_bstrConfig,
|
|
&pwszAuthority,
|
|
NULL,
|
|
&dwServerVersion,
|
|
&pICertAdminD);
|
|
_JumpIfError(hr, error, "myOpenAdminDComConnection");
|
|
|
|
if (2 > dwServerVersion)
|
|
{
|
|
hr = RPC_E_VERSION_MISMATCH;
|
|
_JumpError(hr, error, "old server");
|
|
}
|
|
|
|
__try
|
|
{
|
|
ctbSD.cb = GetSecurityDescriptorLength(pSD);
|
|
ctbSD.pb = (BYTE*)pSD;
|
|
hr = pICertAdminD->SetCASecurity(
|
|
pwszAuthority,
|
|
&ctbSD);
|
|
|
|
if(hr == HRESULT_FROM_WIN32(ERROR_CAN_NOT_COMPLETE))
|
|
{
|
|
// Attempt to fix enrollment object, see bug# 193388
|
|
m_pSvrCA->FixEnrollmentObject();
|
|
|
|
// try again
|
|
hr = pICertAdminD->SetCASecurity(
|
|
pwszAuthority,
|
|
&ctbSD);
|
|
}
|
|
}
|
|
__except(hr = myHEXCEPTIONCODE(), EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
}
|
|
_JumpIfError(hr, error, "pICertAdminD->SetCASecurity");
|
|
|
|
error:
|
|
myCloseDComConnection((IUnknown **) &pICertAdminD, NULL);
|
|
if(hClientToken)
|
|
{
|
|
CloseHandle(hClientToken);
|
|
}
|
|
if(hHandle)
|
|
{
|
|
CloseHandle(hHandle);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CCASecurityObject::SetSecurityRegistry(PSECURITY_DESCRIPTOR pSD)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
variant_t var;
|
|
CertSrv::CCertificateAuthoritySD CASD;
|
|
|
|
// SD passed in contains only a DACL. We need to fully construct the
|
|
// CA SD as certsrv would do
|
|
|
|
hr = CASD.InitializeFromTemplate(WSZ_EMPTY_CA_SECURITY, L"");
|
|
_JumpIfError(hr, error, "CCertificateAuthoritySD::Initialize");
|
|
|
|
hr = CASD.Set(pSD, false);
|
|
_JumpIfError(hr, error, "CCertificateAuthoritySD::Set");
|
|
|
|
hr = myRegValueToVariant(
|
|
REG_BINARY,
|
|
GetSecurityDescriptorLength(CASD.Get()),
|
|
(BYTE const*)CASD.Get(),
|
|
&var);
|
|
_JumpIfError(hr, error, "myRegValueToVariant");
|
|
|
|
hr = m_pSvrCA->SetConfigEntry(
|
|
NULL,
|
|
wszREGCASECURITY,
|
|
&var);
|
|
_JumpIfErrorStr(hr, error, "SetConfigEntry", wszREGCASECURITY);
|
|
|
|
// set status bit to signal certsrv to pick up changes next
|
|
// time it starts
|
|
hr = m_pSvrCA->GetConfigEntry(
|
|
NULL,
|
|
wszREGSETUPSTATUS,
|
|
&var);
|
|
_JumpIfErrorStr(hr, error, "GetConfigEntry", wszREGSETUPSTATUS);
|
|
|
|
V_I4(&var) |= SETUP_SECURITY_CHANGED;
|
|
|
|
hr = m_pSvrCA->SetConfigEntry(
|
|
NULL,
|
|
wszREGSETUPSTATUS,
|
|
&var);
|
|
_JumpIfErrorStr(hr, error, "SetConfigEntry", wszREGSETUPSTATUS);
|
|
|
|
error:
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP
|
|
CCASecurityObject::SetSecurity(SECURITY_INFORMATION si,
|
|
PSECURITY_DESCRIPTOR pSD)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
SECURITY_DESCRIPTOR_CONTROL Control = SE_DACL_PROTECTED;
|
|
DWORD dwSize;
|
|
DWORD dwRevision;
|
|
PSECURITY_DESCRIPTOR pSDSelfRel = NULL;
|
|
|
|
if (DACL_SECURITY_INFORMATION!=si)
|
|
return E_NOTIMPL;
|
|
|
|
if(si & DACL_SECURITY_INFORMATION)
|
|
{
|
|
if(GetSecurityDescriptorControl(pSD, &Control, &dwRevision))
|
|
{
|
|
Control &= SE_DACL_PROTECTED | SE_DACL_AUTO_INHERIT_REQ | SE_DACL_AUTO_INHERITED;
|
|
SetSecurityDescriptorControl(pSD,
|
|
SE_DACL_PROTECTED | SE_DACL_AUTO_INHERIT_REQ | SE_DACL_AUTO_INHERITED,
|
|
Control);
|
|
}
|
|
}
|
|
|
|
dwSize = GetSecurityDescriptorLength(pSD);
|
|
|
|
pSDSelfRel = (PSECURITY_DESCRIPTOR)LocalAlloc(LMEM_FIXED, dwSize);
|
|
if(NULL == pSDSelfRel)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
_JumpError(hr, error, "LocalAlloc");
|
|
}
|
|
|
|
if(!MakeSelfRelativeSD(pSD, pSDSelfRel, &dwSize))
|
|
{
|
|
LocalFree(pSDSelfRel);
|
|
pSDSelfRel = (PSECURITY_DESCRIPTOR)LocalAlloc(LMEM_FIXED, dwSize);
|
|
if(NULL == pSDSelfRel)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
_JumpError(hr, error, "LocalAlloc");
|
|
}
|
|
|
|
if(!MakeSelfRelativeSD(pSD, pSDSelfRel, &dwSize))
|
|
{
|
|
hr = myHLastError();
|
|
_JumpError(hr, error, "LocalAlloc");
|
|
}
|
|
}
|
|
|
|
hr = SetSecurityDCOM(pSDSelfRel);
|
|
if (S_OK != hr)
|
|
{
|
|
HRESULT hr2 = hr;
|
|
|
|
_PrintError(hr, "SetSecurityDCOM");
|
|
|
|
if (E_ACCESSDENIED == hr ||
|
|
(HRESULT) RPC_S_SERVER_UNAVAILABLE == hr ||
|
|
HRESULT_FROM_WIN32(RPC_S_SERVER_UNAVAILABLE) == hr)
|
|
{
|
|
|
|
hr2 = SetSecurityRegistry(pSDSelfRel);
|
|
_JumpIfError(hr2, error, "SetSecurityRegistry");
|
|
}
|
|
DisplayCertSrvErrorWithContext(NULL, hr, IDS_CANNOT_UPDATE_SECURITY_ON_CA);
|
|
if (S_OK == hr2)
|
|
{
|
|
hr = S_OK;
|
|
}
|
|
}
|
|
|
|
error:
|
|
|
|
if(NULL != pSDSelfRel)
|
|
{
|
|
LocalFree(pSDSelfRel);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP
|
|
CCASecurityObject::GetAccessRights(const GUID* /*pguidObjectType*/,
|
|
DWORD /*dwFlags*/,
|
|
PSI_ACCESS *ppAccesses,
|
|
ULONG *pcAccesses,
|
|
ULONG *piDefaultAccess)
|
|
{
|
|
*ppAccesses = g_siObjAccesses;
|
|
*pcAccesses = sizeof(g_siObjAccesses)/sizeof(g_siObjAccesses[0]);
|
|
*piDefaultAccess = g_iObjDefAccess;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP
|
|
CCASecurityObject::MapGeneric(const GUID* /*pguidObjectType*/,
|
|
UCHAR * /*pAceFlags*/,
|
|
ACCESS_MASK *pmask)
|
|
{
|
|
MapGenericMask(pmask, &ObjMap);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP
|
|
CCASecurityObject::GetInheritTypes(PSI_INHERIT_TYPE *ppInheritTypes,
|
|
ULONG *pcInheritTypes)
|
|
{
|
|
*ppInheritTypes = g_siObjInheritTypes;
|
|
*pcInheritTypes = sizeof(g_siObjInheritTypes)/sizeof(g_siObjInheritTypes[0]);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP
|
|
CCASecurityObject::PropertySheetPageCallback(HWND /*hwnd*/,
|
|
UINT /*uMsg*/,
|
|
SI_PAGE_TYPE /*uPage*/)
|
|
{
|
|
return S_OK;
|
|
}
|