2025-11-28 00:35:46 +09:00

374 lines
9.6 KiB
C++

/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
Copyright (C) 1997 - 2000. Microsoft Corporation. All rights reserved.
Module Name:
PrivObSI.CPP
Description:
This file contains the implementation of the CPrivSecurity class
--*/
#define UNICODE
#define _UNICODE
#include <aclui.h>
#include "resource.h"
#include "Main.h"
//
// from Main.cpp
//
extern HINSTANCE g_hInstance;
//
// defined in Security.cpp
//
extern GENERIC_MAPPING ObjMap;
HANDLE GetClientToken( WORD wIndex );
#define INHERIT_FULL (CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE)
//
// 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
//
// The following array defines the permission names for my objects.
//
SI_ACCESS g_siObjAccesses[] =
{
{ &GUID_NULL, ACCESS_READ, MAKEINTRESOURCE(IDS_PRIV_READ), SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC },
{ &GUID_NULL, ACCESS_MODIFY, MAKEINTRESOURCE(IDS_PRIV_MODIFY), SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC },
{ &GUID_NULL, ACCESS_DELETE, MAKEINTRESOURCE(IDS_PRIV_DELETE), SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC },
{ &GUID_NULL, ACCESS_ALL, MAKEINTRESOURCE(IDS_PRIV_ALL), SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC },
};
#define g_iObjDefAccess 1 // ACCESS_READ
// The following array defines the inheritance types for my containers.
SI_INHERIT_TYPE g_siObjInheritTypes[] =
{
&GUID_NULL, CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE, MAKEINTRESOURCE(IDS_INH_ALL),
&GUID_NULL, CONTAINER_INHERIT_ACE, MAKEINTRESOURCE(IDS_INH_CONTAINER),
&GUID_NULL, INHERIT_ONLY_ACE | OBJECT_INHERIT_ACE, MAKEINTRESOURCE(IDS_INH_OBJECT),
&GUID_NULL, 0, MAKEINTRESOURCE(IDS_INH_NONE),
};
HRESULT
LocalAllocString(LPWSTR* ppResult, LPCWSTR pString)
{
SIZE_T cch;
SIZE_T maxlen = 1024;
if (!ppResult || !pString)
return E_INVALIDARG;
cch = wcsnlen(pString, maxlen) + 1;
*ppResult = (LPWSTR)LocalAlloc(LPTR, cch * sizeof(WCHAR));
if (!*ppResult)
return E_OUTOFMEMORY;
wcscpy_s(*ppResult, cch, pString);
return S_OK;
}
void
LocalFreeString(LPWSTR* ppString)
{
if (ppString)
{
if (*ppString)
LocalFree(*ppString);
*ppString = NULL;
}
}
class CObjSecurity : public ISecurityInformation
{
protected:
ULONG m_cRef;
DWORD m_dwSIFlags;
PSECURITY_DESCRIPTOR *m_ppSD;
WORD m_wClient;
LPWSTR m_pszServerName;
LPWSTR m_pszObjectName;
public:
CObjSecurity() : m_cRef(1) {}
virtual ~CObjSecurity();
STDMETHOD(Initialize)(DWORD dwFlags,
PSECURITY_DESCRIPTOR *ppSD,
WORD wClient,
LPCWSTR pszServer,
BOOL fContainer);
// 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);
};
///////////////////////////////////////////////////////////////////////////////
//
// 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
CreateObjSecurityInfo(
DWORD dwFlags, // e.g. SI_EDIT_ALL | SI_ADVANCED | SI_CONTAINER
PSECURITY_DESCRIPTOR *ppSD, // Pointer to security descriptor
LPSECURITYINFO *ppObjSI,
WORD wClient, // Index for client token
LPCWSTR pszServerName, // Name of server on which SIDs will be resolved
BOOL fContainer) // This is the only way to name my generic objects
{
HRESULT hr;
CObjSecurity *psi;
*ppObjSI = NULL;
psi = new CObjSecurity();
if (!psi)
return E_OUTOFMEMORY;
hr = psi->Initialize(dwFlags, ppSD, wClient, pszServerName, fContainer);
if (SUCCEEDED(hr))
*ppObjSI = psi;
else
delete psi;
return hr;
}
CObjSecurity::~CObjSecurity()
{
LocalFreeString(&m_pszServerName);
LocalFreeString(&m_pszObjectName);
}
STDMETHODIMP
CObjSecurity::Initialize(DWORD dwFlags,
PSECURITY_DESCRIPTOR *ppSD,
WORD wClient,
LPCWSTR pszServer,
BOOL fContainer)
{
HRESULT hr;
m_dwSIFlags = dwFlags;
if(fContainer)
m_dwSIFlags |= SI_CONTAINER;
m_ppSD = ppSD;
m_wClient = wClient;
hr = LocalAllocString(&m_pszServerName, pszServer);
if(SUCCEEDED(hr))
{
if(fContainer)
hr = LocalAllocString(&m_pszObjectName,L"Container");
else
hr = LocalAllocString(&m_pszObjectName,L"Object");
}
return hr;
}
///////////////////////////////////////////////////////////
//
// IUnknown methods
//
///////////////////////////////////////////////////////////
STDMETHODIMP_(ULONG)
CObjSecurity::AddRef()
{
return ++m_cRef;
}
STDMETHODIMP_(ULONG)
CObjSecurity::Release()
{
if (--m_cRef == 0)
{
delete this;
return 0;
}
return m_cRef;
}
STDMETHODIMP
CObjSecurity::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
CObjSecurity::GetObjectInformation(PSI_OBJECT_INFO pObjectInfo)
{
pObjectInfo->dwFlags = m_dwSIFlags;
pObjectInfo->hInstance = g_hInstance;
pObjectInfo->pszServerName = m_pszServerName;
pObjectInfo->pszObjectName = m_pszObjectName;
return S_OK;
}
STDMETHODIMP
CObjSecurity::GetSecurity(SECURITY_INFORMATION si,
PSECURITY_DESCRIPTOR *ppSD,
BOOL fDefault)
{
DWORD dwLength = 0;
DWORD dwErr = 0;
*ppSD = NULL;
if (fDefault)
return E_NOTIMPL;
//
// Assume that required privileges have already been enabled
//
GetPrivateObjectSecurity(*m_ppSD, si, NULL, 0, &dwLength);
if (dwLength)
{
*ppSD = LocalAlloc(LPTR, dwLength);
if (*ppSD &&
!GetPrivateObjectSecurity(*m_ppSD, si, *ppSD, dwLength, &dwLength))
{
dwErr = GetLastError();
LocalFree(*ppSD);
*ppSD = NULL;
}
}
else
dwErr = GetLastError();
return HRESULT_FROM_WIN32(dwErr);
}
STDMETHODIMP
CObjSecurity::SetSecurity(SECURITY_INFORMATION si,
PSECURITY_DESCRIPTOR pSD)
{
DWORD dwErr = 0;
//
// Assume that required privileges have already been enabled
//
if (!SetPrivateObjectSecurity(si, pSD, m_ppSD, &ObjMap, GetClientToken(m_wClient)))
dwErr = GetLastError();
return HRESULT_FROM_WIN32(dwErr);
}
STDMETHODIMP
CObjSecurity::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
CObjSecurity::MapGeneric(const GUID* /*pguidObjectType*/,
UCHAR * /*pAceFlags*/,
ACCESS_MASK *pmask)
{
MapGenericMask(pmask, &ObjMap);
return S_OK;
}
STDMETHODIMP
CObjSecurity::GetInheritTypes(PSI_INHERIT_TYPE *ppInheritTypes,
ULONG *pcInheritTypes)
{
*ppInheritTypes = g_siObjInheritTypes;
*pcInheritTypes = sizeof(g_siObjInheritTypes)/sizeof(g_siObjInheritTypes[0]);
return S_OK;
}
STDMETHODIMP
CObjSecurity::PropertySheetPageCallback(HWND /*hwnd*/,
UINT /*uMsg*/,
SI_PAGE_TYPE /*uPage*/)
{
return S_OK;
}