Does an NServiceBus endpoint with SQL Server transport and Windows authentication need to be installed as the user running the service? - nservicebus

I'm installing an NServiceBus 4.x endpoint which uses SQL Server transport. While running the installer (via Octopus Deploy, which runs as Local System by default)...
.\NServiceBus.Host.exe /install NServiceBus.Production /serviceName=$name /username:"$username" /password:"$password
... I get an error:
Failed to execute installers: System.Data.SqlClient.SqlException (0x80131904): Login failed for user 'DOMAIN\MACHINENAME$'.
This is the expected behavior if the installer connects to SQL Server when it's run: Local System becomes the computer account when it leaves the box and the computer account does not have access to the transport database.
However, I do not intend to run the endpoint as Local System. Instead, I intend to use a domain service account which does have access to the transport database, so...
Is it possible to install an NServiceBus endpoint using SQL Server transport as a user who does not have access to the transport database?
Bonus question: Has this behavior been changed in versions of NServiceBus later than 4.x?

The problem here is that the NServiceBus.Host.exe is executed with the credentials of as you say Octopus Deploy and /install runs the NServiceBus installers.
Some alternatives:
Run Octopus Deploy Agent with permissions that also allows doing schema changes on the database during this deployment phase.
Instead of executing the host directly, launch a shell with different credentials so that the host is run with credentials that have appropriate permissions.
Do not use the host, but use self-hosting. Register that service via sc.exe to register the windows service with the right credentials, and use endpointConfiguration.EnableInstallers() to control if installers must be run.
https://docs.particular.net/nservicebus/operations/installers
https://docs.particular.net/samples/hosting/windows-service/
https://docs.particular.net/nservicebus/hosting/windows-service#installation
Use self-hosting as in (3), don't use endpointConfiguration.EnableInstallers() but script all tasks and let these run independently of the 'windows service' registration task. Alternatively, you can instead use sc.exe to register the NServiceBus.Host.exe so that the /install will not be run.
That means generating most scripts yourself. Some components have script generators but our docs have a lot of guidance on scripting
https://docs.particular.net/search?q=script
I would advise NOT to just always run endpointConfiguration.EnableInstallers() on an endpoint. You should distinguish between a deployment and runtime. During deployment you would create tables, schemas etc. but at runtime, that account should not have the permissions to create or drop tables and run least privilege.

Related

What is the purpose of the following service in oracle OracleSchedulerXE

I have a question regarding the purpose of some service in sql. What does the process, the purpose of them.
OracleSchedulerXE
OracleORADB19Home1MTSRecoveryService
OracleOraDB19home1TNSListner
OracleRemExecServiceV2
OracleServiceXE
OracleVSSWriter
I tried to find something about OracleSchedurXE but I did nt find anithing.
Thank you.
If I Google any of the service names, I get back several pages that go into detail about what they do.
OracleSchedulerXE is used by Oracle for the dbms_scheduler package that lets you schedule jobs to run inside the database.
OracleORADB19Home1MTSRecoveryService is used for interacting with the Microsoft Transaction Server. Most commonly, that is used to allow applications to manage distributed transactions that involve Oracle and other Windows services.
OracleOraDB19home1TNSListner is used for the TNS listener.
That's the process that allows users to connect to the database from remote machines.
OracleRemExecServiceV2 is a service used by the Oracle Universal Installer during installation that will be removed once you reboot after a successful install.
OracleServiceXE is the service that actually runs the Oracle database
OracleVSSWriter is a service that interacts with the Windows Volume Shadow Copy service to ensure that backups see files in a consistent state.

Passing MSI token to flyway command line

When running the 'migrate' command of the flyway, the standard way to access DB is by providing user and password. In my case, it's Azure SQL DB and instead of user/password I have only MSI token. Is it possible to pass the token to the command line? Looking at the parameters of the 'migrate' command I couldn't find anything like that.
Azure Active Directory MSI Authentication is supported and please see the Microsoft documentation as it has more details about how these work with JDBC URLs, (link) to download the driver and the applicable connection string properties and client requirements but please note:
Supported since driver version v7.2, authentication=ActiveDirectoryMSI can be used to connect to an Azure SQL Database/Data Warehouse from inside of an Azure Resource with "Identity" support enabled. Optionally, msiClientId can also be specified in the Connection/DataSource properties along with this authentication mode, which must contain the Client ID of a Managed Service Identity to be used to acquire the accessToken for establishing the connection.
You could run this from an Azure AD Federated on-premise host or Azure host using the following java client example and then run the migrate command.

IIS connecting to LocalDB

Is there any way so IIS could connect to LocalDB without using the NT SERVICE\NETWORK SERVICE user account.
This account has not suitable permissions. I'm looking use some other default account or is there some way that I can use the NETWORK SERVICE account without changing permissions?
You should use Shared Instances feature of LocalDB. These two posts on Using LocalDB with Full IIS should give you more information. Especially the second part seems relevant, but the first one contains some context as well.
(note: the original links are no longer available, using archive.org instead)
Part 1: User Profile
Part 2: Instance Ownership
Original (non-working as of March 2019) links:
Part 1: User Profile
Part 2: Instance Ownership
In case the links disappear again, I am copy-pasting solutions from the article for easier access:
Post 1:
The problem we're facing is that the user profile needs to be loaded. That shouldn't be hard since each IIS Application Pool has an option called Load User Profile that can be found in Advanced Settings section. Unfortunately things got slightly more complicated in Service Pack 1 for Windows 7. As described in KB 2547655 enabling loadUserProfile is not enough to fully load user profile, we also need to enable setProfileEnvironment. This requires editing applicationHost.config file which is usually located in C:\Windows\System32\inetsrv\config. Following the instructions from KB 2547655 we should enable both flags for Application Pool ASP.NET v4.0, like this:
<add name="ASP.NET v4.0" autoStart="true" managedRuntimeVersion="v4.0" managedPipelineMode="Integrated">
<processModel identityType="ApplicationPoolIdentity" loadUserProfile="true" setProfileEnvironment="true" />
</add>
Having completed that we restart the Application Pool to make sure the new settings are applied and run our Web Application again.
Note from my side: Just find "applicationPools" tag in that applicationHost file and update those two variables to true, so it looks like this:
<processModel identityType="ApplicationPoolIdentity" loadUserProfile="true" setProfileEnvironment="true" />
That's it, save the file and restart IIS pool.
Post 2:
The Problem of the Private Instance
As we can see we are facing the following error:
System.Data.SqlClient.SqlException: Cannot open database "OldFashionedDB" requested by the login. The login failed.
Login failed for user 'IIS APPPOOL\ASP.NET v4.0'.
This time the error is quite clear. LocalDB was started and the Web Application was able to connect to it, but the connection was then terminated due to login failure. The ApplicationPoolIdentity account for the IIS application pool (in this case IIS APPPOOL\ASP.NET v4.0) couldn't login to LocalDB instance because the database specified in the connection string (OldFashionedDB) wasn't found. How odd, since connecting from Visual Studio with the same connection string succeeds!
How is it possible that Visual Studio connects to LocalDB just fine, while the connection from Web Application fails? In both cases the connection string is the following:
Data Source=(localdb)\v11.0;Initial Catalog=OldFashionedDB;Integrated Security=True
The answer is that there are two different LocalDB instances here. Unlike SQL Server Express instances, which are running as Windows services, LocalDB instances are running as user processes. When different Windows users are connecting to LocalDB, they will end up with different LocalDB processes started for each of them. When we connect to (localdb)\v11.0 from Visual Studio, a LocalDB instance is started for us and runs as our Windows account. But when Web Application, running in IIS as ApplicationPoolIdentity, is connecting to LocalDB, another LocalDB instance is started for it and is running as ApplicationPoolIdentity! In effect, even though both Visual Studio and Web Application are using the same LocalDB connection string, they are connecting to different LocalDB instances. Obviously the database created from Visual Studio on our LocalDB instance will not be available in Web Application's LocalDB instance.
A good analogy to this is My Documents folder in Windows. Say we open Visual Studio and create a file in our My Documents folder. Then we login to the same machine as a different user and go to My Documents folder again. We won't find the file there as My Documents of the second user and our My Documents are two different folders. Similarly LocalDB instances (localdb)\v11.0 owned by two different users are two different processes with two different sets of databases.
This is also the reason the Web Application was able to connect to LocalDB from IIS Express. Just like LocalDB, IIS Express is a user process. It is started by Visual Studio and runs as the same Windows account as the Visual Studio process. Two different processes running as the same Windows account (Visual Studio and IIS Express, both running as our Windows account) connecting to (localdb)\v11.0 are connecting to the same LocalDB process, also started as the same Windows account.
Possible Solutions
Understanding the nature of the problem brings multiple approaches to solving it. As different approaches have different tradeoffs, instead of prescribing one solution, below I presented three approaches that seem most viable to me. My hope is to hear from you about the one that worked best for you! Here is the list:
Approach 1: Run IIS as our Windows user
Approach 2: Use LocalDB Shared Instance
Approach 3: Use full SQL Server Express
Let's take a closer look at each of them.
Approach 1: Run IIS as our Windows user
If different user accounts are the problem, why not try to run our Web Application under our Windows account? Web Application would connect to the same LocalDB as Visual Studio and everything should just work.
Making the configuration change is relatively easy, just start IIS Manager and find the right Application Pool:
Open Advanced Settings screen (available in the context menu):
Click the little button in the Identity property to bring up the Application Pool Identity screen:
Starting the Web Application again will confirm that the problem is solved:
What are the drawbacks of this approach? Of course running Web Application under our account brings certain security risks. If someone hijacks our Web Application they will be able to access all system resources our account can. Running the Web Application as ApplicationPoolIdentity provides additional protection since ApplicationPoolIdentity accounts have very limited access to local system resources. Therefore I cannot recommend this approach in general, but when used with care it is a viable option in some cases.
Approach 2: Use LocalDB Shared Instance
We could also use an instance sharing feature of LocalDB. It allows us to share a LocalDB instance with other users on the same machine. The shared instance will be accessible under a public name.
The easiest way of sharing an instance is to use SqlLocalDB.exe utility. Just start an administrative command line prompt, and type the following command:
sqllocaldb share v11.0 IIS_DB
It will share the private LocalDB instance v11.0 under the public name IIS_DB. All users on the machine will be able to connect to this instance, using (localdb).\IIS_DB as a server address. Note the . before the instance name, indicating this is a shared instance name. We should replace the connection string in our Web Application with an updated one:
Data Source=(localdb)\.\IIS_DB;Initial Catalog=OldFashionedDB;Integrated Security=True
Before the shared instance can be used by the Web Application we need to start it and create logins for the ApplicationPoolIdentity. Starting the instance is easy, simply connecting to it from SQL Server Object Explorer will start it and keep it alive. Once we are in the SQL Server Object Explorer we can also create the login for ApplicationPoolIdentity. We could use the following query:
create login [IIS APPPOOL\ASP.NET v4.0] from windows;
exec sp_addsrvrolemember N'IIS APPPOOL\ASP.NET v4.0', sysadmin
This script gives full administrative access to our LocalDB instance to the ApplicationPoolIdentity account. Whenever possible, I would recommend using more limited, database-level or even table-level permissions.
Now we can run our Web Application again. This time it should work just fine:
What are the drawbacks of this approach? The main one is that, before Web Application can connect to the shared instance, we need to make sure the instance is started. For that to happen the Windows account that owns the instance must connect to it and the connection must be kept open, or the LocalDB instance will shut down.
Approach 3: Use full SQL Server Express
Since full IIS runs as a service, maybe using traditional, service-based SQL Server Express is the right approach? We could just install SQL Server 2012 Express RC0 and create the OldFashionedDB database in it. We can even use our brand new SQL Server Data Tools to do it, as it works with any SQL Server version and edition. Our connection string would have to change to:
Data Source=.\SQLEXPRESS;Initial Catalog=OldFashionedDB;Integrated Security=True
Of course, just as in the previous case, we would need to make sure the ApplicationPoolIdentity account has access to our SQL Server Express instance. We can use the same script as previously:
create login [IIS APPPOOL\ASP.NET v4.0] from windows;
exec sp_addsrvrolemember N'IIS APPPOOL\ASP.NET v4.0', sysadmin
After that, running our Web Application brings the happy picture again:
What are the drawbacks of this approach? Obviously we lose the benefits of using LocalDB. Installing SQL Server Express may take more time than LocalDB, and there may be some machine cleanup necessary for it to succeed. SQL Server Express Setup can be blocked by problems like corrupt WMI database, polluted registry or components left by SQL Server or Visual Studio CTPs and Betas. And SQL Server Express will continue running in the background even when not needed, as services do.
Other options
There are other approaches of using LocalDB under full IIS that are not covered here. We could embrace the Web Application's private LocalDB instance and communicate with it through the Web Application by executing T-SQL scripts from ASP.NET code. We could also use AttachDbFileName option of ADO.NET connection strings and use a database file (.mdf) that would be attached to both our LocalDB during development and Web Application's LocalDB for debugging. I tried both I found them too cumbersome to discuss further.
Based on the answer from #KrzysztofKozielczyk.
I originally posted an answer here:
https://stackoverflow.com/a/62810876/3850405
After following this I verified that Load User Profile was set to true for my Application Pool and then set setProfileEnvironment to true in applicationHost.config. I did the last part by editing applicationHost.config located at:
C:\Windows\System32\inetsrv\config\applicationHost.config

WiX: Mysterious and hard-to-diagnose ICE validation errors on build server build

I'm trying to integrate WiX into my automated build solution using TFS 2010 running on Windows Server 2008 R2. Everything seemed very easy, and then I get this:
light.exe: Error executing ICE action 'ICE01'. The most common cause of this kind of ICE failure is an incorrectly registered scripting engine. See http://wix.sourceforge.net/faq.html#Error217 for details and how to solve this problem. The following string format was not expected by the external UI message logger: "The Windows Installer Service could not be accessed. This can occur if the Windows Installer is not correctly installed. Contact your support personnel for assistance.".
That's odd. But hey! They provided a link. That should help, right?
Error LGHT0217
In WiX v3, Light automatically runs validation-- Windows Installer Internal Consistency Evaluators (ICEs) --after every successful build. Validation is a great way to catch common authoring errors that can lead to service problems, which is why it’s now run by default. Unfortunately, there’s a common issue that occurs on Windows Vista and Windows Server 2008 that can cause ICEs to fail. For details on the cause and how to fix it, see Heath Stewart's Blog and Aaron Stebner's WebLog.
Not at all. These posts just describe a situation involving scripting engine registration, and the conditions they describe were not present. However, I came upon Re: (WiX-users) Why do I get ICE failures building from a serviceaccount? (2010-01-14) that seemed to indicate that if I used a domain account to run the Windows Installer service, it would work. It sounded like it was worth a shot.
"For whatever reason on Windows 2008 (I didn't test Vista, XP, 2003, 7, or
2008 R2) the MSI Service is only available from logins that either have
administrative access or are logins that are "interactive". Logins that are
from service accounts that to not have administrative privileges cannot
access the msi service and thus cannot run ICE tests."
However, when trying to start the Windows Installer service with my build service account:
Windows could not start the Windows Installer service on SKILLET-1. Error 1297: A privilege that the service requires to function properly does not exist in the service account configuration. You may use the Services Microsoft Management Console (MMC) snap-in (services.msc) and the Local Security Settings MMC snap-in (secpol.msc) to view the service configuration and the account configuration.
OK, Windows, so you're telling me that my build service account is missing some ambiguous permission that it needs to start up the service. Making it administrator should fix that right? Nope, that doesn't work either.
So I revert back to local system for the Windows Installer service account. This time I made the build service a local administrator, and lo, success! That's hardly a solution, though.
My next idea was to attempt to isolate the permission set that the build service would actually require to get this done. That would be a nice solution instead of having to add more accounts to the administrator set. Step 1: go into local security policy and add the build service account to all permissions currently given to Administrators. In theory, that should allow the build to succeed, and from there I could selectively remove permissions until I've isolated all the permissions that must be held in order for it to succeed.
Unfortunately, even with all the same permissions, the build will still fail unless the build service account is a member of local administrators. Why is this? What other things besides LSP have dependencies on the administrator group that I could have changed to bring my build service account to equivalence with administrators?
Current conclusion: the build service must be an administrator in order to avoid ICE validation errors.
Open questions:
Why didn't my permissions isolation idea work?
What is this mysterious Error 1297 being thrown when running Windows Installer Service as a domain user? There's almost no documentation I can find on this.
I too faced the same problem. After some struggling and googling I came to the solution that suppressing ICE validation in the WiX project would make the project compile.

Run SSIS package from SQL client

I deployed my working package on server which is enterprise edition, SSIS installed on it. When I tries to run package by connecting to integration services engine from my desktop SQL client (which doesn't have SSIS installed) I get error "The task "Send Mail Task" cannot run on this edition of Integration Services. It requires a higher level edition."
Does it mean that I need to login to the server (RDP) and then run the package?
Also, when I schedule the package thru SQL agent it fails saying login time out but my windos auth login works for everything from connecting, deployment. Any clue?
For your first problem - yes, you need to RDP into the server in order to use SSMS to start the package. When you start it using SSMS on your client, it's attempting to launch the DTExec process on your client machine. It's not running DTExec on the server.
Your second problem is likely a permissions issue. Possibility #1: The connections you have set up on your package require your authentication information, and they don't have it because they're running as the Agent account. You can fix that by creating a Proxy for your account and using that to run your job step. Possibility #2: The connections you have set up on your package are having their sensitive information stripped out due to the default encryption on the packages that prevents anyone but "you" from seeing it - including a SQL Agent job that isn't running "as you". The same resolution as above can help that (as well as others).