/// <summary> /// Prepare response for session user name query /// </summary> private TDSMessage _PrepareSessionUserResponse(ITDSServerSession session) { // Prepare result metadata TDSColMetadataToken metadataToken = new TDSColMetadataToken(); // Prepare column type-specific data TDSShilohVarCharColumnSpecific nVarChar = new TDSShilohVarCharColumnSpecific(256, new TDSColumnDataCollation(13632521, 52)); // Prepare the first column TDSColumnData column = new TDSColumnData(); column.DataType = TDSDataType.NVarChar; column.Flags.Updatable = TDSColumnDataUpdatableFlag.Unknown; column.Flags.IsNullable = true; column.DataTypeSpecific = nVarChar; column.Name = "nt_user_name"; // Add a column to the response metadataToken.Columns.Add(column); // Prepare the second column column = new TDSColumnData(); column.DataType = TDSDataType.NVarChar; column.Flags.Updatable = TDSColumnDataUpdatableFlag.Unknown; column.Flags.IsNullable = true; column.DataTypeSpecific = nVarChar; column.Name = "nt_domain"; // Add a column to the response metadataToken.Columns.Add(column); // Prepare the third column column = new TDSColumnData(); column.DataType = TDSDataType.NVarChar; column.Flags.Updatable = TDSColumnDataUpdatableFlag.Unknown; column.DataTypeSpecific = nVarChar; column.Name = "login_name"; // Add a column to the response metadataToken.Columns.Add(column); // Log response TDSUtilities.Log(Log, "Response", metadataToken); // Prepare result data TDSRowToken rowToken = new TDSRowToken(metadataToken); // Check user type if (session.SQLUserID != null) { // Add row rowToken.Data.Add(null); // nt_user_name rowToken.Data.Add(null); // nt_domain rowToken.Data.Add(session.SQLUserID); // login_name } else if (session.NTUserAuthenticationContext != null) { // Get user identifier string userID = session.NTUserAuthenticationContext.GetRemoteIdentity().Name; // Look for traditional separator for form "<domain>\<user>" int indexOfSeparator = userID.IndexOf('\\'); string domain = null; string user = null; // Parse domain and user out of the entry if (indexOfSeparator != -1) { // Extract parts domain = userID.Substring(0, indexOfSeparator); user = userID.Substring(indexOfSeparator + 1); } else { // Look for a different type of separator for form "<user>@<domain>" indexOfSeparator = userID.IndexOf('@'); // Check if found if (indexOfSeparator != -1) { // Extract parts domain = userID.Substring(indexOfSeparator + 1); user = userID.Substring(0, indexOfSeparator); } else { // We don't recognize this user so don't parse it domain = null; user = userID; } } // Add row rowToken.Data.Add(user); // nt_user_name rowToken.Data.Add(domain); // nt_domain rowToken.Data.Add(userID); // login_name } else { // We don't have a user, which is very strange since we're in query engine already rowToken.Data.Add(null); // nt_user_name rowToken.Data.Add(null); // nt_domain rowToken.Data.Add(null); // login_name } // Log response TDSUtilities.Log(Log, "Response", rowToken); // Create DONE token TDSDoneToken doneToken = new TDSDoneToken(TDSDoneTokenStatusType.Final | TDSDoneTokenStatusType.Count, TDSDoneTokenCommandType.Select, 1); // Log response TDSUtilities.Log(Log, "Response", doneToken); // Serialize tokens into the message return new TDSMessage(TDSMessageType.Response, metadataToken, rowToken, doneToken); }
/// <summary> /// Prepare configuration response /// </summary> private TDSMessage _PrepareConfigurationResponse(ITDSServerSession session) { // Prepare result metadata TDSColMetadataToken metadataToken = new TDSColMetadataToken(); // Start the first column TDSColumnData column = new TDSColumnData(); column.DataType = TDSDataType.IntN; column.DataTypeSpecific = (byte)2; column.Flags.IsNullable = true; column.Flags.Updatable = TDSColumnDataUpdatableFlag.ReadOnly; column.Name = "TraceFlag"; // Add a column to the response metadataToken.Columns.Add(column); // Start the second column column = new TDSColumnData(); column.DataType = TDSDataType.IntN; column.DataTypeSpecific = (byte)2; column.Flags.IsNullable = true; column.Flags.Updatable = TDSColumnDataUpdatableFlag.ReadOnly; column.Name = "Status"; // Add a column to the response metadataToken.Columns.Add(column); // Start the third column column = new TDSColumnData(); column.DataType = TDSDataType.IntN; column.DataTypeSpecific = (byte)2; column.Flags.IsNullable = true; column.Flags.Updatable = TDSColumnDataUpdatableFlag.ReadOnly; column.Name = "Global"; // Add a column to the response metadataToken.Columns.Add(column); // Start the fourth column column = new TDSColumnData(); column.DataType = TDSDataType.IntN; column.DataTypeSpecific = (byte)2; column.Flags.IsNullable = true; column.Flags.Updatable = TDSColumnDataUpdatableFlag.ReadOnly; column.Name = "Session"; // Add a column to the response metadataToken.Columns.Add(column); // Log response TDSUtilities.Log(Log, "Response", metadataToken); // Create DONE token TDSDoneToken doneToken = new TDSDoneToken(TDSDoneTokenStatusType.Final | TDSDoneTokenStatusType.Count, TDSDoneTokenCommandType.Select, 0); // Log response TDSUtilities.Log(Log, "Response", doneToken); // Serialize tokens into the message return new TDSMessage(TDSMessageType.Response, metadataToken, doneToken); }
/// <summary> /// Prepare response for query of class of the SQL Server instance /// </summary> private TDSMessage _PrepareTestSQLServerClassResponse(ITDSServerSession session) { // Prepare result metadata TDSColMetadataToken metadataToken = new TDSColMetadataToken(); // Start first column TDSColumnData column = new TDSColumnData(); column.DataType = TDSDataType.NVarChar; column.DataTypeSpecific = new TDSShilohVarCharColumnSpecific(256, new TDSColumnDataCollation(13632521, 52)); column.Flags.Updatable = TDSColumnDataUpdatableFlag.ReadOnly; // Add a column to the response metadataToken.Columns.Add(column); // Log response TDSUtilities.Log(Log, "Response", metadataToken); // Prepare result data TDSRowToken rowToken = new TDSRowToken(metadataToken); // Get the server class rowToken.Data.Add(session.Server.GetType().FullName); // Log response TDSUtilities.Log(Log, "Response", rowToken); // Create DONE token TDSDoneToken doneToken = new TDSDoneToken(TDSDoneTokenStatusType.Final | TDSDoneTokenStatusType.Count, TDSDoneTokenCommandType.Select, 1); // Log response TDSUtilities.Log(Log, "Response", doneToken); // Serialize tokens into the message return new TDSMessage(TDSMessageType.Response, metadataToken, rowToken, doneToken); }
/// <summary> /// Ensure that federated authentication option is valid /// </summary> protected virtual TDSMessageCollection CheckFederatedAuthenticationOption(ITDSServerSession session, TDSLogin7FedAuthOptionToken federatedAuthenticationOption) { // Check if server's prelogin response for FedAuthRequired prelogin option is echoed back correctly in FedAuth Feature Extenion Echo if (federatedAuthenticationOption.Echo != (session as GenericTDSServerSession).FedAuthRequiredPreLoginServerResponse) { // Create Error message string message = string.Format("FEDAUTHREQUIRED option in the prelogin response is not echoed back correctly: in prelogin response, it is {0} and in login, it is {1}: ", (session as GenericTDSServerSession).FedAuthRequiredPreLoginServerResponse, federatedAuthenticationOption.Echo); // Create errorToken token TDSErrorToken errorToken = new TDSErrorToken(3456, 34, 23, message); // Log response TDSUtilities.Log(Arguments.Log, "Response", errorToken); // Create DONE token TDSDoneToken doneToken = new TDSDoneToken(TDSDoneTokenStatusType.Final | TDSDoneTokenStatusType.Error); // Log response TDSUtilities.Log(Arguments.Log, "Response", doneToken); // Build a collection with a single message of two tokens return new TDSMessageCollection(new TDSMessage(TDSMessageType.Response, errorToken, doneToken)); } // Check if the nonce exists if ((federatedAuthenticationOption.Nonce == null && federatedAuthenticationOption.Library == TDSFedAuthLibraryType.IDCRL) || !AreEqual((session as GenericTDSServerSession).ServerNonce, federatedAuthenticationOption.Nonce)) { // Error message string message = string.Format("Unexpected NONCEOPT specified in the Federated authentication feature extension"); // Create errorToken token TDSErrorToken errorToken = new TDSErrorToken(5672, 32, 87, message); // Log response TDSUtilities.Log(Arguments.Log, "Response", errorToken); // Create DONE token TDSDoneToken doneToken = new TDSDoneToken(TDSDoneTokenStatusType.Final | TDSDoneTokenStatusType.Error); // Log response TDSUtilities.Log(Arguments.Log, "Response", doneToken); // Build a collection with a single message of two tokens return new TDSMessageCollection(new TDSMessage(TDSMessageType.Response, errorToken, doneToken)); } // We're good return null; }
/// <summary> /// Handler for login request /// </summary> public override TDSMessageCollection OnLogin7Request(ITDSServerSession session, TDSMessage request) { // Inflate login7 request from the message TDSLogin7Token loginRequest = request[0] as TDSLogin7Token; // Check if arguments are of the authenticating TDS server if (Arguments is AuthenticatingTDSServerArguments) { // Cast to authenticating TDS server arguments AuthenticatingTDSServerArguments ServerArguments = Arguments as AuthenticatingTDSServerArguments; // Check if we're still processing normal login if (ServerArguments.ApplicationIntentFilter != ApplicationIntentFilterType.All) { // Check filter if ((ServerArguments.ApplicationIntentFilter == ApplicationIntentFilterType.ReadOnly && loginRequest.TypeFlags.ReadOnlyIntent != TDSLogin7TypeFlagsReadOnlyIntent.ReadOnly) || (ServerArguments.ApplicationIntentFilter == ApplicationIntentFilterType.None)) { // Log request to which we're about to send a failure TDSUtilities.Log(Arguments.Log, "Request", loginRequest); // Prepare ERROR token with the denial details TDSErrorToken errorToken = new TDSErrorToken(18456, 1, 14, "Received application intent: " + loginRequest.TypeFlags.ReadOnlyIntent.ToString(), Arguments.ServerName); // Log response TDSUtilities.Log(Arguments.Log, "Response", errorToken); // Serialize the error token into the response packet TDSMessage responseMessage = new TDSMessage(TDSMessageType.Response, errorToken); // Prepare ERROR token for the final decision errorToken = new TDSErrorToken(18456, 1, 14, "Connection is denied by application intent filter", Arguments.ServerName); // Log response TDSUtilities.Log(Arguments.Log, "Response", errorToken); // Serialize the error token into the response packet responseMessage.Add(errorToken); // Create DONE token TDSDoneToken doneToken = new TDSDoneToken(TDSDoneTokenStatusType.Final | TDSDoneTokenStatusType.Error); // Log response TDSUtilities.Log(Arguments.Log, "Response", doneToken); // Serialize DONE token into the response packet responseMessage.Add(doneToken); // Put a single message into the collection and return it return new TDSMessageCollection(responseMessage); } } // Check if we're still processing normal login and there's a filter to check if (ServerArguments.ServerNameFilterType != ServerNameFilterType.None) { // Check each algorithm if ((ServerArguments.ServerNameFilterType == ServerNameFilterType.Equals && string.Compare(ServerArguments.ServerNameFilter, loginRequest.ServerName, true) != 0) || (ServerArguments.ServerNameFilterType == ServerNameFilterType.StartsWith && !loginRequest.ServerName.StartsWith(ServerArguments.ServerNameFilter)) || (ServerArguments.ServerNameFilterType == ServerNameFilterType.EndsWith && !loginRequest.ServerName.EndsWith(ServerArguments.ServerNameFilter)) || (ServerArguments.ServerNameFilterType == ServerNameFilterType.Contains && !loginRequest.ServerName.Contains(ServerArguments.ServerNameFilter))) { // Log request to which we're about to send a failure TDSUtilities.Log(Arguments.Log, "Request", loginRequest); // Prepare ERROR token with the reason TDSErrorToken errorToken = new TDSErrorToken(18456, 1, 14, string.Format("Received server name \"{0}\", expected \"{1}\" using \"{2}\" algorithm", loginRequest.ServerName, ServerArguments.ServerNameFilter, ServerArguments.ServerNameFilterType), Arguments.ServerName); // Log response TDSUtilities.Log(Arguments.Log, "Response", errorToken); // Serialize the errorToken token into the response packet TDSMessage responseMessage = new TDSMessage(TDSMessageType.Response, errorToken); // Prepare ERROR token with the final errorToken errorToken = new TDSErrorToken(18456, 1, 14, "Connection is denied by server name filter", Arguments.ServerName); // Log response TDSUtilities.Log(Arguments.Log, "Response", errorToken); // Serialize the errorToken token into the response packet responseMessage.Add(errorToken); // Create DONE token TDSDoneToken doneToken = new TDSDoneToken(TDSDoneTokenStatusType.Final | TDSDoneTokenStatusType.Error); // Log response TDSUtilities.Log(Arguments.Log, "Response", doneToken); // Serialize DONE token into the response packet responseMessage.Add(doneToken); // Return only a single message with the collection return new TDSMessageCollection(responseMessage); } } // Check if packet size filter is applied if (ServerArguments.PacketSizeFilter != null) { // Check if requested packet size is the same as the filter specified if (loginRequest.PacketSize != ServerArguments.PacketSizeFilter.Value) { // Log request to which we're about to send a failure TDSUtilities.Log(Arguments.Log, "Request", loginRequest); // Prepare ERROR token with the reason TDSErrorToken errorToken = new TDSErrorToken(1919, 1, 14, string.Format("Received packet size \"{0}\", expected \"{1}\"", loginRequest.PacketSize, ServerArguments.PacketSizeFilter.Value), Arguments.ServerName); // Log response TDSUtilities.Log(Arguments.Log, "Response", errorToken); // Serialize the errorToken token into the response packet TDSMessage responseMessage = new TDSMessage(TDSMessageType.Response, errorToken); // Prepare ERROR token with the final errorToken errorToken = new TDSErrorToken(1919, 1, 14, "Connection is denied by packet size filter", Arguments.ServerName); // Log response TDSUtilities.Log(Arguments.Log, "Response", errorToken); // Serialize the errorToken token into the response packet responseMessage.Add(errorToken); // Create DONE token TDSDoneToken doneToken = new TDSDoneToken(TDSDoneTokenStatusType.Final | TDSDoneTokenStatusType.Error); // Log response TDSUtilities.Log(Arguments.Log, "Response", doneToken); // Serialize DONE token into the response packet responseMessage.Add(doneToken); // Return only a single message with the collection return new TDSMessageCollection(responseMessage); } } // If we have an application name filter if (ServerArguments.ApplicationNameFilter != null) { // If we are supposed to block this connection attempt if (loginRequest.ApplicationName.Equals(ServerArguments.ApplicationNameFilter, System.StringComparison.OrdinalIgnoreCase)) { // Log request to which we're about to send a failure TDSUtilities.Log(Arguments.Log, "Request", loginRequest); // Prepare ERROR token with the denial details TDSErrorToken errorToken = new TDSErrorToken(18456, 1, 14, "Received application name: " + loginRequest.ApplicationName, Arguments.ServerName); // Log response TDSUtilities.Log(Arguments.Log, "Response", errorToken); // Serialize the error token into the response packet TDSMessage responseMessage = new TDSMessage(TDSMessageType.Response, errorToken); // Prepare ERROR token for the final decision errorToken = new TDSErrorToken(18456, 1, 14, "Connection is denied by application name filter", Arguments.ServerName); // Log response TDSUtilities.Log(Arguments.Log, "Response", errorToken); // Serialize the error token into the response packet responseMessage.Add(errorToken); // Create DONE token TDSDoneToken doneToken = new TDSDoneToken(TDSDoneTokenStatusType.Final | TDSDoneTokenStatusType.Error); // Log response TDSUtilities.Log(Arguments.Log, "Response", doneToken); // Serialize DONE token into the response packet responseMessage.Add(doneToken); // Put a single message into the collection and return it return new TDSMessageCollection(responseMessage); } } } // Return login response from the base class return base.OnLogin7Request(session, request); }
/// <summary> /// Prepare response to server ping /// </summary> private TDSMessage _PreparePingResponse(ITDSServerSession session) { // Prepare result metadata TDSColMetadataToken metadataToken = new TDSColMetadataToken(); // Start the first column TDSColumnData column = new TDSColumnData(); column.DataType = TDSDataType.IntN; column.DataTypeSpecific = (byte)4; column.Flags.Updatable = TDSColumnDataUpdatableFlag.ReadOnly; column.Flags.IsNullable = true; // TODO: Must be nullable, otherwise something is wrong with SqlClient column.Flags.IsComputed = true; // Add a column to the response metadataToken.Columns.Add(column); // Log response TDSUtilities.Log(Log, "Response", metadataToken); // Prepare result data TDSRowToken rowToken = new TDSRowToken(metadataToken); // Add row rowToken.Data.Add((int)1); // Log response TDSUtilities.Log(Log, "Response", rowToken); // Create DONE token TDSDoneToken doneToken = new TDSDoneToken(TDSDoneTokenStatusType.Final | TDSDoneTokenStatusType.Count, TDSDoneTokenCommandType.Select, 1); // Log response TDSUtilities.Log(Log, "Response", doneToken); // Serialize tokens into the message return new TDSMessage(TDSMessageType.Response, metadataToken, rowToken, doneToken); }
protected virtual TDSMessageCollection OnAuthenticationCompleted(ITDSServerSession session) { // Create new database environment change token TDSEnvChangeToken envChange = new TDSEnvChangeToken(TDSEnvChangeTokenType.Database, session.Database, "master"); // Log response TDSUtilities.Log(Arguments.Log, "Response", envChange); // Serialize the login token into the response packet TDSMessage responseMessage = new TDSMessage(TDSMessageType.Response, envChange); // Create information token on the change TDSInfoToken infoToken = new TDSInfoToken(5701, 2, 0, string.Format("Changed database context to '{0}'", envChange.NewValue), Arguments.ServerName); // Log response TDSUtilities.Log(Arguments.Log, "Response", infoToken); // Serialize the login token into the response packet responseMessage.Add(infoToken); // Create new collation change token envChange = new TDSEnvChangeToken(TDSEnvChangeTokenType.SQLCollation, (session as GenericTDSServerSession).Collation); // Log response TDSUtilities.Log(Arguments.Log, "Response", envChange); // Serialize the login token into the response packet responseMessage.Add(envChange); // Create new language change token envChange = new TDSEnvChangeToken(TDSEnvChangeTokenType.Language, LanguageString.ToString((session as GenericTDSServerSession).Language)); // Log response TDSUtilities.Log(Arguments.Log, "Response", envChange); // Serialize the login token into the response packet responseMessage.Add(envChange); // Create information token on the change infoToken = new TDSInfoToken(5703, 1, 0, string.Format("Changed language setting to {0}", envChange.NewValue), Arguments.ServerName); // Log response TDSUtilities.Log(Arguments.Log, "Response", infoToken); // Serialize the login token into the response packet responseMessage.Add(infoToken); // Create new packet size environment change token envChange = new TDSEnvChangeToken(TDSEnvChangeTokenType.PacketSize, Arguments.PacketSize.ToString(), Arguments.PacketSize.ToString()); // Log response TDSUtilities.Log(Arguments.Log, "Response", envChange); // Serialize the login token into the response packet responseMessage.Add(envChange); // Update session packet size session.PacketSize = (uint)Arguments.PacketSize; // Create login acknowledgnment packet TDSLoginAckToken loginResponseToken = new TDSLoginAckToken(Arguments.ServerVersion, session.TDSVersion, TDSLogin7TypeFlagsSQL.SQL, "Microsoft SQL Server"); // Otherwise SNAC yields E_FAIL // Log response TDSUtilities.Log(Arguments.Log, "Response", loginResponseToken); // Serialize the login token into the response packet responseMessage.Add(loginResponseToken); // Check if session recovery is enabled if (session.IsSessionRecoveryEnabled) { // Create Feature extension Ack token TDSFeatureExtAckToken featureExtActToken = new TDSFeatureExtAckToken(new TDSFeatureExtAckSessionStateOption((session as GenericTDSServerSession).Deflate())); // Log response TDSUtilities.Log(Arguments.Log, "Response", featureExtActToken); // Serialize feature extnesion token into the response responseMessage.Add(featureExtActToken); } // Create DONE token TDSDoneToken doneToken = new TDSDoneToken(TDSDoneTokenStatusType.Final); // Log response TDSUtilities.Log(Arguments.Log, "Response", doneToken); // Serialize DONE token into the response packet responseMessage.Add(doneToken); // Wrap a single message in a collection return new TDSMessageCollection(responseMessage); }
/// <summary> /// Prepare response for options /// </summary> private TDSMessage _PrepareOptionsResponse(ITDSServerSession session) { // Prepare result metadata TDSColMetadataToken metadataToken = new TDSColMetadataToken(); // Start a new column TDSColumnData column = new TDSColumnData(); column.DataType = TDSDataType.Int4; column.Flags.Updatable = TDSColumnDataUpdatableFlag.ReadOnly; column.Flags.IsComputed = true; // Add a column to the response metadataToken.Columns.Add(column); // Log response TDSUtilities.Log(Log, "Response", metadataToken); // Prepare result data TDSRowToken rowToken = new TDSRowToken(metadataToken); // Convert to generic session GenericTDSServerSession genericSession = session as GenericTDSServerSession; // Serialize the options into the bit mask int options = 0; // Check transaction abort on error if (genericSession.TransactionAbortOnError) { options |= 0x4000; } // Check numeric round abort if (genericSession.NumericRoundAbort) { options |= 0x2000; } // Check concatenation of nulls yields null if (genericSession.ConcatNullYieldsNull) { options |= 0x1000; } // Check ansi null default OFF if (!genericSession.AnsiNullDefaultOn) { options |= 0x800; } // Check ansi null default ON if (genericSession.AnsiNullDefaultOn) { options |= 0x400; } // Check no count if (genericSession.NoCount) { options |= 0x200; } // Check quoted identifier if (genericSession.QuotedIdentifier) { options |= 0x100; } // Check arithmetic ignore if (genericSession.ArithIgnore) { options |= 0x80; } // Check arithmetic abort if (genericSession.ArithAbort) { options |= 0x40; } // Check ansi nulls if (genericSession.AnsiNulls) { options |= 0x20; } // Check ansi padding if (genericSession.AnsiPadding) { options |= 0x10; } // Check ansi warnings if (genericSession.AnsiWarnings) { options |= 0x8; } // Check cursor close on commit if (genericSession.CursorCloseOnCommit) { options |= 0x4; } // Check implicit transactions if (genericSession.ImplicitTransactions) { options |= 0x2; } // Read the value from the session rowToken.Data.Add(options); // Log response TDSUtilities.Log(Log, "Response", rowToken); // Create DONE token TDSDoneToken doneToken = new TDSDoneToken(TDSDoneTokenStatusType.Final | TDSDoneTokenStatusType.Count, TDSDoneTokenCommandType.Select, 1); // Log response TDSUtilities.Log(Log, "Response", doneToken); // Serialize tokens into the message return new TDSMessage(TDSMessageType.Response, metadataToken, rowToken, doneToken); }
/// <summary> /// Prepare response for context info /// </summary> private TDSMessage _PrepareContextInfoResponse(ITDSServerSession session) { // Prepare result metadata TDSColMetadataToken metadataToken = new TDSColMetadataToken(); // Start a new column TDSColumnData column = new TDSColumnData(); column.DataType = TDSDataType.BigVarBinary; column.DataTypeSpecific = (ushort)128; column.Flags.Updatable = TDSColumnDataUpdatableFlag.ReadOnly; // Add a column to the response metadataToken.Columns.Add(column); // Log response TDSUtilities.Log(Log, "Response", metadataToken); // Prepare result data TDSRowToken rowToken = new TDSRowToken(metadataToken); // Prepare context info container byte[] contextInfo = null; // Check if session has a context info if ((session as GenericTDSServerSession).ContextInfo != null) { // Allocate a container contextInfo = new byte[128]; // Copy context info into the container Array.Copy((session as GenericTDSServerSession).ContextInfo, contextInfo, (session as GenericTDSServerSession).ContextInfo.Length); } // Set context info rowToken.Data.Add(contextInfo); // Log response TDSUtilities.Log(Log, "Response", rowToken); // Create DONE token TDSDoneToken doneToken = new TDSDoneToken(TDSDoneTokenStatusType.Final | TDSDoneTokenStatusType.Count, TDSDoneTokenCommandType.Select, 1); // Log response TDSUtilities.Log(Log, "Response", doneToken); // Serialize tokens into the message return new TDSMessage(TDSMessageType.Response, metadataToken, rowToken, doneToken); }
/// <summary> /// Prepare response for language /// </summary> private TDSMessage _PrepareLanguageResponse(ITDSServerSession session) { // Prepare result metadata TDSColMetadataToken metadataToken = new TDSColMetadataToken(); // Start a new column TDSColumnData column = new TDSColumnData(); column.DataType = TDSDataType.NVarChar; column.DataTypeSpecific = new TDSShilohVarCharColumnSpecific(256, new TDSColumnDataCollation(13632521, 52)); column.Flags.Updatable = TDSColumnDataUpdatableFlag.ReadOnly; column.Flags.IsNullable = true; column.Name = "language"; // Add a column to the response metadataToken.Columns.Add(column); // Log response TDSUtilities.Log(Log, "Response", metadataToken); // Prepare result data TDSRowToken rowToken = new TDSRowToken(metadataToken); // Generate a date format string rowToken.Data.Add(LanguageString.ToString((session as GenericTDSServerSession).Language)); // Log response TDSUtilities.Log(Log, "Response", rowToken); // Create DONE token TDSDoneToken doneToken = new TDSDoneToken(TDSDoneTokenStatusType.Final | TDSDoneTokenStatusType.Count, TDSDoneTokenCommandType.Select, 1); // Log response TDSUtilities.Log(Log, "Response", doneToken); // Serialize tokens into the message return new TDSMessage(TDSMessageType.Response, metadataToken, rowToken, doneToken); }
/// <summary> /// Prepare response for transaction isolation level /// </summary> private TDSMessage _PrepareTransactionIsolationLevelResponse(ITDSServerSession session) { // Prepare result metadata TDSColMetadataToken metadataToken = new TDSColMetadataToken(); // Start a new column TDSColumnData column = new TDSColumnData(); column.DataType = TDSDataType.Int2; column.Flags.Updatable = TDSColumnDataUpdatableFlag.ReadOnly; column.Name = "transaction_isolation_level"; // Add a column to the response metadataToken.Columns.Add(column); // Log response TDSUtilities.Log(Log, "Response", metadataToken); // Prepare result data TDSRowToken rowToken = new TDSRowToken(metadataToken); // Read the value from the session rowToken.Data.Add((short)(session as GenericTDSServerSession).TransactionIsolationLevel); // Log response TDSUtilities.Log(Log, "Response", rowToken); // Create DONE token TDSDoneToken doneToken = new TDSDoneToken(TDSDoneTokenStatusType.Final | TDSDoneTokenStatusType.Count, TDSDoneTokenCommandType.Select, 1); // Log response TDSUtilities.Log(Log, "Response", doneToken); // Serialize tokens into the message return new TDSMessage(TDSMessageType.Response, metadataToken, rowToken, doneToken); }
/// <summary> /// Prepare response for ANSI null default on /// </summary> private TDSMessage _PrepareAnsiNullDefaultOnResponse(ITDSServerSession session) { // Prepare result metadata TDSColMetadataToken metadataToken = new TDSColMetadataToken(); // Start a new column TDSColumnData column = new TDSColumnData(); column.DataType = TDSDataType.Bit; column.Flags.Updatable = TDSColumnDataUpdatableFlag.ReadOnly; column.Name = "ansi_null_dflt_on"; // Add a column to the response metadataToken.Columns.Add(column); // Log response TDSUtilities.Log(Log, "Response", metadataToken); // Prepare result data TDSRowToken rowToken = new TDSRowToken(metadataToken); // Read the value from the session rowToken.Data.Add((session as GenericTDSServerSession).AnsiNullDefaultOn); // Log response TDSUtilities.Log(Log, "Response", rowToken); // Create DONE token TDSDoneToken doneToken = new TDSDoneToken(TDSDoneTokenStatusType.Final | TDSDoneTokenStatusType.Count, TDSDoneTokenCommandType.Select, 1); // Log response TDSUtilities.Log(Log, "Response", doneToken); // Serialize tokens into the message return new TDSMessage(TDSMessageType.Response, metadataToken, rowToken, doneToken); }
/// <summary> /// Prepare response to connection reset request count /// </summary> private TDSMessage _PrepareAuthSchemeResponse(ITDSServerSession session) { // Prepare result metadata TDSColMetadataToken metadataToken = new TDSColMetadataToken(); // Start the first column TDSColumnData column = new TDSColumnData(); column.DataType = TDSDataType.NVarChar; column.DataTypeSpecific = new TDSShilohVarCharColumnSpecific(40, new TDSColumnDataCollation(13632521, 52)); column.Flags.Updatable = TDSColumnDataUpdatableFlag.ReadOnly; column.Name = "auth_scheme"; // Add a column to the response metadataToken.Columns.Add(column); // Log response TDSUtilities.Log(Log, "Response", metadataToken); // Prepare result data TDSRowToken rowToken = new TDSRowToken(metadataToken); // Check which authentication method are we using // @TODO add Federated Authentication once VSTS 1072394 is resolved if (session.SQLUserID != null) { // Add row rowToken.Data.Add("SQL"); } else { // Add row rowToken.Data.Add("NTML"); } // Log response TDSUtilities.Log(Log, "Response", rowToken); // Create DONE token TDSDoneToken doneToken = new TDSDoneToken(TDSDoneTokenStatusType.Final | TDSDoneTokenStatusType.Count, TDSDoneTokenCommandType.Select, 1); // Log response TDSUtilities.Log(Log, "Response", doneToken); // Serialize tokens into the message return new TDSMessage(TDSMessageType.Response, metadataToken, rowToken, doneToken); }
/// <summary> /// Prepare response to connection reset request count /// </summary> private TDSMessage _PrepareSPIDResponse(ITDSServerSession session) { // Prepare result metadata TDSColMetadataToken metadataToken = new TDSColMetadataToken(); // Start the first column TDSColumnData column = new TDSColumnData(); column.DataType = TDSDataType.NVarChar; column.DataTypeSpecific = new TDSShilohVarCharColumnSpecific(128, new TDSColumnDataCollation(13632521, 52)); column.Flags.Updatable = TDSColumnDataUpdatableFlag.ReadOnly; column.Flags.IsNullable = true; column.Flags.IsComputed = true; // Add a column to the response metadataToken.Columns.Add(column); // Log response TDSUtilities.Log(Log, "Response", metadataToken); // Prepare result data TDSRowToken rowToken = new TDSRowToken(metadataToken); // Add row rowToken.Data.Add(session.SessionID.ToString()); // Log response TDSUtilities.Log(Log, "Response", rowToken); // Create DONE token TDSDoneToken doneToken = new TDSDoneToken(TDSDoneTokenStatusType.Final | TDSDoneTokenStatusType.Count, TDSDoneTokenCommandType.Select, 1); // Log response TDSUtilities.Log(Log, "Response", doneToken); // Serialize tokens into the message return new TDSMessage(TDSMessageType.Response, metadataToken, rowToken, doneToken); }
/// <summary> /// Prepare response to the query about connection end-point /// </summary> private TDSMessage _PrepareConnectionInfoResponse(ITDSServerSession session) { // Prepare result metadata TDSColMetadataToken metadataToken = new TDSColMetadataToken(); // Start the first column TDSColumnData column = new TDSColumnData(); column.DataType = TDSDataType.NVarChar; column.DataTypeSpecific = new TDSShilohVarCharColumnSpecific(40, new TDSColumnDataCollation(13632521, 52)); column.Flags.Updatable = TDSColumnDataUpdatableFlag.ReadOnly; column.Name = "net_transport"; // Add a column to the response metadataToken.Columns.Add(column); // Start the second column column = new TDSColumnData(); column.DataType = TDSDataType.BigVarChar; column.DataTypeSpecific = new TDSShilohVarCharColumnSpecific(48, new TDSColumnDataCollation(13632521, 52)); column.Flags.IsNullable = true; column.Flags.Updatable = TDSColumnDataUpdatableFlag.ReadOnly; column.Name = "local_net_address"; // Add a column to the response metadataToken.Columns.Add(column); // Start the third column column = new TDSColumnData(); column.DataType = TDSDataType.IntN; column.DataTypeSpecific = (byte)4; column.Flags.IsNullable = true; column.Flags.Updatable = TDSColumnDataUpdatableFlag.ReadOnly; column.Name = "local_tcp_port"; // Add a column to the response metadataToken.Columns.Add(column); // Log response TDSUtilities.Log(Log, "Response", metadataToken); // Prepare result data TDSRowToken rowToken = new TDSRowToken(metadataToken); // Add row rowToken.Data.Add(session.ServerEndPointInfo.Transport.ToString()); rowToken.Data.Add(session.ServerEndPointInfo.Address.ToString()); rowToken.Data.Add(session.ServerEndPointInfo.Port); // Log response TDSUtilities.Log(Log, "Response", rowToken); // Create DONE token TDSDoneToken doneToken = new TDSDoneToken(TDSDoneTokenStatusType.Final | TDSDoneTokenStatusType.Count, TDSDoneTokenCommandType.Select, 1); // Log response TDSUtilities.Log(Log, "Response", doneToken); // Serialize tokens into the message return new TDSMessage(TDSMessageType.Response, metadataToken, rowToken, doneToken); }
/// <summary> /// Handle attention from the client /// </summary> public TDSMessageCollection ExecuteAttention(ITDSServerSession session, TDSMessage request) { // Create attention DONE token TDSDoneToken doneToken = new TDSDoneToken(TDSDoneTokenStatusType.Final | TDSDoneTokenStatusType.Attention); // Log response TDSUtilities.Log(Log, "Response", doneToken); // Return a single message with DONE token only return new TDSMessageCollection(new TDSMessage(TDSMessageType.Response, doneToken)); }
/// <summary> /// Prepare response to the query about connection encryption /// </summary> private TDSMessage _PrepareEncryptionInfoResponse(ITDSServerSession session) { // Prepare result metadata TDSColMetadataToken metadataToken = new TDSColMetadataToken(); // Start the first column TDSColumnData column = new TDSColumnData(); column.DataType = TDSDataType.NVarChar; column.DataTypeSpecific = new TDSShilohVarCharColumnSpecific(40, new TDSColumnDataCollation(13632521, 52)); column.Flags.Updatable = TDSColumnDataUpdatableFlag.ReadOnly; column.Name = "encrypt_option"; // Add a column to the response metadataToken.Columns.Add(column); // Log response TDSUtilities.Log(Log, "Response", metadataToken); // Prepare result data TDSRowToken rowToken = new TDSRowToken(metadataToken); // Check if encryption is enabled if (session.Encryption == TDSEncryptionType.Full) { // Add row rowToken.Data.Add("TRUE"); } else { // Add row rowToken.Data.Add("FALSE"); } // Log response TDSUtilities.Log(Log, "Response", rowToken); // Create DONE token TDSDoneToken doneToken = new TDSDoneToken(TDSDoneTokenStatusType.Final | TDSDoneTokenStatusType.Count, TDSDoneTokenCommandType.Select, 1); // Log response TDSUtilities.Log(Log, "Response", doneToken); // Serialize tokens into the message return new TDSMessage(TDSMessageType.Response, metadataToken, rowToken, doneToken); }
/// <summary> /// Execute the query and produce a response /// </summary> public TDSMessageCollection ExecuteBatch(ITDSServerSession session, TDSMessage request) { // Get the batch from the tokens TDSSQLBatchToken batchRequest = request[0] as TDSSQLBatchToken; // Log request TDSUtilities.Log(Log, "Request", batchRequest); // Increase the counter of connection reset requests if the message contains the proper flags if (request.IsResetConnectionRequestSet || request.IsResetConnectionSkipTransactionRequestSet) { session.ConnectionResetRequestCount++; } // Prepare response message TDSMessage responseMessage = new TDSMessage(TDSMessageType.Response); // Prepare query text string lowerBatchText = batchRequest.Text.ToLowerInvariant(); // Check query if (lowerBatchText.Contains("serverproperty('servername')")) // SELECT convert(nvarchar(256), ServerProperty('ServerName')) { // Delegate to server name query responseMessage = _PrepareServerNameResponse(session); } if (lowerBatchText.Contains("serverproperty('machinename')")) // SELECT convert(nvarchar(256), ServerProperty('MachineName')) { // Delegate to server name query responseMessage = _PrepareMachineNameResponse(session); } else if (lowerBatchText.Contains("serverproperty('instancename')")) // SELECT convert(nvarchar(256), ServerProperty('InstanceName')) { // Delegate to instance name query responseMessage = _PrepareInstanceNameResponse(session); } else if (lowerBatchText.Contains("serverproperty('ishadrenabled')")) // SELECT convert(bit, ServerProperty('IsHADREnabled')) { // Delegate to HADRon query responseMessage = _PrepareIsHADRResponse(session); } else if (lowerBatchText.Contains("serverproperty('engineedition')")) // SELECT convert(int, ServerProperty('EngineEdition')) { // Delegate to Azure query responseMessage = _PrepareIsAzure(session); } else if (lowerBatchText.Contains("serverproperty('islocaldb')")) // SELECT convert(bit, ServerProperty('IsLocalDB')) { // Delegate to Local DB query responseMessage = _PrepareIsLocalDB(session); } else if (lowerBatchText.Contains("serverproperty('istestsqlserver')")) // SELECT convert(bit, ServerProperty('IsTestSQLServer')) { // Delegate to test SQL Server query response responseMessage = _PrepareIsTestSQLServerResponse(session); } else if (lowerBatchText.Contains("serverproperty('testsqlserverclass')")) // SELECT convert(nvarchar(256), ServerProperty('TestSQLServerClass')) { // Delegate to test SQL Server class response responseMessage = _PrepareTestSQLServerClassResponse(session); } else if (lowerBatchText.Contains("dm_exec_sessions") && lowerBatchText.Contains("login_name") && lowerBatchText.Contains("nt_domain") && lowerBatchText.Contains("nt_user_name") && lowerBatchText.Contains("session_id")) // SELECT login_name, nt_domain, nt_user_name FROM sys.dm_exec_sessions WHERE session_id = @@spid { // Delegate to session user query responseMessage = _PrepareSessionUserResponse(session); } else if (lowerBatchText.Contains("sp_oledb_ro_usrname")) // exec [sys].sp_oledb_ro_usrname { // Delegate to OLE DB query responseMessage = _PrepareOleDbReadOnlyUserName(session); } else if (lowerBatchText.Contains("physical_net_transport") && lowerBatchText.Contains("local_net_address") && lowerBatchText.Contains("local_tcp_port")) // SELECT convert(nvarchar(40), ConnectionProperty('physical_net_transport')), convert(varchar(48), ConnectionProperty('local_net_address')), convert(int, ConnectionProperty('local_tcp_port')) { // Delegate to connection information query responseMessage = _PrepareConnectionInfoResponse(session); } else if (lowerBatchText.Contains("dm_exec_connections") && lowerBatchText.Contains("encrypt_option") && lowerBatchText.Contains("session_id")) // SELECT TOP (1) [encrypt_option] FROM [sys].[dm_exec_connections] WHERE [session_id] = @@SPID { // Delegate to encryption information query responseMessage = _PrepareEncryptionInfoResponse(session); } else if (lowerBatchText.Contains("select 1")) // SELECT 1 { // Delegate to server ping response responseMessage = _PreparePingResponse(session); } else if (lowerBatchText.Contains("name") && lowerBatchText.Contains("state") && lowerBatchText.Contains("databases") && lowerBatchText.Contains("db_name")) // SELECT [name], [state] FROM [sys].[databases] WHERE [name] = db_name() { // Delegate to current database response responseMessage = _PrepareDatabaseResponse(session); } else if (lowerBatchText.Contains("dbcc") && lowerBatchText.Contains("tracestatus")) // dbcc tracestatus() { // Delegate to current configuration response responseMessage = _PrepareConfigurationResponse(session); } else if (lowerBatchText.Contains("connectionproperty('sp_reset_connection_count')")) // select CONNECTIONPROPERTY('sp_reset_connection_count') { // Delegate to reset connection request response responseMessage = _PrepareConnectionResetRequestCountResponse(session); } else if (lowerBatchText.Contains("select") && lowerBatchText.Contains("convert") && lowerBatchText.Contains("nvarchar(128)") && lowerBatchText.Contains("@@spid")) // SELECT convert(nvarchar(128), @@SPID) { // Delegate to reset connection request response responseMessage = _PrepareSPIDResponse(session); } else if (lowerBatchText.Contains("select") && lowerBatchText.Contains("auth_scheme") && lowerBatchText.Contains("dm_exec_connections")) //select top (1) [auth_scheme] from [sys].[dm_exec_connections] where [session_id] = @@spid { // Delegate to reset connection request response responseMessage = _PrepareAuthSchemeResponse(session); } else if (lowerBatchText.Contains("select") && lowerBatchText.Contains("ansi_defaults") && lowerBatchText.Contains("dm_exec_sessions") && lowerBatchText.Contains("session_id") && lowerBatchText.Contains("@@spid")) // SELECT TOP (1) [ansi_defaults] FROM [sys].[dm_exec_sessions] WHERE [session_id] = @@SPID { // Delegate session property query responseMessage = _PrepareAnsiDefaultsResponse(session); } else if (lowerBatchText.Contains("select") && lowerBatchText.Contains("ansi_null_dflt_on") && lowerBatchText.Contains("dm_exec_sessions") && lowerBatchText.Contains("session_id") && lowerBatchText.Contains("@@spid")) // SELECT TOP (1) [ansi_null_dflt_on] FROM [sys].[dm_exec_sessions] WHERE [session_id] = @@SPID { // Delegate session property query responseMessage = _PrepareAnsiNullDefaultOnResponse(session); } else if (lowerBatchText.Contains("select") && lowerBatchText.Contains("ansi_nulls") && lowerBatchText.Contains("dm_exec_sessions") && lowerBatchText.Contains("session_id") && lowerBatchText.Contains("@@spid")) // SELECT TOP (1) [ansi_nulls] FROM [sys].[dm_exec_sessions] WHERE [session_id] = @@SPID { // Delegate session property query responseMessage = _PrepareAnsiNullsResponse(session); } else if (lowerBatchText.Contains("select") && lowerBatchText.Contains("ansi_padding") && lowerBatchText.Contains("dm_exec_sessions") && lowerBatchText.Contains("session_id") && lowerBatchText.Contains("@@spid")) // SELECT TOP (1) [ansi_padding] FROM [sys].[dm_exec_sessions] WHERE [session_id] = @@SPID { // Delegate session property query responseMessage = _PrepareAnsiPaddingResponse(session); } else if (lowerBatchText.Contains("select") && lowerBatchText.Contains("ansi_warnings") && lowerBatchText.Contains("dm_exec_sessions") && lowerBatchText.Contains("session_id") && lowerBatchText.Contains("@@spid")) // SELECT TOP (1) [ansi_warnings] FROM [sys].[dm_exec_sessions] WHERE [session_id] = @@SPID { // Delegate session property query responseMessage = _PrepareAnsiWarningsResponse(session); } else if (lowerBatchText.Contains("select") && lowerBatchText.Contains("arithabort") && lowerBatchText.Contains("dm_exec_sessions") && lowerBatchText.Contains("session_id") && lowerBatchText.Contains("@@spid")) // SELECT TOP (1) [arithabort] FROM [sys].[dm_exec_sessions] WHERE [session_id] = @@SPID { // Delegate session property query responseMessage = _PrepareArithAbortResponse(session); } else if (lowerBatchText.Contains("select") && lowerBatchText.Contains("concat_null_yields_null") && lowerBatchText.Contains("dm_exec_sessions") && lowerBatchText.Contains("session_id") && lowerBatchText.Contains("@@spid")) // SELECT TOP (1) [concat_null_yields_null] FROM [sys].[dm_exec_sessions] WHERE [session_id] = @@SPID { // Delegate session property query responseMessage = _PrepareConcatNullYieldsNullResponse(session); } else if (lowerBatchText.Contains("select") && lowerBatchText.Contains("date_first") && lowerBatchText.Contains("dm_exec_sessions") && lowerBatchText.Contains("session_id") && lowerBatchText.Contains("@@spid")) // SELECT TOP (1) [date_first] FROM [sys].[dm_exec_sessions] WHERE [session_id] = @@SPID { // Delegate session property query responseMessage = _PrepareDateFirstResponse(session); } else if (lowerBatchText.Contains("select") && lowerBatchText.Contains("date_format") && lowerBatchText.Contains("dm_exec_sessions") && lowerBatchText.Contains("session_id") && lowerBatchText.Contains("@@spid")) // SELECT TOP (1) [date_format] FROM [sys].[dm_exec_sessions] WHERE [session_id] = @@SPID { // Delegate session property query responseMessage = _PrepareDateFormatResponse(session); } else if (lowerBatchText.Contains("select") && lowerBatchText.Contains("deadlock_priority") && lowerBatchText.Contains("dm_exec_sessions") && lowerBatchText.Contains("session_id") && lowerBatchText.Contains("@@spid")) // SELECT TOP (1) [deadlock_priority] FROM [sys].[dm_exec_sessions] WHERE [session_id] = @@SPID { // Delegate session property query responseMessage = _PrepareDeadlockPriorityResponse(session); } else if (lowerBatchText.Contains("select") && lowerBatchText.Contains("language") && lowerBatchText.Contains("dm_exec_sessions") && lowerBatchText.Contains("session_id") && lowerBatchText.Contains("@@spid")) // SELECT TOP (1) [language] FROM [sys].[dm_exec_sessions] WHERE [session_id] = @@SPID { // Delegate session property query responseMessage = _PrepareLanguageResponse(session); } else if (lowerBatchText.Contains("select") && lowerBatchText.Contains("lock_timeout") && lowerBatchText.Contains("dm_exec_sessions") && lowerBatchText.Contains("session_id") && lowerBatchText.Contains("@@spid")) // SELECT TOP (1) [lock_timeout] FROM [sys].[dm_exec_sessions] WHERE [session_id] = @@SPID { // Delegate session property query responseMessage = _PrepareLockTimeoutResponse(session); } else if (lowerBatchText.Contains("select") && lowerBatchText.Contains("quoted_identifier") && lowerBatchText.Contains("dm_exec_sessions") && lowerBatchText.Contains("session_id") && lowerBatchText.Contains("@@spid")) // SELECT TOP (1) [quoted_identifier] FROM [sys].[dm_exec_sessions] WHERE [session_id] = @@SPID { // Delegate session property query responseMessage = _PrepareQuotedIdentifierResponse(session); } else if (lowerBatchText.Contains("select") && lowerBatchText.Contains("text_size") && lowerBatchText.Contains("dm_exec_sessions") && lowerBatchText.Contains("session_id") && lowerBatchText.Contains("@@spid")) // SELECT TOP (1) [text_size] FROM [sys].[dm_exec_sessions] WHERE [session_id] = @@SPID { // Delegate session property query responseMessage = _PrepareTextSizeResponse(session); } else if (lowerBatchText.Contains("select") && lowerBatchText.Contains("transaction_isolation_level") && lowerBatchText.Contains("dm_exec_sessions") && lowerBatchText.Contains("session_id") && lowerBatchText.Contains("@@spid")) // SELECT TOP (1) [transaction_isolation_level] FROM [sys].[dm_exec_sessions] WHERE [session_id] = @@SPID { // Delegate session property query responseMessage = _PrepareTransactionIsolationLevelResponse(session); } else if (lowerBatchText.Contains("select") && lowerBatchText.Contains("@@options")) // SELECT @@OPTIONS { // Delegate session property query responseMessage = _PrepareOptionsResponse(session); } else if (lowerBatchText.Contains("select") && lowerBatchText.Contains("context_info()")) // SELECT CONTEXT_INFO() { // Delegate session property query responseMessage = _PrepareContextInfoResponse(session); } else { // Create an info token that contains the query received TDSInfoToken infoToken = new TDSInfoToken(2012, 2, 0, lowerBatchText); // Log response TDSUtilities.Log(Log, "Response", infoToken); // Serialize DONE token into the response packet responseMessage.Add(infoToken); // Create an info token to let client know that we don't recognize this query infoToken = new TDSInfoToken(2012, 2, 0, "Received query is not recognized by the query engine. Please ask a very specific question."); // Log response TDSUtilities.Log(Log, "Response", infoToken); // Serialize DONE token into the response packet responseMessage.Add(infoToken); // Create generic DONE token TDSDoneToken doneToken = new TDSDoneToken(TDSDoneTokenStatusType.Final); // Log response TDSUtilities.Log(Log, "Response", doneToken); // Serialize DONE token into the response packet responseMessage.Add(doneToken); } // Response collection will contain only one message return new TDSMessageCollection(responseMessage); }
/// <summary> /// Advances one step in SSPI authentication sequence /// </summary> protected virtual TDSMessageCollection ContinueSSPIAuthentication(ITDSServerSession session, byte[] payload) { // Response to send to the client SSPIResponse response; try { // Check if we have an SSPI context if (session.NTUserAuthenticationContext == null) { // This is the first step so we need to create a server context and initialize it session.NTUserAuthenticationContext = SSPIContext.CreateServer(); // Run the first step of authentication response = session.NTUserAuthenticationContext.StartServerAuthentication(payload); } else { // Process SSPI request from the client response = session.NTUserAuthenticationContext.ContinueServerAuthentication(payload); } } catch (Exception e) { // Prepare ERROR token with the reason TDSErrorToken errorToken = new TDSErrorToken(12345, 1, 15, "Failed to accept security SSPI context", Arguments.ServerName); // Log response TDSUtilities.Log(Arguments.Log, "Response", errorToken); // Serialize the error token into the response packet TDSMessage responseErrorMessage = new TDSMessage(TDSMessageType.Response, errorToken); // Prepare ERROR token with the final errorToken errorToken = new TDSErrorToken(12345, 1, 15, e.Message, Arguments.ServerName); // Log response TDSUtilities.Log(Arguments.Log, "Response", errorToken); // Serialize the error token into the response packet responseErrorMessage.Add(errorToken); // Create DONE token TDSDoneToken doneToken = new TDSDoneToken(TDSDoneTokenStatusType.Final | TDSDoneTokenStatusType.Error); // Log response TDSUtilities.Log(Arguments.Log, "Response", doneToken); // Serialize DONE token into the response packet responseErrorMessage.Add(doneToken); // Respond with a single message return new TDSMessageCollection(responseErrorMessage); } // Message collection to respond with TDSMessageCollection responseMessages = new TDSMessageCollection(); // Check if there's a response if (response != null) { // Check if there's a payload if (response.Payload != null) { // Create SSPI token TDSSSPIToken sspiToken = new TDSSSPIToken(response.Payload); // Log response TDSUtilities.Log(Arguments.Log, "Response", sspiToken); // Prepare response message with a single response token responseMessages.Add(new TDSMessage(TDSMessageType.Response, sspiToken)); // Check if we can complete login if (!response.IsFinal) { // Send the message to the client return responseMessages; } } } // Reset SQL user identifier since we're using NT authentication session.SQLUserID = null; // Append successfully authentication response responseMessages.AddRange(OnAuthenticationCompleted(session)); // Return the message with SSPI token return responseMessages; }
/// <summary> /// Prepare response for server instance name query /// </summary> private TDSMessage _PrepareInstanceNameResponse(ITDSServerSession session) { // Prepare result metadata TDSColMetadataToken metadataToken = new TDSColMetadataToken(); // Start first column TDSColumnData column = new TDSColumnData(); column.DataType = TDSDataType.NVarChar; column.DataTypeSpecific = new TDSShilohVarCharColumnSpecific(256, new TDSColumnDataCollation(13632521, 52)); column.Flags.Updatable = TDSColumnDataUpdatableFlag.ReadOnly; // Add a column to the response metadataToken.Columns.Add(column); // Log response TDSUtilities.Log(Log, "Response", metadataToken); // Prepare result data TDSRowToken rowToken = new TDSRowToken(metadataToken); // Start with server name string value = ServerArguments.ServerName; // Check if server name contains a slash if (value.Contains("\\")) { // Take everything after the slash value = value.Substring(value.IndexOf('\\') + 1); } else { // Instance is unnamed value = null; } // Add row rowToken.Data.Add(value); // Log response TDSUtilities.Log(Log, "Response", rowToken); // Create DONE token TDSDoneToken doneToken = new TDSDoneToken(TDSDoneTokenStatusType.Final | TDSDoneTokenStatusType.Count, TDSDoneTokenCommandType.Select, 1); // Log response TDSUtilities.Log(Log, "Response", doneToken); // Serialize tokens into the message return new TDSMessage(TDSMessageType.Response, metadataToken, rowToken, doneToken); }
/// <summary> /// Complete the Federated Login /// </summary> /// <param name="session">Server session</param> /// <returns>Federated Login message collection</returns> protected virtual TDSMessageCollection OnFederatedAuthenticationCompleted(ITDSServerSession session, byte[] ticket) { // Delegate to successful authentication routine TDSMessageCollection responseMessageCollection = OnAuthenticationCompleted(session); // Get the last message TDSMessage targetMessage = responseMessageCollection.Last(); IFederatedAuthenticationTicket decryptedTicket = null; try { // Get the Federated Authentication ticket using RPS decryptedTicket = FederatedAuthenticationTicketService.DecryptTicket((session as GenericTDSServerSession).FederatedAuthenticationLibrary, ticket); if (decryptedTicket is RpsTicket) { TDSUtilities.Log(Arguments.Log, "RPS ticket session key: ", (decryptedTicket as RpsTicket).sessionKey); } else if (decryptedTicket is JwtTicket) { TDSUtilities.Log(Arguments.Log, "JWT Ticket Received", null); } } catch (Exception ex) { // Prepare ERROR token TDSErrorToken errorToken = new TDSErrorToken(54879, 1, 20, "Authentication error in Federated Authentication Ticket Service: " + ex.Message, Arguments.ServerName); // Log response TDSUtilities.Log(Arguments.Log, "Response", errorToken); // Create DONE token TDSDoneToken doneToken = new TDSDoneToken(TDSDoneTokenStatusType.Final | TDSDoneTokenStatusType.Error); // Log response TDSUtilities.Log(Arguments.Log, "Response", doneToken); // Return the message and stop processing request return new TDSMessageCollection(new TDSMessage(TDSMessageType.Response, errorToken, doneToken)); } // Create federated authentication extension option TDSFeatureExtAckFederatedAuthenticationOption federatedAuthenticationOption; if ((session as GenericTDSServerSession).FederatedAuthenticationLibrary == TDSFedAuthLibraryType.ADAL) { // For the time being, fake fedauth tokens are used for ADAL, so decryptedTicket is null. federatedAuthenticationOption = new TDSFeatureExtAckFederatedAuthenticationOption((session as GenericTDSServerSession).ClientNonce, null); } else { federatedAuthenticationOption = new TDSFeatureExtAckFederatedAuthenticationOption((session as GenericTDSServerSession).ClientNonce, decryptedTicket.GetSignature((session as GenericTDSServerSession).ClientNonce)); } // Look for feature extension token TDSFeatureExtAckToken featureExtActToken = (TDSFeatureExtAckToken)targetMessage.Where(t => t is TDSFeatureExtAckToken).FirstOrDefault(); // Check if response already contains federated authentication if (featureExtActToken == null) { // Create Feature extension Ack token featureExtActToken = new TDSFeatureExtAckToken(federatedAuthenticationOption); // Serialize feature extension token into the response // The last token is Done token, so we should put feautureextack token before done token targetMessage.Insert(targetMessage.Count - 1, featureExtActToken); } else { // Update featureExtActToken.Options.Add(federatedAuthenticationOption); } // Log response TDSUtilities.Log(Arguments.Log, "Response", federatedAuthenticationOption); // Wrap a message with a collection return responseMessageCollection; }
/// <summary> /// Prepare response for user nane query that OLE DB stack dispatches upon connection /// </summary> private TDSMessage _PrepareOleDbReadOnlyUserName(ITDSServerSession session) { // Prepare result metadata TDSColMetadataToken metadataToken = new TDSColMetadataToken(); // Start first column TDSColumnData column = new TDSColumnData(); column.DataType = TDSDataType.BigVarChar; column.DataTypeSpecific = new TDSShilohVarCharColumnSpecific(1, new TDSColumnDataCollation(13632521, 52)); column.Flags.Updatable = TDSColumnDataUpdatableFlag.ReadOnly; // Add a column to the response metadataToken.Columns.Add(column); // Start second column column = new TDSColumnData(); column.DataType = TDSDataType.NVarChar; column.DataTypeSpecific = new TDSShilohVarCharColumnSpecific(128, new TDSColumnDataCollation(13632521, 52)); column.Flags.Updatable = TDSColumnDataUpdatableFlag.ReadOnly; // Add a column to the response metadataToken.Columns.Add(column); // Log response TDSUtilities.Log(Log, "Response", metadataToken); // Prepare result data TDSRowToken rowToken = new TDSRowToken(metadataToken); // Add row rowToken.Data.Add("N"); rowToken.Data.Add("dbo"); // Log response TDSUtilities.Log(Log, "Response", rowToken); // Create DONE token TDSDoneToken doneToken = new TDSDoneToken(TDSDoneTokenStatusType.Final | TDSDoneTokenStatusType.Count, TDSDoneTokenCommandType.Select, 1); // Log response TDSUtilities.Log(Log, "Response", doneToken); // Serialize tokens into the message return new TDSMessage(TDSMessageType.Response, metadataToken, rowToken, doneToken); }
/// <summary> /// Checks the TDS version /// </summary> /// <param name="session">Server session</param> /// <returns>Null if the TDS version is supported, errorToken message otherwise</returns> protected virtual TDSMessageCollection CheckTDSVersion(ITDSServerSession session) { // Check if version is supported if (TDSVersion.IsSupported(session.TDSVersion)) { return null; } // Prepare ERROR token TDSErrorToken errorToken = new TDSErrorToken(12345, 1, 16, "Unsupported TDS client version", Arguments.ServerName); // Log response TDSUtilities.Log(Arguments.Log, "Response", errorToken); // Create DONE token TDSDoneToken doneToken = new TDSDoneToken(TDSDoneTokenStatusType.Final | TDSDoneTokenStatusType.Error); // Log response TDSUtilities.Log(Arguments.Log, "Response", doneToken); // Wrap with message collection return new TDSMessageCollection(new TDSMessage(TDSMessageType.Response, errorToken, doneToken)); }
/// <summary> /// Prepare response for query whether this is a SQL Azure instance /// </summary> private TDSMessage _PrepareIsAzure(ITDSServerSession session) { // Prepare result metadata TDSColMetadataToken metadataToken = new TDSColMetadataToken(); // Start a new column TDSColumnData column = new TDSColumnData(); column.DataType = TDSDataType.IntN; column.DataTypeSpecific = (byte)4; column.Flags.Updatable = TDSColumnDataUpdatableFlag.ReadOnly; column.Flags.IsComputed = true; column.Flags.IsNullable = true; // TODO: Must be nullable, otherwise something is wrong with SqlClient // Add a column to the response metadataToken.Columns.Add(column); // Log response TDSUtilities.Log(Log, "Response", metadataToken); // Prepare result data TDSRowToken rowToken = new TDSRowToken(metadataToken); // Per http://msdn.microsoft.com/en-us/library/ms174396.aspx // 4 = Express (This is returned for Express, Express with Advanced Services, and Windows Embedded SQL.) rowToken.Data.Add(4); // Log response TDSUtilities.Log(Log, "Response", rowToken); // Create DONE token TDSDoneToken doneToken = new TDSDoneToken(TDSDoneTokenStatusType.Final | TDSDoneTokenStatusType.Count, TDSDoneTokenCommandType.Select, 1); // Log response TDSUtilities.Log(Log, "Response", doneToken); // Serialize tokens into the message return new TDSMessage(TDSMessageType.Response, metadataToken, rowToken, doneToken); }
/// <summary> /// Handler for login request /// </summary> public override TDSMessageCollection OnLogin7Request(ITDSServerSession session, TDSMessage request) { // Inflate login7 request from the message TDSLogin7Token loginRequest = request[0] as TDSLogin7Token; // Check if arguments are of the routing server if (Arguments is RoutingTDSServerArguments) { // Cast to routing server arguments RoutingTDSServerArguments ServerArguments = Arguments as RoutingTDSServerArguments; // Check filter if (ServerArguments.RequireReadOnly && (loginRequest.TypeFlags.ReadOnlyIntent != TDSLogin7TypeFlagsReadOnlyIntent.ReadOnly)) { // Log request TDSUtilities.Log(Arguments.Log, "Request", loginRequest); // Prepare ERROR token with the denial details TDSErrorToken errorToken = new TDSErrorToken(18456, 1, 14, "Received application intent: " + loginRequest.TypeFlags.ReadOnlyIntent.ToString(), Arguments.ServerName); // Log response TDSUtilities.Log(Arguments.Log, "Response", errorToken); // Serialize the error token into the response packet TDSMessage responseMessage = new TDSMessage(TDSMessageType.Response, errorToken); // Prepare ERROR token for the final decision errorToken = new TDSErrorToken(18456, 1, 14, "Read-Only application intent is required for routing", Arguments.ServerName); // Log response TDSUtilities.Log(Arguments.Log, "Response", errorToken); // Serialize the error token into the response packet responseMessage.Add(errorToken); // Create DONE token TDSDoneToken doneToken = new TDSDoneToken(TDSDoneTokenStatusType.Final | TDSDoneTokenStatusType.Error); // Log response TDSUtilities.Log(Arguments.Log, "Response", doneToken); // Serialize DONE token into the response packet responseMessage.Add(doneToken); // Return a single message in the collection return new TDSMessageCollection(responseMessage); } } // Delegate to the base class return base.OnLogin7Request(session, request); }
/// <summary> /// Prepare current database response /// </summary> private TDSMessage _PrepareDatabaseResponse(ITDSServerSession session) { // Prepare result metadata TDSColMetadataToken metadataToken = new TDSColMetadataToken(); // Start the first column TDSColumnData column = new TDSColumnData(); column.DataType = TDSDataType.NVarChar; column.DataTypeSpecific = new TDSShilohVarCharColumnSpecific(256, new TDSColumnDataCollation(13632521, 52)); column.Flags.Updatable = TDSColumnDataUpdatableFlag.ReadOnly; column.Name = "name"; // Add a column to the response metadataToken.Columns.Add(column); // Start the second column column = new TDSColumnData(); column.DataType = TDSDataType.IntN; column.DataTypeSpecific = (byte)1; column.Flags.IsNullable = true; column.Name = "state"; // Add a column to the response metadataToken.Columns.Add(column); // Log response TDSUtilities.Log(Log, "Response", metadataToken); // Prepare result data TDSRowToken rowToken = new TDSRowToken(metadataToken); // Add row rowToken.Data.Add(session.Database); rowToken.Data.Add((byte)0); // Online // Log response TDSUtilities.Log(Log, "Response", rowToken); // Create DONE token TDSDoneToken doneToken = new TDSDoneToken(TDSDoneTokenStatusType.Final | TDSDoneTokenStatusType.Count, TDSDoneTokenCommandType.Select, 1); // Log response TDSUtilities.Log(Log, "Response", doneToken); // Serialize tokens into the message return new TDSMessage(TDSMessageType.Response, metadataToken, rowToken, doneToken); }