I have a stored procedure Which we call it Test here.
For simplicity I modified the SP code to:
Select * from table A
I can run this SP without any issues.
Now if I use Dynamic SQL
#SQL='Select * from table A'
EXECUTE (#SQL)
I get
The SELECT permission was denied on the object 'A', database 'MyDb', schema 'dbo'.
What is different here?
Dynamic SQL has this restriction/limitation. When you use dynamic sql inside a stored procedure , even if the calling user has the permissions on the stored procedure , the user also need permissions on the tables/objects being called inside the dynamic sql .
You have two options
Do not use Dynamic sql at all.
Give the calling user permissions on the table being used inside the dynamic sql.
This error comes when the user does not have the sufficient privileges
to access your tables in the database. Do grant the privilege to the
user in order to get what you want.
Grant The Permission For Select statement(or any other if you want).
Related
I am getting the following error when trying to run a stored procedure:
The SELECT permission was denied on the object 'tblMarketContact_Type_link', database 'FMS', schema 'Marketing'.
The stored procedure was running fine before I included this table. It has execute permissions for the database role it is being ran under. It uses dynamic SQL.
I am guessing it has something to do with the stored procedure being in a separate schema from the table? The stored procedure is just in the dbo schema.
What is the best way to fix this? I would think simply granting select permissions on this table for the security role would be an easy fix, but I want to avoid that. I'd like for only the stored procedure to have permission to execute and select from that table.
You can use Grant statement on a role an use that role to execute a stored procedure like
Create Role xyz;
Grant execute on "your_stored_procedure_name" to newrole;
If you don't want to use a new role, then you can use grant statement for a particular schema.
Grant select on "your stored procedure name" to "user";
I have a C# Winform application that interacts with an SQL Server DB via stored procedures. In SSMS, how do I create a login that ONLY has permissions to run stored procedures? That login wouldn't be able to view/edit/create table definitions, etc. It would also only have access to a single specified DB.
The reason I want to create such a login is because I store the SQL Server credentials used by my Winform application in its App.config file. Since the app.config can easily be read, anyone with malicious intent can easily perform unwanted operations on the database if the given login had any other permissions than just stored procedures.
A neat trick in this scenario is to create a separate (custom) SQL Server role that can only execute stored procedures:
CREATE ROLE db_executor;
GRANT EXECUTE TO db_executor;
This role now has the permission to execute any stored procedure in the database in which it's been created - and in addition: that permission will also extend to any future stored procedures you might create later on in this database.
Now create a user in your database and give it only this database role - this user will only be able to execute stored procedures - any and all of them in your database.
If you user should be allowed to execute any and all stored procedures - this is a very convenient way to allow this (and you don't have to constantly update the permissions when new stored procedures are created).
You can use the following query in order to allow stored procedure execute permision to your user
USE [DB]
GRANT EXECUTE ON dbo.procname TO username;
However, in my humble opinion , you should secure the connection string in the app.config.
Maybe , this How to store login details securely in the application config file link can be helped to you.
The access to a specific database is done through creating a user on the database that you want him to operate on. You can find more infos about users here.
If the user is created you can Grant, With Grant and Deny actions for every single item on the database.
The user will then be granted/denied those rights by a grantor, which is the dbo by default.
You can use this to also deny him access to every item on your database that isn't your stored procedure, which is what you're looking for if I understand you correctly.
Try folloiwng approach (grant execute should be repeated for every SP). Note that MyStoredProcedure has to be in MyDatabase :)
-- create login to server
create login test_user with password = 'test';
-- create user mapped to a database
use MyDatabase
go
create user test_user for login test_user;
-- grant permission to execute SP
grant execute on MyStoredProcedure to test_user
I would like to have one script to remove the specific user group to execute all stored procedures on the specific database in SQL Server 2014. I searched the web and found the example at Grant Revoke Permissions On Stored Procedures in SQL Server. It looks like I need create the script for all stored procedure.
Also I found another website REVOKE Object Permissions (Transact-SQL). However I have no clue how to write it as one script for all stored procedure.
Also I tried to use the below script in the database, but the Sales group still has permission on the stored procedure.
revoke execute to [Sales]
Would anyone tell me what should I do?
I have a SQL user that I gave explicit Execute permission for a specific stored procedure. This stored procedure contains a truncate statement. The user is unable to execute that procedure and receives the error:
Cannot find the object TableName because it does not exist or you do not have permissions.
If I alter the stored procedure to use Delete instead of truncate the user can execute the procedure.
What do I need to do to allow the user to execute this stored procedure, without giving the user more access than necessary?
From MSDN:
http://msdn.microsoft.com/en-us/library/ms177570.aspx
"The minimum permission required is ALTER on table_name. TRUNCATE TABLE permissions default to the table owner, members of the sysadmin fixed server role, and the db_owner and db_ddladmin fixed database roles, and are not transferable. However, you can incorporate the TRUNCATE TABLE statement within a module, such as a stored procedure, and grant appropriate permissions to the module using the EXECUTE AS clause. For more information, see Using EXECUTE AS to Create Custom Permission Sets."
You can try this:
create procedure SpName
with execute as owner
as
truncate table TableName
go
Then assign permission to user
grant execute on TruncTable to User
truncate table Setting permission on objects like stored procedures can be accomplished with:
GRANT EXECUTE ON <schema>.<object> to <user>;
However, you may also want to grant security rights at both the login and user level. You will want to determine and grant ONLY the necessary rights for the objects that require access (such as execution). Consider use of the EXECUTE AS capability which enables impersonation of another user to validate permissions that are required to execute the code WITHOUT having to grant all of the necessary rights to all of the underlying objects (e.g. tables). EXECUTE AS can be added to stored procedures, functions, triggers, etc.
Add to the code as follows right within the Stored Procedure:
CREATE PROCEDURE dbo.MyProcedure WITH EXECUTE AS OWNER
In this case you are impersonating the owner of the module being called. You can also impersonate SELF, OR the user creating or altering the module OR... imperonate CALLER , which will enable to module to take on the permissionsof the current user, OR... impersonate OWNER, which will take on the permission of the owner of the procedure being called OR... impersonate 'user_name', which will impersonate a specific user OR... impersonate 'login_name' with will impersonate a specific login.
MOST of the time, you will only need to grant EXECUTE rights to stored procs and then rights are granted to all objects referenced within the stored proc.
In this way, you DO NO need to give implicit rights (example: to update data or call additional procs). Ownership chaining handles this for you. This is especially helpful for dynamic sql or if you need to create elevated security tasks such as CREATE TABLE. EXECUTE AS is a handy tool to consider for these.
This example may help clarify all of this:
Create a user called NoPrivUser with public access to a database (e.g. dbadb):
USE [master];
GO
CREATE LOGIN [NoPrivUser] WITH PASSWORD=N'ABC5%', DEFAULT_DATABASE=[dbadb],
CHECK_EXPIRATION=ON, CHECK_POLICY=ON;
GO
USE [DBAdb];
GO
CREATE USER [NoPrivUser] FOR LOGIN [NoPrivUser];
GO
NOTE: CREATOR OR OWNER OF THIS PROCEDURE WILL REQUIRE CREATE TABLE RIGHTS within the target database.
use DBAdb
go
CREATE PROCEDURE dbo.MyProcedure
WITH EXECUTE AS OWNER
truncate table MyTable
GO
GRANT EXEC ON dbo.MyProcedure TO NoPrivUser;
GO
-- Now log into your database server as NoPrivUser and run the following.
With the EXECUTE AS clause the stored procedure is run under the context of the object owner. This code successfully creates dbo.MyTable and rows are inserted successfully. In this example, the user NoPrivUser has absolutey no granted rights to modify the table, or read or modify any of the data in this table.
It only takes on the rights needed to complete this specific task coded WITHIN the context of this procedure.
This method of creating stored procedures that can perform tasks that require elevated security rights without permanently assigning those rights come be very useful.
I have restored a 2005 Database to a new 2008 R2 DB Server. I have created a new user called "gatekeeper"
However this user does not have access to the list of stored procedure in the database.
In a reporting application before running the query the report program is running the following procedure...
exec [Timesheet]..sp_procedures_rowset N'mp_GetTimesheetToPrint',1,N'dbo'
When run under gatekeeper user this returns no rows. However when run as sa it returns the procedure.
What is the minimum permission I need to give to gatekeeper for this procedure to work properly. It seems to be a problem with all system objects, none of them fail to run or give permission errors, they just return no results or subsets of the results.
Really struggling with this. Thanks in advance
Regards
Phil
I am honestly a bit confused by your description, so please let me know if I am off base here. You can try this below. It will grant execute access to all stored procedures. If you only need gatekeeper to have access to the one stored procedure, then just grant execute on that stored procedure. If the stored procedure is accessing data from other databases, you may need to grant permissions on the tables and such that it is accessing outside of its database.
CREATE ROLE db_executor
GRANT EXECUTE TO db_executor
EXEC sp_addrolemember 'db_executor', 'gatekeeper'