WindowsXP/admin/wmi/wbem/shell/atlui/logdrive/fakesecuritysetting.cpp
2025-04-27 07:49:33 -04:00

479 lines
12 KiB
C++

// Copyright (c) 1997-1999 Microsoft Corporation
//
// FakeSecSetting.cpp
//
/////////////////////////////////////////////////
#include "precomp.h"
#include "FakeSecuritySetting.h"
//--------------------------------------------------------------------------
FakeSecuritySetting::FakeSecuritySetting()
{
}
//--------------------------------------------------------------------------
FakeSecuritySetting::~FakeSecuritySetting()
{
}
//--------------------------------------------------------------------------
HRESULT FakeSecuritySetting::Wbem2SD(SECURITY_INFORMATION si,
CWbemClassObject &w32sd,
CWbemServices &service,
SECURITY_DESCRIPTOR **ppSD)
{
HRESULT hr = WBEM_S_NO_ERROR;
// converts the security descriptor from the file into a
// Win32_Security object.
if(si)
{
m_service = service;
SECURITY_DESCRIPTOR absSD;
bool present;
BOOL x = InitializeSecurityDescriptor(&absSD, SECURITY_DESCRIPTOR_REVISION);
DWORD e = GetLastError();
// strict copy for ControlFlags.
if(si & OWNER_SECURITY_INFORMATION)
{
CWbemClassObject pTrusteeOwner;
PSID sidOwner = NULL;
pTrusteeOwner = w32sd.GetEmbeddedObject("Owner");
if(pTrusteeOwner)
{
DWORD sidLen = Wbem2Sid(pTrusteeOwner, sidOwner);
if(sidLen != 0)
{
sidOwner = LocalAlloc(LPTR, sidLen);
if(sidOwner)
{
Wbem2Sid(pTrusteeOwner, sidOwner);
SetSecurityDescriptorOwner(&absSD, sidOwner, FALSE);
}
}
}
}
if(si & GROUP_SECURITY_INFORMATION)
{
CWbemClassObject pTrusteeGroup;
PSID sidGroup = NULL;
pTrusteeGroup = w32sd.GetEmbeddedObject("Group");
if(pTrusteeGroup)
{
DWORD sidLen = Wbem2Sid(pTrusteeGroup, sidGroup);
if(sidLen != 0)
{
sidGroup = LocalAlloc(LPTR, sidLen);
if(sidGroup)
{
Wbem2Sid(pTrusteeGroup, sidGroup);
SetSecurityDescriptorGroup(&absSD, sidGroup, FALSE);
}
}
}
else
{
CWbemClassObject pTrusteeOwner;
PSID sidOwner = NULL;
pTrusteeOwner = w32sd.GetEmbeddedObject("Owner");
if(pTrusteeOwner)
{
DWORD sidLen = Wbem2Sid(pTrusteeOwner, sidOwner);
if(sidLen != 0)
{
sidOwner = LocalAlloc(LPTR, sidLen);
if(sidOwner)
{
Wbem2Sid(pTrusteeOwner, sidOwner);
SetSecurityDescriptorGroup(&absSD, sidOwner, FALSE);
}
}
}
}
}
if(si & DACL_SECURITY_INFORMATION)
{
variant_t pDacl;
PACL dacl = 0;
w32sd.Get("DACL", pDacl);
//if(pDacl.vt != VT_NULL)
{
present = Wbem2ACL(pDacl, &dacl);
SetSecurityDescriptorDacl(&absSD, present, dacl, false);
}
}
if(si & SACL_SECURITY_INFORMATION)
{
variant_t pSacl;
PACL sacl = 0;
w32sd.Get("SACL", pSacl);
// if(pSacl.vt != VT_NULL)
{
present = Wbem2ACL(pSacl, &sacl);
SetSecurityDescriptorSacl(&absSD, present, sacl, false);
}
}
variant_t ControlFlags;
w32sd.Get("ControlFlags", ControlFlags);
SECURITY_DESCRIPTOR_CONTROL control = (SECURITY_DESCRIPTOR_CONTROL)V_I4(&ControlFlags);
// provider sets flag like its self-relative when it actually doesnt apply; but it
// messes up this code. So clear it.
control &= ~SE_SELF_RELATIVE;
SetSecDescCtrl(&absSD, 0xFFFF, control);
DWORD srLen = 0;
SetLastError(0);
// get the size needed.
BOOL x1 = MakeSelfRelativeSD(&absSD, NULL, &srLen);
DWORD eee = GetLastError();
*ppSD = (SECURITY_DESCRIPTOR *)LocalAlloc(LPTR, srLen);
if(ppSD)
{
BOOL converted = MakeSelfRelativeSD(&absSD, *ppSD, &srLen);
hr = S_OK;
}
else
{
hr = E_OUTOFMEMORY;
return hr;
}
} //endif (si)
return hr;
}
//---------------------------------------------------------------------------
// NT4 SP4 doesn't support SetSecurityDescriptorControl, so
// emulate it here
//
DWORD FakeSecuritySetting::SetSecDescCtrl(PSECURITY_DESCRIPTOR psd,
SECURITY_DESCRIPTOR_CONTROL wControlMask,
SECURITY_DESCRIPTOR_CONTROL wControlBits)
{
DWORD dwErr = NOERROR;
PISECURITY_DESCRIPTOR pSD = (PISECURITY_DESCRIPTOR)psd;
if(pSD)
pSD->Control = (pSD->Control & ~wControlMask) | wControlBits;
else
dwErr = ERROR_INVALID_PARAMETER;
return dwErr;
}
//--------------------------------------------------------------------------
HRESULT FakeSecuritySetting::SD2Wbem(SECURITY_INFORMATION si,
SECURITY_DESCRIPTOR *pSD,
CWbemServices &service,
CWbemClassObject &w32sd)
{
HRESULT hr = WBEM_S_NO_ERROR;
// converts the security descriptor from the file into a
// Win32_Security object.
if(si && w32sd.IsNull() && pSD)
{
m_service = service;
w32sd = m_service.CreateInstance("Win32_SecurityDescriptor");
SECURITY_DESCRIPTOR_CONTROL ControlFlags = 0;
BOOL present = FALSE, defaulted = FALSE;
BOOL lpBool = FALSE;
if(si & OWNER_SECURITY_INFORMATION)
{
CWbemClassObject pTrusteeOwner;
PSID sidOwner = NULL;
GetSecurityDescriptorOwner(pSD, &sidOwner, &lpBool);
Sid2Wbem(sidOwner, pTrusteeOwner);
hr = w32sd.PutEmbeddedObject("Owner", pTrusteeOwner);
}
if(SUCCEEDED(hr) && (si & GROUP_SECURITY_INFORMATION))
{
CWbemClassObject pTrusteeGroup;
PSID sidGroup = NULL;
GetSecurityDescriptorGroup(pSD, &sidGroup, &lpBool);
Sid2Wbem(sidGroup, pTrusteeGroup);
hr = w32sd.PutEmbeddedObject("Group", pTrusteeGroup);
}
if(SUCCEEDED(hr) && (si & DACL_SECURITY_INFORMATION))
{
PACL dacl = 0;
GetSecurityDescriptorDacl(pSD, &present, &dacl, &defaulted);
if(present)
{
VARIANT pDacl;
ACL2Wbem(dacl, &pDacl);
hr = w32sd.Put("DACL", pDacl);
}
}
if(SUCCEEDED(hr) && (si & SACL_SECURITY_INFORMATION))
{
PACL sacl = 0;
GetSecurityDescriptorSacl(pSD, &present, &sacl, &defaulted);
if(present)
{
VARIANT pSacl;
ACL2Wbem(sacl, &pSacl);
hr = w32sd.Put("SACL", pSacl);
}
}
if(SUCCEEDED(hr))
{
// strict copy for ControlFlags.
DWORD revision = 0;
GetSecurityDescriptorControl(pSD, &ControlFlags, &revision);
ControlFlags |= SE_SELF_RELATIVE;
hr = w32sd.Put("ControlFlags", (long)ControlFlags);
}
}
return hr;
}
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
bool FakeSecuritySetting::Wbem2ACL(_variant_t &w32ACL, PACL *pAcl)
{
SAFEARRAY* pDACL = V_ARRAY(&w32ACL);
IWbemClassObject *pACEObject;
CWbemClassObject pTrustee;
DWORD aclSize = sizeof(ACL);
// walk DACL
LONG lDimension = 1;
LONG lLowerBound;
LONG lUpperBound;
LONG lIndex = 0;
if(w32ACL.vt != VT_NULL)
{
SafeArrayGetLBound(pDACL, lDimension, &lLowerBound);
SafeArrayGetUBound(pDACL, lDimension, &lUpperBound);
for(lIndex = lLowerBound; lIndex <= lUpperBound; lIndex++)
{
SafeArrayGetElement(pDACL, &lIndex, &pACEObject);
CWbemClassObject ACEInstance = pACEObject;
pTrustee = ACEInstance.GetEmbeddedObject("Trustee");
if(pTrustee)
{
//aclSize += pTrustee.GetLong("SidLength");
aclSize += WbemSidSize(pTrustee);
}
aclSize += sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD);
}
}
*pAcl = (PACL)LocalAlloc(LPTR, aclSize);
if(*pAcl)
{
InitializeAcl(*pAcl, aclSize, ACL_REVISION);
}
else
{
return false;
}
if(w32ACL.vt != VT_NULL)
{
for(lIndex = lLowerBound; lIndex <= lUpperBound; lIndex++)
{
SafeArrayGetElement(pDACL, &lIndex, &pACEObject);
CWbemClassObject ACEInstance = pACEObject;
ACCESS_ALLOWED_ACE *ace = NULL; // NOTE: all 3 we deal with are the same.
DWORD dwSidLength = 0;
// get Win32_Trustee object from Win32_ACE
pTrustee = ACEInstance.GetEmbeddedObject("Trustee");
// process the goofy SID
if(pTrustee)
{
dwSidLength = WbemSidSize(pTrustee);
//dwSidLength = pTrustee.GetLong("SidLength");
WORD wAceSize = sizeof( ACCESS_DENIED_ACE ) + dwSidLength - sizeof(DWORD);
// Allocate the appropriate Ace and fill out its values.
ACCESS_DENIED_ACE* ace = (ACCESS_DENIED_ACE*) LocalAlloc(LPTR, wAceSize );
if(NULL != ace)
{
Wbem2Sid(pTrustee, &(ace->SidStart));
ace->Header.AceType = (BYTE)ACEInstance.GetLong("AceType");
ace->Header.AceFlags = (BYTE)ACEInstance.GetLong("AceFlags");
ace->Mask = ACEInstance.GetLong("AccessMask");
ace->Header.AceSize = wAceSize;
BOOL x = AddAce(*pAcl, ACL_REVISION, lIndex, ace, ace->Header.AceSize);
}
}
DWORD err = GetLastError();
}
}
return true;
}
//--------------------------------------------------------------------------
bool FakeSecuritySetting::ACL2Wbem(PACL pAcl, VARIANT *w32ACL)
{
ACCESS_ALLOWED_ACE *ace;
CWbemClassObject pAce;
CWbemClassObject pTrustee;
ACL_SIZE_INFORMATION aclSize;
bool retval = false;
VariantInit(w32ACL);
if(GetAclInformation(pAcl, &aclSize, sizeof(ACL_SIZE_INFORMATION), AclSizeInformation))
{
// create an empty array.
long ix[1];
ix[0] = 0;
SAFEARRAY* saDACL;
SAFEARRAYBOUND rgsabound[1];
rgsabound->cElements = aclSize.AceCount;
rgsabound->lLbound = 0;
saDACL = SafeArrayCreate(VT_UNKNOWN, 1, rgsabound);
// load the safearray
for(DWORD pos = 0;
(pos < aclSize.AceCount) && GetAce(pAcl, pos, (LPVOID *)&ace);
pos++)
{
// now that we have the ACE, let's create a Win32_ACE object so we can
// add it to the embedded object list.
if(pAce = m_service.CreateInstance("Win32_Ace"))
{
// fill trustee from SID
Sid2Wbem((PSID)&ace->SidStart, pTrustee);
pAce.PutEmbeddedObject("Trustee", pTrustee);
pAce.Put("AceType", (long)ace->Header.AceType);
pAce.Put("AceFlags", (long)ace->Header.AceFlags);
pAce.Put("AccessMask", (long)ace->Mask);
IWbemClassObject *temp = pAce;
SafeArrayPutElement(saDACL, ix, temp);
} // end if
ix[0]++;
retval = true;
} // endfor
// return the safearray in a array variant.
V_VT(w32ACL) = VT_UNKNOWN|VT_ARRAY;
V_ARRAY(w32ACL) = saDACL;
} //endif GetAclInformation
return retval;
}
//--------------------------------------------------------------------------
DWORD FakeSecuritySetting::Wbem2Sid(CWbemClassObject &w32Trust, PSID ppSid)
{
// get SID information out of the Trustee
void* pVoid;
variant_t vValue;
SAFEARRAY* sa;
long sidLen = 0, sidLen2 = 0;
HRESULT hr = w32Trust.Get("Sid",vValue);
if(SUCCEEDED(hr))
{
sa = V_ARRAY(&vValue);
long lLowerBound = 0, lUpperBound = 0 ;
SafeArrayGetLBound(sa, 1, &lLowerBound);
SafeArrayGetUBound(sa, 1, &lUpperBound);
sidLen = w32Trust.GetLong("SidLength");
sidLen2 = lUpperBound - lLowerBound + 1;
// make sure the calculations match.
// ATLASSERT(sidLen == sidLen2);
if(ppSid)
{
// Get a pointer to read the data into
SafeArrayAccessData(sa, &pVoid);
memcpy(ppSid, pVoid, sidLen2);
SafeArrayUnaccessData(sa);
}
}
return sidLen2;
}
//--------------------------------------------------------------------------
DWORD FakeSecuritySetting::WbemSidSize(CWbemClassObject &w32Trust)
{
// get SID information out of the Trustee
variant_t vValue;
SAFEARRAY* sa;
w32Trust.Get("Sid",vValue);
sa = V_ARRAY(&vValue);
long lLowerBound, lUpperBound = 0 ;
SafeArrayGetLBound(sa, 1, &lLowerBound);
SafeArrayGetUBound(sa, 1, &lUpperBound);
return lUpperBound - lLowerBound + 1;
}
//--------------------------------------------------------------------------
void FakeSecuritySetting::Sid2Wbem(PSID pSid, CWbemClassObject &w32Trust)
{
variant_t vValue;
void *pSIDTrustee = 0;
if(IsValidSid(pSid))
{
w32Trust = m_service.CreateInstance("Win32_Trustee");
// set the UINT8 array for the pSid
DWORD dwSidLength = GetLengthSid(pSid);
SAFEARRAY* sa;
SAFEARRAYBOUND rgsabound[1];
PSID pSidTrustee = NULL;
rgsabound[0].cElements = dwSidLength;
rgsabound[0].lLbound = 0;
sa = SafeArrayCreate(VT_UI1, 1, rgsabound);
// Get a pointer to read the data into
SafeArrayAccessData(sa, &pSidTrustee);
memcpy(pSidTrustee, pSid, rgsabound[0].cElements);
SafeArrayUnaccessData(sa);
// Put the safearray into a variant, and send it off
V_VT(&vValue) = VT_UI1 | VT_ARRAY;
V_ARRAY(&vValue) = sa;
w32Trust.Put("Sid", vValue);
//w32Trust.Put("SidLength", (long)dwSidLength);
}
}