How do I configure authentication between linked servers? - sql-server-2005

I am trying to test a proof of concept that I can run a distributed transaction across two linked SQL Servers, linked using sp_addlinkedserver - their names are Server1 and Server2, both running under default instances. Each server holds a single database, Source and Destination respectively and the destination database holds a single table called Output, i.e.
Server1.Source
Server2.Destination.Output
The OUTPUT table has the following structure:
OUT_PKEY int identity(1,1) primary key,
OUT_TEXT nvarchar(255)
From Server1 I have called sp_addlinkedserver 'Server2' to link the two databases and I've attempted to run the following query to test that the link does indeed work:
Select *
From Server2.Destination.dbo.Output
I am returned the following exception:
Access to the remote server is denied because no login-mapping exists.
Fair enough, so from Server1, I run sp_addlinkedsrvlogin 'Server2' which according to the documentation says that it should take the user credentials of whomever runs the query remotely (i.e. from Server1) and apply those credentials to Server2. This implies that since I am connected to Server1 using Windows Authentication, this should mean that my Windows Credentials are applied to Server2 also.
Now the exception message changes to:
Login failed for user 'NT AUTHORITY\ANONYMOUS LOGON'.
Having Googled this exception, I came up with nothing useful that pointed me in the right direction. What am I missing? I would expect [should the login fail at all] the exception to reference my Windows Credentials, not the anonymous logon credentials.
It looks like once I get the link itself working, the distributed transactions themselves should be a fairly simple affair - the documentation implies that I just need to ensure that the DTC Service is running on Server1 and that any queries run on Server1 that will be transacted across the link:
Include SET XACT_ABORT ON prior to initializing my distributed transaction
I use BEGIN DISTRIBUTED TRANSACTION instead of BEGIN TRANSACTION
If I wish to reference a non-default instance of SQL Server on Server2, I replace any instances of the name Server2 in my query with [Server2\InstanceName]
My questions are these:
how do I get past this login issue? The sp_addlinkedsrvlogin stored procedure alone doesn't seem to be doing the trick.
Is it indeed as simple as that to run the distributed transaction as the documentation implies?
TIA

If you're on a domain, then the setting should be "Be made using the login's current security context", but there's one more step - you need to grant an SPN to each of the servers involved in the transaction.
Assuming you're running the SQL Services on both servers as a domain user (which you'll need to in order to make this work - LocalSystem won't do it), here are the instructions you'll need:
http://technet.microsoft.com/en-us/library/bb735885.aspx
Remember that the user will need an SPN for both servers, but not the client - for example, if you are going from client -> server1 -> server2, the SQL Service account will need an SPN for both server1 and server2.
If you're confused (it's a confusing process), post a comment and I'll clarify the instructions.

Assuming these servers are both on the same domain - have you enabled trusted delegation to allow your server to pass the credentials to the targeted server? You would pull up the Active Directory object for the server and go to the Delegation tab and select "Trust this computer for delegation to specified services only" and then enter the SQL Server details that the server is allowed to pass credentials to:
Service Type = MSSQLSvc
User/Computer = YourTargetServer.Your.Domain
Port = 1433
Sadly, a lot of these types of authentication issues with linked servers require a reboot to fully take effect (so if these are production servers it is hard to troubleshoot during the day).
In regards to distributed transactions - if you eventually get the linked server connection up and running correctly then distributed transactions work great. Although the next thing you'll probably run into once you get it working is finding the huge flaw that you can't use any form of SCOPE_IDENTITY(), ##IDENTITY, etc. to retrieve primary keys after inserting something into a linked database. But that's another issue with its own fun workarounds...

Related

Linked Servers security in SSMS

I'm looking to identify all linked servers connections that have security setup with either "Be made using the login's current security context" or "Be made using this security context"
I can utilize a centralized job or PowerShell command to run on all of my instances, but I can't find any queries that link security to queries like select * from sys.syservers, or sys.servers, or executing the stored procedure sp_linkedservers. All of those give me information about that servers linked servers, but no information about the security related to those connections. Is there system tables that I'm not finding that add this information, maybe with a join or something? I'll be doing this on a range of environments from 2014 to 2019.

SQL Server Service Broker and Linked Servers

I've setup a Service Broker on one of databases to automatically pick up stored procedures in a specific schema (Build) and run them on a daily basis. So far everything has been running fine, however we've now got a need where we need to access a remote sql server which is running SQL Server 2017 and has the latest Machine Learning Service installed.
I've given the service account that runs the primary SQL Server (SQL 2016) access on the remote server, and ensured the Service Broker is executing under the service account, rather than the local SQL account (sa).
Whenever we try to access the remote server, we are getting the following error:
Linked servers cannot be used under impersonation without a mapping
for the impersonated login.
I've tried adding an EXECUTE AS to the process, however this doesn't seem to make a difference. I've also ensured it is running under the service account, and it is.
I can get it to work using a mapped login on the linked server, however this isn't ideal, as we don't want to run the sql server in mixed authentication as this has been determined as an IT risk.
I've run out of ideas or what I can do here, and can't find any other help pieces with this same problem. I did want to roll this process out to more of our warehouse builds, however this is a deal breaker at this stage.
help?

Can I link a server that I only have read-access to?

Trying to link a server that I only have read-access to and uses windows authentication to log me in. I'm trying to link it to my local database so I can combine commands in both databases because my web application executes stored procedures.
Is this possible?
https://learn.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-addlinkedserver-transact-sql?view=sql-server-2017
Yes, you can.
From your description, you want to uses windows authentication to log in the linked server.
When a linked server is created by using sp_addlinkedserver, a default self-mapping is added for all local logins. As a result, if the windows account for the local server also exist in the remote account, you can log in the linked server via the current windows account.
Besides after adding the linked server, you can also create a mapping between a login on the local instance of SQL Server and a security account on a remote server. For detailed information, please refer to the sp_addlinkedsrvlogin (Transact-SQL).

SQL 2005: Discover all client connections

I have a project to inventory an SQL Server. Part of this project includes discovering every IP that makes a connection to this SQL Server. It is an internal SQL Server with several other programs running on other servers that access this SQL server. Because this server's IP address is going to be changed, all of those other programs will have to updated with the new address. Plus the boss just wants a diagram of everything running on this server and everything connecting to it.
My initial inclination would be to setup logon triggers to capture the client IP address and port and write it to table. I am unfamiliar with logon triggers and have read that they present dangers to the server.
What is the best way that I can discover who all is connecting to and using this server?
Running the stored procedure sp_who will tell you about the machines connected to a SQL server instance.

Check if external database is online

I know that this sentence tells me that 'MyDatabase' database is online:
select databasepropertyex('MyDatabase', 'Status')
What if I need to check a database from another server? Suppose that I already have a link server, the call should be like this:
select databasepropertyex('[192.168.111.33].MyOtherDatabase', 'Status')
but it doesn't work, anyone knows how to check this?
Thank you.
Might have to run as a pass through query, e.g.
OPENQUERY ( [192.168.111.33] ,'select databasepropertyex(MuOtherDatabase, ''Status'')' )
(assuming your already set up linked server is called [192.168.111.33], as implied above - seems like a dubious naming convention to use IPs?)
Normally, you would just try to connect to the database, and trap the error if the connection fails. But depending on your network setup and security, it might not be possible to connect directly to the database server. Exactly how you do that depends on what language and provider you use.
Some online examples of connection strings>
To see whether a SQL Server 2008 database can accept connections, look at the Collation property instead. I know how strange that sounds, but that's the documented way.
The ONLINE status may be returned while the database is being opened
and is not yet recovered. To identify when a database can accept
connections, query the Collation property of DATABASEPROPERTYEX.
For example, many database servers are set up to deny connections from all IP addresses except one. This is especially common in web-based setups; it's a fundamental security measure. In that case connecting like this (immediately below) would work. Code on the application server or web server tries to connect to the database server, and returns an error if it fails.
Your server --> Application server --> Database server
or workstation or web server
But connecting like this won't, because the database server is configured to accept connections only from the application server or web server.
Your server ----------------------------> Database server
or workstation
Application server
or web server