Leaked source code of windows server 2003
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

//+-------------------------------------------------------------------------
//
// 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);
}