DbConnectionPoolIdentity.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Data / System / Data / ProviderBase / DbConnectionPoolIdentity.cs / 1305376 / DbConnectionPoolIdentity.cs

                            //------------------------------------------------------------------------------ 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// [....] 
//-----------------------------------------------------------------------------
 
namespace System.Data.ProviderBase { 

    using System; 
    using System.Collections;
    using System.Data.Common;
    using System.Diagnostics;
    using System.Globalization; 
    using System.Runtime.CompilerServices;
    using System.Runtime.InteropServices; 
    using System.Security; 
    using System.Security.Permissions;
    using System.Security.Principal; 
    using System.Threading;
    using System.Runtime.Versioning;

    [Serializable] // Serializable so SqlDependencyProcessDispatcher can marshall cross domain to SqlDependency. 
    sealed internal class DbConnectionPoolIdentity {
        private const int E_NotImpersonationToken      = unchecked((int)0x8007051D); 
        private const int Win32_CheckTokenMembership   = 1; 
        private const int Win32_GetTokenInformation_1  = 2;
        private const int Win32_GetTokenInformation_2  = 3; 
        private const int Win32_ConvertSidToStringSidW = 4;
        private const int Win32_CreateWellKnownSid     = 5;

        static public  readonly DbConnectionPoolIdentity NoIdentity = new DbConnectionPoolIdentity(String.Empty, false, true); 
        static private readonly byte[]                   NetworkSid = (ADP.IsWindowsNT ? CreateWellKnownSid(WellKnownSidType.NetworkSid) : null);
 
        private readonly string _sidString; 
        private readonly bool   _isRestricted;
        private readonly bool   _isNetwork; 

        private DbConnectionPoolIdentity (string sidString, bool isRestricted, bool isNetwork) {
            _sidString = sidString;
            _isRestricted = isRestricted; 
            _isNetwork = isNetwork;
        } 
 
        internal bool IsRestricted {
            get { return _isRestricted; } 
        }

#if !ORACLE
        internal bool IsNetwork { 
            get { return _isNetwork; }
        } 
#endif 

        static private byte[] CreateWellKnownSid(WellKnownSidType sidType) { 
            // Passing an array as big as it can ever be is a small price to pay for
            // not having to P/Invoke twice (once to get the buffer, once to get the data)

            uint length = ( uint )SecurityIdentifier.MaxBinaryLength; 
            byte[] resultSid = new byte[ length ];
 
            // NOTE - We copied this code from System.Security.Principal.Win32.CreateWellKnownSid... 

            if ( 0 == UnsafeNativeMethods.CreateWellKnownSid(( int )sidType, null, resultSid, ref length )) { 
                IntegratedSecurityError(Win32_CreateWellKnownSid);
            }
            return resultSid;
        } 

        override public bool Equals(object value) { 
            bool result = ((this == NoIdentity) || (this == value)); 
            if (!result && (null != value)) {
                DbConnectionPoolIdentity that = ((DbConnectionPoolIdentity) value); 
                result = ((this._sidString == that._sidString) && (this._isRestricted == that._isRestricted) && (this._isNetwork == that._isNetwork));
            }
            return result;
        } 

        [SecurityPermission(SecurityAction.Assert, Flags=SecurityPermissionFlag.ControlPrincipal)] 
        static internal WindowsIdentity GetCurrentWindowsIdentity() { 
            return WindowsIdentity.GetCurrent();
        } 

        [SecurityPermission(SecurityAction.Assert, Flags=SecurityPermissionFlag.UnmanagedCode)]
        static private IntPtr GetWindowsIdentityToken(WindowsIdentity identity) {
            return identity.Token; 
        }
 
        [ResourceExposure(ResourceScope.None)] // SxS: this method does not create named objects 
        [ResourceConsumption(ResourceScope.Process, ResourceScope.Process)]
        static internal DbConnectionPoolIdentity GetCurrent() { 

            // DEVNOTE: GetTokenInfo and EqualSID do not work on 9x.  WindowsIdentity does not
            //          work either on 9x.  In fact, after checking with native there is no way
            //          to validate the user on 9x, so simply don't.  It is a known issue in 
            //          native, and we will handle this the same way.
 
            if (!ADP.IsWindowsNT) { 
                return NoIdentity;
            } 

            WindowsIdentity identity     = GetCurrentWindowsIdentity();
            IntPtr          token        = GetWindowsIdentityToken(identity); // Free'd by WindowsIdentity.
            uint            bufferLength = 2048;           // Suggested default given by Greg Fee. 
            uint            lengthNeeded = 0;
 
            IntPtr          tokenStruct = IntPtr.Zero; 
            IntPtr          SID;
            IntPtr          sidStringBuffer = IntPtr.Zero; 
            bool            isNetwork;

            UnsafeNativeMethods.SetLastError(0); // SQLBUDT #373863 - IsTokenRestricted doesn't clear this in all cases.
 
            bool            isRestricted = UnsafeNativeMethods.IsTokenRestricted(token);
            int             isRestrictedTestError = Marshal.GetLastWin32Error(); 
 
            if (0 != isRestrictedTestError) {
                Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error()); // will only throw if (hresult < 0) 
            }

            DbConnectionPoolIdentity current = null;
 
            RuntimeHelpers.PrepareConstrainedRegions();
            try { 
                if (!UnsafeNativeMethods.CheckTokenMembership(token, NetworkSid, out isNetwork)) { 
                    // will always fail with 0x8007051D if token is not an impersonation token
                    IntegratedSecurityError(Win32_CheckTokenMembership); 
                }

                RuntimeHelpers.PrepareConstrainedRegions();
                try { } finally { 
                    // allocating memory and assigning to tokenStruct must happen
                    tokenStruct = SafeNativeMethods.LocalAlloc(DbBuffer.LMEM_FIXED, (IntPtr)bufferLength); 
                } 
                if (IntPtr.Zero == tokenStruct) {
                    throw new OutOfMemoryException(); 
                }
                if (!UnsafeNativeMethods.GetTokenInformation(token, 1, tokenStruct, bufferLength, ref lengthNeeded)) {
                    if (lengthNeeded > bufferLength) {
                        bufferLength = lengthNeeded; 

                        RuntimeHelpers.PrepareConstrainedRegions(); 
                        try { } finally { 
                            // freeing token struct and setting tokenstruct to null must happen together
                            // allocating memory and assigning to tokenStruct must happen 
                            SafeNativeMethods.LocalFree(tokenStruct);
                            tokenStruct = IntPtr.Zero; // protect against LocalAlloc throwing an exception
                            tokenStruct = SafeNativeMethods.LocalAlloc(DbBuffer.LMEM_FIXED, (IntPtr)bufferLength);
                        } 
                        if (IntPtr.Zero == tokenStruct) {
                            throw new OutOfMemoryException(); 
                        } 

                        if (!UnsafeNativeMethods.GetTokenInformation(token, 1, tokenStruct, bufferLength, ref lengthNeeded)) { 
                            IntegratedSecurityError(Win32_GetTokenInformation_1);
                        }
                    }
                    else { 
                        IntegratedSecurityError(Win32_GetTokenInformation_2);
                    } 
                } 

                identity.Dispose(); // Keep identity variable alive until after GetTokenInformation calls. 


                SID = Marshal.ReadIntPtr(tokenStruct, 0);
 
                if (!UnsafeNativeMethods.ConvertSidToStringSidW(SID, out sidStringBuffer)) {
                    IntegratedSecurityError(Win32_ConvertSidToStringSidW); 
                } 

                if (IntPtr.Zero == sidStringBuffer) { 
                    throw ADP.InternalError(ADP.InternalErrorCode.ConvertSidToStringSidWReturnedNull);
                }

                string sidString = Marshal.PtrToStringUni(sidStringBuffer); 
                current = new DbConnectionPoolIdentity(sidString, isRestricted, isNetwork);
            } 
            finally { 
                // Marshal.FreeHGlobal does not have a ReliabilityContract
                if (IntPtr.Zero != tokenStruct) { 
                    SafeNativeMethods.LocalFree(tokenStruct);
                    tokenStruct = IntPtr.Zero;
                }
                if (IntPtr.Zero != sidStringBuffer) { 
                    SafeNativeMethods.LocalFree(sidStringBuffer);
                    sidStringBuffer = IntPtr.Zero; 
                } 
            }
            return current; 
        }

        override public int GetHashCode() {
            return (null != _sidString) ? _sidString.GetHashCode() : 0; 
        }
 
        static private void IntegratedSecurityError(int caller) { 
            // passing 1,2,3,4,5 instead of true/false so that with a debugger
            // we could determine more easily which Win32 method call failed 
            int lastError = Marshal.GetHRForLastWin32Error();
            if ((Win32_CheckTokenMembership != caller) || (E_NotImpersonationToken != lastError)) {
                Marshal.ThrowExceptionForHR(lastError); // will only throw if (hresult < 0)
            } 
        }
 
    } 
}
 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------ 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// [....] 
//-----------------------------------------------------------------------------
 
namespace System.Data.ProviderBase { 

    using System; 
    using System.Collections;
    using System.Data.Common;
    using System.Diagnostics;
    using System.Globalization; 
    using System.Runtime.CompilerServices;
    using System.Runtime.InteropServices; 
    using System.Security; 
    using System.Security.Permissions;
    using System.Security.Principal; 
    using System.Threading;
    using System.Runtime.Versioning;

    [Serializable] // Serializable so SqlDependencyProcessDispatcher can marshall cross domain to SqlDependency. 
    sealed internal class DbConnectionPoolIdentity {
        private const int E_NotImpersonationToken      = unchecked((int)0x8007051D); 
        private const int Win32_CheckTokenMembership   = 1; 
        private const int Win32_GetTokenInformation_1  = 2;
        private const int Win32_GetTokenInformation_2  = 3; 
        private const int Win32_ConvertSidToStringSidW = 4;
        private const int Win32_CreateWellKnownSid     = 5;

        static public  readonly DbConnectionPoolIdentity NoIdentity = new DbConnectionPoolIdentity(String.Empty, false, true); 
        static private readonly byte[]                   NetworkSid = (ADP.IsWindowsNT ? CreateWellKnownSid(WellKnownSidType.NetworkSid) : null);
 
        private readonly string _sidString; 
        private readonly bool   _isRestricted;
        private readonly bool   _isNetwork; 

        private DbConnectionPoolIdentity (string sidString, bool isRestricted, bool isNetwork) {
            _sidString = sidString;
            _isRestricted = isRestricted; 
            _isNetwork = isNetwork;
        } 
 
        internal bool IsRestricted {
            get { return _isRestricted; } 
        }

#if !ORACLE
        internal bool IsNetwork { 
            get { return _isNetwork; }
        } 
#endif 

        static private byte[] CreateWellKnownSid(WellKnownSidType sidType) { 
            // Passing an array as big as it can ever be is a small price to pay for
            // not having to P/Invoke twice (once to get the buffer, once to get the data)

            uint length = ( uint )SecurityIdentifier.MaxBinaryLength; 
            byte[] resultSid = new byte[ length ];
 
            // NOTE - We copied this code from System.Security.Principal.Win32.CreateWellKnownSid... 

            if ( 0 == UnsafeNativeMethods.CreateWellKnownSid(( int )sidType, null, resultSid, ref length )) { 
                IntegratedSecurityError(Win32_CreateWellKnownSid);
            }
            return resultSid;
        } 

        override public bool Equals(object value) { 
            bool result = ((this == NoIdentity) || (this == value)); 
            if (!result && (null != value)) {
                DbConnectionPoolIdentity that = ((DbConnectionPoolIdentity) value); 
                result = ((this._sidString == that._sidString) && (this._isRestricted == that._isRestricted) && (this._isNetwork == that._isNetwork));
            }
            return result;
        } 

        [SecurityPermission(SecurityAction.Assert, Flags=SecurityPermissionFlag.ControlPrincipal)] 
        static internal WindowsIdentity GetCurrentWindowsIdentity() { 
            return WindowsIdentity.GetCurrent();
        } 

        [SecurityPermission(SecurityAction.Assert, Flags=SecurityPermissionFlag.UnmanagedCode)]
        static private IntPtr GetWindowsIdentityToken(WindowsIdentity identity) {
            return identity.Token; 
        }
 
        [ResourceExposure(ResourceScope.None)] // SxS: this method does not create named objects 
        [ResourceConsumption(ResourceScope.Process, ResourceScope.Process)]
        static internal DbConnectionPoolIdentity GetCurrent() { 

            // DEVNOTE: GetTokenInfo and EqualSID do not work on 9x.  WindowsIdentity does not
            //          work either on 9x.  In fact, after checking with native there is no way
            //          to validate the user on 9x, so simply don't.  It is a known issue in 
            //          native, and we will handle this the same way.
 
            if (!ADP.IsWindowsNT) { 
                return NoIdentity;
            } 

            WindowsIdentity identity     = GetCurrentWindowsIdentity();
            IntPtr          token        = GetWindowsIdentityToken(identity); // Free'd by WindowsIdentity.
            uint            bufferLength = 2048;           // Suggested default given by Greg Fee. 
            uint            lengthNeeded = 0;
 
            IntPtr          tokenStruct = IntPtr.Zero; 
            IntPtr          SID;
            IntPtr          sidStringBuffer = IntPtr.Zero; 
            bool            isNetwork;

            UnsafeNativeMethods.SetLastError(0); // SQLBUDT #373863 - IsTokenRestricted doesn't clear this in all cases.
 
            bool            isRestricted = UnsafeNativeMethods.IsTokenRestricted(token);
            int             isRestrictedTestError = Marshal.GetLastWin32Error(); 
 
            if (0 != isRestrictedTestError) {
                Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error()); // will only throw if (hresult < 0) 
            }

            DbConnectionPoolIdentity current = null;
 
            RuntimeHelpers.PrepareConstrainedRegions();
            try { 
                if (!UnsafeNativeMethods.CheckTokenMembership(token, NetworkSid, out isNetwork)) { 
                    // will always fail with 0x8007051D if token is not an impersonation token
                    IntegratedSecurityError(Win32_CheckTokenMembership); 
                }

                RuntimeHelpers.PrepareConstrainedRegions();
                try { } finally { 
                    // allocating memory and assigning to tokenStruct must happen
                    tokenStruct = SafeNativeMethods.LocalAlloc(DbBuffer.LMEM_FIXED, (IntPtr)bufferLength); 
                } 
                if (IntPtr.Zero == tokenStruct) {
                    throw new OutOfMemoryException(); 
                }
                if (!UnsafeNativeMethods.GetTokenInformation(token, 1, tokenStruct, bufferLength, ref lengthNeeded)) {
                    if (lengthNeeded > bufferLength) {
                        bufferLength = lengthNeeded; 

                        RuntimeHelpers.PrepareConstrainedRegions(); 
                        try { } finally { 
                            // freeing token struct and setting tokenstruct to null must happen together
                            // allocating memory and assigning to tokenStruct must happen 
                            SafeNativeMethods.LocalFree(tokenStruct);
                            tokenStruct = IntPtr.Zero; // protect against LocalAlloc throwing an exception
                            tokenStruct = SafeNativeMethods.LocalAlloc(DbBuffer.LMEM_FIXED, (IntPtr)bufferLength);
                        } 
                        if (IntPtr.Zero == tokenStruct) {
                            throw new OutOfMemoryException(); 
                        } 

                        if (!UnsafeNativeMethods.GetTokenInformation(token, 1, tokenStruct, bufferLength, ref lengthNeeded)) { 
                            IntegratedSecurityError(Win32_GetTokenInformation_1);
                        }
                    }
                    else { 
                        IntegratedSecurityError(Win32_GetTokenInformation_2);
                    } 
                } 

                identity.Dispose(); // Keep identity variable alive until after GetTokenInformation calls. 


                SID = Marshal.ReadIntPtr(tokenStruct, 0);
 
                if (!UnsafeNativeMethods.ConvertSidToStringSidW(SID, out sidStringBuffer)) {
                    IntegratedSecurityError(Win32_ConvertSidToStringSidW); 
                } 

                if (IntPtr.Zero == sidStringBuffer) { 
                    throw ADP.InternalError(ADP.InternalErrorCode.ConvertSidToStringSidWReturnedNull);
                }

                string sidString = Marshal.PtrToStringUni(sidStringBuffer); 
                current = new DbConnectionPoolIdentity(sidString, isRestricted, isNetwork);
            } 
            finally { 
                // Marshal.FreeHGlobal does not have a ReliabilityContract
                if (IntPtr.Zero != tokenStruct) { 
                    SafeNativeMethods.LocalFree(tokenStruct);
                    tokenStruct = IntPtr.Zero;
                }
                if (IntPtr.Zero != sidStringBuffer) { 
                    SafeNativeMethods.LocalFree(sidStringBuffer);
                    sidStringBuffer = IntPtr.Zero; 
                } 
            }
            return current; 
        }

        override public int GetHashCode() {
            return (null != _sidString) ? _sidString.GetHashCode() : 0; 
        }
 
        static private void IntegratedSecurityError(int caller) { 
            // passing 1,2,3,4,5 instead of true/false so that with a debugger
            // we could determine more easily which Win32 method call failed 
            int lastError = Marshal.GetHRForLastWin32Error();
            if ((Win32_CheckTokenMembership != caller) || (E_NotImpersonationToken != lastError)) {
                Marshal.ThrowExceptionForHR(lastError); // will only throw if (hresult < 0)
            } 
        }
 
    } 
}
 

// 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