How to tell if SQL Server user can view every table in database
I have an application that lets users browse data in a SQL database, and I'd like to warn the user if they don't have rights t开发者_运维知识库o see every table. I'm getting a list of tables by doing a SELECT on sys.objects, but if the user doesn't have SELECT rights on a table, it doesn't show up in that query, so there's no way I can see to know what I don't know.
I don't even need to know what in particular I'm missing, just if there's anything the user can't view. Anybody know how to accomplish this?
CLARIFICATION:
I'm creating a tool that can be run against any SQL Server, so I'm not looking to set up permissions to see every object - I just want to know if the current user can. If they don't have rights, that's fine - I just want to make sure they know that, since the results they get won't reflect the entire database.
I'm not exactly sure if this is in line with any security concerns of yours, but my idea would be to create a user called SELECT_ALL that has select rights to all tables, create a connection with SELECT_ALL and query the sys.objects table, pass the list of tables (or just a count(*) if you want to simply know if the user has complete access or anything less than complete), close the connection, then repeat with the user's credentials and compare.
You need to mask the sys.objects query with a user with different permissions that can see the lot. The best way is EXECUTE AS OWNER
in a view or udf. This enumerates all objects (if dbo owns everything) thus allowing you to find out what is missing (which is masked by metadata visibility)
CREATE VIEW dbo.mymask
WITH EXECUTE AS OWNER --the magic
AS
SELECT * FROM sys.objects
GO
SELECT
*
FROM
dbo.mymask v
LEFT JOIN
sys.objects o2 ON v.object_id = o.object_id
If you use roles, or want to do it in one then something like
CREATE VIEW dbo.mymask
WITH EXECUTE AS OWNER --the magic
AS
SELECT ...
FROM
sys.objects O
JOIN
sys.database_permissions DP ON ... --premissions
JOIN
sys.database_principals R ON DP. = R --role
etc to role members etc
WHERE
xxx.name = ORIGINAL_LOGIN()
GO
精彩评论