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.
Related
I want to grant exec permission to a user. This code returns no errors but then when I see the user properties I don't see the permission granted.
GRANT EXECUTE TO #USERNAME
The GRANT statement needs both an object and a principal. You only have a principal.
What do you want to allow the user to do - execute a single Stored Procedure or all stored procedures? The object would define that. For example if your stored procedure was named MySchema.MyProc then you would apply the permissions like:
GRANT EXECUTE ON MySchema.MyProc TO MyUser
To allow the user to execute any stored procedure in the MySchema schema then it becomes:
GRANT EXECUTE ON SCHEMA::MySchema TO MyUser
While testing your scenario, I also don't see the the permission reflected in the SSMS at the user level. However, here are three ways in which I can see the permission (I called my user foo because I pity the foo):
Impersonating the user and looking at database permissions:
execute as user = 'foo';
select *
from sys.fn_my_permissions(null, 'database');
go
revert
go
Interrogating the permissions table directly:
select *
from sys.database_permissions
where grantee_principal_id = user_id('foo');
Note - the way in which you're granting permissions grants it to anything (both now and the future) which can have that permission applied. That is, all stored procedures, functions, etc in the database. If that's not what you meant to do (i.e. you only meant to grant permission to one stored procedure), then you need to specify it in the GRANT statement. I only mention this because what you're doing technically works but in my experience is more the exception than the rule.
you need to grant permissions in the database where stored procedure were created, in sql server this option is located in db login --> right click --> new
I want to create three SQL Server database roles.
That can CREATE, ALTER and EXECUTE all stored procedures in database
That can only EXECUTE all stored procedures in database
That have no access to any stored procedures in database
I have created the roles, but I'm facing issues while REVOKE their permissions.
I have executed
REVOKE CREATE PROCEDURE TO [ROLE NAME]
to revoke the permissions to create the procedure and it executed successfully.
But I got error while executing this statement:
Error: Incorrect syntax near 'ALTER'.
I am very new to SQL server role rights so I might be completely wrong with my approach.
Please guide me to achieve my goal in correct way.
Thanks
From the documentation Create a Stored Procedure:
Permissions
Requires CREATE PROCEDURE permission in the database and ALTER
permission on the schema in which the procedure is being created.
Therefore just giving CREATE PROCEDURE on it's own won't allow you to create a procedure. In fact, giving a ROLE the CREATE PROCEDURE permission, and not ALTER on the schema will result in the below error:
The specified schema name "dbo" either does not exist or you do not have permission to use it.
There is no ALTER PROCEDURE permissions, therefore, for a member of a ROLE to be able to both CREATE and ALTER a PROCEDURE you would need to do:
GRANT CREATE PROCEDURE TO YourRole;
GRANT ALTER ON SCHEMA::dbo TO YourRole; --Replace with appropriate schema name
This, however, will also enable to user to ALTER anyprocedures on said schema. Ut also enable those in the role to ALTER other objects on the schema as well (such as tables) though.
If your ROLE has permissions to ALTER the procedures and you want to remove that, you would need to run the below:
REVOKE ALTER ON SCHEMA::dbo TO YourRole;
This will, as mentioned, also revoke their ability to ALTER any other objects on said schema.
Remember, REVOKE doesn't DENY, it simply means that the USER won't inherited that permission from that ROLE any more. If the USER has the permission from a different ROLE, or they have the permission themselves, they will be able to continue to use the permission. If you must stop a USER from performing an action, regardless of any other permissions, they must have the DENY permission.
1) That can CREATE, ALTER and EXECUTE all stored procedures in
database
That's the db_owner role, or the CONTROL permission on the database. Anyone with all those permissions can escalate their own privileges to a database-level admin. So don't try.
2) That can only EXECUTE all stored procedures in database
GRANT EXECUTE TO [SomeRole]
3) That have no access to any stored procedures in database
A user has no access to any stored procedure unless you grant permissisions or add them to a role that has permissions.
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
FYI: SQL Server 2005
I have a database user account (user_web) that has the ability to connect to and run queries and stored procedures in my database. Specifically, I have given the user the db_datareader and db_datawriter roles as well as granted them execute permission on the specific stored procedures it needs to be able to run.
In one of the stored procedures, I need to disable a trigger then re-enable it after some specific edits are done. When I attempt to run that stored procedure with the user I get the following error:
Cannot find the object "TableName" because it does not exist or you do not have permissions.
TableName is the table where I am attempting to disable and enable the trigger. My question is what is the least amount of permissions I can give to my user account that will allow it to successfully run the stored procedure.
The user will "at a minimum" require ALTER permissions on the table in question. See: http://technet.microsoft.com/en-us/library/ms182706.aspx
Rather than grant the user ALTER permissions on the table, which could be a security issue, I'd have that particular stored procedure run as a different user that does have those permissions. Use the EXECUTE AS syntax to accomplish this.
http://msdn.microsoft.com/en-us/library/ms188354.aspx
Is there a way I can give developers permission to grant a user permissions over objects without giving them the option to create users or functions?
I'm trying to limit developers permissions, I recently found out that developers had db_owner permissions in dev and prod environments! So I'm doing my best to stop this madness.
Any good article about this matter?
You can make them members of the "db_securityadmin" database role
As said, if someone could hand out permissions, they could hand out permissions to themselves (or a dummy account). I'm not sure if there is a trick in SQL Server to provide "give user permissions less then me".
The way I would do it is with stored procedures.
Create a stored procedure that gives a specified user a specific right or set of rights (those rights are the ones that regular users are allowed to have). Then give the developers execute access to this stored procedure. In effect you use stored procedures to create a limited version of GRANT, while keeping the full GRANT command to yourself.
If someone can give someone else permissions, he can also give himself the permission to do what he wants. So what is this good for? Probably I don't understand your situation.
Owners of objects can grant permissions on those objects. Provided your developers don't need to grant things like CREATE TABLE rights, you might be able to give them ownership of the objects that you want them to grant permission on.
As Stefan said, giving them grant permissions would effectively give them all permissions, since if they want to do something all they have to do is grant themselves the permissions to do it.
Rather than considering the developers the enemy, though, you may want to consider giving the developers a second user account that's used to administer the database. It's pretty common not to give developers ANY permissions to production, at least on their development account.
Setting permission on objects like stored procedures can be accomplished with "GRANT EXECUTE ON . to ;
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). The EXECUTE AS can be added to stored procs, 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 AS IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].MyTable') AND type in (N'U')) CREATE TABLE MyTable (PKid int, column1 char(10)) INSERT INTO MyTable VALUES (1,'ABCDEF')
GO
GRANT EXEC ON dbo.MyProcedure TO NoPrivUser; GO
-- Now log into your database server as NoPrivUser and run the following.
use dbadb go
EXEC dbo.MyProcedure
(1 row(s) affected)
Now try to select from the new table while logged on as NoPrivuser.
You will get the following:
select * from MyTable go
Msg 229, Level 14, State 5, Line 1 The SELECT permission was denied on the object 'MyTable', database 'DBAdb', schema 'dbo'.
That is expected since you only ran the procedure under the security context of Owner while logged on as NoPrivUser.
NoPrivUser as no rights to actually read the table. Just to execute the procedure which creates and inserts the rows.
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've found that the most dangerous aspect of the db_owner role is that if you issue a deny on a permissions, then the members of the role can grant it back to themselves. I've just started reading about this and I'm testing this
Create role db_ControlDatabase
grant control to db_ControlDatabase
deny backup database to db_ControleDatabase
alter role db_ControlDatabase add member TestUser
So far, I've found that the subject TestUser has permissions without being able to add or remove members of the fixed database roles. You should be able to deny whatever you need at this point like backup certificate, backup master key, etc.
Here is a list of permissions that can be denied or granted: