In the article “How To Authorize non-admin Logins To Read DMWs and DMFs“, I explained how to give dmw and dmf read privileges to logins.
However, with the authorization given in the related article, they can see queries from all databases in instance.
This is a security vulnerability if you have more than one database on the instance. In this article we will learn how to give enough authority to each application developer to see the queries requested from his own database.
First of all, let’s create a database named Test and create a login named TestLogin which is authorized in this database. The following articles will help if you don’t know how to do the related steps.
“How To Create a Database On SQL Server“,
“How To Create a Login On SQL Server(Manage Logins)”
First of all, we need a database with the TRUSTWORTH feature enabled on the instance. After you create the database, you can activate TRUSTWORTHY in your database but I do not recommend it. Because a TRUSTWORTHY-enabled database has been set reliably for SQL Server.
While this feature is active, someone with db_owner privilege in the database can execute a query through a user who has sysadmin privilege with the command EXECUTE AS.
In addition, “.NET” compiled code can be executed in a TRUSTWORTH-enabled database. This is a security vulnerability.
For these reasons, let’s create a new database for these processes. I set the database name as TRUSTDB (you can give another name).
Also, create a sql login named sysadminUser with sysadmin right on the instance.
Activate TRUSTWORTHY in this database with the following script.
1 | ALTER DATABASE TRUSTDB SET TRUSTWORTHY ON; |
Then, with the help of the following script, create a stored procedure for the related user to see only the queries requested from their database.
Instead of “sysadminUser” you must enter a login name with sysadmin right on your instance, and the database name of the corresponding login instead of TestDB. The relevant login will be able to see the queries that will be requested from the database you will be typing here.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | USE [TRUSTDB] GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE PROCEDURE [dbo].[QueryPerformance_For_Your_Database] WITH EXECUTE AS 'sysadminUser' AS select r.total_elapsed_time / 1000.0 as total_elapsed_s,percent_complete,r.blocking_session_id, r.last_wait_type,s.login_name,'thisrequests_sessionid=' + cast(r.session_id as varchar) SessionID, DB_NAME(r.database_id) as DatabaseName,command,SUBSTRING(t.text, (r.statement_start_offset/2) + 1, ((CASE statement_end_offset WHEN -1 THEN DATALENGTH(t.text) ELSE r.statement_end_offset END - r.statement_start_offset)/2) + 1) AS statement_text ,r.status,blocking_session_id,wait_time ,wait_type,wait_resource,text,start_time,r.percent_complete,s.program_name ,r.last_wait_type,s.host_name,r.granted_query_memory * 8 / 1024 as memory_mb from sys.dm_exec_requests r inner join sys.dm_exec_sessions s on r.session_id = s.session_id cross apply sys.dm_exec_sql_text(r.sql_handle) t where r.session_id <> @@SPID and (r.database_id=DB_ID('TestDB')) order by start_time asc |
You must give the execute rights to the user you want to authorize on the Stored Procedure.
First, we give public right to Testlogin(the user who will be execute this stored procedure) on the TrustDB database.
Then, right-click on the TrustDB and click Properties on the related stored procedure as follows.
You must give the execute rights to the user you want to authorize on the Stored Procedure.
First, we give public right to Testlogin(the user who will be execute this stored procedure) on the TrustDB database.
Then, right-click on the TrustDB and click Properties on the related stored procedure as follows.
On the screen that appears, click Permission tab and click Browse to select TestLogin as follows and click OK.
At the bottom screen, we click OK and we give Execute right as follows when TestLogin is selected.
We have authorized TestLogin to execute on a stored procedure that will only show queries reqeusted from database named TestDB.
To test in the next step, you can log in with TestLogin and run the stored procedure as follows.
1 2 3 | USE [TRUSTDB] GO EXEC [dbo].[QueryPerformance_For_Your_Database] |
You can make different examples with similar methods. For example, for another application developer, I created a stored procedure that shows locked queries.