ImpersonationContext.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / whidbey / NetFXspW7 / ndp / fx / src / xsp / System / Web / ImpersonationContext.cs / 1 / ImpersonationContext.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

namespace System.Web { 
    using System; 
    using System.Runtime.InteropServices;
    using System.Security.Permissions; 
    using System.Web.Configuration;
    using System.Web.Hosting;
    using System.Web.Util;
 
    internal class ImpersonationContext : IDisposable {
        private HandleRef _savedToken; 
        private bool _reverted; 
        private bool _impersonating;
 
        // arg-less ctor creates dummy context
        internal ImpersonationContext() {
        }
 
        // ctor that takes a token impersonates that token
        internal ImpersonationContext(IntPtr token) { 
            ImpersonateToken(new HandleRef(this, token)); 
        }
 
        // IDisposable pattern

        ~ImpersonationContext() {
            Dispose(false); 
        }
 
        void IDisposable.Dispose() { 
            Undo();
        } 

        private void Dispose(bool disposing) {
            if (_savedToken.Handle != IntPtr.Zero) {
                try {} finally { 
                    UnsafeNativeMethods.CloseHandle(_savedToken.Handle);
                    _savedToken = new HandleRef(this, IntPtr.Zero); 
                } 
            }
        } 

        // impersonate a given token
        protected void ImpersonateToken(HandleRef token) {
            try { 
                // first revert
                _savedToken = new HandleRef(this, GetCurrentToken()); 
 
                if (_savedToken.Handle != IntPtr.Zero) {
                    if (UnsafeNativeMethods.RevertToSelf() != 0) { 
                        _reverted = true;
                    }
                }
 
                // impersonate token if not zero
                if (token.Handle != IntPtr.Zero) { 
                    if (UnsafeNativeMethods.SetThreadToken(IntPtr.Zero, token.Handle) == 0) { 
                        throw new HttpException(SR.GetString(SR.Cannot_impersonate));
                    } 

                    _impersonating = true;
                }
            } 
            catch {
                RestoreImpersonation(); 
                throw; 
            }
        } 

        // restore impersonation to the original state
        private void RestoreImpersonation() {
            // first revert before reimpersonating 
            if (_impersonating) {
                UnsafeNativeMethods.RevertToSelf(); 
                _impersonating = false; 
            }
 
            // second reimpersonate the orignal saved identity (if exists)
            if (_savedToken.Handle != IntPtr.Zero) {
                if (_reverted) {
                    if (UnsafeNativeMethods.SetThreadToken(IntPtr.Zero, _savedToken.Handle) == 0) { 
                        throw new HttpException(SR.GetString(SR.Cannot_impersonate));
                    } 
                } 

                _reverted = false; 
            }
        }

        // 'public' version of Dispose 
        internal void Undo() {
            RestoreImpersonation(); 
 
            // free unmanaged resources
            Dispose(true); 
            System.GC.SuppressFinalize(this);
        }

        // helper to get the currently impersonated token 
        private static IntPtr GetCurrentToken() {
            IntPtr token = IntPtr.Zero; 
 
            if (UnsafeNativeMethods.OpenThreadToken(
                        UnsafeNativeMethods.GetCurrentThread(), 
                        UnsafeNativeMethods.TOKEN_READ | UnsafeNativeMethods.TOKEN_IMPERSONATE,
                        true,
                        ref token) == 0) {
 
                // if the last error is ERROR_NO_TOKEN it is ok, otherwise throw
                if (Marshal.GetLastWin32Error() != UnsafeNativeMethods.ERROR_NO_TOKEN) { 
                    throw new HttpException(SR.GetString(SR.Cannot_impersonate)); 
                }
            } 

            return token;
        }
 
        // helper to check if there is a current token
        internal static bool CurrentThreadTokenExists { 
            get { 
                bool impersonating = false;
 
                try {} finally {
                   IntPtr token = GetCurrentToken();

                   if (token != IntPtr.Zero) { 
                        impersonating = true;
                        UnsafeNativeMethods.CloseHandle(token); 
                   } 
                }
 
                return impersonating;
            }
        }
    } 

    internal sealed class ProcessImpersonationContext : ImpersonationContext { 
        internal ProcessImpersonationContext() { 
            ImpersonateToken(new HandleRef(this, IntPtr.Zero));
        } 
    }

    internal sealed class ApplicationImpersonationContext : ImpersonationContext {
        internal ApplicationImpersonationContext() { 
            ImpersonateToken(new HandleRef(this, HostingEnvironment.ApplicationIdentityToken));
        } 
    } 

    internal sealed class ClientImpersonationContext : ImpersonationContext { 
        internal ClientImpersonationContext(HttpContext context) {
            Start(context, true);
        }
 
        internal ClientImpersonationContext(HttpContext context, bool throwOnError) {
            Start(context, throwOnError); 
        } 

        private void Start(HttpContext context, bool throwOnError) { 
            IntPtr token = IntPtr.Zero;

            try {
                if (context != null) { 
                    token = context.ImpersonationToken;
                } 
                else { 
                    // by default use app identity
                    token = HostingEnvironment.ApplicationIdentityToken; 
                }
            }
            catch {
                if (throwOnError) { 
                    throw;
                } 
            } 

            // only impersonate if there is a token 
            // this is to optimize for the default case of impersonation="false"
            // and no UNC identity, when requests run under process identity
            if (token != IntPtr.Zero) {
                ImpersonateToken(new HandleRef(this, token)); 
            }
        } 
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

namespace System.Web { 
    using System; 
    using System.Runtime.InteropServices;
    using System.Security.Permissions; 
    using System.Web.Configuration;
    using System.Web.Hosting;
    using System.Web.Util;
 
    internal class ImpersonationContext : IDisposable {
        private HandleRef _savedToken; 
        private bool _reverted; 
        private bool _impersonating;
 
        // arg-less ctor creates dummy context
        internal ImpersonationContext() {
        }
 
        // ctor that takes a token impersonates that token
        internal ImpersonationContext(IntPtr token) { 
            ImpersonateToken(new HandleRef(this, token)); 
        }
 
        // IDisposable pattern

        ~ImpersonationContext() {
            Dispose(false); 
        }
 
        void IDisposable.Dispose() { 
            Undo();
        } 

        private void Dispose(bool disposing) {
            if (_savedToken.Handle != IntPtr.Zero) {
                try {} finally { 
                    UnsafeNativeMethods.CloseHandle(_savedToken.Handle);
                    _savedToken = new HandleRef(this, IntPtr.Zero); 
                } 
            }
        } 

        // impersonate a given token
        protected void ImpersonateToken(HandleRef token) {
            try { 
                // first revert
                _savedToken = new HandleRef(this, GetCurrentToken()); 
 
                if (_savedToken.Handle != IntPtr.Zero) {
                    if (UnsafeNativeMethods.RevertToSelf() != 0) { 
                        _reverted = true;
                    }
                }
 
                // impersonate token if not zero
                if (token.Handle != IntPtr.Zero) { 
                    if (UnsafeNativeMethods.SetThreadToken(IntPtr.Zero, token.Handle) == 0) { 
                        throw new HttpException(SR.GetString(SR.Cannot_impersonate));
                    } 

                    _impersonating = true;
                }
            } 
            catch {
                RestoreImpersonation(); 
                throw; 
            }
        } 

        // restore impersonation to the original state
        private void RestoreImpersonation() {
            // first revert before reimpersonating 
            if (_impersonating) {
                UnsafeNativeMethods.RevertToSelf(); 
                _impersonating = false; 
            }
 
            // second reimpersonate the orignal saved identity (if exists)
            if (_savedToken.Handle != IntPtr.Zero) {
                if (_reverted) {
                    if (UnsafeNativeMethods.SetThreadToken(IntPtr.Zero, _savedToken.Handle) == 0) { 
                        throw new HttpException(SR.GetString(SR.Cannot_impersonate));
                    } 
                } 

                _reverted = false; 
            }
        }

        // 'public' version of Dispose 
        internal void Undo() {
            RestoreImpersonation(); 
 
            // free unmanaged resources
            Dispose(true); 
            System.GC.SuppressFinalize(this);
        }

        // helper to get the currently impersonated token 
        private static IntPtr GetCurrentToken() {
            IntPtr token = IntPtr.Zero; 
 
            if (UnsafeNativeMethods.OpenThreadToken(
                        UnsafeNativeMethods.GetCurrentThread(), 
                        UnsafeNativeMethods.TOKEN_READ | UnsafeNativeMethods.TOKEN_IMPERSONATE,
                        true,
                        ref token) == 0) {
 
                // if the last error is ERROR_NO_TOKEN it is ok, otherwise throw
                if (Marshal.GetLastWin32Error() != UnsafeNativeMethods.ERROR_NO_TOKEN) { 
                    throw new HttpException(SR.GetString(SR.Cannot_impersonate)); 
                }
            } 

            return token;
        }
 
        // helper to check if there is a current token
        internal static bool CurrentThreadTokenExists { 
            get { 
                bool impersonating = false;
 
                try {} finally {
                   IntPtr token = GetCurrentToken();

                   if (token != IntPtr.Zero) { 
                        impersonating = true;
                        UnsafeNativeMethods.CloseHandle(token); 
                   } 
                }
 
                return impersonating;
            }
        }
    } 

    internal sealed class ProcessImpersonationContext : ImpersonationContext { 
        internal ProcessImpersonationContext() { 
            ImpersonateToken(new HandleRef(this, IntPtr.Zero));
        } 
    }

    internal sealed class ApplicationImpersonationContext : ImpersonationContext {
        internal ApplicationImpersonationContext() { 
            ImpersonateToken(new HandleRef(this, HostingEnvironment.ApplicationIdentityToken));
        } 
    } 

    internal sealed class ClientImpersonationContext : ImpersonationContext { 
        internal ClientImpersonationContext(HttpContext context) {
            Start(context, true);
        }
 
        internal ClientImpersonationContext(HttpContext context, bool throwOnError) {
            Start(context, throwOnError); 
        } 

        private void Start(HttpContext context, bool throwOnError) { 
            IntPtr token = IntPtr.Zero;

            try {
                if (context != null) { 
                    token = context.ImpersonationToken;
                } 
                else { 
                    // by default use app identity
                    token = HostingEnvironment.ApplicationIdentityToken; 
                }
            }
            catch {
                if (throwOnError) { 
                    throw;
                } 
            } 

            // only impersonate if there is a token 
            // this is to optimize for the default case of impersonation="false"
            // and no UNC identity, when requests run under process identity
            if (token != IntPtr.Zero) {
                ImpersonateToken(new HandleRef(this, token)); 
            }
        } 
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK