Can anyone help me with this problem please?
I have 2 databases on the same server, both owned by sa. A Windows login has permission to execute a stored proc in database A that selects data from a table database B. The stored proc and table are also both owned by dbo. The Windows login is a member of a Windows domain group that is a member of a database role in database A that has the permission to execute the stored proc, but it has not been granted or denied any permissions on database B directly. The login is able to execute stored procs in database A that use database A and other procs that access other databases that the login has permissions to already but when it attempts to execute this stored proc it generates the error "The server principal "" is not able to access the database "B" under the current security context." Cross database ownership chaining is enabled at the server level but the two databases have is_db_chaining_on = 0 in sys.databases.
Is it as simple as you have to enable cross-database ownership chaining at both the server and database level?
From memory if you enable cross-database chaining at the server level it is available for all databases, you do not have to specifically set it on the database level.
How did you set chaining on? For some system settings a restart is required, or you can run the RECONFIGURE command in a query window.
http://msdn.microsoft.com/en-us/library/ms176069(SQL.90).aspx
Related
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.
I've got 2 databases, let's call them Database1 and Database2, a user with very limited permissions, let's call it User1, and a stored procedure in Database1, let's call it Proc1.
I grant EXECUTE permission to User1 on Proc1; GRANT EXECUTE ON [dbo].[Proc1] TO [User1] and things worked fine as long as all the referenced tables (for SELECT, UPDATE ... etc.) are in Database1, although User1 does not have explicit permission on those tables.
I modified Proc1 to SELECT from a table, let's call it Table1, in Database2. Now when I execute Proc1 I get the following error: The SELECT permission was denied on the object 'Table1', database 'Database2', schema 'dbo'
My understanding is that SQL Server will take care of the required permissions when I grant EXECUTE to a stored procedure; does that work differently when the table (or object) is in another database?
Notes:
User1 is a user in both databases with same limited permissions
I'm using SQL Server 2005
There seem to be a difference when SQL Server checks the permissions along the permission chain. Specifically:
SQL Server can be configured to allow ownership chaining between specific databases or across all databases inside a single instance of SQL Server. Cross-database ownership chaining is disabled by default, and should not be enabled unless it is specifically required.
(Source: http://msdn.microsoft.com/en-us/library/ms188676.aspx)
Late to the party, but I recommend taking a look at signed stored procedures for this scenario. They are much more secure than granting users permissions to multiple databases or turning on database ownership chaining.
... To make it possible for a user to run this procedure without
SELECT permission on testtbl, you need to take these four steps:
1.Create a certificate.
2.Create a user associated with that certificate.
3.Grant that user SELECT rights on testtbl.
4.Sign the procedure with the certificate, each time you have changed the procedure.
When the procedure is invoked, the rights of the certificate user are
added to the rights of the actual user. ...
(From http://www.sommarskog.se/grantperm.html#Certificates)
Further documentation is also available on MSDN.
Be sure that the user is actually the same in both databases. Not just NAMED the same. Try deleting the user from both databases, then create the user under the SERVER users, and assign the appropriate permissions on each database from that single user account.
To expand on #Szymon's answer with updated text from Microsoft at the end of 2018:
Ownership chaining across databases is turned off by default. Microsoft recommends that you disable cross-database ownership chaining because it exposes you to the following security risks:
Database owners and members of the db_ddladmin or the db_owners database roles can create objects that are owned by other users. These objects can potentially target objects in other databases. This means that if you enable cross-database ownership chaining, you must fully trust these users with data in all databases.
Users with CREATE DATABASE permission can create new databases and attach existing databases. If cross-database ownership chaining is enabled, these users can access objects in other databases that they might not have privileges in from the newly created or attached databases that they create.
There is also mention about dynamic SQL and certificate signing for procedures like #Rozwel mentions in their answer.
(Source: https://learn.microsoft.com/en-us/dotnet/framework/data/adonet/sql/enabling-cross-database-access-in-sql-server)
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
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".
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.......