views:

35

answers:

3

Hello,

I am testing the permissions in mssql and run into a problem. I've made a 'Countries' table and a 'spCountries' Stored procedure. Now I've made a user 'silverlight' and gave it no rights to the Countries table. The user can execute the stored procedure.

Now when I do a Select it fails like it should, but in a exec spCountries, al the data is visible. How can I check for the permissions in the stored procedure?

Is this also possible if the stored procedure does EXEC "SELECT * FROM Countries" instead of just SELECT FROM ...?

Maybe it's also better just to return an empty recordset instead of an error...

Does somebody have an idea?

+1  A: 

That is how permissions work in SQL Server.

So you can give permissions on stored procedures without having to give permissions to the underlying objects. This allows you to exercise control over exactly what updates etc. people can make.

Don't give the user silverlight permissions to execute the stored procedure if you don't want them to execute it!

Edit: Although having read the question again it sounds like maybe this is the kind of thing you need?

Martin Smith
When I just place the select command (in the sp), it gives no error. When I place the exec("SELECT..") command (in the sp), it throws me an error. My main idea is to quickly fill multiple datagrids in c#. So I want to make a sp with the name of the table as parameter. User1 can see the data, but user2 cannot see the data. So the EXEC(...) is probably what I need. Than I can probably catch the error in c# and exit the form or something. Is this a good idea?
VeeWee
What version of SQL Server are you on? You can use `EXEC AS...` with dynamic SQL to get it to execute under the credentials of an account with sufficient permissions.
Martin Smith
mssql 2008 server. I want the sp to run under the current user: Every user has execute permissions on sp, but the sp throws error when the current user doesn't have select permissions on the table.
VeeWee
Right. I guess you could have a try, catch in the stored procedure itself and in the catch block use something like `select top 0 'col1' as col1, 'col2' as col2` to return an empty resultset if that makes the C# code more straightforward.
Martin Smith
Alright. Didn't know there was a try-catch in mssql! Very helpfull, thanx!
VeeWee
+2  A: 
SELECT has_perms_by_name('dbo.Countries', 'OBJECT', 'SELECT')
igor
I want the users to run the query inside the stored procedure, but throw an error or an empty recordset if not permitted.
VeeWee
+1 That would be cleaner than `try...catch`
Martin Smith
@VeeWee SELECT has_perms_by_name('dbo.Countries', 'OBJECT', 'SELECT')
igor
ok, that seems to work good! I'm going to build this in my sp. Thx!
VeeWee
+2  A: 

That's due to ownership chaining. Basically, if the same principal (e.g. dbo) owns an SP and a table used int it, permissions for the table are not checked.
Actually, this makes sense. For instance, it allows you to give a user acces to some data, but only in specifiс ways coded in the SPs.

If you use dynamic SQL, the permissions are calculated every time. Since SQL2005 you can use EXECUTE AS clause to specify execution context. For example, EXECUTE AS OWNER makes dynamic SQL in the SP execute in SP owner's context, giving similar effect to ownership chaining with static SQL.

VladV