windows-nt/Source/XPSP1/NT/ds/security/gina/rsoputil/rsopsec.cpp
2020-09-26 16:20:57 +08:00

1342 lines
32 KiB
C++

//******************************************************************************
//
// Microsoft Confidential. Copyright (c) Microsoft Corporation 1999. All rights reserved
//
// File: RsopSec.cpp
//
// Description: RSOP Namespace Security functions
//
// History: 8-26-99 leonardm Created
//
//******************************************************************************
#include <windows.h>
#include <objbase.h>
#include <wbemcli.h>
#include <accctrl.h>
#include <aclapi.h>
#include <lm.h>
#include "RsopUtil.h"
#include "RsopSec.h"
#include "rsopdbg.h"
#include "smartptr.h"
//******************************************************************************
//
// Function:
//
// Description:
//
// Parameters:
//
// Return:
//
// History: 8-26-99 leonardm Created
//
//******************************************************************************
STDMETHODIMP GetExplicitAccesses( long lSecurityLevel,
EXPLICIT_ACCESS** ppExplicitAccess,
DWORD* pdwCount,
CWString* psTrustees)
{
WKSTA_INFO_100* pWkstaInfo = NULL;
NET_API_STATUS status = NetWkstaGetInfo(NULL,100,(LPBYTE*)&pWkstaInfo);
if(status != NERR_Success)
{
return E_FAIL;
}
CWString sCurrentDomain = pWkstaInfo->wki100_langroup;
NetApiBufferFree(pWkstaInfo);
if(!sCurrentDomain.ValidString() || sCurrentDomain == L"")
{
return E_FAIL;
}
static ACCESS_MODE AccessMode = GRANT_ACCESS;
static DWORD Inheritance = SUB_CONTAINERS_ONLY_INHERIT;
static DWORD AccessPermissions = WBEM_ENABLE |
WBEM_METHOD_EXECUTE |
WBEM_FULL_WRITE_REP |
WBEM_PARTIAL_WRITE_REP |
WBEM_WRITE_PROVIDER |
WBEM_REMOTE_ACCESS |
READ_CONTROL |
WRITE_DAC;
XPtrArray<EXPLICIT_ACCESS> xpExplicitAccess = NULL;
if(lSecurityLevel == NAMESPACE_SECURITY_DIAGNOSTIC)
{
if(*pdwCount < 1)
{
*pdwCount = 1;
return E_FAIL;
}
*pdwCount = 1;
xpExplicitAccess = new EXPLICIT_ACCESS[*pdwCount];
if(!xpExplicitAccess)
{
return E_OUTOFMEMORY;
}
psTrustees[0] = sCurrentDomain + L"\\Domain Users";
if(!psTrustees[0].ValidString())
{
return E_OUTOFMEMORY;
}
BuildExplicitAccessWithName(&(xpExplicitAccess[0]),
psTrustees[0],
AccessPermissions,
AccessMode,
Inheritance);
}
else if(lSecurityLevel == NAMESPACE_SECURITY_PLANNING)
{
if(*pdwCount < 2)
{
*pdwCount = 2;
return E_FAIL;
}
*pdwCount = 2;
xpExplicitAccess = new EXPLICIT_ACCESS[*pdwCount];
if(!xpExplicitAccess)
{
return E_OUTOFMEMORY;
}
psTrustees[0] = sCurrentDomain + L"\\RSOP Admins";
if(!psTrustees[0].ValidString())
{
return E_OUTOFMEMORY;
}
BuildExplicitAccessWithName(&(xpExplicitAccess[0]),
psTrustees[0],
AccessPermissions,
AccessMode,
Inheritance);
psTrustees[1] = sCurrentDomain + L"\\Domain Admins";
if(!psTrustees[1].ValidString())
{
return E_OUTOFMEMORY;
}
BuildExplicitAccessWithName(&(xpExplicitAccess[1]),
psTrustees[1],
AccessPermissions,
AccessMode,
Inheritance);
}
else
{
return E_INVALIDARG;
}
*ppExplicitAccess = xpExplicitAccess.Acquire();
return S_OK;
}
//******************************************************************************
//
// Function:
//
// Description:
//
// Parameters:
//
// Return:
//
// History: 8-26-99 leonardm Created
//
//******************************************************************************
STDMETHODIMP ReplaceDaclOnSD(PSECURITY_DESCRIPTOR pSD, long lSecurityLevel)
{
HRESULT hr;
XPtrArray<EXPLICIT_ACCESS> xpExplicitAccess = NULL;
DWORD dwCount = 2;
XPtrArray<CWString> xpTrustees = new CWString[dwCount];
if(!xpTrustees)
{
return E_OUTOFMEMORY;
}
hr = GetExplicitAccesses(lSecurityLevel, &xpExplicitAccess, &dwCount, xpTrustees);
if(FAILED(hr))
{
return hr;
}
//
// Get the DACL of the Security descriptor
//
BOOL bDaclPresent;
BOOL bDaclDefaulted;
ACL* pAcl = NULL;
BOOL bRes = GetSecurityDescriptorDacl(pSD, &bDaclPresent, &pAcl,&bDaclDefaulted);
if(!bRes)
{
return E_FAIL;
}
if(bDaclPresent)
{
//
// Get the count of existing ACEs
//
ACL_SIZE_INFORMATION info;
bRes = GetAclInformation(pAcl, &info, sizeof(ACL_SIZE_INFORMATION), AclSizeInformation);
if(!bRes)
{
return E_FAIL;
}
//
// Remove existing ACEs from DACL
//
for(int aceIndex = info.AceCount - 1; aceIndex >= 0; aceIndex--)
{
bRes = DeleteAce(pAcl, aceIndex);
if(!bRes)
{
return E_FAIL;
}
}
LocalFree(pAcl);
}
pAcl = NULL;
//
// SetEntriesInAcl
//
DWORD dwRes = SetEntriesInAcl(dwCount, xpExplicitAccess, NULL, &pAcl);
if(dwRes != ERROR_SUCCESS)
{
return E_FAIL;
}
//
// SetSecurityDescriptorDacl
//
bRes = SetSecurityDescriptorDacl(pSD, bDaclPresent, pAcl, bDaclDefaulted);
if(!bRes)
{
DWORD dwLastError = GetLastError();
return E_FAIL;
}
return S_OK;
}
//******************************************************************************
//
// Function:
//
// Description:
//
// Parameters:
//
// Return:
//
// History: 8-26-99 leonardm Created
//
//******************************************************************************
STDMETHODIMP RSoPMakeAbsoluteSD(SECURITY_DESCRIPTOR* pSelfRelativeSD, SECURITY_DESCRIPTOR** ppAbsoluteSD)
{
BOOL bRes = IsValidSecurityDescriptor(pSelfRelativeSD);
if(!bRes)
{
return WBEM_E_INVALID_PARAMETER;
}
XPtrLF<SECURITY_DESCRIPTOR> xpAbsoluteSD;
XPtrLF<ACL> xpDacl;
XPtrLF<ACL> xpSacl;
XPtrLF<SID> xpOwner;
XPtrLF<SID> xpPrimaryGroup;
DWORD dwAbsoluteSecurityDescriptorSize = 0;
DWORD dwDaclSize = 0;
DWORD dwSaclSize = 0;
DWORD dwOwnerSize = 0;
DWORD dwPrimaryGroupSize = 0;
bRes = ::MakeAbsoluteSD(
pSelfRelativeSD,
xpAbsoluteSD,
&dwAbsoluteSecurityDescriptorSize,
xpDacl, // discretionary ACL
&dwDaclSize, // size of discretionary ACL
xpSacl, // system ACL
&dwSaclSize, // size of system ACL
xpOwner, // owner SID
&dwOwnerSize, // size of owner SID
xpPrimaryGroup, // primary-group SID
&dwPrimaryGroupSize // size of group SID
);
DWORD dwLastError = GetLastError();
if(dwLastError != ERROR_INSUFFICIENT_BUFFER)
{
return E_FAIL;
}
if(!dwAbsoluteSecurityDescriptorSize)
{
return E_FAIL;
}
xpAbsoluteSD = reinterpret_cast<SECURITY_DESCRIPTOR*>(LocalAlloc(LPTR, dwAbsoluteSecurityDescriptorSize));
if(!xpAbsoluteSD)
{
return E_OUTOFMEMORY;
}
if(dwDaclSize)
{
xpDacl = reinterpret_cast<ACL*>(LocalAlloc(LPTR, dwDaclSize));
if(!xpDacl)
{
return E_OUTOFMEMORY;
}
}
if(dwSaclSize)
{
xpSacl = reinterpret_cast<ACL*>(LocalAlloc(LPTR, dwSaclSize));
if(!xpSacl)
{
return E_OUTOFMEMORY;
}
}
if(dwOwnerSize)
{
xpOwner = reinterpret_cast<SID*>(LocalAlloc(LPTR, dwOwnerSize));
if(!xpOwner)
{
return E_OUTOFMEMORY;
}
}
if(dwPrimaryGroupSize)
{
xpPrimaryGroup = reinterpret_cast<SID*>(LocalAlloc(LPTR, dwPrimaryGroupSize));
if(!xpPrimaryGroup)
{
return E_OUTOFMEMORY;
}
}
bRes = ::MakeAbsoluteSD(
pSelfRelativeSD,
xpAbsoluteSD,
&dwAbsoluteSecurityDescriptorSize,
xpDacl, // discretionary ACL
&dwDaclSize, // size of discretionary ACL
xpSacl, // system ACL
&dwSaclSize, // size of system ACL
xpOwner, // owner SID
&dwOwnerSize, // size of owner SID
xpPrimaryGroup, // primary-group SID
&dwPrimaryGroupSize // size of group SID
);
if(!bRes)
{
return E_FAIL;
}
bRes = IsValidSecurityDescriptor(xpAbsoluteSD);
if(!bRes)
{
return E_FAIL;
}
xpDacl.Acquire();
xpSacl.Acquire();
xpOwner.Acquire();
xpPrimaryGroup.Acquire();
*ppAbsoluteSD = xpAbsoluteSD.Acquire();
return S_OK;
}
//******************************************************************************
//
// Function:
//
// Description:
//
// Parameters:
//
// Return:
//
// History: 8-26-99 leonardm Created
//
//******************************************************************************
STDMETHODIMP FreeAbsoluteSD(SECURITY_DESCRIPTOR* pAbsoluteSD)
{
if(!pAbsoluteSD)
{
return E_POINTER;
}
BOOL bRes;
BOOL bDaclPresent;
BOOL bDaclDefaulted;
XPtrLF<ACL> xpDacl;
bRes = GetSecurityDescriptorDacl( pAbsoluteSD,
&bDaclPresent,
&xpDacl,
&bDaclDefaulted);
if(!bRes)
{
return E_FAIL;
}
BOOL bSaclPresent;
BOOL bSaclDefaulted;
XPtrLF<ACL> xpSacl;
bRes = GetSecurityDescriptorSacl( pAbsoluteSD,
&bSaclPresent,
&xpSacl,
&bSaclDefaulted);
if(!bRes)
{
return E_FAIL;
}
BOOL bOwnerDefaulted;
XPtrLF<SID>xpOwner;
bRes = GetSecurityDescriptorOwner(pAbsoluteSD, reinterpret_cast<void**>(&xpOwner), &bOwnerDefaulted);
if(!bRes)
{
return E_FAIL;
}
BOOL bGroupDefaulted;
XPtrLF<SID>xpPrimaryGroup;
bRes = GetSecurityDescriptorGroup(pAbsoluteSD, reinterpret_cast<void**>(&xpPrimaryGroup), &bGroupDefaulted);
if(!bRes)
{
return E_FAIL;
}
return S_OK;
}
//******************************************************************************
//
// Function:
//
// Description:
//
// Parameters:
//
// Return:
//
// History: 8-26-99 leonardm Created
//
//******************************************************************************
STDMETHODIMP GetNamespaceSD(IWbemServices* pWbemServices, SECURITY_DESCRIPTOR** ppSD)
{
if(!pWbemServices)
{
return E_POINTER;
}
HRESULT hr;
XInterface<IWbemClassObject> xpOutParams;
const BSTR bstrInstancePath = SysAllocString(L"__systemsecurity=@");
if(!bstrInstancePath)
{
return E_OUTOFMEMORY;
}
const BSTR bstrMethodName = SysAllocString(L"GetSD");
if(!bstrMethodName)
{
SysFreeString(bstrInstancePath);
return E_OUTOFMEMORY;
}
hr = pWbemServices->ExecMethod( bstrInstancePath,
bstrMethodName,
0,
NULL,
NULL,
&xpOutParams,
NULL);
SysFreeString(bstrInstancePath);
SysFreeString(bstrMethodName);
if(FAILED(hr))
{
return hr;
}
VARIANT v;
XVariant xv(&v);
VariantInit(&v);
hr = xpOutParams->Get(L"sd", 0, &v, NULL, NULL);
if(FAILED(hr))
{
return hr;
}
if(v.vt != (VT_ARRAY | VT_UI1))
{
return E_FAIL;
}
long lLowerBound;
hr = SafeArrayGetLBound(v.parray, 1, &lLowerBound);
if(FAILED(hr))
{
return hr;
}
long lUpperBound;
hr = SafeArrayGetUBound(v.parray, 1, &lUpperBound);
if(FAILED(hr))
{
return hr;
}
DWORD dwSize = static_cast<DWORD>(lUpperBound - lLowerBound + 1);
XPtrLF<SECURITY_DESCRIPTOR> xpSelfRelativeSD = static_cast<SECURITY_DESCRIPTOR*>(LocalAlloc(LPTR, dwSize));
if(!xpSelfRelativeSD)
{
return E_OUTOFMEMORY;
}
BYTE* pSrc;
hr = SafeArrayAccessData(v.parray, reinterpret_cast<void**>(&pSrc));
if(FAILED(hr))
{
return hr;
}
CopyMemory(xpSelfRelativeSD, pSrc, dwSize);
hr = SafeArrayUnaccessData(v.parray);
if(FAILED(hr))
{
return hr;
}
*ppSD = xpSelfRelativeSD.Acquire();
return S_OK;
}
//******************************************************************************
//
// Function:
//
// Description:
//
// Parameters:
//
// Return:
//
// History: 8/20/99 leonardm Created.
//
//******************************************************************************
STDMETHODIMP SetNamespaceSD(SECURITY_DESCRIPTOR* pSD, IWbemServices* pWbemServices)
{
if(!pWbemServices)
{
return E_POINTER;
}
HRESULT hr;
//
// Get the class object
//
XInterface<IWbemClassObject> xpClass;
BSTR bstrClassPath = SysAllocString(L"__systemsecurity");
if(!bstrClassPath)
{
return E_OUTOFMEMORY;
}
hr = pWbemServices->GetObject(bstrClassPath, 0, NULL, &xpClass, NULL);
SysFreeString(bstrClassPath);
if(FAILED(hr))
{
return hr;
}
//
// Get the input parameter class
//
XInterface<IWbemClassObject> xpMethod;
hr = xpClass->GetMethod(L"SetSD", 0, &xpMethod, NULL);
if(FAILED(hr))
{
return hr;
}
//
// move the SD into a variant.
//
SAFEARRAYBOUND rgsabound[1];
rgsabound[0].lLbound = 0;
DWORD dwLength = GetSecurityDescriptorLength(pSD);
rgsabound[0].cElements = dwLength;
SAFEARRAY* psa = SafeArrayCreate(VT_UI1, 1, rgsabound);
if(!psa)
{
return E_FAIL;
}
BYTE* pDest = NULL;
hr = SafeArrayAccessData(psa, reinterpret_cast<void**>(&pDest));
if(FAILED(hr))
{
return hr;
}
CopyMemory(pDest, pSD, dwLength);
hr = SafeArrayUnaccessData(psa);
if(FAILED(hr))
{
return hr;
}
VARIANT v;
XVariant xv(&v);
v.vt = VT_UI1|VT_ARRAY;
v.parray = psa;
//
// put the property
//
XInterface<IWbemClassObject> xpInParam;
hr = xpMethod->SpawnInstance(0, &xpInParam);
if(FAILED(hr))
{
return hr;
}
hr = xpInParam->Put(L"sd" , 0, &v, 0);
if(FAILED(hr))
{
return hr;
}
//
// Execute the method
//
BSTR bstrInstancePath = SysAllocString(L"__systemsecurity=@");
if(!bstrInstancePath)
{
return E_OUTOFMEMORY;
}
BSTR bstrMethodName = SysAllocString(L"SetSD");
if(!bstrMethodName)
{
SysFreeString(bstrInstancePath);
return E_OUTOFMEMORY;
}
hr = pWbemServices->ExecMethod( bstrInstancePath,
bstrMethodName,
0,
NULL,
xpInParam,
NULL,
NULL);
SysFreeString(bstrInstancePath);
SysFreeString(bstrMethodName);
return hr;
}
//******************************************************************************
//
// Function:
//
// Description:
//
// Parameters:
//
// Return:
//
// History: 8/20/99 leonardm Created.
//
//******************************************************************************
HRESULT SetNamespaceSecurity(const WCHAR* pszNamespace,
long lSecurityLevel,
IWbemServices* pWbemServices)
{
HRESULT hr;
if(!pszNamespace)
{
return E_POINTER;
}
CWString sNamespace = pszNamespace;
if(!sNamespace.ValidString() || sNamespace == L"" || !pWbemServices)
{
return E_INVALIDARG;
}
XPtrLF<SECURITY_DESCRIPTOR> xpOrgSelfRelativeSD;
hr = GetNamespaceSD(pWbemServices, &xpOrgSelfRelativeSD);
if(FAILED(hr))
{
return hr;
}
SECURITY_DESCRIPTOR* pAbsoluteSD = NULL;
hr = RSoPMakeAbsoluteSD(xpOrgSelfRelativeSD, &pAbsoluteSD);
if(FAILED(hr))
{
return hr;
}
hr = ReplaceDaclOnSD(pAbsoluteSD, lSecurityLevel);
if(FAILED(hr))
{
FreeAbsoluteSD(pAbsoluteSD);
return hr;
}
//
// Make a new self-relative SD here before proceeding.
//
DWORD dwBufferLength = 0;
MakeSelfRelativeSD( pAbsoluteSD, NULL,&dwBufferLength);
DWORD dwLastError = GetLastError();
if((dwLastError != ERROR_INSUFFICIENT_BUFFER) || !dwBufferLength)
{
FreeAbsoluteSD(pAbsoluteSD);
return E_FAIL;
}
XPtrLF<SECURITY_DESCRIPTOR> xpNewSelfRelativeSD = reinterpret_cast<SECURITY_DESCRIPTOR*>(LocalAlloc(LPTR, dwBufferLength));
if(!xpNewSelfRelativeSD)
{
FreeAbsoluteSD(pAbsoluteSD);
return E_OUTOFMEMORY;
}
BOOL bRes = MakeSelfRelativeSD( pAbsoluteSD, xpNewSelfRelativeSD, &dwBufferLength);
hr = FreeAbsoluteSD(pAbsoluteSD);
if(!bRes || FAILED(hr))
{
return E_FAIL;
}
xpNewSelfRelativeSD->Control |= SE_DACL_PROTECTED;
bRes = IsValidSecurityDescriptor(xpNewSelfRelativeSD);
if(!bRes)
{
return E_FAIL;
}
hr = SetNamespaceSD( xpNewSelfRelativeSD, pWbemServices);
return hr;
}
#undef dbg
#define dbg dbgCommon
const DWORD DEFAULT_ACE_NUM=10;
CSecDesc::CSecDesc() :
m_cAces(0), m_xpSidList(NULL),
m_cAllocated(0), m_bInitialised(FALSE), m_bFailed(FALSE)
{
m_xpSidList = (SidStruct *)LocalAlloc(LPTR, sizeof(SidStruct)*DEFAULT_ACE_NUM);
if (!m_xpSidList)
return;
m_cAllocated = DEFAULT_ACE_NUM;
m_bInitialised = TRUE;
}
CSecDesc::~CSecDesc()
{
if (m_xpSidList)
for (DWORD i = 0; i < m_cAllocated; i++)
if (m_xpSidList[i].pSid)
if (m_xpSidList[i].bUseLocalFree)
LocalFree(m_xpSidList[i].pSid);
else
FreeSid(m_xpSidList[i].pSid);
}
BOOL CSecDesc::ReAllocSidList()
{
XPtrLF<SidStruct> xSidListNew;
//
// first allocate a larger buffer
//
xSidListNew = (SidStruct *)LocalAlloc(LPTR, sizeof(SidStruct)*(m_cAllocated+DEFAULT_ACE_NUM));
if (!xSidListNew) {
dbg.Msg( DEBUG_MESSAGE_WARNING, L"CSecDesc::ReallocArgStrings Cannot add memory, error = %d", GetLastError());
m_bFailed = TRUE;
return FALSE;
}
//
// copy the arguments
//
for (DWORD i = 0; i < (m_cAllocated); i++) {
xSidListNew[i] = m_xpSidList[i];
}
m_xpSidList = xSidListNew.Acquire();
m_cAllocated+= DEFAULT_ACE_NUM;
return TRUE;
}
BOOL CSecDesc::AddLocalSystem(DWORD dwAccess, DWORD AceFlags)
{
SID_IDENTIFIER_AUTHORITY authNT = SECURITY_NT_AUTHORITY;
XPtr<SID, FreeSid> xSid;
if ((!m_bInitialised) || (m_bFailed)) {
dbg.Msg( DEBUG_MESSAGE_WARNING, L"AddLocalSystem: Not initialised or failure.");
return FALSE;
}
m_bFailed = TRUE;
if (!AllocateAndInitializeSid(&authNT, 1, SECURITY_LOCAL_SYSTEM_RID,
0, 0, 0, 0, 0, 0, 0, (PSID *)&xSid)) {
dbg.Msg( DEBUG_MESSAGE_WARNING, L"AddLocalSystem: Failed to initialize sid. Error = %d", GetLastError());
return FALSE;
}
if (m_cAces == m_cAllocated)
if (!ReAllocSidList())
return FALSE;
m_xpSidList[m_cAces].pSid = xSid.Acquire();
m_xpSidList[m_cAces].dwAccess = dwAccess;
m_xpSidList[m_cAces].AceFlags = AceFlags;
m_cAces++;
m_bFailed = FALSE;
return TRUE;
}
BOOL CSecDesc::AddAdministrators(DWORD dwAccess, DWORD AceFlags)
{
SID_IDENTIFIER_AUTHORITY authNT = SECURITY_NT_AUTHORITY;
XPtr<SID, FreeSid> xSid;
if ((!m_bInitialised) || (m_bFailed)) {
dbg.Msg( DEBUG_MESSAGE_WARNING, L"AddAdministrators: Not initialised or failure.");
return FALSE;
}
m_bFailed = TRUE;
if (!AllocateAndInitializeSid(&authNT, 2, SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_ADMINS, 0, 0,
0, 0, 0, 0, (PSID *)&xSid)) {
dbg.Msg( DEBUG_MESSAGE_WARNING, L"AddAdministrators: Failed to initialize sid. Error = %d", GetLastError());
return FALSE;
}
if (m_cAces == m_cAllocated)
if (!ReAllocSidList())
return FALSE;
m_xpSidList[m_cAces].pSid = xSid.Acquire();
m_xpSidList[m_cAces].dwAccess = dwAccess;
m_xpSidList[m_cAces].AceFlags = AceFlags;
m_cAces++;
m_bFailed = FALSE;
return TRUE;
}
BOOL CSecDesc::AddAdministratorsAsOwner()
{
SID_IDENTIFIER_AUTHORITY authNT = SECURITY_NT_AUTHORITY;
XPtr<SID, FreeSid> xSid;
if ((!m_bInitialised) || (m_bFailed)) {
dbg.Msg( DEBUG_MESSAGE_WARNING, L"AddAdministrators: Not initialised or failure.");
return FALSE;
}
m_bFailed = TRUE;
if (!AllocateAndInitializeSid(&authNT, 2, SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_ADMINS, 0, 0,
0, 0, 0, 0, (PSID *)&xSid)) {
dbg.Msg( DEBUG_MESSAGE_WARNING, L"AddAdministrators: Failed to initialize sid. Error = %d", GetLastError());
return FALSE;
}
m_xpOwnerSid = xSid.Acquire();
m_bFailed = FALSE;
return TRUE;
}
BOOL CSecDesc::AddAdministratorsAsGroup()
{
SID_IDENTIFIER_AUTHORITY authNT = SECURITY_NT_AUTHORITY;
XPtr<SID, FreeSid> xSid;
if ((!m_bInitialised) || (m_bFailed)) {
dbg.Msg( DEBUG_MESSAGE_WARNING, L"AddAdministrators: Not initialised or failure.");
return FALSE;
}
m_bFailed = TRUE;
if (!AllocateAndInitializeSid(&authNT, 2, SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_ADMINS, 0, 0,
0, 0, 0, 0, (PSID *)&xSid)) {
dbg.Msg( DEBUG_MESSAGE_WARNING, L"AddAdministrators: Failed to initialize sid. Error = %d", GetLastError());
return FALSE;
}
m_xpGrpSid = xSid.Acquire();
m_bFailed = FALSE;
return TRUE;
}
BOOL CSecDesc::AddEveryOne(DWORD dwAccess, DWORD AceFlags)
{
SID_IDENTIFIER_AUTHORITY authWORLD = SECURITY_WORLD_SID_AUTHORITY;
XPtr<SID, FreeSid> xSid;
if ((!m_bInitialised) || (m_bFailed)) {
dbg.Msg( DEBUG_MESSAGE_WARNING, L"AddEveryOne: Not initialised or failure.");
return FALSE;
}
m_bFailed = TRUE;
if (!AllocateAndInitializeSid(&authWORLD, 1, SECURITY_WORLD_RID,
0, 0, 0, 0, 0, 0, 0, (PSID *)&xSid)) {
dbg.Msg( DEBUG_MESSAGE_WARNING, L"AddEveryOne: Failed to initialize sid. Error = %d", GetLastError());
return FALSE;
}
if (m_cAces == m_cAllocated)
if (!ReAllocSidList())
return FALSE;
m_xpSidList[m_cAces].pSid = xSid.Acquire();
m_xpSidList[m_cAces].dwAccess = dwAccess;
m_xpSidList[m_cAces].AceFlags = AceFlags;
m_cAces++;
m_bFailed = FALSE;
return TRUE;
}
#if 0
BOOL CSecDesc::AddThisUser(HANDLE hToken, DWORD dwAccess, DWORD AceFlags)
{
XPtrLF<SID> xSid;
if ((!m_bInitialised) || (m_bFailed)) {
dbg.Msg( DEBUG_MESSAGE_WARNING, L"AddThisUser: Not initialised or failure.");
return FALSE;
}
m_bFailed = TRUE;
xSid = (SID *)GetUserSid(hToken);
if (!pSid) {
dbg.Msg( DEBUG_MESSAGE_WARNING, L"AddThisUser: Failed to initialize sid. Error = %d", GetLastError());
return FALSE;
}
if (m_cAces == m_cAllocated)
if (!ReAllocSidList())
return FALSE;
m_xpSidList[m_cAces].pSid = xSid.Acquire();
m_xpSidList[m_cAces].dwAccess = dwAccess;
m_xpSidList[m_cAces].bUseLocalFree = TRUE;
m_xpSidList[m_cAces].AceFlags = AceFlags;
m_cAces++;
m_bFailed = FALSE;
return TRUE;
}
#endif
BOOL CSecDesc::AddUsers(DWORD dwAccess, DWORD AceFlags)
{
SID_IDENTIFIER_AUTHORITY authNT = SECURITY_NT_AUTHORITY;
XPtr<SID, FreeSid> xSid;
if ((!m_bInitialised) || (m_bFailed)) {
dbg.Msg( DEBUG_MESSAGE_WARNING, L"AddAdministrators: Not initialised or failure.");
return FALSE;
}
m_bFailed = TRUE;
if (!AllocateAndInitializeSid(&authNT, 2, SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_USERS,
0, 0, 0, 0, 0, 0, (PSID *)&xSid)) {
dbg.Msg( DEBUG_MESSAGE_WARNING, L"AddUsers: Failed to initialize sid. Error = %d", GetLastError());
return FALSE;
}
if (m_cAces == m_cAllocated)
if (!ReAllocSidList())
return FALSE;
m_xpSidList[m_cAces].pSid = xSid.Acquire();
m_xpSidList[m_cAces].dwAccess = dwAccess;
m_xpSidList[m_cAces].AceFlags = AceFlags;
m_cAces++;
m_bFailed = FALSE;
return TRUE;
}
BOOL CSecDesc::AddAuthUsers(DWORD dwAccess, DWORD AceFlags)
{
SID_IDENTIFIER_AUTHORITY authNT = SECURITY_NT_AUTHORITY;
XPtr<SID, FreeSid> xSid;
if ((!m_bInitialised) || (m_bFailed)) {
dbg.Msg( DEBUG_MESSAGE_WARNING, L"AddAuthUsers: Not initialised or failure.");
return FALSE;
}
m_bFailed = TRUE;
if (!AllocateAndInitializeSid(&authNT, 1, SECURITY_AUTHENTICATED_USER_RID,
0, 0, 0, 0, 0, 0, 0, (PSID *)&xSid)) {
dbg.Msg( DEBUG_MESSAGE_WARNING, L"AddAuthUsers: Failed to initialize authenticated users sid. Error = %d", GetLastError());
return FALSE;
}
if (m_cAces == m_cAllocated)
if (!ReAllocSidList())
return FALSE;
m_xpSidList[m_cAces].pSid = xSid.Acquire();
m_xpSidList[m_cAces].dwAccess = dwAccess;
m_xpSidList[m_cAces].AceFlags = AceFlags;
m_cAces++;
m_bFailed = FALSE;
return TRUE;
}
BOOL CSecDesc::AddSid(PSID pSid, DWORD dwAccess, DWORD AceFlags)
{
XPtrLF<SID> pLocalSid = 0;
DWORD dwSidLen = 0;
if ((!m_bInitialised) || (m_bFailed)) {
dbg.Msg( DEBUG_MESSAGE_WARNING, L"AddSid: Not initialised or failure.");
return FALSE;
}
m_bFailed = TRUE;
if (!IsValidSid(pSid)) {
dbg.Msg( DEBUG_MESSAGE_WARNING, L"AddSid: Not a vaild Sid.");
return FALSE;
}
dwSidLen = GetLengthSid(pSid);
pLocalSid = (SID *)LocalAlloc(LPTR, dwSidLen);
if (!pLocalSid) {
dbg.Msg( DEBUG_MESSAGE_WARNING, L"AddSid: Couldn't allocate memory. Error %d", GetLastError());
return FALSE;
}
if (!CopySid(dwSidLen, pLocalSid, pSid)) {
dbg.Msg( DEBUG_MESSAGE_WARNING, L"AddSid: Couldn't copy Sid. Error %d", GetLastError());
return FALSE;
}
m_xpSidList[m_cAces].pSid = (SID *)pLocalSid.Acquire();
m_xpSidList[m_cAces].dwAccess = dwAccess;
m_xpSidList[m_cAces].bUseLocalFree = TRUE;
m_xpSidList[m_cAces].AceFlags = AceFlags;
m_cAces++;
m_bFailed = FALSE;
return TRUE;
}
PISECURITY_DESCRIPTOR CSecDesc::MakeSD()
{
XPtrLF<SECURITY_DESCRIPTOR> xsd;
PACL pAcl = 0;
DWORD cbMemSize;
DWORD cbAcl;
DWORD i;
if ((!m_bInitialised) || (m_bFailed)) {
dbg.Msg( DEBUG_MESSAGE_WARNING, L"MakeSD: Not initialised or failure.");
return NULL;
}
m_bFailed = TRUE;
cbAcl = 0;
for (i = 0; i < m_cAces; i++)
cbAcl+= GetLengthSid((SID *)(m_xpSidList[i].pSid));
cbAcl += sizeof(ACL) + m_cAces*(sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD));
//
// Allocate space for the SECURITY_DESCRIPTOR + ACL
//
cbMemSize = sizeof( SECURITY_DESCRIPTOR ) + cbAcl;
xsd = (PISECURITY_DESCRIPTOR) LocalAlloc(LPTR, cbMemSize);
if (!xsd) {
dbg.Msg( DEBUG_MESSAGE_WARNING, L"CSecDesc::MakeSD: Failed to alocate security descriptor. Error = %d", GetLastError());
return NULL;
}
//
// increment psd by sizeof SECURITY_DESCRIPTOR
//
pAcl = (PACL) ( ( (unsigned char*)((SECURITY_DESCRIPTOR *)xsd) ) + sizeof(SECURITY_DESCRIPTOR) );
if (!InitializeAcl(pAcl, cbAcl, ACL_REVISION)) {
dbg.Msg( DEBUG_MESSAGE_WARNING, L"CSecDesc::MakeSD: Failed to initialize acl. Error = %d", GetLastError());
return NULL;
}
//
// Add each of the new ACEs
//
for (i = 0; i < m_cAces; i++) {
if (!AddAccessAllowedAceEx(pAcl, ACL_REVISION, m_xpSidList[i].AceFlags, m_xpSidList[i].dwAccess, m_xpSidList[i].pSid)) {
dbg.Msg( DEBUG_MESSAGE_WARNING, L"CSecDesc::MakeSD: Failed to add ace (%d). Error = %d", i, GetLastError());
return NULL;
}
}
//
// Put together the security descriptor
//
if (!InitializeSecurityDescriptor(xsd, SECURITY_DESCRIPTOR_REVISION)) {
dbg.Msg( DEBUG_MESSAGE_WARNING, L"MakeGenericSecurityDesc: Failed to initialize security descriptor. Error = %d", GetLastError());
return NULL;
}
if (!SetSecurityDescriptorDacl(xsd, TRUE, pAcl, FALSE)) {
dbg.Msg( DEBUG_MESSAGE_WARNING, L"MakeGenericSecurityDesc: Failed to set security descriptor dacl. Error = %d", GetLastError());
return NULL;
}
if (m_xpOwnerSid) {
if (!SetSecurityDescriptorOwner(xsd, m_xpOwnerSid, 0)) {
dbg.Msg( DEBUG_MESSAGE_WARNING, L"MakeGenericSecurityDesc: Failed to set security descriptor dacl. Error = %d", GetLastError());
return NULL;
}
}
if (m_xpGrpSid) {
if (!SetSecurityDescriptorGroup(xsd, m_xpGrpSid, 0)) {
dbg.Msg( DEBUG_MESSAGE_WARNING, L"MakeGenericSecurityDesc: Failed to set security descriptor dacl. Error = %d", GetLastError());
return NULL;
}
}
m_bFailed = FALSE;
return xsd.Acquire();
}
PISECURITY_DESCRIPTOR CSecDesc::MakeSelfRelativeSD()
{
XPtrLF<SECURITY_DESCRIPTOR> xAbsoluteSD;
DWORD dwLastError;
if ((!m_bInitialised) || (m_bFailed)) {
dbg.Msg( DEBUG_MESSAGE_WARNING, L"AddAdministrators: Not initialised or failure.");
return FALSE;
}
xAbsoluteSD = MakeSD();
if (!xAbsoluteSD) {
dbg.Msg( DEBUG_MESSAGE_WARNING, L"CSecDesc::MakeSelfRelativeSD: Failed to set security descriptor dacl. Error = %d", GetLastError());
return NULL;
}
m_bFailed = TRUE;
//
// Make a new self-relative SD here
//
DWORD dwBufferLength = 0;
::MakeSelfRelativeSD( xAbsoluteSD, 0, &dwBufferLength);
dwLastError = GetLastError();
if((dwLastError != ERROR_INSUFFICIENT_BUFFER) || !dwBufferLength)
{
dbg.Msg( DEBUG_MESSAGE_VERBOSE, L"CSecDesc::MakeSelfRelativeSD: MakeSelfRelativeSD failed, 0x%X", dwLastError );
return NULL;
}
XPtrLF<SECURITY_DESCRIPTOR> xsd = reinterpret_cast<SECURITY_DESCRIPTOR*>(LocalAlloc(LPTR, dwBufferLength));
if(!xsd)
{
dbg.Msg( DEBUG_MESSAGE_VERBOSE, L"CSecDesc::MakeSelfRelativeSD: MakeSelfRelativeSD failed, 0x%X", E_OUTOFMEMORY );
return NULL;
}
BOOL bRes = ::MakeSelfRelativeSD( xAbsoluteSD, xsd, &dwBufferLength);
if (!bRes) {
dbg.Msg( DEBUG_MESSAGE_VERBOSE, L"CSecDesc::MakeSelfRelativeSD: MakeSelfRelativeSD failed, 0x%X", GetLastError() );
return NULL;
}
m_bFailed = FALSE;
return xsd.Acquire();
}