+++ /dev/null
-/*
- * PROJECT: ReactOS Service Host
- * LICENSE: BSD - See COPYING.ARM in the top level directory
- * FILE: base/services/svchost/security.cxx
- * PURPOSE: Initializes the COM Object Security Model and Parameters
- * PROGRAMMERS: ReactOS Portable Systems Group
- */
-
-/* INCLUDES ******************************************************************/
-
-extern "C"
-{
-#include "svchost.h"
-
-#include <aclapi.h>
-#include <objidl.h>
-}
-
-/* GLOBALS *******************************************************************/
-
-SID NtSid = { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SYSTEM_RID } };
-
-/* FUNCTIONS *****************************************************************/
-
-DWORD
-WINAPI
-DwInitializeSdFromThreadToken (
- _Out_ PVOID *ppSecurityDescriptor,
- _Out_ PACL *ppAcl
- )
-{
- HANDLE hToken;
- DWORD dwGroupLength, dwUserLength, dwError, dwAlignLength;
- PTOKEN_PRIMARY_GROUP pTokenGroup;
- PTOKEN_USER pTokenUser;
- EXPLICIT_ACCESS_W pListOfExplicitEntries;
- PACL pAcl = NULL;
- PISECURITY_DESCRIPTOR pSd;
-
- /* Assume failure */
- *ppSecurityDescriptor = NULL;
- *ppAcl = NULL;
-
- /* Open the token of the current thread */
- if (OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, 0, &hToken) == FALSE)
- {
- /* The thread is not impersonating, use the process token */
- if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken) == FALSE)
- {
- /* No token could be queried, fail */
- return GetLastError();
- }
- }
-
- /* Get the size of the token's user */
- if ((GetTokenInformation(hToken, TokenUser, NULL, 0, &dwUserLength) == FALSE) ||
- (GetLastError() != ERROR_INSUFFICIENT_BUFFER))
- {
- return GetLastError();
- }
-
- /* Get the size of the token's primary group */
- if ((GetTokenInformation(hToken, TokenPrimaryGroup, NULL, 0, &dwGroupLength) == FALSE) ||
- (GetLastError() != ERROR_INSUFFICIENT_BUFFER))
- {
- return GetLastError();
- }
-
- /* Allocate an SD large enough to hold the SIDs for the above */
- dwAlignLength = ALIGN_UP(dwUserLength, ULONG);
- pSd = (PISECURITY_DESCRIPTOR)MemAlloc(0,
- dwAlignLength +
- dwGroupLength +
- sizeof(*pSd));
- if (pSd == NULL) return ERROR_OUTOFMEMORY;
-
- /* Assume success for now */
- dwError = ERROR_SUCCESS;
-
- /* We'll put them right after the SD itself */
- pTokenUser = (PTOKEN_USER)(pSd + 1);
- pTokenGroup = (PTOKEN_PRIMARY_GROUP)((ULONG_PTR)pTokenUser + dwAlignLength);
-
- /* Now initialize it */
- if (InitializeSecurityDescriptor(pSd, SECURITY_DESCRIPTOR_REVISION) == FALSE)
- {
- dwError = GetLastError();
- }
-
- /* And do the actual query for the user */
- if (GetTokenInformation(hToken,
- TokenUser,
- pTokenUser,
- dwUserLength,
- &dwUserLength) == FALSE)
- {
- dwError = GetLastError();
- }
-
- /* And then the actual query for the primary group */
- if (GetTokenInformation(hToken,
- TokenPrimaryGroup,
- pTokenGroup,
- dwGroupLength,
- &dwGroupLength) == FALSE)
- {
- dwError = GetLastError();
- }
-
- /* Set the user as owner */
- if (SetSecurityDescriptorOwner(pSd, pTokenUser->User.Sid, FALSE) == FALSE)
- {
- dwError = GetLastError();
- }
-
- /* Set the group as primary */
- if (SetSecurityDescriptorGroup(pSd, pTokenGroup->PrimaryGroup, FALSE) == FALSE)
- {
- dwError = GetLastError();
- }
-
- /* Did everything so far work out? */
- if (dwError == ERROR_SUCCESS)
- {
- /* Yes, create an ACL granting the SYSTEM account access */
- pListOfExplicitEntries.grfAccessMode = SET_ACCESS;
- pListOfExplicitEntries.Trustee.TrusteeType = TRUSTEE_IS_GROUP;
- pListOfExplicitEntries.grfAccessPermissions = 1;
- pListOfExplicitEntries.grfInheritance = 0;
- pListOfExplicitEntries.Trustee.pMultipleTrustee = 0;
- pListOfExplicitEntries.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
- pListOfExplicitEntries.Trustee.TrusteeForm = TRUSTEE_IS_SID;
- pListOfExplicitEntries.Trustee.ptstrName = (LPWSTR)&NtSid;
- dwError = SetEntriesInAclW(1, &pListOfExplicitEntries, NULL, &pAcl);
- if (dwError == ERROR_SUCCESS)
- {
- /* Make that ACL the DACL of the SD we just built */
- if (SetSecurityDescriptorDacl(pSd, 1, pAcl, FALSE) == FALSE)
- {
- /* We failed, bail out */
- LocalFree(pAcl);
- dwError = GetLastError();
- }
- else
- {
- /* Now we have the SD and the ACL all ready to go */
- *ppSecurityDescriptor = pSd;
- *ppAcl = pAcl;
- return ERROR_SUCCESS;
- }
- }
- }
-
- /* Failure path, we'll free the SD since the caller can't use it */
- MemFree(pSd);
- return dwError;
-}
-
-BOOL
-WINAPI
-InitializeSecurity (
- _In_ DWORD dwParam,
- _In_ DWORD dwAuthnLevel,
- _In_ DWORD dwImpLevel,
- _In_ DWORD dwCapabilities
- )
-{
- HRESULT hr;
- PACL pAcl;
- PSECURITY_DESCRIPTOR pSecurityDescriptor;
- IGlobalOptions *pGlobalOptions;
- ASSERT(dwParam != 0);
-
- /* Create a valid SD and ACL based on the current thread's token */
- if (DwInitializeSdFromThreadToken(&pSecurityDescriptor, &pAcl) == ERROR_SUCCESS)
- {
- /* It worked -- initialize COM without DDE support */
- hr = CoInitializeEx(NULL, COINIT_DISABLE_OLE1DDE);
- }
- else
- {
- /* Don't keep going if we don't have an SD */
- hr = E_FAIL;
- }
-
- /* Did we make it? */
- if (SUCCEEDED(hr))
- {
- /* Indeed, initialize COM security now */
- DBG_TRACE("Calling CoInitializeSecurity (dwAuthCapabilities = 0x%08x)\n",
- dwCapabilities);
- hr = CoInitializeSecurity(pSecurityDescriptor,
- -1,
- NULL,
- NULL,
- dwAuthnLevel,
- dwImpLevel,
- NULL,
- dwCapabilities,
- NULL);
- if (FAILED(hr)) DBG_ERR("CoInitializeSecurity returned hr=0x%08x\n", hr);
- }
-
- /* Free the SD and ACL since we no longer need it */
- MemFree(pSecurityDescriptor);
- LocalFree(pAcl);
-
- /* Did we initialize COM correctly? */
- if (SUCCEEDED(hr))
- {
- /* Get the COM Global Options Interface */
- hr = CoCreateInstance(CLSID_GlobalOptions,
- NULL,
- CLSCTX_INPROC_SERVER,
- IID_IGlobalOptions,
- (LPVOID*)&pGlobalOptions);
- if (SUCCEEDED(hr))
- {
- /* Use it to disable COM exception handling */
- hr = pGlobalOptions->Set(COMGLB_EXCEPTION_HANDLING,
- COMGLB_EXCEPTION_DONOT_HANDLE);
- pGlobalOptions->Release();
- ASSERT(SUCCEEDED(hr));
- }
- }
-
- /* Return whether all COM calls were successful or not */
- return SUCCEEDED(hr);
-}