internal void Connect(ServerInfo serverInfo, SqlInternalConnectionTds connHandler, bool ignoreSniOpenTimeout, long timerExpire, bool encrypt, bool trustServerCert, bool integratedSecurity, bool withFailover, bool isFirstTransparentAttempt, SqlAuthenticationMethod authType) { if (_state != TdsParserState.Closed) { Debug.Assert(false, "TdsParser.Connect called on non-closed connection!"); return; } _connHandler = connHandler; _loginWithFailover = withFailover; UInt32 sniStatus = SNILoadHandle.SingletonInstance.SNIStatus; if (sniStatus != TdsEnums.SNI_SUCCESS) { _physicalStateObj.AddError(ProcessSNIError(_physicalStateObj)); _physicalStateObj.Dispose(); ThrowExceptionAndWarning(_physicalStateObj); Debug.Assert(false, "SNI returned status != success, but no error thrown?"); } //Create LocalDB instance if necessary if (connHandler.ConnectionOptions.LocalDBInstance != null) LocalDBAPI.CreateLocalDBInstance(connHandler.ConnectionOptions.LocalDBInstance); if (integratedSecurity || authType == SqlAuthenticationMethod.ActiveDirectoryIntegrated) { LoadSSPILibrary(); // now allocate proper length of buffer _sniSpnBuffer = new byte[SNINativeMethodWrapper.SniMaxComposedSpnLength]; Bid.Trace("<sc.TdsParser.Connect|SEC> SSPI or Active Directory Authentication Library for SQL Server based integrated authentication\n"); } else { _sniSpnBuffer = null; if (authType == SqlAuthenticationMethod.ActiveDirectoryPassword) { Bid.Trace("<sc.TdsParser.Connect|SEC> Active Directory Password authentication\n"); } else if (authType == SqlAuthenticationMethod.SqlPassword) { Bid.Trace("<sc.TdsParser.Connect|SEC> SQL Password authentication\n"); } else{ Bid.Trace("<sc.TdsParser.Connect|SEC> SQL authentication\n"); } } byte[] instanceName = null; Debug.Assert(_connHandler != null, "SqlConnectionInternalTds handler can not be null at this point."); _connHandler.TimeoutErrorInternal.EndPhase(SqlConnectionTimeoutErrorPhase.PreLoginBegin); _connHandler.TimeoutErrorInternal.SetAndBeginPhase(SqlConnectionTimeoutErrorPhase.InitializeConnection); bool fParallel = _connHandler.ConnectionOptions.MultiSubnetFailover; TransparentNetworkResolutionState transparentNetworkResolutionState; if(_connHandler.ConnectionOptions.TransparentNetworkIPResolution) { if(isFirstTransparentAttempt) transparentNetworkResolutionState = TransparentNetworkResolutionState.SequentialMode; else transparentNetworkResolutionState = TransparentNetworkResolutionState.ParallelMode; } else transparentNetworkResolutionState = TransparentNetworkResolutionState.DisabledMode; int totalTimeout = _connHandler.ConnectionOptions.ConnectTimeout; _physicalStateObj.CreatePhysicalSNIHandle(serverInfo.ExtendedServerName, ignoreSniOpenTimeout, timerExpire, out instanceName, _sniSpnBuffer, false, true, fParallel, transparentNetworkResolutionState, totalTimeout); if (TdsEnums.SNI_SUCCESS != _physicalStateObj.Status) { _physicalStateObj.AddError(ProcessSNIError(_physicalStateObj)); // Since connect failed, free the unmanaged connection memory. // HOWEVER - only free this after the netlib error was processed - if you // don't, the memory for the connection object might not be accurate and thus // a bad error could be returned (as it was when it was freed to early for me). _physicalStateObj.Dispose(); Bid.Trace("<sc.TdsParser.Connect|ERR|SEC> Login failure\n"); ThrowExceptionAndWarning(_physicalStateObj); Debug.Assert(false, "SNI returned status != success, but no error thrown?"); } _server = serverInfo.ResolvedServerName; if (null != connHandler.PoolGroupProviderInfo) { // If we are pooling, check to see if we were processing an // alias which has changed, which means we need to clean out // the pool. See Webdata 104293. // This should not apply to routing, as it is not an alias change, routed connection // should still use VNN of AlwaysOn cluster as server for pooling purposes. connHandler.PoolGroupProviderInfo.AliasCheck(serverInfo.PreRoutingServerName==null ? serverInfo.ResolvedServerName: serverInfo.PreRoutingServerName); } _state = TdsParserState.OpenNotLoggedIn; _physicalStateObj.SniContext = SniContext.Snix_PreLoginBeforeSuccessfullWrite; // SQL BU DT 376766 _physicalStateObj.TimeoutTime = timerExpire; bool marsCapable = false; _connHandler.TimeoutErrorInternal.EndPhase(SqlConnectionTimeoutErrorPhase.InitializeConnection); _connHandler.TimeoutErrorInternal.SetAndBeginPhase(SqlConnectionTimeoutErrorPhase.SendPreLoginHandshake); UInt32 result = SNINativeMethodWrapper.SniGetConnectionId(_physicalStateObj.Handle, ref _connHandler._clientConnectionId); Debug.Assert(result == TdsEnums.SNI_SUCCESS, "Unexpected failure state upon calling SniGetConnectionId"); // Bid.Trace("<sc.TdsParser.Connect|SEC> Sending prelogin handshake\n"); SendPreLoginHandshake(instanceName, encrypt); _connHandler.TimeoutErrorInternal.EndPhase(SqlConnectionTimeoutErrorPhase.SendPreLoginHandshake); _connHandler.TimeoutErrorInternal.SetAndBeginPhase(SqlConnectionTimeoutErrorPhase.ConsumePreLoginHandshake); _physicalStateObj.SniContext = SniContext.Snix_PreLogin; Bid.Trace("<sc.TdsParser.Connect|SEC> Consuming prelogin handshake\n"); PreLoginHandshakeStatus status = ConsumePreLoginHandshake(authType, encrypt, trustServerCert, integratedSecurity, out marsCapable, out _connHandler._fedAuthRequired); if (status == PreLoginHandshakeStatus.InstanceFailure) { Bid.Trace("<sc.TdsParser.Connect|SEC> Prelogin handshake unsuccessful. Reattempting prelogin handshake\n"); _physicalStateObj.Dispose(); // Close previous connection // On Instance failure re-connect and flush SNI named instance cache. _physicalStateObj.SniContext=SniContext.Snix_Connect; _physicalStateObj.CreatePhysicalSNIHandle(serverInfo.ExtendedServerName, ignoreSniOpenTimeout, timerExpire, out instanceName, _sniSpnBuffer, true, true, fParallel, transparentNetworkResolutionState, totalTimeout); if (TdsEnums.SNI_SUCCESS != _physicalStateObj.Status) { _physicalStateObj.AddError(ProcessSNIError(_physicalStateObj)); Bid.Trace("<sc.TdsParser.Connect|ERR|SEC> Login failure\n"); ThrowExceptionAndWarning(_physicalStateObj); } UInt32 retCode = SNINativeMethodWrapper.SniGetConnectionId(_physicalStateObj.Handle, ref _connHandler._clientConnectionId); Debug.Assert(retCode == TdsEnums.SNI_SUCCESS, "Unexpected failure state upon calling SniGetConnectionId"); Bid.Trace("<sc.TdsParser.Connect|SEC> Sending prelogin handshake\n"); SendPreLoginHandshake(instanceName, encrypt); status = ConsumePreLoginHandshake(authType, encrypt, trustServerCert, integratedSecurity, out marsCapable, out _connHandler._fedAuthRequired); // Don't need to check for Sphinx failure, since we've already consumed // one pre-login packet and know we are connecting to Shiloh. if (status == PreLoginHandshakeStatus.InstanceFailure) { Bid.Trace("<sc.TdsParser.Connect|ERR|SEC> Prelogin handshake unsuccessful. Login failure\n"); throw SQL.InstanceFailure(); } } Bid.Trace("<sc.TdsParser.Connect|SEC> Prelogin handshake successful\n"); if (_fMARS && marsCapable) { // if user explictly disables mars or mars not supported, don't create the session pool _sessionPool = new TdsParserSessionPool(this); } else { _fMARS = false; } if (authType == SqlAuthenticationMethod.ActiveDirectoryPassword || (authType == SqlAuthenticationMethod.ActiveDirectoryIntegrated && _connHandler._fedAuthRequired)) { Debug.Assert(!integratedSecurity, "The legacy Integrated Security connection string option cannot be true when using Active Directory Authentication Library for SQL Server Based workflows."); LoadADALLibrary(); if (Bid.AdvancedOn) { Bid.Trace("<sc.TdsParser.Connect|SEC> Active directory authentication.Loaded Active Directory Authentication Library for SQL Server\n"); } } return; }
internal void Connect(ServerInfo serverInfo, SqlInternalConnectionTds connHandler, bool ignoreSniOpenTimeout, long timerExpire, bool encrypt, bool trustServerCert, bool integratedSecurity, bool withFailover) { if (_state != TdsParserState.Closed) { Debug.Assert(false, "TdsParser.Connect called on non-closed connection!"); return; } _connHandler = connHandler; _loginWithFailover = withFailover; UInt32 sniStatus = SNILoadHandle.SingletonInstance.SNIStatus; if (sniStatus != TdsEnums.SNI_SUCCESS) { _physicalStateObj.AddError(ProcessSNIError(_physicalStateObj)); _physicalStateObj.Dispose(); ThrowExceptionAndWarning(_physicalStateObj); Debug.Assert(false, "SNI returned status != success, but no error thrown?"); } if (integratedSecurity) { LoadSSPILibrary(); // now allocate proper length of buffer _sniSpnBuffer = new byte[SNINativeMethodWrapper.SniMaxComposedSpnLength]; } else { _sniSpnBuffer = null; } byte[] instanceName = null; Debug.Assert(_connHandler != null, "SqlConnectionInternalTds handler can not be null at this point."); _connHandler.TimeoutErrorInternal.EndPhase(SqlConnectionTimeoutErrorPhase.PreLoginBegin); _connHandler.TimeoutErrorInternal.SetAndBeginPhase(SqlConnectionTimeoutErrorPhase.InitializeConnection); bool fParallel = _connHandler.ConnectionOptions.MultiSubnetFailover; _physicalStateObj.CreatePhysicalSNIHandle(serverInfo.ExtendedServerName, ignoreSniOpenTimeout, timerExpire, out instanceName, _sniSpnBuffer, false, true, fParallel); if (TdsEnums.SNI_SUCCESS != _physicalStateObj.Status) { _physicalStateObj.AddError(ProcessSNIError(_physicalStateObj)); // Since connect failed, free the unmanaged connection memory. // HOWEVER - only free this after the netlib error was processed - if you // don't, the memory for the connection object might not be accurate and thus // a bad error could be returned (as it was when it was freed to early for me). _physicalStateObj.Dispose(); ThrowExceptionAndWarning(_physicalStateObj); Debug.Assert(false, "SNI returned status != success, but no error thrown?"); } _server = serverInfo.ResolvedServerName; if (null != connHandler.PoolGroupProviderInfo) { // If we are pooling, check to see if we were processing an // alias which has changed, which means we need to clean out // the pool. See Webdata 104293. // This should not apply to routing, as it is not an alias change, routed connection // should still use VNN of AlwaysOn cluster as server for pooling purposes. connHandler.PoolGroupProviderInfo.AliasCheck(serverInfo.PreRoutingServerName == null ? serverInfo.ResolvedServerName : serverInfo.PreRoutingServerName); } _state = TdsParserState.OpenNotLoggedIn; _physicalStateObj.SniContext = SniContext.Snix_PreLoginBeforeSuccessfullWrite; _physicalStateObj.TimeoutTime = timerExpire; bool marsCapable = false; _connHandler.TimeoutErrorInternal.EndPhase(SqlConnectionTimeoutErrorPhase.InitializeConnection); _connHandler.TimeoutErrorInternal.SetAndBeginPhase(SqlConnectionTimeoutErrorPhase.SendPreLoginHandshake); UInt32 result = SNINativeMethodWrapper.SniGetConnectionId(_physicalStateObj.Handle, ref _connHandler._clientConnectionId); Debug.Assert(result == TdsEnums.SNI_SUCCESS, "Unexpected failure state upon calling SniGetConnectionId"); SendPreLoginHandshake(instanceName, encrypt); _connHandler.TimeoutErrorInternal.EndPhase(SqlConnectionTimeoutErrorPhase.SendPreLoginHandshake); _connHandler.TimeoutErrorInternal.SetAndBeginPhase(SqlConnectionTimeoutErrorPhase.ConsumePreLoginHandshake); _physicalStateObj.SniContext = SniContext.Snix_PreLogin; PreLoginHandshakeStatus status = ConsumePreLoginHandshake(encrypt, trustServerCert, integratedSecurity, out marsCapable); if (status == PreLoginHandshakeStatus.InstanceFailure) { _physicalStateObj.Dispose(); // Close previous connection // On Instance failure re-connect and flush SNI named instance cache. _physicalStateObj.SniContext = SniContext.Snix_Connect; _physicalStateObj.CreatePhysicalSNIHandle(serverInfo.ExtendedServerName, ignoreSniOpenTimeout, timerExpire, out instanceName, _sniSpnBuffer, true, true, fParallel); if (TdsEnums.SNI_SUCCESS != _physicalStateObj.Status) { _physicalStateObj.AddError(ProcessSNIError(_physicalStateObj)); ThrowExceptionAndWarning(_physicalStateObj); } UInt32 retCode = SNINativeMethodWrapper.SniGetConnectionId(_physicalStateObj.Handle, ref _connHandler._clientConnectionId); Debug.Assert(retCode == TdsEnums.SNI_SUCCESS, "Unexpected failure state upon calling SniGetConnectionId"); SendPreLoginHandshake(instanceName, encrypt); status = ConsumePreLoginHandshake(encrypt, trustServerCert, integratedSecurity, out marsCapable); // Don't need to check for Sphinx failure, since we've already consumed // one pre-login packet and know we are connecting to Shiloh. if (status == PreLoginHandshakeStatus.InstanceFailure) { throw SQL.InstanceFailure(); } } if (_fMARS && marsCapable) { // if user explictly disables mars or mars not supported, don't create the session pool _sessionPool = new TdsParserSessionPool(this); } else { _fMARS = false; } return; }
internal void Connect(ServerInfo serverInfo, SqlInternalConnectionTds connHandler, bool ignoreSniOpenTimeout, long timerExpire, bool encrypt, bool trustServerCert, bool integratedSecurity) { if (this._state == TdsParserState.Closed) { this._connHandler = connHandler; if (SNILoadHandle.SingletonInstance.SNIStatus != 0) { this.Errors.Add(this.ProcessSNIError(this._physicalStateObj)); this._physicalStateObj.Dispose(); this.ThrowExceptionAndWarning(); } if (connHandler.ConnectionOptions.LocalDBInstance != null) { LocalDBAPI.CreateLocalDBInstance(connHandler.ConnectionOptions.LocalDBInstance); } if (integratedSecurity) { this.LoadSSPILibrary(); this._sniSpnBuffer = new byte[SNINativeMethodWrapper.SniMaxComposedSpnLength]; Bid.Trace("<sc.TdsParser.Connect|SEC> SSPI authentication\n"); } else { this._sniSpnBuffer = null; Bid.Trace("<sc.TdsParser.Connect|SEC> SQL authentication\n"); } byte[] instanceName = null; bool multiSubnetFailover = this._connHandler.ConnectionOptions.MultiSubnetFailover; this._physicalStateObj.CreatePhysicalSNIHandle(serverInfo.ExtendedServerName, ignoreSniOpenTimeout, timerExpire, out instanceName, this._sniSpnBuffer, false, this._fAsync, multiSubnetFailover); if (this._physicalStateObj.Status != 0) { this.Errors.Add(this.ProcessSNIError(this._physicalStateObj)); this._physicalStateObj.Dispose(); Bid.Trace("<sc.TdsParser.Connect|ERR|SEC> Login failure\n"); this.ThrowExceptionAndWarning(); } this._server = serverInfo.ResolvedServerName; if (connHandler.PoolGroupProviderInfo != null) { connHandler.PoolGroupProviderInfo.AliasCheck((serverInfo.PreRoutingServerName == null) ? serverInfo.ResolvedServerName : serverInfo.PreRoutingServerName); } this._state = TdsParserState.OpenNotLoggedIn; this._physicalStateObj.SniContext = SniContext.Snix_PreLoginBeforeSuccessfullWrite; this._physicalStateObj.TimeoutTime = timerExpire; bool marsCapable = false; this.SendPreLoginHandshake(instanceName, encrypt); this._physicalStateObj.SniContext = SniContext.Snix_PreLogin; switch (this.ConsumePreLoginHandshake(encrypt, trustServerCert, out marsCapable)) { case PreLoginHandshakeStatus.SphinxFailure: this._fMARS = false; this._physicalStateObj._sniPacket = null; this._physicalStateObj.SniContext = SniContext.Snix_Connect; this._physicalStateObj.CreatePhysicalSNIHandle(serverInfo.ExtendedServerName, ignoreSniOpenTimeout, timerExpire, out instanceName, this._sniSpnBuffer, false, this._fAsync, multiSubnetFailover); if (this._physicalStateObj.Status != 0) { this.Errors.Add(this.ProcessSNIError(this._physicalStateObj)); Bid.Trace("<sc.TdsParser.Connect|ERR|SEC> Login failure\n"); this.ThrowExceptionAndWarning(); } break; case PreLoginHandshakeStatus.InstanceFailure: this._physicalStateObj.Dispose(); this._physicalStateObj.SniContext = SniContext.Snix_Connect; this._physicalStateObj.CreatePhysicalSNIHandle(serverInfo.ExtendedServerName, ignoreSniOpenTimeout, timerExpire, out instanceName, this._sniSpnBuffer, true, this._fAsync, multiSubnetFailover); if (this._physicalStateObj.Status != 0) { this.Errors.Add(this.ProcessSNIError(this._physicalStateObj)); Bid.Trace("<sc.TdsParser.Connect|ERR|SEC> Login failure\n"); this.ThrowExceptionAndWarning(); } this.SendPreLoginHandshake(instanceName, encrypt); if (this.ConsumePreLoginHandshake(encrypt, trustServerCert, out marsCapable) == PreLoginHandshakeStatus.InstanceFailure) { Bid.Trace("<sc.TdsParser.Connect|ERR|SEC> Login failure\n"); throw SQL.InstanceFailure(); } break; } if (this._fMARS && marsCapable) { this._sessionPool = new TdsParserSessionPool(this); } else { this._fMARS = false; } } }