I've got a SSRS report that is calling a stored procedure in my database.
Locally everything works, I am connecting with Windows authentication locally to hit the database and there are no problems.
When the SSRS report is deployed it's set up to use a different login, and this login has the correct role to grant execute on stored procedures. However, when trying to view the report on SSRS server I get this message:
Cannot find the user 'dbo', because it does not exist or you do not have permission.
If I remove the role that allows the grant execute rights I get a more specific error saying that I don't have permission to execute the stored procedure. But once this role is put back on the user account SSRS runs as it goes back go showing an error
Cannot find the user 'dbo'
The role I have that is granted execute rights is granted by 'dbo' user, this is the database owner. I have found things online saying that it's possible that a database backup messed up some user logins. I have checked, and the database owner sid is the same as the sysuser sid for name = 'dbo', so I do not think this is the problem.
Does anyone else know what I might be able to try?
EDIT: Details on stored procedure: it is a simple select with some inner joins.
At the end of the stored procedure is the following, granting access to the role my SSRS user is part of:
GRANT EXECUTE
ON OBJECT::[dbo].[Application_LoadData] TO [SSRSUserRole]
AS [dbo];
A stored procedure includes all statements in the batch after the CREATE PROCEDURE. So a proc like this
CREATE PROCEDURE USP_FOO
AS
BEGIN
SELECT * FROM FOO
END
GRANT EXECUTE ON USP_FOO TO SOMEUSER AS DBO;
Will attempt to execute to GRANT every time the procedure is run, and will fail when not run by dbo.
The script to create the procedure should have a batch separator before the grant. eg:
CREATE PROCEDURE USP_FOO
AS
BEGIN
SELECT * FROM FOO
END
GO
GRANT EXECUTE ON USP_FOO TO SOMEUSER AS DBO;
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 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 created some stored procedures and I am trying to execute them within a web application. To endure the security I have created SQL Server users, logins roles and permissions.
Then I grant the execute permission to the rule and give that rule to a specific user. My problem is for example if I grant execution on StoredProcedureA to roleA and the StoredProcedureA uses a select on a tableA I got the error
SELECT permission was denied on the object '[tableA]'
The error is easy to fix: I have to grant select on that table.
But since I am using many procedure in my project, it's hard to make the modification for each one. Is there a way to configure SSMS so that If I grant the execute on a procedure to a role, that role will have automatically all the permission on the actions (select, insert, update, delete) that are in that procedure?
Thanks
Can you alter your procedure to include the EXECUTE AS clause?
Example:
ALTER PROCEDURE sprocName...
EXECUTE AS dbo -- high level example
...
This would allow you to only grant your users and roles the ability to execute the procedures but the procedures the ability to do what it needs to, be that select, insert, update, etc.
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.