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.
491 lines
11 KiB
491 lines
11 KiB
//+-------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
//
|
|
// Copyright (C) Microsoft Corporation, 1996 - 1999
|
|
//
|
|
// File: si.cpp
|
|
//
|
|
// This file contains the implementation of the CSecurityInformation
|
|
// base class.
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
#include "si.h"
|
|
|
|
#include <wmistr.h>
|
|
|
|
CSecurityInformation::CSecurityInformation()
|
|
: m_cRef(1), m_pszObjectName(NULL)
|
|
{
|
|
|
|
}
|
|
|
|
CSecurityInformation::~CSecurityInformation()
|
|
{
|
|
}
|
|
|
|
STDMETHODIMP
|
|
CSecurityInformation::Initialize(LPTSTR pszObject,
|
|
LPGUID Guid)
|
|
{
|
|
m_pszObjectName = pszObject;
|
|
m_guid = *Guid;
|
|
|
|
|
|
return(S_OK);
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////
|
|
//
|
|
// IUnknown methods
|
|
//
|
|
///////////////////////////////////////////////////////////
|
|
|
|
STDMETHODIMP_(ULONG)
|
|
CSecurityInformation::AddRef()
|
|
{
|
|
return ++m_cRef;
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG)
|
|
CSecurityInformation::Release()
|
|
{
|
|
if (--m_cRef == 0)
|
|
{
|
|
delete this;
|
|
return 0;
|
|
}
|
|
|
|
return m_cRef;
|
|
}
|
|
|
|
STDMETHODIMP
|
|
CSecurityInformation::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
|
|
//
|
|
///////////////////////////////////////////////////////////
|
|
|
|
ULONG DiscpAnsiToUnicodeSize(
|
|
IN LPCSTR AnsiString,
|
|
OUT ULONG *UnicodeSizeInChar
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine will return the length needed to represent the ANSI
|
|
string as unicode
|
|
|
|
Arguments:
|
|
|
|
AnsiString is the ansi string whose unicode length is returned
|
|
|
|
*UnicodeSizeInChar is number of chars needed to represent ansi
|
|
string as unicode
|
|
|
|
Return Value:
|
|
|
|
ERROR_SUCCESS or error code
|
|
|
|
--*/
|
|
{
|
|
*UnicodeSizeInChar = MultiByteToWideChar(CP_ACP,
|
|
0,
|
|
AnsiString,
|
|
-1,
|
|
NULL,
|
|
0);
|
|
|
|
return((*UnicodeSizeInChar == 0) ? GetLastError() : ERROR_SUCCESS);
|
|
}
|
|
|
|
|
|
ULONG DiscpAnsiToUnicode(
|
|
IN LPSTR pszA,
|
|
OUT LPWSTR *ppszW,
|
|
IN ULONG MaxLen
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Convert Ansi string into its Unicode equivalent
|
|
|
|
Arguments:
|
|
|
|
pszA is ansi string to convert
|
|
|
|
*ppszW on entry has pointer to buffer to write converted string or
|
|
NULL is converted string is to be dynamically allocated
|
|
|
|
Return Value:
|
|
|
|
Error code
|
|
|
|
--*/
|
|
{
|
|
ULONG cCharacters;
|
|
ULONG cbUnicodeUsed;
|
|
ULONG Status;
|
|
BOOLEAN AllocMemory;
|
|
PWCHAR u;
|
|
|
|
//
|
|
// If input is null then just return the same.
|
|
//
|
|
if (pszA == NULL)
|
|
{
|
|
*ppszW = NULL;
|
|
Status = ERROR_SUCCESS;
|
|
} else {
|
|
if (*ppszW == NULL)
|
|
{
|
|
Status = DiscpAnsiToUnicodeSize(pszA, &MaxLen);
|
|
if (Status == ERROR_SUCCESS)
|
|
{
|
|
*ppszW = (PWCHAR)LocalAlloc(LPTR, MaxLen * sizeof(WCHAR));
|
|
if (*ppszW == NULL)
|
|
{
|
|
Status = ERROR_NOT_ENOUGH_MEMORY;
|
|
} else {
|
|
AllocMemory = TRUE;
|
|
}
|
|
}
|
|
} else {
|
|
Status = ERROR_SUCCESS;
|
|
AllocMemory = FALSE;
|
|
}
|
|
|
|
if (Status == ERROR_SUCCESS)
|
|
{
|
|
//
|
|
// Convert to Unicode
|
|
//
|
|
cbUnicodeUsed = MultiByteToWideChar(CP_ACP,
|
|
0,
|
|
pszA,
|
|
-1,
|
|
*ppszW,
|
|
MaxLen);
|
|
|
|
if (0 == cbUnicodeUsed)
|
|
{
|
|
Status = GetLastError();
|
|
if (AllocMemory)
|
|
{
|
|
LocalFree(*ppszW);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return(Status);
|
|
|
|
}
|
|
|
|
STDMETHODIMP
|
|
CSecurityInformation::GetObjectInformation(PSI_OBJECT_INFO pObjectInfo)
|
|
{
|
|
PWCHAR u;
|
|
|
|
pObjectInfo->dwFlags = SI_EDIT_PERMS | SI_ADVANCED | SI_EDIT_AUDITS;
|
|
pObjectInfo->hInstance = NULL;
|
|
pObjectInfo->pszServerName = NULL;
|
|
u = NULL;
|
|
DiscpAnsiToUnicode(m_pszObjectName,
|
|
&u,
|
|
0);
|
|
pObjectInfo->pszObjectName = u;
|
|
|
|
return(S_OK);
|
|
}
|
|
|
|
STDMETHODIMP
|
|
CSecurityInformation::GetSecurity(SECURITY_INFORMATION si,
|
|
PSECURITY_DESCRIPTOR *ppSD,
|
|
BOOL fDefault)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
*ppSD = NULL;
|
|
|
|
hr = ReadObjectSecurity(m_pszObjectName, si, ppSD);
|
|
|
|
return(hr);
|
|
}
|
|
|
|
STDMETHODIMP
|
|
CSecurityInformation::SetSecurity(SECURITY_INFORMATION si,
|
|
PSECURITY_DESCRIPTOR pSD)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
hr = WriteObjectSecurity(m_pszObjectName, si, pSD);
|
|
|
|
return(hr);
|
|
}
|
|
|
|
STDMETHODIMP
|
|
CSecurityInformation::PropertySheetPageCallback(HWND hwnd,
|
|
UINT uMsg,
|
|
SI_PAGE_TYPE uPage)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
STDMETHODIMP
|
|
CSecurityInformation::ReadObjectSecurity(LPCTSTR pszObject,
|
|
SECURITY_INFORMATION si,
|
|
PSECURITY_DESCRIPTOR *ppSD)
|
|
{
|
|
DWORD dwErr;
|
|
|
|
dwErr = GetWmiGuidSecurityInfo(&m_guid,
|
|
si,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
ppSD);
|
|
|
|
return(HRESULT_FROM_WIN32(dwErr));
|
|
}
|
|
|
|
|
|
STDMETHODIMP
|
|
CSecurityInformation::WriteObjectSecurity(LPCTSTR pszObject,
|
|
SECURITY_INFORMATION si,
|
|
PSECURITY_DESCRIPTOR pSD)
|
|
{
|
|
DWORD dwErr;
|
|
SECURITY_DESCRIPTOR_CONTROL wSDControl = 0;
|
|
DWORD dwRevision;
|
|
PSID psidOwner = NULL;
|
|
PSID psidGroup = NULL;
|
|
PACL pDacl = NULL;
|
|
PACL pSacl = NULL;
|
|
BOOL bDefaulted;
|
|
BOOL bPresent;
|
|
|
|
//
|
|
// Get pointers to various security descriptor parts for
|
|
// calling SetNamedSecurityInfo
|
|
//
|
|
GetSecurityDescriptorControl(pSD, &wSDControl, &dwRevision);
|
|
GetSecurityDescriptorOwner(pSD, &psidOwner, &bDefaulted);
|
|
GetSecurityDescriptorGroup(pSD, &psidGroup, &bDefaulted);
|
|
GetSecurityDescriptorDacl(pSD, &bPresent, &pDacl, &bDefaulted);
|
|
GetSecurityDescriptorSacl(pSD, &bPresent, &pSacl, &bDefaulted);
|
|
|
|
if (si & DACL_SECURITY_INFORMATION)
|
|
{
|
|
if (wSDControl & SE_DACL_PROTECTED)
|
|
si |= PROTECTED_DACL_SECURITY_INFORMATION;
|
|
else
|
|
si |= UNPROTECTED_DACL_SECURITY_INFORMATION;
|
|
}
|
|
if (si & SACL_SECURITY_INFORMATION)
|
|
{
|
|
if (wSDControl & SE_SACL_PROTECTED)
|
|
si |= PROTECTED_SACL_SECURITY_INFORMATION;
|
|
else
|
|
si |= UNPROTECTED_SACL_SECURITY_INFORMATION;
|
|
}
|
|
|
|
dwErr = SetWmiGuidSecurityInfo(&m_guid,
|
|
si,
|
|
psidOwner,
|
|
psidGroup,
|
|
pDacl,
|
|
pSacl);
|
|
return(HRESULT_FROM_WIN32(dwErr));
|
|
}
|
|
|
|
GUID GuidNull = {0, 0, 0, 0, 0, 0x0, 0, 0, 0, 0, 0};
|
|
|
|
|
|
SI_ACCESS SIAccess[] =
|
|
{
|
|
{
|
|
&GuidNull,
|
|
WMIGUID_QUERY,
|
|
L"Query",
|
|
SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC
|
|
},
|
|
|
|
{
|
|
&GuidNull,
|
|
WMIGUID_SET,
|
|
L"Set",
|
|
SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC
|
|
},
|
|
|
|
{
|
|
&GuidNull,
|
|
WMIGUID_EXECUTE,
|
|
L"Execute Method",
|
|
SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC
|
|
},
|
|
|
|
{
|
|
&GuidNull,
|
|
WMIGUID_NOTIFICATION,
|
|
L"Receive Notification",
|
|
SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC
|
|
},
|
|
|
|
{
|
|
&GuidNull,
|
|
SYNCHRONIZE,
|
|
L"Synchronize",
|
|
SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC
|
|
},
|
|
|
|
{
|
|
&GuidNull,
|
|
TRACELOG_CREATE_REALTIME,
|
|
L"TRACELOG_CREATE_REALTIME",
|
|
SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC
|
|
},
|
|
|
|
{
|
|
&GuidNull,
|
|
TRACELOG_CREATE_ONDISK,
|
|
L"TRACELOG_CREATE_ONDISK",
|
|
SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC
|
|
},
|
|
|
|
{
|
|
&GuidNull,
|
|
TRACELOG_GUID_ENABLE,
|
|
L"TRACELOG_GUID_ENABLE",
|
|
SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC
|
|
},
|
|
|
|
{
|
|
&GuidNull,
|
|
TRACELOG_ACCESS_KERNEL_LOGGER,
|
|
L"TRACELOG_ACCESS_KERNEL_LOGGER",
|
|
SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC
|
|
},
|
|
|
|
{
|
|
&GuidNull,
|
|
TRACELOG_CREATE_INPROC,
|
|
L"TRACELOG_CREATE_INPROC",
|
|
SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC
|
|
},
|
|
|
|
{
|
|
&GuidNull,
|
|
TRACELOG_ACCESS_REALTIME,
|
|
L"TRACELOG_ACCESS_REALTIME",
|
|
SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC
|
|
},
|
|
|
|
{
|
|
&GuidNull,
|
|
TRACELOG_REGISTER_GUIDS,
|
|
L"TRACELOG_REGISTER_GUIDS",
|
|
SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC
|
|
},
|
|
|
|
{
|
|
&GuidNull,
|
|
WRITE_DAC,
|
|
L"WRITE_DAC",
|
|
SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC
|
|
},
|
|
|
|
{
|
|
&GuidNull,
|
|
DELETE,
|
|
L"DELETE",
|
|
SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC
|
|
},
|
|
|
|
|
|
|
|
};
|
|
|
|
#define SIAccessCount ( sizeof(SIAccess) / sizeof(SI_ACCESS) )
|
|
|
|
STDMETHODIMP
|
|
CSecurityInformation::GetAccessRights(const GUID* pguidObjectType,
|
|
DWORD dwFlags,
|
|
PSI_ACCESS *ppAccess,
|
|
ULONG *pcAccesses,
|
|
ULONG *piDefaultAccess)
|
|
{
|
|
*ppAccess = SIAccess;
|
|
*pcAccesses = SIAccessCount;
|
|
*piDefaultAccess = 0;
|
|
return(S_OK);
|
|
}
|
|
|
|
GENERIC_MAPPING GenericMapping =
|
|
{
|
|
// GENERIC_READ <--> WMIGUID_QUERY
|
|
WMIGUID_QUERY,
|
|
// GENERIC_WRUTE <--> WMIGUID_SET
|
|
WMIGUID_SET,
|
|
// GENERIC_EXECUTE <--> WMIGUID_EXECUTE
|
|
WMIGUID_EXECUTE,
|
|
// GENERIC_ALL <--> WMIGUID_ALL_ACCESS
|
|
WMIGUID_ALL_ACCESS
|
|
};
|
|
|
|
STDMETHODIMP
|
|
CSecurityInformation::MapGeneric(const GUID *pguidObjectType,
|
|
UCHAR *pAceFlags,
|
|
ACCESS_MASK *pmask)
|
|
{
|
|
MapGenericMask(pmask, &GenericMapping);
|
|
return(S_OK);
|
|
}
|
|
|
|
STDMETHODIMP
|
|
CSecurityInformation::GetInheritTypes(PSI_INHERIT_TYPE *ppInheritTypes,
|
|
ULONG *pcInheritTypes)
|
|
{
|
|
*ppInheritTypes = NULL;
|
|
*pcInheritTypes = 0;
|
|
return(S_OK);
|
|
}
|
|
|
|
|
|
void EditGuidSecurity(
|
|
LPTSTR GuidString,
|
|
LPGUID Guid
|
|
)
|
|
{
|
|
CSecurityInformation *pSec;
|
|
|
|
pSec = new CSecurityInformation();
|
|
|
|
pSec->Initialize(GuidString,
|
|
Guid);
|
|
|
|
EditSecurity(NULL,
|
|
pSec);
|
|
}
|