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.
333 lines
9.9 KiB
333 lines
9.9 KiB
// PermPage.cxx : Implementation ACL Editor classes
|
|
// jonn 7/10/97 copied from \nt\private\admin\snapin\filemgmt\permpage.cpp
|
|
|
|
#include "headers.hxx"
|
|
#pragma hdrstop
|
|
|
|
#include "acl.hxx"
|
|
#include "resource.h" // IDS_SHAREPERM_*
|
|
#include "util.hxx" // CopySecurityDescriptor
|
|
|
|
// need IID_ISecurityInformation
|
|
#define INITGUID
|
|
#include <initguid.h>
|
|
#include <aclui.h>
|
|
|
|
//
|
|
// I define my own implementation of ISecurityInformation
|
|
//
|
|
|
|
class CSecurityInformation : public ISecurityInformation
|
|
{
|
|
public:
|
|
// IUnknown
|
|
STDMETHOD(QueryInterface)(REFIID riid, void **ppv);
|
|
STDMETHOD_(ULONG, AddRef)();
|
|
STDMETHOD_(ULONG, Release)();
|
|
|
|
// *** ISecurityInformation methods ***
|
|
STDMETHOD(GetObjectInformation) (PSI_OBJECT_INFO pObjectInfo ) = 0;
|
|
STDMETHOD(GetSecurity) (SECURITY_INFORMATION RequestedInformation,
|
|
PSECURITY_DESCRIPTOR *ppSecurityDescriptor,
|
|
BOOL fDefault ) = 0;
|
|
STDMETHOD(SetSecurity) (SECURITY_INFORMATION SecurityInformation,
|
|
PSECURITY_DESCRIPTOR pSecurityDescriptor ) = 0;
|
|
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 );
|
|
|
|
CSecurityInformation() : _cRef(1) {}
|
|
|
|
private:
|
|
LONG _cRef;
|
|
};
|
|
|
|
class CShareSecurityInformation : public CSecurityInformation
|
|
{
|
|
private:
|
|
LPCWSTR m_strMachineName;
|
|
LPCWSTR m_strShareName;
|
|
WCHAR m_szTitle[200];
|
|
public:
|
|
CShareSecurityInformation(LPCWSTR pszMachineName, LPCWSTR pszShareName)
|
|
: m_strMachineName(pszMachineName), m_strShareName(pszShareName)
|
|
{
|
|
LoadString( g_hInstance, IDS_PERMPAGE_TITLE, m_szTitle, ARRAYLEN(m_szTitle) );
|
|
}
|
|
LPCWSTR QueryMachineName()
|
|
{
|
|
return m_strMachineName;
|
|
}
|
|
LPCWSTR QueryShareName()
|
|
{
|
|
return m_strShareName;
|
|
}
|
|
|
|
// *** ISecurityInformation methods ***
|
|
STDMETHOD(GetObjectInformation) (PSI_OBJECT_INFO pObjectInfo );
|
|
};
|
|
|
|
class CSMBSecurityInformation : public CShareSecurityInformation
|
|
{
|
|
STDMETHOD(GetSecurity) (SECURITY_INFORMATION RequestedInformation,
|
|
PSECURITY_DESCRIPTOR *ppSecurityDescriptor,
|
|
BOOL fDefault );
|
|
STDMETHOD(SetSecurity) (SECURITY_INFORMATION SecurityInformation,
|
|
PSECURITY_DESCRIPTOR pSecurityDescriptor );
|
|
public:
|
|
PSECURITY_DESCRIPTOR m_pInitialDescriptor;
|
|
PSECURITY_DESCRIPTOR* m_ppCurrentDescriptor;
|
|
CSMBSecurityInformation(LPCWSTR pszMachineName, LPCWSTR pszShareName, PSECURITY_DESCRIPTOR pSDOriginal, PSECURITY_DESCRIPTOR *ppSDResult);
|
|
~CSMBSecurityInformation();
|
|
};
|
|
|
|
|
|
// IUnknown implementation
|
|
|
|
STDMETHODIMP CSecurityInformation::QueryInterface(REFIID riid, void **ppv)
|
|
{
|
|
static const QITAB qit[] =
|
|
{
|
|
QITABENT(CSecurityInformation, ISecurityInformation),
|
|
{ 0 },
|
|
};
|
|
return QISearch(this, qit, riid, ppv);
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG) CSecurityInformation::AddRef()
|
|
{
|
|
return InterlockedIncrement(&_cRef);
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG) CSecurityInformation::Release()
|
|
{
|
|
appAssert(0 != _cRef);
|
|
ULONG cRef = InterlockedDecrement(&_cRef);
|
|
if (0 == cRef)
|
|
{
|
|
delete this;
|
|
}
|
|
return cRef;
|
|
}
|
|
|
|
// ISecurityInformation interface implementation
|
|
|
|
SI_ACCESS siShareAccesses[] =
|
|
{
|
|
{ &GUID_NULL,
|
|
FILE_ALL_ACCESS,
|
|
MAKEINTRESOURCE(IDS_SHAREPERM_ALL),
|
|
SI_ACCESS_GENERAL },
|
|
{ &GUID_NULL,
|
|
FILE_GENERIC_READ | FILE_EXECUTE | FILE_GENERIC_WRITE | DELETE,
|
|
MAKEINTRESOURCE(IDS_SHAREPERM_MODIFY),
|
|
SI_ACCESS_GENERAL },
|
|
{ &GUID_NULL,
|
|
FILE_GENERIC_READ | FILE_EXECUTE,
|
|
MAKEINTRESOURCE(IDS_SHAREPERM_READ),
|
|
SI_ACCESS_GENERAL }
|
|
};
|
|
#define iShareDefAccess 2 // FILE_GEN_READ
|
|
|
|
STDMETHODIMP CSecurityInformation::GetAccessRights (
|
|
const GUID* /*pguidObjectType*/,
|
|
DWORD /*dwFlags*/,
|
|
PSI_ACCESS *ppAccess,
|
|
ULONG *pcAccesses,
|
|
ULONG *piDefaultAccess )
|
|
{
|
|
appAssert(ppAccess != NULL);
|
|
appAssert(pcAccesses != NULL);
|
|
appAssert(piDefaultAccess != NULL);
|
|
|
|
*ppAccess = siShareAccesses;
|
|
*pcAccesses = ARRAYLEN(siShareAccesses);
|
|
*piDefaultAccess = iShareDefAccess;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
// This is consistent with the NETUI code
|
|
GENERIC_MAPPING ShareMap =
|
|
{
|
|
FILE_GENERIC_READ,
|
|
FILE_GENERIC_WRITE,
|
|
FILE_GENERIC_EXECUTE,
|
|
FILE_ALL_ACCESS
|
|
};
|
|
|
|
STDMETHODIMP CSecurityInformation::MapGeneric (
|
|
const GUID* /*pguidObjectType*/,
|
|
UCHAR* /*pAceFlags*/,
|
|
ACCESS_MASK *pMask)
|
|
{
|
|
appAssert(pMask != NULL);
|
|
|
|
MapGenericMask(pMask, &ShareMap);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CSecurityInformation::GetInheritTypes (
|
|
PSI_INHERIT_TYPE* /*ppInheritTypes*/,
|
|
ULONG* /*pcInheritTypes*/ )
|
|
{
|
|
appAssert(FALSE);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP CSecurityInformation::PropertySheetPageCallback(HWND /*hwnd*/, UINT /*uMsg*/, SI_PAGE_TYPE /*uPage*/)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
/*
|
|
JeffreyS 1/24/97:
|
|
If you don't set the SI_RESET flag in
|
|
ISecurityInformation::GetObjectInformation, then fDefault should never be TRUE
|
|
so you can ignore it. Returning E_NOTIMPL in this case is OK too.
|
|
|
|
If you want the user to be able to reset the ACL to some default state
|
|
(defined by you) then turn on SI_RESET and return your default ACL
|
|
when fDefault is TRUE. This happens if/when the user pushes a button
|
|
that is only visible when SI_RESET is on.
|
|
*/
|
|
STDMETHODIMP CShareSecurityInformation::GetObjectInformation (
|
|
PSI_OBJECT_INFO pObjectInfo )
|
|
{
|
|
if (NULL == pObjectInfo)
|
|
return E_POINTER;
|
|
|
|
pObjectInfo->dwFlags = SI_EDIT_PERMS | SI_NO_ACL_PROTECT | SI_PAGE_TITLE;
|
|
pObjectInfo->hInstance = g_hInstance;
|
|
pObjectInfo->pszServerName = (LPWSTR)QueryMachineName();
|
|
pObjectInfo->pszObjectName = (LPWSTR)QueryShareName();
|
|
|
|
// page title added JonN 3/8/99 per 115196
|
|
pObjectInfo->pszPageTitle = m_szTitle;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
CSMBSecurityInformation::CSMBSecurityInformation(
|
|
LPCWSTR pszMachineName, LPCWSTR pszShareName,
|
|
PSECURITY_DESCRIPTOR pSDOriginal, PSECURITY_DESCRIPTOR *ppSDResult
|
|
)
|
|
: CShareSecurityInformation(pszMachineName, pszShareName)
|
|
, m_pInitialDescriptor( pSDOriginal )
|
|
, m_ppCurrentDescriptor( ppSDResult )
|
|
{
|
|
}
|
|
|
|
CSMBSecurityInformation::~CSMBSecurityInformation()
|
|
{
|
|
}
|
|
|
|
STDMETHODIMP CSMBSecurityInformation::GetSecurity (
|
|
SECURITY_INFORMATION RequestedInformation,
|
|
PSECURITY_DESCRIPTOR *ppSecurityDescriptor,
|
|
BOOL fDefault )
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
if (NULL == ppSecurityDescriptor)
|
|
return E_POINTER;
|
|
|
|
*ppSecurityDescriptor = NULL;
|
|
|
|
if (0 == RequestedInformation )
|
|
return E_INVALIDARG;
|
|
|
|
if (fDefault)
|
|
return E_NOTIMPL;
|
|
|
|
appAssert( NULL != m_ppCurrentDescriptor );
|
|
if (NULL != *m_ppCurrentDescriptor)
|
|
{
|
|
hr = CopySecurityDescriptor(*m_ppCurrentDescriptor, ppSecurityDescriptor);
|
|
}
|
|
else if (NULL != m_pInitialDescriptor)
|
|
{
|
|
hr = CopySecurityDescriptor(m_pInitialDescriptor, ppSecurityDescriptor);
|
|
}
|
|
else
|
|
{
|
|
// Ok to return NULL for "no security". Aclui will interpret
|
|
// this as "Everyone: Full Control".
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CSMBSecurityInformation::SetSecurity (
|
|
SECURITY_INFORMATION /*SecurityInformation*/,
|
|
PSECURITY_DESCRIPTOR pSecurityDescriptor )
|
|
{
|
|
PSECURITY_DESCRIPTOR psdTemp;
|
|
HRESULT hr = CopySecurityDescriptor(pSecurityDescriptor, &psdTemp);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
appAssert( NULL != m_ppCurrentDescriptor );
|
|
::LocalFree(*m_ppCurrentDescriptor);
|
|
*m_ppCurrentDescriptor = psdTemp;
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
HMODULE g_hlibACLUI = NULL;
|
|
typedef BOOL (*EDIT_SECURITY_PROC) ( HWND, LPSECURITYINFO );
|
|
EDIT_SECURITY_PROC g_pfnEditSecurityProc;
|
|
|
|
LONG
|
|
EditShareAcl(
|
|
IN HWND hwndParent,
|
|
IN LPCWSTR pszServerName,
|
|
IN LPCWSTR pszShareName,
|
|
IN PSECURITY_DESCRIPTOR pSecDesc,
|
|
OUT BOOL* pfSecDescModified,
|
|
OUT PSECURITY_DESCRIPTOR* ppSecDesc
|
|
)
|
|
{
|
|
appAssert( ppSecDesc != NULL );
|
|
*ppSecDesc = NULL;
|
|
|
|
if (NULL == g_hlibACLUI)
|
|
{
|
|
g_hlibACLUI = ::LoadLibrary(L"ACLUI.DLL");
|
|
if (NULL == g_hlibACLUI)
|
|
{
|
|
appAssert(FALSE); // ACLUI.DLL isn't installed?
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
if (NULL == g_pfnEditSecurityProc)
|
|
{
|
|
g_pfnEditSecurityProc = reinterpret_cast<EDIT_SECURITY_PROC>(::GetProcAddress(g_hlibACLUI,"EditSecurity"));
|
|
if (NULL == g_pfnEditSecurityProc)
|
|
{
|
|
appAssert(FALSE); // ACLUI.DLL is invalid?
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
CSMBSecurityInformation* psecinfo = new CSMBSecurityInformation(pszServerName, pszShareName, pSecDesc, ppSecDesc);
|
|
if (NULL == psecinfo)
|
|
return 0;
|
|
|
|
(g_pfnEditSecurityProc)(hwndParent,psecinfo);
|
|
|
|
if (NULL != pfSecDescModified)
|
|
*pfSecDescModified = (NULL != *ppSecDesc);
|
|
|
|
psecinfo->Release();
|
|
|
|
return 0;
|
|
}
|