Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Permissions on tables are not checked if the tables and the procedure have the the same owner. This is called <a href="http://msdn.microsoft.com/en-us/library/ms188676.aspx" rel="noreferrer">ownership chaining</a>.</p> <p>Note that "ownership" in this context means "schema owner". For example, the table <code>TestDB.Schema1.Table1</code> is owned by the user that owns of <code>Schema1</code>.</p> <p>Because <code>Orders</code> has the same owner as <code>GetCustomerOrderInfo</code>, the stored procedure has implicit rights to read from <code>Orders</code>.</p> <p>But <code>Customers</code> has a different owner, so you have to grant permission on that explicitly.</p> <p>Here is a test script to demonstrate the issue:</p> <pre><code>use Test go if exists (select * from sys.syslogins where name = 'UserA') drop login UserA create login UserA with password = 'Welcome' if exists (select * from sys.syslogins where name = 'UserB') drop login UserB create login UserB with password = 'Welcome' if exists (select * from sys.syslogins where name = 'UserC') drop login UserC create login UserC with password = 'Welcome' if exists (select * from sys.tables where name = 'Customers' and schema_name(schema_id) = 'SchemaA') drop table SchemaA.Customers if exists (select * from sys.schemas where name = 'SchemaA') drop schema SchemaA if exists (select * from sys.sysusers where name = 'UserA') drop user UserA if exists (select * from sys.tables where name = 'Orders' and schema_name(schema_id) = 'SchemaB') drop table SchemaB.Orders if exists (select * from sys.procedures where name = 'GetCustomerOrderInfo' and schema_name(schema_id) = 'SchemaB') drop procedure SchemaB.GetCustomerOrderInfo if exists (select * from sys.schemas where name = 'SchemaB') drop schema SchemaB if exists (select * from sys.sysusers where name = 'UserB') drop user UserB if exists (select * from sys.sysusers where name = 'UserC') drop user UserC create user UserA for login UserA alter role db_owner add member UserA go create schema SchemaA authorization UserA go create user UserB for login UserB alter role db_owner add member UserB go create schema SchemaB authorization UserB go create user UserC for login UserC create table SchemaA.Customers (id int identity) create table SchemaB.Orders (id int identity, CustomerId int) go create procedure SchemaB.GetCustomerOrderInfo as select * from SchemaB.Orders o join SchemaA.Customers c on c.id = o.CustomerId go </code></pre> <p>When we're all set up, we can test the procedure with different permissions. First we'll need execute permission on the stored procedure, then read permission on <code>Customers</code>. After that, the stored procedure works, even though we did not grant read access on <code>Orders</code>.</p> <pre><code>execute as login = 'UserC' -- Login as UserC exec SchemaB.GetCustomerOrderInfo -- The EXECUTE permission was denied on the object 'GetCustomerOrderInfo', database 'Test', schema 'SchemaB' revert -- Revert back to our original login grant execute on SchemaB.GetCustomerOrderInfo to UserC execute as login = 'UserC' exec SchemaB.GetCustomerOrderInfo -- The SELECT permission was denied on the object 'Customers', database 'Test', schema 'SchemaA'. revert grant select on SchemaA.Customers to UserC execute as login = 'UserC' exec SchemaB.GetCustomerOrderInfo -- (0 row(s) affected) revert </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload