How do I grant a database role execute permissions on a schema? What am I doing wrong? - sql

I am using SQL Server 2008 Express edition.
I have created a Login , User, Role and Schema.
I have mapped the user to the login, and assigned the role to the user.
The schema contains a number of tables and stored procedures.
I would like the Role to have execute permissions on the entire schema.
I have tried granting execute permission through management studio and through entering the command in a query window.
GRANT EXEC ON SCHEMA::schema_name TO role_name
But When I connect to the database using SQL management studio (as the login I have created) firstly I cannot see the stored procedures, but more importantly I get a permission denied error when attempting to run them.
The stored procedure in question does nothing except select data from a table within the same schma.
I have tried creating the stored procedure with and without the line:
WITH EXECUTE AS OWNER
This doesn't make any difference.
I suspect that I have made an error when creating my schema, or there is an ownership issue somewhere, but I am really struggling to get something working.
The only way I have successfully managed to execute the stored procedures is by granting control permissions to the role as well as execute, but I don't believe this is the correct, secure way to proceed.
Any suggestions/comments would be really appreciated.
Thanks.

There are couple of issues that I can see in your case.
First of all you would need View Definition granted for you to be able to see the objects in the Management studio.
I would recommend this if you want the role to have all permissions,
GRANT EXECUTE, SELECT, INSERT, UPDATE, DELETE, VIEW DEFINITION
ON Schema::SchemaName TO [RoleName/LoginName]
Also make sure the owner of your user-defined schema is "dbo".

Related

SQL Server stored procedures and permissions with other databases

I am configuring the database accounts for some new users. I have come up with the following solution which is 99% of the way to getting the accounts to work but I have hit a problem which I cannot resolve.
Firstly, I created a new login with SQL Server authentication and then gave them the EXECUTE permission to all stored procedures. This allows them to run them all but they cannot view the code and they cannot view the database tables.
Inside the stored procedures I added the following:
WITH EXEC AS OWNER
This allowed the stored procedures to run as the default account we normally use and this has the role of db_owner. This allows the new users to run all the stored procedures and it works great until I hit the following problem:
Some of the stored procedures (all of which are using dynamic SQL) call some synonyms which link to tables in two other databases (history and a data mart database). This gives me the following error:
The server principal "{username}" is not able to access the database "{database name}" under the current security context.
The account which I am using in the WITH EXEC AS is the db_owner of all three databases I am working with.
What can I do to resolve this problem? Many thanks
EXECUTE AS Owner is a database sandbox. Think about it, it has to be. Otherwise a database administrator can issue and EXECUTE AS USER = 'somesystemadmin' and elevate himself to an instance level administrator. The details are described in Extending Database Impersonation by Using EXECUTE AS:
when impersonating a principal by using the EXECUTE AS USER statement, or within a database-scoped module by using the EXECUTE AS clause, the scope of impersonation is restricted to the database by default. This means that references to objects outside the scope of the database will return an error.
The solution is simple: sign the procedure. See Call a procedure in another database from an activated procedure for an example. Read more at Module Signing and Signing Stored Procedures in SQL Server.

Does GRANT EXECUTE to a stored procedure give you permission to access all objects inside it?

I have a procedure which selects data from a table in another database and also uses sp_send_dbmail. It seems execute permission is denied on cross database calls inside the procedure.
Can someone confirm that I need separate permissions on these cross database objects too or is there any way to grant execute permission so it can access anything under that proc?
This is the SQL statement for granting execute permission:
GRANT EXECUTE ON OBJECT::uspAppStoredProcedure TO AppRole;
This is the error I got:
The EXECUTE permission was denied on the object 'sp_send_dbmail',
database 'msdb', schema 'dbo'.
I got a similar error for trying to select data from another database.
This behavior is controlled by the cross db ownership chaining option in SQL Server, which is disabled by default.
uspAppStoredProcedure is attempting to execute a stored procedure outside of its ownership chain, so it would need explicit permission granted to execute the sp_send_dbmail.
It would be possible to enable ownership chaining on the databases involved, which would remove the need for granting specific permissions, but doing so would present a security risk... so it would likely be better to grant explicit access as needed.
This article goes into additional details on cross database ownership chaining.
Another potential solution would be to make use of the EXECUTE AS clause when defining the stored procedure, which would allow you to execute under the context of a different user as described in this article.
This would allow you to create a stored procedure that would allow specific users to execute it while avoiding having to grant permissions to the underlying objects directly to the users.

Run xp_create_subdir without admin privilidges

The Point: I want to be able to create a directory on the filesystem through a non-sysadmin SQL user.
I'm creating a web front-end for a deployment script which creates new databases from a specified template database.
Essentially I'm backing up said template database and then restoring this as a brand new database with a different name.
Our DB server has our client databases stored in sub-folders within our database store. If I were to use the default settings it would look something like:
D:\Microsoft SQL Server\MSSQL10.MSSQLSERVER\MSSQL\DATA\[ClientRef]\[ClientRef].mdf
D:\Microsoft SQL Server\MSSQL10.MSSQLSERVER\MSSQL\DATA\[ClientRef]\[ClientRef].ldf
I only have SQL access to the database server (via a programming language, hosted on a separate box) so I can't execute anything other than SQL.
My database user is extremely limited, however I would like to somehow grant this user to access/execute master.dbo.xp_create_subdir only. Is this possible at all?
I'm loathe to give our local DB user sys-admin rights, it has a limited user for a reason.
DB Server is Microsoft SQL Server 2008 R2.
Cheers, any help will be appreciated.
One possible solution is to write your own sproc that internally uses master.dbo.xp_create_subdir.
Create the sproc while logged in as an account that's a member of the sysadmin role and use "WITH EXECUTE AS SELF". Then grant permissions to that other account to execute this sproc. The database catalog where you create this wrapper-sproc must be marked as "trustworthy" or you'll still get the: User must be a member of 'sysadmin' server role. error.
E.g.
CREATE PROCEDURE [dbo].[sprocAssureDirectory] #directoryFullPath varchar(4000)
WITH EXECUTE AS SELF
AS
BEGIN
EXEC master.dbo.xp_create_subdir #directoryFullPath;
END
Just make sure you add any needed assertions/checks to your sproc that make sense for your application (e.g. the path can only be of a pattern that you expect).
Belated Update: Added the critical mention of marking the catalog as trustworthy.
You could give access for the user to use that stored proc explicitly. It is gonna be something like:
GRANT EXECUTE ON OBJECT::master.dbo.xp_create_subdir
TO <SQL USER>;
It sounds like that user is limited for a reason though and getting the extra permissions to run something like that can get a little push back from whoever is managing the DB. So be careful when dealing with getting the elevated privledges.

User can create but not execute stored procedure

Problem
I have a SQL Server login that is allowed to create stored procedures, but not execute them. I cannot use another login to grant execute so I am looking for an alternative way to either run the code in the sp or to grant these permissions.
The EXECUTE permission was denied on the object 'sp_mystoredprocedurename', database 'mydatabasename', schema 'dbo'.
The user cannot grant execute to itself
Cannot grant, deny, or revoke permissions to sa, dbo, entity owner, information_schema, sys, or yourself.
Background
We have a Windows software application, written in Powerbuilder, that creates and updates the SQL Server database it works on itself.
On first startup the application prompts for a database admin login which it uses 1 time (we don't store this information) to create the database and a login. The login is given db_ddladmin, db_datareader and db_datawriter permissions. We currently have hundreds of these applications and databases running on servers managed by us, but also on our customers' own servers.
For this reason I would do anything to prevent the need to ask the user for a db admin login again so I can grant the execute permissions, which would be the easiest way... Downgrading all servers to SQL Server 2000 is of course also not an option :)
The stored procedure I am trying to implement is a "getnewid" method. Currently my Powerbuilder code uses multiple embedded TSQL statements to achieve this but because of network performance issues I would like to move these to a single stored procedure.
Does this help ?
CREATE ROLE db_executer
GRANT EXECUTE to db_executer
EXEC sp_addrolemember N'db_executer', N'<username>'
Try this.
GRANT EXECUTE ON sp_OACreate to UserLogin
GO

Transfer permissions from one domain to another in SQL Server

At the bottom of most of our stored procedures we have a grant similar to
GRANT EXECUTE ON [dbo].[uspFOO] TO [DOMAIN\SQLServerUsers]
Luckily for me, our domain is changing and we now need to go through and change the permissions. Does anyone know of an easy way to do this using the DB metadata so I can pull out all the places where [DOMAIN\SQLServerUsers] is given permission to run and substitute it with [DOMAIN2\SQLServerUsers]?
Thanks.
For those asking, this is on SQL Server 2005.
What version of SQL Server are you on??
In 2005 and up, you could
create a new database role "db_executor" and do
GRANT EXECUTE TO db_executor
grant that database role to all necessary users
This will create a "catch all" role that has execute rights on every existing and future (!!) stored proc in your database. Yes, that does include future stored procs, too! Very handy indeed (at least as long as every user is allowed to execute all stored procs)
That way, you don't have to create separate GRANT EXECUTE statements for each and every stored proc.......