Can you protect linked servers from sa - sql-server

We have a third-party vendor setting up software on a server. They have full access to that server and the sql-server on it with the sa account. We would like to set up a linked server so that a trigger can update data on a remote machine. Does access to the sa account necessarily mean that they have full access to the linked server or is there a way to protect yourself from sa?
EDIT: We wanted to give them full control of the server because we want them to have full responsibility. It takes the blame off us when it stops working. "hey, we didn't touch it, you fix it, you have full permissions". That way, they can do whatever they need to to get their software working, but it's in a sand boxed environment. We just need a trigger to get the final records out of their database and insert into our production database. That requires permissions we don't want to give them. The question was meant to ask if there was a way to save the password in that sand boxed environment under there noses. so to speak.

Never give anyone access to the SA account.
Instead, give them a named user account even if it still has full system level privileges.
Second, the linked server is going to be set up with a named user that is allowed to impersonate a named user on the other end. If they have an account with full privileges on the first server then they will be able to get to the other. It's as simple as changing the password of the user account that is granted access to the remote server.
Which brings us to another item: Never give an external entity full rights to anything unless they OWN the box. If, for some weird reason, you have no other choice then you should find an alternate way of transferring the data from this server to your production server.
One way would be to set up SSIS packages that drop the data in a directory the remote server will monitor for pickup. Sure this adds a bit more complexity, but in the end it will mean your stuff is still secure.
Finally, Linked Servers are notorious for being flaky in general. You are much better off finding a different way to transfer the data... Such as using the SSIS method.

You can set up the linked server to use a named user -- your third party contractor will still be able to see "the other end" of the link, but only with the rights granted to that named user.

Related

Setting up access to SSRS report requiring login to data source

I have a report that accesses sensitive data and I'm required to have the user log in to the SSRS portal and then again into the data source to make sure the data isn't viewed by the wrong staff.
I feel like I've tried everything at this point, but no matter what I try I cannot access a data source by logging in to it from an SSRS report. I've tried:
Logging in with a windows authenticated db_owner account. Produces "Cannot create a connection to data source" error without any other info.
Logging in with a SQL authenticated account with select permissions to the view used by the data source with the same result.
Using current users credentials, same result.
I've enable remote errors on SSRS, but cannot locate a log of errors and the errors produced on SSRS portal have not changed.
I've read just about every tutorial about creating logins and users and how to set them up to access data sources.
Voodoo
Psychics
Therapists
All users have access through to the data when i run a select statement in SSMS, so I'm stumped. I've messed around with giving explicit rights to Connect, Select, Authenticate for the Server, DB, view and still no luck.
Are your users in Active Directory, or are you using SQL Authentication? Because if your users are in AD you can do this easily. I think you need the SSRS in Native Mode not SharePoint mode too, but I'm not 100% certain about that.
Create an AD group to hold privileged users, I'll call it
MyOU\SSRSViewers
Put all the users who can access this sensitive data in this group
In SSRS, in the security settings for the reports, data sets, and
data sources, give this group read or read/execute permissions
In the database create stored procedures to access your sensitive
data (you can give data_reader access instead, but if you want to
lock down data then access through stored procedures is much easier
to control).
In the database, create a USER for the MyOU\SSRSViewers group. At
the server level users need PUBLIC role, this lets them see the
server at all. They probably already inherit that from elsewhere,
but if not you can tie it to this group, too.
Grant EXECUTE permission on those stored procedures to the
MyOU\SSRSViewers user (it's a group, but it looks like a user in
SSMS, don't worry)
Create or modify your report data sources to use WINDOWS
AUTHENTICATION method and data sets to call the stored procedures to
get the data instead of SELECT statements.
Make sure you don't have any explicit deny permissions on the data
in question, or if you do at least test them very carefully, because
they can mess up this access (by denying access to somebody who
should have it, not by leaking your data)
If you do all this, here's how access works - when a users first goes to SSRS to view a report, SSRS will check to see if the user has permission to see the (empty) report. If they are in the group (or have permissions another way, so this is hard for a developer to test on their own machine) they get the empty report.
SSRS then checks the data source (which has no credentials!) to see if they can use it. Again, if in the group, yes. They still don't have data, but they can get the connection details. If they can, SSRS will pass a token from their windows session to the database to see if they can actually get the data.
If they make it this far, SQL will only let them execute the stored procedure (and get the data) if they are in that group with EXECUTE permissions on that stored procedure.
The users don't see these logins, the browser is automatically forwarding their login tokens (not credentials), but authorization is checked at every step and is very secure.
A few notes:
First, your SSRS server has to be in a trusted zone for this to work smoothly, if it is then the browser will pass authentication tokens to SSRS seamlessly. If not, they'll have to "log in" to SSRS every time, which gets old fast. Set this with your Group Policy.
Second, some configurations may include 2-hop authentication, a problem for ordinary NTLM. You may need to set up Delegated Constraints to make this work smoothly.
I didn't do either of these myself, but we had to do both at my company. Neither was particularly painful (or at least the guy who did it didn't complain), but I couldn't tell you how to do either, and I may not be using the ideal descriptions/terms.
Third, this scales well, if you have 3 different types of reports, you can create 3 different groups and your users can be in any combination of groups, getting access to only the data relevant to the groups they are in.

How to give read and write permissions to a user to my database?

I am looking for a way to guarantee read and write permissions to my database to another user in my network.
I know Microsoft SQL Server Management lets my add users by right clicking on the user section
here
and filling this
form.
Still, I am not sure what my Login name should be. For example, If I want to guarantee permission to the Administrator of a computer named GOR-PC, what should I enter?
Many Thanks.
You should use GOR-PC\Administrator.
However, adding local users to your SQL Server is generally a bad idea.
Ideally, you should use Active Directory users (in the form DomainName\UserName). This guarantees that the permissions you grant are independent of the existing of a PC or server.
First you should create a user or group for the administrator on the server level that is under the general "Security" tab below the dabases: Security->Login->create.
After tahat you can use the same login name you just created under the specific databse and Beowse the user and after that give the user read and write permission.
Hope that helps.

Find source of SQLserver login error

We have SQLserver2008 and the error log is filling up with these lines:
Login failed for user 'user1'. Reason: Failed to open the explicitly specified database. [CLIENT: xxx.xxx.xx.xxx]
We use user1 many places on many web-applications (classic asp). There must be some faulty password somewhere. All the applications seem to be working fine. We are getting hundreds of those messages per day.
We do know the ip-of source computer but there are thousands of classic asp-scripts. How to trace the one causing the login errors?
Your error does not indicate a password error. It instead indicates that the SQL login specifies a database that the login should open, or the connection string specifies a database to open.
However, the database you're trying to open either does not exist, or the login has no permission to access the database.
Suggested Diagnosis Procedure
Can you open 'user1' in management studio by right clicking it and viewing its properties? If so, on the General page, see if there is a default database specified. Then on the User Mapping page, ensure that the login has permissions to said database.
If it does, then the connection string specifies a database to open, and User1 has no permissions or the database does not exist.
To test if the database exists without checking each and every database, you could go one-by-one through the database and give user1 db_datareader permissions until the errors stop. Please don't simply assign user1 a sysadmin role to test this, since that is a real security danger.
If you cannot make the errors disappear by giving db_datareader permissions to other user databases, then the connection string is trying to open a non-existent database.
Prevention
I encourage you to eliminate this User1 login ASAP, and replace it with well-designed integrated security. IIS application pools can be assigned a domain user, and those user(s) can be given SQL logins with tailored permissions.
If you cannot do that, then set up SQL logins for each web-app with tailored permissions and change those connection strings one-by-one. The project may be laborious, but the user1 login is a serious security vulnerability, especially since you don't have control over its use at this time.
At the same time, the connection strings in a classic ASP application should be moved into global.asa and administered there so that you have one connection string (or set of connection strings) for each app, rather than individual ASP scripts all containing 1,000 redundant strings (which is what it sounds like to me).
Not trying to be preachy, but this is a problem I see all the time.
I can't see how there's any other way than searching all the files for everywhere where user1 is used and compare the lines (personally if I had thousands, I'd write a program to search a folder and sub folders and return the whole string of the line the match was found on. As it's at the point of connection it makes it hard to narrow down to which script and all scripts using the same user will produce the same error.
EDIT: Actually, as you know what the password should be, you could check the line and if it doesn't contain the correct password then it's going to error.
Regards
Liam

SQL Server Execute As Requires Individual Logins

Evening,
I would like some practical confirmation in relation to an issue we are having.
We have a K2/SourceCode solution that turns upon the successful use of EXECUTE AS with Sql Server 2008 R2.
We have no direct control over how this solution is implemented, i.e. we cannot modify the queries that are submitted to the Sql Server engine. We can, of course, capture them using Profiler, and they tend to follow this pattern:
DECLARE #cookie VARBINARY(100);
EXECUTE AS LOGIN = 'DOMAIN\username' WITH COOKIE INTO #cookie;
SELECT #cookie;
exec [dbo].[SomeStoredProcedure] /* ... various params ...*/
exec sp_executesql N'REVERT WITH COOKIE = #cookie;',N'#cookie varbinary(100)',#cookie=/* some cookie value */
So what is happening is that [SomeStoredProcedure] is being executed in the security context of the user [Domain\username], with the service (application) account impersonating that user. Again, I emphasise that we have no control over this pattern. That's what the app does.
Outwardly this behaviour is perfectly-desirable, because we want things arranged in such a way that the stored procedure is effectively executed by whichever user is at the front-end of the application at the time.
However, these queries were consistently failing, and our investigation eventually led us to this, from the Sql Server documentation (my emphasis):
Specifying a User or Login Name
The user or login name specified in EXECUTE AS must exist as a principal in
sys.database_principals or sys.server_principals, respectively, or the
EXECUTE AS statement fails. Additionally, IMPERSONATE permissions
must be granted on the principal. Unless the caller is the database
owner, or is a member of the sysadmin fixed server role, the principal
must exist even when the user is accessing the database or instance of
SQL Server through a Windows group membership. For example, assume the
following conditions: CompanyDomain\SQLUsers group has access to the
Sales database. CompanyDomain\SqlUser1 is a member of SQLUsers and,
therefore, has implicit access to the Sales database. Although
CompanyDomain\SqlUser1 has access to the database through membership
in the SQLUsers group, the statement EXECUTE AS USER =
'CompanyDomain\SqlUser1' fails because CompanyDomain\SqlUser1 does not
exist as a principal in the database. If the user is orphaned (the
associated login no longer exists), and the user was not created with
WITHOUT LOGIN, EXECUTE AS will fail for the user.
We have a group of around 30 end users who need to be able to use this application, and the requirement is that the application security account must be able to impersonate any one of those users for the execution of these stored procedures. This requirement is fixed and non-negotiable.
The above documentation seems to preclude the possibility of meeting this requirement by adding all 30 users to an AD group, adding that group as a SQL Server login, and granting the group adequate permissions. And our practical testing results support this - EXECUTE AS fails.
Take one of those Users and give them their own, individual AD login on the Sql Server and the solution will work successfully for that user. EXECUTE AS succeeds, and the necessary permissions do not need to be assigned to the individual account because they have already been assigned by way of the AD group.
So, at this point, I am reasonably confident that I know what I am going to have to do. The requirement will be that every user has to have their AD account added as an individual Sql Server Windows login.
However, before I proceed with the rigmarole of implementing this, I wanted to ask the question publicly: is there something I am missing here?
It's instructive to imagine a similar scenario on an Enterprise-scale application - this model would somewhat fall apart, because of the need to add hundreds of individual, Windows-authenticated, Sql Server logins. Setting aside the possibility of automating this process, and the administrative burden that would ultimately result, I'm just finding it a bit of a stretch to imagine that this is the only way.
I would be grateful for confirmation and/or comments.
Thanks
Robert
As no-one has responded to the contrary (or indeed at all) we have assumed that BOL is accurate, and that there is no alternative resolution.

Allow remote connection only for specific users

I just enabled remote connections on my SQL Server Express 2012 installation. Now I am a little bit worried about the server security because allowing connections to everybody sounds like a big security hole for me.
Is it possible to tell the SQL Server to disconnect if the user is trying to authenticate with a user which is not on my "allow" list? If so, I could add my monitoring user to this list and don't have to worry that my administration accounts are accessible.
First of all, this is probably a question that should be asked in the DBA site. Anyway, you can set up the security of the server so that only certain users are allowed to login.
When you set up the server, you add Logins to the Server Level and then Users at the database level. Only the users that are setup can, obviously, use a particular database. You can place users into roles, so, for example, they will have read-only access to a database. You can control, down to the object level, who has access to what.
There is a good article on what SQL Server security is about here
Having said that, sometimes, after, you have setup your security, you need to disallow certain users to not be allowed to Logon. Perhaps you are doing some major upgrade to the database. One option in this case is to create a Logon trigger.
A Logon Trigger will fire every time a user Logs in. You could create a table of "allowed" users and, in the trigger, if they are not in the table you ROLLBACK, effectively disallowing the Logon.
Here is information about creating a Logon trigger
You should be able to set up the db server to only accept connections from certain IP addresses, rather than to all of them. I'm unsure of the T-SQL syntax, but someone will surely chime in with the correct one.
If you really mean business, that being said, you'll want to authenticate clients using certificates that you give them. See this and the various articles it links to:
https://security.stackexchange.com/questions/14589/advantages-of-client-certificates-for-client-authentication
Being able to connect remotely to a SQL Server instance does not mean that they can Login to it. If they are not authorized properly, they should still get kicked-off by the SQL Server Login Authentication sequence.
This is silent/invisible for "Trusted Logins" (where the authorization comes from their Windows Login/Domain Account), but it still happens.
If you look under the "Security" folder of your Server (in SSMS), you will see the list of authorized Logins to you SQL Server. By adding or removing these you can control who can actually create a session on your SQL Server.

Resources