static void KeyVaultSecretsDemo()
        {
            // Use Key for authorization AccessToken
            var keyVaultClient = new KeyVaultClient(GetAccessToken, new HttpClient());

            // Use Certificate for authorization AccessToken
            // var keyVaultClient = new KeyVaultClient(GetAccessCertificateToken, new HttpClient());
            
            var keyVaultAddress = ConfigurationManager.AppSettings["VaultUrl"];
            
            // Get connection string without password
            var connectionString = keyVaultClient.GetSecretAsync(keyVaultAddress, "ConnectionStringsWilco").GetAwaiter().GetResult();            
            var builder = new SqlConnectionStringBuilder(connectionString.Value);

            // Get password
            var password = keyVaultClient.GetSecretAsync(keyVaultAddress, "SqlPasswordWilco").GetAwaiter().GetResult();

            // Convert password to SecureString. 'password.Value' object still keeps it in plain text. Hopefuly this is the only reference.
            // The reason to keep password out of connection string is to minimize number of it's instances in managed heap.
            var securePassword = new SecureString();
            foreach (char c in password.Value)
            {
                securePassword.AppendChar(c);
            }

            securePassword.MakeReadOnly(); 
            // Allow GC to collect it
            password = null;

            // Keep connection in SqlCredential. When connection goes to pool or paged to disk credentials are not exposed.
            var credentials = new SqlCredential(builder.UserID, securePassword);
            builder.UserID = string.Empty; // Need to clen up user id as SqlCredential won't attach to sql connection

            // Put connection string and credentials in cache. We don't want to fetch connection string each time from KV.
            // Remove callback policy is designed to dispose objects. In case of SecureString it should be packed with '0'oz.
            MemoryCache.Default.Add("ConnectionStringsWilco", builder.ConnectionString, new CacheItemPolicy { RemovedCallback = DisposePolicyRemovedCallback });
            MemoryCache.Default.Add("SqlCredentialsWilco", credentials, new CacheItemPolicy { RemovedCallback = DisposePolicyRemovedCallback });

            BusinessOperation();

            Console.ReadLine();
        }
Beispiel #2
1
		static void Main(string[] args)
		{
			try
			{
				//Connect to a remote instance of SQL Server.
				SecureString ss = readPassword();
				ss.MakeReadOnly();
				SqlCredential creds = new SqlCredential("CozDev01_DBA!Us3rAcc0unt@zypnl8g76k", ss);

				connection = new SqlConnection("Server=zypnl8g76k.database.windows.net;database=master", creds);
				connection.Open();
				SqlCommand command = connection.CreateCommand();

				//Create new DB
				string dbName = "TestDb";

				//command.CommandText = "CREATE DATABASE " + dbName;
				//command.ExecuteNonQuery();

				var scriptRan = ScriptExecutor.executeScript(command, dbName);
				if (scriptRan)
				{
					Console.WriteLine("It worked!");
				}
				else
				{
					Console.WriteLine("It didn't work");
				}
				connection.Close();
			}
			catch (Exception e)
			{
				if (connection.State == ConnectionState.Open)
				{
					connection.Close();
				}
				Console.WriteLine(e.ToString());
			}
			Console.ReadLine();
		}
 internal SqlConnectionPoolKey(string connectionString, SqlCredential credential, string accessToken) : base(connectionString)
 {
     Debug.Assert(_credential == null || _accessToken == null, "Credential and AccessToken can't have the value at the same time.");
     _credential = credential;
     _accessToken = accessToken;
     CalculateHashCode();
 }
 internal SqlConnectionPoolKey(string connectionString, SqlCredential credential, string accessToken) : base(connectionString)
 {
     Debug.Assert(_credential == null || _accessToken == null, "Credential and AccessToken can't have the value at the same time.");
     _credential  = credential;
     _accessToken = accessToken;
     CalculateHashCode();
 }
    // Attempt to login to a host that has a failover partner
    //
    // Connection & timeout sequence is
    //      First target, timeout = interval * 1
    //      second target, timeout = interval * 1
    //      sleep for 100ms
    //      First target, timeout = interval * 2
    //      Second target, timeout = interval * 2
    //      sleep for 200ms
    //      First Target, timeout = interval * 3
    //      etc.
    //
    // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    //  DEVNOTE: The logic in this method is paralleled by the logic in LoginNoFailover.
    //           Changes to either one should be examined to see if they need to be reflected in the other
    // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    private void LoginWithFailover(
            bool                useFailoverHost, 
            ServerInfo          primaryServerInfo, 
            string              failoverHost, 
            string              newPassword,
            SecureString        newSecurePassword,
            bool                redirectedUserInstance, 
            SqlConnectionString connectionOptions,
            SqlCredential       credential,
            TimeoutTimer        timeout
        ) {

        Debug.Assert(!connectionOptions.MultiSubnetFailover, "MultiSubnetFailover should not be set if failover partner is used");

        if (Bid.AdvancedOn) {
            Bid.Trace("<sc.SqlInternalConnectionTds.LoginWithFailover|ADV> %d#, useFailover=%d{bool}, primary=", ObjectID, useFailoverHost);
            Bid.PutStr(primaryServerInfo.UserServerName);
            Bid.PutStr(", failover=");
            Bid.PutStr(failoverHost);
            Bid.PutStr("\n");
        }
        int  sleepInterval = 100;  //milliseconds to sleep (back off) between attempts.
        long timeoutUnitInterval;

        string     protocol = ConnectionOptions.NetworkLibrary;
        ServerInfo failoverServerInfo = new ServerInfo(connectionOptions, failoverHost);

        ResolveExtendedServerName(primaryServerInfo, !redirectedUserInstance, connectionOptions);
        if (null == ServerProvidedFailOverPartner) {// No point in resolving the failover partner when we're going to override it below
            // Don't resolve aliases if failover == primary // 
            ResolveExtendedServerName(failoverServerInfo, !redirectedUserInstance && failoverHost != primaryServerInfo.UserServerName, connectionOptions);
        }

        // Determine unit interval
        if (timeout.IsInfinite) {
            timeoutUnitInterval = checked((long) ADP.FailoverTimeoutStep * ADP.TimerFromSeconds(ADP.DefaultConnectionTimeout));
        }
        else {
            timeoutUnitInterval = checked((long) (ADP.FailoverTimeoutStep * timeout.MillisecondsRemaining));
        }

        // Initialize loop variables
        bool failoverDemandDone = false; // have we demanded for partner information yet (as necessary)?
        int attemptNumber = 0;

        // Only three ways out of this loop:
        //  1) Successfully connected
        //  2) Parser threw exception while main timer was expired
        //  3) Parser threw logon failure-related exception (LOGON_FAILED, PASSWORD_EXPIRED, etc)
        //
        //  Of these methods, only #1 exits normally. This preserves the call stack on the exception 
        //  back into the parser for the error cases.
        while (true) {
            // Set timeout for this attempt, but don't exceed original timer
            long nextTimeoutInterval = checked(timeoutUnitInterval * ((attemptNumber / 2) + 1));
            long milliseconds = timeout.MillisecondsRemaining;
            if (nextTimeoutInterval > milliseconds) {
                nextTimeoutInterval = milliseconds;
            }

            TimeoutTimer intervalTimer = TimeoutTimer.StartMillisecondsTimeout(nextTimeoutInterval);

            // Re-allocate parser each time to make sure state is known
            // RFC 50002652 - if parser was created by previous attempt, dispose it to properly close the socket, if created
            if (_parser != null)
                _parser.Disconnect();

            _parser = new TdsParser(ConnectionOptions.MARS, ConnectionOptions.Asynchronous);
            Debug.Assert(SniContext.Undefined== Parser._physicalStateObj.SniContext, String.Format((IFormatProvider)null, "SniContext should be Undefined; actual Value: {0}", Parser._physicalStateObj.SniContext));

            ServerInfo currentServerInfo;
            if (useFailoverHost) {
                if (!failoverDemandDone) {
                    FailoverPermissionDemand();
                    failoverDemandDone = true;
                }

                // Primary server may give us a different failover partner than the connection string indicates.  Update it
                if (null != ServerProvidedFailOverPartner && failoverServerInfo.ResolvedServerName != ServerProvidedFailOverPartner) {
                    if (Bid.AdvancedOn) {
                        Bid.Trace("<sc.SqlInternalConnectionTds.LoginWithFailover|ADV> %d#, new failover partner=%ls\n", ObjectID, ServerProvidedFailOverPartner);
                    }
                    failoverServerInfo.SetDerivedNames(protocol, ServerProvidedFailOverPartner);
                }
                currentServerInfo = failoverServerInfo;
                timeoutErrorInternal.SetInternalSourceType(SqlConnectionInternalSourceType.Failover);
            }
            else {
                currentServerInfo = primaryServerInfo;
                timeoutErrorInternal.SetInternalSourceType(SqlConnectionInternalSourceType.Principle);
            }

            try {
                // Attempt login.  Use timerInterval for attempt timeout unless infinite timeout was requested.
                AttemptOneLogin(
                        currentServerInfo,
                        newPassword,
                        newSecurePassword,
                        false,          // Use timeout in SniOpen
                        intervalTimer,
                        withFailover:true
                        );

                if (_routingInfo != null) {
                    // We are in login with failover scenation and server sent routing information
                    // If it is read-only routing - we did not supply AppIntent=RO (it should be checked before)
                    // If it is something else, not known yet (future server) - this client is not designed to support this.                    
                    // In any case, server should not have sent the routing info.
                    Bid.Trace("<sc.SqlInternalConnectionTds.LoginWithFailover> Routed to %ls", _routingInfo.ServerName);
                    throw SQL.ROR_UnexpectedRoutingInfo(this);
                }

                break; // leave the while loop -- we've successfully connected
            }
            catch (SqlException sqlex) {
                if (IsDoNotRetryConnectError(sqlex)
                        || timeout.IsExpired) 
                {       // no more time to try again
                    throw;  // Caller will call LoginFailure()
                }

                if (IsConnectionDoomed) {
                    throw;
                }

                if (1 == attemptNumber % 2) {
                    // Check sleep interval to make sure we won't exceed the original timeout
                    //  Do this in the catch block so we can re-throw the current exception
                    if (timeout.MillisecondsRemaining <= sleepInterval) {
                        throw;
                    }
                }

                // 
            }

            // We only get here when we failed to connect, but are going to re-try

            // After trying to connect to both servers fails, sleep for a bit to prevent clogging 
            //  the network with requests, then update sleep interval for next iteration (max 1 second interval)
            if (1 == attemptNumber % 2) {
                if (Bid.AdvancedOn) {
                    Bid.Trace("<sc.SqlInternalConnectionTds.LoginWithFailover|ADV> %d#, sleeping %d{milisec}\n", ObjectID, sleepInterval);
                }
                Thread.Sleep(sleepInterval);
                sleepInterval = (sleepInterval < 500) ? sleepInterval * 2 : 1000;
            }

            // Update attempt number and target host
            attemptNumber++;
            useFailoverHost = !useFailoverHost;
        }

        // If we get here, connection/login succeeded!  Just a few more checks & record-keeping

        // if connected to failover host, but said host doesn't have DbMirroring set up, throw an error
        if (useFailoverHost && null == ServerProvidedFailOverPartner) {
            throw SQL.InvalidPartnerConfiguration(failoverHost, CurrentDatabase);
        }

        if (null != PoolGroupProviderInfo) {
            // We must wait for CompleteLogin to finish for to have the
            // env change from the server to know its designated failover 
            // partner; save this information in _currentFailoverPartner.
            PoolGroupProviderInfo.FailoverCheck(this, useFailoverHost, connectionOptions, ServerProvidedFailOverPartner);
        }
        CurrentDataSource = (useFailoverHost ? failoverHost : primaryServerInfo.UserServerName);
    }
        // 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);
            }
        }
        private void OpenLoginEnlist(TimeoutTimer timeout, SqlConnectionString connectionOptions, SqlCredential credential,
                    string newPassword, SecureString newSecurePassword, bool redirectedUserInstance) {
            bool useFailoverPartner; // should we use primary or secondary first
            ServerInfo dataSource = new ServerInfo(connectionOptions);
            string failoverPartner;

            if (null != PoolGroupProviderInfo) {
                useFailoverPartner = PoolGroupProviderInfo.UseFailoverPartner;
                failoverPartner = PoolGroupProviderInfo.FailoverPartner;
            }
            else {
                // Only ChangePassword or SSE User Instance comes through this code path.
                useFailoverPartner = false;
                failoverPartner = ConnectionOptions.FailoverPartner; 
            }

            timeoutErrorInternal.SetInternalSourceType(useFailoverPartner ? SqlConnectionInternalSourceType.Failover : SqlConnectionInternalSourceType.Principle);

            bool hasFailoverPartner = !ADP.IsEmpty(failoverPartner);

            // Open the connection and Login
            try {
                timeoutErrorInternal.SetAndBeginPhase(SqlConnectionTimeoutErrorPhase.PreLoginBegin);
                if (hasFailoverPartner) {
                    timeoutErrorInternal.SetFailoverScenario(true); // this is a failover scenario
                    LoginWithFailover(
                                useFailoverPartner, 
                                dataSource, 
                                failoverPartner, 
                                newPassword,
                                newSecurePassword,
                                redirectedUserInstance, 
                                connectionOptions,
                                credential,
                                timeout);
                }
                else {
                    timeoutErrorInternal.SetFailoverScenario(false); // not a failover scenario
                    LoginNoFailover(dataSource, newPassword, newSecurePassword, redirectedUserInstance, 
                            connectionOptions, credential, timeout);
                }
                timeoutErrorInternal.EndPhase(SqlConnectionTimeoutErrorPhase.PostLogin);
            }
            catch (Exception e) {
                // 
                if (ADP.IsCatchableExceptionType(e)) {
                    LoginFailure();
                }
                throw;
            }
            timeoutErrorInternal.SetAllCompleteMarker();

#if DEBUG
            _parser._physicalStateObj.InvalidateDebugOnlyCopyOfSniContext();
#endif
        }
    // Attempt to login to a host that does not have a failover partner
    //
    //  Will repeatedly attempt to connect, but back off between each attempt so as not to clog the network.
    //  Back off period increases for first few failures: 100ms, 200ms, 400ms, 800ms, then 1000ms for subsequent attempts
    //
    // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    //  DEVNOTE: The logic in this method is paralleled by the logic in LoginWithFailover.
    //           Changes to either one should be examined to see if they need to be reflected in the other
    // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    private void LoginNoFailover(ServerInfo serverInfo, string newPassword, SecureString newSecurePassword, bool redirectedUserInstance, 
                SqlConnectionString connectionOptions, SqlCredential credential, TimeoutTimer timeout) {

        Debug.Assert(object.ReferenceEquals(connectionOptions, this.ConnectionOptions), "ConnectionOptions argument and property must be the same"); // consider removing the argument
        int routingAttempts = 0;
        ServerInfo originalServerInfo = serverInfo; // serverInfo may end up pointing to new object due to routing, original object is used to set CurrentDatasource

        if (Bid.AdvancedOn) {
            Bid.Trace("<sc.SqlInternalConnectionTds.LoginNoFailover|ADV> %d#, host=%ls\n", ObjectID, serverInfo.UserServerName);
        }
        int  sleepInterval = 100;  //milliseconds to sleep (back off) between attempts.

        ResolveExtendedServerName(serverInfo, !redirectedUserInstance, connectionOptions);

        long timeoutUnitInterval = 0;
        Boolean isParallel = connectionOptions.MultiSubnetFailover || connectionOptions.TransparentNetworkIPResolution;

        if(isParallel) {
            // Determine unit interval
            if (timeout.IsInfinite) {
                timeoutUnitInterval = checked((long)(ADP.FailoverTimeoutStep * (1000L * ADP.DefaultConnectionTimeout)));
            }
            else {
                timeoutUnitInterval = checked((long)(ADP.FailoverTimeoutStep * timeout.MillisecondsRemaining));
            }
        }
        // Only three ways out of this loop:
        //  1) Successfully connected
        //  2) Parser threw exception while main timer was expired
        //  3) Parser threw logon failure-related exception 
        //  4) Parser threw exception in post-initial connect code,
        //      such as pre-login handshake or during actual logon. (parser state != Closed)
        //
        //  Of these methods, only #1 exits normally. This preserves the call stack on the exception 
        //  back into the parser for the error cases.
        int attemptNumber = 0;
        TimeoutTimer intervalTimer = null;
        TimeoutTimer firstTransparentAttemptTimeout = TimeoutTimer.StartMillisecondsTimeout(ADP.FirstTransparentAttemptTimeout);
        TimeoutTimer attemptOneLoginTimeout = timeout;
        while(true) {

            if(isParallel) {
                attemptNumber++;
                // Set timeout for this attempt, but don't exceed original timer                
                long nextTimeoutInterval = checked(timeoutUnitInterval * attemptNumber);
                long milliseconds = timeout.MillisecondsRemaining;
                if (nextTimeoutInterval > milliseconds) {
                    nextTimeoutInterval = milliseconds;
                }
                intervalTimer = TimeoutTimer.StartMillisecondsTimeout(nextTimeoutInterval);
            }

            // Re-allocate parser each time to make sure state is known
            // RFC 50002652 - if parser was created by previous attempt, dispose it to properly close the socket, if created
            if (_parser != null)
                _parser.Disconnect();
 
            _parser = new TdsParser(ConnectionOptions.MARS, ConnectionOptions.Asynchronous);
            Debug.Assert(SniContext.Undefined== Parser._physicalStateObj.SniContext, String.Format((IFormatProvider)null, "SniContext should be Undefined; actual Value: {0}", Parser._physicalStateObj.SniContext));

            try {
                // 


                Boolean isFirstTransparentAttempt =  connectionOptions.TransparentNetworkIPResolution && attemptNumber == 1;

                if(isFirstTransparentAttempt) {
                    attemptOneLoginTimeout = firstTransparentAttemptTimeout;
                }
                else {
                    if(isParallel) {
                        attemptOneLoginTimeout = intervalTimer;
                    }
                }
                
                AttemptOneLogin(    serverInfo, 
                                    newPassword,
                                    newSecurePassword,
                                    !isParallel,    // ignore timeout for SniOpen call unless MSF , and TNIR
                                    attemptOneLoginTimeout,
                                    isFirstTransparentAttempt:isFirstTransparentAttempt);
                
                if (connectionOptions.MultiSubnetFailover && null != ServerProvidedFailOverPartner) {
                    // connection succeeded: trigger exception if server sends failover partner and MultiSubnetFailover is used.
                    throw SQL.MultiSubnetFailoverWithFailoverPartner(serverProvidedFailoverPartner: true, internalConnection: this);
                }

                if (_routingInfo != null) {
                    Bid.Trace("<sc.SqlInternalConnectionTds.LoginNoFailover> Routed to %ls", serverInfo.ExtendedServerName);

                    if (routingAttempts > 0) {
                        throw SQL.ROR_RecursiveRoutingNotSupported(this);
                    }

                    if (timeout.IsExpired) {
                        throw SQL.ROR_TimeoutAfterRoutingInfo(this);
                    }                    

                    serverInfo = new ServerInfo(ConnectionOptions, _routingInfo, serverInfo.ResolvedServerName);
                    timeoutErrorInternal.SetInternalSourceType(SqlConnectionInternalSourceType.RoutingDestination);
                    _originalClientConnectionId = _clientConnectionId;
                    _routingDestination = serverInfo.UserServerName;

                    // restore properties that could be changed by the environment tokens
                    _currentPacketSize = ConnectionOptions.PacketSize;
                    _currentLanguage = _originalLanguage = ConnectionOptions.CurrentLanguage;
                    CurrentDatabase = _originalDatabase = ConnectionOptions.InitialCatalog;
                    _currentFailoverPartner = null;
                    _instanceName = String.Empty;

                    routingAttempts++;

                    continue; // repeat the loop, but skip code reserved for failed connections (after the catch)
                }
                else {
                    break; // leave the while loop -- we've successfully connected
                }
            }
            catch (SqlException sqlex) {
                if (null == _parser
                    || TdsParserState.Closed != _parser.State
                    || IsDoNotRetryConnectError(sqlex)
                    || timeout.IsExpired) {       // no more time to try again
                    throw;  // Caller will call LoginFailure()
                }

                // Check sleep interval to make sure we won't exceed the timeout
                //  Do this in the catch block so we can re-throw the current exception
                if (timeout.MillisecondsRemaining <= sleepInterval) {
                    throw;
                }

                // 
            }

            // We only get here when we failed to connect, but are going to re-try

            // Switch to failover logic if the server provided a partner
            if (null != ServerProvidedFailOverPartner) {
                if (connectionOptions.MultiSubnetFailover) {
                    // connection failed: do not allow failover to server-provided failover partner if MultiSubnetFailover is set
                    throw SQL.MultiSubnetFailoverWithFailoverPartner(serverProvidedFailoverPartner: true, internalConnection: this);
                }
                Debug.Assert(ConnectionOptions.ApplicationIntent != ApplicationIntent.ReadOnly, "FAILOVER+AppIntent=RO: Should already fail (at LOGSHIPNODE in OnEnvChange)");

                timeoutErrorInternal.ResetAndRestartPhase();
                timeoutErrorInternal.SetAndBeginPhase(SqlConnectionTimeoutErrorPhase.PreLoginBegin);
                timeoutErrorInternal.SetInternalSourceType(SqlConnectionInternalSourceType.Failover);
                timeoutErrorInternal.SetFailoverScenario(true); // this is a failover scenario
                LoginWithFailover(
                            true,   // start by using failover partner, since we already failed to connect to the primary
                            serverInfo,
                            ServerProvidedFailOverPartner,
                            newPassword,
                            newSecurePassword,
                            redirectedUserInstance,
                            connectionOptions,
                            credential,
                            timeout);
                return; // LoginWithFailover successfully connected and handled entire connection setup
            }

            // Sleep for a bit to prevent clogging the network with requests, 
            //  then update sleep interval for next iteration (max 1 second interval)
            if (Bid.AdvancedOn) {
                Bid.Trace("<sc.SqlInternalConnectionTds.LoginNoFailover|ADV> %d#, sleeping %d{milisec}\n", ObjectID, sleepInterval);
            }
            Thread.Sleep(sleepInterval);
            sleepInterval = (sleepInterval < 500) ? sleepInterval * 2 : 1000;
        }

        if (null != PoolGroupProviderInfo) {
            // We must wait for CompleteLogin to finish for to have the
            // env change from the server to know its designated failover 
            // partner; save this information in _currentFailoverPartner.
            PoolGroupProviderInfo.FailoverCheck(this, false, connectionOptions, ServerProvidedFailOverPartner);
        }
        CurrentDataSource = originalServerInfo.UserServerName;
    }
 /// <summary>
 /// Initializes a new connection to a graph database.
 /// The database could be a SQL Server instance or Azure SQL Database, 
 /// as specified by the connection string and the SQL credential. 
 /// </summary>
 /// <param name="connectionString">The connection string of the SQL database</param>
 /// <param name="sqlCredential">A SqlCredential object</param>
 public GraphViewConnection(string connectionString, SqlCredential sqlCredential)
 {
     _disposed = false;
     Conn = new SqlConnection(connectionString, sqlCredential);
 }
Beispiel #10
0
 public SqlConnection(string connectionString, SqlCredential cred)
 {
     throw new PlatformNotSupportedException(EXCEPTION_MESSAGE);
 }
 private SqlConnectionPoolKey(SqlConnectionPoolKey key) : base(key)
 {
     _credential  = key.Credential;
     _accessToken = key.AccessToken;
     CalculateHashCode();
 }
 public SqlConnectionInfo(SqlConnectionStringBuilder connectionString, SqlCredential credential)
 {
     ConnectionString = connectionString;
     Credential = credential;
 }
 public static void ChangePassword(string connectionString, SqlCredential credential, SecureString newSecurePassword)
 => throw new PlatformNotSupportedException(EXCEPTION_MESSAGE);
 public SqlConnection(string connectionString, SqlCredential credential)
 {
     ConnectionString = connectionString;
     Credentials      = credential;
 }
 private SqlConnectionPoolKey(SqlConnectionPoolKey key) : base(key)
 {
     _credential = key.Credential;
     CalculateHashCode();
 }
 internal SqlConnectionPoolKey(string connectionString, SqlCredential credential) : base(connectionString)
 {
     _credential = credential;
     CalculateHashCode();
 }
		public SqlConnection (string connectionString, SqlCredential cred)
		{
			throw new PlatformNotSupportedException (EXCEPTION_MESSAGE);
		}
 internal SqlConnectionPoolKey(string connectionString, SqlCredential credential) : base(connectionString)
 {
     _credential = credential;
     CalculateHashCode();
 }
Beispiel #19
0
		public SqlConnection (string connectionString, SqlCredential cred)
		{
			ConnectionString = connectionString;
			Credentials = cred;
		}
 private SqlConnectionPoolKey(SqlConnectionPoolKey key) : base (key)
 {
      _credential = key.Credential;
      CalculateHashCode();
 }
 private SqlConnectionPoolKey(SqlConnectionPoolKey key) : base (key)
 {
      _credential = key.Credential;
      _accessToken = key.AccessToken;
      CalculateHashCode();
 }