private static SqlConnectionContainerHashHelper GetHashHelper(string connectionString, out SqlConnectionStringBuilder connectionStringBuilder, out DbConnectionPoolIdentity identity, out string user, string queue)
 {
     SqlConnectionContainerHashHelper helper;
     IntPtr ptr;
     Bid.NotificationsScopeEnter(out ptr, "<sc.SqlDependencyProcessDispatcher.GetHashString|DEP> %d#, queue: %ls", _staticInstance.ObjectID, queue);
     try
     {
         connectionStringBuilder = new SqlConnectionStringBuilder(connectionString);
         connectionStringBuilder.AsynchronousProcessing = true;
         connectionStringBuilder.Pooling = false;
         connectionStringBuilder.Enlist = false;
         if (queue != null)
         {
             connectionStringBuilder.ApplicationName = queue;
         }
         if (connectionStringBuilder.IntegratedSecurity)
         {
             identity = DbConnectionPoolIdentity.GetCurrent();
             user = null;
         }
         else
         {
             identity = null;
             user = connectionStringBuilder.UserID;
         }
         helper = new SqlConnectionContainerHashHelper(identity, connectionStringBuilder.ConnectionString, queue, connectionStringBuilder);
     }
     finally
     {
         Bid.ScopeLeave(ref ptr);
     }
     return helper;
 }
        internal static DbConnectionPoolIdentity GetCurrent()
        {
            DbConnectionPoolIdentity current;
            using (WindowsIdentity identity = WindowsIdentity.GetCurrent())
            {
                IntPtr token = identity.AccessToken.DangerousGetHandle();
                bool isNetwork = identity.User.IsWellKnown(WellKnownSidType.NetworkSid);
                string sidString = identity.User.Value;

                // Win32NativeMethods.IsTokenRestricted will raise exception if the native call fails
                bool isRestricted = Win32NativeMethods.IsTokenRestrictedWrapper(token);

                var lastIdentity = s_lastIdentity;
                if ((lastIdentity != null) && (lastIdentity._sidString == sidString) && (lastIdentity._isRestricted == isRestricted) && (lastIdentity._isNetwork == isNetwork))
                {
                    current = lastIdentity;
                }
                else
                {
                    current = new DbConnectionPoolIdentity(sidString, isRestricted, isNetwork);
                }
            }
            s_lastIdentity = current;
            return current;
        }
Esempio n. 3
0
        static internal DbConnectionPoolIdentity GetCurrent()
        {
            DbConnectionPoolIdentity current;

            using (WindowsIdentity identity = WindowsIdentity.GetCurrent())
            {
                IntPtr token     = identity.AccessToken.DangerousGetHandle();
                bool   isNetwork = identity.User.IsWellKnown(WellKnownSidType.NetworkSid);
                string sidString = identity.User.Value;

                // Win32NativeMethods.IsTokenRestricted will raise exception if the native call fails
                bool isRestricted = Win32NativeMethods.IsTokenRestrictedWrapper(token);

                var lastIdentity = s_lastIdentity;
                if ((lastIdentity != null) && (lastIdentity._sidString == sidString) && (lastIdentity._isRestricted == isRestricted) && (lastIdentity._isNetwork == isNetwork))
                {
                    current = lastIdentity;
                }
                else
                {
                    current = new DbConnectionPoolIdentity(sidString, isRestricted, isNetwork);
                }
            }
            s_lastIdentity = current;
            return(current);
        }
Esempio n. 4
0
        internal DbConnectionPool GetConnectionPool(DbConnectionFactory connectionFactory)
        {
            object obj2 = null;

            if (this._poolGroupOptions != null)
            {
                DbConnectionPoolIdentity noIdentity = DbConnectionPoolIdentity.NoIdentity;
                if (this._poolGroupOptions.PoolByIdentity)
                {
                    noIdentity = DbConnectionPoolIdentity.GetCurrent();
                    if (noIdentity.IsRestricted)
                    {
                        noIdentity = null;
                    }
                }
                if (noIdentity != null)
                {
                    obj2 = this._poolCollection[noIdentity];
                    if (obj2 == null)
                    {
                        DbConnectionPoolProviderInfo connectionPoolProviderInfo = connectionFactory.CreateConnectionPoolProviderInfo(this.ConnectionOptions);
                        DbConnectionPool             pool = new DbConnectionPool(connectionFactory, this, noIdentity, connectionPoolProviderInfo);
                        lock (this)
                        {
                            HybridDictionary dictionary = this._poolCollection;
                            obj2 = dictionary[noIdentity];
                            if ((obj2 == null) && this.MarkPoolGroupAsActive())
                            {
                                pool.Startup();
                                HybridDictionary dictionary2 = new HybridDictionary(1 + dictionary.Count, false);
                                foreach (DictionaryEntry entry in dictionary)
                                {
                                    dictionary2.Add(entry.Key, entry.Value);
                                }
                                dictionary2.Add(noIdentity, pool);
                                connectionFactory.PerformanceCounters.NumberOfActiveConnectionPools.Increment();
                                this._poolCollection = dictionary2;
                                this._poolCount      = dictionary2.Count;
                                obj2 = pool;
                                pool = null;
                            }
                        }
                        if (pool != null)
                        {
                            pool.Shutdown();
                        }
                    }
                }
            }
            if (obj2 == null)
            {
                lock (this)
                {
                    this.MarkPoolGroupAsActive();
                }
            }
            return((DbConnectionPool)obj2);
        }
Esempio n. 5
0
        override public bool Equals(object value)
        {
            bool result = ((this == NoIdentity) || (this == value));

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

            if (!flag && (value != null))
            {
                DbConnectionPoolIdentity identity = (DbConnectionPoolIdentity)value;
                flag = ((this._sidString == identity._sidString) && (this._isRestricted == identity._isRestricted)) && (this._isNetwork == identity._isNetwork);
            }
            return(flag);
        }
 internal SqlInternalConnectionTds(DbConnectionPoolIdentity identity, SqlConnectionString connectionOptions, object providerInfo, string newPassword, SqlConnection owningObject, bool redirectedUserInstance) : base(connectionOptions)
 {
     this._instanceName = string.Empty;
     if (connectionOptions.UserInstance && InOutOfProcHelper.InProc)
     {
         throw SQL.UserInstanceNotAvailableInProc();
     }
     this._identity = identity;
     this._poolGroupProviderInfo = (SqlConnectionPoolGroupProviderInfo) providerInfo;
     this._fResetConnection = connectionOptions.ConnectionReset;
     if (this._fResetConnection)
     {
         this._originalDatabase = connectionOptions.InitialCatalog;
         this._originalLanguage = connectionOptions.CurrentLanguage;
     }
     RuntimeHelpers.PrepareConstrainedRegions();
     try
     {
         TimeoutTimer timeout = TimeoutTimer.StartSecondsTimeout(connectionOptions.ConnectTimeout);
         this.OpenLoginEnlist(owningObject, timeout, connectionOptions, newPassword, redirectedUserInstance);
     }
     catch (OutOfMemoryException)
     {
         base.DoomThisConnection();
         throw;
     }
     catch (StackOverflowException)
     {
         base.DoomThisConnection();
         throw;
     }
     catch (ThreadAbortException)
     {
         base.DoomThisConnection();
         throw;
     }
     if (Bid.AdvancedOn)
     {
         Bid.Trace("<sc.SqlInternalConnectionTds.ctor|ADV> %d#, constructed new TDS internal connection\n", base.ObjectID);
     }
 }
Esempio n. 8
0
        // only created by DbConnectionPoolGroup.GetConnectionPool
        internal DbConnectionPool(
            DbConnectionFactory connectionFactory,
            DbConnectionPoolGroup connectionPoolGroup,
            DbConnectionPoolIdentity identity,
            DbConnectionPoolProviderInfo?connectionPoolProviderInfo)
        {
            Debug.Assert(null != connectionPoolGroup, "null connectionPoolGroup");

            if ((null != identity) && identity.IsRestricted)
            {
                throw ADP.InternalError(ADP.InternalErrorCode.AttemptingToPoolOnRestrictedToken);
            }

            _state = State.Initializing;

            lock (s_random)
            {                                                     // Random.Next is not thread-safe
                _cleanupWait = s_random.Next(12, 24) * 10 * 1000; // 2-4 minutes in 10 sec intervals
            }

            _connectionFactory          = connectionFactory;
            _connectionPoolGroup        = connectionPoolGroup;
            _connectionPoolGroupOptions = connectionPoolGroup.PoolGroupOptions;
            _connectionPoolProviderInfo = connectionPoolProviderInfo;
            _identity = identity;

            _waitHandles = new PoolWaitHandles();

            _errorWait  = ERROR_WAIT_DEFAULT;
            _errorTimer = null;  // No error yet.

            _objectList = new List <DbConnectionInternal>(MaxPoolSize);

            _poolCreateRequest = new WaitCallback(PoolCreateRequest); // used by CleanupCallback
            _state             = State.Running;

            //_cleanupTimer & QueuePoolCreateRequest is delayed until DbConnectionPoolGroup calls
            // StartBackgroundCallbacks after pool is actually in the collection
        }
        // although the new password is generally not used it must be passed to the c'tor
        // the new Login7 packet will always write out the new password (or a length of zero and no bytes if not present)
        //
        internal SqlInternalConnectionTds(
                DbConnectionPoolIdentity identity,
                SqlConnectionString connectionOptions,
                object providerInfo,
                bool redirectedUserInstance,
                SqlConnectionString userConnectionOptions = null, // NOTE: userConnectionOptions may be different to connectionOptions if the connection string has been expanded (see SqlConnectionString.Expand)
                SessionData reconnectSessionData = null,
                bool applyTransientFaultHandling = false) : base(connectionOptions)
        {
#if DEBUG
            if (reconnectSessionData != null)
            {
                reconnectSessionData._debugReconnectDataApplied = true;
            }
#endif
            Debug.Assert(reconnectSessionData == null || connectionOptions.ConnectRetryCount > 0, "Reconnect data supplied with CR turned off");

            if (connectionOptions.ConnectRetryCount > 0)
            {
                _recoverySessionData = reconnectSessionData;
                if (reconnectSessionData == null)
                {
                    _currentSessionData = new SessionData();
                }
                else
                {
                    _currentSessionData = new SessionData(_recoverySessionData);
                    _originalDatabase = _recoverySessionData._initialDatabase;
                    _originalLanguage = _recoverySessionData._initialLanguage;
                }
            }


            _identity = identity;

            _poolGroupProviderInfo = (SqlConnectionPoolGroupProviderInfo)providerInfo;
            _fResetConnection = connectionOptions.ConnectionReset;
            if (_fResetConnection && _recoverySessionData == null)
            {
                _originalDatabase = connectionOptions.InitialCatalog;
                _originalLanguage = connectionOptions.CurrentLanguage;
            }

            _timeoutErrorInternal = new SqlConnectionTimeoutErrorInternal();

            _parserLock.Wait(canReleaseFromAnyThread: false);
            ThreadHasParserLockForClose = true;   // In case of error, let ourselves know that we already own the parser lock
            try
            {
                var timeout = TimeoutTimer.StartSecondsTimeout(connectionOptions.ConnectTimeout);

                // If transient fault handling is enabled then we can retry the login upto the ConnectRetryCount.
                int connectionEstablishCount = applyTransientFaultHandling ? connectionOptions.ConnectRetryCount + 1 : 1;
                int transientRetryIntervalInMilliSeconds = connectionOptions.ConnectRetryInterval * 1000; // Max value of transientRetryInterval is 60*1000 ms. The max value allowed for ConnectRetryInterval is 60
                for (int i = 0; i < connectionEstablishCount; i++)
                {
                    try
                    {
                        OpenLoginEnlist(timeout, connectionOptions, redirectedUserInstance);
                        break;
                    }
                    catch (SqlException sqlex)
                    {
                        if (i + 1 == connectionEstablishCount
                            || !applyTransientFaultHandling
                            || timeout.IsExpired
                            || timeout.MillisecondsRemaining < transientRetryIntervalInMilliSeconds
                            || !IsTransientError(sqlex))
                        {
                            throw sqlex;
                        }
                        else
                        {
                            Thread.Sleep(transientRetryIntervalInMilliSeconds);
                        }
                    }
                }
            }
            finally
            {
                ThreadHasParserLockForClose = false;
                _parserLock.Release();
            }
        }
    private bool Start(    string                              connectionString, 
                       out string                              server, 
                       out DbConnectionPoolIdentity            identity,
                       out string                              user, 
                       out string                              database, 
                       ref string                              queueService, 
                           string                              appDomainKey, 
                           SqlDependencyPerAppDomainDispatcher dispatcher, 
                       out bool                                errorOccurred, 
                       out bool                                appDomainStart,
                           bool                                useDefaults) {
        IntPtr hscp;
        Bid.NotificationsScopeEnter(out hscp, "<sc.SqlDependencyProcessDispatcher.Start|DEP> %d#, queue: '%ls', appDomainKey: '%ls', perAppDomainDispatcher ID: '%d'", ObjectID, queueService, appDomainKey, dispatcher.ObjectID);
        try {
            Debug.Assert(this == _staticInstance, "Instance method called on non _staticInstance instance!");
            server         = null;  // Reset out params.
            identity       = null;
            user           = null;
            database       = null;
            errorOccurred  = false;
            appDomainStart = false;

            lock (_sqlDependencyPerAppDomainDispatchers) {
                if (!_sqlDependencyPerAppDomainDispatchers.ContainsKey(appDomainKey)) {
                    _sqlDependencyPerAppDomainDispatchers[appDomainKey] = dispatcher;
                }
            }

            SqlConnectionStringBuilder       connectionStringBuilder = null;
            SqlConnectionContainerHashHelper hashHelper              = GetHashHelper(    connectionString, 
                                                                                     out connectionStringBuilder, 
                                                                                     out identity, 
                                                                                     out user,
                                                                                         queueService);
#if DEBUG
            SqlConnectionString connectionStringOptions = new SqlConnectionString(connectionStringBuilder.ConnectionString);
            Bid.NotificationsTrace("<sc.SqlDependencyProcessDispatcher.Start|DEP> Modified connection string: '%ls'\n", connectionStringOptions.UsersConnectionStringForTrace());
#endif
      
            bool started = false;

            SqlConnectionContainer container = null;
            lock (_connectionContainers) {
                if (!_connectionContainers.ContainsKey(hashHelper)) {
                    Bid.NotificationsTrace("<sc.SqlDependencyProcessDispatcher.Start|DEP> %d#, hashtable miss, creating new container.\n", ObjectID);
                    container = new SqlConnectionContainer(hashHelper, appDomainKey, useDefaults);
                    _connectionContainers.Add(hashHelper, container);
                    started        = true;
                    appDomainStart = true;
                }
                else {
                    container = _connectionContainers[hashHelper];
                    Bid.NotificationsTrace("<sc.SqlDependencyProcessDispatcher.Start|DEP> %d#, hashtable hit, container: %d\n", ObjectID, container.ObjectID);
                    if (container.InErrorState) {
                        Bid.NotificationsTrace("<sc.SqlDependencyProcessDispatcher.Start|DEP> %d#, container: %d is in error state!\n", ObjectID, container.ObjectID);
                        errorOccurred = true; // Set outparam errorOccurred true so we invalidate on Start().
                    }
                    else {
                        container.IncrementStartCount(appDomainKey, out appDomainStart);
                    }
                }
            }

            if (useDefaults && !errorOccurred) { // Return server, database, and queue for use by SqlDependency.
                server       = container.Server;
                database     = container.Database;
                queueService = container.Queue;
                Bid.NotificationsTrace("<sc.SqlDependencyProcessDispatcher.Start|DEP> %d#, default service: '%ls', server: '%ls', database: '%ls'\n", ObjectID, queueService, server, database);
            }

            Bid.NotificationsTrace("<sc.SqlDependencyProcessDispatcher.Start|DEP> %d#, started: %d\n", ObjectID, started);
            
            return started;
        }
        finally {
            Bid.ScopeLeave(ref hscp);
        }
    }
    // ------------
    // Stop methods
    // ------------

    internal bool Stop(    string                   connectionString, 
                       out string                   server, 
                       out DbConnectionPoolIdentity identity, 
                       out string                   user, 
                       out string                   database, 
                       ref string                   queueService, 
                           string                   appDomainKey, 
                       out bool                     appDomainStop) {
        IntPtr hscp;
        Bid.NotificationsScopeEnter(out hscp, "<sc.SqlDependencyProcessDispatcher.Stop|DEP> %d#, queue: '%ls'", ObjectID, queueService);
        try {
            Debug.Assert(this == _staticInstance, "Instance method called on non _staticInstance instance!");
            server        = null;  // Reset out param.
            identity      = null;
            user          = null;
            database      = null;
            appDomainStop = false; 
            
            SqlConnectionStringBuilder       connectionStringBuilder = null;
            SqlConnectionContainerHashHelper hashHelper              = GetHashHelper(    connectionString,
                                                                                     out connectionStringBuilder,
                                                                                     out identity, 
                                                                                     out user,
                                                                                         queueService);
#if DEBUG
            SqlConnectionString connectionStringOptions = new SqlConnectionString(connectionStringBuilder.ConnectionString);
            Bid.NotificationsTrace("<sc.SqlDependencyProcessDispatcher.Stop|DEP> Modified connection string: '%ls'\n", connectionStringOptions.UsersConnectionStringForTrace());
#endif

            bool stopped = false;

            lock (_connectionContainers) {
                if (_connectionContainers.ContainsKey(hashHelper)) {
                    SqlConnectionContainer container = _connectionContainers[hashHelper];
                    Bid.NotificationsTrace("<sc.SqlDependencyProcessDispatcher.Stop|DEP> %d#, hashtable hit, container: %d\n", ObjectID, container.ObjectID);
                    server       = container.Server;   // Return server, database, and queue info for use by calling SqlDependency.
                    database     = container.Database;
                    queueService = container.Queue;
                    if (container.Stop(appDomainKey, out appDomainStop)) { // Stop can be blocking if refCount == 0 on container.
                        stopped = true;
                        _connectionContainers.Remove(hashHelper); // Remove from collection.
                    }
                }
                else {
                    Bid.NotificationsTrace("<sc.SqlDependencyProcessDispatcher.Stop|DEP> %d#, hashtable miss.\n", ObjectID);
                }
            }

            Bid.NotificationsTrace("<sc.SqlDependencyProcessDispatcher.Stop|DEP> %d#, stopped: %d\n", ObjectID, stopped);
            return stopped;
        }
        finally {
            Bid.ScopeLeave(ref hscp);
        }
    }        
    // -----------------------
    // Various private methods
    // -----------------------

    private static SqlConnectionContainerHashHelper GetHashHelper(    string                     connectionString,
                                                                  out SqlConnectionStringBuilder connectionStringBuilder,
                                                                  out DbConnectionPoolIdentity   identity, 
                                                                  out string                     user,
                                                                      string                     queue) {
        IntPtr hscp;
        Bid.NotificationsScopeEnter(out hscp, "<sc.SqlDependencyProcessDispatcher.GetHashString|DEP> %d#, queue: %ls", _staticInstance.ObjectID, queue);
        try {
            // Force certain connection string properties to be used by SqlDependencyProcessDispatcher.  
            // This logic is done here to enable us to have the complete connection string now to be used
            // for tracing as we flow through the logic.
            connectionStringBuilder                        = new SqlConnectionStringBuilder(connectionString);
            connectionStringBuilder.AsynchronousProcessing = true;
            connectionStringBuilder.Pooling                = false;
            connectionStringBuilder.Enlist                 = false;
            connectionStringBuilder.ConnectRetryCount      = 0;
            if (null != queue) { // User provided!
                connectionStringBuilder.ApplicationName    = queue; // ApplicationName will be set to queue name.
            }

            if (connectionStringBuilder.IntegratedSecurity) {
                // Use existing identity infrastructure for error cases and proper hash value.
                identity   = DbConnectionPoolIdentity.GetCurrent();
                user       = null;
            }
            else {
                identity   = null;
                user       = connectionStringBuilder.UserID; 
            }

            return new SqlConnectionContainerHashHelper(identity, connectionStringBuilder.ConnectionString,
                                                        queue, connectionStringBuilder);
        }
        finally {
            Bid.ScopeLeave(ref hscp);
        }
    }
    // -------------
    // Start methods
    // -------------

    internal bool StartWithDefault(    string                              connectionString, 
                                   out string                              server, 
                                   out DbConnectionPoolIdentity            identity,
                                   out string                              user, 
                                   out string                              database, 
                                   ref string                              service,
                                       string                              appDomainKey,
                                       SqlDependencyPerAppDomainDispatcher dispatcher, 
                                   out bool                                errorOccurred, 
                                   out bool                                appDomainStart) {
        Debug.Assert(this == _staticInstance, "Instance method called on non _staticInstance instance!");
        return Start(    connectionString,
                     out server, 
                     out identity, 
                     out user, 
                     out database, 
                     ref service, 
                         appDomainKey,
                         dispatcher, 
                     out errorOccurred, 
                     out appDomainStart,
                         true);
    }
 internal bool Stop(string connectionString, out string server, out DbConnectionPoolIdentity identity, out string user, out string database, ref string queueService, string appDomainKey, out bool appDomainStop)
 {
     bool flag2;
     IntPtr ptr;
     Bid.NotificationsScopeEnter(out ptr, "<sc.SqlDependencyProcessDispatcher.Stop|DEP> %d#, queue: '%ls'", this.ObjectID, queueService);
     try
     {
         server = null;
         identity = null;
         user = null;
         database = null;
         appDomainStop = false;
         SqlConnectionStringBuilder connectionStringBuilder = null;
         SqlConnectionContainerHashHelper key = GetHashHelper(connectionString, out connectionStringBuilder, out identity, out user, queueService);
         bool flag = false;
         lock (this._connectionContainers)
         {
             if (this._connectionContainers.ContainsKey(key))
             {
                 SqlConnectionContainer container = this._connectionContainers[key];
                 Bid.NotificationsTrace("<sc.SqlDependencyProcessDispatcher.Stop|DEP> %d#, hashtable hit, container: %d\n", this.ObjectID, container.ObjectID);
                 server = container.Server;
                 database = container.Database;
                 queueService = container.Queue;
                 if (container.Stop(appDomainKey, out appDomainStop))
                 {
                     flag = true;
                     this._connectionContainers.Remove(key);
                 }
             }
             else
             {
                 Bid.NotificationsTrace("<sc.SqlDependencyProcessDispatcher.Stop|DEP> %d#, hashtable miss.\n", this.ObjectID);
             }
         }
         Bid.NotificationsTrace("<sc.SqlDependencyProcessDispatcher.Stop|DEP> %d#, stopped: %d\n", this.ObjectID, flag);
         flag2 = flag;
     }
     finally
     {
         Bid.ScopeLeave(ref ptr);
     }
     return flag2;
 }
        private SqlConnectionStringBuilder _connectionStringBuilder; // Not to be used for comparison!

        internal SqlConnectionContainerHashHelper(DbConnectionPoolIdentity identity, string connectionString, 
                                                  string queue, SqlConnectionStringBuilder connectionStringBuilder) {
            _identity                = identity;
            _connectionString        = connectionString;
            _queue                   = queue;
            _connectionStringBuilder = connectionStringBuilder;
        }
Esempio n. 16
0
        // only created by DbConnectionPoolGroup.GetConnectionPool
        internal DbConnectionPool(
                            DbConnectionFactory connectionFactory,
                            DbConnectionPoolGroup connectionPoolGroup,
                            DbConnectionPoolIdentity identity,
                            DbConnectionPoolProviderInfo connectionPoolProviderInfo)
        {
            Debug.Assert(null != connectionPoolGroup, "null connectionPoolGroup");

            if ((null != identity) && identity.IsRestricted)
            {
                throw ADP.InternalError(ADP.InternalErrorCode.AttemptingToPoolOnRestrictedToken);
            }

            _state = State.Initializing;

            lock (s_random)
            { // Random.Next is not thread-safe
                _cleanupWait = s_random.Next(12, 24) * 10 * 1000; // 2-4 minutes in 10 sec intervals
            }

            _connectionFactory = connectionFactory;
            _connectionPoolGroup = connectionPoolGroup;
            _connectionPoolGroupOptions = connectionPoolGroup.PoolGroupOptions;
            _connectionPoolProviderInfo = connectionPoolProviderInfo;
            _identity = identity;

            _waitHandles = new PoolWaitHandles();

            _errorWait = ERROR_WAIT_DEFAULT;
            _errorTimer = null;  // No error yet.

            _objectList = new List<DbConnectionInternal>(MaxPoolSize);

            _poolCreateRequest = new WaitCallback(PoolCreateRequest); // used by CleanupCallback
            _state = State.Running;

            //_cleanupTimer & QueuePoolCreateRequest is delayed until DbConnectionPoolGroup calls
            // StartBackgroundCallbacks after pool is actually in the collection
        }
 internal static DbConnectionPoolIdentity GetCurrent()
 {
     if (!ADP.IsWindowsNT)
     {
         return NoIdentity;
     }
     WindowsIdentity currentWindowsIdentity = GetCurrentWindowsIdentity();
     IntPtr windowsIdentityToken = GetWindowsIdentityToken(currentWindowsIdentity);
     uint tokenInformationLength = 0x800;
     uint tokenString = 0;
     IntPtr zero = IntPtr.Zero;
     IntPtr stringSid = IntPtr.Zero;
     System.Data.Common.UnsafeNativeMethods.SetLastError(0);
     bool isRestricted = System.Data.Common.UnsafeNativeMethods.IsTokenRestricted(windowsIdentityToken);
     if (Marshal.GetLastWin32Error() != 0)
     {
         Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
     }
     DbConnectionPoolIdentity identity = null;
     RuntimeHelpers.PrepareConstrainedRegions();
     try
     {
         bool flag;
         if (!System.Data.Common.UnsafeNativeMethods.CheckTokenMembership(windowsIdentityToken, NetworkSid, out flag))
         {
             IntegratedSecurityError(1);
         }
         RuntimeHelpers.PrepareConstrainedRegions();
         try
         {
         }
         finally
         {
             zero = SafeNativeMethods.LocalAlloc(0, (IntPtr) tokenInformationLength);
         }
         if (IntPtr.Zero == zero)
         {
             throw new OutOfMemoryException();
         }
         if (!System.Data.Common.UnsafeNativeMethods.GetTokenInformation(windowsIdentityToken, 1, zero, tokenInformationLength, ref tokenString))
         {
             if (tokenString > tokenInformationLength)
             {
                 tokenInformationLength = tokenString;
                 RuntimeHelpers.PrepareConstrainedRegions();
                 try
                 {
                 }
                 finally
                 {
                     SafeNativeMethods.LocalFree(zero);
                     zero = IntPtr.Zero;
                     zero = SafeNativeMethods.LocalAlloc(0, (IntPtr) tokenInformationLength);
                 }
                 if (IntPtr.Zero == zero)
                 {
                     throw new OutOfMemoryException();
                 }
                 if (!System.Data.Common.UnsafeNativeMethods.GetTokenInformation(windowsIdentityToken, 1, zero, tokenInformationLength, ref tokenString))
                 {
                     IntegratedSecurityError(2);
                 }
             }
             else
             {
                 IntegratedSecurityError(3);
             }
         }
         currentWindowsIdentity.Dispose();
         if (!System.Data.Common.UnsafeNativeMethods.ConvertSidToStringSidW(Marshal.ReadIntPtr(zero, 0), out stringSid))
         {
             IntegratedSecurityError(4);
         }
         if (IntPtr.Zero == stringSid)
         {
             throw ADP.InternalError(ADP.InternalErrorCode.ConvertSidToStringSidWReturnedNull);
         }
         identity = new DbConnectionPoolIdentity(Marshal.PtrToStringUni(stringSid), isRestricted, flag);
     }
     finally
     {
         if (IntPtr.Zero != zero)
         {
             SafeNativeMethods.LocalFree(zero);
             zero = IntPtr.Zero;
         }
         if (IntPtr.Zero != stringSid)
         {
             SafeNativeMethods.LocalFree(stringSid);
             stringSid = IntPtr.Zero;
         }
     }
     return identity;
 }
        // although the new password is generally not used it must be passed to the c'tor
        // the new Login7 packet will always write out the new password (or a length of zero and no bytes if not present)
        //
        internal SqlInternalConnectionTds(
                DbConnectionPoolIdentity identity,
                SqlConnectionString connectionOptions,
                object providerInfo,
                bool redirectedUserInstance,
                SqlConnectionString userConnectionOptions = null, // NOTE: userConnectionOptions may be different to connectionOptions if the connection string has been expanded (see SqlConnectionString.Expand)
                SessionData reconnectSessionData = null) : base(connectionOptions)
        {
#if DEBUG
            if (reconnectSessionData != null)
            {
                reconnectSessionData._debugReconnectDataApplied = true;
            }
#endif
            Debug.Assert(reconnectSessionData == null || connectionOptions.ConnectRetryCount > 0, "Reconnect data supplied with CR turned off");

            if (connectionOptions.ConnectRetryCount > 0)
            {
                _recoverySessionData = reconnectSessionData;
                if (reconnectSessionData == null)
                {
                    _currentSessionData = new SessionData();
                }
                else
                {
                    _currentSessionData = new SessionData(_recoverySessionData);
                    _originalDatabase = _recoverySessionData._initialDatabase;
                    _originalLanguage = _recoverySessionData._initialLanguage;
                }
            }


            _identity = identity;

            _poolGroupProviderInfo = (SqlConnectionPoolGroupProviderInfo)providerInfo;
            _fResetConnection = connectionOptions.ConnectionReset;
            if (_fResetConnection && _recoverySessionData == null)
            {
                _originalDatabase = connectionOptions.InitialCatalog;
                _originalLanguage = connectionOptions.CurrentLanguage;
            }

            _timeoutErrorInternal = new SqlConnectionTimeoutErrorInternal();

            _parserLock.Wait(canReleaseFromAnyThread: false);
            ThreadHasParserLockForClose = true;   // In case of error, let ourselves know that we already own the parser lock
            try
            {
                var timeout = TimeoutTimer.StartSecondsTimeout(connectionOptions.ConnectTimeout);
                OpenLoginEnlist(timeout, connectionOptions, redirectedUserInstance);
            }
            finally
            {
                ThreadHasParserLockForClose = false;
                _parserLock.Release();
            }
        }
 internal bool StartWithDefault(string connectionString, out string server, out DbConnectionPoolIdentity identity, out string user, out string database, ref string service, string appDomainKey, SqlDependencyPerAppDomainDispatcher dispatcher, out bool errorOccurred, out bool appDomainStart)
 {
     return this.Start(connectionString, out server, out identity, out user, out database, ref service, appDomainKey, dispatcher, out errorOccurred, out appDomainStart, true);
 }
        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;

            // Win32NativeMethods.IsTokenRestricted will raise exception if the native call fails
            bool isRestricted = Win32NativeMethods.IsTokenRestrictedWrapper(token);

            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);

                var lastIdentity = _lastIdentity;
                if ((lastIdentity != null) && (lastIdentity._sidString == sidString) && (lastIdentity._isRestricted == isRestricted) && (lastIdentity._isNetwork == isNetwork))
                {
                    current = lastIdentity;
                }
                else
                {
                    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;
                }
            }
            _lastIdentity = current;
            return(current);
        }
 internal IdentityUserNamePair(DbConnectionPoolIdentity identity, string userName)
 {
     this._identity = identity;
     this._userName = userName;
 }
Esempio n. 22
0
 internal IdentityUserNamePair(DbConnectionPoolIdentity identity, string userName) {
     Debug.Assert( (identity == null && userName != null) ||
                   (identity != null && userName == null), "Unexpected arguments!"); 
     _identity = identity;
     _userName = userName;
 }
        // although the new password is generally not used it must be passed to the c'tor
        // the new Login7 packet will always write out the new password (or a length of zero and no bytes if not present)
        //
        internal SqlInternalConnectionTds(
                DbConnectionPoolIdentity    identity, 
                SqlConnectionString         connectionOptions,
                SqlCredential               credential,
                object                      providerInfo, 
                string                      newPassword,
                SecureString                newSecurePassword,
                bool                        redirectedUserInstance,
                SqlConnectionString         userConnectionOptions = null, // NOTE: userConnectionOptions may be different to connectionOptions if the connection string has been expanded (see SqlConnectionString.Expand)
                SessionData                 reconnectSessionData = null,
                DbConnectionPool            pool = null,
                string                      accessToken = null,
                bool applyTransientFaultHandling = false
                ) : base(connectionOptions) {

#if DEBUG
            if (reconnectSessionData != null) {
                reconnectSessionData._debugReconnectDataApplied = true;
            }
            try { // use this to help validate this object is only created after the following permission has been previously demanded in the current codepath
                if (userConnectionOptions != null) {
                    // As mentioned above, userConnectionOptions may be different to connectionOptions, so we need to demand on the correct connection string
                    userConnectionOptions.DemandPermission();
                }
                else {
                    connectionOptions.DemandPermission();
                }
            }
            catch(System.Security.SecurityException) {
                System.Diagnostics.Debug.Assert(false, "unexpected SecurityException for current codepath");
                throw;
            }
#endif
            Debug.Assert(reconnectSessionData == null || connectionOptions.ConnectRetryCount > 0, "Reconnect data supplied with CR turned off");

            _dbConnectionPool = pool;
  
            if (connectionOptions.ConnectRetryCount > 0) {
                _recoverySessionData = reconnectSessionData;          
                if (reconnectSessionData == null) {
                    _currentSessionData = new SessionData();
                }
                else {
                    _currentSessionData = new SessionData(_recoverySessionData);
                    _originalDatabase = _recoverySessionData._initialDatabase;
                    _originalLanguage = _recoverySessionData._initialLanguage;
                }
            }
          
            if (connectionOptions.UserInstance && InOutOfProcHelper.InProc) {
                throw SQL.UserInstanceNotAvailableInProc();
            }

            if (accessToken != null) {
                _accessTokenInBytes = System.Text.Encoding.Unicode.GetBytes(accessToken);
            }

            _identity = identity;
            Debug.Assert(newSecurePassword != null || newPassword != null, "cannot have both new secure change password and string based change password to be null");
            Debug.Assert(credential == null || (String.IsNullOrEmpty(connectionOptions.UserID) && String.IsNullOrEmpty(connectionOptions.Password)), "cannot mix the new secure password system and the connection string based password");

            Debug.Assert(credential == null || !connectionOptions.IntegratedSecurity, "Cannot use SqlCredential and Integrated Security");
            Debug.Assert(credential == null || !connectionOptions.ContextConnection, "Cannot use SqlCredential with context connection");

            _poolGroupProviderInfo = (SqlConnectionPoolGroupProviderInfo)providerInfo;
            _fResetConnection = connectionOptions.ConnectionReset;
            if (_fResetConnection && _recoverySessionData == null) {
                _originalDatabase = connectionOptions.InitialCatalog;
                _originalLanguage = connectionOptions.CurrentLanguage;
            }

            timeoutErrorInternal = new SqlConnectionTimeoutErrorInternal();
            _credential = credential;

            _parserLock.Wait(canReleaseFromAnyThread:false);
            ThreadHasParserLockForClose = true;   // In case of error, let ourselves know that we already own the parser lock
            RuntimeHelpers.PrepareConstrainedRegions();
            try {
#if DEBUG
                TdsParser.ReliabilitySection tdsReliabilitySection = new TdsParser.ReliabilitySection();

                RuntimeHelpers.PrepareConstrainedRegions();
                try {
                    tdsReliabilitySection.Start();
#else
                {
#endif //DEBUG
                    _timeout = TimeoutTimer.StartSecondsTimeout(connectionOptions.ConnectTimeout);

                    // If transient fault handling is enabled then we can retry the login upto the ConnectRetryCount.
                    int connectionEstablishCount = applyTransientFaultHandling ? connectionOptions.ConnectRetryCount + 1 : 1;
                    int transientRetryIntervalInMilliSeconds = connectionOptions.ConnectRetryInterval * 1000; // Max value of transientRetryInterval is 60*1000 ms. The max value allowed for ConnectRetryInterval is 60
                    for (int i = 0; i < connectionEstablishCount; i++)
                    {
                        try
                        {
                            OpenLoginEnlist(_timeout, connectionOptions, credential, newPassword, newSecurePassword, redirectedUserInstance);
                            break;
                        }
                        catch (SqlException sqlex)
                        {
                            if (i + 1 == connectionEstablishCount 
                                || !applyTransientFaultHandling
                                || _timeout.IsExpired
                                || _timeout.MillisecondsRemaining < transientRetryIntervalInMilliSeconds
                                || !IsTransientError(sqlex))
                            {
                                throw sqlex;
                            }
                            else
                            {
                                Thread.Sleep(transientRetryIntervalInMilliSeconds);
                            }
                        }
                    }
                }
#if DEBUG
                finally {
                    tdsReliabilitySection.Stop();
                }
#endif //DEBUG
            }
            catch (System.OutOfMemoryException) {
                DoomThisConnection();
                throw;
            }
            catch (System.StackOverflowException) {
                DoomThisConnection();
                throw;
            }
            catch (System.Threading.ThreadAbortException) {
                DoomThisConnection();
                throw;
            }
            finally {
                ThreadHasParserLockForClose = false;
                _parserLock.Release();
            }
            if (Bid.AdvancedOn) {
                Bid.Trace("<sc.SqlInternalConnectionTds.ctor|ADV> %d#, constructed new TDS internal connection\n", ObjectID);
            }
        }
        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;

            // Win32NativeMethods.IsTokenRestricted will raise exception if the native call fails
            bool            isRestricted = Win32NativeMethods.IsTokenRestrictedWrapper(token);
            
            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);

                var lastIdentity = _lastIdentity;
                if ((lastIdentity != null) && (lastIdentity._sidString == sidString) && (lastIdentity._isRestricted == isRestricted) && (lastIdentity._isNetwork == isNetwork)) {
                    current = lastIdentity;
                }
                else {
                    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;
                }
            }
            _lastIdentity = current;
            return current;
        }
        internal DbConnectionPool GetConnectionPool(DbConnectionFactory connectionFactory)
        {
            // When this method returns null it indicates that the connection
            // factory should not use pooling.

            // We don't support connection pooling on Win9x; it lacks too
            // many of the APIs we require.
            // PoolGroupOptions will only be null when we're not supposed to pool
            // connections.
            DbConnectionPool pool = null;

            if (null != _poolGroupOptions)
            {
                Debug.Assert(ADP.IsWindowsNT, "should not be pooling on Win9x");

                DbConnectionPoolIdentity currentIdentity = DbConnectionPoolIdentity.NoIdentity;
                if (_poolGroupOptions.PoolByIdentity)
                {
                    // if we're pooling by identity (because integrated security is
                    // being used for these connections) then we need to go out and
                    // search for the connectionPool that matches the current identity.

                    currentIdentity = DbConnectionPoolIdentity.GetCurrent();

                    // If the current token is restricted in some way, then we must
                    // not attempt to pool these connections.
                    if (currentIdentity.IsRestricted)
                    {
                        currentIdentity = null;
                    }
                }
                if (null != currentIdentity)
                {
                    if (!_poolCollection.TryGetValue(currentIdentity, out pool))   // find the pool
                    {
                        DbConnectionPoolProviderInfo connectionPoolProviderInfo = connectionFactory.CreateConnectionPoolProviderInfo(this.ConnectionOptions);

                        // optimistically create pool, but its callbacks are delayed until after actual add
                        DbConnectionPool newPool = new DbConnectionPool(connectionFactory, this, currentIdentity, connectionPoolProviderInfo);

                        lock (this) {
                            // Did someone already add it to the list?
                            if (!_poolCollection.TryGetValue(currentIdentity, out pool))
                            {
                                if (MarkPoolGroupAsActive())
                                {
                                    // If we get here, we know for certain that we there isn't
                                    // a pool that matches the current identity, so we have to
                                    // add the optimistically created one
                                    newPool.Startup(); // must start pool before usage
                                    bool addResult = _poolCollection.TryAdd(currentIdentity, newPool);
                                    Debug.Assert(addResult, "No other pool with current identity should exist at this point");
#if !MOBILE
                                    connectionFactory.PerformanceCounters.NumberOfActiveConnectionPools.Increment();
#endif
                                    pool    = newPool;
                                    newPool = null;
                                }
                                else
                                {
                                    // else pool entry has been disabled so don't create new pools
                                    Debug.Assert(PoolGroupStateDisabled == _state, "state should be disabled");
                                }
                            }
                            else
                            {
                                // else found an existing pool to use instead
                                Debug.Assert(PoolGroupStateActive == _state, "state should be active since a pool exists and lock holds");
                            }
                        }

                        if (null != newPool)
                        {
                            // don't need to call connectionFactory.QueuePoolForRelease(newPool) because
                            // pool callbacks were delayed and no risk of connections being created
                            newPool.Shutdown();
                        }
                    }
                    // the found pool could be in any state
                }
            }

            if (null == pool)
            {
                lock (this) {
                    // keep the pool entry state active when not pooling
                    MarkPoolGroupAsActive();
                }
            }
            return(pool);
        }
Esempio n. 26
0
        internal static DbConnectionPoolIdentity GetCurrent()
        {
            if (!ADP.IsWindowsNT)
            {
                return(NoIdentity);
            }
            WindowsIdentity currentWindowsIdentity = GetCurrentWindowsIdentity();
            IntPtr          windowsIdentityToken   = GetWindowsIdentityToken(currentWindowsIdentity);
            uint            tokenInformationLength = 0x800;
            uint            tokenString            = 0;
            IntPtr          zero      = IntPtr.Zero;
            IntPtr          stringSid = IntPtr.Zero;

            System.Data.Common.UnsafeNativeMethods.SetLastError(0);
            bool isRestricted = System.Data.Common.UnsafeNativeMethods.IsTokenRestricted(windowsIdentityToken);

            if (Marshal.GetLastWin32Error() != 0)
            {
                Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
            }
            DbConnectionPoolIdentity identity = null;

            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
                bool flag;
                if (!System.Data.Common.UnsafeNativeMethods.CheckTokenMembership(windowsIdentityToken, NetworkSid, out flag))
                {
                    IntegratedSecurityError(1);
                }
                RuntimeHelpers.PrepareConstrainedRegions();
                try
                {
                }
                finally
                {
                    zero = SafeNativeMethods.LocalAlloc(0, (IntPtr)tokenInformationLength);
                }
                if (IntPtr.Zero == zero)
                {
                    throw new OutOfMemoryException();
                }
                if (!System.Data.Common.UnsafeNativeMethods.GetTokenInformation(windowsIdentityToken, 1, zero, tokenInformationLength, ref tokenString))
                {
                    if (tokenString > tokenInformationLength)
                    {
                        tokenInformationLength = tokenString;
                        RuntimeHelpers.PrepareConstrainedRegions();
                        try
                        {
                        }
                        finally
                        {
                            SafeNativeMethods.LocalFree(zero);
                            zero = IntPtr.Zero;
                            zero = SafeNativeMethods.LocalAlloc(0, (IntPtr)tokenInformationLength);
                        }
                        if (IntPtr.Zero == zero)
                        {
                            throw new OutOfMemoryException();
                        }
                        if (!System.Data.Common.UnsafeNativeMethods.GetTokenInformation(windowsIdentityToken, 1, zero, tokenInformationLength, ref tokenString))
                        {
                            IntegratedSecurityError(2);
                        }
                    }
                    else
                    {
                        IntegratedSecurityError(3);
                    }
                }
                currentWindowsIdentity.Dispose();
                if (!System.Data.Common.UnsafeNativeMethods.ConvertSidToStringSidW(Marshal.ReadIntPtr(zero, 0), out stringSid))
                {
                    IntegratedSecurityError(4);
                }
                if (IntPtr.Zero == stringSid)
                {
                    throw ADP.InternalError(ADP.InternalErrorCode.ConvertSidToStringSidWReturnedNull);
                }
                identity = new DbConnectionPoolIdentity(Marshal.PtrToStringUni(stringSid), isRestricted, flag);
            }
            finally
            {
                if (IntPtr.Zero != zero)
                {
                    SafeNativeMethods.LocalFree(zero);
                    zero = IntPtr.Zero;
                }
                if (IntPtr.Zero != stringSid)
                {
                    SafeNativeMethods.LocalFree(stringSid);
                    stringSid = IntPtr.Zero;
                }
            }
            return(identity);
        }
 private bool Start(string connectionString, out string server, out DbConnectionPoolIdentity identity, out string user, out string database, ref string queueService, string appDomainKey, SqlDependencyPerAppDomainDispatcher dispatcher, out bool errorOccurred, out bool appDomainStart, bool useDefaults)
 {
     bool flag2;
     IntPtr ptr;
     Bid.NotificationsScopeEnter(out ptr, "<sc.SqlDependencyProcessDispatcher.Start|DEP> %d#, queue: '%ls', appDomainKey: '%ls', perAppDomainDispatcher ID: '%d'", this.ObjectID, queueService, appDomainKey, dispatcher.ObjectID);
     try
     {
         server = null;
         identity = null;
         user = null;
         database = null;
         errorOccurred = false;
         appDomainStart = false;
         lock (this._sqlDependencyPerAppDomainDispatchers)
         {
             if (!this._sqlDependencyPerAppDomainDispatchers.ContainsKey(appDomainKey))
             {
                 this._sqlDependencyPerAppDomainDispatchers[appDomainKey] = dispatcher;
             }
         }
         SqlConnectionStringBuilder connectionStringBuilder = null;
         SqlConnectionContainerHashHelper key = GetHashHelper(connectionString, out connectionStringBuilder, out identity, out user, queueService);
         bool flag = false;
         SqlConnectionContainer container = null;
         lock (this._connectionContainers)
         {
             if (!this._connectionContainers.ContainsKey(key))
             {
                 Bid.NotificationsTrace("<sc.SqlDependencyProcessDispatcher.Start|DEP> %d#, hashtable miss, creating new container.\n", this.ObjectID);
                 container = new SqlConnectionContainer(key, appDomainKey, useDefaults);
                 this._connectionContainers.Add(key, container);
                 flag = true;
                 appDomainStart = true;
             }
             else
             {
                 container = this._connectionContainers[key];
                 Bid.NotificationsTrace("<sc.SqlDependencyProcessDispatcher.Start|DEP> %d#, hashtable hit, container: %d\n", this.ObjectID, container.ObjectID);
                 if (container.InErrorState)
                 {
                     Bid.NotificationsTrace("<sc.SqlDependencyProcessDispatcher.Start|DEP> %d#, container: %d is in error state!\n", this.ObjectID, container.ObjectID);
                     errorOccurred = true;
                 }
                 else
                 {
                     container.IncrementStartCount(appDomainKey, out appDomainStart);
                 }
             }
         }
         if (useDefaults && !errorOccurred)
         {
             server = container.Server;
             database = container.Database;
             queueService = container.Queue;
             Bid.NotificationsTrace("<sc.SqlDependencyProcessDispatcher.Start|DEP> %d#, default service: '%ls', server: '%ls', database: '%ls'\n", this.ObjectID, queueService, server, database);
         }
         Bid.NotificationsTrace("<sc.SqlDependencyProcessDispatcher.Start|DEP> %d#, started: %d\n", this.ObjectID, flag);
         flag2 = flag;
     }
     finally
     {
         Bid.ScopeLeave(ref ptr);
     }
     return flag2;
 }
Esempio n. 28
0
        private void PoolCreateRequest(object?state)
        {
            // called by pooler to ensure pool requests are currently being satisfied -
            // creation mutex has not been obtained

            if (State.Running == _state)
            {
                // in case WaitForPendingOpen ever failed with no subsequent OpenAsync calls,
                // start it back up again
                if (!_pendingOpens.IsEmpty && _pendingOpensWaiting == 0)
                {
                    Thread waitOpenThread = new Thread(WaitForPendingOpen);
                    waitOpenThread.IsBackground = true;
                    waitOpenThread.Start();
                }

                // Before creating any new objects, reclaim any released objects that were
                // not closed.
                ReclaimEmancipatedObjects();

                if (!ErrorOccurred)
                {
                    if (NeedToReplenish)
                    {
                        // Check to see if pool was created using integrated security and if so, make
                        // sure the identity of current user matches that of user that created pool.
                        // If it doesn't match, do not create any objects on the ThreadPool thread,
                        // since either Open will fail or we will open a object for this pool that does
                        // not belong in this pool.  The side effect of this is that if using integrated
                        // security min pool size cannot be guaranteed.
                        if (UsingIntegrateSecurity && !_identity !.Equals(DbConnectionPoolIdentity.GetCurrent()))
                        {
                            return;
                        }
                        int waitResult = BOGUS_HANDLE;
                        try
                        {
                            try { }
                            finally
                            {
                                waitResult = WaitHandle.WaitAny(_waitHandles.GetHandles(withCreate: true), CreationTimeout);
                            }
                            if (CREATION_HANDLE == waitResult)
                            {
                                DbConnectionInternal newObj;

                                // Check ErrorOccurred again after obtaining mutex
                                if (!ErrorOccurred)
                                {
                                    while (NeedToReplenish)
                                    {
                                        // Don't specify any user options because there is no outer connection associated with the new connection
                                        newObj = CreateObject(owningObject: null, userOptions: null, oldConnection: null);

                                        // We do not need to check error flag here, since we know if
                                        // CreateObject returned null, we are in error case.
                                        if (null != newObj)
                                        {
                                            PutNewObject(newObj);
                                        }
                                        else
                                        {
                                            break;
                                        }
                                    }
                                }
                            }
                            else if (WaitHandle.WaitTimeout == waitResult)
                            {
                                // do not wait forever and potential block this worker thread
                                // instead wait for a period of time and just requeue to try again
                                QueuePoolCreateRequest();
                            }
                        }
                        finally
                        {
                            if (CREATION_HANDLE == waitResult)
                            {
                                // reuse waitResult and ignore its value
                                _waitHandles.CreationSemaphore.Release(1);
                            }
                        }
                    }
                }
            }
        }