I have a SQL Server 2016 instance and I've just noticed that some user logins aren't listed for some users. For example, if I execute this query:
select count(*) FROM sys.database_principals a where type = 'U'
I receive a count of 1348
. But if I execute this query:
execute as user = 'some_user';
select count(*) FROM sys.database_principals a where type = 'U';
revert;
I receive a count of 92
, meaning that there are 1256
users that can't be seen by the above user. If I grant the user db_accessadmin
database role membership, then they're able to see all 1348
users returned from that above query. However I do not want to grant db_accessadmin
to all users as that gives much more access than I want to grant.
I've compared the properties of one of the 92 users that does show up to the properties of the users that don't show up however I haven't noticed any property that looks to allow listing the user.
How may I go about allowing all users to be listed in the query to database_principals?
Best Answer
Seeing users requires the VIEW DEFINITION permission on the User Principle. This is implied by the ALTER USER permission.
With ALTER USER you can do a handy ALTER ANY USER, which is the right db_accessadmin gets. But there's no such thing for VIEW DEFINITION only.
So to accomplish what you want, the easiest way would probably be to create a new Database Role, give it through a script VIEW DEFINITION rights to all users in the database. And then assign users to this new role that you want to give these rights.
The above script can be saved/made into a procedure and rerun when necessary, or one can make a trigger upon creating new users to grant view definition to the database role.
Then to add a user to this database role (SQL Server 2012+)