Skip to content
This repository has been archived by the owner on Feb 9, 2024. It is now read-only.

Exception when extracting a database into a DACPAC as impersonated user #48

Open
t-mxcom opened this issue Jun 26, 2020 · 0 comments
Open

Comments

@t-mxcom
Copy link

t-mxcom commented Jun 26, 2020

Introduction

My solution makes use of the Microsoft.SqlServer.DacFx.x64 (v150.4826.1) NuGet-package to programmatically extract a database into a DACPAC, built using Visual Studio 2019 (Version 16.6.2) and SQL Server Data Tools (16.0.62006.03190).

The application itself gets started by the interactively logged on user on Windows under the users domain account.
Let's call this user User-A.
Internally, the application logs on another Windows domain account (let's call it User-B) by calling LogonUser and impersonates the user-context before executing the DacFx assemblys extract method.
After the extract operation, the user-context is reverted back to User-A.

Issue

When executing the extract operation (DacServices.Extract), the following exception gets thrown:

18.05.2020 12:23:44 - E - Microsoft.SqlServer.Dac.DacServicesException: Could not save package to file. ---> Microsoft.Data.Tools.Schema.Sql.Build.SqlPackageException: Der Typeninitialisierer für "MS.Utility.EventTrace" hat eine Ausnahme verursacht. ---> System.TypeInitializationException: Der Typeninitialisierer für "MS.Utility.EventTrace" hat eine Ausnahme verursacht. ---> System.Security.SecurityException: Der angeforderte Registrierungszugriff ist unzulässig.
18.05.2020 12:23:44 - E -    bei System.ThrowHelper.ThrowSecurityException(ExceptionResource resource)
18.05.2020 12:23:44 - E -    bei Microsoft.Win32.RegistryKey.OpenSubKey(String name, Boolean writable)
18.05.2020 12:23:44 - E -    bei Microsoft.Win32.RegistryKey.OpenSubKey(String name)
18.05.2020 12:23:44 - E -    bei Microsoft.Win32.Registry.GetValue(String keyName, String valueName, Object defaultValue)
18.05.2020 12:23:44 - E -    bei MS.Utility.EventTrace.IsClassicETWRegistryEnabled()
18.05.2020 12:23:44 - E -    bei MS.Utility.EventTrace..cctor()
18.05.2020 12:23:44 - E -    --- Ende der internen Ausnahmestapelüberwachung ---
18.05.2020 12:23:44 - E -    bei MS.Utility.EventTrace.EasyTraceEvent(Keyword keywords, Event eventID)
18.05.2020 12:23:44 - E -    bei System.IO.Packaging.Package.Open(Stream stream, FileMode packageMode, FileAccess packageAccess, Boolean streaming)
18.05.2020 12:23:44 - E -    bei Microsoft.Data.Tools.Schema.Sql.Build.SqlPackage.Artifact.InitializefromStream(Stream stream, FileMode mode, FileAccess access)
18.05.2020 12:23:44 - E -    --- Ende der internen Ausnahmestapelüberwachung ---
18.05.2020 12:23:44 - E -    bei Microsoft.Data.Tools.Schema.Sql.Build.SqlPackage.Artifact.InitializefromStream(Stream stream, FileMode mode, FileAccess access)
18.05.2020 12:23:44 - E -    bei Microsoft.Data.Tools.Schema.Sql.Build.SqlPackage.Artifact..ctor(Stream stream, FileAccess access)
18.05.2020 12:23:44 - E -    bei Microsoft.Data.Tools.Schema.Sql.Build.SqlPackage.Open(Stream stream, FileAccess access)
18.05.2020 12:23:44 - E -    bei Microsoft.SqlServer.Dac.DacPackage.Save(Stream stream, DataSchemaModel model, DacMetadata metadata, Nullable`1 minModelVersion)
18.05.2020 12:23:44 - E -    --- Ende der internen Ausnahmestapelüberwachung ---
18.05.2020 12:23:44 - E -    bei Microsoft.SqlServer.Dac.DacPackage.Save(Stream stream, DataSchemaModel model, DacMetadata metadata, Nullable`1 minModelVersion)
18.05.2020 12:23:44 - E -    bei Microsoft.SqlServer.Dac.DacServices.<>c__DisplayClass65.<>c__DisplayClass67.<CreateExportOperation>b__63()
18.05.2020 12:23:44 - E -    bei Microsoft.Data.Tools.Schema.Sql.Dac.OperationLogger.Capture(Action action)
18.05.2020 12:23:44 - E -    bei Microsoft.SqlServer.Dac.DacServices.<>c__DisplayClass65.<CreateExportOperation>b__62(Object operation, CancellationToken token)
18.05.2020 12:23:44 - E -    bei Microsoft.SqlServer.Dac.Operation.Microsoft.SqlServer.Dac.IOperation.Run(OperationContext context)
18.05.2020 12:23:44 - E -    bei Microsoft.SqlServer.Dac.OperationExtension.CompositeOperation.Microsoft.SqlServer.Dac.IOperation.Run(OperationContext context)
18.05.2020 12:23:44 - E -    bei Microsoft.SqlServer.Dac.OperationExtension.Execute(IOperation operation, DacLoggingContext loggingContext, CancellationToken cancellationToken)
18.05.2020 12:23:44 - E -    bei Microsoft.SqlServer.Dac.DacServices.Extract(Func`1 streamGetter, String databaseName, String applicationName, Version applicationVersion, String applicationDescription, IEnumerable`1 tables, DacExtractOptions extractOptions, Nullable`1 cancellationToken, DacLoggingContext extractLoggingContext)
18.05.2020 12:23:44 - E -    bei Microsoft.SqlServer.Dac.DacServices.Extract(Stream packageStream, String databaseName, String applicationName, Version applicationVersion, String applicationDescription, IEnumerable`1 tables, DacExtractOptions extractOptions, Nullable`1 cancellationToken)

(Timestamps were added by my application)

If I launch the application as User-B and execute the extract operation without the additional impersonation, everything works fine.

How to solve this?

When tracking down this issue, I found out, that even if I perform several actions to fully load the profile of User-B, something still seems to be missing so I can't get it to work.
Finally I modified the workflow so my application gets directly launched as User-B rather than as User-A by using CreateProcessWithLogon, which basically works now. But I'm not very satisfied with this solution.

What does MS.Utility.EventTrace do during it's initialization that's missing after LogonUser?
And what has to be done to support executing DacFx actions in an impersonated user-context?

Thank you for your help!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant