Skip to content

Commit

Permalink
Add support for aliases on netcore+Windows (#1588)
Browse files Browse the repository at this point in the history
* Add support for aliases on netcore+Windows

* Add test

* Revert spacing

* Better partition Windows/Unix code

* Add missing files

* Fix attempt

* Re-work new test

* Applying review suggestions

* Deduplicate code

Co-authored-by: DavoudEshtehari <61173489+DavoudEshtehari@users.noreply.github.com>
  • Loading branch information
David-Engel and DavoudEshtehari authored Jun 9, 2022
1 parent c45c507 commit 3082ae5
Show file tree
Hide file tree
Showing 11 changed files with 330 additions and 125 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@
<Compile Include="..\..\src\Microsoft\Data\SqlClient\RowsCopiedEventHandler.cs">
<Link>Microsoft\Data\SqlClient\RowsCopiedEventHandler.cs</Link>
</Compile>
<Compile Include="..\..\src\Microsoft\Data\SqlClient\SqlSequentialTextReader.cs">
<Compile Include="..\..\src\Microsoft\Data\SqlClient\SqlSequentialTextReader.cs">
<Link>Microsoft\Data\SqlClient\SqlSequentialTextReader.cs</Link>
</Compile>
<Compile Include="..\..\src\Microsoft\Data\SqlClient\Server\ExtendedClrTypeCode.cs">
Expand Down Expand Up @@ -481,6 +481,9 @@
<Compile Include="..\..\src\Microsoft\Data\SqlClient\TdsParameterSetter.cs">
<Link>Microsoft\Data\SqlClient\TdsParameterSetter.cs</Link>
</Compile>
<Compile Include="..\..\src\Microsoft\Data\SqlClient\TdsParserStaticMethods.cs">
<Link>Microsoft\Data\SqlClient\TdsParserStaticMethods.cs</Link>
</Compile>
<Compile Include="..\..\src\Microsoft\Data\SqlClient\TdsRecordBufferSetter.cs">
<Link>Microsoft\Data\SqlClient\TdsRecordBufferSetter.cs</Link>
</Compile>
Expand Down Expand Up @@ -656,10 +659,12 @@
<Compile Include="Microsoft\Data\SqlClient\TdsParserSessionPool.cs" />
<Compile Include="Microsoft\Data\SqlClient\TdsParserStateObject.cs" />
<Compile Include="Microsoft\Data\SqlClient\TdsParserStateObjectManaged.cs" />
<Compile Include="Microsoft\Data\SqlClient\TdsParserStaticMethods.cs" />
</ItemGroup>
<!-- Windows only -->
<ItemGroup Condition="'$(TargetsWindows)' == 'true'">
<Compile Include="..\..\src\Microsoft\Data\Common\AdapterUtil.Windows.cs">
<Link>Microsoft\Data\Common\AdapterUtil.Windows.cs</Link>
</Compile>
<Compile Include="..\..\src\Microsoft\Data\Sql\SqlDataSourceEnumeratorNativeHelper.cs">
<Link>Microsoft\Data\Sql\SqlDataSourceEnumeratorNativeHelper.cs</Link>
</Compile>
Expand All @@ -672,6 +677,9 @@
</ItemGroup>
<!-- Unix only -->
<ItemGroup Condition="'$(TargetsUnix)' == 'true'">
<Compile Include="..\..\src\Microsoft\Data\Common\AdapterUtil.Unix.cs">
<Link>Microsoft\Data\Common\AdapterUtil.Unix.cs</Link>
</Compile>
<Compile Include="Microsoft\Data\SqlClient\SqlColumnEncryptionCertificateStoreProvider.Unix.cs" />
<Compile Include="Microsoft\Data\SqlClient\SqlColumnEncryptionCngProvider.Unix.cs" />
<Compile Include="Microsoft\Data\SqlClient\SqlColumnEncryptionCspProvider.Unix.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1856,11 +1856,36 @@ private void ResolveExtendedServerName(ServerInfo serverInfo, bool aliasLookup,
string host = serverInfo.UserServerName;
string protocol = serverInfo.UserProtocol;

//TODO: fix local host enforcement with datadirectory and failover
if (options.EnforceLocalHost)
{
// verify LocalHost for |DataDirectory| usage
SqlConnectionString.VerifyLocalHostAndFixup(ref host, true, true /*fix-up to "."*/);
if (aliasLookup)
{ // We skip this for UserInstances...
// Perform registry lookup to see if host is an alias. It will appropriately set host and protocol, if an Alias.
// Check if it was already resolved, during CR reconnection _currentSessionData values will be copied from
// _reconnectSessonData of the previous connection
if (_currentSessionData != null && !string.IsNullOrEmpty(host))
{
Tuple<string, string> hostPortPair;
if (_currentSessionData._resolvedAliases.TryGetValue(host, out hostPortPair))
{
host = hostPortPair.Item1;
protocol = hostPortPair.Item2;
}
else
{
TdsParserStaticMethods.AliasRegistryLookup(ref host, ref protocol);
_currentSessionData._resolvedAliases.Add(serverInfo.UserServerName, new Tuple<string, string>(host, protocol));
}
}
else
{
TdsParserStaticMethods.AliasRegistryLookup(ref host, ref protocol);
}

//TODO: fix local host enforcement with datadirectory and failover
if (options.EnforceLocalHost)
{
// verify LocalHost for |DataDirectory| usage
SqlConnectionString.VerifyLocalHostAndFixup(ref host, true, true /*fix-up to "."*/);
}
}

serverInfo.SetDerivedNames(protocol, host);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@
<Compile Include="..\..\src\Microsoft\Data\Common\AdapterUtil.cs">
<Link>Microsoft\Data\Common\AdapterUtil.cs</Link>
</Compile>
<Compile Include="..\..\src\Microsoft\Data\Common\AdapterUtil.Windows.cs">
<Link>Microsoft\Data\Common\AdapterUtil.Windows.cs</Link>
</Compile>
<Compile Include="..\..\src\Microsoft\Data\Common\DbConnectionStringCommon.cs">
<Link>Microsoft\Data\Common\DbConnectionStringCommon.cs</Link>
</Compile>
Expand Down Expand Up @@ -545,6 +548,9 @@
<Compile Include="..\..\src\Microsoft\Data\SqlClient\TdsParameterSetter.cs">
<Link>Microsoft\Data\SqlClient\TdsParameterSetter.cs</Link>
</Compile>
<Compile Include="..\..\src\Microsoft\Data\SqlClient\TdsParserStaticMethods.cs">
<Link>Microsoft\Data\SqlClient\TdsParserStaticMethods.cs</Link>
</Compile>
<Compile Include="..\..\src\Microsoft\Data\SqlClient\TdsRecordBufferSetter.cs">
<Link>Microsoft\Data\SqlClient\TdsRecordBufferSetter.cs</Link>
</Compile>
Expand Down Expand Up @@ -639,7 +645,6 @@
<Compile Include="Microsoft\Data\SqlClient\TdsParserSafeHandles.cs" />
<Compile Include="Microsoft\Data\SqlClient\TdsParserSessionPool.cs" />
<Compile Include="Microsoft\Data\SqlClient\TdsParserStateObject.cs" />
<Compile Include="Microsoft\Data\SqlClient\TdsParserStaticMethods.cs" />
<Compile Include="Microsoft\Data\SqlTypes\SqlFileStream.cs" />
<Compile Include="Microsoft\Data\SqlTypes\SqlStreamChars.cs" />
<Compile Include="Microsoft\Data\SqlTypes\UnsafeNativeMethods.cs" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

namespace Microsoft.Data.Common
{
/// <summary>
/// The class ADP defines the exceptions that are specific to the Adapters.
/// The class contains functions that take the proper informational variables and then construct
/// the appropriate exception with an error string obtained from the resource framework.
/// The exception is then returned to the caller, so that the caller may then throw from its
/// location so that the catcher of the exception will have the appropriate call stack.
/// This class is used so that there will be compile time checking of error messages.
/// The resource Framework.txt will ensure proper string text based on the appropriate locale.
/// </summary>
internal static partial class ADP
{
internal static object LocalMachineRegistryValue(string subkey, string queryvalue)
{
// No registry in non-Windows environments
return null;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using Microsoft.Win32;

namespace Microsoft.Data.Common
{
/// <summary>
/// The class ADP defines the exceptions that are specific to the Adapters.
/// The class contains functions that take the proper informational variables and then construct
/// the appropriate exception with an error string obtained from the resource framework.
/// The exception is then returned to the caller, so that the caller may then throw from its
/// location so that the catcher of the exception will have the appropriate call stack.
/// This class is used so that there will be compile time checking of error messages.
/// The resource Framework.txt will ensure proper string text based on the appropriate locale.
/// </summary>
internal static partial class ADP
{
[ResourceExposure(ResourceScope.Machine)]
[ResourceConsumption(ResourceScope.Machine)]
internal static object LocalMachineRegistryValue(string subkey, string queryvalue)
{ // MDAC 77697
(new RegistryPermission(RegistryPermissionAccess.Read, "HKEY_LOCAL_MACHINE\\" + subkey)).Assert(); // MDAC 62028
try
{
using (RegistryKey key = Registry.LocalMachine.OpenSubKey(subkey, false))
{
return key?.GetValue(queryvalue);
}
}
catch (SecurityException e)
{
// Even though we assert permission - it's possible there are
// ACL's on registry that cause SecurityException to be thrown.
ADP.TraceExceptionWithoutRethrow(e);
return null;
}
finally
{
RegistryPermission.RevertAssert();
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ namespace Microsoft.Data.Common
/// This class is used so that there will be compile time checking of error messages.
/// The resource Framework.txt will ensure proper string text based on the appropriate locale.
/// </summary>
internal static class ADP
internal static partial class ADP
{
// NOTE: Initializing a Task in SQL CLR requires the "UNSAFE" permission set (http://msdn.microsoft.com/en-us/library/ms172338.aspx)
// Therefore we are lazily initializing these Tasks to avoid forcing customers to use the "UNSAFE" set when they are actually using no Async features
Expand Down Expand Up @@ -1478,31 +1478,6 @@ internal static string GetComputerNameDnsFullyQualified()
return value;
}

[ResourceExposure(ResourceScope.Machine)]
[ResourceConsumption(ResourceScope.Machine)]
internal static object LocalMachineRegistryValue(string subkey, string queryvalue)
{ // MDAC 77697
(new RegistryPermission(RegistryPermissionAccess.Read, "HKEY_LOCAL_MACHINE\\" + subkey)).Assert(); // MDAC 62028
try
{
using (RegistryKey key = Registry.LocalMachine.OpenSubKey(subkey, false))
{
return key?.GetValue(queryvalue);
}
}
catch (SecurityException e)
{
// Even though we assert permission - it's possible there are
// ACL's on registry that cause SecurityException to be thrown.
ADP.TraceExceptionWithoutRethrow(e);
return null;
}
finally
{
RegistryPermission.RevertAssert();
}
}

[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
internal static IntPtr IntPtrOffset(IntPtr pbase, int offset)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1102,20 +1102,6 @@ internal PoolBlockingPeriod ConvertValueToPoolBlockingPeriod()
}
}

#if NETFRAMEWORK
protected internal override PermissionSet CreatePermissionSet()
{
PermissionSet permissionSet = new(PermissionState.None);
permissionSet.AddPermission(new SqlClientPermission(this));
return permissionSet;
}

internal bool ConvertValueToEncrypt()
{
bool defaultEncryptValue = !Parsetable.ContainsKey(KEY.Authentication) ? DEFAULT.Encrypt : true;
return ConvertValueToBoolean(KEY.Encrypt, defaultEncryptValue);
}

static internal Hashtable NetlibMapping()
{
const int NetLibCount = 8;
Expand Down Expand Up @@ -1166,6 +1152,21 @@ internal static class NETLIB
}

private static Hashtable s_netlibMapping;

#if NETFRAMEWORK
protected internal override PermissionSet CreatePermissionSet()
{
PermissionSet permissionSet = new(PermissionState.None);
permissionSet.AddPermission(new SqlClientPermission(this));
return permissionSet;
}

internal bool ConvertValueToEncrypt()
{
bool defaultEncryptValue = !Parsetable.ContainsKey(KEY.Authentication) ? DEFAULT.Encrypt : true;
return ConvertValueToBoolean(KEY.Encrypt, defaultEncryptValue);
}

private readonly bool _connectionReset;
private readonly bool _contextConnection;
private readonly bool _transparentNetworkIPResolution;
Expand Down
Loading

0 comments on commit 3082ae5

Please sign in to comment.