dotnet / SqlClient

Microsoft.Data.SqlClient provides database connectivity to SQL Server for .NET applications.
MIT License
846 stars 281 forks source link

Microsoft.Data.SqlClient.SNINativeMethodWrapper.UnmanagedIsTokenRestricted can't read sni.dll on IIS with custom apppool Identity #468

Closed chromigo closed 4 years ago

chromigo commented 4 years ago

We're seeing sni.dll error with old asp.net mvc 5 project(net4.8) with Microsoft.EntityFrameworkCore* 3.1.2 installed(and Microsoft.Data.SqlClient.SNI v1.1.1 too). The problem only on full IIS with custom account Identity in app pool configured. Locally on IISExpress all works fine.

Workound for us is to copy C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App\2.*...sni.dll to application/bin/x64 and replace. (found here https://github.com/dotnet/SqlClient/issues/385)

Is there some more convinient solution of this problem?

Exception message:
System.TypeInitializationException
The type initializer for 'Microsoft.Data.SqlClient.SNINativeMethodWrapper' threw an exception.
Stack trace:
System.TypeInitializationException: The type initializer for 'Microsoft.Data.SqlClient.SNINativeMethodWrapper' threw an exception. ---> System.ComponentModel.Win32Exception: Failed to load C:\www\site3\site\bin\x64\SNI.dll ---> System.ComponentModel.Win32Exception: The specified module could not be found
   --- End of inner exception stack trace ---
   at Microsoft.Data.SqlClient.SNINativeMethodWrapper..cctor()
   --- End of inner exception stack trace ---
   at Microsoft.Data.SqlClient.SNINativeMethodWrapper.UnmanagedIsTokenRestricted(IntPtr token, Boolean& isRestricted)
   at Microsoft.Data.Win32NativeMethods.IsTokenRestrictedWrapper(IntPtr token)
   at Microsoft.Data.ProviderBase.DbConnectionPoolIdentity.GetCurrent()
   at Microsoft.Data.ProviderBase.DbConnectionPoolGroup.GetConnectionPool(DbConnectionFactory connectionFactory)
   at Microsoft.Data.ProviderBase.DbConnectionFactory.GetConnectionPool(DbConnection owningObject, DbConnectionPoolGroup connectionPoolGroup)
   at Microsoft.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal oldConnection, DbConnectionInternal& connection)
   at Microsoft.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
   at Microsoft.Data.SqlClient.SqlConnection.TryOpenInner(TaskCompletionSource`1 retry)
   at Microsoft.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1 retry)
   at Microsoft.Data.SqlClient.SqlConnection.Open()
   at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenDbConnection(Boolean errorsExpected)
   at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.Open(Boolean errorsExpected)
   at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReader(RelationalCommandParameterObject parameterObject)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable`1.Enumerator.InitializeReader(DbContext _, Boolean result)
   at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.Execute[TState,TResult](TState state, Func`3 operation, Func`3 verifySucceeded)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable`1.Enumerator.MoveNext()
   at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
   at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
   at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
cheenamalhotra commented 4 years ago

Could you gather build logs when you deploy on LocalIIS v/s full IIS and upload them here? If using "msbuild", use can use flag "/bl" and capture the same in msbuild.binlog files. We'd can try to compare and analyze them.

chromigo commented 4 years ago

Well, I have resolved problem. TLDR: had Microsoft Visual C++ 2015 Redistributable x86 but had not x64.

Details: The exception contains

System.ComponentModel.Win32Exception: The specified module could not be found specified module is keyword here. sni.dll is ok, but probably he still has dependencies.

So I looked at https://github.com/dotnet/SqlClient/issues/211 and https://github.com/dotnet/SqlClient/issues/361 I already checked that machine has Microsoft Visual C++ 2015 Redistributable installed. But it was only x86 version... Installing x64 solved the problem.

It's strange, because here https://github.com/dotnet/SqlClient/issues/361#issuecomment-594759511 say that "we have removed dependency on VC Runtime, so you don't need that installed on your client". I have 1.1.1 version of Microsoft.Data.SqlClient but it look like he still need visual c++ 2015. binding redirect

<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.Data.SqlClient" publicKeyToken="23ec7fc2d6eaa4a5" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-1.11.20045.2" newVersion="1.11.20045.2" />
      </dependentAssembly>
    </assemblyBinding>
cheenamalhotra commented 4 years ago

@chromigo

That's great to know!

I have 1.1.1 version of Microsoft.Data.SqlClient but it look like he still need visual c++ 2015.

You should have reference to Microsoft.Data.SqlClient.SNI v1.1.1 that does not depend on VC++ Redist packages any more.

chromigo commented 4 years ago

@cheenamalhotra yep, seems like it helps. Thank you!

naveedahmed1 commented 4 years ago

I am receiving below error when deploying .Net Core 3.1 application is it related?:

I have verified sni.dll does exist in the deployed files.

Any help would be really appreciate.

An unhandled exception occurred while processing the request.
DllNotFoundException: Unable to load DLL 'sni.dll' or one of its dependencies: Access is denied. (0x80070005 (E_ACCESSDENIED))
Microsoft.Data.SqlClient.SNINativeMethodWrapper.SNIInitialize(IntPtr pmo)

TypeInitializationException: The type initializer for 'Microsoft.Data.SqlClient.SNILoadHandle' threw an exception.
Microsoft.Data.SqlClient.TdsParserStateObjectFactory.get_EncryptionOptions()

TypeInitializationException: The type initializer for 'Microsoft.Data.SqlClient.TdsParser' threw an exception.
Microsoft.Data.SqlClient.TdsParser..ctor(bool MARS, bool fAsynchronous)
Shubbi commented 4 years ago

I am also getting this error after we upgraded to EFCore 3.1.3 from EFCore 2.x

(on local machines with iis express it is working fine .....only when I deploy it to server it fails)

I've taken following steps so far

But no luck so far Only the exception message changed a little bit. Previously it was -Exception: System.TypeInitializationException: The type initializer for 'Microsoft.Data.SqlClient.SNINativeMethodWrapper' threw an exception. ---> System.ComponentModel.Win32Exception: Failed to load d:\webdocs\myapplication\bin\x64\SNI.dll at Microsoft.Data.SqlClient.SNINativeMethodWrapper..cctor() in E:\agent1_work\34\s\src\Microsoft.Data.SqlClient\netfx\src\Microsoft\Data\Interop\SNINativeMethodWrapper.cs:line 66

Now it is System.TypeInitializationException: The type initializer for 'Microsoft.Data.SqlClient.SNINativeMethodWrapper' threw an exception. ---> System.ComponentModel.Win32Exception: Failed to load d:\webdocs\esamd\esamservice\bin\x64\SNI.dll ---> System.ComponentModel.Win32Exception: Access is denied

We are having WebAPi project on .Net Fremework 4.7.1 , and the class libraries are .Net Standard 2.0

vanlanckerst commented 4 years ago

I've tried all steps listed above and still having the same issue, which blocks me to deploy to our server at the moment

naveedahmed1 commented 4 years ago

Only thing that works in my case is https://github.com/dotnet/SqlClient/issues/496#issuecomment-605507382