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