Skip to main content
added 633 characters in body
Source Link
Aaron Bertrand
  • 181.5k
  • 28
  • 402
  • 619

The whole point of roles like the db_datareader role is that you don't have to explicitly define read permissions for every person in that role for every object. So, you won't find a row in there for every user in the role. This is not a query, but you should essentially do this:

  1. Get all the users who have been explicitly granted access to that table, and for which a DENY/REVOKE does not exist.
  2. Get all the users who are members of any of the roles that implicitly grant read access to the given object (but again also check for explicit DENY/REVOKE).

Pseudo code (I'll update with real examples when I have time):

-- is user in role(s)? If so:
 -- does role have exec on procedure - include them
 -- does role have select on base table - include them
 -- does role have DENY/REVOKE on procedure - exclude them
 -- does role have DENY/REVOKE on table - exclude them

-- is user not in role(s)? Then:
 -- does user have exec on procedure - include them
 -- does user have select on base table - include them
 -- does user have DENY/REVOKE on procedure - exclude them
 -- does user have DENY/REVOKE on table - exclude them

The whole point of roles like the db_datareader role is that you don't have to explicitly define read permissions for every person in that role for every object. So, you won't find a row in there for every user in the role. This is not a query, but you should essentially do this:

  1. Get all the users who have been explicitly granted access to that table, and for which a DENY/REVOKE does not exist.
  2. Get all the users who are members of any of the roles that implicitly grant read access to the given object (but again also check for explicit DENY/REVOKE).

The whole point of roles like the db_datareader role is that you don't have to explicitly define read permissions for every person in that role for every object. So, you won't find a row in there for every user in the role. This is not a query, but you should essentially do this:

  1. Get all the users who have been explicitly granted access to that table, and for which a DENY/REVOKE does not exist.
  2. Get all the users who are members of any of the roles that implicitly grant read access to the given object (but again also check for explicit DENY/REVOKE).

Pseudo code (I'll update with real examples when I have time):

-- is user in role(s)? If so:
 -- does role have exec on procedure - include them
 -- does role have select on base table - include them
 -- does role have DENY/REVOKE on procedure - exclude them
 -- does role have DENY/REVOKE on table - exclude them

-- is user not in role(s)? Then:
 -- does user have exec on procedure - include them
 -- does user have select on base table - include them
 -- does user have DENY/REVOKE on procedure - exclude them
 -- does user have DENY/REVOKE on table - exclude them
Source Link
Aaron Bertrand
  • 181.5k
  • 28
  • 402
  • 619

The whole point of roles like the db_datareader role is that you don't have to explicitly define read permissions for every person in that role for every object. So, you won't find a row in there for every user in the role. This is not a query, but you should essentially do this:

  1. Get all the users who have been explicitly granted access to that table, and for which a DENY/REVOKE does not exist.
  2. Get all the users who are members of any of the roles that implicitly grant read access to the given object (but again also check for explicit DENY/REVOKE).