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.
640 lines
19 KiB
640 lines
19 KiB
// Copyright (c) 1997-1999 Microsoft Corporation
|
|
#include "precomp.h"
|
|
#include <winioctl.h>
|
|
#include "si.h"
|
|
#include "resource.h"
|
|
#include <cguid.h>
|
|
#include <stdio.h>
|
|
|
|
//-----------------------------------------------------------------------------
|
|
CSecurityInformation::~CSecurityInformation()
|
|
{
|
|
}
|
|
|
|
#define HINST_THISDLL _Module.GetModuleInstance()
|
|
//-----------------------------------------------------------------------------
|
|
HRESULT CSecurityInformation::PropertySheetPageCallback(HWND hwnd,
|
|
UINT uMsg,
|
|
SI_PAGE_TYPE uPage)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
//======================================================================
|
|
//------------------- ISECURITYINFORMATION follows ---------------------------
|
|
//EXTERN_C const GUID IID_ISecurityInformation =
|
|
// { 0x965fc360, 0x16ff, 0x11d0, 0x91, 0xcb, 0x0, 0xaa, 0x0, 0xbb, 0xb7, 0x23 };
|
|
|
|
#define WBEM_ENABLE ( 0x0001 )
|
|
#define WBEM_METHOD_EXECUTE ( 0x0002 )
|
|
#define WBEM_FULL_WRITE_REP ( 0x001c )
|
|
#define WBEM_PARTIAL_WRITE_REP ( 0x0008 )
|
|
#define WBEM_WRITE_PROVIDER ( 0x0010 )
|
|
#define WBEM_REMOTE_ENABLE ( 0x0020 )
|
|
|
|
#define WBEM_GENERAL_WRITE (WBEM_FULL_WRITE_REP|WBEM_PARTIAL_WRITE_REP|WBEM_WRITE_PROVIDER)
|
|
|
|
#define WBEM_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED |\
|
|
SYNCHRONIZE |\
|
|
WBEM_ENABLE |\
|
|
WBEM_METHOD_EXECUTE |\
|
|
WBEM_FULL_WRITE_REP |\
|
|
WBEM_PARTIAL_WRITE_REP |\
|
|
WBEM_WRITE_PROVIDER)
|
|
|
|
#define WBEM_GENERIC_READ (STANDARD_RIGHTS_READ |\
|
|
WBEM_ENABLE)
|
|
|
|
|
|
#define WBEM_GENERIC_WRITE (STANDARD_RIGHTS_WRITE |\
|
|
WBEM_FULL_WRITE_REP |\
|
|
WBEM_PARTIAL_WRITE_REP |\
|
|
WBEM_WRITE_PROVIDER)
|
|
|
|
|
|
#define WBEM_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE |\
|
|
WBEM_METHOD_EXECUTE)
|
|
|
|
// The following array defines the permission names for WMI.
|
|
SI_ACCESS siWMIAccesses[] =
|
|
{
|
|
{ &GUID_NULL, WBEM_METHOD_EXECUTE, MAKEINTRESOURCEW(IDS_WBEM_GENERIC_EXECUTE), SI_ACCESS_GENERAL | SI_ACCESS_CONTAINER },
|
|
{ &GUID_NULL, WBEM_FULL_WRITE_REP, MAKEINTRESOURCEW(IDS_WBEM_FULL_WRITE), SI_ACCESS_GENERAL | SI_ACCESS_CONTAINER },
|
|
{ &GUID_NULL, WBEM_PARTIAL_WRITE_REP, MAKEINTRESOURCEW(IDS_WBEM_PARTIAL_WRITE), SI_ACCESS_GENERAL | SI_ACCESS_CONTAINER },
|
|
{ &GUID_NULL, WBEM_WRITE_PROVIDER, MAKEINTRESOURCEW(IDS_WBEM_PROVIDER_WRITE), SI_ACCESS_GENERAL | SI_ACCESS_CONTAINER },
|
|
{ &GUID_NULL, WBEM_ENABLE, MAKEINTRESOURCEW(IDS_WBEM_ENABLE), SI_ACCESS_GENERAL | SI_ACCESS_CONTAINER },
|
|
{ &GUID_NULL, WBEM_REMOTE_ENABLE, MAKEINTRESOURCEW(IDS_WBEM_REMOTE_ENABLE), SI_ACCESS_GENERAL | SI_ACCESS_CONTAINER },
|
|
{ &GUID_NULL, READ_CONTROL, MAKEINTRESOURCEW(IDS_WBEM_READ_SECURITY), SI_ACCESS_GENERAL | SI_ACCESS_CONTAINER },
|
|
{ &GUID_NULL, WRITE_DAC, MAKEINTRESOURCEW(IDS_WBEM_EDIT_SECURITY), SI_ACCESS_GENERAL | SI_ACCESS_CONTAINER },
|
|
{ &GUID_NULL, 0, MAKEINTRESOURCEW(IDS_NONE), 0 }
|
|
};
|
|
#define iWMIDefAccess 4 // FILE_GENERAL_READ_EX
|
|
|
|
SI_ACCESS siWMIAccessesAdvanced[] =
|
|
{
|
|
{ &GUID_NULL, WBEM_METHOD_EXECUTE, MAKEINTRESOURCEW(IDS_WBEM_GENERIC_EXECUTE), SI_ACCESS_SPECIFIC },
|
|
{ &GUID_NULL, WBEM_FULL_WRITE_REP, MAKEINTRESOURCEW(IDS_WBEM_FULL_WRITE), SI_ACCESS_SPECIFIC },
|
|
{ &GUID_NULL, WBEM_PARTIAL_WRITE_REP, MAKEINTRESOURCEW(IDS_WBEM_PARTIAL_WRITE), SI_ACCESS_SPECIFIC },
|
|
{ &GUID_NULL, WBEM_WRITE_PROVIDER, MAKEINTRESOURCEW(IDS_WBEM_PROVIDER_WRITE), SI_ACCESS_SPECIFIC },
|
|
{ &GUID_NULL, WBEM_ENABLE, MAKEINTRESOURCEW(IDS_WBEM_ENABLE), SI_ACCESS_SPECIFIC },
|
|
{ &GUID_NULL, WBEM_REMOTE_ENABLE, MAKEINTRESOURCEW(IDS_WBEM_REMOTE_ENABLE), SI_ACCESS_SPECIFIC },
|
|
{ &GUID_NULL, READ_CONTROL, MAKEINTRESOURCEW(IDS_WBEM_READ_SECURITY), SI_ACCESS_SPECIFIC },
|
|
{ &GUID_NULL, WRITE_DAC, MAKEINTRESOURCEW(IDS_WBEM_EDIT_SECURITY), SI_ACCESS_SPECIFIC },
|
|
{ &GUID_NULL, 0, MAKEINTRESOURCEW(IDS_NONE), 0 }
|
|
};
|
|
#define iWMIDefAccessAdvanced 4 // FILE_GENERAL_READ_EX
|
|
|
|
SI_INHERIT_TYPE siWMIInheritTypes[] =
|
|
{
|
|
&GUID_NULL, 0, MAKEINTRESOURCEW(IDS_WBEM_NAMESPACE),
|
|
&GUID_NULL, CONTAINER_INHERIT_ACE, MAKEINTRESOURCEW(IDS_WBEM_NAMESPACE_SUBNAMESPACE),
|
|
&GUID_NULL, INHERIT_ONLY_ACE | CONTAINER_INHERIT_ACE, MAKEINTRESOURCEW(IDS_WBEM_SUBNAMESPACE_ONLY),
|
|
};
|
|
|
|
GENERIC_MAPPING WMIMap =
|
|
{
|
|
WBEM_GENERIC_READ,
|
|
WBEM_GENERIC_WRITE,
|
|
WBEM_GENERIC_EXECUTE,
|
|
WBEM_ALL_ACCESS
|
|
};
|
|
|
|
|
|
//---------------------------------------------------------------
|
|
CSDSecurity::CSDSecurity(struct NSNODE *nsNode,
|
|
_bstr_t server,
|
|
bool local)
|
|
: m_nsNode(nsNode),
|
|
m_server(server),
|
|
m_local(local),
|
|
m_pSidOwner(NULL),
|
|
m_pSidGroup(NULL)
|
|
{
|
|
}
|
|
|
|
//------------------ Accessors to the above arrays---------------
|
|
//---------------------------------------------------------------
|
|
HRESULT CSDSecurity::MapGeneric(const GUID *pguidObjectType,
|
|
UCHAR *pAceFlags,
|
|
ACCESS_MASK *pMask)
|
|
{
|
|
*pAceFlags &= ~OBJECT_INHERIT_ACE;
|
|
MapGenericMask(pMask, &WMIMap);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
HRESULT CSDSecurity::GetInheritTypes(PSI_INHERIT_TYPE *ppInheritTypes,
|
|
ULONG *pcInheritTypes)
|
|
{
|
|
*ppInheritTypes = siWMIInheritTypes;
|
|
*pcInheritTypes = ARRAYSIZE(siWMIInheritTypes);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
//---------------------------------------------------
|
|
LPWSTR CSDSecurity::CloneWideString(_bstr_t pszSrc )
|
|
{
|
|
LPWSTR pszDst = NULL;
|
|
|
|
pszDst = new WCHAR[(lstrlen(pszSrc) + 1)];
|
|
if (pszDst)
|
|
{
|
|
wcscpy( pszDst, pszSrc );
|
|
}
|
|
|
|
return pszDst;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
HRESULT CSDSecurity::GetObjectInformation(PSI_OBJECT_INFO pObjectInfo)
|
|
{
|
|
// ATLASSERT(pObjectInfo != NULL &&
|
|
// !IsBadWritePtr(pObjectInfo, sizeof(*pObjectInfo)));
|
|
|
|
pObjectInfo->dwFlags = SI_EDIT_PERMS | /*SI_EDIT_OWNER |*/ // dacl, owner pages.
|
|
SI_ADVANCED | SI_CONTAINER |
|
|
SI_NO_TREE_APPLY | SI_NO_ACL_PROTECT;
|
|
|
|
USES_CONVERSION;
|
|
|
|
// NOTE: This weirdness is so nt4sp5+ can put up the
|
|
// user browser for Add User.
|
|
if(m_local)
|
|
{
|
|
pObjectInfo->pszServerName = NULL;
|
|
}
|
|
else
|
|
{
|
|
// NOTE: NT4 seems to want the "\\" and w2k doesn't care.
|
|
bstr_t temp(_T("\\\\"));
|
|
temp += m_server;
|
|
pObjectInfo->pszServerName = CloneWideString(temp);
|
|
}
|
|
pObjectInfo->hInstance = HINST_THISDLL;
|
|
pObjectInfo->pszObjectName = CloneWideString(m_nsNode->display);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
HRESULT CSDSecurity::GetAccessRights(const GUID *pguidObjectType,
|
|
DWORD dwFlags,
|
|
PSI_ACCESS *ppAccess,
|
|
ULONG *pcAccesses,
|
|
ULONG *piDefaultAccess)
|
|
{
|
|
// dwFlags is zero if the basic security page is being initialized,
|
|
// Otherwise, it is a combination of the following values:
|
|
// SI_ADVANCED - Advanced sheet is being initialized.
|
|
// SI_EDIT_AUDITS - Advanced sheet includes the Audit property page.
|
|
// SI_EDIT_PROPERTIES - Advanced sheet enables editing of ACEs that
|
|
// apply to object's properties and property sets
|
|
|
|
// We only currently support '0' or 'SI_ADVANCED'
|
|
ATLASSERT(0 == dwFlags || SI_ADVANCED == dwFlags);
|
|
if(0 == dwFlags)
|
|
{
|
|
*ppAccess = siWMIAccesses;
|
|
*pcAccesses = ARRAYSIZE(siWMIAccesses);
|
|
*piDefaultAccess = iWMIDefAccess;
|
|
}
|
|
else
|
|
{
|
|
*ppAccess = siWMIAccessesAdvanced;
|
|
*pcAccesses = ARRAYSIZE(siWMIAccessesAdvanced);
|
|
*piDefaultAccess = iWMIDefAccessAdvanced;
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
//------------------ Real workers -------------------------------
|
|
//---------------------------------------------------------------
|
|
#define FirstAce(Acl) ((PVOID)((PUCHAR)(Acl) + sizeof(ACL)))
|
|
#define NextAce(Ace) ((PVOID)((PUCHAR)(Ace) + ((PACE_HEADER)(Ace))->AceSize))
|
|
|
|
/* Commenting out since winbase.h makes one available for 0x0500 and above
|
|
|
|
BOOL WINAPI SetSecurityDescriptorControl(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;
|
|
}
|
|
*/
|
|
|
|
void CSDSecurity::ProtectACLs(SECURITY_INFORMATION si, PSECURITY_DESCRIPTOR pSD)
|
|
{
|
|
SECURITY_DESCRIPTOR_CONTROL wSDControl;
|
|
DWORD dwRevision;
|
|
PACL pAcl;
|
|
BOOL bDefaulted;
|
|
BOOL bPresent;
|
|
PACE_HEADER pAce;
|
|
UINT cAces;
|
|
|
|
|
|
if (0 == si || NULL == pSD)
|
|
return; // Nothing to do
|
|
|
|
// Get the ACL protection control bits
|
|
GetSecurityDescriptorControl(pSD, &wSDControl, &dwRevision);
|
|
wSDControl &= SE_DACL_PROTECTED | SE_SACL_PROTECTED;
|
|
|
|
if ((si & DACL_SECURITY_INFORMATION) && !(wSDControl & SE_DACL_PROTECTED))
|
|
{
|
|
wSDControl |= SE_DACL_PROTECTED;
|
|
pAcl = NULL;
|
|
GetSecurityDescriptorDacl(pSD, &bPresent, &pAcl, &bDefaulted);
|
|
|
|
// Theoretically, modifying the DACL in this way can cause it to be
|
|
// no longer canonical. However, the only way this can happen is if
|
|
// there is an inherited Deny ACE and a non-inherited Allow ACE.
|
|
// Since this function is only called for root objects, this means
|
|
// a) the server DACL must have a Deny ACE and b) the DACL on this
|
|
// object must have been modified later. But if the DACL was
|
|
// modified through the UI, then we would have eliminated all of the
|
|
// Inherited ACEs already. Therefore, it must have been modified
|
|
// through some other means. Considering that the DACL originally
|
|
// inherited from the server never has a Deny ACE, this situation
|
|
// should be extrememly rare. If it ever does happen, the ACL
|
|
// Editor will just tell the user that the DACL is non-canonical.
|
|
//
|
|
// Therefore, let's ignore the possibility here.
|
|
|
|
if (NULL != pAcl)
|
|
{
|
|
for (cAces = pAcl->AceCount, pAce = (PACE_HEADER)FirstAce(pAcl);
|
|
cAces > 0;
|
|
--cAces, pAce = (PACE_HEADER)NextAce(pAce))
|
|
{
|
|
pAce->AceFlags &= ~INHERITED_ACE;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ((si & SACL_SECURITY_INFORMATION) && !(wSDControl & SE_SACL_PROTECTED))
|
|
{
|
|
wSDControl |= SE_SACL_PROTECTED;
|
|
pAcl = NULL;
|
|
GetSecurityDescriptorSacl(pSD, &bPresent, &pAcl, &bDefaulted);
|
|
|
|
if (NULL != pAcl)
|
|
{
|
|
for (cAces = pAcl->AceCount, pAce = (PACE_HEADER)FirstAce(pAcl);
|
|
cAces > 0;
|
|
--cAces, pAce = (PACE_HEADER)NextAce(pAce))
|
|
{
|
|
pAce->AceFlags &= ~INHERITED_ACE;
|
|
}
|
|
}
|
|
}
|
|
|
|
SetSecurityDescriptorControl(pSD, SE_DACL_PROTECTED | SE_SACL_PROTECTED, wSDControl);
|
|
}
|
|
|
|
//---------------------------------------------------------------
|
|
HRESULT CSDSecurity::GetSecurity(THIS_ SECURITY_INFORMATION RequestedInformation,
|
|
PSECURITY_DESCRIPTOR *ppSecurityDescriptor,
|
|
BOOL fDefault )
|
|
{
|
|
// ATLASSERT(ppSecurityDescriptor != NULL);
|
|
|
|
HRESULT hr = E_FAIL;
|
|
|
|
*ppSecurityDescriptor = NULL;
|
|
|
|
if(fDefault)
|
|
{
|
|
ATLTRACE(_T("Default security descriptor not supported"));
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
// does it want something?
|
|
if(RequestedInformation != 0)
|
|
{
|
|
if(m_pSidOwner != NULL)
|
|
{
|
|
BYTE *p = (LPBYTE)m_pSidOwner;
|
|
delete []p;
|
|
m_pSidOwner = NULL;
|
|
}
|
|
|
|
if(m_pSidGroup != NULL)
|
|
{
|
|
BYTE *p = (LPBYTE)m_pSidGroup;
|
|
delete []p;
|
|
m_pSidGroup = NULL;
|
|
}
|
|
|
|
switch(m_nsNode->sType)
|
|
{
|
|
case TYPE_NAMESPACE:
|
|
{
|
|
|
|
CWbemClassObject _in;
|
|
CWbemClassObject _out;
|
|
|
|
hr = m_nsNode->ns->GetMethodSignatures("__SystemSecurity", "GetSD",
|
|
_in, _out);
|
|
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
hr = m_nsNode->ns->ExecMethod("__SystemSecurity", "GetSD",
|
|
_in, _out);
|
|
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
HRESULT hr1 = HRESULT_FROM_NT(_out.GetLong("ReturnValue"));
|
|
if(FAILED(hr1))
|
|
{
|
|
hr = hr1;
|
|
}
|
|
else
|
|
{
|
|
_out.GetBLOB("SD", (LPBYTE *)ppSecurityDescriptor);
|
|
hr = InitializeOwnerandGroup(ppSecurityDescriptor);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case TYPE_STATIC_INSTANCE:
|
|
{
|
|
m_nsNode->pclsObj->GetBLOB("__SD",(LPBYTE *)ppSecurityDescriptor);
|
|
hr = InitializeOwnerandGroup(ppSecurityDescriptor);
|
|
break;
|
|
}
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
*ppSecurityDescriptor = LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
|
|
|
|
if(*ppSecurityDescriptor)
|
|
InitializeSecurityDescriptor(*ppSecurityDescriptor,
|
|
SECURITY_DESCRIPTOR_REVISION);
|
|
else
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
|
|
//ProtectACLs(RequestedInformation, *ppSecurityDescriptor);
|
|
return hr;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
#define FirstAce(Acl) ((PVOID)((PUCHAR)(Acl) + sizeof(ACL)))
|
|
#define NextAce(Ace) ((PVOID)((PUCHAR)(Ace) + ((PACE_HEADER)(Ace))->AceSize))
|
|
|
|
HRESULT CSDSecurity::SetSecurity(SECURITY_INFORMATION SecurityInformation,
|
|
PSECURITY_DESCRIPTOR pSecurityDescriptor)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
|
|
// dont pass the SI_OWNER_RECURSE bit to wbem.
|
|
// SecurityInformation &= ~(OWNER_SECURITY_INFORMATION | SI_OWNER_RECURSE);
|
|
|
|
// if something was changed...
|
|
if(SecurityInformation != 0)
|
|
{
|
|
// set the CONTAINER_INHERIT_ACE bit.
|
|
if(SecurityInformation & DACL_SECURITY_INFORMATION)
|
|
{
|
|
PACL pAcl = NULL;
|
|
BOOL bDefaulted;
|
|
BOOL bPresent;
|
|
PACE_HEADER pAce;
|
|
UINT cAces;
|
|
|
|
GetSecurityDescriptorDacl(pSecurityDescriptor, &bPresent, &pAcl, &bDefaulted);
|
|
|
|
if(NULL != pAcl)
|
|
{
|
|
for(cAces = pAcl->AceCount, pAce = (PACE_HEADER)FirstAce(pAcl);
|
|
cAces > 0;
|
|
--cAces, pAce = (PACE_HEADER)NextAce(pAce))
|
|
{
|
|
// Make sure we don't get 'object inherit'
|
|
// This happens when creating a new ace from advance page
|
|
pAce->AceFlags &= ~OBJECT_INHERIT_ACE;
|
|
}
|
|
}
|
|
}
|
|
|
|
SECURITY_DESCRIPTOR *pSD = NULL;
|
|
|
|
// ACLUI sends absolute format so change to self-relative so the
|
|
// PutBLOB() has contiguous memory to copy.
|
|
DWORD srLen = 0;
|
|
SetLastError(0);
|
|
BOOL bCheck;
|
|
if(m_pSidOwner != NULL)
|
|
{
|
|
bCheck = SetSecurityDescriptorOwner(pSecurityDescriptor,m_pSidOwner,m_bOwnerDefaulted);
|
|
if(bCheck == FALSE)
|
|
{
|
|
return E_FAIL;
|
|
}
|
|
}
|
|
|
|
if(m_pSidGroup != NULL)
|
|
{
|
|
bCheck = SetSecurityDescriptorGroup(pSecurityDescriptor,m_pSidGroup,m_bGroupDefaulted);
|
|
|
|
if(bCheck == FALSE)
|
|
{
|
|
return E_FAIL;
|
|
}
|
|
}
|
|
|
|
// get the size needed.
|
|
BOOL x1 = MakeSelfRelativeSD(pSecurityDescriptor, NULL, &srLen);
|
|
|
|
DWORD eee = GetLastError();
|
|
|
|
pSD = (SECURITY_DESCRIPTOR *)LocalAlloc(LPTR, srLen);
|
|
|
|
if(pSD)
|
|
{
|
|
BOOL converted = MakeSelfRelativeSD(pSecurityDescriptor, pSD, &srLen);
|
|
hr = S_OK;
|
|
}
|
|
else
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
return hr;
|
|
}
|
|
|
|
switch(m_nsNode->sType)
|
|
{
|
|
case TYPE_NAMESPACE:
|
|
{
|
|
CWbemClassObject _in;
|
|
CWbemClassObject _out;
|
|
|
|
hr = m_nsNode->ns->GetMethodSignatures("__SystemSecurity", "SetSD",
|
|
_in, _out);
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
_in.PutBLOB("SD", (LPBYTE)pSD, GetSecurityDescriptorLength(pSD));
|
|
|
|
hr = m_nsNode->ns->ExecMethod("__SystemSecurity", "SetSD",
|
|
_in, _out);
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
HRESULT hr1 = HRESULT_FROM_NT(_out.GetLong("ReturnValue"));
|
|
if(FAILED(hr1))
|
|
{
|
|
hr = hr1;
|
|
}
|
|
}
|
|
}
|
|
// HACK: because of how the core caches/uses security, I have to close &
|
|
// reopen my connection because GetSecurity() will be immediately called
|
|
// to refresh the UI. If I dont do this, GetSecurity() will return to old
|
|
// security settings even though they're really saved.
|
|
|
|
m_nsNode->ns->DisconnectServer();
|
|
CHString1 path;
|
|
// if we've got a server, here - append it.
|
|
if (((BSTR)m_server != NULL) && wcslen(m_server))
|
|
path = CHString1("\\\\") + CHString1((BSTR)m_server) + CHString1("\\") + CHString1((BSTR)m_nsNode->fullPath);
|
|
else
|
|
path = m_nsNode->fullPath;
|
|
|
|
m_nsNode->ns->ConnectServer(_bstr_t((const WCHAR*)path));
|
|
|
|
break;
|
|
}
|
|
case TYPE_STATIC_INSTANCE:
|
|
{
|
|
m_nsNode->pclsObj->PutBLOB("__SD",(LPBYTE)pSD, GetSecurityDescriptorLength(pSD));
|
|
//Now put the instance back
|
|
hr = m_nsNode->ns->PutInstance(*(m_nsNode->pclsObj)/*,flag*/);
|
|
delete m_nsNode->pclsObj;
|
|
*(m_nsNode->pclsObj) = m_nsNode->ns->GetObject(m_nsNode->relPath/*,flag*/);
|
|
break;
|
|
}
|
|
}
|
|
if(m_pSidOwner != NULL)
|
|
{
|
|
BYTE *p = (LPBYTE)m_pSidOwner;
|
|
delete []p;
|
|
m_pSidOwner = NULL;
|
|
}
|
|
|
|
if(m_pSidGroup != NULL)
|
|
{
|
|
BYTE *p = (LPBYTE)m_pSidGroup;
|
|
delete []p;
|
|
m_pSidGroup = NULL;
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CSDSecurity::InitializeOwnerandGroup(PSECURITY_DESCRIPTOR *ppSecurityDescriptor)
|
|
{
|
|
|
|
SID *pSid;
|
|
BOOL bDefaulted;
|
|
|
|
BOOL bCheck = GetSecurityDescriptorOwner(*ppSecurityDescriptor,
|
|
(void **)&pSid,&m_bOwnerDefaulted);
|
|
if(bCheck == TRUE)
|
|
{
|
|
if (pSid != NULL)
|
|
{
|
|
m_nLengthOwner = GetSidLengthRequired(pSid->SubAuthorityCount);
|
|
|
|
if(m_pSidOwner != NULL)
|
|
{
|
|
BYTE *p = (LPBYTE)m_pSidOwner;
|
|
delete []p;
|
|
m_pSidOwner = NULL;
|
|
}
|
|
|
|
m_pSidOwner = (SID *)new BYTE[m_nLengthOwner];
|
|
|
|
if(m_pSidOwner == NULL ||
|
|
CopySid(m_nLengthOwner,m_pSidOwner,pSid) == FALSE)
|
|
{
|
|
delete m_pSidOwner;
|
|
m_pSidOwner = NULL;
|
|
m_nLengthOwner = -1;
|
|
return E_FAIL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
m_pSidOwner = NULL;
|
|
m_nLengthOwner = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
m_pSidOwner = NULL;
|
|
m_nLengthOwner = -1;
|
|
return E_FAIL;
|
|
}
|
|
|
|
SID *pGroup;
|
|
|
|
bCheck = GetSecurityDescriptorGroup(*ppSecurityDescriptor,
|
|
(void **)&pGroup,&m_bGroupDefaulted);
|
|
|
|
if(bCheck == TRUE)
|
|
{
|
|
if (pGroup != NULL)
|
|
{
|
|
m_nLengthGroup = GetSidLengthRequired(pGroup->SubAuthorityCount);
|
|
|
|
if(m_pSidGroup != NULL)
|
|
{
|
|
BYTE *p = (LPBYTE)m_pSidGroup;
|
|
delete []p;
|
|
m_pSidGroup = NULL;
|
|
}
|
|
|
|
m_pSidGroup = (SID *)new BYTE[m_nLengthGroup];
|
|
|
|
if(m_pSidGroup == NULL ||
|
|
CopySid(m_nLengthGroup,m_pSidGroup,pGroup) == FALSE)
|
|
{
|
|
delete m_pSidGroup;
|
|
m_pSidGroup = NULL;
|
|
m_nLengthGroup = -1;
|
|
return E_FAIL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
m_pSidGroup = NULL;
|
|
m_nLengthGroup = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
m_pSidGroup = NULL;
|
|
m_nLengthGroup = -1;
|
|
return E_FAIL;
|
|
}
|
|
|
|
return S_OK;
|
|
}
|