summaryrefslogtreecommitdiff
path: root/src/vm/securityprincipal.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/vm/securityprincipal.cpp')
-rw-r--r--src/vm/securityprincipal.cpp227
1 files changed, 227 insertions, 0 deletions
diff --git a/src/vm/securityprincipal.cpp b/src/vm/securityprincipal.cpp
new file mode 100644
index 0000000000..5f31d3a24d
--- /dev/null
+++ b/src/vm/securityprincipal.cpp
@@ -0,0 +1,227 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+#include "common.h"
+
+#include "securityprincipal.h"
+#include "corhost.h"
+#include "security.h"
+
+#ifndef FEATURE_CORECLR
+INT32 QCALLTYPE COMPrincipal::ImpersonateLoggedOnUser(HANDLE hToken)
+{
+ QCALL_CONTRACT;
+
+ HRESULT hr = S_OK;
+
+ BEGIN_QCALL;
+
+#ifdef FEATURE_INCLUDE_ALL_INTERFACES
+ IHostSecurityManager *pSM = CorHost2::GetHostSecurityManager();
+ if (pSM) {
+ BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
+ hr = pSM->ImpersonateLoggedOnUser(hToken);
+ END_SO_TOLERANT_CODE_CALLING_HOST;
+ }
+ else
+#endif // FEATURE_INCLUDE_ALL_INTERFACES
+ {
+ if (!::ImpersonateLoggedOnUser(hToken))
+ hr = HRESULT_FROM_GetLastError();
+ }
+
+ STRESS_LOG2(LF_SECURITY, LL_INFO100, "COMPrincipal::ImpersonateLoggedOnUser called with hTokenSAFE = %d. Returning 0x%x\n",hToken,hr);
+
+ END_QCALL;
+
+ return hr;
+}
+
+FCIMPL3(INT32, COMPrincipal::OpenThreadToken, DWORD dwDesiredAccess, DWORD dwOpenAs, SafeHandle** phThreadTokenUNSAFE)
+{
+ CONTRACTL {
+ FCALL_CHECK;
+ PRECONDITION(CheckPointer(phThreadTokenUNSAFE));
+ } CONTRACTL_END;
+
+ HRESULT hr = S_OK;
+ HELPER_METHOD_FRAME_BEGIN_RET_0();
+
+ SafeHandle** phThreadTokenSAFE = phThreadTokenUNSAFE;
+ GCPROTECT_BEGININTERIOR(phThreadTokenSAFE);
+
+ *phThreadTokenUNSAFE = NULL;
+ HandleHolder hThreadToken;
+ {
+ GCX_PREEMP();
+ BOOL bOpenAsSelf = TRUE;
+#ifdef FEATURE_INCLUDE_ALL_INTERFACES
+ IHostSecurityManager *pSM = CorHost2::GetHostSecurityManager();
+ if (pSM) {
+ if (dwOpenAs == WINSECURITYCONTEXT_THREAD)
+ bOpenAsSelf = FALSE;
+
+ BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
+ hr = pSM->OpenThreadToken(dwDesiredAccess, bOpenAsSelf, &hThreadToken);
+ END_SO_TOLERANT_CODE_CALLING_HOST;
+ if (FAILED(hr) && dwOpenAs == WINSECURITYCONTEXT_BOTH) {
+ bOpenAsSelf = FALSE;
+ BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
+ hr = pSM->OpenThreadToken(dwDesiredAccess, bOpenAsSelf, &hThreadToken);
+ END_SO_TOLERANT_CODE_CALLING_HOST;
+ }
+ }
+ else
+#endif // FEATURE_INCLUDE_ALL_INTERFACES
+ {
+ if (dwOpenAs == WINSECURITYCONTEXT_THREAD)
+ bOpenAsSelf = FALSE;
+
+ if (!::OpenThreadToken(::GetCurrentThread(), dwDesiredAccess, bOpenAsSelf, &hThreadToken)) {
+ if (dwOpenAs == WINSECURITYCONTEXT_BOTH) {
+ bOpenAsSelf = FALSE;
+ hr = S_OK;
+ if (!::OpenThreadToken(::GetCurrentThread(), dwDesiredAccess, bOpenAsSelf, &hThreadToken))
+ hr = HRESULT_FROM_GetLastError();
+ }
+ else
+ hr = HRESULT_FROM_GetLastError();
+ }
+ }
+ }
+
+ if (SUCCEEDED(hr)) {
+ struct _gc {
+ SAFEHANDLE pSafeTokenHandle;
+ } gc;
+ gc.pSafeTokenHandle = NULL;
+
+ GCPROTECT_BEGIN(gc);
+ // Allocate a SafeHandle here
+ MethodTable *pMT = MscorlibBinder::GetClass(CLASS__SAFE_TOKENHANDLE);
+ gc.pSafeTokenHandle = (SAFEHANDLE) AllocateObject(pMT);
+ CallDefaultConstructor(gc.pSafeTokenHandle);
+ gc.pSafeTokenHandle->SetHandle((void*) hThreadToken);
+ hThreadToken.SuppressRelease();
+
+ SetObjectReference((OBJECTREF*) phThreadTokenSAFE, (OBJECTREF) gc.pSafeTokenHandle, gc.pSafeTokenHandle->GetAppDomain());
+ GCPROTECT_END();
+ }
+
+ GCPROTECT_END();
+
+ HELPER_METHOD_FRAME_END();
+ return hr;
+}
+FCIMPLEND
+
+INT32 QCALLTYPE COMPrincipal::RevertToSelf()
+{
+ QCALL_CONTRACT;
+
+ HRESULT hr = S_OK;
+
+ BEGIN_QCALL;
+
+#ifdef FEATURE_INCLUDE_ALL_INTERFACES
+ IHostSecurityManager *pSM = CorHost2::GetHostSecurityManager();
+ if (pSM) {
+ BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
+ hr = pSM->RevertToSelf();
+ END_SO_TOLERANT_CODE_CALLING_HOST;
+ }
+ else
+#endif // FEATURE_INCLUDE_ALL_INTERFACES
+ {
+ if (!::RevertToSelf())
+ hr = HRESULT_FROM_GetLastError();
+ }
+
+ STRESS_LOG1(LF_SECURITY, LL_INFO100, "COMPrincipal::RevertToSelf returning 0x%x\n",hr);
+
+ END_QCALL;
+
+ return hr;
+}
+
+INT32 QCALLTYPE COMPrincipal::SetThreadToken(HANDLE hToken)
+{
+ QCALL_CONTRACT;
+
+ HRESULT hr = S_OK;
+
+ BEGIN_QCALL;
+
+#ifdef FEATURE_INCLUDE_ALL_INTERFACES
+ IHostSecurityManager *pSM = CorHost2::GetHostSecurityManager();
+ if (pSM)
+ {
+ BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
+ hr = pSM->SetThreadToken(hToken);
+ END_SO_TOLERANT_CODE_CALLING_HOST;
+ }
+ else
+#endif // FEATURE_INCLUDE_ALL_INTERFACES
+ {
+ if (!::SetThreadToken(NULL, hToken))
+ hr = HRESULT_FROM_GetLastError();
+ }
+
+ END_QCALL;
+
+ return hr;
+}
+#endif // !FEATURE_CORECLR
+
+void COMPrincipal::CLR_ImpersonateLoggedOnUser(HANDLE hToken)
+{
+ CONTRACTL {
+ NOTHROW;
+ GC_TRIGGERS;
+ MODE_ANY;
+ } CONTRACTL_END;
+
+ HRESULT hr = S_OK;
+
+ {
+ GCX_PREEMP();
+#ifdef FEATURE_INCLUDE_ALL_INTERFACES
+ IHostSecurityManager *pSM = CorHost2::GetHostSecurityManager();
+ if (pSM) {
+ hr = pSM->RevertToSelf();
+ if (hr != S_OK)
+ {
+ // FailFast
+ STRESS_LOG2(LF_EH, LL_INFO100, "CLR_ImpersonateLoggedOnUser failed for hImpersonateToken = %d with error:0x%x\n",hToken, hr);
+ EEPOLICY_HANDLE_FATAL_ERROR(COR_E_SECURITY);
+ }
+ if (hToken != NULL)
+ hr = pSM->ImpersonateLoggedOnUser(hToken);
+ }
+ else
+#endif // FEATURE_INCLUDE_ALL_INTERFACES
+ {
+ if (!::RevertToSelf())
+ hr = HRESULT_FROM_GetLastError();
+ if (hr != S_OK)
+ {
+ // FailFast
+ STRESS_LOG2(LF_EH, LL_INFO100, "CLR_ImpersonateLoggedOnUser failed for hImpersonateToken = %d with error:0x%x\n",hToken, hr);
+ EEPOLICY_HANDLE_FATAL_ERROR(COR_E_SECURITY);
+ }
+ if (hToken != NULL && !::ImpersonateLoggedOnUser(hToken))
+ hr = HRESULT_FROM_GetLastError();
+ }
+
+ if (hr != S_OK)
+ {
+ // FailFast
+ STRESS_LOG2(LF_EH, LL_INFO100, "CLR_ImpersonateLoggedOnUser failed for hImpersonateToken = %d with error:0x%x\n",hToken, hr);
+ EEPOLICY_HANDLE_FATAL_ERROR(COR_E_SECURITY);
+ }
+ }
+
+ return;
+}
+