Help with Linked Server Error - sql-server

In SSMS 2008, I am trying to execute a stored procedure in a database on another server. The call looks something like the following:
EXEC [RemoteServer].Database.Schema.StoredProcedureName
#param1,
#param2
The linked server is set up correctly, and has both RPC and RPC OUT set to true. Security on the linked server is set to Be made using the login's current security context.
When I attempt to execute the stored procedure, I get the following error:
Msg 18483, Level 14, State 1, Line 1
Could not connect to server 'RemoteServer' because '' is not defined as a remote login at the server. Verify that you have specified the correct login name.
I am connected to the local server using Windows Authentication. Anyone know why I would be getting this error?

'Be made using the login's current security context' translates as impersonation (aka. as 'self-mapping' in SQL Server linked in terms). Access a remote server under an impersonated context means delegation. So you need to set up the constraint delegation, see Configuring Linked Servers for Delegation:
Requirements for the Client
The Windows user must have access permissions to SQLSERVER1 and
SQLSERVER2.
The user AD property Account is sensitive and cannot be delegated must not be
selected.
The client computer must be using TCP/IP or named pipes network connectivity.
Requirements for the First/Middle Server (SQLSERVER1)
The server must have an SPN registered by the domain administrator.
The account under which SQL Server is running must be trusted for delegation.
The server must be using TCP/IP or named pipes network connectivity.
The linked server logins must be configured for self mapping.
Requirements for the Second Server (SQLSERVER2)
If using TCP/IP network connectivity, the server must have an SPN registered by the domain administrator.
The server must be using TCP/IP or named pipes network connectivity.

run the following command, and it may fix it for you
exec sp_AddRemoteLogin 'YourServerName','LoginName'
I think (not sure) that the passwords have to be the same on both machines.

Related

Cannot connect Access to SQL Server Linked Tables - error message loggingin

I have a client for which I am setting up a new SQL Server Express and (on a different computer) connecting their Access front end to that SQL Server. I created an account on SQL Server, changed authentication to SQL Server. I am able to log on to that account with no issues locally (through SQL Server Management Studio) on the server itself, but when I go back to the client machine and try to create either an ODBC connection or connect directly in Linked Table manager, I get the error below. Looking at the error log in SQL Server I can see no failed logins. In Access and/or ODBC I use Servername\SQLEXPRESS, choose SQL authentication and type in the username/password that I created. But it's still being stubborn.
I'm kind of at my wits end with this one. I checked to make sure that login is enabled, that the created database is mapped to this user, but I'm out of answers. Anyone have any ideas? I'm sure it's something really stupid that I'm overlooking, I've used SQL Server for a long time but I'm not an experienced DB Administrator I'm sure it's something really simple I'm overlooking, but I've done this hundreds of times before. And Windows Authentication won't work because it's on a different computer.
To connect to a named instance on SQL Server Express with Servername\SQLEXPRESS, you need:
SQL Server Browser service running,
and its UDP port 1434 open in the firewall.
https://learn.microsoft.com/en-us/sql/sql-server/install/configure-the-windows-firewall-to-allow-sql-server-access
SQL Server Browser service
UDP port 1434
The SQL Server Browser service listens for incoming connections to a named instance and provides the client the TCP port number that corresponds to that named instance.
The fixed TCP port for your instance open in the firewall.
You set this in SQL Server Configuration Manager
https://learn.microsoft.com/en-us/sql/database-engine/configure-windows/configure-a-server-to-listen-on-a-specific-tcp-port
This looks more like a network setting rather than server issue.
Check if all necessary permissions, configuration and settings on your machine running the server are OK to accept external connections.
Usually its the server that is rejecting the connection for security reasons.

How can I give SQL Server permission to read my SSL Key?

I recently created a self-signed certificate and turned encryption on in SQL Server 2014:
The problem is that now the SQL Server service won't start:
This article from 2010 identifies the problem as a permissions issue: The SQL Server service does not have the necessary permission to read the SSL cert's private key.
The problem is that I am stuck on step 4 of the solution proposed in the article:
There is no group or user name matching the proposed format when I bring up the window shown in the article.
Is there another way I can determine the account that SQL Server service runs under, so that I can give it permissions to read the SSL cert?
An entirely different solution is welcome too.
If you specify the certificate, which should be used for TLS by SQL Server, then the SQL Server windows service have to read the certificate and the private key (the file from the folder %ProgramData%\Microsoft\Crypto\RSA\MachineKeys), which corresponds the certificate. The problem is: the SQL Server Configuration Manager in not comfortable and it makes not all the required work.
Thus first of all one should localize the Account used by SQL Server. One should start services.msc, find the account of SQL Server service. It's typically a build-in account like Local System, Network Service a local or domain account like .\SQLServer, DOMAIN\SQLServerAccount or an service account like NT Service\NT Service\MSSQL$SQL2012 on the picture below:
To grant permission on the private key to the account one can use Certificate Snap-In of mmc. One can start mmc.exe, choose "Add/Remove Snap-in" in the "File" menu, choose "Certificates" Snap-in and to choose "Computer account" of the Local computer. Then one should select the SSL certificate of Personal store and then use context menu "Manage Private Keys...".
and to add account like NT Service\NT Service\MSSQL$SQL2012, found above, and to set "Read" permission to the account on the private key:
If you would like to establish connection to the SQL server inside of the domain (both the client and the server have to belong to the same Active Directory or to the directories connected via the trust) then one should to create SPNs for the SQL server. If I correctly understand your requirements, you want to allow remove connection to SQL Server over HTTPS. One have to active mixed security to be able to connect to the server via SQL Server Authentication:
After creating SQL Login, making all above changed and restarting SQL Server service one will be able to establish TLS (encrypted) connection to the SQL server. In case of attempting to connect via Windows Account without creating SPN previously one get the error:
A connection was successfully established with the server, but then an
error occurred during the login process. (provider: SSL Provider,
error: 0 - The target principal name is incorrect.) (Microsoft SQL
Server, Error: -2146893022)
The target principal name is incorrect
If one forget to change Windows Authentication to Mixed authentication () then one will get the error like
Login failed for user 'OlegKi'. (Microsoft SQL Server, Error: 18456)
If all above steps done one can establish TLS connection using SQL Management Studio for example, but one still have to choose some options:
One should check "Encrypt connection"
and to set additional connection property TrustServerCertificate=true
Typically one use Encrypt=true;TrustServerCertificate=true; as the part of connection string in the application which establish the connection to SQL server. We set Encrypt=true property by the checkbox "Encrypt connection" describe above. More detailed about the meaning of the properties and different combinations of the options can be read in "Enabling Encryption" section of the MSDN article.
If one do all the above steps and check "Encrypt connection" without setting TrustServerCertificate=true property then one will get the error:
A connection was successfully established with the server, but then an
error occurred during the login process. (provider: SSL Provider,
error: 0 - The target principal name is incorrect.) (Microsoft SQL
Server, Error: -2146893022)
The target principal name is incorrect
which I already described above in a little another situation (connection with Windows account).
I described all above steps because configuration of TLS connection to the server is really not so easy and one can get strange errors, which direct description gives no direct tips how to fix the problem.
One other note: If you are entering the certificate thumbprint into the registry manually by copying and pasting from the certificate manager, you must remove the leading character. It is an invisible unicode character, but it will cause the SQL Server service to be unable to start if it is present. This is in addition to making it ALL CAPS, and removing all spaces.
I ran into this issue as well. What i was doing was:
Importing the certificate from the sql server protocol properties dialog, using the 'import' button. I imported the public key, then another open dialog opened to import the private keys. I then set the private key permission to the sql server service.
When importing a key pair directly, such as a .pfx bundle, the application crashed.
All permissions to MachineKeys were granted as well for the sql serive, but I could not find through process monitor any access denied for that path.
In order to solve my issue, i imported the pfx directly from the explorer. I first removed the key pair from the store, then I ran through the wizard to import the pfx in the local machine store, personal folder. I checked the permissions on the private key, they were still set for the sql service. I checked the protocol properties, the certificate was already selected. Only then the server started.

Cannot log in using SQL authentication ONLY from a remote server

I am trying to connect to SQL Server 2008 from a remote server using 'sa' username and its password (I can log in normally with this username and password from my own computer - so "SQL Server and Windows authentication mode" is chosen).
In the SQL Server log file on my computer I see this error:
Login failed for user 'sa'. Reason: An attempt to login using SQL
authentication failed. Server is configured for Windows authentication
only.
I thought it might be a remote connection problem, so I checked that the remote connection in the properties is enabled, in the configuration manager I enabled TCP/IP and Shared Pipes and restarted the service afterwards and I created a firewall rule for port 1433. I also tried to turn off the firewall in case that it is being blocked somehow, but I got the same error.
How this error appears only when accessing SQL Server from a remote server?
How can I fix it?
From the SQL Server management studio, right click on your server (after connect) in the Object Explorer window and choose Properties.
On Security item, make sure that SQL Server And Windows Authentication mode is selected.
The most obvious solution for me seems to allow SQL Server authentication on the server if it's really necessary to use sa for access (what it should not normally).
To answer the "why" we need more information. Which program do you use to access the server. Is the connection string really identical for both accesses?
Just guessing: From your local machine you use integrated security=true somehow (which causes user and password to be ignored), and your local windows user is allowed to access the server. From remote you use integrated security=false so that you can't logon using user/password, as the server is configured to only accept Windows authentication.
I had the exact same problem today. I was not able to connect to SQL server remotely using username/password, but it worked with windows authentication, and logging in locally also worked.
The reason it didn't work here was that I was using a password that was too short on the sa user. Apparently it does enforce password policy if logging on locally, but remote connections are blocked.
You can either change the password to a longer/more complex one, or disable the password policy enforcement for the sa user.
Short how-to:
In SQL Server Management Studio, open Security -> Logins, find "sa" -> Properties -> Change password or uncheck this box:
In my situation, I have SQL Server 2008 and SQL Server 2012 installed. So, in server name field, I need a concrete name (for example: 10.141.133.125\SQLServer2012). That's it!
Hope this useful for you!

SQL Server - Linked servers, querying one way is fine but the other?

I have two SQL Servers which have been linked using sp_addlinkedserver 'ServerB\Instance' from ServerA and sp_addlinkedserver 'ServerA\Instance' from ServerB.
If I execute the following query from ServerA then everything is okay:
SELECT *
FROM [ServerB\Instance].Database.dbo.Table
If I execute the following query from ServerB an error occurs:
SELECT *
FROM [ServerA\Instance].Database.dbo.Table
Error:
Msg 18456, Level 14, State 1, Line 1
Login failed for user 'NT
AUTHORITY\ANONYMOUS LOGON'.
The service accounts that SQL Server runs under on ServerA and ServerB have been given elevated permissions on both servers in an attempt to solve the issue but no success.
I have done research but want to avoid a convoluted process when communication one way is okay.
I have solved this by following the process:
Deleted both linked servers.
Executed sp_addlinkedserver for ServerA from ServerA RDP (SSMS) and for ServerB from ServerB RDP (SSMS).
Previously I had executed sp_addlinkedserver for both servers from the one server RDP (SSMS) session only. Executing from each server has solved the problem. If someone can add comments as to why this is then I will be very grateful.
In SQL Management Studio, view the properties for the linked server from Server B to Server A. There's a security "tab" that you can view from there. That will tell you the security context the connection from B to A is using. The error you are getting normally occurs when you don't have a valid security context set for the linked server.
The reason that it can work from A to B and not B to A is that you need to set up the linked server correctly on each side. Just doing it for one is not going to work to go both ways.
You have to map your local user to a remote user on the other server.
Do can do this by calling sp_addremotelogin() as explained here: http://msdn.microsoft.com/en-us/library/ms186338.aspx
To work around this problem, use one of the following methods:
Map the clients on server A to a standard security login on server B, by using either the sp_addlinkedsrvlogin stored procedure or the Security tab of the Linked Server Properties dialog box in Enterprise Manager.
If you are running the distributed query on an instance of SQL Server that is running on a Microsoft Windows 2000-based computer, configure SQL Server to listen for client requests by using the Named Pipes Server network library, instead of using the TCP/IP Server network library or the Multiprotocol Server network library. To configure the Server network libraries for SQL Server, use the Server Network Utility.
Take a look at:
http://support.microsoft.com/kb/238477

Integrated Windows authentication in IIS causing ADO.NET failure

We have a .NET 3.5 Web Service (not WCF) running under IIS. It must use identity impersonate="true" and Integrated Windows authentication in order to authenticate to third-party software. In addition, it connects to a SQL Server database using ADO.NET and SQL Server Authentication (specifying a fixed User ID and Password in the connection string).
Everything worked fine until the database was moved from SQL Server A to SQL Server B. (Neither was the same as the web server.) Then the Web Service would throw the following exception:
A network-related or
instance-specific error occurred while
establishing a connection to SQL
Server. The server was not found or
was not accessible. Verify that the
instance name is correct and that SQL
Server is configured to allow remote
connections. (provider: Named Pipes
Provider, error: 40 - Could not open a
connection to SQL Server)
This error only occurs if identity impersonate is true in the Web.config.
Again, the connection string hasn't changed and it specifies the user. I have tested the connection string and it works, both under the impersonated account and under the service account (and from both the remote machine and the server).
What needs to be changed to get this to work with impersonation?
EDIT:
Remus Rusanu pointed us in the right direction. It came down to Kerberos - the SPNs weren't set up for the new server. See also asp.net via kerberos integrated windows authentication to sql server. Thank you!
When using impersonation and accessing a resource on a different host, delegation occurs (what the laymen call 'two hops'). Since delegation is restricted by default, authentication fails, unless constrained delegation is explicitly enabled.
But wait, you says, I use SQL Authentication and SQL authentication is not an NTLM/Kerberos 'resource'. True, says I, but you also use NAMED PIPES and named pipes are an NTLM/Kerberos resource, therefore delegation does occur.
See How to: Configure Client Protocols to make sure SQL Server is listening on TCP and Configuring Client Network Protocols for how to force the client to choose a specific protocol (ie. not try named pipe first). You can also force TCP by simply appending tcp: in front of the server name in the connection string.
are you using impersonation in the web service itself?
Impersonation in web services operates on a different layer than IIS does. To get from client to web service, you can have identity=impersonate off and get the user token from ServiceSecurityContext, even with Anonymous mode on.
To impersonate that token in the web service, get the WindowsCredential from ServiceSecurityContext and call the credential.Impersonate() method in a using statement, placing your connection to the database inside the using block.
public class HelloService : IHelloService
{
[OperationBehavior]
public string Hello(string message)
{
WindowsIdentity callerWindowsIdentity =
ServiceSecurityContext.Current.WindowsIdentity;
if (callerWindowsIdentity == null)
{
throw new InvalidOperationException
("The caller cannot be mapped to a WindowsIdentity");
}
using (callerWindowsIdentity.Impersonate())
{
// Access a file as the caller.
}
return "Hello";
}
}
Also, if you need another leg in the process (i.e. the back-end service is on another server), you will need to use Delegation to propagate the credentials. You may also do this declaratively. See this article for full details: http://msdn.microsoft.com/en-us/library/ms730088.aspx
Since it worked when the SQL Server was on the same box, it could be connected to transactions.
It may be that it is trying to use the the MSDTC, and the impersonated users are lacking some rights.
Another thing that you could try is to log on to the web server with a user that you are trying to impersonate, and see if you can then connect to the sql server.
If Delegation is your problem, see this article for enabling constrained delegation
http://msdn.microsoft.com/en-us/library/ms730088.aspx
go to the very bottom to see how to set up an account for constrained delegation. I know its a WCF article, but the process for setting up an account to use delegation should be the same.
for even more details, go here
http://technet.microsoft.com/en-us/library/cc739587(WS.10).aspx
Alternatively, have your SQL server enable TCP access and access it that way, as Remus explained.

Resources