//****************************************************************************** // // 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 #include #include #include #include #include #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 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 xpExplicitAccess = NULL; DWORD dwCount = 2; XPtrArray 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 xpAbsoluteSD; XPtrLF xpDacl; XPtrLF xpSacl; XPtrLF xpOwner; XPtrLF 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(LocalAlloc(LPTR, dwAbsoluteSecurityDescriptorSize)); if(!xpAbsoluteSD) { return E_OUTOFMEMORY; } if(dwDaclSize) { xpDacl = reinterpret_cast(LocalAlloc(LPTR, dwDaclSize)); if(!xpDacl) { return E_OUTOFMEMORY; } } if(dwSaclSize) { xpSacl = reinterpret_cast(LocalAlloc(LPTR, dwSaclSize)); if(!xpSacl) { return E_OUTOFMEMORY; } } if(dwOwnerSize) { xpOwner = reinterpret_cast(LocalAlloc(LPTR, dwOwnerSize)); if(!xpOwner) { return E_OUTOFMEMORY; } } if(dwPrimaryGroupSize) { xpPrimaryGroup = reinterpret_cast(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 xpDacl; bRes = GetSecurityDescriptorDacl( pAbsoluteSD, &bDaclPresent, &xpDacl, &bDaclDefaulted); if(!bRes) { return E_FAIL; } BOOL bSaclPresent; BOOL bSaclDefaulted; XPtrLF xpSacl; bRes = GetSecurityDescriptorSacl( pAbsoluteSD, &bSaclPresent, &xpSacl, &bSaclDefaulted); if(!bRes) { return E_FAIL; } BOOL bOwnerDefaulted; XPtrLFxpOwner; bRes = GetSecurityDescriptorOwner(pAbsoluteSD, reinterpret_cast(&xpOwner), &bOwnerDefaulted); if(!bRes) { return E_FAIL; } BOOL bGroupDefaulted; XPtrLFxpPrimaryGroup; bRes = GetSecurityDescriptorGroup(pAbsoluteSD, reinterpret_cast(&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 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(lUpperBound - lLowerBound + 1); XPtrLF xpSelfRelativeSD = static_cast(LocalAlloc(LPTR, dwSize)); if(!xpSelfRelativeSD) { return E_OUTOFMEMORY; } BYTE* pSrc; hr = SafeArrayAccessData(v.parray, reinterpret_cast(&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 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 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(&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 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 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 xpNewSelfRelativeSD = reinterpret_cast(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 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 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 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 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 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 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 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 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 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 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 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 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 xsd = reinterpret_cast(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(); }