//------------------------------------------------------------------------------ // // Copyright (c) Microsoft Corporation. All rights reserved. // // [....] // [....] //------------------------------------------------------------------------------ namespace System.Data.SqlClient { using System; using System.Collections; using System.Data; using System.Data.Common; using System.Diagnostics; using System.Globalization; using System.IO; using System.Security; using System.Security.Permissions; using System.Text; using System.Runtime.Versioning; internal sealed class SqlConnectionString : DbConnectionOptions { // instances of this class are intended to be immutable, i.e readonly // used by pooling classes so it is much easier to verify correctness // when not worried about the class being modified during execution internal static class DEFAULT { internal const ApplicationIntent ApplicationIntent = DbConnectionStringDefaults.ApplicationIntent; internal const string Application_Name = TdsEnums.SQL_PROVIDER_NAME; internal const bool Asynchronous = false; internal const string AttachDBFilename = ""; internal const int Connect_Timeout = ADP.DefaultConnectionTimeout; internal const bool Connection_Reset = true; internal const bool Context_Connection = false; internal const string Current_Language = ""; internal const string Data_Source = ""; internal const bool Encrypt = false; internal const bool Enlist = true; internal const string FailoverPartner = ""; internal const string Initial_Catalog = ""; internal const bool Integrated_Security = false; internal const int Load_Balance_Timeout = 0; // default of 0 means don't use internal const bool MARS = false; internal const int Max_Pool_Size = 100; internal const int Min_Pool_Size = 0; internal const bool MultiSubnetFailover = DbConnectionStringDefaults.MultiSubnetFailover; internal const bool TransparentNetworkIPResolution = DbConnectionStringDefaults.TransparentNetworkIPResolution; internal const string Network_Library = ""; internal const int Packet_Size = 8000; internal const string Password = ""; internal const bool Persist_Security_Info = false; internal const bool Pooling = true; internal const bool TrustServerCertificate = false; internal const string Type_System_Version = ""; internal const string User_ID = ""; internal const bool User_Instance = false; internal const bool Replication = false; internal const int Connect_Retry_Count = 1; internal const int Connect_Retry_Interval = 10; internal static readonly SqlAuthenticationMethod Authentication = SqlAuthenticationMethod.NotSpecified; internal static readonly SqlConnectionColumnEncryptionSetting ColumnEncryptionSetting = SqlConnectionColumnEncryptionSetting.Disabled; } // SqlConnection ConnectionString Options // keys must be lowercase! internal static class KEY { internal const string ApplicationIntent = "applicationintent"; internal const string Application_Name = "application name"; internal const string AsynchronousProcessing = "asynchronous processing"; internal const string AttachDBFilename = "attachdbfilename"; internal const string ColumnEncryptionSetting = "column encryption setting"; internal const string Connect_Timeout = "connect timeout"; internal const string Connection_Reset = "connection reset"; internal const string Context_Connection = "context connection"; internal const string Current_Language = "current language"; internal const string Data_Source = "data source"; internal const string Encrypt = "encrypt"; internal const string Enlist = "enlist"; internal const string FailoverPartner = "failover partner"; internal const string Initial_Catalog = "initial catalog"; internal const string Integrated_Security = "integrated security"; internal const string Load_Balance_Timeout = "load balance timeout"; internal const string MARS = "multipleactiveresultsets"; internal const string Max_Pool_Size = "max pool size"; internal const string Min_Pool_Size = "min pool size"; internal const string MultiSubnetFailover = "multisubnetfailover"; internal const string TransparentNetworkIPResolution = "transparentnetworkipresolution"; internal const string Network_Library = "network library"; internal const string Packet_Size = "packet size"; internal const string Password = "password"; internal const string Persist_Security_Info = "persist security info"; internal const string Pooling = "pooling"; internal const string TransactionBinding = "transaction binding"; internal const string TrustServerCertificate = "trustservercertificate"; internal const string Type_System_Version = "type system version"; internal const string User_ID = "user id"; internal const string User_Instance = "user instance"; internal const string Workstation_Id = "workstation id"; internal const string Replication = "replication"; internal const string Connect_Retry_Count = "connectretrycount"; internal const string Connect_Retry_Interval = "connectretryinterval"; internal const string Authentication = "authentication"; } // Constant for the number of duplicate options in the connnection string private static class SYNONYM { // application name internal const string APP = "app"; internal const string Async = "async"; // attachDBFilename internal const string EXTENDED_PROPERTIES = "extended properties"; internal const string INITIAL_FILE_NAME = "initial file name"; // connect timeout internal const string CONNECTION_TIMEOUT = "connection timeout"; internal const string TIMEOUT = "timeout"; // current language internal const string LANGUAGE = "language"; // data source internal const string ADDR = "addr"; internal const string ADDRESS = "address"; internal const string SERVER = "server"; internal const string NETWORK_ADDRESS = "network address"; // initial catalog internal const string DATABASE = "database"; // integrated security internal const string TRUSTED_CONNECTION = "trusted_connection"; // load balance timeout internal const string Connection_Lifetime = "connection lifetime"; // network library internal const string NET = "net"; internal const string NETWORK = "network"; // password internal const string Pwd = "pwd"; // persist security info internal const string PERSISTSECURITYINFO = "persistsecurityinfo"; // user id internal const string UID = "uid"; internal const string User = "user"; // workstation id internal const string WSID = "wsid"; // make sure to update SynonymCount value below when adding or removing synonyms } internal const int SynonymCount = 21; // the following are all inserted as keys into the _netlibMapping hash internal static class NETLIB { internal const string AppleTalk = "dbmsadsn"; internal const string BanyanVines = "dbmsvinn"; internal const string IPXSPX = "dbmsspxn"; internal const string Multiprotocol = "dbmsrpcn"; internal const string NamedPipes = "dbnmpntw"; internal const string SharedMemory = "dbmslpcn"; internal const string TCPIP = "dbmssocn"; internal const string VIA = "dbmsgnet"; } internal enum TypeSystem { Latest = 2008, SQLServer2000 = 2000, SQLServer2005 = 2005, SQLServer2008 = 2008, SQLServer2012 = 2012, } internal static class TYPESYSTEMVERSION { internal const string Latest = "Latest"; internal const string SQL_Server_2000 = "SQL Server 2000"; internal const string SQL_Server_2005 = "SQL Server 2005"; internal const string SQL_Server_2008 = "SQL Server 2008"; internal const string SQL_Server_2012 = "SQL Server 2012"; } internal enum TransactionBindingEnum { ImplicitUnbind, ExplicitUnbind } internal static class TRANSACIONBINDING { internal const string ImplicitUnbind = "Implicit Unbind"; internal const string ExplicitUnbind = "Explicit Unbind"; } static private Hashtable _sqlClientSynonyms; static private Hashtable _netlibMapping; private readonly bool _integratedSecurity; private readonly bool _connectionReset; private readonly bool _contextConnection; private readonly bool _encrypt; private readonly bool _trustServerCertificate; private readonly bool _enlist; private readonly bool _mars; private readonly bool _persistSecurityInfo; private readonly bool _pooling; private readonly bool _replication; private readonly bool _userInstance; private readonly bool _multiSubnetFailover; private readonly bool _transparentNetworkIPResolution; private readonly SqlAuthenticationMethod _authType; private readonly SqlConnectionColumnEncryptionSetting _columnEncryptionSetting; private readonly int _connectTimeout; private readonly int _loadBalanceTimeout; private readonly int _maxPoolSize; private readonly int _minPoolSize; private readonly int _packetSize; private readonly int _connectRetryCount; private readonly int _connectRetryInterval; private readonly ApplicationIntent _applicationIntent; private readonly string _applicationName; private readonly string _attachDBFileName; private readonly string _currentLanguage; private readonly string _dataSource; private readonly string _localDBInstance; // created based on datasource, set to NULL if datasource is not LocalDB private readonly string _failoverPartner; private readonly string _initialCatalog; private readonly string _password; private readonly string _userID; private readonly string _networkLibrary; private readonly string _workstationId; private readonly TypeSystem _typeSystemVersion; private readonly Version _typeSystemAssemblyVersion; private static readonly Version constTypeSystemAsmVersion10 = new Version("10.0.0.0"); private static readonly Version constTypeSystemAsmVersion11 = new Version("11.0.0.0"); private readonly TransactionBindingEnum _transactionBinding; private readonly string _expandedAttachDBFilename; // expanded during construction so that CreatePermissionSet & Expand are consistent // SxS: reading Software\\Microsoft\\MSSQLServer\\Client\\SuperSocketNetLib\Encrypt value from registry [ResourceExposure(ResourceScope.None)] [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)] internal SqlConnectionString(string connectionString) : base(connectionString, GetParseSynonyms(), false) { bool runningInProc = InOutOfProcHelper.InProc; _integratedSecurity = ConvertValueToIntegratedSecurity(); ConvertValueToBoolean(KEY.AsynchronousProcessing, DEFAULT.Asynchronous); // while we don't use it anymore, we still need to verify it is true/false // SQLPT 41700: Ignore ResetConnection=False (still validate the keyword/value) _connectionReset = ConvertValueToBoolean(KEY.Connection_Reset, DEFAULT.Connection_Reset); _contextConnection = ConvertValueToBoolean(KEY.Context_Connection, DEFAULT.Context_Connection); _encrypt = ConvertValueToEncrypt(); _enlist = ConvertValueToBoolean(KEY.Enlist, ADP.IsWindowsNT); _mars = ConvertValueToBoolean(KEY.MARS, DEFAULT.MARS); _persistSecurityInfo = ConvertValueToBoolean(KEY.Persist_Security_Info, DEFAULT.Persist_Security_Info); _pooling = ConvertValueToBoolean(KEY.Pooling, DEFAULT.Pooling); _replication = ConvertValueToBoolean(KEY.Replication, DEFAULT.Replication); _userInstance = ConvertValueToBoolean(KEY.User_Instance, DEFAULT.User_Instance); _multiSubnetFailover = ConvertValueToBoolean(KEY.MultiSubnetFailover, DEFAULT.MultiSubnetFailover); _transparentNetworkIPResolution = ConvertValueToBoolean(KEY.TransparentNetworkIPResolution, DEFAULT.TransparentNetworkIPResolution); _connectTimeout = ConvertValueToInt32(KEY.Connect_Timeout, DEFAULT.Connect_Timeout); _loadBalanceTimeout = ConvertValueToInt32(KEY.Load_Balance_Timeout, DEFAULT.Load_Balance_Timeout); _maxPoolSize = ConvertValueToInt32(KEY.Max_Pool_Size, DEFAULT.Max_Pool_Size); _minPoolSize = ConvertValueToInt32(KEY.Min_Pool_Size, DEFAULT.Min_Pool_Size); _packetSize = ConvertValueToInt32(KEY.Packet_Size, DEFAULT.Packet_Size); _connectRetryCount = ConvertValueToInt32(KEY.Connect_Retry_Count, DEFAULT.Connect_Retry_Count); _connectRetryInterval = ConvertValueToInt32(KEY.Connect_Retry_Interval, DEFAULT.Connect_Retry_Interval); _applicationIntent = ConvertValueToApplicationIntent(); _applicationName = ConvertValueToString(KEY.Application_Name, DEFAULT.Application_Name); _attachDBFileName = ConvertValueToString(KEY.AttachDBFilename, DEFAULT.AttachDBFilename); _currentLanguage = ConvertValueToString(KEY.Current_Language, DEFAULT.Current_Language); _dataSource = ConvertValueToString(KEY.Data_Source, DEFAULT.Data_Source); _localDBInstance = LocalDBAPI.GetLocalDbInstanceNameFromServerName(_dataSource); _failoverPartner = ConvertValueToString(KEY.FailoverPartner, DEFAULT.FailoverPartner); _initialCatalog = ConvertValueToString(KEY.Initial_Catalog, DEFAULT.Initial_Catalog); _networkLibrary = ConvertValueToString(KEY.Network_Library, null); _password = ConvertValueToString(KEY.Password, DEFAULT.Password); _trustServerCertificate = ConvertValueToBoolean(KEY.TrustServerCertificate, DEFAULT.TrustServerCertificate); _authType = ConvertValueToAuthenticationType(); _columnEncryptionSetting = ConvertValueToColumnEncryptionSetting(); // Temporary string - this value is stored internally as an enum. string typeSystemVersionString = ConvertValueToString(KEY.Type_System_Version, null); string transactionBindingString = ConvertValueToString(KEY.TransactionBinding, null); _userID = ConvertValueToString(KEY.User_ID, DEFAULT.User_ID); _workstationId = ConvertValueToString(KEY.Workstation_Id, null); if (_contextConnection) { // We have to be running in the engine for you to request a // context connection. if (!runningInProc) { throw SQL.ContextUnavailableOutOfProc(); } // When using a context connection, we need to ensure that no // other connection string keywords are specified. foreach (DictionaryEntry entry in Parsetable) { if ((string) entry.Key != KEY.Context_Connection && (string) entry.Key != KEY.Type_System_Version) { throw SQL.ContextAllowsLimitedKeywords(); } } } if (!_encrypt) { // Support legacy registry encryption settings const string folder = "Software\\Microsoft\\MSSQLServer\\Client\\SuperSocketNetLib"; const string value = "Encrypt"; Object obj = ADP.LocalMachineRegistryValue(folder, value); if ((obj is Int32) && (1 == (int)obj)) { // If the registry key exists _encrypt = true; } } if (_loadBalanceTimeout < 0) { throw ADP.InvalidConnectionOptionValue(KEY.Load_Balance_Timeout); } if (_connectTimeout < 0) { throw ADP.InvalidConnectionOptionValue(KEY.Connect_Timeout); } if (_maxPoolSize < 1) { throw ADP.InvalidConnectionOptionValue(KEY.Max_Pool_Size); } if (_minPoolSize < 0) { throw ADP.InvalidConnectionOptionValue(KEY.Min_Pool_Size); } if (_maxPoolSize < _minPoolSize) { throw ADP.InvalidMinMaxPoolSizeValues(); } if ((_packetSize < TdsEnums.MIN_PACKET_SIZE) || (TdsEnums.MAX_PACKET_SIZE < _packetSize)) { throw SQL.InvalidPacketSizeValue(); } if (null != _networkLibrary) { // MDAC 83525 string networkLibrary = _networkLibrary.Trim().ToLower(CultureInfo.InvariantCulture); Hashtable netlib = NetlibMapping(); if (!netlib.ContainsKey(networkLibrary)) { throw ADP.InvalidConnectionOptionValue(KEY.Network_Library); } _networkLibrary = (string) netlib[networkLibrary]; } else { _networkLibrary = DEFAULT.Network_Library; } ValidateValueLength(_applicationName, TdsEnums.MAXLEN_APPNAME, KEY.Application_Name); ValidateValueLength(_currentLanguage , TdsEnums.MAXLEN_LANGUAGE, KEY.Current_Language); ValidateValueLength(_dataSource, TdsEnums.MAXLEN_SERVERNAME, KEY.Data_Source); ValidateValueLength(_failoverPartner, TdsEnums.MAXLEN_SERVERNAME, KEY.FailoverPartner); ValidateValueLength(_initialCatalog, TdsEnums.MAXLEN_DATABASE, KEY.Initial_Catalog); ValidateValueLength(_password, TdsEnums.MAXLEN_PASSWORD, KEY.Password); ValidateValueLength(_userID, TdsEnums.MAXLEN_USERNAME, KEY.User_ID); if (null != _workstationId) { ValidateValueLength(_workstationId, TdsEnums.MAXLEN_HOSTNAME, KEY.Workstation_Id); } if (!String.Equals(DEFAULT.FailoverPartner, _failoverPartner, StringComparison.OrdinalIgnoreCase)) { // fail-over partner is set if (_multiSubnetFailover) { throw SQL.MultiSubnetFailoverWithFailoverPartner(serverProvidedFailoverPartner: false, internalConnection: null); } if (String.Equals(DEFAULT.Initial_Catalog, _initialCatalog, StringComparison.OrdinalIgnoreCase)) { throw ADP.MissingConnectionOptionValue(KEY.FailoverPartner, KEY.Initial_Catalog); } } // expand during construction so that CreatePermissionSet and Expand are consistent string datadir = null; _expandedAttachDBFilename = ExpandDataDirectory(KEY.AttachDBFilename, _attachDBFileName, ref datadir); if (null != _expandedAttachDBFilename) { if (0 <= _expandedAttachDBFilename.IndexOf('|')) { throw ADP.InvalidConnectionOptionValue(KEY.AttachDBFilename); } ValidateValueLength(_expandedAttachDBFilename, TdsEnums.MAXLEN_ATTACHDBFILE, KEY.AttachDBFilename); if (_localDBInstance == null) { // fail fast to verify LocalHost when using |DataDirectory| // still must check again at connect time string host = _dataSource; string protocol = _networkLibrary; TdsParserStaticMethods.AliasRegistryLookup(ref host, ref protocol); VerifyLocalHostAndFixup(ref host, true, false /*don't fix-up*/); } } else if (0 <= _attachDBFileName.IndexOf('|')) { throw ADP.InvalidConnectionOptionValue(KEY.AttachDBFilename); } else { ValidateValueLength(_attachDBFileName, TdsEnums.MAXLEN_ATTACHDBFILE, KEY.AttachDBFilename); } _typeSystemAssemblyVersion = constTypeSystemAsmVersion10; if (true == _userInstance && !ADP.IsEmpty(_failoverPartner)) { throw SQL.UserInstanceFailoverNotCompatible(); } if (ADP.IsEmpty(typeSystemVersionString)) { typeSystemVersionString = DbConnectionStringDefaults.TypeSystemVersion; } if (typeSystemVersionString.Equals(TYPESYSTEMVERSION.Latest, StringComparison.OrdinalIgnoreCase)) { _typeSystemVersion = TypeSystem.Latest; } else if (typeSystemVersionString.Equals(TYPESYSTEMVERSION.SQL_Server_2000, StringComparison.OrdinalIgnoreCase)) { if (_contextConnection) { throw SQL.ContextAllowsOnlyTypeSystem2005(); } _typeSystemVersion = TypeSystem.SQLServer2000; } else if (typeSystemVersionString.Equals(TYPESYSTEMVERSION.SQL_Server_2005, StringComparison.OrdinalIgnoreCase)) { _typeSystemVersion = TypeSystem.SQLServer2005; } else if (typeSystemVersionString.Equals(TYPESYSTEMVERSION.SQL_Server_2008, StringComparison.OrdinalIgnoreCase)) { _typeSystemVersion = TypeSystem.SQLServer2008; } else if (typeSystemVersionString.Equals(TYPESYSTEMVERSION.SQL_Server_2012, StringComparison.OrdinalIgnoreCase)) { _typeSystemVersion = TypeSystem.SQLServer2012; _typeSystemAssemblyVersion = constTypeSystemAsmVersion11; } else { throw ADP.InvalidConnectionOptionValue(KEY.Type_System_Version); } if (ADP.IsEmpty(transactionBindingString)) { transactionBindingString = DbConnectionStringDefaults.TransactionBinding; } if (transactionBindingString.Equals(TRANSACIONBINDING.ImplicitUnbind, StringComparison.OrdinalIgnoreCase)) { _transactionBinding = TransactionBindingEnum.ImplicitUnbind; } else if (transactionBindingString.Equals(TRANSACIONBINDING.ExplicitUnbind, StringComparison.OrdinalIgnoreCase)) { _transactionBinding = TransactionBindingEnum.ExplicitUnbind; } else { throw ADP.InvalidConnectionOptionValue(KEY.TransactionBinding); } if (_applicationIntent == ApplicationIntent.ReadOnly && !String.IsNullOrEmpty(_failoverPartner)) throw SQL.ROR_FailoverNotSupportedConnString(); if ((_connectRetryCount<0) || (_connectRetryCount>255)) { throw ADP.InvalidConnectRetryCountValue(); } if ((_connectRetryInterval < 1) || (_connectRetryInterval > 60)) { throw ADP.InvalidConnectRetryIntervalValue(); } if (Authentication != SqlAuthenticationMethod.NotSpecified && _integratedSecurity == true) { throw SQL.AuthenticationAndIntegratedSecurity(); } if (Authentication == SqlClient.SqlAuthenticationMethod.ActiveDirectoryIntegrated && (HasUserIdKeyword || HasPasswordKeyword)) { throw SQL.IntegratedWithUserIDAndPassword(); } } // This c-tor is used to create SSE and user instance connection strings when user instance is set to true // internal SqlConnectionString(SqlConnectionString connectionOptions, string dataSource, bool userInstance, bool? setEnlistValue) : base(connectionOptions) { _integratedSecurity = connectionOptions._integratedSecurity; _connectionReset = connectionOptions._connectionReset; _contextConnection = connectionOptions._contextConnection; _encrypt = connectionOptions._encrypt; if (setEnlistValue.HasValue) { _enlist = setEnlistValue.Value; } else { _enlist = connectionOptions._enlist; } _mars = connectionOptions._mars; _persistSecurityInfo = connectionOptions._persistSecurityInfo; _pooling = connectionOptions._pooling; _replication = connectionOptions._replication; _userInstance = userInstance; _connectTimeout = connectionOptions._connectTimeout; _loadBalanceTimeout = connectionOptions._loadBalanceTimeout; _maxPoolSize = connectionOptions._maxPoolSize; _minPoolSize = connectionOptions._minPoolSize; _multiSubnetFailover = connectionOptions._multiSubnetFailover; _transparentNetworkIPResolution = connectionOptions._transparentNetworkIPResolution; _packetSize = connectionOptions._packetSize; _applicationName = connectionOptions._applicationName; _attachDBFileName = connectionOptions._attachDBFileName; _currentLanguage = connectionOptions._currentLanguage; _dataSource = dataSource; _localDBInstance = LocalDBAPI.GetLocalDbInstanceNameFromServerName(_dataSource); _failoverPartner = connectionOptions._failoverPartner; _initialCatalog = connectionOptions._initialCatalog; _password = connectionOptions._password; _userID = connectionOptions._userID; _networkLibrary = connectionOptions._networkLibrary; _workstationId = connectionOptions._workstationId; _expandedAttachDBFilename = connectionOptions._expandedAttachDBFilename; _typeSystemVersion = connectionOptions._typeSystemVersion; _typeSystemAssemblyVersion = connectionOptions._typeSystemAssemblyVersion; _transactionBinding = connectionOptions._transactionBinding; _applicationIntent = connectionOptions._applicationIntent; _connectRetryCount = connectionOptions._connectRetryCount; _connectRetryInterval = connectionOptions._connectRetryInterval; _authType = connectionOptions._authType; _columnEncryptionSetting = connectionOptions._columnEncryptionSetting; ValidateValueLength(_dataSource, TdsEnums.MAXLEN_SERVERNAME, KEY.Data_Source); } internal bool IntegratedSecurity { get { return _integratedSecurity; } } // We always initialize in Async mode so that both synchronous and asynchronous methods // will work. In the future we can deprecate the keyword entirely. internal bool Asynchronous { get { return true; } } // SQLPT 41700: Ignore ResetConnection=False, always reset the connection for security internal bool ConnectionReset { get { return true; } } internal bool ContextConnection { get { return _contextConnection; } } // internal bool EnableUdtDownload { get { return _enableUdtDownload;} } internal bool Encrypt { get { return _encrypt; } } internal bool TrustServerCertificate { get { return _trustServerCertificate; } } internal bool Enlist { get { return _enlist; } } internal bool MARS { get { return _mars; } } internal bool MultiSubnetFailover { get { return _multiSubnetFailover; } } internal bool TransparentNetworkIPResolution { get { return _transparentNetworkIPResolution; } } internal SqlAuthenticationMethod Authentication { get { return _authType; } } internal SqlConnectionColumnEncryptionSetting ColumnEncryptionSetting { get { return _columnEncryptionSetting; } } internal bool PersistSecurityInfo { get { return _persistSecurityInfo; } } internal bool Pooling { get { return _pooling; } } internal bool Replication { get { return _replication; } } internal bool UserInstance { get { return _userInstance; } } internal int ConnectTimeout { get { return _connectTimeout; } } internal int LoadBalanceTimeout { get { return _loadBalanceTimeout; } } internal int MaxPoolSize { get { return _maxPoolSize; } } internal int MinPoolSize { get { return _minPoolSize; } } internal int PacketSize { get { return _packetSize; } } internal int ConnectRetryCount { get { return _connectRetryCount; } } internal int ConnectRetryInterval { get { return _connectRetryInterval; } } internal ApplicationIntent ApplicationIntent { get { return _applicationIntent; } } internal string ApplicationName { get { return _applicationName; } } internal string AttachDBFilename { get { return _attachDBFileName; } } internal string CurrentLanguage { get { return _currentLanguage; } } internal string DataSource { get { return _dataSource; } } internal string LocalDBInstance { get { return _localDBInstance; } } internal string FailoverPartner { get { return _failoverPartner; } } internal string InitialCatalog { get { return _initialCatalog; } } internal string NetworkLibrary { get { return _networkLibrary; } } internal string Password { get { return _password; } } internal string UserID { get { return _userID; } } internal string WorkstationId { get { return _workstationId; } } internal TypeSystem TypeSystemVersion { get { return _typeSystemVersion; } } internal Version TypeSystemAssemblyVersion { get { return _typeSystemAssemblyVersion; } } internal TransactionBindingEnum TransactionBinding { get { return _transactionBinding; } } internal bool EnforceLocalHost { get { // so tdsparser.connect can determine if SqlConnection.UserConnectionOptions // needs to enfoce local host after datasource alias lookup return (null != _expandedAttachDBFilename) && (null == _localDBInstance); } } protected internal override System.Security.PermissionSet CreatePermissionSet() { System.Security.PermissionSet permissionSet = new System.Security.PermissionSet(System.Security.Permissions.PermissionState.None); permissionSet.AddPermission(new SqlClientPermission(this)); return permissionSet; } protected internal override string Expand() { if (null != _expandedAttachDBFilename) { return ExpandKeyword(KEY.AttachDBFilename, _expandedAttachDBFilename); } else { return base.Expand(); } } private static bool CompareHostName(ref string host, string name, bool fixup) { // same computer name or same computer name + "\named instance" bool equal = false; if (host.Equals(name, StringComparison.OrdinalIgnoreCase)) { if (fixup) { host = "."; } equal = true; } else if (host.StartsWith(name+@"\", StringComparison.OrdinalIgnoreCase)) { if (fixup) { host = "." + host.Substring(name.Length); } equal = true; } return equal; } // this hashtable is meant to be read-only translation of parsed string // keywords/synonyms to a known keyword string internal static Hashtable GetParseSynonyms() { Hashtable hash = _sqlClientSynonyms; if (null == hash) { hash = new Hashtable(SqlConnectionStringBuilder.KeywordsCount + SynonymCount); hash.Add(KEY.ApplicationIntent, KEY.ApplicationIntent); hash.Add(KEY.Application_Name, KEY.Application_Name); hash.Add(KEY.AsynchronousProcessing, KEY.AsynchronousProcessing); hash.Add(KEY.AttachDBFilename, KEY.AttachDBFilename); hash.Add(KEY.Connect_Timeout, KEY.Connect_Timeout); hash.Add(KEY.Connection_Reset, KEY.Connection_Reset); hash.Add(KEY.Context_Connection, KEY.Context_Connection); hash.Add(KEY.Current_Language, KEY.Current_Language); hash.Add(KEY.Data_Source, KEY.Data_Source); hash.Add(KEY.Encrypt, KEY.Encrypt); hash.Add(KEY.Enlist, KEY.Enlist); hash.Add(KEY.FailoverPartner, KEY.FailoverPartner); hash.Add(KEY.Initial_Catalog, KEY.Initial_Catalog); hash.Add(KEY.Integrated_Security, KEY.Integrated_Security); hash.Add(KEY.Load_Balance_Timeout, KEY.Load_Balance_Timeout); hash.Add(KEY.MARS, KEY.MARS); hash.Add(KEY.Max_Pool_Size, KEY.Max_Pool_Size); hash.Add(KEY.Min_Pool_Size, KEY.Min_Pool_Size); hash.Add(KEY.MultiSubnetFailover, KEY.MultiSubnetFailover); hash.Add(KEY.TransparentNetworkIPResolution, KEY.TransparentNetworkIPResolution); hash.Add(KEY.Network_Library, KEY.Network_Library); hash.Add(KEY.Packet_Size, KEY.Packet_Size); hash.Add(KEY.Password, KEY.Password); hash.Add(KEY.Persist_Security_Info, KEY.Persist_Security_Info); hash.Add(KEY.Pooling, KEY.Pooling); hash.Add(KEY.Replication, KEY.Replication); hash.Add(KEY.TrustServerCertificate, KEY.TrustServerCertificate); hash.Add(KEY.TransactionBinding, KEY.TransactionBinding); hash.Add(KEY.Type_System_Version, KEY.Type_System_Version); hash.Add(KEY.ColumnEncryptionSetting, KEY.ColumnEncryptionSetting); hash.Add(KEY.User_ID, KEY.User_ID); hash.Add(KEY.User_Instance, KEY.User_Instance); hash.Add(KEY.Workstation_Id, KEY.Workstation_Id); hash.Add(KEY.Connect_Retry_Count, KEY.Connect_Retry_Count); hash.Add(KEY.Connect_Retry_Interval, KEY.Connect_Retry_Interval); hash.Add(KEY.Authentication, KEY.Authentication); hash.Add(SYNONYM.APP, KEY.Application_Name); hash.Add(SYNONYM.Async, KEY.AsynchronousProcessing); hash.Add(SYNONYM.EXTENDED_PROPERTIES, KEY.AttachDBFilename); hash.Add(SYNONYM.INITIAL_FILE_NAME, KEY.AttachDBFilename); hash.Add(SYNONYM.CONNECTION_TIMEOUT, KEY.Connect_Timeout); hash.Add(SYNONYM.TIMEOUT, KEY.Connect_Timeout); hash.Add(SYNONYM.LANGUAGE, KEY.Current_Language); hash.Add(SYNONYM.ADDR, KEY.Data_Source); hash.Add(SYNONYM.ADDRESS, KEY.Data_Source); hash.Add(SYNONYM.NETWORK_ADDRESS, KEY.Data_Source); hash.Add(SYNONYM.SERVER, KEY.Data_Source); hash.Add(SYNONYM.DATABASE, KEY.Initial_Catalog); hash.Add(SYNONYM.TRUSTED_CONNECTION, KEY.Integrated_Security); hash.Add(SYNONYM.Connection_Lifetime, KEY.Load_Balance_Timeout); hash.Add(SYNONYM.NET, KEY.Network_Library); hash.Add(SYNONYM.NETWORK, KEY.Network_Library); hash.Add(SYNONYM.Pwd, KEY.Password); hash.Add(SYNONYM.PERSISTSECURITYINFO, KEY.Persist_Security_Info); hash.Add(SYNONYM.UID, KEY.User_ID); hash.Add(SYNONYM.User, KEY.User_ID); hash.Add(SYNONYM.WSID, KEY.Workstation_Id); Debug.Assert(SqlConnectionStringBuilder.KeywordsCount + SynonymCount == hash.Count, "incorrect initial ParseSynonyms size"); _sqlClientSynonyms = hash; } return hash; } internal string ObtainWorkstationId() { // If not supplied by the user, the default value is the MachineName // Note: In Longhorn you'll be able to rename a machine without // rebooting. Therefore, don't cache this machine name. string result = WorkstationId; if (null == result) { // permission to obtain Environment.MachineName is Asserted // since permission to open the connection has been granted // the information is shared with the server, but not directly with the user result = ADP.MachineName(); ValidateValueLength(result, TdsEnums.MAXLEN_HOSTNAME, KEY.Workstation_Id); } return result; } static internal Hashtable NetlibMapping() { const int NetLibCount = 8; Hashtable hash = _netlibMapping; if (null == hash) { hash = new Hashtable(NetLibCount); hash.Add(NETLIB.TCPIP, TdsEnums.TCP); hash.Add(NETLIB.NamedPipes, TdsEnums.NP); hash.Add(NETLIB.Multiprotocol, TdsEnums.RPC); hash.Add(NETLIB.BanyanVines, TdsEnums.BV); hash.Add(NETLIB.AppleTalk, TdsEnums.ADSP); hash.Add(NETLIB.IPXSPX, TdsEnums.SPX); hash.Add(NETLIB.VIA, TdsEnums.VIA); hash.Add(NETLIB.SharedMemory, TdsEnums.LPC); Debug.Assert(NetLibCount == hash.Count, "incorrect initial NetlibMapping size"); _netlibMapping = hash; } return hash; } static internal bool ValidProtocal (string protocal) { switch (protocal) { case TdsEnums.TCP : case TdsEnums.NP : case TdsEnums.VIA : case TdsEnums.LPC : return true; // case TdsEnums.RPC : Invalid Protocals // case TdsEnums.BV : // case TdsEnums.ADSP : // case TdsEnums.SPX : default : return false; } } private void ValidateValueLength (string value, int limit, string key) { if (limit < value.Length) { throw ADP.InvalidConnectionOptionValueLength(key, limit); } } internal static void VerifyLocalHostAndFixup(ref string host, bool enforceLocalHost, bool fixup) { if (ADP.IsEmpty(host)) { if (fixup) { host = "."; } } else if (!CompareHostName(ref host, @".", fixup) && !CompareHostName(ref host, @"(local)", fixup)) { // Fix-up completed in CompareHostName if return value true. string name = ADP.GetComputerNameDnsFullyQualified(); // i.e, machine.location.corp.company.com if (!CompareHostName(ref host, name, fixup)) { int separatorPos = name.IndexOf('.'); // to compare just 'machine' part if ((separatorPos <= 0) || !CompareHostName(ref host, name.Substring(0, separatorPos), fixup)) { if (enforceLocalHost) { throw ADP.InvalidConnectionOptionValue(KEY.AttachDBFilename); } } } } } internal System.Data.SqlClient.ApplicationIntent ConvertValueToApplicationIntent() { object value = base.Parsetable[KEY.ApplicationIntent]; if (value == null) { return DEFAULT.ApplicationIntent; } // when wrong value is used in the connection string provided to SqlConnection.ConnectionString or c-tor, // wrap Format and Overflow exceptions with Argument one, to be consistent with rest of the keyword types (like int and bool) try { return DbConnectionStringBuilderUtil.ConvertToApplicationIntent(KEY.ApplicationIntent, value); } catch (FormatException e) { throw ADP.InvalidConnectionOptionValue(KEY.ApplicationIntent, e); } catch (OverflowException e) { throw ADP.InvalidConnectionOptionValue(KEY.ApplicationIntent, e); } // ArgumentException and other types are raised as is (no wrapping) } internal SqlAuthenticationMethod ConvertValueToAuthenticationType() { object value = base.Parsetable[KEY.Authentication]; string valStr = value as string; if (valStr == null) { return DEFAULT.Authentication; } try { return DbConnectionStringBuilderUtil.ConvertToAuthenticationType(KEY.Authentication, valStr); } catch (FormatException e) { throw ADP.InvalidConnectionOptionValue(KEY.Authentication, e); } catch (OverflowException e) { throw ADP.InvalidConnectionOptionValue(KEY.Authentication, e); } } /// /// Convert the value to SqlConnectionColumnEncryptionSetting. /// /// internal SqlConnectionColumnEncryptionSetting ConvertValueToColumnEncryptionSetting() { object value = base.Parsetable[KEY.ColumnEncryptionSetting]; string valStr = value as string; if (valStr == null) { return DEFAULT.ColumnEncryptionSetting; } try { return DbConnectionStringBuilderUtil.ConvertToColumnEncryptionSetting(KEY.ColumnEncryptionSetting, valStr); } catch (FormatException e) { throw ADP.InvalidConnectionOptionValue(KEY.ColumnEncryptionSetting, e); } catch (OverflowException e) { throw ADP.InvalidConnectionOptionValue(KEY.ColumnEncryptionSetting, e); } } internal bool ConvertValueToEncrypt() { // If the Authentication keyword is provided, default to Encrypt=true; // otherwise keep old default for backwards compatibility object authValue = base.Parsetable[KEY.Authentication]; bool defaultEncryptValue = (authValue == null) ? DEFAULT.Encrypt : true; return ConvertValueToBoolean(KEY.Encrypt, defaultEncryptValue); } } }