Restricting a user to only have access in a ssis package - sql-server

We are running SQL Server 2016. For in-house political reasons, I can't restrict access the way I want to. Assume that I can't change the premise.
We have a user that is used in SSIS packages. Unfortunately, some devs are logging directly into the db with ssms using this user. I need to prevent this without changing the password or something. What I need is to be able to allow a user access to the database ONLY if it is running from an SSIS package and NOT if it is coming in any other way.
I am not looking for other suggestions of how to fix this issue. I understand most of them already, I am stuck because of management decisions that I cannot change.
Can anyone tell me how to restrict a user in such a way?

An approach is to use a LOGON trigger
A first blush approach might be to reject any process that look's like the SSMS application
CREATE OR ALTER TRIGGER logon_developer_check
ON ALL SERVER
FOR LOGON
AS
BEGIN
IF (ORIGINAL_LOGIN() = 'triskydeveloper'
and EXISTS
(
SELECT
*
FROM
sys.sysprocesses AS S
WHERE
S.spid = ##SPID
AND S.program_name LIKE 'Microsoft SQL Server Management%'
)
BEGIN
ROLLBACK
END
END
But developers, being devious little buggers, will then write their own .NET application or use SQLCMD so you'd fall into a rat race trying to identify all the program_names that might show up.
I would instead look at the hostname column on sys.sysprocesses - if the connection isn't coming from the server itself, just reject it. Unless you have to deal with developers able to RDP onto the server.
Oh and if you mangle the logon trigger and it's rejecting everything, use SQLCMD and the dedicated admin console, DAC, and
sqlcmd.exe -S localhost -d master -Q "DISABLE TRIGGER ALL ON SERVER" -A

Related

Login failed for user 'NT AUTHORITY\ANONYMOUS LOGON' - MS SQL Server - possibility of being unable to solve the issue

Why not asking on dba.stackexchange: the description says it is for professionals, which I am not and SO has its "for enthusiasts" part.
I have an error
"Login failed for user 'NT AUTHORITY\ANONYMOUS LOGON'"
This is a common error with several possible reasons and solutions. The problem is that I have no knowledge of the database and server administration and credentials authentication topics, thus I will need to spend some significant time understanding what is being said and proposed.
Before I do that I would like to ask if it might be possible for me not to be able to solve the problem due to technical limitations. I will describe the situation in more detail now.
There is an MS SQL Server A with database Adb and table dbo.At. I can read from it. There is also an MS SQL Server B. I can read and write here.
I have MS SQL Server Management Studio 2012 open on my computer. I have a connection with server A open with query "select * from Adb.dbo.At" which works just fine. The connection used Windows Authentication.
I have a connection with server B (Windows Authentication as well) with query "select * from A.Adb.dbo.At" which results in the aforementioned error.
At this point I do have read access to A, I have read and write access to B. I can export data from A and then import it to B using my computer, i.e. I can do a kind of a copy paste and I will end up having what I want. There is no insurmountable wall between these 2 servers with me being the middle man. I simply would like to make it easier. Before I dwell on SPNs, delegations, Kerberos, Active Directory and whatnot I would like to ask if, assuming that I have nothing more than read on A and read/write on B, I might not be able to solve the issue?
It seems I have a "double hop" problem.
https://blogs.technet.microsoft.com/askds/2008/06/13/understanding-kerberos-double-hop/
I have found a workaround. I can use Server Agent on server B. Using this I can use the server to perform some actions, for example query other servers. The Agent jobs are of a specific type (like T-SQL script). For specific job types the Agent can run the jobs in "run as" mode (requires a proxy). I created a proxy referring to my normal Windows login. Sadly T-SQL script type job cannot be executed in "run as" mode. But PowerShell type job can. PowerShell can also execute SQL statements. Thus I have created PowerShell job running with proxy with the command being:
SQLCMD -Q "select * into Bdb.dbo.Bt from A.dbA.dbo.At" -E
This solved my problem.

SQL Server Express edition - read-only database?

I'm having a very strange problem with a fresh install I have of SQL Server 2008 Express edition (yeah it's a bit old now, but whatever). When I connect via SQL Server Management Studio, I can both read and edit data (update or insert), but when I connect via my web application's data access layer, which uses SqlConnection and SqlCommand to try and update and insert data in tables, no changes occur in the database. The strange thing is that the code runs as if no error had occurred though; no exceptions are thrown, and my update statement causes SqlCommand.ExecuteNonQuery to return 1, indicating that supposedly 1 row has been updated. However, it hasn't. The application can, however, read data from the database via select statements.
Does anyone have any idea what's going on here? I even tried tracing SQL Server using ExpressProfiler, and its output seemed to indicate that the update should have occurred:
exec sp_executesql N'UPDATE Match SET TicketsSold=#ticketsSold WHERE MatchId=#matchId',N'#matchId int,#ticketsSold int',#matchId=1,#ticketsSold=1234
go
Yet TicketsSold stays at the same value (123) it was at before, and does not update to 1234. Is there some kind of "silent" read-only mode SQL Server 2008 Express could be running in? I'm baffled as to why the database isn't being updated.
By the way, this is a proper SQL Server database I created in SSMS, not some attached MDF file that resides in the same directory as my web application. The database is not set to "read-only" in database options, and I'm pretty sure that the user that the web application is logging in as has read/write permission on the MDF file; it is logging in as the same user I am logging in as using SSMS - with integrated Windows security - and I am able to update/insert as that user via SSMS.
Thanks to shf301 in the comments - I was creating a transaction but forgetting to call .Commit before the end of the using block. :-D I put that in and now it works.

Extreme wait-time when taking a SQL Server database offline

I'm trying to perform some offline maintenance (dev database restore from live backup) on my dev database, but the 'Take Offline' command via SQL Server Management Studio is performing extremely slowly - on the order of 30 minutes plus now. I am just about at my wits end and I can't seem to find any references online as to what might be causing the speed problem, or how to fix it.
Some sites have suggested that open connections to the database cause this slowdown, but the only application that uses this database is my dev machine's IIS instance, and the service is stopped - there are no more open connections.
What could be causing this slowdown, and what can I do to speed it up?
After some additional searching (new search terms inspired by gbn's answer and u07ch's comment on KMike's answer) I found this, which completed successfully in 2 seconds:
ALTER DATABASE <dbname> SET OFFLINE WITH ROLLBACK IMMEDIATE
(Update)
When this still fails with the following error, you can fix it as inspired by this blog post:
ALTER DATABASE failed because a lock could not be placed on database 'dbname' Try again later.
you can run the following command to find out who is keeping a lock on your database:
EXEC sp_who2
And use whatever SPID you find in the following command:
KILL <SPID>
Then run the ALTER DATABASE command again. It should now work.
There is most likely a connection to the DB from somewhere (a rare example: asynchronous statistic update)
To find connections, use sys.sysprocesses
USE master
SELECT * FROM sys.sysprocesses WHERE dbid = DB_ID('MyDB')
To force disconnections, use ROLLBACK IMMEDIATE
USE master
ALTER DATABASE MyDB SET SINGLE_USER WITH ROLLBACK IMMEDIATE
Do you have any open SQL Server Management Studio windows that are connected to this DB?
Put it in single user mode, and then try again.
In my case, after waiting so much for it to finish I had no patience and simply closed management studio. Before exiting, it showed the success message, db is offline. The files were available to rename.
execute the stored procedure
sp_who2
This will allow you to see if there is any blocking locks.. kill their should fix it.
In SSMS: right-click on SQL server icon, Activity Monitor. Open Processes. Find the processed connected. Right-click on the process, Kill.
In my case I had looked at some tables in the DB prior to executing this action. My user account was holding an active connection to this DB in SSMS. Once I disconnected from the server in SSMS (leaving the 'Take database offline' dialog box open) the operation succeeded.
anytime you run into this type of thing you should always think of your transaction log. The alter db statment with rollback immediate indicates this to be the case. Check this out: http://msdn.microsoft.com/en-us/library/ms189085.aspx
Bone up on checkpoints, etc. You need to decide if the transactions in your log are worth saving or not and then pick the mode to run your db in accordingly. There's really no reason for you to have to wait but also no reason for you to lose data either - you can have both.
Closing the instance of SSMS (SQL Service Manager) from which the request was made solved the problem for me.....
To get around this I stopped the website that was connected to the db in IIS and immediately the 'frozen' 'take db offline' panel became unfrozen.
Also, close any query windows you may have open that are connected to the database in question ;)
I tried all the suggestions below and nothing worked.
EXEC sp_who
Kill < SPID >
ALTER DATABASE SET SINGLE_USER WITH Rollback Immediate
ALTER DATABASE SET OFFLINE WITH ROLLBACK IMMEDIATE
Result: Both the above commands were also stuck.
4 . Right-click the database -> Properties -> Options
Set Database Read-Only to True
Click 'Yes' at the dialog warning SQL Server will close all connections to the database.
Result: The window was stuck on executing.
As a last resort, I restarted the SQL server service from configuration manager and then ran ALTER DATABASE SET OFFLINE WITH ROLLBACK IMMEDIATE. It worked like a charm
In SSMS, set the database to read-only then back. The connections will be closed, which frees up the locks.
In my case there was a website that had open connections to the database. This method was easy enough:
Right-click the database -> Properties -> Options
Set Database Read-Only to True
Click 'Yes' at the dialog warning SQL Server will close all connections to the database.
Re-open Options and turn read-only back off
Now try renaming the database or taking it offline.
For me, I just had to go into the Job Activity Monitor and stop two things that were processing. Then it went offline immediately. In my case though I knew what those 2 processes were and that it was ok to stop them.
In my case, the database was related to an old Sharepoint install. Stopping and disabling related services in the server manager "unhung" the take offline action, which had been running for 40 minutes, and it completed immediately.
You may wish to check if any services are currently utilizing the database.
Next time, from the Take Offline dialog, remember to check the 'Drop All Active Connections' checkbox. I was also on SQL_EXPRESS on local machine with no connections, but this slowdown happened for me unless I checked that checkbox.
SSMS, especially if running it from your own desktop remotely and not directly within the database server, can be a reason for the long delays in detaching a database. For some reason SSMS may not be able to disconnect any existing "connections" to the database.
We found the process was almost instant when we did it directly from the database server itself. And in fact it killed the attempt from my own desktop SSMS session, and it "took over" and detached the database.
Nothing else suggested here worked.
Thanks
In my case i stopped Tomcat server . then immediately the DB went offline .

Grouping sys.dm_exec_connections by database (it's not quite like sys.sysprocesses)

Following on from my last question:
I've written some code to upgrade a SQL Server database. Before I upgrade the database, I plan to limit access to the database with the following statement:
ALTER DATABASE Test SET SINGLE_USER WITH ROLLBACK IMMEDIATE
Before running this code, I'll give the user an opportunity to opt out. At the time of prompting the user, I thought it would be nice to show the list of active connections (continuously polled at a set interval); providing the user with a tool to identify applications/users they would like to boot off the server before proceeding.
In SQL 2000, you can use the sys.sysprocesses table to see all connections that apply to a database. This includes connections that have no active request (like when you open a Query Analyser window and select a database).
However, using:
sys.dm_exec_connections
sys.dm_exec_sessions; and
sys.dm_exec_requests
I couldn't figure out a way to achieve the same outcome. It appears that these views only tie connections to a database through a request. Is there a way to mimic the behaviour of sys.sysprocesses? I'd prefer not to use this table for SQL Server 2005/2008 databases.
Er... I recommended these for your other question.
Sorry, but, I've found out that you still have to use sysprocesses
It's logged as a bug in Microsoft Connect 144515 to be fixed, I found it here
Personally, I still use sysprocesses because I'm comfortable with it, however lazy and luddite that may be...

How to change MS SQLServer authenticated login without closing and reopening the connection?

I have a connection to a Microsoft SQL Server and want the change the connection authenticated user. Is it possible to do it without closing and reopening the connection?
The ideal is something like Oracle set role feature.
I'd love if the solution also works for SQL Server 2000.
You might want to take a look at app roles (sp_setapprole), but you must be aware of consequences being that once the context is changed (e.g. the role is set), it can't be reverted with SQL Server 2000 (it's possible with 2005). The result of this is that the connection is effectively useless when closed in your code, e.g. it can't be returned to the pool and reused, which leads to scalability issues.
Otherwise it is not possible to change the security context once it has been established.
As far as I know SQL Server is very distinct on the account that is passed is the authenticated context. Take Enterprise Manager and other tools for example you must disconnect and re-connect to change users.
Plus looking at the way connection pooling works, it indicates that the connection itself is cached user specific, so if you changed executing parties part way through it would cause major problems with security.
So the short answer, no, it isn't possible as far as I know.
Depending on what you are doing, EXECUTE AS may help you out here. This allows you to execute SQL in the context of another user in a similar fashion to the RUN AS available from the Windows shell. The profiler and audit tracing in SQL Server allows you to see both the original user and which context a statement is run under.
EXECUTE AS USER = 'newuser';
SELECT ... <-- SQL code from under the context of newuser
REVERT;
Note: This is not available under SQL Server 2000 and was added because of requests like yours.

Resources