From f8460ddb162988930345535cc683b3d3caffc7a2 Mon Sep 17 00:00:00 2001 From: Cheena Malhotra Date: Wed, 24 Jun 2020 16:43:04 -0700 Subject: [PATCH 1/7] Add support for Data Classification v2 Introduces Sensitivity Rank with Sensitivity Classification information --- .../ColumnSensitivity.xml | 3 +- .../InformationType.xml | 9 +- .../Label.xml | 5 +- .../SensitivityClassification.xml | 33 +- .../SensitivityProperty.xml | 28 +- .../SensitivityRank.xml | 17 + .../netcore/ref/Microsoft.Data.SqlClient.cs | 24 +- .../SqlClient/SqlInternalConnectionTds.cs | 11 +- .../src/Microsoft/Data/SqlClient/TdsEnums.cs | 3 +- .../src/Microsoft/Data/SqlClient/TdsParser.cs | 40 +- .../netfx/ref/Microsoft.Data.SqlClient.cs | 344 +++++++++--------- .../SqlClient/SqlInternalConnectionTds.cs | 11 +- .../src/Microsoft/Data/SqlClient/TdsEnums.cs | 3 +- .../src/Microsoft/Data/SqlClient/TdsParser.cs | 44 ++- .../SensitivityClassification.cs | 29 +- .../DataClassificationTest.cs | 106 +++++- 16 files changed, 480 insertions(+), 230 deletions(-) create mode 100644 doc/snippets/Microsoft.Data.SqlClient.DataClassification/SensitivityRank.xml diff --git a/doc/snippets/Microsoft.Data.SqlClient.DataClassification/ColumnSensitivity.xml b/doc/snippets/Microsoft.Data.SqlClient.DataClassification/ColumnSensitivity.xml index 8f1fcfeb99..2c43af620c 100644 --- a/doc/snippets/Microsoft.Data.SqlClient.DataClassification/ColumnSensitivity.xml +++ b/doc/snippets/Microsoft.Data.SqlClient.DataClassification/ColumnSensitivity.xml @@ -3,15 +3,14 @@ Represents the Data Classification Sensitivity Information for columns as configured in Database. - To be added. Initializes a new instance of the class. + List of sensitivity properties. Returns the list of sensitivity properties as received from Server for this 'ColumnSensitivity' information List of sensitivity properties. - To be added. diff --git a/doc/snippets/Microsoft.Data.SqlClient.DataClassification/InformationType.xml b/doc/snippets/Microsoft.Data.SqlClient.DataClassification/InformationType.xml index db93a31054..ff2dca0c3c 100644 --- a/doc/snippets/Microsoft.Data.SqlClient.DataClassification/InformationType.xml +++ b/doc/snippets/Microsoft.Data.SqlClient.DataClassification/InformationType.xml @@ -3,20 +3,19 @@ Represents the Data Classification Information Types as received from SQL Server for the active 'SqlDataReader' - To be added. Initializes a new instance of the class. + Name of Information Type. + ID of Information Type. Gets the ID for this 'InformationType' object - ID of InformationType. - To be added. + ID of Information Type. Gets the name for this 'InformationType' object - Name of InformationType. - To be added. + Name of Information Type. diff --git a/doc/snippets/Microsoft.Data.SqlClient.DataClassification/Label.xml b/doc/snippets/Microsoft.Data.SqlClient.DataClassification/Label.xml index 6ccdecde4d..7d75923abe 100644 --- a/doc/snippets/Microsoft.Data.SqlClient.DataClassification/Label.xml +++ b/doc/snippets/Microsoft.Data.SqlClient.DataClassification/Label.xml @@ -3,20 +3,19 @@ Initializes a new instance of the class. + Name of label. + ID of label. Gets the ID for this 'Label' object ID of label. - To be added. Gets the name for this 'Label' object Name of label. - To be added. diff --git a/doc/snippets/Microsoft.Data.SqlClient.DataClassification/SensitivityClassification.xml b/doc/snippets/Microsoft.Data.SqlClient.DataClassification/SensitivityClassification.xml index e9c6e90b2e..4bc3e643ea 100644 --- a/doc/snippets/Microsoft.Data.SqlClient.DataClassification/SensitivityClassification.xml +++ b/doc/snippets/Microsoft.Data.SqlClient.DataClassification/SensitivityClassification.xml @@ -3,26 +3,47 @@ Provides the functionlity to retrieve Sensitivity Classification data as received from SQL Server for the active 'SqlDataReader' - To be added. Returns the column sensitivity for this 'SensitivityClassification' Object List of column sensitivities. - To be added. Returns the information types collection for this 'SensitivityClassification' Object List of information types. - To be added. Returns the labels collection for this 'SensitivityClassification' Object List of labels. - To be added. + + Returns the relative sensitivity rank for the query associated with the active 'SqlDataReader'. + Relative sensitivity ranking for this query. + + + + + + - Initializes a new instance of the - class. + Initializes a new instance of the class. + List of labels. + List of information types. + List of column sensitivities. + Relative sensitivity rank for the query associated with the active 'SqlDataReader'. diff --git a/doc/snippets/Microsoft.Data.SqlClient.DataClassification/SensitivityProperty.xml b/doc/snippets/Microsoft.Data.SqlClient.DataClassification/SensitivityProperty.xml index b54c8384b9..beafa279cc 100644 --- a/doc/snippets/Microsoft.Data.SqlClient.DataClassification/SensitivityProperty.xml +++ b/doc/snippets/Microsoft.Data.SqlClient.DataClassification/SensitivityProperty.xml @@ -3,20 +3,42 @@ Represents the Data Classification Sensitivity Information for columns as configured in Database. - To be added. Initializes a new instance of the class. + Label for this SensitivityProperty. + Information type for this SensitivityProperty. + Sensitivity rank for this SensitivityProperty. Returns the information type for this 'SensitivityProperty' Object Information type for this SensitivityProperty. - To be added. + + Returns the sensitivity rank for this 'SensitivityProperty' Object + Sensitivity rank for this SensitivityProperty. + + + + + + diff --git a/doc/snippets/Microsoft.Data.SqlClient.DataClassification/SensitivityRank.xml b/doc/snippets/Microsoft.Data.SqlClient.DataClassification/SensitivityRank.xml new file mode 100644 index 0000000000..41e215e29e --- /dev/null +++ b/doc/snippets/Microsoft.Data.SqlClient.DataClassification/SensitivityRank.xml @@ -0,0 +1,17 @@ + + + + + + A relative ranking of the sensitivity of a query or of a column that is part of percolumn data. + It is an identifier based on a predefined set of values which define sensitivity rank. Used by other services like Advanced Threat Protection to detect anomalies based on their rank. + + + No sensitivity rank defined. + Corresponds to rank value of 0. + Corresponds to rank value of 10. + Corresponds to rank value 20. + Corresponds to rank value 30. + Corresponds to rank value 40. + + diff --git a/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.cs b/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.cs index 8b53ecfdf6..514a35ad36 100644 --- a/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.cs +++ b/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.cs @@ -1895,26 +1895,46 @@ public partial class Label /// public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } } + /// + public enum SensitivityRank + { + /// + NOT_DEFINED = -1, + /// + NONE = 0, + /// + LOW = 10, + /// + MEDIUM = 20, + /// + HIGH = 30, + /// + CRITICAL = 40 + } /// public partial class SensitivityClassification { /// - public SensitivityClassification(System.Collections.Generic.IList labels, System.Collections.Generic.IList informationTypes, System.Collections.Generic.IList columnSensitivity) { } + public SensitivityClassification(System.Collections.Generic.IList labels, System.Collections.Generic.IList informationTypes, System.Collections.Generic.IList columnSensitivity, SensitivityRank sensitivityRank) { } /// public System.Collections.ObjectModel.ReadOnlyCollection ColumnSensitivities { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } /// public System.Collections.ObjectModel.ReadOnlyCollection InformationTypes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } /// public System.Collections.ObjectModel.ReadOnlyCollection Labels { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + /// + public SensitivityRank SensitivityRank { get { throw null; } } } /// public partial class SensitivityProperty { /// - public SensitivityProperty(Microsoft.Data.SqlClient.DataClassification.Label label, Microsoft.Data.SqlClient.DataClassification.InformationType informationType) { } + public SensitivityProperty(Microsoft.Data.SqlClient.DataClassification.Label label, Microsoft.Data.SqlClient.DataClassification.InformationType informationType, SensitivityRank sensitivityRank) { } /// public Microsoft.Data.SqlClient.DataClassification.InformationType InformationType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } /// public Microsoft.Data.SqlClient.DataClassification.Label Label { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + /// + public SensitivityRank SensitivityRank { get { throw null; } } } } diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs index 4525d4c75d..4220d86e24 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs @@ -129,9 +129,10 @@ sealed internal class SqlInternalConnectionTds : SqlInternalConnection, IDisposa private readonly SqlAuthenticationProviderManager _sqlAuthenticationProviderManager; internal bool _cleanSQLDNSCaching = false; - private bool _serverSupportsDNSCaching = false; + internal byte _supportedDataClassificationVersion = TdsEnums.DATA_CLASSIFICATION_NOT_ENABLED; + /// /// Get or set if SQLDNSCaching is supported by the server. /// @@ -2609,11 +2610,11 @@ internal void OnFeatureExtAck(int featureId, byte[] data) SqlClientEventSource.Log.TraceEvent(" {0}, Unknown token for DATACLASSIFICATION", ObjectID); throw SQL.ParsingError(ParsingErrorState.CorruptedTdsStream); } - byte supportedDataClassificationVersion = data[0]; - if ((0 == supportedDataClassificationVersion) || (supportedDataClassificationVersion > TdsEnums.MAX_SUPPORTED_DATA_CLASSIFICATION_VERSION)) + _supportedDataClassificationVersion = data[0]; + if ((0 == _supportedDataClassificationVersion) || (_supportedDataClassificationVersion > TdsEnums.MAX_SUPPORTED_DATA_CLASSIFICATION_VERSION)) { SqlClientEventSource.Log.TraceEvent(" {0}, Invalid version number for DATACLASSIFICATION", ObjectID); - throw SQL.ParsingErrorValue(ParsingErrorState.DataClassificationInvalidVersion, supportedDataClassificationVersion); + throw SQL.ParsingErrorValue(ParsingErrorState.DataClassificationInvalidVersion, _supportedDataClassificationVersion); } if (data.Length != 2) @@ -2622,7 +2623,7 @@ internal void OnFeatureExtAck(int featureId, byte[] data) throw SQL.ParsingError(ParsingErrorState.CorruptedTdsStream); } byte enabled = data[1]; - _parser.DataClassificationVersion = (enabled == 0) ? TdsEnums.DATA_CLASSIFICATION_NOT_ENABLED : supportedDataClassificationVersion; + _parser.DataClassificationVersion = (enabled == 0) ? TdsEnums.DATA_CLASSIFICATION_NOT_ENABLED : _supportedDataClassificationVersion; break; } diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsEnums.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsEnums.cs index 25dbb5dd76..c57b591428 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsEnums.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsEnums.cs @@ -933,7 +933,8 @@ internal enum FedAuthInfoId : byte // Data Classification constants internal const byte DATA_CLASSIFICATION_NOT_ENABLED = 0x00; - internal const byte MAX_SUPPORTED_DATA_CLASSIFICATION_VERSION = 0x01; + internal const byte DATA_CLASSIFICATION_VERSION_WITHOUT_RANK_SUPPORT = 0x01; + internal const byte MAX_SUPPORTED_DATA_CLASSIFICATION_VERSION = 0x02; // Needed for UapAot, since we cannot use Enum.GetName() on SniContext. // Enum.GetName() uses reflection, which is blocked on UapAot for internal types diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs index 9070b88fa6..b616e0d4dd 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs @@ -471,13 +471,13 @@ internal void ProcessPendingAck(TdsParserStateObject stateObj) uint result = _physicalStateObj.SniGetConnectionId(ref _connHandler._clientConnectionId); Debug.Assert(result == TdsEnums.SNI_SUCCESS, "Unexpected failure state upon calling SniGetConnectionId"); - + if (null == _connHandler.pendingSQLDNSObject) { // for DNS Caching phase 1 _physicalStateObj.AssignPendingDNSInfo(serverInfo.UserProtocol, FQDNforDNSCahce, ref _connHandler.pendingSQLDNSObject); } - + SqlClientEventSource.Log.TraceEvent(" Sending prelogin handshake", "SEC"); SendPreLoginHandshake(instanceName, encrypt); @@ -3136,7 +3136,7 @@ private bool TryProcessFeatureExtAck(TdsParserStateObject stateObj) ret = SQLFallbackDNSCache.Instance.DeleteDNSInfo(FQDNforDNSCahce); } - if ( _connHandler.IsSQLDNSCachingSupported && _connHandler.pendingSQLDNSObject != null + if (_connHandler.IsSQLDNSCachingSupported && _connHandler.pendingSQLDNSObject != null && !SQLFallbackDNSCache.Instance.IsDuplicate(_connHandler.pendingSQLDNSObject)) { ret = SQLFallbackDNSCache.Instance.AddDNSInfo(_connHandler.pendingSQLDNSObject); @@ -3356,6 +3356,21 @@ private bool TryProcessDataClassification(TdsParserStateObject stateObj, out Sen informationTypes.Add(new InformationType(informationType, id)); } + // get sensitivity rank + Int32 sensitivityRank = (int)SensitivityRank.NOT_DEFINED; + if (_connHandler._supportedDataClassificationVersion > TdsEnums.DATA_CLASSIFICATION_VERSION_WITHOUT_RANK_SUPPORT) + { + if (!stateObj.TryReadInt32(out sensitivityRank)) + { + return false; + } + Console.WriteLine(sensitivityRank); + if (!Enum.IsDefined(typeof(SensitivityRank), sensitivityRank)) + { + return false; + } + } + // get the per column classification data (corresponds to order of output columns for query) UInt16 numResultColumns; if (!stateObj.TryReadUInt16(out numResultColumns)) @@ -3406,14 +3421,27 @@ private bool TryProcessDataClassification(TdsParserStateObject stateObj, out Sen informationType = informationTypes[informationTypeIndex]; } + // get sensitivity rank + Int32 sensitivityRankProperty = (int)SensitivityRank.NOT_DEFINED; + if (_connHandler._supportedDataClassificationVersion > TdsEnums.DATA_CLASSIFICATION_VERSION_WITHOUT_RANK_SUPPORT) + { + if (!stateObj.TryReadInt32(out sensitivityRankProperty)) + { + return false; + } + if (!Enum.IsDefined(typeof(SensitivityRank), sensitivityRankProperty)) + { + return false; + } + } + // add sentivity properties for the source - sensitivityProperties.Add(new SensitivityProperty(label, informationType)); + sensitivityProperties.Add(new SensitivityProperty(label, informationType, (SensitivityRank)sensitivityRankProperty)); } columnSensitivities.Add(new ColumnSensitivity(sensitivityProperties)); } - sensitivityClassification = new SensitivityClassification(labels, informationTypes, columnSensitivities); - + sensitivityClassification = new SensitivityClassification(labels, informationTypes, columnSensitivities, (SensitivityRank)sensitivityRank); return true; } diff --git a/src/Microsoft.Data.SqlClient/netfx/ref/Microsoft.Data.SqlClient.cs b/src/Microsoft.Data.SqlClient/netfx/ref/Microsoft.Data.SqlClient.cs index 69dbf03312..523a903962 100644 --- a/src/Microsoft.Data.SqlClient/netfx/ref/Microsoft.Data.SqlClient.cs +++ b/src/Microsoft.Data.SqlClient/netfx/ref/Microsoft.Data.SqlClient.cs @@ -5,7 +5,7 @@ [assembly: System.Resources.NeutralResourcesLanguageAttribute("en-US")] namespace Microsoft.Data { - /// + /// [System.Serializable] public sealed partial class OperationAbortedException : System.SystemException { @@ -17,18 +17,18 @@ public sealed partial class OperationAbortedException : System.SystemException } namespace Microsoft.Data.Sql { - /// + /// public sealed partial class SqlNotificationRequest { - /// + /// public SqlNotificationRequest() { } - /// + /// public SqlNotificationRequest(string userData, string options, int timeout) { } - /// + /// public string Options { get { throw null; } set { } } - /// + /// public int Timeout { get { throw null; } set { } } - /// + /// public string UserData { get { throw null; } set { } } } } @@ -826,21 +826,21 @@ public enum SqlConnectionColumnEncryptionSetting Enabled = 1, } - /// + /// public enum SqlConnectionAttestationProtocol { - /// + /// NotSpecified = 0, - /// + /// AAS = 1, #if ENCLAVE_SIMULATOR - /// + /// SIM = 2, #endif - /// + /// HGS = 3 } @@ -923,7 +923,7 @@ public sealed partial class SqlConnectionStringBuilder : System.Data.Common.DbCo /// [System.ComponentModel.DisplayNameAttribute("Attestation Protocol")] [System.ComponentModel.RefreshPropertiesAttribute(System.ComponentModel.RefreshProperties.All)] - public Microsoft.Data.SqlClient.SqlConnectionAttestationProtocol AttestationProtocol {get { throw null; } set { } } + public Microsoft.Data.SqlClient.SqlConnectionAttestationProtocol AttestationProtocol { get { throw null; } set { } } /// [System.ComponentModel.DisplayNameAttribute("Encrypt")] @@ -1921,332 +1921,352 @@ public partial class SqlDataRecord : System.Data.IDataRecord /// public virtual int SetValues(params object[] values) { throw null; } } - /// + /// [System.AttributeUsage(System.AttributeTargets.Method, AllowMultiple = false, Inherited = false), System.SerializableAttribute] public partial class SqlFunctionAttribute : System.Attribute { - /// + /// public SqlFunctionAttribute() { } - /// + /// public bool IsDeterministic { get { throw null; } set { } } - /// + /// public DataAccessKind DataAccess { get { throw null; } set { } } - /// + /// public SystemDataAccessKind SystemDataAccess { get { throw null; } set { } } - /// + /// public bool IsPrecise { get { throw null; } set { } } - /// + /// public string Name { get { throw null; } set { } } - /// + /// public string TableDefinition { get { throw null; } set { } } - /// + /// public string FillRowMethodName { get { throw null; } set { } } } - /// + /// public sealed partial class SqlMetaData { - /// + /// public SqlMetaData(string name, System.Data.SqlDbType dbType) { } - /// + /// public SqlMetaData(string name, System.Data.SqlDbType dbType, bool useServerDefault, bool isUniqueKey, Microsoft.Data.SqlClient.SortOrder columnSortOrder, int sortOrdinal) { } - /// + /// public SqlMetaData(string name, System.Data.SqlDbType dbType, byte precision, byte scale) { } - /// + /// public SqlMetaData(string name, System.Data.SqlDbType dbType, byte precision, byte scale, bool useServerDefault, bool isUniqueKey, Microsoft.Data.SqlClient.SortOrder columnSortOrder, int sortOrdinal) { } - /// + /// public SqlMetaData(string name, System.Data.SqlDbType dbType, long maxLength) { } - /// + /// public SqlMetaData(string name, System.Data.SqlDbType dbType, long maxLength, bool useServerDefault, bool isUniqueKey, Microsoft.Data.SqlClient.SortOrder columnSortOrder, int sortOrdinal) { } - /// + /// public SqlMetaData(string name, System.Data.SqlDbType dbType, long maxLength, byte precision, byte scale, long locale, System.Data.SqlTypes.SqlCompareOptions compareOptions, System.Type userDefinedType) { } - /// + /// public SqlMetaData(string name, System.Data.SqlDbType dbType, long maxLength, byte precision, byte scale, long localeId, System.Data.SqlTypes.SqlCompareOptions compareOptions, System.Type userDefinedType, bool useServerDefault, bool isUniqueKey, Microsoft.Data.SqlClient.SortOrder columnSortOrder, int sortOrdinal) { } - /// + /// public SqlMetaData(string name, System.Data.SqlDbType dbType, long maxLength, long locale, System.Data.SqlTypes.SqlCompareOptions compareOptions) { } - /// + /// public SqlMetaData(string name, System.Data.SqlDbType dbType, long maxLength, long locale, System.Data.SqlTypes.SqlCompareOptions compareOptions, bool useServerDefault, bool isUniqueKey, Microsoft.Data.SqlClient.SortOrder columnSortOrder, int sortOrdinal) { } - /// + /// public SqlMetaData(string name, System.Data.SqlDbType dbType, string database, string owningSchema, string objectName) { } - /// + /// public SqlMetaData(string name, System.Data.SqlDbType dbType, string database, string owningSchema, string objectName, bool useServerDefault, bool isUniqueKey, Microsoft.Data.SqlClient.SortOrder columnSortOrder, int sortOrdinal) { } - /// + /// public SqlMetaData(string name, System.Data.SqlDbType dbType, System.Type userDefinedType) { } - /// + /// public SqlMetaData(string name, System.Data.SqlDbType dbType, System.Type userDefinedType, string serverTypeName) { } - /// + /// public SqlMetaData(string name, System.Data.SqlDbType dbType, System.Type userDefinedType, string serverTypeName, bool useServerDefault, bool isUniqueKey, Microsoft.Data.SqlClient.SortOrder columnSortOrder, int sortOrdinal) { } - /// + /// public System.Data.SqlTypes.SqlCompareOptions CompareOptions { get { throw null; } } - /// + /// public System.Data.DbType DbType { get { throw null; } } - /// + /// public bool IsUniqueKey { get { throw null; } } - /// + /// public long LocaleId { get { throw null; } } - /// + /// public static long Max { get { throw null; } } - /// + /// public long MaxLength { get { throw null; } } - /// + /// public string Name { get { throw null; } } - /// + /// public byte Precision { get { throw null; } } - /// + /// public byte Scale { get { throw null; } } - /// + /// public Microsoft.Data.SqlClient.SortOrder SortOrder { get { throw null; } } - /// + /// public int SortOrdinal { get { throw null; } } - /// + /// public System.Data.SqlDbType SqlDbType { get { throw null; } } - /// + /// public System.Type Type { get { throw null; } } - /// + /// public string TypeName { get { throw null; } } - /// + /// public bool UseServerDefault { get { throw null; } } - /// + /// public string XmlSchemaCollectionDatabase { get { throw null; } } - /// + /// public string XmlSchemaCollectionName { get { throw null; } } - /// + /// public string XmlSchemaCollectionOwningSchema { get { throw null; } } - /// + /// public bool Adjust(bool value) { throw null; } - /// + /// public byte Adjust(byte value) { throw null; } - /// + /// public byte[] Adjust(byte[] value) { throw null; } - /// + /// public char Adjust(char value) { throw null; } - /// + /// public char[] Adjust(char[] value) { throw null; } - /// + /// public System.Data.SqlTypes.SqlBinary Adjust(System.Data.SqlTypes.SqlBinary value) { throw null; } - /// + /// public System.Data.SqlTypes.SqlBoolean Adjust(System.Data.SqlTypes.SqlBoolean value) { throw null; } - /// + /// public System.Data.SqlTypes.SqlByte Adjust(System.Data.SqlTypes.SqlByte value) { throw null; } - /// + /// public System.Data.SqlTypes.SqlBytes Adjust(System.Data.SqlTypes.SqlBytes value) { throw null; } - /// + /// public System.Data.SqlTypes.SqlChars Adjust(System.Data.SqlTypes.SqlChars value) { throw null; } - /// + /// public System.Data.SqlTypes.SqlDateTime Adjust(System.Data.SqlTypes.SqlDateTime value) { throw null; } - /// + /// public System.Data.SqlTypes.SqlDecimal Adjust(System.Data.SqlTypes.SqlDecimal value) { throw null; } - /// + /// public System.Data.SqlTypes.SqlDouble Adjust(System.Data.SqlTypes.SqlDouble value) { throw null; } - /// + /// public System.Data.SqlTypes.SqlGuid Adjust(System.Data.SqlTypes.SqlGuid value) { throw null; } - /// + /// public System.Data.SqlTypes.SqlInt16 Adjust(System.Data.SqlTypes.SqlInt16 value) { throw null; } - /// + /// public System.Data.SqlTypes.SqlInt32 Adjust(System.Data.SqlTypes.SqlInt32 value) { throw null; } - /// + /// public System.Data.SqlTypes.SqlInt64 Adjust(System.Data.SqlTypes.SqlInt64 value) { throw null; } - /// + /// public System.Data.SqlTypes.SqlMoney Adjust(System.Data.SqlTypes.SqlMoney value) { throw null; } - /// + /// public System.Data.SqlTypes.SqlSingle Adjust(System.Data.SqlTypes.SqlSingle value) { throw null; } - /// + /// public System.Data.SqlTypes.SqlString Adjust(System.Data.SqlTypes.SqlString value) { throw null; } - /// + /// public System.Data.SqlTypes.SqlXml Adjust(System.Data.SqlTypes.SqlXml value) { throw null; } - /// + /// public System.DateTime Adjust(System.DateTime value) { throw null; } - /// + /// public System.DateTimeOffset Adjust(System.DateTimeOffset value) { throw null; } - /// + /// public decimal Adjust(decimal value) { throw null; } - /// + /// public double Adjust(double value) { throw null; } - /// + /// public System.Guid Adjust(System.Guid value) { throw null; } - /// + /// public short Adjust(short value) { throw null; } - /// + /// public int Adjust(int value) { throw null; } - /// + /// public long Adjust(long value) { throw null; } - /// + /// public object Adjust(object value) { throw null; } - /// + /// public float Adjust(float value) { throw null; } - /// + /// public string Adjust(string value) { throw null; } - /// + /// public System.TimeSpan Adjust(System.TimeSpan value) { throw null; } - /// + /// public static Microsoft.Data.SqlClient.Server.SqlMetaData InferFromValue(object value, string name) { throw null; } } - /// + /// [System.AttributeUsage(System.AttributeTargets.Method, AllowMultiple = false, Inherited = false), System.SerializableAttribute] public sealed partial class SqlMethodAttribute : SqlFunctionAttribute { - /// + /// public SqlMethodAttribute() { } - /// + /// public bool OnNullCall { get { throw null; } set { } } - /// + /// public bool IsMutator { get { throw null; } set { } } - /// + /// public bool InvokeIfReceiverIsNull { get { throw null; } set { } } } - /// + /// [System.AttributeUsage(System.AttributeTargets.Class | System.AttributeTargets.Struct, AllowMultiple = false, Inherited = false)] public sealed partial class SqlUserDefinedAggregateAttribute : System.Attribute { - /// + /// public const int MaxByteSizeValue = 8000; - /// + /// public SqlUserDefinedAggregateAttribute(Format format) { } - /// + /// public int MaxByteSize { get { throw null; } set { } } - /// + /// public bool IsInvariantToDuplicates { get { throw null; } set { } } - /// + /// public bool IsInvariantToNulls { get { throw null; } set { } } - /// + /// public bool IsInvariantToOrder { get { throw null; } set { } } - /// + /// public bool IsNullIfEmpty { get { throw null; } set { } } - /// + /// public Format Format { get { throw null; } } - /// + /// public string Name { get { throw null; } set { } } } - /// + /// [System.AttributeUsage(System.AttributeTargets.Class | System.AttributeTargets.Struct, AllowMultiple = false, Inherited = true)] public sealed partial class SqlUserDefinedTypeAttribute : System.Attribute { - /// + /// public SqlUserDefinedTypeAttribute(Format format) { } - /// + /// public int MaxByteSize { get { throw null; } set { } } - /// + /// public bool IsFixedLength { get { throw null; } set { } } - /// + /// public bool IsByteOrdered { get { throw null; } set { } } - /// + /// public Format Format { get { throw null; } } - /// + /// public string ValidationMethodName { get { throw null; } set { } } - /// + /// public string Name { get { throw null; } set { } } } - /// + /// public enum SystemDataAccessKind { - /// + /// None = 0, - /// + /// Read = 1 } } namespace Microsoft.Data.SqlClient.DataClassification { - /// + /// public partial class ColumnSensitivity { - /// + /// public ColumnSensitivity(System.Collections.Generic.IList sensitivityProperties) { } - /// + /// public System.Collections.ObjectModel.ReadOnlyCollection SensitivityProperties { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } } - /// + /// public partial class InformationType { - /// + /// public InformationType(string name, string id) { } - /// + /// public string Id { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - /// + /// public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } } - /// + /// public partial class Label { - /// + /// public Label(string name, string id) { } - /// + /// public string Id { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - /// + /// public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } } - /// + /// + public enum SensitivityRank + { + /// + NOT_DEFINED = -1, + /// + NONE = 0, + /// + LOW = 10, + /// + MEDIUM = 20, + /// + HIGH = 30, + /// + CRITICAL = 40 + } + /// public partial class SensitivityClassification { - /// - public SensitivityClassification(System.Collections.Generic.IList labels, System.Collections.Generic.IList informationTypes, System.Collections.Generic.IList columnSensitivity) { } - /// + /// + public SensitivityClassification(System.Collections.Generic.IList labels, System.Collections.Generic.IList informationTypes, System.Collections.Generic.IList columnSensitivity, int sensitivityRank) { } + /// public System.Collections.ObjectModel.ReadOnlyCollection ColumnSensitivities { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - /// + /// public System.Collections.ObjectModel.ReadOnlyCollection InformationTypes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - /// + /// public System.Collections.ObjectModel.ReadOnlyCollection Labels { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + /// + public int SensitivityRank { get { throw null; } } } - /// + /// public partial class SensitivityProperty { - /// - public SensitivityProperty(Microsoft.Data.SqlClient.DataClassification.Label label, Microsoft.Data.SqlClient.DataClassification.InformationType informationType) { } - /// + /// + public SensitivityProperty(Microsoft.Data.SqlClient.DataClassification.Label label, Microsoft.Data.SqlClient.DataClassification.InformationType informationType, int sensitivityRank) { } + /// public Microsoft.Data.SqlClient.DataClassification.InformationType InformationType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - /// + /// public Microsoft.Data.SqlClient.DataClassification.Label Label { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + /// + public int SensitivityRank { get { throw null; } } } } namespace Microsoft.Data.SqlTypes { - /// + /// public sealed partial class SqlFileStream : System.IO.Stream { - /// + /// public SqlFileStream(string path, byte[] transactionContext, System.IO.FileAccess access) { } - /// + /// public SqlFileStream(string path, byte[] transactionContext, System.IO.FileAccess access, System.IO.FileOptions options, System.Int64 allocationSize) { } - /// + /// public string Name { get { throw null; } } - /// + /// public byte[] TransactionContext { get { throw null; } } - /// + /// public override bool CanRead { get { throw null; } } - /// + /// public override bool CanSeek { get { throw null; } } - /// + /// public override bool CanTimeout { get { throw null; } } - /// + /// public override bool CanWrite { get { throw null; } } - /// + /// public override long Length { get { throw null; } } - /// + /// public override long Position { get { throw null; } set { throw null; } } - /// + /// public override int ReadTimeout { get { throw null; } } - /// + /// public override int WriteTimeout { get { throw null; } } - /// + /// public override void Flush() { } - /// + /// public override System.IAsyncResult BeginRead(byte[] buffer, int offset, int count, System.AsyncCallback callback, object state) { throw null; } - /// + /// public override int EndRead(System.IAsyncResult asyncResult) { throw null; } - /// + /// public override System.IAsyncResult BeginWrite(byte[] buffer, int offset, int count, System.AsyncCallback callback, System.Object state) { throw null; } - /// + /// public override void EndWrite(System.IAsyncResult asyncResult) { } - /// + /// public override long Seek(long offset, System.IO.SeekOrigin origin) { throw null; } - /// + /// public override void SetLength(long value) { throw null; } - /// + /// public override int Read(byte[] buffer, int offset, int count) { throw null; } - /// + /// public override int ReadByte() { throw null; } - /// + /// public override void Write(byte[] buffer, int offset, int count) { throw null; } - /// + /// public override void WriteByte(byte value) { } } } diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs index 0da06ba54d..37303a8a28 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs @@ -143,9 +143,10 @@ sealed internal class SqlInternalConnectionTds : SqlInternalConnection, IDisposa SqlClientOriginalNetworkAddressInfo _originalNetworkAddressInfo; internal bool _cleanSQLDNSCaching = false; - private bool _serverSupportsDNSCaching = false; + internal byte _supportedDataClassificationVersion = TdsEnums.DATA_CLASSIFICATION_NOT_ENABLED; + /// /// Get or set if SQLDNSCaching FeatureExtAck is supported by the server. /// @@ -3062,11 +3063,11 @@ internal void OnFeatureExtAck(int featureId, byte[] data) throw SQL.ParsingError(ParsingErrorState.CorruptedTdsStream); } - byte supportedDataClassificationVersion = data[0]; - if ((0 == supportedDataClassificationVersion) || (supportedDataClassificationVersion > TdsEnums.MAX_SUPPORTED_DATA_CLASSIFICATION_VERSION)) + _supportedDataClassificationVersion = data[0]; + if ((0 == _supportedDataClassificationVersion) || (_supportedDataClassificationVersion > TdsEnums.MAX_SUPPORTED_DATA_CLASSIFICATION_VERSION)) { SqlClientEventSource.Log.TraceEvent(" {0}, Invalid version number for DATACLASSIFICATION", ObjectID); - throw SQL.ParsingErrorValue(ParsingErrorState.DataClassificationInvalidVersion, supportedDataClassificationVersion); + throw SQL.ParsingErrorValue(ParsingErrorState.DataClassificationInvalidVersion, _supportedDataClassificationVersion); } if (data.Length != 2) @@ -3075,7 +3076,7 @@ internal void OnFeatureExtAck(int featureId, byte[] data) throw SQL.ParsingError(ParsingErrorState.CorruptedTdsStream); } byte enabled = data[1]; - _parser.DataClassificationVersion = (enabled == 0) ? TdsEnums.DATA_CLASSIFICATION_NOT_ENABLED : supportedDataClassificationVersion; + _parser.DataClassificationVersion = (enabled == 0) ? TdsEnums.DATA_CLASSIFICATION_NOT_ENABLED : _supportedDataClassificationVersion; break; } diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsEnums.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsEnums.cs index eaba0b9cc8..beb74f6c9d 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsEnums.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsEnums.cs @@ -938,7 +938,8 @@ internal enum FedAuthInfoId : byte // Data Classification constants internal const byte DATA_CLASSIFICATION_NOT_ENABLED = 0x00; - internal const byte MAX_SUPPORTED_DATA_CLASSIFICATION_VERSION = 0x01; + internal const byte DATA_CLASSIFICATION_VERSION_WITHOUT_RANK_SUPPORT = 0x01; + internal const byte MAX_SUPPORTED_DATA_CLASSIFICATION_VERSION = 0x02; // TCE Related constants internal const byte MAX_SUPPORTED_TCE_VERSION = 0x02; // max version diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs index 4f5fd8a2e1..c16077ab56 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs @@ -623,7 +623,7 @@ internal void ProcessPendingAck(TdsParserStateObject stateObj) UInt32 result = SNINativeMethodWrapper.SniGetConnectionId(_physicalStateObj.Handle, ref _connHandler._clientConnectionId); Debug.Assert(result == TdsEnums.SNI_SUCCESS, "Unexpected failure state upon calling SniGetConnectionId"); - + // for DNS Caching phase 1 AssignPendingDNSInfo(serverInfo.UserProtocol, FQDNforDNSCahce); @@ -705,12 +705,12 @@ internal void AssignPendingDNSInfo(string userProtocol, string DNSCacheKey) if (string.IsNullOrEmpty(userProtocol)) { - + result = SNINativeMethodWrapper.SniGetProviderNumber(_physicalStateObj.Handle, ref providerNumber); Debug.Assert(result == TdsEnums.SNI_SUCCESS, "Unexpected failure state upon calling SniGetProviderNumber"); isTcpProtocol = (providerNumber == SNINativeMethodWrapper.ProviderEnum.TCP_PROV); } - else if (userProtocol == TdsEnums.TCP) + else if (userProtocol == TdsEnums.TCP) { isTcpProtocol = true; } @@ -3558,7 +3558,7 @@ private bool TryProcessFeatureExtAck(TdsParserStateObject stateObj) ret = SQLFallbackDNSCache.Instance.DeleteDNSInfo(FQDNforDNSCahce); } - if ( _connHandler.IsSQLDNSCachingSupported && _connHandler.pendingSQLDNSObject != null + if (_connHandler.IsSQLDNSCachingSupported && _connHandler.pendingSQLDNSObject != null && !SQLFallbackDNSCache.Instance.IsDuplicate(_connHandler.pendingSQLDNSObject)) { ret = SQLFallbackDNSCache.Instance.AddDNSInfo(_connHandler.pendingSQLDNSObject); @@ -3777,6 +3777,21 @@ private bool TryProcessDataClassification(TdsParserStateObject stateObj, out Sen informationTypes.Add(new InformationType(informationType, id)); } + // get sensitivity rank + Int32 sensitivityRank = (int)SensitivityRank.NOT_DEFINED; + if (_connHandler._supportedDataClassificationVersion > TdsEnums.DATA_CLASSIFICATION_VERSION_WITHOUT_RANK_SUPPORT) + { + if (!stateObj.TryReadInt32(out sensitivityRank)) + { + return false; + } + Console.WriteLine(sensitivityRank); + if (!Enum.IsDefined(typeof(SensitivityRank), sensitivityRank)) + { + return false; + } + } + // get the per column classification data (corresponds to order of output columns for query) UInt16 numResultColumns; if (!stateObj.TryReadUInt16(out numResultColumns)) @@ -3827,14 +3842,27 @@ private bool TryProcessDataClassification(TdsParserStateObject stateObj, out Sen informationType = informationTypes[informationTypeIndex]; } + // get sensitivity rank + Int32 sensitivityRankProperty = (int)SensitivityRank.NOT_DEFINED; + if (_connHandler._supportedDataClassificationVersion > TdsEnums.DATA_CLASSIFICATION_VERSION_WITHOUT_RANK_SUPPORT) + { + if (!stateObj.TryReadInt32(out sensitivityRankProperty)) + { + return false; + } + if (!Enum.IsDefined(typeof(SensitivityRank), sensitivityRankProperty)) + { + return false; + } + } + // add sentivity properties for the source - sensitivityProperties.Add(new SensitivityProperty(label, informationType)); + sensitivityProperties.Add(new SensitivityProperty(label, informationType, (SensitivityRank)sensitivityRankProperty)); } columnSensitivities.Add(new ColumnSensitivity(sensitivityProperties)); } - sensitivityClassification = new SensitivityClassification(labels, informationTypes, columnSensitivities); - + sensitivityClassification = new SensitivityClassification(labels, informationTypes, columnSensitivities, (SensitivityRank)sensitivityRank); return true; } @@ -9828,7 +9856,7 @@ internal Task TdsExecuteSQLBatch(string text, int timeout, SqlNotificationReques // Stream out parameters SqlParameter[] parameters = rpcext.parameters; - + bool isAdvancedTraceOn = SqlClientEventSource.Log.IsAdvancedTraceOn(); for (int i = (ii == startRpc) ? startParam : 0; i < parameters.Length; i++) diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/DataClassification/SensitivityClassification.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/DataClassification/SensitivityClassification.cs index 084083b338..87a70cfa70 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/DataClassification/SensitivityClassification.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/DataClassification/SensitivityClassification.cs @@ -41,6 +41,23 @@ public InformationType(string name, string id) } } + /// + public enum SensitivityRank + { + /// + NOT_DEFINED = -1, + /// + NONE = 0, + /// + LOW = 10, + /// + MEDIUM = 20, + /// + HIGH = 30, + /// + CRITICAL = 40 + } + /// public class SensitivityProperty { @@ -50,11 +67,15 @@ public class SensitivityProperty /// public InformationType InformationType { get; private set; } + /// + public SensitivityRank SensitivityRank { get; private set; } + /// - public SensitivityProperty(Label label, InformationType informationType) + public SensitivityProperty(Label label, InformationType informationType, SensitivityRank sensitivityRank = SensitivityRank.NOT_DEFINED) // Default to NOT_DEFINED for backwards compatibility { Label = label; InformationType = informationType; + SensitivityRank = sensitivityRank; } } @@ -80,15 +101,19 @@ public class SensitivityClassification /// public ReadOnlyCollection InformationTypes { get; private set; } + /// + public SensitivityRank SensitivityRank { get; private set; } + /// public ReadOnlyCollection ColumnSensitivities { get; private set; } /// - public SensitivityClassification(IList